diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5f3b5a3effada..8811470d4fc4f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,11 +15,8 @@ # Helm Chart /chart/ @dstandish @jedcunningham @hussein-awala -# Docs (without Providers) -/docs/*.py @potiuk -/docs/apache-airflow @potiuk -/docs/docker-stack @potiuk -/docs/helm-chart @dstandish @jedcunningham +# Docs +/docs/*.py @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @kaxil @eladkal @jason810496 # API /airflow-core/src/airflow/api/ @ephraimbuddy @pierrejeambrun @rawwar @jason810496 @@ -41,17 +38,23 @@ airflow-core/src/airflow/ui/public/i18n/locales/ar/ @shahar1 @hussein-awala # + @ahmadtfarhan airflow-core/src/airflow/ui/public/i18n/locales/ca/ @jscheffl @bugraoz93 # + @ecodina airflow-core/src/airflow/ui/public/i18n/locales/de/ @jscheffl # + @TJaniF @m1racoli +airflow-core/src/airflow/ui/public/i18n/locales/el/ @ashb # + @PApostol airflow-core/src/airflow/ui/public/i18n/locales/es/ @bbovenzi # + @aoelvp94 airflow-core/src/airflow/ui/public/i18n/locales/fr/ @pierrejeambrun @vincbeck airflow-core/src/airflow/ui/public/i18n/locales/he/ @eladkal @shahar1 @romsharon98 # +@Dev-iL airflow-core/src/airflow/ui/public/i18n/locales/hi/ @vatsrahul1001 airflow-core/src/airflow/ui/public/i18n/locales/hu/ @jscheffl @potiuk # +@majorosdonat +airflow-core/src/airflow/ui/public/i18n/locales/it/ @bbovenzi # + @aoelvp94 airflow-core/src/airflow/ui/public/i18n/locales/ko/ @jscheffl @potiuk # + @choo121600 @kgw7401 @0ne-stone airflow-core/src/airflow/ui/public/i18n/locales/nl/ @BasPH # + @DjVinnii airflow-core/src/airflow/ui/public/i18n/locales/pl/ @potiuk @mobuchowski # + @kacpermuda +airflow-core/src/airflow/ui/public/i18n/locales/pt/ @potiuk # + @aoelvp94 @victoru2 +airflow-core/src/airflow/ui/public/i18n/locales/th/ @potiuk # + @zkan @blackbass64 @lifnaja @Aphinan-Th @chonla @Srabasti airflow-core/src/airflow/ui/public/i18n/locales/tr/ @bugraoz93 # +@hasancatalgol +airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/ @potiuk # + @Fortytwoo @gyli airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/ @Lee-W @jason810496 # + @RoyLee1224 @guan404ming + # Security/Permissions /airflow-core/src/airflow/security/permissions.py @vincbeck @@ -74,7 +77,7 @@ airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/ @Lee-W @jason810496 # + @ /docs/apache-airflow/authoring-and-scheduling/deferring.rst @dstandish @hussein-awala # Secrets Backends -/airflow-core/src/airflow/secrets @dstandish @potiuk @ashb +/airflow-core/src/airflow/secrets @dstandish @ashb # Providers /providers/amazon/ @eladkal @o-nikolas @@ -90,26 +93,27 @@ airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/ @Lee-W @jason810496 # + @ /providers/openlineage/ @mobuchowski /providers/slack/ @eladkal /providers/smtp/ @hussein-awala -/providers/snowflake/ @potiuk @mik-laj +/providers/snowflake/ @potiuk /providers/apache/iceberg/ @Fokko # Dev tools -/.github/workflows/ @potiuk @ashb @gopidesupavan -/dev/ @potiuk @ashb @jedcunningham @gopidesupavan @amoghrajesh +/.github/workflows/ @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @kaxil @eladkal @jason810496 +/dev/ @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @kaxil @eladkal @jason810496 @jedcunningham @ephraimbuddy /dev/react-plugin-tools/ @pierrejeambrun @bbovenzi /docker-tests/ @potiuk @ashb @gopidesupavan @jason810496 /kubernetes-tests/ @potiuk @ashb @gopidesupavan @jason810496 /helm-tests/ @dstandish @jedcunningham -/scripts/ @potiuk @ashb @gopidesupavan -Dockerfile @potiuk @ashb @gopidesupavan -Dockerfile.ci @potiuk @ashb @gopidesupavan - -# Releasing Guides & Project Guidelines -/dev/PROJECT_GUIDELINES.md @kaxil -/dev/PROVIDER_DISTRIBUTIONS_DETAILS.md @eladkal -/dev/README.md @kaxil -/dev/README_RELEASE_*.md @kaxil @pierrejeambrun -/dev/README_RELEASE_PROVIDERS.md @eladkal +/scripts/ @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @kaxil @eladkal @jason810496 +Dockerfile @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @kaxil @eladkal @jason810496 +Dockerfile.ci @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @kaxil @eladkal @jason810496 + +# E2E integration tests +/airflow-e2e-tests/ @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @kaxil @eladkal @jason810496 + +# Task SDK integration tests +/task-sdk-tests/ @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @kaxil @eladkal @jason810496 + +# Issue triage process ISSUE_TRIAGE_PROCESS.rst @eladkal # AIP-52 - Setup and Teardown diff --git a/.github/actions/breeze/action.yml b/.github/actions/breeze/action.yml index a7fff7dc397fe..7b583d8a45a36 100644 --- a/.github/actions/breeze/action.yml +++ b/.github/actions/breeze/action.yml @@ -22,6 +22,9 @@ inputs: python-version: description: 'Python version to use' default: "3.10" + uv-version: + description: 'uv version to use' + default: "0.9.4" # Keep this comment to allow automatic replacement of uv version outputs: host-python-version: description: Python version used in host @@ -33,6 +36,11 @@ runs: uses: actions/setup-python@v5 with: python-version: ${{ inputs.python-version }} + - name: "Install uv" + shell: bash + run: curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh + env: + UV_VERSION: ${{ inputs.uv-version }} # NOTE! Installing Breeze without using cache is FASTER than when using cache - uv is so fast and has # so low overhead, that just running upload cache/restore cache is slower than installing it from scratch - name: "Install Breeze" diff --git a/.github/actions/install-prek/action.yml b/.github/actions/install-prek/action.yml index 3bf30da69c9ae..10f80d14959e0 100644 --- a/.github/actions/install-prek/action.yml +++ b/.github/actions/install-prek/action.yml @@ -24,13 +24,10 @@ inputs: default: "3.10" uv-version: description: 'uv version to use' - default: "0.8.15" # Keep this comment to allow automatic replacement of uv version + default: "0.9.4" # Keep this comment to allow automatic replacement of uv version prek-version: description: 'prek version to use' - default: "0.1.6" # Keep this comment to allow automatic replacement of prek version - skip-prek-hooks: - description: "Skip some prek hooks from installation" - default: "" + default: "0.2.10" # Keep this comment to allow automatic replacement of prek version save-cache: description: "Whether to save prek cache" required: true @@ -40,14 +37,17 @@ inputs: runs: using: "composite" steps: - - name: Install uv and prek + - name: "Install uv" + shell: bash + run: curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh + env: + UV_VERSION: ${{ inputs.uv-version }} + - name: Install prek shell: bash env: - UV_VERSION: ${{inputs.uv-version}} PREK_VERSION: ${{inputs.prek-version}} - SKIP: ${{ inputs.skip-prek-hooks }} + UV_VERSION: ${{ inputs.uv-version }} run: | - curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh uv tool install prek==${PREK_VERSION} --with uv==${UV_VERSION} working-directory: ${{ github.workspace }} # We need to use tar file with archive to restore all the permissions and symlinks @@ -64,7 +64,7 @@ runs: uses: apache/infrastructure-actions/stash/restore@1c35b5ccf8fba5d4c3fdf25a045ca91aa0cbc468 with: # yamllint disable rule:line-length - key: cache-prek-v6-${{ inputs.platform }}-${{ inputs.python-version }}-${{inputs.skip-prek-hooks}}-${{ hashFiles('.pre-commit-config.yaml') }} + key: cache-prek-v9-${{ inputs.platform }}-python${{ inputs.python-version }}-uv${{ inputs.uv-version }}-${{ hashFiles('**/.pre-commit-config.yaml') }} path: /tmp/ id: restore-prek-cache - name: "Check if prek cache tarball exists" @@ -88,12 +88,21 @@ runs: echo shell: bash if: steps.restore-prek-cache.outputs.stash-hit == 'true' + - name: "Make sure cache is cleared on cache miss" + run: | + echo "Cleaning up prek cache in case of cache miss (in case of pre-installed-cache from the system)" + ls -la ~/.cache/prek || true + rm -rf ~/.cache/prek + shell: bash + if: steps.restore-prek-cache.outputs.stash-hit != 'true' - name: Install prek hooks shell: bash - run: prek install-hooks || (cat ~/.cache/prek/prek.log && exit 1) + run: prek install-hooks working-directory: ${{ github.workspace }} - env: - SKIP: ${{ inputs.skip-prek-hooks }} + - name: "Show prek log" + shell: bash + run: cat ~/.cache/prek/prek.log || true + if: always() - name: "Prepare .tar file from prek cache" run: | tar -C ~ -czf /tmp/cache-prek.tar.gz .cache/prek @@ -103,7 +112,7 @@ runs: uses: apache/infrastructure-actions/stash/save@1c35b5ccf8fba5d4c3fdf25a045ca91aa0cbc468 with: # yamllint disable rule:line-length - key: cache-prek-v6-${{ inputs.platform }}-${{ inputs.python-version }}-${{ inputs.skip-prek-hooks }}-${{ hashFiles('.pre-commit-config.yaml') }} + key: cache-prek-v9-${{ inputs.platform }}-python${{ inputs.python-version }}-uv${{ inputs.uv-version }}-${{ hashFiles('**/.pre-commit-config.yaml') }} path: /tmp/cache-prek.tar.gz if-no-files-found: 'error' retention-days: '2' diff --git a/.github/actions/migration_tests/action.yml b/.github/actions/migration_tests/action.yml index 93e966de8a847..447af1c6368ff 100644 --- a/.github/actions/migration_tests/action.yml +++ b/.github/actions/migration_tests/action.yml @@ -28,7 +28,7 @@ runs: - name: "Test migration file 2 to 3 migration: ${{env.BACKEND}}" shell: bash run: | - breeze shell "${AIRFLOW_2_CMD}" --use-airflow-version 2.11.0 --answer y && + breeze shell "${AIRFLOW_2_CMD}" --use-airflow-version 2.11.0 --airflow-extras pydantic --answer y && breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${DB_MANGERS} ${AIRFLOW_3_CMD}" --no-db-cleanup env: @@ -57,7 +57,7 @@ runs: - name: "Test ORM migration 2 to 3: ${{env.BACKEND}}" shell: bash run: > - breeze shell "${AIRFLOW_2_CMD}" --use-airflow-version 2.11.0 --answer y && + breeze shell "${AIRFLOW_2_CMD}" --use-airflow-version 2.11.0 --airflow-extras pydantic --answer y && breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${DB_MANGERS} ${AIRFLOW_3_CMD}" --no-db-cleanup env: diff --git a/.github/boring-cyborg.yml b/.github/boring-cyborg.yml index bafa93822095f..d21efe82960bd 100644 --- a/.github/boring-cyborg.yml +++ b/.github/boring-cyborg.yml @@ -332,23 +332,23 @@ labelPRBasedOnFilePath: - .rat-excludes - .readthedocs.yml - # This should be copy of the "area:dev-tools" above and should be updated when we switch maintenance branch - backport-to-v3-0-test: - - scripts/**/* - - dev/**/* - - .github/**/* - - Dockerfile.ci - - CONTRIBUTING.rst - - contributing-docs/**/* - - yamllint-config.yml - - .asf.yaml - - .bash_completion - - .dockerignore - - .hadolint.yaml - - .pre-commit-config.yaml - - .rat-excludes - - .readthedocs.yml - + # # This should be copy of the "area:dev-tools" above and should be updated when + # # we switch maintenance branch + # backport-to-v3-1-test: + # - scripts/**/* + # - dev/**/* + # - .github/**/* + # - Dockerfile.ci + # - CONTRIBUTING.rst + # - contributing-docs/**/* + # - yamllint-config.yml + # - .asf.yaml + # - .bash_completion + # - .dockerignore + # - .hadolint.yaml + # - .pre-commit-config.yaml + # - .rat-excludes + # - .readthedocs.yml kind:documentation: - airflow-core/docs/**/* @@ -381,6 +381,9 @@ labelPRBasedOnFilePath: translation:de: - airflow-core/src/airflow/ui/public/i18n/locales/de/* + translation:el: + - airflow-core/src/airflow/ui/public/i18n/locales/el/* + translation:es: - airflow-core/src/airflow/ui/public/i18n/locales/es/* @@ -396,6 +399,9 @@ labelPRBasedOnFilePath: translation:hu: - airflow-core/src/airflow/ui/public/i18n/locales/hu/* + translation:it: + - airflow-core/src/airflow/ui/public/i18n/locales/it/* + translation:ko: - airflow-core/src/airflow/ui/public/i18n/locales/ko/* @@ -405,9 +411,18 @@ labelPRBasedOnFilePath: translation:pl: - airflow-core/src/airflow/ui/public/i18n/locales/pl/* + translation:pt: + - airflow-core/src/airflow/ui/public/i18n/locales/pt/* + + translation:th: + - airflow-core/src/airflow/ui/public/i18n/locales/th/* + translation:tr: - airflow-core/src/airflow/ui/public/i18n/locales/tr/* + translation:zh-CN: + - airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/* + translation:zh-TW: - airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/* @@ -424,7 +439,7 @@ labelPRBasedOnFilePath: area:Logging: - airflow-core/src/airflow/config_templates/airflow_local_settings.py - - airflow-core/tests/unit/core/test_logging_config.py + - shared/logging/**/* - airflow-core/src/airflow/utils/log/**/* - airflow-core/docs/administration-and-deployment/logging-monitoring/logging-*.rst - airflow-core/tests/unit/utils/log/**/* diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0251dc0060c23..37cf84bf1d646 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -119,3 +119,8 @@ updates: core-ui-package-updates: patterns: - "*" + + - package-ecosystem: "uv" + directory: "/dev/breeze" + schedule: + interval: "weekly" diff --git a/.github/workflows/airflow-distributions-tests.yml b/.github/workflows/airflow-distributions-tests.yml index beda0fcd8036a..8a76f5cf06797 100644 --- a/.github/workflows/airflow-distributions-tests.yml +++ b/.github/workflows/airflow-distributions-tests.yml @@ -113,7 +113,7 @@ jobs: USE_LOCAL_HATCH: "${{ inputs.use-local-venv }}" run: | uv tool uninstall hatch || true - uv tool install hatch==1.14.1 + uv tool install hatch==1.15.1 breeze release-management "${DISTRIBUTION_TYPE}" --distribution-format wheel if: ${{ matrix.python-version == inputs.default-python-version }} - name: "Verify wheel packages with twine" diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index 548b9ce5b0fae..1fafc6e59379c 100644 --- a/.github/workflows/basic-tests.yml +++ b/.github/workflows/basic-tests.yml @@ -66,7 +66,7 @@ on: # yamllint disable-line rule:truthy type: string uv-version: description: 'uv version to use' - default: "0.8.15" # Keep this comment to allow automatic replacement of uv version + default: "0.9.4" # Keep this comment to allow automatic replacement of uv version type: string platform: description: 'Platform for the build - linux/amd64 or linux/arm64' @@ -100,8 +100,6 @@ jobs: matrix: shared-distribution: ${{ fromJSON(inputs.shared-distributions-as-json) }} runs-on: ${{ fromJSON(inputs.runners) }} - env: - UV_VERSION: ${{inputs.uv-version}} steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -110,6 +108,8 @@ jobs: persist-credentials: false - name: "Install uv" run: curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh + env: + UV_VERSION: ${{ inputs.uv-version }} - name: "Run shared ${{ matrix.shared-distribution }} tests" run: uv run --group dev pytest --color=yes -n auto working-directory: shared/${{ matrix.shared-distribution }} @@ -193,7 +193,6 @@ jobs: id: prek with: python-version: ${{steps.breeze.outputs.host-python-version}} - skip-prek-hooks: ${{ inputs.skip-prek-hooks }} platform: ${{ inputs.platform }} save-cache: false - name: "Check translation completeness" @@ -229,9 +228,8 @@ jobs: id: prek with: python-version: ${{ steps.breeze.outputs.host-python-version }} - skip-prek-hooks: ${{ inputs.skip-prek-hooks }} platform: ${{ inputs.platform }} - save-cache: false + save-cache: true - name: Fetch incoming commit ${{ github.sha }} with its parent uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: @@ -282,13 +280,14 @@ jobs: id: prek with: python-version: ${{ steps.breeze.outputs.host-python-version }} - skip-prek-hooks: ${{ inputs.skip-prek-hooks }} platform: ${{ inputs.platform }} save-cache: false - name: "Autoupdate all prek hooks" run: prek autoupdate --freeze - name: "Autoupdate Lucas-C hooks to bleeding edge" run: prek autoupdate --bleeding-edge --freeze --repo https://github.com/Lucas-C/pre-commit-hooks + - name: "Autoupdate Octopin to bleeding edge" + run: prek autoupdate --bleeding-edge --freeze --repo https://github.com/eclipse-csi/octopin - name: "Check if there are any changes in pre-commit hooks" run: git diff --exit-code - name: "Run automated upgrade for chart dependencies" @@ -319,6 +318,7 @@ jobs: UPGRADE_GITPYTHON: "false" UPGRADE_RICH: "false" UPGRADE_RUFF: "false" + UPGRADE_MYPY: "false" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: "Run automated upgrade for important versions minus uv(failing if needed)" run: > @@ -338,6 +338,7 @@ jobs: UPGRADE_GITPYTHON: "true" UPGRADE_RICH: "true" UPGRADE_RUFF: "true" + UPGRADE_MYPY: "true" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} test-airflow-release-commands: @@ -394,3 +395,55 @@ jobs: run: | breeze release-management generate-issue-content-core \ --limit-pr-count 2 --previous-release 3.0.1 --current-release 3.0.2 --verbose + + test-airflow-standalone: + timeout-minutes: 30 + name: "Test Airflow standalone commands" + runs-on: ${{ fromJSON(inputs.runners) }} + env: + AIRFLOW_HOME: ~/airflow + FORCE_COLOR: 1 + steps: + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + - name: "Install uv" + run: curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh + env: + UV_VERSION: ${{ inputs.uv-version }} + - name: "Set up Airflow home directory" + run: | + echo "Setting AIRFLOW_HOME to $AIRFLOW_HOME" + mkdir -p $AIRFLOW_HOME + - name: "Install Airflow from current repo (simulating user installation)" + run: | + uv venv + set -x + uv pip install -e ./airflow-core + - name: "Test airflow standalone command" + run: | + uv run --no-sync airflow standalone 2>&1 | tee airflow_startup.log & + AIRFLOW_PID=$! + + # Wait for ready message till timeout (10 minutes) + for i in {1..600}; do + if ! kill -0 $AIRFLOW_PID 2>/dev/null; then + wait $AIRFLOW_PID + EXIT_CODE=$? + echo "FAILED: Airflow standalone exited with code $EXIT_CODE" + exit $EXIT_CODE + fi + + if grep -q "Airflow is ready" airflow_startup.log; then + echo "SUCCESS: Airflow standalone is ready!" + kill $AIRFLOW_PID + exit 0 + fi + + sleep 1 + done + + echo "FAILED: Airflow standalone did not become ready in time" + kill $AIRFLOW_PID 2>/dev/null || true + exit 1 diff --git a/.github/workflows/ci-amd.yml b/.github/workflows/ci-amd.yml index e65bc71e0fc38..c5bff2395b03f 100644 --- a/.github/workflows/ci-amd.yml +++ b/.github/workflows/ci-amd.yml @@ -165,14 +165,6 @@ jobs: env: PR_LABELS: ${{ steps.source-run-info.outputs.pr-labels }} GITHUB_CONTEXT: ${{ toJson(github) }} - - name: "Install and cache prek" - uses: ./.github/actions/install-prek - id: prek - with: - python-version: ${{ steps.breeze.outputs.host-python-version }} - skip-prek-hooks: ${{ needs.build-info.outputs.skip-prek-hooks }} - platform: "linux/amd64" - save-cache: true run-pin-versions-hook: name: "Run pin-versions hook" needs: [build-info] @@ -190,10 +182,9 @@ jobs: python-version: "3.11" platform: "linux/amd64" save-cache: true - skip-prek-hooks: "" - name: "Run pin-versions" run: > - prek -c .github/.pre-commit-config.yaml --all-files --verbose --hook-stage manual + prek -c dev/.pre-commit-config.yaml --all-files --verbose --hook-stage manual pin-versions env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -829,13 +820,13 @@ jobs: - name: Setup Gotestsum shell: bash run: | - go install gotest.tools/gotestsum@ddd0b05a6878e2e8257a2abe6e7df66cebc53d0e # v1.12.3 + go install gotest.tools/gotestsum@c4a0df2e75a225d979a444342dd3db752b53619f # v1.13.0 gotestsum --version - name: "Cleanup dist files" run: rm -fv ./dist/* - name: Run Go tests working-directory: ./go-sdk - run: gotestsum --format testname ./... + run: gotestsum --format github-actions ./... tests-airflow-ctl: name: "Airflow CTL tests" @@ -883,7 +874,6 @@ jobs: - tests-non-db-providers - tests-postgres-core - tests-postgres-providers - # - tests-special - tests-sqlite-core - tests-sqlite-providers - tests-task-sdk @@ -935,6 +925,21 @@ jobs: summarize-warnings: timeout-minutes: 15 name: "Summarize warnings" + needs: + - build-info + - tests-mysql-core + - tests-mysql-providers + - tests-non-db-core + - tests-non-db-providers + - tests-postgres-core + - tests-postgres-providers + - tests-sqlite-core + - tests-sqlite-providers + - tests-task-sdk + - tests-airflow-ctl + - tests-special + - tests-with-lowest-direct-resolution-core + - tests-with-lowest-direct-resolution-providers runs-on: ${{ fromJSON(needs.build-info.outputs.amd-runners) }} if: needs.build-info.outputs.run-unit-tests == 'true' steps: diff --git a/.github/workflows/ci-arm.yml b/.github/workflows/ci-arm.yml index 28dd6967dae8f..a54504891416f 100644 --- a/.github/workflows/ci-arm.yml +++ b/.github/workflows/ci-arm.yml @@ -117,7 +117,8 @@ jobs: shared-distributions-as-json: ${{ steps.selective-checks.outputs.shared-distributions-as-json }} skip-prek-hooks: ${{ steps.selective-checks.outputs.skip-prek-hooks }} skip-providers-tests: ${{ steps.selective-checks.outputs.skip-providers-tests }} - source-head-repo: ${{ steps.source-run-info.outputs.source-head-repo }} + source-head-repo: ${{ steps.source-run-info.outputs.head-repo }} + source-head-ref: ${{ steps.source-run-info.outputs.head-ref }} sqlite-exclude: ${{ steps.selective-checks.outputs.sqlite-exclude }} testable-core-integrations: ${{ steps.selective-checks.outputs.testable-core-integrations }} testable-providers-integrations: ${{ steps.selective-checks.outputs.testable-providers-integrations }} @@ -157,14 +158,7 @@ jobs: env: PR_LABELS: ${{ steps.source-run-info.outputs.pr-labels }} GITHUB_CONTEXT: ${{ toJson(github) }} - - name: "Install and cache prek" - uses: ./.github/actions/install-prek - id: prek - with: - python-version: ${{ steps.breeze.outputs.host-python-version }} - skip-prek-hooks: ${{ needs.build-info.outputs.skip-prek-hooks }} - platform: "linux/arm64" - save-cache: true + basic-tests: name: "Basic tests" needs: [build-info] @@ -249,6 +243,41 @@ jobs: debug-resources: ${{ needs.build-info.outputs.debug-resources }} use-uv: ${{ needs.build-info.outputs.use-uv }} + ci-image-checks: + name: "CI image checks" + needs: [build-info, build-ci-images] + uses: ./.github/workflows/ci-image-checks.yml + permissions: + id-token: write + contents: read + with: + runners: ${{ needs.build-info.outputs.arm-runners }} + platform: "linux/arm64" + run-mypy: ${{ needs.build-info.outputs.run-mypy }} + mypy-checks: ${{ needs.build-info.outputs.mypy-checks }} + python-versions-list-as-string: ${{ needs.build-info.outputs.python-versions-list-as-string }} + branch: ${{ needs.build-info.outputs.default-branch }} + canary-run: ${{ needs.build-info.outputs.canary-run }} + default-python-version: "${{ needs.build-info.outputs.default-python-version }}" + docs-list-as-string: ${{ needs.build-info.outputs.docs-list-as-string }} + latest-versions-only: ${{ needs.build-info.outputs.latest-versions-only }} + basic-checks-only: ${{ needs.build-info.outputs.basic-checks-only }} + upgrade-to-newer-dependencies: ${{ needs.build-info.outputs.upgrade-to-newer-dependencies }} + skip-prek-hooks: ${{ needs.build-info.outputs.skip-prek-hooks }} + ci-image-build: ${{ needs.build-info.outputs.ci-image-build }} + include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} + debug-resources: ${{ needs.build-info.outputs.debug-resources }} + docs-build: ${{ needs.build-info.outputs.docs-build }} + run-api-codegen: ${{ needs.build-info.outputs.run-api-codegen }} + default-postgres-version: ${{ needs.build-info.outputs.default-postgres-version }} + run-coverage: ${{ needs.build-info.outputs.run-coverage }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + source-head-repo: ${{ needs.build-info.outputs.source-head-repo }} + source-head-ref: ${{ needs.build-info.outputs.source-head-ref }} + secrets: + DOCS_AWS_ACCESS_KEY_ID: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} + DOCS_AWS_SECRET_ACCESS_KEY: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} + providers: name: "provider distributions tests" uses: ./.github/workflows/test-providers.yml @@ -258,7 +287,8 @@ jobs: packages: read if: > needs.build-info.outputs.skip-providers-tests != 'true' && - needs.build-info.outputs.latest-versions-only != 'true' + needs.build-info.outputs.latest-versions-only != 'true' && + needs.build-info.outputs.run-unit-tests == 'true' with: runners: ${{ needs.build-info.outputs.arm-runners }} platform: "linux/arm64" @@ -413,7 +443,6 @@ jobs: default-branch: ${{ needs.build-info.outputs.default-branch }} if: needs.build-info.outputs.run-unit-tests == 'true' - tests-non-db-core: name: "Non-DB tests: core" uses: ./.github/workflows/run-unit-tests.yml @@ -474,6 +503,99 @@ jobs: default-branch: ${{ needs.build-info.outputs.default-branch }} if: needs.build-info.outputs.run-unit-tests == 'true' + tests-special: + name: "Special tests" + uses: ./.github/workflows/special-tests.yml + needs: [build-info, build-ci-images] + permissions: + contents: read + packages: read + if: > + needs.build-info.outputs.run-unit-tests == 'true' && + (needs.build-info.outputs.canary-run == 'true' || + needs.build-info.outputs.upgrade-to-newer-dependencies != 'false' || + needs.build-info.outputs.full-tests-needed == 'true') + with: + default-branch: ${{ needs.build-info.outputs.default-branch }} + runners: ${{ needs.build-info.outputs.arm-runners }} + platform: "linux/arm64" + core-test-types-list-as-strings-in-json: > + ${{ needs.build-info.outputs.core-test-types-list-as-strings-in-json }} + providers-test-types-list-as-strings-in-json: > + ${{ needs.build-info.outputs.providers-test-types-list-as-strings-in-json }} + run-coverage: ${{ needs.build-info.outputs.run-coverage }} + default-python-version: "${{ needs.build-info.outputs.default-python-version }}" + python-versions: ${{ needs.build-info.outputs.python-versions }} + default-postgres-version: ${{ needs.build-info.outputs.default-postgres-version }} + excluded-providers-as-string: ${{ needs.build-info.outputs.excluded-providers-as-string }} + canary-run: ${{ needs.build-info.outputs.canary-run }} + upgrade-to-newer-dependencies: ${{ needs.build-info.outputs.upgrade-to-newer-dependencies }} + include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} + skip-providers-tests: ${{ needs.build-info.outputs.skip-providers-tests }} + debug-resources: ${{ needs.build-info.outputs.debug-resources }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + + tests-with-lowest-direct-resolution-core: + name: "Low dep tests:core" + needs: [build-info, build-ci-images] + uses: ./.github/workflows/run-unit-tests.yml + permissions: + contents: read + packages: read + if: > + needs.build-info.outputs.run-unit-tests == 'true' + with: + runners: ${{ needs.build-info.outputs.arm-runners }} + platform: "linux/arm64" + test-name: "LowestDeps" + force-lowest-dependencies: "true" + test-scope: "All" + test-group: "core" + backend: "sqlite" + python-versions: ${{ needs.build-info.outputs.python-versions }} + backend-versions: "['${{ needs.build-info.outputs.default-postgres-version }}']" + excluded-providers-as-string: "" + excludes: "[]" + test-types-as-strings-in-json: > + ${{ needs.build-info.outputs.core-test-types-list-as-strings-in-json }} + include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} + run-coverage: ${{ needs.build-info.outputs.run-coverage }} + debug-resources: ${{ needs.build-info.outputs.debug-resources }} + monitor-delay-time-in-seconds: 120 + skip-providers-tests: ${{ needs.build-info.outputs.skip-providers-tests }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + default-branch: ${{ needs.build-info.outputs.default-branch }} + + tests-with-lowest-direct-resolution-providers: + name: "Low dep tests: providers" + needs: [build-info, build-ci-images] + uses: ./.github/workflows/run-unit-tests.yml + permissions: + contents: read + packages: read + if: needs.build-info.outputs.run-unit-tests == 'true' + with: + runners: ${{ needs.build-info.outputs.arm-runners }} + platform: "linux/arm64" + test-name: "LowestDeps" + force-lowest-dependencies: "true" + test-scope: "All" + test-group: "providers" + backend: "sqlite" + python-versions: ${{ needs.build-info.outputs.python-versions }} + backend-versions: "['${{ needs.build-info.outputs.default-postgres-version }}']" + excluded-providers-as-string: ${{ needs.build-info.outputs.excluded-providers-as-string }} + excludes: "[]" + test-types-as-strings-in-json: > + ${{ needs.build-info.outputs.individual-providers-test-types-list-as-strings-in-json }} + include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} + run-coverage: ${{ needs.build-info.outputs.run-coverage }} + debug-resources: ${{ needs.build-info.outputs.debug-resources }} + monitor-delay-time-in-seconds: 120 + skip-providers-tests: ${{ needs.build-info.outputs.skip-providers-tests }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + default-branch: ${{ needs.build-info.outputs.default-branch }} + build-prod-images: name: Build PROD images needs: [build-info, build-ci-images, generate-constraints] @@ -500,6 +622,23 @@ jobs: disable-airflow-repo-cache: ${{ needs.build-info.outputs.disable-airflow-repo-cache }} prod-image-build: ${{ needs.build-info.outputs.prod-image-build }} + additional-prod-image-tests: + name: "Additional PROD image tests" + needs: [build-info, build-prod-images, generate-constraints] + uses: ./.github/workflows/additional-prod-image-tests.yml + with: + runners: ${{ needs.build-info.outputs.arm-runners }} + platform: "linux/arm64" + default-branch: ${{ needs.build-info.outputs.default-branch }} + constraints-branch: ${{ needs.build-info.outputs.default-constraints-branch }} + upgrade-to-newer-dependencies: ${{ needs.build-info.outputs.upgrade-to-newer-dependencies }} + docker-cache: ${{ needs.build-info.outputs.docker-cache }} + disable-airflow-repo-cache: ${{ needs.build-info.outputs.disable-airflow-repo-cache }} + default-python-version: "${{ needs.build-info.outputs.default-python-version }}" + canary-run: ${{ needs.build-info.outputs.canary-run }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + if: needs.build-info.outputs.prod-image-build == 'true' + tests-kubernetes: name: "Kubernetes tests" uses: ./.github/workflows/k8s-tests.yml @@ -519,9 +658,30 @@ jobs: ( needs.build-info.outputs.run-kubernetes-tests == 'true' || needs.build-info.outputs.run-helm-tests == 'true') + tests-task-sdk: + name: "Task SDK tests" + uses: ./.github/workflows/airflow-distributions-tests.yml + needs: [build-info, build-ci-images] + permissions: + contents: read + packages: read + with: + runners: ${{ needs.build-info.outputs.arm-runners }} + platform: "linux/arm64" + default-python-version: "${{ needs.build-info.outputs.default-python-version }}" + python-versions: ${{ needs.build-info.outputs.python-versions }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + canary-run: ${{ needs.build-info.outputs.canary-run }} + distribution-name: "task-sdk" + distribution-cmd-format: "prepare-task-sdk-distributions" + test-type: "task-sdk-tests" + use-local-venv: 'false' + test-timeout: 20 + if: needs.build-info.outputs.run-task-sdk-tests == 'true' + tests-go-sdk: name: "Go SDK tests" - needs: [build-info, build-ci-images] + needs: [build-info] runs-on: ${{ fromJSON(needs.build-info.outputs.arm-runners) }} timeout-minutes: 15 permissions: @@ -544,11 +704,38 @@ jobs: with: go-version: 1.24 cache-dependency-path: go-sdk/go.sum + # keep this in sync with go.mod in go-sdk/ + - name: Setup Gotestsum + shell: bash + run: | + go install gotest.tools/gotestsum@c4a0df2e75a225d979a444342dd3db752b53619f # v1.13.0 + gotestsum --version - name: "Cleanup dist files" run: rm -fv ./dist/* - name: Run Go tests working-directory: ./go-sdk - run: go test -v ./... + run: gotestsum --format github-actions ./... + + tests-airflow-ctl: + name: "Airflow CTL tests" + uses: ./.github/workflows/airflow-distributions-tests.yml + needs: [build-info] + permissions: + contents: read + packages: read + with: + runners: ${{ needs.build-info.outputs.arm-runners }} + platform: "linux/arm64" + default-python-version: "${{ needs.build-info.outputs.default-python-version }}" + python-versions: ${{ needs.build-info.outputs.python-versions }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + canary-run: ${{ needs.build-info.outputs.canary-run }} + distribution-name: "airflow-ctl" + distribution-cmd-format: "prepare-airflow-ctl-distributions" + test-type: "airflow-ctl-tests" + use-local-venv: 'true' + test-timeout: 20 + if: needs.build-info.outputs.run-airflow-ctl-tests == 'true' finalize-tests: name: Finalize tests @@ -559,11 +746,12 @@ jobs: if: always() && !failure() && !cancelled() needs: - additional-ci-image-checks + - additional-prod-image-tests - basic-tests - build-info - - basic-tests - - generate-constraints - build-prod-images + - ci-image-checks + - generate-constraints - providers - tests-helm - tests-kubernetes @@ -573,6 +761,11 @@ jobs: - tests-postgres-providers - tests-sqlite-core - tests-sqlite-providers + - tests-task-sdk + - tests-airflow-ctl + - tests-go-sdk + - tests-with-lowest-direct-resolution-core + - tests-with-lowest-direct-resolution-providers uses: ./.github/workflows/finalize-tests.yml with: runners: ${{ needs.build-info.outputs.arm-runners }} @@ -613,3 +806,55 @@ jobs: type: "mrkdwn" text: "🚨🕒 Failure Alert: Scheduled CI (ARM) 🕒🚨\n\n*Details:* " # yamllint enable rule:line-length + + summarize-warnings: + timeout-minutes: 15 + name: "Summarize warnings" + needs: + - build-info + - tests-non-db-core + - tests-non-db-providers + - tests-postgres-core + - tests-postgres-providers + - tests-sqlite-core + - tests-sqlite-providers + - tests-task-sdk + - tests-airflow-ctl + - tests-special + - tests-with-lowest-direct-resolution-core + - tests-with-lowest-direct-resolution-providers + runs-on: ${{ fromJSON(needs.build-info.outputs.arm-runners) }} + if: needs.build-info.outputs.run-unit-tests == 'true' + steps: + - name: "Cleanup repo" + shell: bash + run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + - name: "Free up disk space" + shell: bash + run: ./scripts/tools/free_up_disk_space.sh + - name: "Download all test warning artifacts from the current build" + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + path: ./artifacts + pattern: test-warnings-* + - name: "Setup python" + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: "${{ inputs.default-python-version }}" + - name: "Summarize all warnings" + run: | + ./scripts/ci/testing/summarize_captured_warnings.py ./artifacts \ + --pattern "**/warnings-*.txt" \ + --output ./files + - name: "Upload artifact for summarized warnings" + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: test-summarized-arm-runner-warnings + path: ./files/warn-summary-*.txt + retention-days: 7 + if-no-files-found: ignore + overwrite: true diff --git a/.github/workflows/ci-image-build.yml b/.github/workflows/ci-image-build.yml index b7e09a38648e6..6fc2c4e9bf649 100644 --- a/.github/workflows/ci-image-build.yml +++ b/.github/workflows/ci-image-build.yml @@ -72,6 +72,7 @@ on: # yamllint disable-line rule:truthy description: "JSON-formatted array of Python versions to build images from" required: true type: string + default: '[""]' branch: description: "Branch used to run the CI jobs in (main/v*_*_test)." required: true @@ -99,7 +100,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: ${{ fromJSON(inputs.python-versions) || fromJSON('[""]') }} + python-version: ${{ fromJSON(inputs.python-versions) }} timeout-minutes: 110 name: "Build CI ${{ inputs.platform }} image ${{ matrix.python-version }}" runs-on: ${{ fromJSON(inputs.runners) }} diff --git a/.github/workflows/ci-image-checks.yml b/.github/workflows/ci-image-checks.yml index a4954d0344579..6bd4d16d985f4 100644 --- a/.github/workflows/ci-image-checks.yml +++ b/.github/workflows/ci-image-checks.yml @@ -153,7 +153,7 @@ jobs: with: python-version: ${{steps.breeze.outputs.host-python-version}} platform: ${{ inputs.platform }} - save-cache: false + save-cache: true - name: "Static checks" run: prek --all-files --show-diff-on-failure --color always env: @@ -163,6 +163,9 @@ jobs: SKIP_GROUP_OUTPUT: "true" DEFAULT_BRANCH: ${{ inputs.branch }} RUFF_FORMAT: "github" + - name: "Show prek log on failure" + run: cat ~/.cache/prek/prek.log || true + if: failure() mypy: timeout-minutes: 45 @@ -184,6 +187,9 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + - name: "Free up disk space" + shell: bash + run: ./scripts/tools/free_up_disk_space.sh - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" uses: ./.github/actions/prepare_breeze_and_image with: diff --git a/.github/workflows/k8s-tests.yml b/.github/workflows/k8s-tests.yml index 1770f44bb553f..47bd7ba83211e 100644 --- a/.github/workflows/k8s-tests.yml +++ b/.github/workflows/k8s-tests.yml @@ -83,6 +83,9 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + - name: "Free up disk space" + shell: bash + run: ./scripts/tools/free_up_disk_space.sh # env.PYTHON_MAJOR_MINOR_VERSION, env.KUBERNETES_VERSION are set in the previous # step id: prepare-versions - name: "Prepare breeze & PROD image: ${{ env.PYTHON_MAJOR_MINOR_VERSION }}" diff --git a/.github/workflows/prod-image-build.yml b/.github/workflows/prod-image-build.yml index 31127a8e132cb..93eb251cf0d63 100644 --- a/.github/workflows/prod-image-build.yml +++ b/.github/workflows/prod-image-build.yml @@ -76,6 +76,7 @@ on: # yamllint disable-line rule:truthy description: "JSON-formatted array of Python versions to build images from" required: true type: string + default: '[""]' default-python-version: description: "Which version of python should be used by default" required: true @@ -184,7 +185,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ${{ fromJSON(inputs.python-versions) || fromJSON('[""]') }} + python-version: ${{ fromJSON(inputs.python-versions) }} timeout-minutes: 80 name: "Build PROD ${{ inputs.build-type }} image ${{ matrix.python-version }}" runs-on: ${{ fromJSON(inputs.runners) }} @@ -227,6 +228,10 @@ jobs: with: name: prod-packages path: ./docker-context-files + - name: "Remove fab provider for python 3.13" + shell: bash + run: rm -vf ./docker-context-files/apache_airflow_providers_fab-*.whl + if: matrix.python-version == '3.13' - name: "Show downloaded packages" run: ls -la ./docker-context-files - name: "Download constraints" diff --git a/.github/workflows/publish-docs-to-s3.yml b/.github/workflows/publish-docs-to-s3.yml index 97bce1515f52f..f2541d0626caa 100644 --- a/.github/workflows/publish-docs-to-s3.yml +++ b/.github/workflows/publish-docs-to-s3.yml @@ -318,6 +318,9 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + - name: "Make /mnt writeable and cleanup" + shell: bash + run: ./scripts/ci/make_mnt_writeable.sh - name: "Install Breeze" uses: ./.github/actions/breeze - name: "Download docs prepared as artifacts" diff --git a/.github/workflows/push-image-cache.yml b/.github/workflows/push-image-cache.yml index 9458b536e68e7..69ee1145361a0 100644 --- a/.github/workflows/push-image-cache.yml +++ b/.github/workflows/push-image-cache.yml @@ -116,6 +116,8 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + - name: "Free up disk space" + run: ./scripts/tools/free_up_disk_space.sh - name: "Install Breeze" uses: ./.github/actions/breeze - name: Login to ghcr.io @@ -183,6 +185,8 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + - name: "Free up disk space" + run: ./scripts/tools/free_up_disk_space.sh - name: "Install Breeze" uses: ./.github/actions/breeze - name: "Cleanup dist and context file" diff --git a/.github/workflows/release_dockerhub_image.yml b/.github/workflows/release_dockerhub_image.yml index 4c1349f20f070..8fc99b537d5eb 100644 --- a/.github/workflows/release_dockerhub_image.yml +++ b/.github/workflows/release_dockerhub_image.yml @@ -58,7 +58,7 @@ jobs: AIRFLOW_VERSION: ${{ github.event.inputs.airflowVersion }} AMD_ONLY: ${{ github.event.inputs.amdOnly }} LIMIT_PYTHON_VERSIONS: ${{ github.event.inputs.limitPythonVersions }} - UV_VERSION: "0.8.15" # Keep this comment to allow automatic replacement of uv version + UV_VERSION: "0.9.4" # Keep this comment to allow automatic replacement of uv version if: contains(fromJSON('[ "ashb", "eladkal", @@ -87,19 +87,19 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - name: "Install uv" - run: curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh - - name: "Check airflow version" - id: check-airflow-version - shell: bash - run: uv run scripts/ci/airflow_version_check.py "${AIRFLOW_VERSION}" >> "${GITHUB_OUTPUT}" - name: "Install Breeze" uses: ./.github/actions/breeze + with: + uv-version: ${{ env.UV_VERSION }} - name: Selective checks id: selective-checks env: VERBOSE: "false" run: breeze ci selective-check 2>> ${GITHUB_OUTPUT} + - name: "Check airflow version" + id: check-airflow-version + shell: bash + run: uv run scripts/ci/airflow_version_check.py "${AIRFLOW_VERSION}" >> "${GITHUB_OUTPUT}" - name: "Determine build matrix" shell: bash id: determine-matrix diff --git a/.github/workflows/test-providers.yml b/.github/workflows/test-providers.yml index 338c6f395bc1a..264f75e759be6 100644 --- a/.github/workflows/test-providers.yml +++ b/.github/workflows/test-providers.yml @@ -92,6 +92,9 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + - name: "Free up disk space" + shell: bash + run: ./scripts/tools/free_up_disk_space.sh - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" uses: ./.github/actions/prepare_breeze_and_image with: @@ -188,6 +191,9 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + - name: "Free up disk space" + shell: bash + run: ./scripts/tools/free_up_disk_space.sh - name: "Prepare breeze & CI image: ${{ matrix.compat.python-version }}" uses: ./.github/actions/prepare_breeze_and_image with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aac71bbb1793f..2ec142eaf0f70 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,8 +19,7 @@ default_stages: [pre-commit, pre-push] default_language_version: python: python3 node: 22.19.0 - golang: 1.24.0 -minimum_prek_version: '0.1.3' +minimum_prek_version: '0.2.0' exclude: ^.*/.*_vendor/ repos: - repo: meta @@ -172,18 +171,6 @@ repos: - --fuzzy-match-generates-todo files: > \.cfg$|\.conf$|\.ini$|\.ldif$|\.properties$|\.service$|\.tf$|Dockerfile.*$ - - id: insert-license - name: Add license for all Go files - types: [go] - exclude: mocks/.*\.go$ - args: - - --comment-style - - "|//|" - - --license-filepath - - scripts/ci/license-templates/LICENSE.txt - - --insert-license-after-regex - # We need this 'generated by' line at the top for `golines` to not format it - - '// Code generated by .*' - repo: local hooks: - id: check-min-python-version @@ -319,7 +306,7 @@ repos: ^.*reproducible_build\.yaml$| ^.*pnpm-lock\.yaml$ - repo: https://github.com/ikamensh/flynt - rev: '97be693bf18bc2f050667dd282d243e2824b81e2' # frozen: 1.0.6 + rev: 97be693bf18bc2f050667dd282d243e2824b81e2 # frozen: 1.0.6 hooks: - id: flynt name: Run flynt string format converter for Python @@ -355,7 +342,7 @@ repos: - --skip=providers/.*/src/airflow/providers/*/*.rst,providers/*/docs/changelog.rst,docs/*/commits.rst,providers/*/docs/commits.rst,providers/*/*/docs/commits.rst,docs/apache-airflow/tutorial/pipeline_example.csv,*.min.js,*.lock,INTHEWILD.md,*.svg - --exclude-file=.codespellignorelines - repo: https://github.com/woodruffw/zizmor-pre-commit - rev: 5fee7cc03a2498e0ce36a18f36dfb558a30a426c # frozen: v1.12.1 + rev: 122d24ec728f140b38330ae8b04e3c5fe8b774c5 # frozen: v1.15.2 hooks: - id: zizmor name: Run zizmor to check for github workflow syntax errors @@ -426,7 +413,7 @@ repos: types_or: [python, pyi] args: [--fix] require_serial: true - additional_dependencies: ['ruff==0.12.12'] + additional_dependencies: ['ruff==0.14.1'] exclude: ^airflow-core/tests/unit/dags/test_imports\.py$|^performance/tests/test_.*\.py$ - id: ruff-format name: Run 'ruff format' @@ -987,13 +974,6 @@ repos: files: ^scripts/ci/docker-compose/integration-.*\.yml$|^contributing-docs/testing/integration_tests\.rst$ require_serial: true pass_filenames: false - - id: update-breeze-readme-config-hash - name: Update Breeze README.md with config files hash - language: python - entry: ./scripts/ci/prek/update_breeze_config_hash.py - files: ^dev/breeze/pyproject\.toml$|^dev/breeze/README\.md$ - pass_filenames: false - require_serial: true - id: update-pyproject-toml name: Update Airflow's meta-package pyproject.toml language: python @@ -1303,36 +1283,6 @@ repos: files: ^airflow-core/src/airflow/migrations/versions/.*\.py$ exclude: ^airflow-core/src/airflow/migrations/versions/0028_3_0_0_drop_ab_user_id_foreign_key.py$ - - id: go-mockery - name: Generate mocks for go - entry: -w /src/go-sdk vektra/mockery:3 - files: ^go-sdk/ - exclude: mocks/.*\.go$ - types: [go] - pass_filenames: false - language: docker_image - - id: go-mod-tidy - name: Run go mod tidy - entry: bash -c "cd go-sdk && go mod tidy" - files: ^go-sdk/ - exclude: mocks/.*\.go$ - pass_filenames: false - language: system - - id: gofmt - name: Format go code - entry: golines --base-formatter=gofumpt --write-output --max-len=100 --chain-split-dots - additional_dependencies: [github.com/segmentio/golines@latest, mvdan.cc/gofumpt@v0.8.0] - files: ^go-sdk/ - types: [go] - language: golang - - id: gci - name: Consistent import ordering for Go files - # Since this is invoked from the root folder, not go-sdk/, gci can't auto-detect the prefix - entry: gci write --skip-generated -s standard -s default -s "prefix(github.com/apache/airflow)" - additional_dependencies: [github.com/daixiang0/gci@v0.13.6] - files: ^go-sdk/ - types: [go] - language: golang - id: ts-compile-lint-ui name: Compile / format / lint UI description: TS types generation / ESLint / Prettier new UI files @@ -1386,6 +1336,7 @@ repos: ## ADD MOST PREK HOOK ABOVE THAT LINE # The below prek hooks are those requiring CI image to be built - id: mypy-dev + stages: ['pre-push'] name: Run mypy for dev language: python entry: ./scripts/ci/prek/mypy.py @@ -1400,6 +1351,7 @@ repos: files: ^.*\.py$ require_serial: true - id: mypy-airflow-core + stages: ['pre-push'] name: Run mypy for airflow-core language: python entry: ./scripts/ci/prek/mypy.py @@ -1414,6 +1366,7 @@ repos: files: ^airflow-core/.*\.py$ require_serial: true - id: mypy-providers + stages: ['pre-push'] name: Run mypy for providers language: python entry: ./scripts/ci/prek/mypy.py @@ -1428,6 +1381,7 @@ repos: files: ^.*\.py$ require_serial: true - id: mypy-task-sdk + stages: ['pre-push'] name: Run mypy for task-sdk language: python entry: ./scripts/ci/prek/mypy.py @@ -1442,6 +1396,7 @@ repos: files: ^.*\.py$ require_serial: true - id: mypy-devel-common + stages: ['pre-push'] name: Run mypy for devel-common language: python entry: ./scripts/ci/prek/mypy.py @@ -1456,6 +1411,7 @@ repos: files: ^.*\.py$ require_serial: true - id: mypy-airflow-ctl + stages: ['pre-push'] name: Run mypy for airflow-ctl language: python entry: ./scripts/ci/prek/mypy.py @@ -1656,6 +1612,7 @@ repos: ^airflow-core/src/airflow/operators/subdag\.py$| ^airflow-core/src/airflow/plugins_manager\.py$| ^airflow-core/src/airflow/providers_manager\.py$| + ^airflow-core/src/airflow/secrets/__init__.py$| ^airflow-core/src/airflow/serialization/definitions/[_a-z]+\.py$| ^airflow-core/src/airflow/serialization/enums\.py$| ^airflow-core/src/airflow/serialization/helpers\.py$| @@ -1692,3 +1649,9 @@ repos: files: ^airflow-core/src/airflow/serialization/schema\.json$|^airflow-core/src/airflow/serialization/serialized_objects\.py$ pass_filenames: false require_serial: true + - id: check-contextmanager-class-decorators + name: Check for problematic context manager class decorators + entry: ./scripts/ci/prek/check_contextmanager_class_decorators.py + language: python + files: .*test.*\.py$ + pass_filenames: true diff --git a/Dockerfile b/Dockerfile index 2bef0b0887adf..4501fdb3a64d3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,14 +49,14 @@ ARG AIRFLOW_USER_HOME_DIR=/home/airflow ARG AIRFLOW_VERSION="3.0.6" ARG BASE_IMAGE="debian:bookworm-slim" - +ARG AIRFLOW_PYTHON_VERSION="3.12.12" # You can swap comments between those two args to test pip from the main version # When you attempt to test if the version of `pip` from specified branch works for our builds # Also use `force pip` label on your PR to swap all places we use `uv` to `pip` ARG AIRFLOW_PIP_VERSION=25.2 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main" -ARG AIRFLOW_UV_VERSION=0.8.15 +ARG AIRFLOW_UV_VERSION=0.9.4 ARG AIRFLOW_USE_UV="false" ARG UV_HTTP_TIMEOUT="300" ARG AIRFLOW_IMAGE_REPOSITORY="https://github.com/apache/airflow" @@ -1619,6 +1619,11 @@ if [[ ${AIRFLOW_COMMAND} =~ ^(scheduler|celery)$ ]] \ wait_for_celery_broker fi +if [[ "$#" -eq 0 && "${_AIRFLOW_DB_MIGRATE}" == "true" ]]; then + echo "[INFO] No commands passed and _AIRFLOW_DB_MIGRATE=true. Exiting script with code 0." + exit 0 +fi + exec "airflow" "${@}" EOF @@ -1693,14 +1698,14 @@ ARG ADDITIONAL_DEV_APT_DEPS="" ARG DEV_APT_COMMAND="" ARG ADDITIONAL_DEV_APT_COMMAND="" ARG ADDITIONAL_DEV_APT_ENV="" +ARG AIRFLOW_PYTHON_VERSION ENV DEV_APT_DEPS=${DEV_APT_DEPS} \ ADDITIONAL_DEV_APT_DEPS=${ADDITIONAL_DEV_APT_DEPS} \ DEV_APT_COMMAND=${DEV_APT_COMMAND} \ ADDITIONAL_DEV_APT_COMMAND=${ADDITIONAL_DEV_APT_COMMAND} \ - ADDITIONAL_DEV_APT_ENV=${ADDITIONAL_DEV_APT_ENV} - -ENV AIRFLOW_PYTHON_VERSION=${AIRFLOW_PYTHON_VERSION} + ADDITIONAL_DEV_APT_ENV=${ADDITIONAL_DEV_APT_ENV} \ + AIRFLOW_PYTHON_VERSION=${AIRFLOW_PYTHON_VERSION} COPY --from=scripts install_os_dependencies.sh /scripts/docker/ RUN bash /scripts/docker/install_os_dependencies.sh dev diff --git a/Dockerfile.ci b/Dockerfile.ci index b56d94bf7e8c5..74c7692031d8d 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1518,9 +1518,9 @@ ENV DEV_APT_COMMAND=${DEV_APT_COMMAND} \ ADDITIONAL_DEV_APT_DEPS=${ADDITIONAL_DEV_APT_DEPS} \ ADDITIONAL_DEV_APT_COMMAND=${ADDITIONAL_DEV_APT_COMMAND} -ARG AIRFLOW_PYTHON_VERSION="3.12.11" +ARG AIRFLOW_PYTHON_VERSION="3.12.12" ENV AIRFLOW_PYTHON_VERSION=${AIRFLOW_PYTHON_VERSION} -ENV GOLANG_MAJOR_MINOR_VERSION="1.25.1" +ENV GOLANG_MAJOR_MINOR_VERSION="1.25.3" COPY --from=scripts install_os_dependencies.sh /scripts/docker/ @@ -1655,8 +1655,8 @@ COPY --from=scripts common.sh install_packaging_tools.sh install_additional_depe # Also use `force pip` label on your PR to swap all places we use `uv` to `pip` ARG AIRFLOW_PIP_VERSION=25.2 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main" -ARG AIRFLOW_UV_VERSION=0.8.15 -ARG AIRFLOW_PREK_VERSION="0.1.6" +ARG AIRFLOW_UV_VERSION=0.9.4 +ARG AIRFLOW_PREK_VERSION="0.2.10" # UV_LINK_MODE=copy is needed since we are using cache mounted from the host ENV AIRFLOW_PIP_VERSION=${AIRFLOW_PIP_VERSION} \ diff --git a/README.md b/README.md index 1d9e08a763e97..1ac9db8ed0dc6 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ Apache Airflow version life cycle: | Version | Current Patch/Minor | State | First Release | Limited Maintenance | EOL/Terminated | |-----------|-----------------------|-----------|-----------------|-----------------------|------------------| -| 3 | 3.0.6 | Supported | Apr 22, 2025 | TBD | TBD | +| 3 | 3.1.1 | Supported | Apr 22, 2025 | TBD | TBD | | 2 | 2.11.0 | Supported | Dec 17, 2020 | Oct 22, 2025 | Apr 22, 2026 | | 1.10 | 1.10.15 | EOL | Aug 27, 2018 | Dec 17, 2020 | June 17, 2021 | | 1.9 | 1.9.0 | EOL | Jan 03, 2018 | Aug 27, 2018 | Aug 27, 2018 | diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index 97310ce20cc5d..23ea9797194de 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -24,6 +24,539 @@ .. towncrier release notes start +Airflow 3.1.0 (2025-09-25) +-------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +Human in the Loop (HITL) +"""""""""""""""""""""""" + +Airflow 3.1 introduces :doc:`Human-in-the-Loop (HITL) ` functionality that enables +workflows to pause and wait for human decision-making. This powerful feature is particularly valuable for +AI/ML workflows, content moderation, and approval processes where human judgment is essential. + +HITL tasks pause execution in a ``deferred`` state while waiting for human input via the Airflow UI. Users +with appropriate roles can see pending tasks, review context (including ``XCom`` data and ``DAG`` parameters), and +complete actions through intuitive web forms. The feature also supports API-driven interactions for custom +UIs and notification integration. + +For detailed usage instructions, see :doc:`/tutorial/hitl`. + +**Note**: HITL operators require ``apache-airflow-providers-standard`` package and Airflow 3.1+. + +Task SDK Decoupling for Independent Upgrades +""""""""""""""""""""""""""""""""""""""""""""" + +Airflow 3.1 advances the decoupling of the Task SDK from Airflow Core through +improved DAG serialization with versioned contracts. While complete code separation is planned for Airflow 3.2.0, +the serialization foundation enables independent upgrades when components are deployed separately. + +**For DAG Authors**: Import constructs from ``airflow.sdk`` namespace: + +- ``from airflow.sdk import DAG, task, asset`` +- Access to latest authoring features with forward compatibility +- Reduced dependency on server-side Airflow versions + +**For Platform Teams**: Foundation for independent upgrades: + +- Schema compliance ensures compatibility across versions +- Deployment flexibility when components are separated +- Reduced coordination overhead between development and operations teams + +For technical details on the serialization contract, see :doc:`/administration-and-deployment/dag-serialization`. + +Deadline Alerts +""""""""""""""" + +Deadline Alerts provide proactive monitoring for DAG execution by automatically triggering notifications +when time thresholds are exceeded. This helps ensure SLA compliance and timely completion of critical workflows. + +Configure deadline monitoring by specifying: + +- **Reference point**: Choose from DAG run queued time, logical date, or fixed datetime +- **Interval**: Time threshold relative to the reference point (positive or negative) +- **Callback**: Response action using Airflow Notifiers or custom functions + +Example use cases: + +- Alert if a daily ETL hasn't completed 1 hour after its scheduled time +- Notify stakeholders 30 minutes before a critical deadline +- Escalate when resource-constrained DAGs remain queued too long + +**Current Limitations**: Deadline Alerts currently support only asynchronous callbacks (``AsyncCallback``). +Support for synchronous callbacks (``SyncCallback``) is planned for a future release. + +For configuration details and examples, see :doc:`/howto/deadline-alerts`. + +.. warning:: + + Deadline Alerts are experimental in 3.1 and may change in future versions based on user feedback. + +UI Internationalization +""""""""""""""""""""""" + +Airflow 3.1 delivers comprehensive internationalization (``i18n``) support, making the web interface +accessible to users worldwide. The React-based UI now supports 17 languages with robust translation infrastructure. + +**Supported Languages**: + +- Arabic +- Catalan +- Dutch +- English +- French +- German +- Hebrew +- Hindi +- Hungarian +- Italian +- Korean +- Polish +- Portuguese +- Simplified Chinese +- Spanish +- Traditional Chinese +- Turkish + +The translation system includes automated completeness checking and clear contribution guidelines for community translators. + +React Plugin System (AIP-68) +""""""""""""""""""""""""""""" + +Airflow 3.1 introduces a modern plugin architecture enabling rich integrations through React components and +external views. This extensibility framework allows organizations to embed custom dashboards, +monitoring tools, and domain-specific interfaces directly within the Airflow UI. + +**New Plugin Capabilities**: + +- **React Apps**: Full-featured React applications integrated into Airflow navigation +- **External Views**: Embed external web applications via iframe with seamless authentication +- **Dashboard Integration**: Custom widgets and panels for operational dashboards +- **Menu Integration**: Add custom navigation items and organize tools logically + +**Developer Experience**: + +- Hot reloading during development with ``airflow-react-plugin`` dev tools +- TypeScript support and modern React patterns +- Standardized plugin loading and validation +- Comprehensive documentation and boilerplate generation + +This plugin system replaces legacy Flask-based approaches with modern web standards, improving performance, +maintainability, and user experience. + +For more details and examples, see :doc:`/howto/custom-view-plugin`. + +Enhanced UI Views and Filtering +"""""""""""""""""""""""""""""""" + +Airflow 3.1 brings significant UI improvements including rebuilt Calendar and Gantt chart views for the modern React UI, +comprehensive filtering capabilities, and a refreshed visual design system. + +**Visual Design Improvements** + +The UI now features an updated color palette leveraging Chakra UI semantic tokens, providing better consistency, +accessibility, and theme support across the interface. This modernization improves readability and creates +a more cohesive visual experience throughout Airflow. + +**Rebuilt Views and Enhanced Filtering** + +The Calendar and Gantt views from Airflow 2.x have been rebuilt for the modern React UI, along with enhanced +filtering capabilities across all views. These improvements provide better performance and a more consistent +user experience with the rest of the modern Airflow interface. + +**DAG Dashboard Organization** + +Users can now pin and favorite DAGs for better dashboard organization, making it easier to find and prioritize +frequently used workflows. This feature is particularly valuable for teams managing large numbers of DAGs, +providing quick access to critical workflows without searching through extensive DAG lists. + +Inference Execution (Synchronous DAGs) +"""""""""""""""""""""""""""""""""""""" + +Airflow 3.1 introduces a new streaming API endpoint that allows applications to watch DAG runs until completion, +enabling more responsive integration patterns for real-time and inference workflows. + +**New Streaming Endpoint**: +The ``/dags/{dag_id}/dagRuns/{dag_run_id}/wait`` endpoint repeatedly emits JSON updates at specified intervals until the DAG run reaches a finished state. + +.. code-block:: bash + + # Watch a DAG run with 2-second polling interval, including XCom results + curl -X GET "http://localhost:8080/api/v2/dags/ml_pipeline/dagRuns/manual_2024_01_15/wait?result=inference_task" \ + -H "Accept: application/x-ndjson" + +This enables use cases like: + +- **ML Inference Monitoring**: Trigger inference DAGs and wait for completion before returning results +- **Real-time Processing**: Monitor event-driven workflows with immediate response requirements +- **API Integration**: Build responsive services that react to DAG completion without polling +- **Synchronous Workflows**: Create quasi-synchronous behavior for workflows that need immediate feedback + +New Trigger Rule: ``ALL_DONE_MIN_ONE_SUCCESS`` +"""""""""""""""""""""""""""""""""""""""""""""" + +``ALL_DONE_MIN_ONE_SUCCESS``: This rule triggers when all upstream tasks are done (success, failed, or skipped) and +at least one has succeeded, filling a gap between existing trigger rules for complex workflow patterns. + +Enhanced DAG Processing Visibility +""""""""""""""""""""""""""""""""""" + +DAG parsing duration is now exposed in the UI, providing better visibility into DAG processing +performance and helping identify parsing bottlenecks. This information is displayed alongside +other DAG metadata to assist with performance optimization. + +Python 3.13 support added & 3.9 support removed +""""""""""""""""""""""""""""""""""""""""""""""" + +Support for Python 3.9 has been removed, as it has reached end-of-life. +Airflow 3.1.0 requires Python 3.10, 3.11, 3.12 or 3.13. + +Configuration Changes and Cleanup +"""""""""""""""""""""""""""""""""" + +**Webserver Configuration Reorganization** + +Several webserver configuration options have been moved to the ``api`` section for better organization: + +- ``[webserver] log_fetch_timeout_sec`` → ``[api] log_fetch_timeout_sec`` +- ``[webserver] hide_paused_dags_by_default`` → ``[api] hide_paused_dags_by_default`` +- ``[webserver] page_size`` → ``[api] page_size`` +- ``[webserver] default_wrap`` → ``[api] default_wrap`` +- ``[webserver] require_confirmation_dag_change`` → ``[api] require_confirmation_dag_change`` +- ``[webserver] auto_refresh_interval`` → ``[api] auto_refresh_interval`` + +Unused configuration options have been removed: + +- ``[webserver] instance_name_has_markup`` +- ``[webserver] warn_deployment_exposure`` + +**API Server Logging Configuration** + +The API server configuration option ``[api] access_logfile`` has been replaced with ``[api] log_config`` to align with uvicorn's logging configuration. The new option accepts a path to a logging configuration file compatible with ``logging.config.fileConfig``, providing more flexible logging configuration. + +**Security Improvement: XCom Deserialization** + +The ``enable_xcom_deserialize_support`` configuration option has been removed as a security improvement. This option previously allowed deserializing unknown objects in the API, which posed a security risk due to potential remote code execution vulnerabilities when deserializing arbitrary Python objects. + +The XCom display improvements now handle showing non-native XComs (like custom objects, Assets, datetime objects) in a human-readable way through safer methods that don't require deserializing unknown objects in the API server. This provides better user experience when viewing XCom data in the Airflow UI while eliminating the security risk. + +API Changes +""""""""""" + +**Asset API Key Rename** + +The ``consuming_dags`` key in asset API responses has been renamed to ``scheduled_dags`` to better reflect its purpose. This key contains only DAGs that use the asset in their ``schedule`` argument, not all DAGs that technically use the asset. + +Task SDK Interface Changes +"""""""""""""""""""""""""" + +**Removed Functions** + +The following functions have been removed from the task-sdk (``airflow.sdk.definitions.taskgroup``) and moved to server-side API services: + +- ``get_task_group_children_getter`` +- ``task_group_to_dict`` + +These functions are now internal to Airflow's API layer and should not be imported directly by users. + +Reduce default API server workers to 1 +"""""""""""""""""""""""""""""""""""""" + +The default number of API server workers (``[api] workers``) has been reduced from ``4`` to ``1``. + +With FastAPI, sync code runs in external thread pools, making multiple workers within a single +process less necessary. Additionally, with uvicorn's spawn behavior instead of fork, there is +no shared copy-on-write memory between workers, so horizontal scaling with multiple API server +instances is now the recommended approach for better resource utilization and fault isolation. + +A good starting point for the number of workers is to set it to the number of CPU cores available. +If you do have multiple CPU cores available for the API server, consider deploying multiple API +server instances instead of increasing the number of workers. + +Airflow now uses `structlog `_ everywhere +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Most users should not notice the difference, but it is now possible to emit structured log key/value pairs from tasks. + +If your class subclasses ``LoggingMixin`` (which all ``BaseHook`` and ``BaseOperator`` do -- i.e. all hooks and +operators) then ``self.log`` is now a ``_. + +The advantage of using structured logging is that it is much easier to find specific information about log +message, especially when using a central store such as ``OpenSearch``/``Elastic``/``Splunk`` etc. +You don't have to make any changes, but you can now take advantage of this. + +.. code-block:: python + + # Inside a Task/Hook etc. + + # Before: + # self.log.info("Registering adapter %r", item.name) + # Now: + self.log.info("Registering adapter", name=item.name) + +This will produce a log that (in the UI) will look something like this:: + + [2025-09-16 10:36:13] INFO - Registering adapter name="adapter1" + +or in JSON (i.e. the log files on disk):: + + {"timestamp": "2025-09-16T10:36:13Z", "log_level": "info", "event": "Registering adapter", "name": "adapter1"} + +You can also use ``structlog`` loggers at the top level of modules etc, and ``stdlib`` both continue to work: + +.. code-block:: python + + import logging + import structlog + + log1 = logging.getLogger(__name__) + log2 = strcutlog.get_logger(__name__) + + log1.info("Loading something from %s", __name__) + log2.info("Loading something", source=__name__) + +(You can't add arbitrary key/value pairs to ``stdlib``, but the normal ``percent-formatter`` approaches still work fine.) + +Serialization Interface Changes +""""""""""""""""""""""""""""""" + +The deserializer interface in ``airflow.serialization.serializers`` has changed for improved security. + +**Before 3.1.0:** + +``def deserialize(classname: str, version: int, data: Any)`` + +**Starting with 3.1.0:** + +``def deserialize(cls: type, version: int, data: Any)`` + +The class loading is now handled in ``serde.py``, and the deserializer receives the loaded class directly rather than a ``classname`` string. +This update avoids the use of ``import_string`` in the deserializer, making deserialization more secure. + +New Features +^^^^^^^^^^^^ + +- Add Calendar and Gantt chart views to modern React UI with enhanced filtering (#54252, #51667) +- Add Python 3.13 support for Airflow runtime and dependencies (#46891) +- Add ``SQLAlchemy 2.0`` support with various compatibility fixes for ``Python 3.13`` (#52233, #52518, #54940) +- Add support for the ``psycopg3`` postgres driver (#52976) +- Add ability to track & display user who triggers DAG runs (#51738, #53510, #54164, #55112) +- Add toggle for log grouping in task log viewer for better organization (#51146) +- Add tag filtering improvements with Any/All selection options (#51162) +- Add comprehensive filtering for DAG runs, task instances, and audit logs (#53652, #54210, #55082) +- Add ``XCom`` browsing with filtering and improved navigation (#54049) +- Add bulk task instance actions and deletion endpoints (#50443, #50165, #50235) +- Add DAG run deletion functionality through UI (#50368) +- Add test connection button for connection validation (#51055) +- Add hyperlink support for URLs in XCom values (#54288) +- Add pool column to task instances list and improve pool integration (#51185, #51031) +- Add drag-and-drop log grouping and improved log visualization (#51146) +- Add color support for XCom JSON display (#51323) +- Add configuration column to DAG runs page (#51270) +- Add enhanced note visibility and management in task headers (#51764, #54163) +- Introduce React plugin system (AIP-68) for modern UI extensions (#52255) +- Add support for external view plugins via iframe integration (#51003, #51889) +- Add dashboard integration capabilities for custom React apps (#54131, #54144) +- Add comprehensive plugin development tools and documentation (#53643) +- Implement complete HITL operator suite (``HITLOperator``, ``ApprovalOperator``, ``HITLEntryOperator``) for human decision workflows (#52868) +- Add HITL UI integration with role-based access and form handling (#53035) +- Add HITL API endpoints with filtering and query support (#53376, #53923) +- Add HITL utility functions for generating URLs to required actions page (#54827) +- Improve HITL user experience with bug fixes, UI enhancements, and data model consistency (#55463, #55539, #55575, #55546, #55543, #55536, #55535) +- Add ordering and filtering support for HITL details endpoints (#55217) +- Add "No Response Received" required action state (#55149) +- Add operator filter for HITL task instances (#54773) +- Implement deadline alert system for proactive DAG monitoring (AIP-86) (#53951, #53903, #53201, #55086) +- Add configurable reference points and notification callbacks (#50677, #50093) +- Add deadline calculation and tracking in DAG execution lifecycle (#51638, #50925) +- Add comprehensive UI translation support for 16 languages (#51266, #51038, #51219, #50929, #50981, #51793 and more) +- Add right-to-left (RTL) layout support for Arabic and Hebrew (#51376) +- Add language selection interface and browser preference detection (#51369) +- Add translation completeness validation and automated checks (#51166, #51131) +- Add calendar data API endpoints for DAG execution visualization (#52748) +- Add endpoint to watch DAG runs until completion (#51920, #53346) +- Add DAG run ID pattern search functionality (#52437) +- Add multi-sorting capabilities for improved data navigation (#53408) +- Add bulk connection deletion API and UI (#51201) +- Add task group detail pages across DAG runs (#50412, #50309) +- Add asset event tracking with last event timestamps (#50060, #50279) +- Add ``has_import_errors`` filter to Core API GET ``/dags`` endpoint (#54563) +- Add dag_version filter to get_dag_runs endpoint (#54882) +- Add pattern search for event log endpoint (#55114) +- Add dry_run support with consistent audit log handling (#55116) +- Add utility functions for generic filter counting (#54817) +- Add keyboard navigation for Grid view interface (#51784) +- Add improved error handling for plugin import failures (#49643) +- Add plugin validation in ``/plugins`` API with warnings for invalid plugins (#55673) +- Improve accessibility for screen readers and assistive technologies with proper language detection (#55839) +- Add enhanced variable management with upsert operations (#48547) +- Add favorites/pinning support for DAG dashboard organization (#51264) +- Add system theme support with automatic OS preference detection (#52649) +- Add hotkey shortcut to toggle between Grid and Graph views (#54667) +- Add queued DAGs filter button to DAGs page (#55052) +- Add DAG parsing duration visibility in UI (#54752) +- Add owner links support in DAG Header UI for better navigation (#50627) +- Add ``dag_display_name`` aliases for improved API consistency (#50332, #50065, #50014, #49933, #49641) +- Add enhanced search capabilities with SearchParamsKeys constants (#55218) +- Add ALL_DONE_MIN_ONE_SUCCESS trigger rule for flexible task dependencies (#53959) +- Add fail_when_dag_is_paused parameter to TriggerDagRunOperator for better control (#48214) +- Add ``XCom`` validation to prevent empty keys in ``XCom.set()`` and ``XCom.get()`` operations (#46929) +- Add collapsible plugin menu when multiple plugins are present (#55265) +- Add external view plugin categories (admin, browse, docs, user) (#52737) +- Add iframe plugins integration to DAG pages (#52795) +- Add plugin error display in UI with comprehensive error handling (#49643, #49436) +- Add collapsible failed task logs to prevent React error overflow (#54377) +- Add dynamic legend system for calendar view (#55155) +- Add React UI for Edge functionality (#53563) +- Add pending actions display to DAG UI (#55041) +- Add description field for filter parameters (#54903) +- Add Catalan language support to Airflow UI (#55013) +- Add Hungarian language support to Airflow UI (#54716) +- Add map_index validation in categorize_task_instances (#54791) +- Add Grid view UX improvements (#54846) +- Add HITL UX improvements for better user experience (#54990) +- Add async support for Notifiers (AIP-86) (#53831) +- Add filtering capabilities for tasks view (#54484) +- Add asset-based filtering support to DAG API endpoint (#54263) +- Add iframe plugins to navigation (#51706) +- Add RTL (right-to-left) layout support for Arabic and Hebrew (#51376) +- Add test connection button to UI (#51055) +- Add task instance bulk actions endpoint (#50443) +- Add connection bulk deletion functionality (#51201) +- Add pool column to task instances list (#51185) +- Add ``iframe_views`` to backend plugin support (#51003) +- Add keyboard shortcuts to clear and mark state for task instances and DAG runs (#50885) +- Add deadline relationship to DAG runs and deadline model (#50925, #50093) +- Add DAG run deletion UI (#50368) +- Add task instance deletion UI and endpoint (#50235, #50165) +- Switch all airflow logging to structlog (#52651, #55434, #55431, #55638) +- Add Filter Bar to Audit Log (#55487) +- Add Filters UI for Asset View (#54640) +- Update color palette and leverage Chakra semantic tokens (#53981, #55739) +- Improve calendar view UI with enhanced tooltips and visual fixes (#55476) + +Bug Fixes +^^^^^^^^^ + +- Fix DAG list filtering to include ``QUEUED`` runs with null ``start_date`` (#52668) +- Fix XCom deletion failure for mapped task instances through bulk deletion API (#51850) +- Fix XCom deletion failure for mapped task instances (#54954) +- Fix task timeout handling within task SDK (#54089) +- Fix task instance tries API duplicate entries (#50597) +- Fix connection validation and type checking during construction (#54759) +- Fix mapped task instance index display in Task Instances tab (#55363) +- Fix Gantt chart state mismatch with Grid view (#55300) +- Fix Gantt chart status color display issues (#55296) +- Fix XCom mapping for dynamically-mapped task groups (#51556) +- Fix missing ``ti_successes`` and related metrics in Airflow 3.0 Task SDK (#55322) +- Fix bulk operation permissions for connection, pool and variable (#55278) +- Fix ``clearTaskInstances`` API: Restore ``include_past``/``future`` support on UI (#54416) +- Fix migration when XCom has NaN values (#53812) +- Fix HITL related UI schema generated by prek hooks (#55204) +- Fix consistent no-log handling for tasks with try_number=0 in API and UI (#55035) +- Fix timezone conversion in datetime trigger parameters (#54593) +- Fix audit log payload for DAG pause/unpause actions (#55091) +- Fix pushing None as an XCom value (#55080) +- Fix scheduler processing of cleared running tasks stuck in RESTARTING state (#55084) +- Fix XCom deletion failure for mapped task instances (#54954) +- Fix outgoing graph edges should exit opposite of incoming edges (#54789) +- Fix external links in Navigation buttons (#52220) +- Fix Error when viewing DAG details of a no longer configured bundle (#52086) +- Fix compatibility with new numpy and pandas versions (#52071) +- Fix connection recovery from URI when host has protocol (#51953) +- Fix last DAG run not showing on DAG listing (#51115) +- Fix task instance tries API returning duplicate entries (#50597) +- Fix Graph view vanishing and loading issues (#53886, #54756) +- Fix rendered template display formatting for better readability (#53657) +- Fix Grid view expand/collapse button functionality (#54257) +- Fix tooltip visibility and positioning issues (#53913) +- Fix grid keyboard navigation focus management (#54271) +- Fix plugin registration for invalid objects and middleware registration (#55264, #55399) +- Fix external links for plugins with undefined URL routes (#55221) +- Fix language display consistency and flag representation (#51560, #51177) +- Fix RTL layout rendering for Arabic and Hebrew interfaces (#51853) +- Fix graph export cropping when view is partial (#55012) +- Fix log viewer "Toggle Source" to hide only source fields, not all structured log fields (#55474) +- Output on stdout/stderr from within tasks is now filterable in the Sources list in the UI log view (#55508) +- Redact JWT tokens in task logs (#55499) +- Fix grid view to handle long task name (#55332) +- Allow slash characters in Variable keys similar to Airflow 2.x (#55324) +- Fix Grid cache invalidation for multi-run task operations (#55504) +- Fix Gantt chart rendering issues (#55554) +- Fix ``XCom`` access in DAG processor callbacks for notifiers (#55542) +- Fix alignment of arrows in RTL mode for right-to-left languages (#55619) +- Fix connection form extras not inferring correct type in UI (#55492) +- Fix incorrect log timestamps in UI when ``default_timezone`` is not UTC (#54431) +- Fix handling of priority_weight for DAG processor callbacks (#55436) +- Fix pointless requests from Gantt view when there is no Run ID (#55668) +- Ensure filename and ``lineno`` of logger calls are present in Task Logs (#55581) +- Fix DAG disappearing after callback execution in stale detection (#55698) +- Fix DB downgrade to Airflow 2 when fab tables exists (#55738) +- Fix UI stats endpoint causing dashboard loading issues (#55733) +- Fix unintended console output when DAG not found in ``serialized_dag`` table (#54972) +- Fix scheduler handling of orphaned tasks from Airflow 2 during upgrade (#55848) +- Fix logging format to respect existing configuration during upgrade to prevent unexpected log format changes (#55824) +- Fix Grid view crashes when DAG version information is missing (#55771) +- Fix compatibility for custom triggers migrating from Airflow 2.x that use synchronous connection calls (#55799) +- Fix DAG runs triggered from UI incorrectly marked as REST API triggers instead of UI triggers (#54650) +- Fix XCom API responses failing when encountering non-serializable objects by falling back to string representation (#55880) +- Fix asset queue display in UI showing incorrect timestamps for deleted queue events (#54652) +- Fix SQLite database migrations failing due to foreign key constraint handling (#55883) +- Fix DAG deserialization failure when using non-default weight_rule values like 'absolute' (#55906) +- Fix async connection retrieval in triggerer context preventing event loop blocking (#55812) +- Fix Airflow downgrade compatibility by handling serialized DAG format conversion from v3 to v2 (#55975) +- Fix 'All Log Levels' filter not working in task log viewer (#55851) +- Fix Grid view scrollbar overlapping issues on Firefox browser (#55960) +- Fix Gantt chart misalignment with Grid view layout (#55995) +- Fix Grid view task names being extremely collapsed and unreadable when displaying many DAG runs (#55997) +- Fix ``LocalExecutor`` race condition where tasks could start before database state was committed (#56010) + +Miscellaneous +^^^^^^^^^^^^^ + +- Move secrets masker to shared distribution for better modularity (#54449) +- Move email notifications from scheduler to DAG processor for better architecture (#55238) +- Add graph UI load optimization with latest run info endpoint (#53429) +- Optimize UI bundle size by moving translations to dynamic loading (#51735) +- Relocate Task SDK components for improved separation (#55174, #54795) +- Refactor trigger rule utilities and weight rule consolidation (#54797, #53393) +- Remove deprecated Airflow 2.x modules and legacy imports (#50482) +- Clean up unused code and improve module organization (#52176, #52173, #53031) +- Add SQLAlchemy 2.0 CI support for future compatibility (#52233) +- Improve test fixtures and SDK communication testing (#54795, #50603) +- Add translation completeness linting and validation tools (#51166) +- Upgrade to latest versions of important dependencies (#55350) +- Move webserver configuration options to API section (#50693, #50656) +- Improve DAG bundle handling and versioning support (#47592) +- Add database management CLI tools for external database operations (#50657) +- Add comprehensive HITL operator documentation and examples (#54618) +- Add guards for registering middlewares from plugins (#55399) +- Optimize Gantt group expansion with de-bouncing and deferred rendering (#55334) +- Differentiate between triggers and watchers currently running for better visibility (#55376) +- Removed unused config: ``dag_stale_not_seen_duration`` (#55601, #55684) +- Update UI's query client strategy for improved performance (#55528) +- Unify datetime format across the UI for consistency (#55572) +- Mark React Apps as Experimental for Airflow 3.1 release (#55478) +- Improve OOM error messaging for clearer task failure diagnosis (#55602) +- Display responder username for better audit trail in HITL workflows (#55509) +- The constraint file do not contain developer dependencies anymore (#53631) +- Add hyperlinks to ``dag_id`` column in DAG Runs and Task Instances pages for better navigation (#55648) +- Add responsive web design (RWD) support to Grid view (#55745) + +Doc Only Changes +^^^^^^^^^^^^^^^^ + +- Add comprehensive Human-in-the-Loop operator tutorial and examples (#54618) +- Add deadline alerts configuration and usage documentation (#53727) +- Make term Dag consistent in docs task-sdk (#55100) +- Add migration guide for upgrading from legacy SLA functionality to deadline alerts (#55743) +- Add DAG bundles triggerer limitation documentation (#55232) +- Add deadline alerts usage guides and best practices (#53727) +- Remove ``--preview`` flag from ``ruff check`` instructions for Airflow 3 upgrade path (#55516) +- Add documentation for context parameter (#55377) + Airflow 3.0.6 (2025-08-29) -------------------------- @@ -332,6 +865,7 @@ Bug Fixes - Fix OpenAPI schema for ``get_log`` API (#50547) - Remove ``logical_date`` check when validating inlets and outlets (#51464) - Guard ``ti`` update state and set task to fail if exception encountered (#51295) +- Fix task log URL generation with various ``base_url`` formats (#55699) Miscellaneous """"""""""""" @@ -692,7 +1226,7 @@ simplify onboarding: - ``catchup_by_default`` is now set to ``False`` by default. DAGs will not automatically backfill unless explicitly configured to do so. - ``create_cron_data_intervals`` is now set to ``False`` by default. As a result, cron expressions will be interpreted using the ``CronTriggerTimetable`` instead of the legacy ``CronDataIntervalTimetable``. -- ``SimpleAuthManager`` is now the default ``auth_manager``. To continue using Flask AppBuilder-based authentication, install the ``apache-airflow-providers-flask-appbuilder`` provider and explicitly set ``auth_manager = airflow.providers.fab.auth_manager.FabAuthManager``. +- ``SimpleAuthManager`` is now the default ``auth_manager``. To continue using Flask AppBuilder-based authentication, install the ``apache-airflow-providers-fab`` provider and explicitly set ``auth_manager = airflow.providers.fab.auth_manager.FabAuthManager``. These changes represent the most significant evolution of the Airflow platform since the release of 2.0 — setting the stage for more scalable, event-driven, and language-agnostic orchestration in the years ahead. diff --git a/airflow-core/docs/administration-and-deployment/dag-serialization.rst b/airflow-core/docs/administration-and-deployment/dag-serialization.rst index 89384f3436b89..986821d7e2b28 100644 --- a/airflow-core/docs/administration-and-deployment/dag-serialization.rst +++ b/airflow-core/docs/administration-and-deployment/dag-serialization.rst @@ -153,7 +153,7 @@ Serialized Dags now include a ``client_defaults`` section that contains common d .. code-block:: json { - "__version": 2, + "__version": 3, "client_defaults": { "tasks": { "retry_delay": 300.0, diff --git a/airflow-core/docs/administration-and-deployment/plugins.rst b/airflow-core/docs/administration-and-deployment/plugins.rst index a93eb48ffdbd3..0e50686cd53f6 100644 --- a/airflow-core/docs/administration-and-deployment/plugins.rst +++ b/airflow-core/docs/administration-and-deployment/plugins.rst @@ -111,6 +111,8 @@ looks like: # A list of dictionaries containing external views and some metadata. See the example below. external_views = [] # A list of dictionaries containing react apps and some metadata. See the example below. + # Note: React apps are only supported in Airflow 3.1 and later. + # Note: The React app integration is experimental and interfaces might change in future versions. Particularly, dependency and state interactions between the UI and plugins may need to be refactored for more complex plugin apps. react_apps = [] # A callback to perform actions when Airflow starts and the plugin is loaded. @@ -218,6 +220,7 @@ definitions in Airflow. "category": "browse", } + # Note: The React app integration is experimental and interfaces might change in future versions. react_app_with_metadata = { # Name of the React app, this will be displayed in the UI. "name": "Name of the React App", diff --git a/airflow-core/docs/authoring-and-scheduling/asset-scheduling.rst b/airflow-core/docs/authoring-and-scheduling/asset-scheduling.rst index 51ae64c62c7a5..4feaf7e24a97c 100644 --- a/airflow-core/docs/authoring-and-scheduling/asset-scheduling.rst +++ b/airflow-core/docs/authoring-and-scheduling/asset-scheduling.rst @@ -152,16 +152,35 @@ Fetching information from a triggering asset event A triggered Dag can fetch information from the asset that triggered it using the ``triggering_asset_events`` template or parameter. See more at :ref:`templates-ref`. -Example: +The ``triggering_asset_events`` is a dictionary that looks like this: .. code-block:: python - example_snowflake_asset = Asset("snowflake://my_db/my_schema/my_table") + { + Asset("s3://asset-bucket/example.csv"): [ + AssetEvent(uri="s3://asset-bucket/example.csv", source_dag_run=DagRun(...), ...), + ..., + ], + Asset("s3://another-bucket/another.csv"): [ + AssetEvent(uri="s3://another-bucket/another.csv", source_dag_run=DagRun(...), ...), + ..., + ], + } - with DAG(dag_id="load_snowflake_data", schedule="@hourly", ...): - SQLExecuteQueryOperator( - task_id="load", conn_id="snowflake_default", outlets=[example_snowflake_asset], ... - ) +You can access this information in your tasks using Jinja templating or directly in Python functions. + +Accessing triggering asset events with Jinja +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can use Jinja templating to pass information from the triggering asset events to your operators. + +**Example: Single Triggering Asset** + +If your DAG is triggered by a single asset, you can access its information like this: + +.. code-block:: python + + example_snowflake_asset = Asset("snowflake://my_db/my_schema/my_table") with DAG(dag_id="query_snowflake_data", schedule=[example_snowflake_asset], ...): SQLExecuteQueryOperator( @@ -175,13 +194,58 @@ Example: """, ) - @task - def print_triggering_asset_events(triggering_asset_events=None): - for asset, asset_list in triggering_asset_events.items(): - print(asset, asset_list) - print(asset_list[0].source_dag_run.dag_id) +In this example, ``triggering_asset_events.values() | first | first`` does the following: +1. ``triggering_asset_events.values()``: Gets a list of all lists of asset events. +2. ``| first``: Gets the first list of asset events (since we only have one triggering asset). +3. ``| first``: Gets the first ``AssetEvent`` from that list. + +**Example: Multiple Triggering Assets** + +When your DAG is triggered by multiple assets, you can iterate through them in your Jinja template. + +.. code-block:: python + + with DAG(dag_id="process_assets", schedule=[asset1, asset2], ...): + BashOperator( + task_id="process", + bash_command=""" + {% for asset_uri, events in triggering_asset_events.items() %} + echo "Processing asset: {{ asset_uri }}" + {% for event in events %} + echo " Triggered by DAG: {{ event.source_dag_run.dag_id }}" + echo " Data interval start: {{ event.source_dag_run.data_interval_start }}" + echo " Data interval end: {{ event.source_dag_run.data_interval_end }}" + {% endfor %} + {% endfor %} + """, + ) + + +Accessing triggering asset events in Python +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also access the ``triggering_asset_events`` directly in a Python function by passing it as a parameter. + +.. code-block:: python + + @task + def print_triggering_asset_events(triggering_asset_events=None): + if triggering_asset_events: + for asset, asset_events in triggering_asset_events.items(): + print(f"Asset: {asset.uri}") + for event in asset_events: + print(f" - Triggered by DAG run: {event.source_dag_run.dag_id}") + print( + f" Data interval: {event.source_dag_run.data_interval_start} to {event.source_dag_run.data_interval_end}" + ) + print(f" Run ID: {event.source_dag_run.run_id}") + print(f" Timestamp: {event.timestamp}") + + + print_triggering_asset_events() - print_triggering_asset_events() +.. note:: + When a DAG is scheduled by multiple assets, there may be multiple asset events for each asset. The logic for handling these events can be complex. It is up to the DAG author to decide how to process them. For example, you might want to process all new data since the last run, or you might want to process each triggering event individually. Note that this example is using `(.values() | first | first) `_ to fetch the first of one asset given to the Dag, and the first of one AssetEvent for that asset. An implementation can be quite complex if you diff --git a/airflow-core/docs/authoring-and-scheduling/serializers.rst b/airflow-core/docs/authoring-and-scheduling/serializers.rst index 433485bb3b8af..fb19a111d9177 100644 --- a/airflow-core/docs/authoring-and-scheduling/serializers.rst +++ b/airflow-core/docs/authoring-and-scheduling/serializers.rst @@ -74,8 +74,7 @@ Airflow Object @staticmethod def deserialize(data: dict[str, Any], version: int): - f = Foo(a=data["a"]) - f.b = data["b"] + f = Foo(a=data["a"], v=data["b"]) return f @@ -86,17 +85,18 @@ Registered from __future__ import annotations - from decimal import Decimal from typing import TYPE_CHECKING from airflow.utils.module_loading import qualname if TYPE_CHECKING: + import decimal + from airflow.serialization.serde import U serializers = [ - Decimal + "decimal.Decimal" ] # this can be a type or a fully qualified str. Str can be used to prevent circular imports deserializers = serializers # in some cases you might not have a deserializer (e.g. k8s pod) @@ -105,25 +105,28 @@ Registered # the serializer expects output, classname, version, is_serialized? def serialize(o: object) -> tuple[U, str, int, bool]: - if isinstance(o, Decimal): - name = qualname(o) - _, _, exponent = o.as_tuple() - if exponent >= 0: # No digits after the decimal point. - return int(o), name, __version__, True - # Technically lossy due to floating point errors, but the best we - # can do without implementing a custom encode function. - return float(o), name, __version__, True + from decimal import Decimal - return "", "", 0, False + if not isinstance(o, Decimal): + return "", "", 0, False + name = qualname(o) + _, _, exponent = o.as_tuple() + if isinstance(exponent, int) and exponent >= 0: # No digits after the decimal point. + return int(o), name, __version__, True + # Technically lossy due to floating point errors, but the best we + # can do without implementing a custom encode function. + return float(o), name, __version__, True # the deserializer sanitizes the data for you, so you do not need to deserialize values yourself - def deserialize(classname: str, version: int, data: object) -> Decimal: + def deserialize(cls: type, version: int, data: object) -> Decimal: + from decimal import Decimal + # always check version compatibility if version > __version__: - raise TypeError(f"serialized {version} of {classname} > {__version__}") + raise TypeError(f"serialized {version} of {qualname(cls)} > {__version__}") - if classname != qualname(Decimal): - raise TypeError(f"{classname} != {qualname(Decimal)}") + if cls is not Decimal: + raise TypeError(f"do not know how to deserialize {qualname(cls)}") return Decimal(str(data)) diff --git a/airflow-core/docs/best-practices.rst b/airflow-core/docs/best-practices.rst index 5c8fdf43dc6a7..183fe880c41c2 100644 --- a/airflow-core/docs/best-practices.rst +++ b/airflow-core/docs/best-practices.rst @@ -310,13 +310,13 @@ Installing and Using ruff .. code-block:: bash - pip install "ruff>=0.12.12" + pip install "ruff>=0.14.1" 2. **Running ruff**: Execute ``ruff`` to check your Dags for potential issues: .. code-block:: bash - ruff check dags/ --select AIR3 --preview + ruff check dags/ --select AIR3 This command will analyze your Dags located in the ``dags/`` directory and report any issues related to the specified rules. @@ -347,8 +347,6 @@ Running ``ruff`` will produce: By integrating ``ruff`` into your development workflow, you can proactively address deprecations and maintain code quality, facilitating smoother transitions between Airflow versions. -For more information on ``ruff`` and its integration with Airflow, refer to the `official Airflow documentation `_. - .. _best_practices/dynamic_dag_generation: Dynamic Dag Generation diff --git a/airflow-core/docs/conf.py b/airflow-core/docs/conf.py index c9886a172b328..bd63dd2771fc7 100644 --- a/airflow-core/docs/conf.py +++ b/airflow-core/docs/conf.py @@ -27,12 +27,6 @@ from pathlib import Path from typing import Any -from packaging.version import Version, parse as parse_version - -import airflow -from airflow.api_fastapi.auth.managers.simple.openapi import __file__ as sam_openapi_file -from airflow.api_fastapi.core_api.openapi import __file__ as main_openapi_file -from airflow.configuration import retrieve_configuration_description from docs.utils.conf_constants import ( AIRFLOW_CORE_DOC_STATIC_PATH, AIRFLOW_CORE_DOCKER_COMPOSE_PATH, @@ -61,6 +55,12 @@ get_rst_filepath_from_path, skip_util_classes_extension, ) +from packaging.version import Version, parse as parse_version + +import airflow +from airflow.api_fastapi.auth.managers.simple.openapi import __file__ as sam_openapi_file +from airflow.api_fastapi.core_api.openapi import __file__ as main_openapi_file +from airflow.configuration import retrieve_configuration_description PACKAGE_NAME = "apache-airflow" PACKAGE_VERSION = airflow.__version__ diff --git a/airflow-core/docs/core-concepts/auth-manager/index.rst b/airflow-core/docs/core-concepts/auth-manager/index.rst index fffc89fc4d572..5ace2150eb87d 100644 --- a/airflow-core/docs/core-concepts/auth-manager/index.rst +++ b/airflow-core/docs/core-concepts/auth-manager/index.rst @@ -166,7 +166,7 @@ cookie named ``_token`` before redirecting to the Airflow UI. The Airflow UI wil response = RedirectResponse(url="/") secure = request.base_url.scheme == "https" or bool(conf.get("api", "ssl_cert", fallback="")) - response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure) + response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure, httponly=True) return response .. note:: diff --git a/airflow-core/docs/core-concepts/dag-run.rst b/airflow-core/docs/core-concepts/dag-run.rst index f524515e3b179..e1e54d8aa7bfe 100644 --- a/airflow-core/docs/core-concepts/dag-run.rst +++ b/airflow-core/docs/core-concepts/dag-run.rst @@ -278,6 +278,28 @@ Example of a parameterized Dag: **Note**: The parameters from ``dag_run.conf`` can only be used in a template field of an operator. +Wait for a Dag Run +------------------ + +Airflow provides an experimental API to **wait for a Dag run to complete**. This is particularly useful when integrating Airflow into external systems or automation pipelines that need to pause execution until a Dag finishes. + +The endpoint blocks (by polling) until the specified Dag run reaches a terminal state: ``success``, ``failed``, or ``canceled``. + +This endpoint streams responses using the **NDJSON (Newline-Delimited JSON)** format. Each line in the response is a JSON object representing the state of the Dag run at that moment. + +For example: + +.. code-block:: none + + {"state": "running"} + {"state": "success", "results": {"op": 42}} + +This allows clients to monitor the run in real time and optionally collect XCom results from specific tasks. + +.. note:: + + This feature is **experimental** and may change or be removed in future Airflow versions. + Using CLI ^^^^^^^^^^^ diff --git a/airflow-core/docs/core-concepts/dags.rst b/airflow-core/docs/core-concepts/dags.rst index 04551838bed44..101977b3aa227 100644 --- a/airflow-core/docs/core-concepts/dags.rst +++ b/airflow-core/docs/core-concepts/dags.rst @@ -857,8 +857,8 @@ Here's a simple example using the existing email Notifier: interval=timedelta(minutes=30), callback=SmtpNotifier( to="team@example.com", - subject="[Alert] Dag {{ dag.dag_id }} exceeded time threshold", - html_content="The Dag has been running for more than 30 minutes since being queued.", + subject="🚨 Dag {{ dag_run.dag_id }} missed deadline at {{ deadline.deadline_time }}", + html_content="The Dag Run {{ dag_run.dag_run_id }} has been running for more than 30 minutes since being queued.", ), ), ): diff --git a/airflow-core/docs/core-concepts/operators.rst b/airflow-core/docs/core-concepts/operators.rst index 256613537b4c7..2e8b82713d3d1 100644 --- a/airflow-core/docs/core-concepts/operators.rst +++ b/airflow-core/docs/core-concepts/operators.rst @@ -84,11 +84,25 @@ Here, ``{{ ds }}`` is a templated variable, and because the ``env`` parameter of You can also pass in a callable instead when Python is more readable than a Jinja template. The callable must accept two named arguments ``context`` and ``jinja_env``: +The ``context`` parameter is an Airflow's ``Context`` object that provides runtime information for the current task execution. Its contents can be accessed with Python's standard `dict syntax `_. It includes all variables available in Jinja templates and is read-only from the perspective of template rendering - while you can access and use its values, modifications won't affect the task execution environment. + +For a complete list of available context variables see :ref:`Templates reference `. + .. code-block:: python - def build_complex_command(context, jinja_env): + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + import jinja2 + from airflow.sdk import Context + + + def build_complex_command(context: Context, jinja_env: jinja2.Environment) -> str: + # Access runtime information from the context dictionary + task_id = context["ti"].task_id + execution_date = context["ds"] with open("file.csv") as f: - return do_complex_things(f) + return do_complex_things(f, task_id, execution_date) t = BashOperator( @@ -101,7 +115,7 @@ Since each template field is only rendered once, the callable's return value wil .. code-block:: python - def build_complex_command(context, jinja_env): + def build_complex_command(context: Context, jinja_env: jinja2.Environment) -> str: with open("file.csv") as f: data = do_complex_things(f) return context["task"].render_template(data, context, jinja_env) diff --git a/airflow-core/docs/core-concepts/overview.rst b/airflow-core/docs/core-concepts/overview.rst index 9b80ff331b483..f2d4b44e07f33 100644 --- a/airflow-core/docs/core-concepts/overview.rst +++ b/airflow-core/docs/core-concepts/overview.rst @@ -244,6 +244,6 @@ User interface Airflow comes with a user interface that lets you see what Dags and their tasks are doing, trigger runs of Dags, view logs, and do some limited debugging and resolution of problems with your Dags. -.. image:: ../img/ui-dark/dags.png +.. image:: ../img/ui-light/dags.png It's generally the best way to see the status of your Airflow installation as a whole, as well as diving into individual Dags to see their layout, the status of each task, and the logs from each task. diff --git a/airflow-core/docs/faq.rst b/airflow-core/docs/faq.rst index 00673a8e5f7f3..f57f2ddebf22c 100644 --- a/airflow-core/docs/faq.rst +++ b/airflow-core/docs/faq.rst @@ -227,7 +227,6 @@ There are several reasons why Dags might disappear from the UI. Common causes in * :ref:`config:dag_processor__file_parsing_sort_mode` - Ensure sorting method matches your sync strategy * :ref:`config:dag_processor__parsing_processes` - Number of parallel parsers * :ref:`config:scheduler__parsing_cleanup_interval` - Controls stale Dag cleanup frequency - * :ref:`config:scheduler__dag_stale_not_seen_duration` - Time threshold for marking Dags as stale * **File synchronization problems** - Common with git-sync setups: diff --git a/airflow-core/docs/howto/custom-view-plugin.rst b/airflow-core/docs/howto/custom-view-plugin.rst index 1250475fcba4e..3520de1a652ec 100644 --- a/airflow-core/docs/howto/custom-view-plugin.rst +++ b/airflow-core/docs/howto/custom-view-plugin.rst @@ -54,6 +54,13 @@ available in :doc:`plugin `. Developing React Applications with the Bootstrap Tool ===================================================== +.. warning:: + React applications are new in Airflow 3.1 and should be considered experimental. The feature may be + subject to changes in future versions without warning based on user feedback and errors reported. + Dependency and state interactions between the UI and plugins may need to be refactored, which will also change the bootstrapped example project provided. + +|experimental| + Airflow provides a React plugin bootstrap tool to help developers quickly create, develop, and integrate external React applications into the core UI. This is the most flexible and recommended way to customize the Airflow UI. This tool generates a complete React project structure that builds as a library compatible with dynamic imports and shares React instances with the host Airflow application. diff --git a/airflow-core/docs/howto/customize-ui.rst b/airflow-core/docs/howto/customize-ui.rst index 1eb393096100c..3681554f8aee8 100644 --- a/airflow-core/docs/howto/customize-ui.rst +++ b/airflow-core/docs/howto/customize-ui.rst @@ -21,7 +21,7 @@ Customizing the UI .. _customizing-the-ui: Customizing Dag UI Header and Airflow Page Titles -================================================== +------------------------------------------------- Airflow now allows you to customize the Dag home page header and page title. This will help distinguish between various installations of Airflow or simply amend the page text. @@ -61,17 +61,47 @@ After .. image:: ../img/change-site-title/example_instance_name_configuration.png +| -Add custom alert messages on the dashboard ------------------------------------------- +Adding Dashboard Alert Messages +=============================== -Extra alert messages can be shown on the UI dashboard. This can be useful for warning about setup issues -or announcing changes to end users. The following example shows how to add alert messages: +Extra alert messages can be shown on the Airflow dashboard. This can be useful for warning about setup issues, announcing changes +to end users, or providing real-time status information. Dashboard alerts support both static and dynamic content. -1. Add the following contents to ``airflow_local_settings.py`` file under ``$AIRFLOW_HOME/config``. - Each alert message should specify a severity level (``info``, ``warning``, ``error``) using ``category``. +Basic Static Alerts +------------------- - .. code-block:: python +To add static alert messages that remain constant until the webserver is restarted: + +1. Create an ``airflow_local_settings.py`` file and place it in ``$PYTHONPATH`` or in the ``$AIRFLOW_HOME/config`` folder. + (Airflow adds ``$AIRFLOW_HOME/config`` to ``PYTHONPATH`` when Airflow is initialized) + +2. Add the following contents to ``airflow_local_settings.py``: + + .. note:: + See :ref:`Configuring local settings ` for details on how to configure local settings. + + .. code-block:: python + + from airflow.www.utils import UIAlert + + DASHBOARD_UIALERTS = [ + UIAlert("Welcome to Airflow"), + ] + +3. Restart the Airflow webserver, and you should now see the alert message displayed on the dashboard. + +Alert Categories +---------------- + +You can control the category of the alert message. Available categories include: + +- ``"info"`` (default) - Blue informational alerts +- ``"warning"`` - Yellow warning alerts +- ``"error"`` - Red error alerts + +.. code-block:: python from airflow.api_fastapi.common.types import UIAlert @@ -81,19 +111,70 @@ or announcing changes to end users. The following example shows how to add alert UIAlert(text="Critical error detected!", category="error"), ] - See :ref:`Configuring local settings ` for details on how to - configure local settings. +.. image:: ../img/ui-alert-message.png -2. Restart Airflow Webserver, and you should now see: +Markdown Content in Alerts +-------------------------- -.. image:: ../img/ui-alert-message.png +Markdown can be included in alert messages for richer formatting. In the following example, we show an alert +message of heading 2 with a link included: -Alert messages also support Markdown. In the following example, we show an alert message of heading 2 with a link included. +.. code-block:: python - .. code-block:: python + from airflow.www.utils import UIAlert - DASHBOARD_UIALERTS = [ - UIAlert(text="## Visit [airflow.apache.org](https://airflow.apache.org)", category="info"), - ] + DASHBOARD_UIALERTS = [ + UIAlert(text="## Visit [airflow.apache.org](https://airflow.apache.org)", category="info"), + ] .. image:: ../img/ui-alert-message-markdown.png + +Dynamic Dashboard Alerts +------------------------ + +Dashboard alerts support dynamic content that updates each time the dashboard page is refreshed. This allows for real-time +status updates without requiring webserver restarts. Dynamic alerts must be defined as an instance of an iterable object. +The recommended approach is to create a class that subclasses ``list`` and implements a custom ``__iter__`` method that +yields fresh alerts each time Airflow iterates over the alerts. + +.. note:: + When implementing dynamic alerts it is important to keep alert generation logic lightweight to avoid + impacting dashboard load times. Consider caching results for expensive operations and handle exceptions + gracefully to prevent alert generation from breaking the UI. + +Dynamic alerts are particularly useful for: + +- **Real-time notifications**: Display current status updates or announcements +- **Deployment notifications**: Show current deployment status, build progress, or GitOps state +- **Temporary maintenance alerts**: Provide time-sensitive information about ongoing maintenance or issues +- **Environment-specific warnings**: Display different alerts based on current environment conditions +- **External service status**: Show the availability of dependent services or APIs + +Creating Dynamic Alerts +^^^^^^^^^^^^^^^^^^^^^^^ + +To create dynamic alerts, define ``DASHBOARD_UIALERTS`` as an instance of a class that subclasses ``list`` +and implements the ``__iter__`` method. The UI will iterate over any number ``UIAlert`` instances yielded by +this method and expose them as alerts on the dashboard page. + +The example below demonstrates how logic can be applied to yield alerts dynamically. More practical use +cases might include alerts yielded from APIs, database queries or files. + +.. code-block:: python + + import random + from airflow.www.utils import UIAlert + + + class DynamicAlerts(list): + def __iter__(self): + # This method is called each time Airflow iterates over DASHBOARD_UIALERTS + # Example: Flip a coin + if random.choice([True, False]): + yield UIAlert("Heads!", category="info") + else: + yield UIAlert("Tails!", category="warning") + + + # Create an instance of the class + DASHBOARD_UIALERTS = DynamicAlerts() diff --git a/airflow-core/docs/howto/deadline-alerts.rst b/airflow-core/docs/howto/deadline-alerts.rst index 19b4ea58e786a..e52fdd6aeb1d7 100644 --- a/airflow-core/docs/howto/deadline-alerts.rst +++ b/airflow-core/docs/howto/deadline-alerts.rst @@ -29,6 +29,11 @@ Deadline Alerts allow you to set time thresholds for your Dag runs and automatic thresholds are exceeded. You can set up Deadline Alerts by choosing a built-in reference point, setting an interval, and defining a response using either Airflow's Notifiers or a custom callback function. +Migrating from SLA +------------------ + +For help migrating from SLA to Deadlines, see the :doc:`migration guide ` + Creating a Deadline Alert ------------------------- @@ -64,7 +69,9 @@ Below is an example Dag implementation. If the Dag has not finished 15 minutes a interval=timedelta(minutes=15), callback=AsyncCallback( SlackWebhookNotifier, - kwargs={"text": "Dag 'slack_deadline_alert' still running after 30 minutes."}, + kwargs={ + "text": "🚨 Dag {{ dag_run.dag_id }} missed deadline at {{ deadline.deadline_time }}. DagRun: {{ dag_run }}" + }, ), ), ): @@ -78,6 +85,8 @@ The timeline for this example would look like this: Scheduled Queued Started Deadline 00:00 00:03 00:05 00:18 +.. _built-in-deadline-references: + Using Built-in References ------------------------- @@ -108,7 +117,9 @@ Here's an example using a fixed datetime: interval=timedelta(minutes=-30), # Alert 30 minutes before the reference. callback=AsyncCallback( SlackWebhookNotifier, - kwargs={"text": "Dag 'slack_deadline_alert' still running after 30 minutes."}, + kwargs={ + "text": "🚨 Dag {{ dag_run.dag_id }} missed deadline at {{ deadline.deadline_time }}. DagRun: {{ dag_run }}" + }, ), ), ): @@ -128,9 +139,10 @@ The timeline for this example would look like this: Using Callbacks --------------- -When a deadline is exceeded, the callback is executed. You can use an existing :doc:`Notifier ` -or create a custom callback function. A callback must be an :class:`~airflow.sdk.definitions.deadline.AsyncCallback`, -with support coming soon for :class:`~airflow.sdk.definitions.deadline.SyncCallback`. +When a deadline is exceeded, the callback's callable is executed with the specified kwargs. You can use an +existing :doc:`Notifier ` or create a custom callable. A callback must be an +:class:`~airflow.sdk.definitions.deadline.AsyncCallback`, with support coming soon for +:class:`~airflow.sdk.definitions.deadline.SyncCallback`. Using Built-in Notifiers ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -146,7 +158,9 @@ Here's an example using the Slack Notifier if the Dag run has not finished withi interval=timedelta(minutes=30), callback=AsyncCallback( SlackWebhookNotifier, - kwargs={"text": "Dag 'slack_deadline_alert' still running after 30 minutes."}, + kwargs={ + "text": "🚨 Dag {{ dag_run.dag_id }} missed deadline at {{ deadline.deadline_time }}. DagRun: {{ dag_run }}" + }, ), ), ): @@ -155,7 +169,7 @@ Here's an example using the Slack Notifier if the Dag run has not finished withi Creating Custom Callbacks ^^^^^^^^^^^^^^^^^^^^^^^^^ -You can create custom callbacks for more complex handling. If ``kwargs`` are specified in the ``Callback``, +You can create custom callables for more complex handling. If ``kwargs`` are specified in the ``Callback``, they are passed to the callback function. **Asynchronous callbacks** must be defined somewhere in the Triggerer's system path. @@ -163,7 +177,8 @@ Triggerer's system path. Regarding Async Custom Deadline callbacks: * Async callbacks are executed by the Triggerer, so users must ensure they are importable by the Triggerer. - * One easy way to do this is to place the callback as a top-level method in a new file in the plugins folder. + * One easy way to do this is to place the callable as a top-level method in a new file in the plugins folder. + Nested callables are not currently supported. * The Triggerer will need to be restarted when a callback is added or changed in order to reload the file. @@ -175,7 +190,9 @@ A **custom asynchronous callback** might look like this: async def custom_async_callback(**kwargs): """Handle deadline violation with custom logic.""" - print(f"Deadline exceeded for Dag {kwargs.get("dag_id")}!") + context = kwargs.get("context", {}) + print(f"Deadline exceeded for Dag {context.get("dag_run", {}).get("dag_id")}!") + print(f"Context: {context}") print(f"Alert type: {kwargs.get("alert_type")}") # Additional custom handling here @@ -199,12 +216,21 @@ A **custom asynchronous callback** might look like this: interval=timedelta(minutes=15), callback=AsyncCallback( custom_async_callback, - kwargs={"alert_type": "time_exceeded", "dag_id": "custom_deadline_alert"}, + kwargs={"alert_type": "time_exceeded"}, ), ), ): EmptyOperator(task_id="example_task") +Templating and Context +^^^^^^^^^^^^^^^^^^^^^^ + +Currently, a relatively simple version of the Airflow context is passed to callables and Airflow does not run +:ref:`concepts:jinja-templating` on the kwargs. However, Notifiers already run templating with the +provided context as part of their execution. This means that templating can be used when using a Notifier +as long as the variables being templated are included in the simplified context. This currently includes the +ID and the calculated deadline time of the Deadline Alert as well as the data included in the ``GET`` REST API +response for Dag Run. Support for more comprehensive context and templating will be added in future versions. Deadline Calculation ^^^^^^^^^^^^^^^^^^^^ diff --git a/airflow-core/docs/howto/docker-compose/index.rst b/airflow-core/docs/howto/docker-compose/index.rst index 7e6d15a9e67a6..c417950e73319 100644 --- a/airflow-core/docs/howto/docker-compose/index.rst +++ b/airflow-core/docs/howto/docker-compose/index.rst @@ -154,6 +154,24 @@ If you want to initialize ``airflow.cfg`` with default values before launching t This will seed ``airflow.cfg`` with default values in ``config`` folder. +On systems with SELinux/AppArmor, you may run into permission issues. If this happens, edit your ``docker-compose.yaml`` file by added the suffix ``:z`` to all volumes: + +.. code-block:: yaml + + volumes: + - ${AIRFLOW_PROJ_DIR:-.}/dags:/opt/airflow/dags:z + - ${AIRFLOW_PROJ_DIR:-.}/logs:/opt/airflow/logs:z + - ${AIRFLOW_PROJ_DIR:-.}/config:/opt/airflow/config:z + - ${AIRFLOW_PROJ_DIR:-.}/plugins:/opt/airflow/plugins:z + +If, after this change, you are still experiencing permission issues when creating the ``airflow.cfg`` file, you can apply a very permissive setting to the ``config/`` folder: + +.. code-block:: bash + + sudo chmod -R 777 ./config + +Note that the above is a *work around* that should never be used in production. + Initialize the database ----------------------- @@ -163,14 +181,11 @@ On **all operating systems**, you need to run database migrations and create the docker compose up airflow-init -After initialization is complete, you should see a message like this: +After initialization is complete, you should see output related to files, folders, and plug-ins and finally a message like this: .. parsed-literal:: - airflow-init_1 | Upgrades done - airflow-init_1 | Admin user airflow created - airflow-init_1 | |version| - start_airflow-init_1 exited with code 0 + airflow-init-1 exited with code 0 The account created has the login ``airflow`` and the password ``airflow``. diff --git a/airflow-core/docs/howto/index.rst b/airflow-core/docs/howto/index.rst index 28dd34a8058e3..9abc9caa76e3f 100644 --- a/airflow-core/docs/howto/index.rst +++ b/airflow-core/docs/howto/index.rst @@ -34,6 +34,7 @@ configuring an Airflow environment. add-dag-tags add-owner-links notifications + sla-to-deadlines deadline-alerts set-config set-up-database diff --git a/airflow-core/docs/howto/sla-to-deadlines.rst b/airflow-core/docs/howto/sla-to-deadlines.rst new file mode 100644 index 0000000000000..dd1e41592605a --- /dev/null +++ b/airflow-core/docs/howto/sla-to-deadlines.rst @@ -0,0 +1,89 @@ + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +Migrating from SLA to Deadline Alerts +===================================== + +Two Different Paradigms +----------------------- + +While the goal of the **SLA** and **Deadline Alerts** features are very similar, they use two very different approaches. +This guide will lay out the major differences and help you decide on the best approach for your use case. + +To begin with, we'll start by explaining the two approaches then go into how to find the right Deadline for your use case. + +SLA +^^^ + +When the dag run **finishes**, check the current time. If the time is greater than (logical_date + sla) then +execute ``sla_miss_callback``. If the Dag run never finishes, the SLA is never checked. + +Deadline Alerts +^^^^^^^^^^^^^^^ + +When a Dag run **starts**, calculate and store (:ref:`DeadlineReference ` + interval). +The scheduler loop then checks periodically (default 5 seconds, set by ``scheduler_heartbeat_sec``) if any of those +times have passed then execute ``callback(**kwargs)``. + +The most direct migration path would be to use the ``DeadlineReference.DAGRUN_LOGICAL_DATE`` reference, but note that +the major change is that the Deadline's callback will execute "immediately" (within ``scheduler_heartbeat_sec`` of the +calculated expiration time) and not wait until the Dag finishes first. + +Equivalent Example Dags +----------------------- + +Below is a Dag using a 1-hour SLA, followed by an equivalent Dag using Deadline Alerts. + +SLA Example +^^^^^^^^^^^ + +.. code-block:: python + + with DAG( + "minimal_sla_example", + default_args={"sla": timedelta(hours=1)}, + sla_miss_callback=SlackWebhookNotifier( + text="SLA missed for {{ dag_run.dag_id }}", + ), + ): + BashOperator(task_id="long_task", bash_command="sleep 3600") + +Deadline Alerts Example +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: python + + with DAG( + "minimal_deadline_example", + deadline=DeadlineAlert( + reference=DeadlineReference.DAGRUN_LOGICAL_DATE, + interval=timedelta(hours=1), + callback=AsyncCallback( + SlackWebhookNotifier, + kwargs={ + text: "Deadline missed for {{ dag_run.dag_id }}", + }, + ), + ), + ): + BashOperator(task_id="long_task", bash_command="sleep 3600") + + +Further Reading +--------------- + +For more details on the Deadline Alerts feature, see the :doc:`how-to guide `. diff --git a/airflow-core/docs/img/airflow_erd.sha256 b/airflow-core/docs/img/airflow_erd.sha256 index ee840ec21f2d0..6162bcff312cc 100644 --- a/airflow-core/docs/img/airflow_erd.sha256 +++ b/airflow-core/docs/img/airflow_erd.sha256 @@ -1 +1 @@ -c05cefbe080ed889ebe132a0285756db477ff28256bbc1e86da1e053873f6478 \ No newline at end of file +db7901e22801d299714b84b9a676081b12bc6247de807cb2469f3c59bdabcfad \ No newline at end of file diff --git a/airflow-core/docs/img/airflow_erd.svg b/airflow-core/docs/img/airflow_erd.svg index a129862ad113f..c6fc5f0ea7d45 100644 --- a/airflow-core/docs/img/airflow_erd.svg +++ b/airflow-core/docs/img/airflow_erd.svg @@ -1437,71 +1437,72 @@ hitl_detail - -hitl_detail - -ti_id - - [UUID] - NOT NULL - -body - - [TEXT] - -chosen_options - - [JSON] - -defaults - - [JSON] - -multiple - - [BOOLEAN] - -options - - [JSON] - NOT NULL - -params - - [JSON] - NOT NULL - -params_input - - [JSON] - NOT NULL - -responded_user_id - - [VARCHAR(128)] - -responded_user_name - - [VARCHAR(128)] - -respondents - - [JSON] - -response_at - - [TIMESTAMP] - -subject - - [TEXT] - NOT NULL + +hitl_detail + +ti_id + + [UUID] + NOT NULL + +assignees + + [JSON] + +body + + [TEXT] + +chosen_options + + [JSON] + +created_at + + [TIMESTAMP] + NOT NULL + +defaults + + [JSON] + +multiple + + [BOOLEAN] + +options + + [JSON] + NOT NULL + +params + + [JSON] + NOT NULL + +params_input + + [JSON] + NOT NULL + +responded_at + + [TIMESTAMP] + +responded_by + + [JSON] + +subject + + [TEXT] + NOT NULL task_instance--hitl_detail - -1 + +1 1 diff --git a/airflow-core/docs/img/apache.jpg b/airflow-core/docs/img/apache.jpg deleted file mode 100644 index 312251f8d22cd..0000000000000 Binary files a/airflow-core/docs/img/apache.jpg and /dev/null differ diff --git a/airflow-core/docs/img/asf_logo_wide.png b/airflow-core/docs/img/asf_logo_wide.png new file mode 100644 index 0000000000000..cef985efb0219 Binary files /dev/null and b/airflow-core/docs/img/asf_logo_wide.png differ diff --git a/airflow-core/docs/img/hitl_approve_reject.png b/airflow-core/docs/img/hitl_approve_reject.png deleted file mode 100644 index 94963dbcc8e12..0000000000000 Binary files a/airflow-core/docs/img/hitl_approve_reject.png and /dev/null differ diff --git a/airflow-core/docs/img/hitl_branch_selected.png b/airflow-core/docs/img/hitl_branch_selected.png deleted file mode 100644 index 342a13c937628..0000000000000 Binary files a/airflow-core/docs/img/hitl_branch_selected.png and /dev/null differ diff --git a/airflow-core/docs/img/hitl_branch_selection.png b/airflow-core/docs/img/hitl_branch_selection.png deleted file mode 100644 index fb3fc472bcc2c..0000000000000 Binary files a/airflow-core/docs/img/hitl_branch_selection.png and /dev/null differ diff --git a/airflow-core/docs/img/hitl_wait_for_input.png b/airflow-core/docs/img/hitl_wait_for_input.png deleted file mode 100644 index 3d0ba69ddb42f..0000000000000 Binary files a/airflow-core/docs/img/hitl_wait_for_input.png and /dev/null differ diff --git a/airflow-core/docs/img/hitl_wait_for_multiple_options.png b/airflow-core/docs/img/hitl_wait_for_multiple_options.png deleted file mode 100644 index 549b168318e69..0000000000000 Binary files a/airflow-core/docs/img/hitl_wait_for_multiple_options.png and /dev/null differ diff --git a/airflow-core/docs/img/hitl_wait_for_option.png b/airflow-core/docs/img/hitl_wait_for_option.png deleted file mode 100644 index af348e5054cf9..0000000000000 Binary files a/airflow-core/docs/img/hitl_wait_for_option.png and /dev/null differ diff --git a/airflow-core/docs/img/operator_extra_link.png b/airflow-core/docs/img/operator_extra_link.png index 30302de841dd0..e4b0624a51ff5 100644 Binary files a/airflow-core/docs/img/operator_extra_link.png and b/airflow-core/docs/img/operator_extra_link.png differ diff --git a/airflow-core/docs/img/ui-dark/add-dag-tags.png b/airflow-core/docs/img/ui-dark/add-dag-tags.png index 640fc56597a76..b6740e3998041 100644 Binary files a/airflow-core/docs/img/ui-dark/add-dag-tags.png and b/airflow-core/docs/img/ui-dark/add-dag-tags.png differ diff --git a/airflow-core/docs/img/ui-dark/asset_view.png b/airflow-core/docs/img/ui-dark/asset_view.png index a42d0eca5d144..434bb15bc5d59 100644 Binary files a/airflow-core/docs/img/ui-dark/asset_view.png and b/airflow-core/docs/img/ui-dark/asset_view.png differ diff --git a/airflow-core/docs/img/ui-dark/backfill.png b/airflow-core/docs/img/ui-dark/backfill.png index 8b9a41c698d8d..53950b9698536 100644 Binary files a/airflow-core/docs/img/ui-dark/backfill.png and b/airflow-core/docs/img/ui-dark/backfill.png differ diff --git a/airflow-core/docs/img/ui-dark/basic_dag.png b/airflow-core/docs/img/ui-dark/basic_dag.png index f62203ea869b1..ad8d05899e89a 100644 Binary files a/airflow-core/docs/img/ui-dark/basic_dag.png and b/airflow-core/docs/img/ui-dark/basic_dag.png differ diff --git a/airflow-core/docs/img/ui-dark/branch_note.png b/airflow-core/docs/img/ui-dark/branch_note.png index 6e27b68a86b04..1faf58d7d432b 100644 Binary files a/airflow-core/docs/img/ui-dark/branch_note.png and b/airflow-core/docs/img/ui-dark/branch_note.png differ diff --git a/airflow-core/docs/img/ui-dark/branch_with_trigger.png b/airflow-core/docs/img/ui-dark/branch_with_trigger.png index 04467635005c8..3befb712cfe47 100644 Binary files a/airflow-core/docs/img/ui-dark/branch_with_trigger.png and b/airflow-core/docs/img/ui-dark/branch_with_trigger.png differ diff --git a/airflow-core/docs/img/ui-dark/branch_without_trigger.png b/airflow-core/docs/img/ui-dark/branch_without_trigger.png index 6c30d728ca892..c76153962190d 100644 Binary files a/airflow-core/docs/img/ui-dark/branch_without_trigger.png and b/airflow-core/docs/img/ui-dark/branch_without_trigger.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_doc.png b/airflow-core/docs/img/ui-dark/dag_doc.png index 0f048cd6ca6b7..f4bf08801f0e5 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_doc.png and b/airflow-core/docs/img/ui-dark/dag_doc.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_graph_external_conditions.png b/airflow-core/docs/img/ui-dark/dag_graph_external_conditions.png index 38537e1850bb7..55d3a3b135998 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_graph_external_conditions.png and b/airflow-core/docs/img/ui-dark/dag_graph_external_conditions.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_list.png b/airflow-core/docs/img/ui-dark/dag_list.png index c7b378a459470..a9de2f8082f4a 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_list.png and b/airflow-core/docs/img/ui-dark/dag_list.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_overview_details.png b/airflow-core/docs/img/ui-dark/dag_overview_details.png index c3c7222060011..0513d025c3b63 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_overview_details.png and b/airflow-core/docs/img/ui-dark/dag_overview_details.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_run_details.png b/airflow-core/docs/img/ui-dark/dag_run_details.png index fe0a1648d035a..2a3b30dc36d02 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_run_details.png and b/airflow-core/docs/img/ui-dark/dag_run_details.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_run_graph.png b/airflow-core/docs/img/ui-dark/dag_run_graph.png index 09b4b897458a3..954f1ced30c0e 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_run_graph.png and b/airflow-core/docs/img/ui-dark/dag_run_graph.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_run_task_instances.png b/airflow-core/docs/img/ui-dark/dag_run_task_instances.png index cebbae11c8b95..a33fed1ab5a0c 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_run_task_instances.png and b/airflow-core/docs/img/ui-dark/dag_run_task_instances.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_task_instance_details.png b/airflow-core/docs/img/ui-dark/dag_task_instance_details.png index d6dd08f9ec51e..28c17a41e1f8d 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_task_instance_details.png and b/airflow-core/docs/img/ui-dark/dag_task_instance_details.png differ diff --git a/airflow-core/docs/img/ui-dark/dag_trigger_window_single_run.png b/airflow-core/docs/img/ui-dark/dag_trigger_window_single_run.png index f5eeab007846c..2495730e8be8d 100644 Binary files a/airflow-core/docs/img/ui-dark/dag_trigger_window_single_run.png and b/airflow-core/docs/img/ui-dark/dag_trigger_window_single_run.png differ diff --git a/airflow-core/docs/img/ui-dark/dags.png b/airflow-core/docs/img/ui-dark/dags.png index 56458caedef62..75f28fd7281b0 100644 Binary files a/airflow-core/docs/img/ui-dark/dags.png and b/airflow-core/docs/img/ui-dark/dags.png differ diff --git a/airflow-core/docs/img/ui-dark/demo_complex_dag_overview_with_failed_tasks.png b/airflow-core/docs/img/ui-dark/demo_complex_dag_overview_with_failed_tasks.png new file mode 100644 index 0000000000000..67b5053d37380 Binary files /dev/null and b/airflow-core/docs/img/ui-dark/demo_complex_dag_overview_with_failed_tasks.png differ diff --git a/airflow-core/docs/img/ui-dark/demo_dag_overview_with_failed_tasks.png b/airflow-core/docs/img/ui-dark/demo_dag_overview_with_failed_tasks.png deleted file mode 100644 index 86269a9103c1a..0000000000000 Binary files a/airflow-core/docs/img/ui-dark/demo_dag_overview_with_failed_tasks.png and /dev/null differ diff --git a/airflow-core/docs/img/ui-dark/demo_graph_and_code_view.png b/airflow-core/docs/img/ui-dark/demo_graph_and_code_view.png index c35615a2d7122..e69c59e0d0a15 100644 Binary files a/airflow-core/docs/img/ui-dark/demo_graph_and_code_view.png and b/airflow-core/docs/img/ui-dark/demo_graph_and_code_view.png differ diff --git a/airflow-core/docs/img/ui-dark/demo_grid_view_with_task_logs.png b/airflow-core/docs/img/ui-dark/demo_grid_view_with_task_logs.png index 36c6d28d59fda..e85e8f3664a66 100644 Binary files a/airflow-core/docs/img/ui-dark/demo_grid_view_with_task_logs.png and b/airflow-core/docs/img/ui-dark/demo_grid_view_with_task_logs.png differ diff --git a/airflow-core/docs/img/ui-dark/hitl_approve_reject.png b/airflow-core/docs/img/ui-dark/hitl_approve_reject.png new file mode 100644 index 0000000000000..97827d126f126 Binary files /dev/null and b/airflow-core/docs/img/ui-dark/hitl_approve_reject.png differ diff --git a/airflow-core/docs/img/ui-dark/hitl_branch_selected.png b/airflow-core/docs/img/ui-dark/hitl_branch_selected.png new file mode 100644 index 0000000000000..d0da408e90429 Binary files /dev/null and b/airflow-core/docs/img/ui-dark/hitl_branch_selected.png differ diff --git a/airflow-core/docs/img/ui-dark/hitl_branch_selection.png b/airflow-core/docs/img/ui-dark/hitl_branch_selection.png new file mode 100644 index 0000000000000..c194bb6bb83ad Binary files /dev/null and b/airflow-core/docs/img/ui-dark/hitl_branch_selection.png differ diff --git a/airflow-core/docs/img/ui-dark/hitl_wait_for_input.png b/airflow-core/docs/img/ui-dark/hitl_wait_for_input.png new file mode 100644 index 0000000000000..1cc50013c48ba Binary files /dev/null and b/airflow-core/docs/img/ui-dark/hitl_wait_for_input.png differ diff --git a/airflow-core/docs/img/ui-dark/hitl_wait_for_multiple_options.png b/airflow-core/docs/img/ui-dark/hitl_wait_for_multiple_options.png new file mode 100644 index 0000000000000..982de55eb5c44 Binary files /dev/null and b/airflow-core/docs/img/ui-dark/hitl_wait_for_multiple_options.png differ diff --git a/airflow-core/docs/img/ui-dark/hitl_wait_for_option.png b/airflow-core/docs/img/ui-dark/hitl_wait_for_option.png new file mode 100644 index 0000000000000..64792bd3802e9 Binary files /dev/null and b/airflow-core/docs/img/ui-dark/hitl_wait_for_option.png differ diff --git a/airflow-core/docs/img/ui-dark/task_doc.png b/airflow-core/docs/img/ui-dark/task_doc.png index bd9e7e1038df3..f2e7170ea403a 100644 Binary files a/airflow-core/docs/img/ui-dark/task_doc.png and b/airflow-core/docs/img/ui-dark/task_doc.png differ diff --git a/airflow-core/docs/img/ui-dark/task_instance_history.png b/airflow-core/docs/img/ui-dark/task_instance_history.png index 4755ac4038cf0..35d8c00a17ccf 100644 Binary files a/airflow-core/docs/img/ui-dark/task_instance_history.png and b/airflow-core/docs/img/ui-dark/task_instance_history.png differ diff --git a/airflow-core/docs/img/ui-dark/task_instance_history_log.png b/airflow-core/docs/img/ui-dark/task_instance_history_log.png index 36a45b06bdd6b..3d978c7919224 100644 Binary files a/airflow-core/docs/img/ui-dark/task_instance_history_log.png and b/airflow-core/docs/img/ui-dark/task_instance_history_log.png differ diff --git a/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-1.png b/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-1.png index abc253fa94cba..b4c093d0548c4 100644 Binary files a/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-1.png and b/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-1.png differ diff --git a/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-2.png b/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-2.png index c7551ff142140..2493fa57c009d 100644 Binary files a/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-2.png and b/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-2.png differ diff --git a/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-3.png b/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-3.png index 9c6c33ce9c2db..3e928ae0a1961 100644 Binary files a/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-3.png and b/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-3.png differ diff --git a/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-4.png b/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-4.png index f415de98148a4..6efae446e06b8 100644 Binary files a/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-4.png and b/airflow-core/docs/img/ui-dark/trigger-dag-tutorial-form-4.png differ diff --git a/airflow-core/docs/img/ui-dark/tutorial_pipeline_add_connection.png b/airflow-core/docs/img/ui-dark/tutorial_pipeline_add_connection.png index 51506890ac288..480f0ade8d6cb 100644 Binary files a/airflow-core/docs/img/ui-dark/tutorial_pipeline_add_connection.png and b/airflow-core/docs/img/ui-dark/tutorial_pipeline_add_connection.png differ diff --git a/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_list.png b/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_list.png deleted file mode 100644 index 27311e1fd7443..0000000000000 Binary files a/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_list.png and /dev/null differ diff --git a/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_list_trigger.png b/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_list_trigger.png new file mode 100644 index 0000000000000..6f89b1602d34c Binary files /dev/null and b/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_list_trigger.png differ diff --git a/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_overview_processed.png b/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_overview_processed.png index 5054139b3526f..dc7a137a4a088 100644 Binary files a/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_overview_processed.png and b/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_overview_processed.png differ diff --git a/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_task_instance_logs.png b/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_task_instance_logs.png new file mode 100644 index 0000000000000..559fa029ea7d8 Binary files /dev/null and b/airflow-core/docs/img/ui-dark/tutorial_pipeline_dag_task_instance_logs.png differ diff --git a/airflow-core/docs/img/ui-dark/variable_hidden.png b/airflow-core/docs/img/ui-dark/variable_hidden.png index 44c8bcca227be..a1d92f72ddf48 100644 Binary files a/airflow-core/docs/img/ui-dark/variable_hidden.png and b/airflow-core/docs/img/ui-dark/variable_hidden.png differ diff --git a/airflow-core/docs/img/ui-light/asset_view.png b/airflow-core/docs/img/ui-light/asset_view.png index 69cc8ff5089ec..2f2d1dcde10aa 100644 Binary files a/airflow-core/docs/img/ui-light/asset_view.png and b/airflow-core/docs/img/ui-light/asset_view.png differ diff --git a/airflow-core/docs/img/ui-light/backfill.png b/airflow-core/docs/img/ui-light/backfill.png index 0eab89ae7b800..4d8dc84f2bd90 100644 Binary files a/airflow-core/docs/img/ui-light/backfill.png and b/airflow-core/docs/img/ui-light/backfill.png differ diff --git a/airflow-core/docs/img/ui-light/basic_dag.png b/airflow-core/docs/img/ui-light/basic_dag.png index 458ee61544bba..1cdaa57482d57 100644 Binary files a/airflow-core/docs/img/ui-light/basic_dag.png and b/airflow-core/docs/img/ui-light/basic_dag.png differ diff --git a/airflow-core/docs/img/ui-light/branch_note.png b/airflow-core/docs/img/ui-light/branch_note.png index 0a3d923d1a906..a7efb2c1b620d 100644 Binary files a/airflow-core/docs/img/ui-light/branch_note.png and b/airflow-core/docs/img/ui-light/branch_note.png differ diff --git a/airflow-core/docs/img/ui-light/branch_with_trigger.png b/airflow-core/docs/img/ui-light/branch_with_trigger.png index eb171565321ad..80124a4c3041f 100644 Binary files a/airflow-core/docs/img/ui-light/branch_with_trigger.png and b/airflow-core/docs/img/ui-light/branch_with_trigger.png differ diff --git a/airflow-core/docs/img/ui-light/branch_without_trigger.png b/airflow-core/docs/img/ui-light/branch_without_trigger.png index c2d726506c50a..48b9d2e468eb1 100644 Binary files a/airflow-core/docs/img/ui-light/branch_without_trigger.png and b/airflow-core/docs/img/ui-light/branch_without_trigger.png differ diff --git a/airflow-core/docs/img/ui-light/dag_doc.png b/airflow-core/docs/img/ui-light/dag_doc.png index 3b94e97d3f270..478cb6e310c58 100644 Binary files a/airflow-core/docs/img/ui-light/dag_doc.png and b/airflow-core/docs/img/ui-light/dag_doc.png differ diff --git a/airflow-core/docs/img/ui-light/dag_graph_external_conditions.png b/airflow-core/docs/img/ui-light/dag_graph_external_conditions.png index 1c4b2e0d69ecc..c274b0ef65f32 100644 Binary files a/airflow-core/docs/img/ui-light/dag_graph_external_conditions.png and b/airflow-core/docs/img/ui-light/dag_graph_external_conditions.png differ diff --git a/airflow-core/docs/img/ui-light/dag_list.png b/airflow-core/docs/img/ui-light/dag_list.png index ceb1065dcc468..3be956f3e57a6 100644 Binary files a/airflow-core/docs/img/ui-light/dag_list.png and b/airflow-core/docs/img/ui-light/dag_list.png differ diff --git a/airflow-core/docs/img/ui-light/dag_overview_details.png b/airflow-core/docs/img/ui-light/dag_overview_details.png index cfb18a3cfca23..5bc67c283cbb9 100644 Binary files a/airflow-core/docs/img/ui-light/dag_overview_details.png and b/airflow-core/docs/img/ui-light/dag_overview_details.png differ diff --git a/airflow-core/docs/img/ui-light/dag_run_details.png b/airflow-core/docs/img/ui-light/dag_run_details.png index b0a271e2342dc..00fbd5b219acf 100644 Binary files a/airflow-core/docs/img/ui-light/dag_run_details.png and b/airflow-core/docs/img/ui-light/dag_run_details.png differ diff --git a/airflow-core/docs/img/ui-light/dag_run_graph.png b/airflow-core/docs/img/ui-light/dag_run_graph.png index 31dccef7612ee..4ca25568b78c7 100644 Binary files a/airflow-core/docs/img/ui-light/dag_run_graph.png and b/airflow-core/docs/img/ui-light/dag_run_graph.png differ diff --git a/airflow-core/docs/img/ui-light/dag_run_task_instances.png b/airflow-core/docs/img/ui-light/dag_run_task_instances.png index 42c71c958dec1..4576972351ff2 100644 Binary files a/airflow-core/docs/img/ui-light/dag_run_task_instances.png and b/airflow-core/docs/img/ui-light/dag_run_task_instances.png differ diff --git a/airflow-core/docs/img/ui-light/dag_task_instance_details.png b/airflow-core/docs/img/ui-light/dag_task_instance_details.png index e2a3be93226ba..86e42f2ec3a77 100644 Binary files a/airflow-core/docs/img/ui-light/dag_task_instance_details.png and b/airflow-core/docs/img/ui-light/dag_task_instance_details.png differ diff --git a/airflow-core/docs/img/ui-light/dag_trigger_window_single_run.png b/airflow-core/docs/img/ui-light/dag_trigger_window_single_run.png index 60062d5960aaa..a0fe4eec40c85 100644 Binary files a/airflow-core/docs/img/ui-light/dag_trigger_window_single_run.png and b/airflow-core/docs/img/ui-light/dag_trigger_window_single_run.png differ diff --git a/airflow-core/docs/img/ui-light/dags.png b/airflow-core/docs/img/ui-light/dags.png index 0c408515fb172..1d2e168a8e17f 100644 Binary files a/airflow-core/docs/img/ui-light/dags.png and b/airflow-core/docs/img/ui-light/dags.png differ diff --git a/airflow-core/docs/img/ui-light/demo_complex_dag_overview_with_failed_tasks.png b/airflow-core/docs/img/ui-light/demo_complex_dag_overview_with_failed_tasks.png new file mode 100644 index 0000000000000..bb459b5c6c92d Binary files /dev/null and b/airflow-core/docs/img/ui-light/demo_complex_dag_overview_with_failed_tasks.png differ diff --git a/airflow-core/docs/img/ui-light/demo_dag_overview_with_failed_tasks.png b/airflow-core/docs/img/ui-light/demo_dag_overview_with_failed_tasks.png deleted file mode 100644 index 18ccd3c11c912..0000000000000 Binary files a/airflow-core/docs/img/ui-light/demo_dag_overview_with_failed_tasks.png and /dev/null differ diff --git a/airflow-core/docs/img/ui-light/demo_graph_and_code_view.png b/airflow-core/docs/img/ui-light/demo_graph_and_code_view.png index d17d9bda00742..613cbdc7063a6 100644 Binary files a/airflow-core/docs/img/ui-light/demo_graph_and_code_view.png and b/airflow-core/docs/img/ui-light/demo_graph_and_code_view.png differ diff --git a/airflow-core/docs/img/ui-light/demo_grid_view_with_task_logs.png b/airflow-core/docs/img/ui-light/demo_grid_view_with_task_logs.png index a00ed336a936a..c28729cc9b6ce 100644 Binary files a/airflow-core/docs/img/ui-light/demo_grid_view_with_task_logs.png and b/airflow-core/docs/img/ui-light/demo_grid_view_with_task_logs.png differ diff --git a/airflow-core/docs/img/ui-light/hitl_approve_reject.png b/airflow-core/docs/img/ui-light/hitl_approve_reject.png new file mode 100644 index 0000000000000..0ae6161854464 Binary files /dev/null and b/airflow-core/docs/img/ui-light/hitl_approve_reject.png differ diff --git a/airflow-core/docs/img/ui-light/hitl_branch_selected.png b/airflow-core/docs/img/ui-light/hitl_branch_selected.png new file mode 100644 index 0000000000000..f1e6b5176a21d Binary files /dev/null and b/airflow-core/docs/img/ui-light/hitl_branch_selected.png differ diff --git a/airflow-core/docs/img/ui-light/hitl_branch_selection.png b/airflow-core/docs/img/ui-light/hitl_branch_selection.png new file mode 100644 index 0000000000000..45d9c71dce73a Binary files /dev/null and b/airflow-core/docs/img/ui-light/hitl_branch_selection.png differ diff --git a/airflow-core/docs/img/ui-light/hitl_wait_for_input.png b/airflow-core/docs/img/ui-light/hitl_wait_for_input.png new file mode 100644 index 0000000000000..9d74d32edc055 Binary files /dev/null and b/airflow-core/docs/img/ui-light/hitl_wait_for_input.png differ diff --git a/airflow-core/docs/img/ui-light/hitl_wait_for_multiple_options.png b/airflow-core/docs/img/ui-light/hitl_wait_for_multiple_options.png new file mode 100644 index 0000000000000..8888a0b68e3fe Binary files /dev/null and b/airflow-core/docs/img/ui-light/hitl_wait_for_multiple_options.png differ diff --git a/airflow-core/docs/img/ui-light/hitl_wait_for_option.png b/airflow-core/docs/img/ui-light/hitl_wait_for_option.png new file mode 100644 index 0000000000000..8dd32cfcb3de0 Binary files /dev/null and b/airflow-core/docs/img/ui-light/hitl_wait_for_option.png differ diff --git a/airflow-core/docs/img/ui-light/task_doc.png b/airflow-core/docs/img/ui-light/task_doc.png index 887332b71bb4b..9b2a6fd56d77d 100644 Binary files a/airflow-core/docs/img/ui-light/task_doc.png and b/airflow-core/docs/img/ui-light/task_doc.png differ diff --git a/airflow-core/docs/img/ui-light/task_instance_history.png b/airflow-core/docs/img/ui-light/task_instance_history.png index 27835950e7cca..f7a61689f7096 100644 Binary files a/airflow-core/docs/img/ui-light/task_instance_history.png and b/airflow-core/docs/img/ui-light/task_instance_history.png differ diff --git a/airflow-core/docs/img/ui-light/task_instance_history_log.png b/airflow-core/docs/img/ui-light/task_instance_history_log.png index afcccd0f2898e..6bc1843b6d2eb 100644 Binary files a/airflow-core/docs/img/ui-light/task_instance_history_log.png and b/airflow-core/docs/img/ui-light/task_instance_history_log.png differ diff --git a/airflow-core/docs/img/ui-light/tutorial_pipeline_add_connection.png b/airflow-core/docs/img/ui-light/tutorial_pipeline_add_connection.png index c455897a6e6b2..3810f56567ce6 100644 Binary files a/airflow-core/docs/img/ui-light/tutorial_pipeline_add_connection.png and b/airflow-core/docs/img/ui-light/tutorial_pipeline_add_connection.png differ diff --git a/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_list.png b/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_list.png deleted file mode 100644 index 678634214d5c1..0000000000000 Binary files a/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_list.png and /dev/null differ diff --git a/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_list_trigger.png b/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_list_trigger.png new file mode 100644 index 0000000000000..78f561ddadcbb Binary files /dev/null and b/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_list_trigger.png differ diff --git a/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_overview_processed.png b/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_overview_processed.png index 1de592d0769f8..503ee59620219 100644 Binary files a/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_overview_processed.png and b/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_overview_processed.png differ diff --git a/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_task_instance_logs.png b/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_task_instance_logs.png new file mode 100644 index 0000000000000..9076318b2af28 Binary files /dev/null and b/airflow-core/docs/img/ui-light/tutorial_pipeline_dag_task_instance_logs.png differ diff --git a/airflow-core/docs/img/ui-light/variable_hidden.png b/airflow-core/docs/img/ui-light/variable_hidden.png index 51d1331e99af3..9f03ba3152c7b 100644 Binary files a/airflow-core/docs/img/ui-light/variable_hidden.png and b/airflow-core/docs/img/ui-light/variable_hidden.png differ diff --git a/airflow-core/docs/index.rst b/airflow-core/docs/index.rst index d3788b024c4b0..fc2d641d306f8 100644 --- a/airflow-core/docs/index.rst +++ b/airflow-core/docs/index.rst @@ -79,7 +79,7 @@ Here you see: Airflow parses the script, schedules the tasks, and executes them in the defined order. The status of the ``"demo"`` Dag is displayed in the web interface: -.. image:: /img/ui-dark/demo_graph_and_code_view.png +.. image:: /img/ui-light/demo_graph_and_code_view.png :alt: Demo Dag in the Graph View, showing the status of one Dag run along with Dag code. | @@ -88,7 +88,7 @@ This example uses a simple Bash command and Python function, but Airflow tasks c tasks to run a Spark job, move files between storage buckets, or send a notification email. Here's what that same Dag looks like over time, with multiple runs: -.. image:: /img/ui-dark/demo_grid_view_with_task_logs.png +.. image:: /img/ui-light/demo_grid_view_with_task_logs.png :alt: Demo Dag in the Grid View, showing the status of all Dag runs, as well as logs for a task instance | @@ -96,7 +96,7 @@ like over time, with multiple runs: Each column in the grid represents a single Dag run. While the graph and grid views are most commonly used, Airflow provides several other views to help you monitor and troubleshoot workflows — such as the ``Dag Overview`` view: -.. image:: /img/ui-dark/demo_dag_overview_with_failed_tasks.png +.. image:: /img/ui-light/demo_complex_dag_overview_with_failed_tasks.png :alt: Overview of a complex Dag in the Grid View, showing the status of all Dag runs, as well as quick links to recently failed task logs | @@ -144,8 +144,6 @@ experience is continuously improving, but defining workflows as code is central .. toctree:: :hidden: :caption: Content - :titlesonly: - :maxdepth: 1 Overview start diff --git a/airflow-core/docs/installation/supported-versions.rst b/airflow-core/docs/installation/supported-versions.rst index 8193b1d62237d..34a04d5c7a23c 100644 --- a/airflow-core/docs/installation/supported-versions.rst +++ b/airflow-core/docs/installation/supported-versions.rst @@ -29,7 +29,7 @@ Apache Airflow® version life cycle: ========= ===================== ========= =============== ===================== ================ Version Current Patch/Minor State First Release Limited Maintenance EOL/Terminated ========= ===================== ========= =============== ===================== ================ -3 3.0.6 Supported Apr 22, 2025 TBD TBD +3 3.1.1 Supported Apr 22, 2025 TBD TBD 2 2.11.0 Supported Dec 17, 2020 Oct 22, 2025 Apr 22, 2026 1.10 1.10.15 EOL Aug 27, 2018 Dec 17, 2020 June 17, 2021 1.9 1.9.0 EOL Jan 03, 2018 Aug 27, 2018 Aug 27, 2018 diff --git a/airflow-core/docs/installation/upgrading_to_airflow3.rst b/airflow-core/docs/installation/upgrading_to_airflow3.rst index c0aa1b8e33ffd..57fd939ac8d40 100644 --- a/airflow-core/docs/installation/upgrading_to_airflow3.rst +++ b/airflow-core/docs/installation/upgrading_to_airflow3.rst @@ -89,24 +89,24 @@ Step 3: Dag authors - Check your Airflow Dags for compatibility To minimize friction for users upgrading from prior versions of Airflow, we have created a Dag upgrade check utility using `Ruff `_ combined with `AIR `_ rules. The rules AIR301 and AIR302 indicate breaking changes in Airflow 3, while AIR311 and AIR312 highlight changes that are not currently breaking but are strongly recommended for updates. -The latest available ``ruff`` version will have the most up-to-date rules, but be sure to use at least version ``0.11.13``. The below example demonstrates how to check +The latest available ``ruff`` version will have the most up-to-date rules, but be sure to use at least version ``0.13.1``. The below example demonstrates how to check for Dag incompatibilities that will need to be fixed before they will work as expected on Airflow 3. .. code-block:: bash - ruff check dags/ --select AIR301 --preview + ruff check dags/ --select AIR301 To preview the recommended fixes, run the following command: .. code-block:: bash - ruff check dags/ --select AIR301 --show-fixes --preview + ruff check dags/ --select AIR301 --show-fixes Some changes can be automatically fixed. To do so, run the following command: .. code-block:: bash - ruff check dags/ --select AIR301 --fix --preview + ruff check dags/ --select AIR301 --fix Some of the fixes are marked as unsafe. Unsafe fixes usually do not break Dag code. They're marked as unsafe as they may change some runtime behavior. For more information, see `Fix Safety `_. @@ -114,12 +114,7 @@ To trigger these fixes, run the following command: .. code-block:: bash - ruff check dags/ --select AIR301 --fix --unsafe-fixes --preview - -.. note:: - Ruff has strict policy about when a rule becomes stable. Till it does you must use --preview flag. - The progress of Airflow Ruff rule become stable can be tracked in https://github.com/astral-sh/ruff/issues/17749 - That said, from Airflow side the rules are perfectly fine to be used. + ruff check dags/ --select AIR301 --fix --unsafe-fixes .. note:: @@ -127,6 +122,68 @@ To trigger these fixes, run the following command: You can also configure these flags through configuration files. See `Configuring Ruff `_ for details. +Key Import Updates +^^^^^^^^^^^^^^^^^^ + +While ruff can automatically fix many import issues, here are the key import changes you'll need to make to ensure your DAGs and other +code import Airflow components correctly in Airflow 3. The older paths are deprecated and will be removed in a future Airflow version. + +.. list-table:: + :header-rows: 1 + :widths: 50, 50 + + * - **Old Import Path (Deprecated)** + - **New Import Path (airflow.sdk)** + * - ``airflow.decorators.dag`` + - ``airflow.sdk.dag`` + * - ``airflow.decorators.task`` + - ``airflow.sdk.task`` + * - ``airflow.decorators.task_group`` + - ``airflow.sdk.task_group`` + * - ``airflow.decorators.setup`` + - ``airflow.sdk.setup`` + * - ``airflow.decorators.teardown`` + - ``airflow.sdk.teardown`` + * - ``airflow.models.dag.DAG`` + - ``airflow.sdk.DAG`` + * - ``airflow.models.baseoperator.BaseOperator`` + - ``airflow.sdk.BaseOperator`` + * - ``airflow.models.param.Param`` + - ``airflow.sdk.Param`` + * - ``airflow.models.param.ParamsDict`` + - ``airflow.sdk.ParamsDict`` + * - ``airflow.models.baseoperatorlink.BaseOperatorLink`` + - ``airflow.sdk.BaseOperatorLink`` + * - ``airflow.sensors.base.BaseSensorOperator`` + - ``airflow.sdk.BaseSensorOperator`` + * - ``airflow.hooks.base.BaseHook`` + - ``airflow.sdk.BaseHook`` + * - ``airflow.notifications.basenotifier.BaseNotifier`` + - ``airflow.sdk.BaseNotifier`` + * - ``airflow.utils.task_group.TaskGroup`` + - ``airflow.sdk.TaskGroup`` + * - ``airflow.datasets.Dataset`` + - ``airflow.sdk.Asset`` + * - ``airflow.datasets.DatasetAlias`` + - ``airflow.sdk.AssetAlias`` + * - ``airflow.datasets.DatasetAll`` + - ``airflow.sdk.AssetAll`` + * - ``airflow.datasets.DatasetAny`` + - ``airflow.sdk.AssetAny`` + * - ``airflow.models.connection.Connection`` + - ``airflow.sdk.Connection`` + * - ``airflow.models.context.Context`` + - ``airflow.sdk.Context`` + * - ``airflow.models.variable.Variable`` + - ``airflow.sdk.Variable`` + * - ``airflow.io.*`` + - ``airflow.sdk.io.*`` + +**Migration Timeline** + +- **Airflow 3.1**: Legacy imports show deprecation warnings but continue to work +- **Future Airflow version**: Legacy imports will be **removed** + Step 4: Install the Standard Provider -------------------------------------- @@ -202,7 +259,7 @@ These include: - **SubDAGs**: Replaced by TaskGroups, Assets, and Data Aware Scheduling. - **Sequential Executor**: Replaced by LocalExecutor, which can be used with SQLite for local development use cases. - **CeleryKubernetesExecutor and LocalKubernetesExecutor**: Replaced by `Multiple Executor Configuration `_ -- **SLAs**: Deprecated and removed; Will be replaced by forthcoming `Deadline Alerts `_. +- **SLAs**: Deprecated and removed; replaced with :doc:`Deadline Alerts `. - **Subdir**: Used as an argument on many CLI commands, ``--subdir`` or ``-S`` has been superseded by :doc:`Dag bundles `. - **REST API** (``/api/v1``) replaced: Use the modern FastAPI-based stable ``/api/v2`` instead; see :doc:`Airflow API v2 ` for details. - **Some Airflow context variables**: The following keys are no longer available in a :ref:`task instance's context `. If not replaced, will cause Dag errors: diff --git a/airflow-core/docs/license.rst b/airflow-core/docs/license.rst index 3ef9a61927834..a5b85d9da238d 100644 --- a/airflow-core/docs/license.rst +++ b/airflow-core/docs/license.rst @@ -20,8 +20,10 @@ License ======== -.. image:: img/apache.jpg +.. image:: img/asf_logo_wide.png :width: 150 + :align: center + .. code-block:: text diff --git a/airflow-core/docs/migrations-ref.rst b/airflow-core/docs/migrations-ref.rst index 1e0c886097e00..c8569e667be75 100644 --- a/airflow-core/docs/migrations-ref.rst +++ b/airflow-core/docs/migrations-ref.rst @@ -39,7 +39,10 @@ Here's the list of all the Database Migrations that are executed via when you ru +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | Revision ID | Revises ID | Airflow Version | Description | +=========================+==================+===================+==============================================================+ -| ``eaf332f43c7c`` (head) | ``a3c7f2b18d4e`` | ``3.1.0`` | add last_parse_duration to dag model. | +| ``cc92b33c6709`` (head) | ``eaf332f43c7c`` | ``3.1.0`` | Add backward compatibility for serialized DAG format v3 to | +| | | | v2. | ++-------------------------+------------------+-------------------+--------------------------------------------------------------+ +| ``eaf332f43c7c`` | ``a3c7f2b18d4e`` | ``3.1.0`` | add last_parse_duration to dag model. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``a3c7f2b18d4e`` | ``7582ea3f3dd5`` | ``3.1.0`` | Add tables to store teams and associations with dag bundles. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ diff --git a/airflow-core/docs/public-airflow-interface.rst b/airflow-core/docs/public-airflow-interface.rst index 9abe6cbd5cb44..a4221e4c3fecf 100644 --- a/airflow-core/docs/public-airflow-interface.rst +++ b/airflow-core/docs/public-airflow-interface.rst @@ -15,9 +15,8 @@ specific language governing permissions and limitations under the License. -===================================== Public Interface for Airflow 3.0+ -===================================== +================================= .. warning:: @@ -27,9 +26,6 @@ Public Interface for Airflow 3.0+ `Airflow 2.11 Public Interface Documentation `_ for the legacy interface. -Public Interface of Airflow -........................... - The Public Interface of Apache Airflow is the collection of interfaces and behaviors in Apache Airflow whose changes are governed by semantic versioning. A user interacts with Airflow's public interface by creating and managing Dags, managing tasks and dependencies, @@ -46,7 +42,7 @@ from task code is no longer allowed. Instead, use the :doc:`Stable REST API `_. Using Airflow Public Interfaces -=============================== +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. note:: @@ -89,7 +85,7 @@ way, the Stable REST API is recommended. Using the Public Interface for Dag authors -========================================== +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The primary interface for Dag authors is the :doc:`airflow.sdk namespace `. This provides a stable, well-defined interface for creating Dags and tasks that is not subject to internal @@ -142,7 +138,7 @@ Legacy import paths (e.g., ``airflow.models.dag.DAG``, ``airflow.decorator.task` removed in a future Airflow version. Dags -==== +---- The Dag is Airflow's core entity that represents a recurring workflow. You can create a Dag by instantiating the :class:`~airflow.sdk.DAG` class in your Dag file. Dags can also have parameters @@ -156,7 +152,6 @@ Airflow has a set of example Dags that you can use to learn how to write Dags .. toctree:: :includehidden: :glob: - :hidden: :maxdepth: 1 _api/airflow/example_dags/index @@ -183,7 +178,7 @@ References for the modules used in Dags are here: .. _pythonapi:operators: Operators -========= +--------- The base classes :class:`~airflow.sdk.BaseOperator` and :class:`~airflow.sdk.BaseSensorOperator` are public and may be extended to make new operators. @@ -193,7 +188,7 @@ from the airflow.sdk namespace. Subclasses of BaseOperator which are published in Apache Airflow are public in *behavior* but not in *structure*. That is to say, the Operator's parameters and behavior is governed by semver but the methods are subject to change at any time. Task Instances -============== +-------------- Task instances are the individual runs of a single task in a Dag (in a Dag Run). Task instances are accessed through the Task Context via :func:`~airflow.sdk.get_current_context`. Direct database access is not possible. @@ -203,7 +198,7 @@ the Task Context via :func:`~airflow.sdk.get_current_context`. Direct database a For detailed API documentation, see the `Task SDK Reference `_. Task Instance Keys -================== +------------------ Task instance keys are unique identifiers of task instances in a Dag (in a Dag Run). A key is a tuple that consists of ``dag_id``, ``task_id``, ``run_id``, ``try_number``, and ``map_index``. @@ -240,7 +235,7 @@ Example of accessing task instance information through Task Context: .. _pythonapi:hooks: Hooks -===== +----- Hooks are interfaces to external platforms and databases, implementing a common interface when possible and acting as building blocks for operators. All hooks @@ -252,13 +247,12 @@ by extending them: .. toctree:: :includehidden: :glob: - :hidden: :maxdepth: 1 _api/airflow/hooks/index Public Airflow utilities -======================== +^^^^^^^^^^^^^^^^^^^^^^^^ When writing or extending Hooks and Operators, Dag authors and developers can use the following classes: @@ -309,7 +303,7 @@ Reference for classes used for the utilities are here: Public Exceptions -================= +^^^^^^^^^^^^^^^^^ When writing the custom Operators and Hooks, you can handle and raise public Exceptions that Airflow exposes: @@ -317,25 +311,23 @@ exposes: .. toctree:: :includehidden: :glob: - :hidden: :maxdepth: 1 _api/airflow/exceptions/index Public Utility classes -====================== +^^^^^^^^^^^^^^^^^^^^^^ .. toctree:: :includehidden: :glob: - :hidden: :maxdepth: 1 _api/airflow/utils/state/index Using Public Interface to extend Airflow capabilities -===================================================== +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Airflow uses Plugin mechanism to extend Airflow platform capabilities. They allow to extend Airflow UI but also they are the way to expose the below customizations (Triggers, Timetables, Listeners, etc.). @@ -348,7 +340,7 @@ that do not require plugins - you can read more about them in :doc:`howto/custom Here are the ways how Plugins can be used to extend Airflow: Triggers -======== +-------- Airflow uses Triggers to implement ``asyncio`` compatible Deferrable Operators. All Triggers derive from :class:`~airflow.triggers.base.BaseTrigger`. @@ -359,7 +351,6 @@ by extending them: .. toctree:: :includehidden: :glob: - :hidden: :maxdepth: 1 _api/airflow/triggers/index @@ -367,7 +358,7 @@ by extending them: You can read more about Triggers in :doc:`authoring-and-scheduling/deferring`. Timetables -========== +---------- Custom timetable implementations provide Airflow's scheduler additional logic to schedule Dag runs in ways not possible with built-in schedule expressions. @@ -378,7 +369,6 @@ by extending them: .. toctree:: :includehidden: - :hidden: :maxdepth: 1 _api/airflow/timetables/index @@ -386,7 +376,7 @@ by extending them: You can read more about Timetables in :doc:`howto/timetable`. Listeners -========= +--------- Listeners enable you to respond to Dag/Task lifecycle events. @@ -400,7 +390,7 @@ can be implemented to respond to Dag/Task lifecycle events. You can read more about Listeners in :doc:`administration-and-deployment/listeners`. Extra Links -=========== +----------- Extra links are dynamic links that could be added to Airflow independently from custom Operators. Normally they can be defined by the Operators, but plugins allow you to override the links on a global level. @@ -408,7 +398,7 @@ they can be defined by the Operators, but plugins allow you to override the link You can read more about the Extra Links in :doc:`/howto/define-extra-link`. Using Public Interface to integrate with external services and applications -=========================================================================== +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Tasks in Airflow can orchestrate external services via Hooks and Operators. The core functionality of @@ -417,7 +407,7 @@ You can read more about providers :doc:`providers `. Executors -========= +--------- Executors are the mechanism by which task instances get run. All executors are derived from :class:`~airflow.executors.base_executor.BaseExecutor`. There are several @@ -437,7 +427,7 @@ You can read more about executors and how to write your own in :doc:`core-concep executors, and custom executors could not provide full functionality that built-in executors had. Secrets Backends -================ +---------------- Airflow can be configured to rely on secrets backends to retrieve :class:`~airflow.sdk.Connection` and :class:`~airflow.sdk.Variable`. @@ -448,7 +438,6 @@ All Secrets Backend implementations are public. You can extend their functionali .. toctree:: :includehidden: :glob: - :hidden: :maxdepth: 1 _api/airflow/secrets/index @@ -458,7 +447,7 @@ You can also find all the available Secrets Backends implemented in community pr in :doc:`apache-airflow-providers:core-extensions/secrets-backends`. Auth managers -============= +------------- Auth managers are responsible of user authentication and user authorization in Airflow. All auth managers are derived from :class:`~airflow.api_fastapi.auth.managers.base_auth_manager.BaseAuthManager`. @@ -469,21 +458,21 @@ public, but the different implementations of auth managers are not (i.e. FabAuth You can read more about auth managers and how to write your own in :doc:`core-concepts/auth-manager/index`. Connections -=========== +----------- When creating Hooks, you can add custom Connections. You can read more about connections in :doc:`apache-airflow-providers:core-extensions/connections` for available Connections implemented in the community providers. Extra Links -=========== +----------- When creating Hooks, you can add custom Extra Links that are displayed when the tasks are run. You can find out more about extra links in :doc:`apache-airflow-providers:core-extensions/extra-links` that also shows available extra links implemented in the community providers. Logging and Monitoring -====================== +---------------------- You can extend the way how logs are written by Airflow. You can find out more about log writing in :doc:`administration-and-deployment/logging-monitoring/index`. @@ -492,7 +481,7 @@ The :doc:`apache-airflow-providers:core-extensions/logging` that also shows avai implemented in the community providers. Decorators -========== +---------- Dag authors can use decorators to author Dags using the :doc:`TaskFlow ` concept. All Decorators derive from :class:`~airflow.sdk.bases.decorator.TaskDecorator`. @@ -512,24 +501,24 @@ by extending them: You can read more about creating custom Decorators in :doc:`howto/create-custom-decorator`. Email notifications -=================== +------------------- Airflow has a built-in way of sending email notifications and it allows to extend it by adding custom email notification classes. You can read more about email notifications in :doc:`howto/email-config`. Notifications -============= +------------- Airflow has a built-in extensible way of sending notifications using the various ``on_*_callback``. You can read more about notifications in :doc:`howto/notifications`. Cluster Policies -================ +---------------- Cluster Policies are the way to dynamically apply cluster-wide policies to the Dags being parsed or tasks being executed. You can read more about Cluster Policies in :doc:`administration-and-deployment/cluster-policies`. Lineage -======= +------- Airflow can help track origins of data, what happens to it and where it moves over time. You can read more about lineage in :doc:`administration-and-deployment/lineage`. @@ -538,7 +527,7 @@ about lineage in :doc:`administration-and-deployment/lineage`. What is not part of the Public Interface of Apache Airflow? -=========================================================== +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Everything not mentioned in this document should be considered as non-Public Interface. diff --git a/airflow-core/docs/security/audit_logs.rst b/airflow-core/docs/security/audit_logs.rst index 8c86a224736ef..c01c99b3fcd98 100644 --- a/airflow-core/docs/security/audit_logs.rst +++ b/airflow-core/docs/security/audit_logs.rst @@ -18,50 +18,607 @@ Audit Logs in Airflow ===================== +Understanding Audit Logs +------------------------- -Overview ---------- +Audit logs serve as the historical record of an Airflow system, documenting who performed what actions and when they occurred. These logs are essential for maintaining system integrity, meeting compliance requirements, and conducting forensic analysis when issues arise. -Audit logs are a critical component of any system that needs to maintain a high level of security and compliance. -They provide a way to track user actions and system events, which can be used to troubleshoot issues, detect security breaches, and ensure regulatory compliance. +In essence, audit logs answer three fundamental questions: -In Airflow, audit logs are used to track user actions and system events that occur during the execution of Dags and tasks. -They are stored in a database and can be accessed through the Airflow UI. +- **Who**: Which user or system component initiated an action +- **What**: The specific operation that was performed +- **When**: The precise timestamp of the event -To be able to see audit logs, a user needs to have the ``Audit Logs.can_read`` permission. Such user will be able to see all audit logs, independently of the Dags permissions applied. +The primary purposes of audit logs include: +- **Regulatory Compliance**: Meeting requirements for data governance and audit trails +- **Security Monitoring**: Detecting unauthorized access or suspicious activities +- **Operational Troubleshooting**: Understanding the sequence of events leading to system issues +- **Change Management**: Tracking modifications to critical system components -Level of Audit Logs +.. note:: + Access to audit logs requires the ``Audit Logs.can_read`` permission. Users with this permission can view all audit entries regardless of their DAG-specific access rights. + + +Understanding Event Logs +------------------------- + +Event logs represent the operational heartbeat of an Airflow system. Unlike audit logs, which focus on accountability and compliance, event logs capture the technical details of system behavior, application performance, and operational metrics. + +Event logs serve several critical functions: + +- **Debugging and Troubleshooting**: Providing detailed error messages and stack traces +- **Performance Monitoring**: Recording execution times, resource usage, and system metrics +- **Operational Insights**: Tracking system health, component interactions, and workflow execution +- **Development Support**: Offering detailed information for code debugging and optimization + +Event logs are typically stored in log files or external logging systems and include information such as: + +- Task execution details and output +- System errors and warnings +- Performance metrics and timing information +- Component startup and shutdown events +- Resource utilization data + +Audit Logs vs Event Logs +------------------------------------------ + +While both logging systems are crucial for system management, they serve distinct purposes and audiences: + +.. list-table:: + :header-rows: 1 + :widths: 25 37 38 + + * - Characteristic + - Audit Logs + - Event Logs + * - **Primary Purpose** + - Accountability and compliance tracking + - Operational monitoring and system debugging + * - **Target Audience** + - Security teams, auditors, compliance officers + - Developers, system administrators, operations teams + * - **Content Focus** + - User actions and administrative changes + - System behavior, errors, and performance data + * - **Storage Location** + - Structured database table (``log``) + - Log files, external logging systems + * - **Retention Requirements** + - Long-term (months to years for compliance) + - Short to medium-term (days to weeks) + * - **Query Patterns** + - "Who modified this configuration?" + - "Why did this task execution fail?" + + +Accessing Audit Logs -------------------- -Audit logs exist at the task level and the user level. +Airflow provides multiple interfaces for accessing audit log data, each suited to different use cases and technical requirements: -- Task Level: At the task level, audit logs capture information related to the execution of a task, such as the start time, end time, and status of the task. +**Web User Interface** + The Airflow web interface provides the most accessible method for viewing audit logs. Navigate to **Browse → Audit Logs** to access an interface with built-in filtering, sorting, and search capabilities. This interface is ideal for ad-hoc investigations and routine monitoring. -- User Level: At the user level, audit logs capture information related to user actions, such as creating, modifying, or deleting a Dag or task. +**REST API Integration** + For programmatic access and system integration, use the ``/eventLogs`` REST API endpoint. This approach enables automated monitoring, integration with external security tools, and custom reporting applications. +**Direct Database Access** + Advanced users can query the ``log`` table directly using SQL. This method provides maximum flexibility for complex queries, custom reporting, and integration with business intelligence tools. -Location of Audit Logs +Scope of Audit Logging ---------------------- -Audit logs can be accessed through the Airflow UI. They are located under the "Browse" tab, and can be viewed by selecting "Audit Logs" from the dropdown menu. +Airflow's audit logging system captures events across three distinct operational domains: + +**User-Initiated Actions** + These events occur when users interact with Airflow through any interface (web UI, REST API, or command-line tools). Examples include: + + - Manual DAG run triggers and modifications + - Configuration changes to variables, connections, and pools + - Task instance state modifications (clearing, marking as success/failed) + - Administrative operations and user management activities + +**System-Generated Events** + These events are automatically created by Airflow's internal processes during normal operation: + + - Task lifecycle state transitions (queued, running, success, failed) + - System monitoring events (heartbeat timeouts, external state changes) + - Automatic recovery operations (task rescheduling, retry attempts) + - Resource management activities + +**Command-Line Interface Operations** + These events capture activities performed through Airflow's CLI tools: + + - Direct task execution commands + - DAG management operations + - System administration and maintenance tasks + - Automated script executions + + +Common Audit Log Scenarios +--------------------------- + +To facilitate audit log analysis, here are some frequently encountered scenarios and their corresponding queries: + +**"Who triggered this DAG?"** + +.. code-block:: sql + + SELECT dttm, owner, extra + FROM log + WHERE event = 'trigger_dag_run' AND dag_id = 'example_dag' + ORDER BY dttm DESC; + +**"What happened to this failed task?"** + +.. code-block:: sql + + SELECT dttm, event, owner, extra + FROM log + WHERE dag_id = 'example_dag' AND task_id = 'example_task' + ORDER BY dttm DESC; + +**"Who changed variables recently?"** + +.. code-block:: sql + + SELECT dttm, event, owner, extra + FROM log + WHERE event LIKE '%variable%' + ORDER BY dttm DESC LIMIT 20; + +Event Catalog +-------------- + +The following section provides a complete reference of all events tracked by Airflow's audit logging system. Understanding these event types will help interpret audit logs and construct effective queries for specific use cases. + +Task Instance Events +~~~~~~~~~~~~~~~~~~~~ + +**System-generated task events**: + +- ``running``: Task instance started execution +- ``success``: Task instance completed successfully +- ``failed``: Task instance failed during execution +- ``skipped``: Task instance was skipped +- ``upstream_failed``: Task instance failed due to upstream failure +- ``up_for_retry``: Task instance is scheduled for retry +- ``up_for_reschedule``: Task instance is rescheduled +- ``queued``: Task instance is queued for execution +- ``scheduled``: Task instance is scheduled +- ``deferred``: Task instance is deferred (waiting for trigger) +- ``restarting``: Task instance is restarting +- ``removed``: Task instance was removed + +**System monitoring events**: + +- ``heartbeat timeout``: Task instance stopped sending heartbeats and will be terminated +- ``state mismatch``: Task instance state changed externally (outside of Airflow) +- ``stuck in queued reschedule``: Task instance was stuck in queued state and rescheduled +- ``stuck in queued tries exceeded``: Task instance exceeded maximum requeue attempts + +**User-initiated task events**: + +- ``fail task``: User manually marked task as failed +- ``skip task``: User manually marked task as skipped +- ``action_set_failed``: User set task instance as failed through UI/API +- ``action_set_success``: User set task instance as successful through UI/API +- ``action_set_retry``: User set task instance to retry +- ``action_set_skipped``: User set task instance as skipped +- ``action_set_running``: User set task instance as running +- ``action_clear``: User cleared task instance state + +User Action Events +~~~~~~~~~~~~~~~~~~ + +**DAG operations**: + +- ``trigger_dag_run``: User triggered a DAG run +- ``delete_dag_run``: User deleted a DAG run +- ``patch_dag_run``: User modified a DAG run +- ``clear_dag_run``: User cleared a DAG run +- ``get_dag_run``: User retrieved DAG run information +- ``get_dag_runs_batch``: User retrieved multiple DAG runs +- ``post_dag_run``: User created a DAG run +- ``patch_dag``: User modified DAG configuration +- ``get_dag``: User retrieved DAG information +- ``get_dags``: User retrieved multiple DAGs +- ``delete_dag``: User deleted a DAG + +**Task instance operations**: + +- ``post_clear_task_instances``: User cleared task instances +- ``patch_task_instance``: User modified a task instance +- ``get_task_instances_batch``: User retrieved task instance information +- ``delete_task_instance``: User deleted a task instance +- ``get_task_instance``: User retrieved single task instance information +- ``get_task_instance_tries``: User retrieved task instance retry information +- ``patch_task_instances_batch``: User modified multiple task instances + +**Variable operations**: + +- ``delete_variable``: User deleted a variable +- ``patch_variable``: User modified a variable +- ``post_variable``: User created a variable +- ``bulk_variables``: User performed bulk variable operations + +**Connection operations**: + +- ``delete_connection``: User deleted a connection +- ``post_connection``: User created a connection +- ``patch_connection``: User modified a connection +- ``bulk_connections``: User performed bulk connection operations +- ``create_default_connections``: User created default connections + +**Pool operations**: + +- ``get_pool``: User retrieved pool information +- ``get_pools``: User retrieved multiple pools +- ``post_pool``: User created a pool +- ``patch_pool``: User modified a pool +- ``delete_pool``: User deleted a pool +- ``bulk_pools``: User performed bulk pool operations + +**Asset operations**: + +- ``get_asset``: User retrieved asset information +- ``get_assets``: User retrieved multiple assets +- ``get_asset_alias``: User retrieved asset alias information +- ``get_asset_aliases``: User retrieved multiple asset aliases +- ``post_asset_events``: User created asset events +- ``get_asset_events``: User retrieved asset events +- ``materialize_asset``: User triggered asset materialization +- ``get_asset_queued_events``: User retrieved queued asset events +- ``delete_asset_queued_events``: User deleted queued asset events +- ``get_dag_asset_queued_events``: User retrieved DAG asset queued events +- ``delete_dag_asset_queued_events``: User deleted DAG asset queued events +- ``get_dag_asset_queued_event``: User retrieved specific DAG asset queued event +- ``delete_dag_asset_queued_event``: User deleted specific DAG asset queued event + +**Backfill operations**: + +- ``get_backfill``: User retrieved backfill information +- ``get_backfills``: User retrieved multiple backfills +- ``post_backfill``: User created a backfill +- ``pause_backfill``: User paused a backfill +- ``unpause_backfill``: User unpaused a backfill +- ``cancel_backfill``: User cancelled a backfill +- ``create_backfill_dry_run``: User performed backfill dry run + +**User and Role Management**: + +- ``get_user``: User retrieved user information +- ``get_users``: User retrieved multiple users +- ``post_user``: User created a user account +- ``patch_user``: User modified a user account +- ``delete_user``: User deleted a user account +- ``get_role``: User retrieved role information +- ``get_roles``: User retrieved multiple roles +- ``post_role``: User created a role +- ``patch_role``: User modified a role +- ``delete_role``: User deleted a role + +CLI Events +~~~~~~~~~~ + +**DAG Management Commands**: + +- ``cli_dags_list``: List all DAGs in the system +- ``cli_dags_show``: Display DAG information and structure +- ``cli_dags_state``: Check the state of a DAG run +- ``cli_dags_next_execution``: Show next execution time for a DAG +- ``cli_dags_trigger``: Trigger a DAG run from command line +- ``cli_dags_delete``: Delete a DAG and its metadata +- ``cli_dags_pause``: Pause a DAG +- ``cli_dags_unpause``: Unpause a DAG +- ``cli_dags_backfill``: Backfill DAG runs for a date range +- ``cli_dags_test``: Test a DAG without affecting the database + +**Task Management Commands**: + +- ``cli_tasks_list``: List tasks for a specific DAG +- ``cli_tasks_run``: Execute a specific task instance +- ``cli_tasks_test``: Test a task without affecting the database +- ``cli_tasks_state``: Check the state of a task instance +- ``cli_tasks_failed_deps``: Show failed dependencies for a task +- ``cli_tasks_render``: Render task templates +- ``cli_tasks_clear``: Clear task instance state + +**Database and System Commands**: + +- ``cli_db_init``: Initialize the Airflow database +- ``cli_db_upgrade``: Upgrade the database schema +- ``cli_db_reset``: Reset the database (dangerous operation) +- ``cli_db_shell``: Open database shell +- ``cli_db_check``: Check database connectivity and schema +- ``cli_db_migrate``: Migrate database schema (legacy command) +- ``cli_migratedb``: Legacy database migration command +- ``cli_initdb``: Legacy database initialization command +- ``cli_resetdb``: Legacy database reset command +- ``cli_upgradedb``: Legacy database upgrade command + +**User and Security Commands**: + +- ``cli_users_create``: Create a new user account +- ``cli_users_delete``: Delete a user account +- ``cli_users_list``: List all users in the system +- ``cli_users_add_role``: Add role to a user +- ``cli_users_remove_role``: Remove role from a user + +**Configuration and Variable Commands**: + +- ``cli_variables_get``: Retrieve variable value +- ``cli_variables_set``: Set variable value +- ``cli_variables_delete``: Delete a variable +- ``cli_variables_list``: List all variables +- ``cli_variables_import``: Import variables from file +- ``cli_variables_export``: Export variables to file + +**Connection Management Commands**: + +- ``cli_connections_get``: Retrieve connection details +- ``cli_connections_add``: Add a new connection +- ``cli_connections_delete``: Delete a connection +- ``cli_connections_list``: List all connections +- ``cli_connections_import``: Import connections from file +- ``cli_connections_export``: Export connections to file + +**Pool Management Commands**: + +- ``cli_pools_get``: Get pool information +- ``cli_pools_set``: Create or update a pool +- ``cli_pools_delete``: Delete a pool +- ``cli_pools_list``: List all pools +- ``cli_pools_import``: Import pools from file +- ``cli_pools_export``: Export pools to file + +**Service and Process Commands**: + +- ``cli_webserver``: Start the Airflow webserver +- ``cli_scheduler``: Start the Airflow scheduler +- ``cli_worker``: Start a Celery worker +- ``cli_flower``: Start Flower monitoring tool +- ``cli_triggerer``: Start the triggerer process +- ``cli_standalone``: Start Airflow in standalone mode +- ``cli_api_server``: Start the Airflow API server +- ``cli_dag_processor``: Start the DAG processor service +- ``cli_celery_worker``: Start Celery worker (alternative command) +- ``cli_celery_flower``: Start Celery Flower (alternative command) + +**Maintenance and Utility Commands**: + +- ``cli_cheat_sheet``: Display CLI command reference +- ``cli_version``: Show Airflow version information +- ``cli_info``: Display system information +- ``cli_config_get_value``: Get configuration value +- ``cli_config_list``: List configuration options +- ``cli_plugins``: List installed plugins +- ``cli_rotate_fernet_key``: Rotate Fernet encryption key +- ``cli_sync_perm``: Synchronize permissions +- ``cli_shell``: Start interactive Python shell +- ``cli_kerberos``: Start Kerberos ticket renewer + +**Testing and Development Commands**: + +- ``cli_test``: Run tests +- ``cli_render``: Render templates +- ``cli_dag_deps``: Show DAG dependencies +- ``cli_task_deps``: Show task dependencies + +**Legacy Commands**: + +- ``cli_run``: Legacy task run command +- ``cli_backfill``: Legacy backfill command +- ``cli_clear``: Legacy clear command +- ``cli_list_dags``: Legacy DAG list command +- ``cli_list_tasks``: Legacy task list command +- ``cli_pause``: Legacy pause command +- ``cli_unpause``: Legacy unpause command +- ``cli_trigger_dag``: Legacy DAG trigger command + +Each CLI command audit log entry includes: + +- **User identification**: Who executed the command +- **Command details**: Full command with arguments +- **Execution context**: Working directory, environment variables +- **Timestamp**: When the command was executed +- **Exit status**: Success or failure indication + +Custom Events +~~~~~~~~~~~~~ + +Airflow allows creating custom audit log entries programmatically: + +.. code-block:: python + + from airflow.models.log import Log + from airflow.utils.session import provide_session + + + @provide_session + def log_custom_event(session=None): + log_entry = Log(event="custom_event", owner="username", extra="Additional context information") + session.add(log_entry) + session.commit() + + +Anatomy of an Audit Log Entry +------------------------------ + +Each audit log record contains structured information that provides a complete picture of the logged event. Understanding these fields is essential for effective log analysis: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Field Name + - Description and Usage + * - ``dttm`` + - Timestamp indicating when the event occurred (UTC timezone) + * - ``event`` + - Descriptive name of the action or event (e.g., ``trigger_dag_run``, ``failed``) + * - ``owner`` + - Identity of the actor: username for user actions, "airflow" for system events + * - ``dag_id`` + - Identifier of the affected DAG (when applicable) + * - ``task_id`` + - Identifier of the affected task (when applicable) + * - ``run_id`` + - Specific DAG run identifier for tracking execution instances + * - ``try_number`` + - Attempt number for task retries and re-executions + * - ``map_index`` + - Index for dynamically mapped tasks + * - ``logical_date`` + - Logical execution date of the DAG run + * - ``extra`` + - JSON-formatted additional context (parameters, error details, etc.) + + +Audit Log Query Methods +----------------------- + +Effective audit log analysis requires understanding the various methods available for querying and retrieving log data. Each method has its strengths and is suited to different scenarios: + +**REST API Examples**: + +.. code-block:: bash + + # Get all audit logs + curl -X GET "http://localhost:8080/api/v1/eventLogs" + + # Filter by event type + curl -X GET "http://localhost:8080/api/v1/eventLogs?event=trigger_dag_run" + + # Filter by DAG + curl -X GET "http://localhost:8080/api/v1/eventLogs?dag_id=example_dag" + + # Filter by date range + curl -X GET "http://localhost:8080/api/v1/eventLogs?after=2024-01-01T00:00:00Z&before=2024-12-31T23:59:59Z" + +**Database Query Examples**: + +.. code-block:: sql + + -- Get recent user actions + SELECT dttm, event, owner, dag_id, task_id, extra + FROM log + WHERE owner IS NOT NULL + ORDER BY dttm DESC + LIMIT 100; + + -- Get task failure events + SELECT dttm, dag_id, task_id, run_id, extra + FROM log + WHERE event = 'failed' + ORDER BY dttm DESC; + + -- Get user actions on specific DAG + SELECT dttm, event, owner, extra + FROM log + WHERE dag_id = 'example_dag' AND owner IS NOT NULL + ORDER BY dttm DESC; + + +Querying Event Logs +------------------- + +Event logs (operational logs) are typically accessed through different methods depending on the logging configuration: + +**Log Files**: + +.. code-block:: bash + + # View scheduler logs + tail -f $AIRFLOW_HOME/logs/scheduler/latest/*.log + + # View webserver logs + tail -f $AIRFLOW_HOME/logs/webserver/webserver.log + + # View task logs for specific DAG run + cat $AIRFLOW_HOME/logs/dag_id/task_id/2024-01-01T00:00:00+00:00/1.log + +**REST API for Task Logs**: + +.. code-block:: bash + + # Get task instance logs + curl -X GET "http://localhost:8080/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/logs/{try_number}" + + # Get task logs with metadata + curl -X GET "http://localhost:8080/api/v1/dags/example_dag/dagRuns/2024-01-01T00:00:00+00:00/taskInstances/example_task/logs/1?full_content=true" + +**Python Logging Integration**: + +.. code-block:: python + + import logging + from airflow.utils.log.logging_mixin import LoggingMixin + + + class MyOperator(BaseOperator, LoggingMixin): + def execute(self, context): + # These will appear in event logs + self.log.info("Task started") + self.log.warning("Warning message") + self.log.error("Error occurred") + +**External Logging Systems**: + +When using external logging systems (e.g., ELK stack, Splunk, CloudWatch): + +.. code-block:: bash + + # Example Elasticsearch query + curl -X GET "elasticsearch:9200/airflow-*/_search" -H 'Content-Type: application/json' -d' + { + "query": { + "bool": { + "must": [ + {"match": {"dag_id": "example_dag"}}, + {"range": {"@timestamp": {"gte": "2024-01-01", "lte": "2024-01-31"}}} + ] + } + } + }' + + +Practical Query Examples +------------------------------------- + +The following examples demonstrate practical applications of audit log queries for common operational and security scenarios. These queries serve as templates that can be adapted for specific requirements: + +**Security Investigation** + +.. code-block:: sql + + -- Find all actions by a specific user in the last 24 hours + SELECT dttm, event, dag_id, task_id, extra + FROM log + WHERE owner = 'suspicious_user' + AND dttm > NOW() - INTERVAL '24 hours' + ORDER BY dttm DESC; + +**Compliance Reporting** +.. code-block:: sql -Types of Events ---------------- + -- Get all variable and connection changes for audit report + SELECT dttm, event, owner, extra + FROM log + WHERE event IN ('post_variable', 'patch_variable', 'delete_variable', + 'post_connection', 'patch_connection', 'delete_connection') + AND dttm BETWEEN '2024-01-01' AND '2024-01-31' + ORDER BY dttm; -Airflow provides a set of predefined events that can be tracked in audit logs. These events include, but aren't limited to: +**Troubleshooting DAG Issues** -- ``trigger``: Triggering a Dag -- ``[variable,connection].create``: A user created a Connection or Variable -- ``[variable,connection].edit``: A user modified a Connection or Variable -- ``[variable,connection].delete``: A user deleted a Connection or Variable -- ``delete``: A user deleted a Dag or task -- ``failed``: Airflow or a user set a task as failed -- ``success``: Airflow or a user set a task as success -- ``retry``: Airflow or a user retried a task instance -- ``clear``: A user cleared a task's state -- ``cli_task_run``: Airflow triggered a task instance +.. code-block:: sql -In addition to these predefined events, Airflow allows you to define custom events that can be tracked in audit logs. -This can be done by calling the ``log`` method of the ``TaskInstance`` object. + -- See all events for a problematic DAG run + SELECT dttm, event, task_id, owner, extra + FROM log + WHERE dag_id = 'example_dag' + AND run_id = '2024-01-15T10:00:00+00:00' + ORDER BY dttm; diff --git a/airflow-core/docs/start.rst b/airflow-core/docs/start.rst index 3ad574bdeefab..2f934118e255d 100644 --- a/airflow-core/docs/start.rst +++ b/airflow-core/docs/start.rst @@ -68,7 +68,7 @@ This quick start guide will help you bootstrap an Airflow standalone instance on :substitutions: - AIRFLOW_VERSION=3.0.3 + AIRFLOW_VERSION=3.1.1 # Extract the version of Python you have installed. If you're currently using a Python version that is not supported by Airflow, you may want to set this manually. # See above for supported versions. diff --git a/airflow-core/docs/troubleshooting.rst b/airflow-core/docs/troubleshooting.rst index 6756ab87e1051..b0f786469e420 100644 --- a/airflow-core/docs/troubleshooting.rst +++ b/airflow-core/docs/troubleshooting.rst @@ -36,16 +36,26 @@ Below are some example scenarios that could cause a task's state to change by a - A user marked the task as successful or failed in the Airflow UI. - An external script or process used the :doc:`Airflow REST API ` to change the state of a task. -TaskRunner killed ------------------ +Process terminated by signal +---------------------------- Sometimes, Airflow or some adjacent system will kill a task instance's ``TaskRunner``, causing the task instance to fail. -Here are some examples that could cause such an event: +Below we discuss a few common cases. -- A Dag run timeout, specified by ``dagrun_timeout`` in the Dag's definition. -- An Airflow worker running out of memory - - Usually, Airflow workers that run out of memory receive a SIGKILL, and the scheduler will fail the corresponding task instance for not having a heartbeat. However, in some scenarios, Airflow kills the task before that happens. +Dag run timeout +""""""""""""""" + +A dag run timeout can be specified by ``dagrun_timeout`` in the dag's definition. +The task process would likely be killed with SIGTERM (exit code -15). + +Out of memory error (OOM) +""""""""""""""""""""""""" + +When a task process consumes too much memory for a worker, the best case scenario is it is killed +with SIGKILL (exit code -9). Depending on configuration and infrastructure, it is also +possible that the whole worker will be killed due to OOM and then the tasks would be marked as +failed after failing to heartbeat. Lingering task supervisor processes ----------------------------------- diff --git a/airflow-core/docs/tutorial/fundamentals.rst b/airflow-core/docs/tutorial/fundamentals.rst index 0017860e343dc..02e60b5e8d153 100644 --- a/airflow-core/docs/tutorial/fundamentals.rst +++ b/airflow-core/docs/tutorial/fundamentals.rst @@ -165,11 +165,11 @@ documentation at the start of your Dag file. | -.. image:: ../img/ui-dark/task_doc.png +.. image:: ../img/ui-light/task_doc.png | -.. image:: ../img/ui-dark/dag_doc.png +.. image:: ../img/ui-light/dag_doc.png Setting up Dependencies ----------------------- diff --git a/airflow-core/docs/tutorial/hitl.rst b/airflow-core/docs/tutorial/hitl.rst index b104bc7d03366..cc6a76b5ef1ec 100644 --- a/airflow-core/docs/tutorial/hitl.rst +++ b/airflow-core/docs/tutorial/hitl.rst @@ -52,7 +52,7 @@ This is useful for workflows involving human guidance within large language mode You can click the task and find the Required Actions tab in the details panel. -.. image:: /img/hitl_wait_for_input.png +.. image:: /img/ui-light/hitl_wait_for_input.png :alt: Demo HITL task instance waiting for input | @@ -71,7 +71,7 @@ Users can select one of the available options, which can be used to direct the w | -.. image:: /img/hitl_wait_for_option.png +.. image:: /img/ui-light/hitl_wait_for_option.png :alt: Demo HITL task instance waiting for an option | @@ -86,7 +86,7 @@ Multiple options are also allowed. | -.. image:: /img/hitl_wait_for_multiple_options.png +.. image:: /img/ui-light/hitl_wait_for_multiple_options.png :alt: Demo HITL task instance waiting for multiple options | @@ -95,6 +95,9 @@ Approval or Rejection --------------------- A specialized form of option selection, which has only 'Approval' and 'Rejection' as options. +You can also set the ``assigned_users`` to restrict the users allowed to respond for a HITL operator. +It should be a list of user ids and user names (both needed) (e.g., ``[{"id": "1", "name": "user1"}, {"id": "2", "name": "user2"}]``. +ONLY the users within this list will be allowed to respond. .. exampleinclude:: /../../providers/standard/src/airflow/providers/standard/example_dags/example_hitl_operator.py :language: python @@ -106,7 +109,7 @@ A specialized form of option selection, which has only 'Approval' and 'Rejection As you can see in the body of this code snippet, you can use XComs to get information provided by the user. -.. image:: /img/hitl_approve_reject.png +.. image:: /img/ui-light/hitl_approve_reject.png :alt: Demo HITL task instance waiting for approval or rejection | @@ -136,14 +139,14 @@ And remember to specify their relationship in the workflow. | -.. image:: /img/hitl_branch_selection.png +.. image:: /img/ui-light/hitl_branch_selection.png :alt: Demo HITL task instance waiting for branch selection | After the branch is chosen, the workflow will proceed along the selected path. -.. image:: /img/hitl_branch_selected.png +.. image:: /img/ui-light/hitl_branch_selected.png :alt: Demo HITL task instance after branch selection Notifiers diff --git a/airflow-core/docs/tutorial/pipeline.rst b/airflow-core/docs/tutorial/pipeline.rst index c1b956ae29960..196ee7857bbb2 100644 --- a/airflow-core/docs/tutorial/pipeline.rst +++ b/airflow-core/docs/tutorial/pipeline.rst @@ -95,7 +95,7 @@ Fill in the following details: - Password: ``airflow`` - Port: ``5432`` -.. image:: ../img/ui-dark/tutorial_pipeline_add_connection.png +.. image:: ../img/ui-light/tutorial_pipeline_add_connection.png :alt: Add Connection form in Airflow's web UI with Postgres details filled in. | @@ -341,16 +341,21 @@ run using the play button. You can watch each task as it runs in the **Grid** view, and explore logs for each step. -.. image:: ../img/ui-dark/tutorial_pipeline_dag_list.png +.. image:: ../img/ui-light/tutorial_pipeline_dag_list_trigger.png :alt: Dag List view showing the ``process_employees`` Dag | -.. image:: ../img/ui-dark/tutorial_pipeline_dag_overview_processed.png +.. image:: ../img/ui-light/tutorial_pipeline_dag_overview_processed.png :alt: Dag Overview page for ``process_employees`` Dag showing the Dag run | +.. image:: ../img/ui-light/tutorial_pipeline_dag_task_instance_logs.png + :alt: Task instance page for a task in ``process_employees`` Dag showing the task instance logs + +| + Once it succeeds, you'll have a fully working pipeline that integrates data from the outside world, loads it into Postgres, and keeps it clean. diff --git a/airflow-core/newsfragments/46929.bugfix.rst b/airflow-core/newsfragments/46929.bugfix.rst deleted file mode 100644 index bff83a3807dae..0000000000000 --- a/airflow-core/newsfragments/46929.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Added validation in XCom.set() to disallow None or empty string keys; XCom.get() still allows None as key but disallows empty strings. diff --git a/airflow-core/newsfragments/49779.significant.rst b/airflow-core/newsfragments/49779.significant.rst deleted file mode 100644 index 187f6ac199198..0000000000000 --- a/airflow-core/newsfragments/49779.significant.rst +++ /dev/null @@ -1,20 +0,0 @@ -SecretCache class has been moved to ``airflow.sdk.execution_time.cache`` from ``airflow.secrets.cache`` - -* Types of change - - * [ ] Dag changes - * [ ] Config changes - * [ ] API changes - * [ ] CLI changes - * [ ] Behaviour changes - * [ ] Plugin changes - * [ ] Dependency changes - * [x] Code interface changes - -* Migration rules needed - - * ruff - - * AIR301 - - * [ ] ``airflow.secrets.cache.SecretCache`` → ``airflow.sdk.execution_time.cache.SecretCache`` diff --git a/airflow-core/newsfragments/50374.feature.rst b/airflow-core/newsfragments/50374.feature.rst deleted file mode 100644 index 85e4dc165e9c7..0000000000000 --- a/airflow-core/newsfragments/50374.feature.rst +++ /dev/null @@ -1 +0,0 @@ -When a Dag specifies ``schedule="@once"`` without an explicit ``start_date``, run it as soon as convenient. (Previously, the Dag would never run.) diff --git a/airflow-core/newsfragments/50693.significant.rst b/airflow-core/newsfragments/50693.significant.rst deleted file mode 100644 index 6368ddf0ee56c..0000000000000 --- a/airflow-core/newsfragments/50693.significant.rst +++ /dev/null @@ -1,41 +0,0 @@ -Unused webserver configuration options have been removed - -The following webserver options were moved into the ``api`` section: - -* ``[webserver] log_fetch_timeout_sec`` → ``[api] log_fetch_timeout_sec`` -* ``[webserver] hide_paused_dags_by_default`` → ``[api] hide_paused_dags_by_default`` -* ``[webserver] page_size`` → ``[api] page_size`` -* ``[webserver] default_wrap`` → ``[api] default_wrap`` -* ``[webserver] require_confirmation_dag_change`` → ``[api] require_confirmation_dag_change`` -* ``[webserver] auto_refresh_interval`` → ``[api] auto_refresh_interval`` - -The following configuration options are now unused and have been removed: - -- ``[webserver] instance_name_has_markup`` -- ``[webserver] warn_deployment_exposure`` - -* Types of change - - * [ ] Dag changes - * [x] Config changes - * [ ] API changes - * [ ] CLI changes - * [ ] Behaviour changes - * [ ] Plugin changes - * [ ] Dependency changes - * [ ] Code interface changes - -.. List the migration rules needed for this change (see https://github.com/apache/airflow/issues/41641) - -* Migration rules needed - - * ``airflow config lint`` - - * [ ] Remove configuration option ``[webserver] instance_name_has_markup`` - * [ ] Remove configuration option ``[webserver] warn_deployment_exposure`` - * [ ] [webserver] log_fetch_timeout_sec`` → ``[api] log_fetch_timeout_sec`` - * [ ] [webserver] hide_paused_dags_by_default`` → ``[api] hide_paused_dags_by_default`` - * [ ] [webserver] page_size`` → ``[api] page_size`` - * [ ] [webserver] default_wrap`` → ``[api] default_wrap`` - * [ ] [webserver] require_confirmation_dag_change`` → ``[api] require_confirmation_dag_change`` - * [ ] [webserver] auto_refresh_interval`` → ``[api] auto_refresh_interval`` diff --git a/airflow-core/newsfragments/51424.significant.rst b/airflow-core/newsfragments/51424.significant.rst deleted file mode 100644 index a455a28eb1c9b..0000000000000 --- a/airflow-core/newsfragments/51424.significant.rst +++ /dev/null @@ -1,17 +0,0 @@ -The ``consuming_dags`` key in asset API has been renamed to ``scheduled_dags``. - -The previous name caused confusion to users since the list does not contain all -Dags that technically *use* the asset, but only those that use it in their -``schedule`` argument. As a bug fix, the key has been renamed to clarify its -intention. - -* Types of change - - * [ ] Dag changes - * [ ] Config changes - * [x] API changes - * [ ] CLI changes - * [ ] Behaviour changes - * [ ] Plugin changes - * [ ] Dependency changes - * [ ] Code interface changes diff --git a/airflow-core/newsfragments/51639.significant.rst b/airflow-core/newsfragments/51639.significant.rst deleted file mode 100644 index 78708b4eb1913..0000000000000 --- a/airflow-core/newsfragments/51639.significant.rst +++ /dev/null @@ -1,17 +0,0 @@ -``enable_xcom_deserialize_support`` configuration option has been removed. - -This configuration was previously marked as a security risk due to potential remote code execution vulnerabilities -when deserializing arbitrary Python objects that came in from XComs. The removal is a security improvement since -all custom XCom serialization/deserialization is now handled safely at the worker level, making this configuration -unnecessary in core. Users should migrate to not setting this configuration. - -* Types of change - - * [ ] Dag changes - * [x] Config changes - * [ ] API changes - * [ ] CLI changes - * [ ] Behaviour changes - * [ ] Plugin changes - * [ ] Dependency changes - * [ ] Code interface changes diff --git a/airflow-core/newsfragments/52860.significant.rst b/airflow-core/newsfragments/52860.significant.rst deleted file mode 100644 index 5962897ec206d..0000000000000 --- a/airflow-core/newsfragments/52860.significant.rst +++ /dev/null @@ -1,17 +0,0 @@ -Replace API server ``access_logfile`` configuration with ``log_config`` - -The API server configuration option ``[api] access_logfile`` has been replaced with ``[api] log_config`` to align with uvicorn's logging configuration instead of the legacy gunicorn approach. -The new ``log_config`` option accepts a path to a logging configuration file compatible with ``logging.config.fileConfig``, providing more flexible logging configuration for the API server. - -This change also removes the dependency on gunicorn for daemonization, making the API server ``--daemon`` option consistent with other Airflow components like scheduler and triggerer. - -* Types of change - - * [ ] Dag changes - * [x] Config changes - * [ ] API changes - * [ ] CLI changes - * [ ] Behaviour changes - * [ ] Plugin changes - * [ ] Dependency changes - * [ ] Code interface changes diff --git a/airflow-core/newsfragments/53631.misc.rst b/airflow-core/newsfragments/53631.misc.rst deleted file mode 100644 index a6cef457b5844..0000000000000 --- a/airflow-core/newsfragments/53631.misc.rst +++ /dev/null @@ -1 +0,0 @@ -The constraint do not contain developer dependencies as of Airflow 3.1.0 diff --git a/airflow-core/newsfragments/53727.feature.rst b/airflow-core/newsfragments/53727.feature.rst deleted file mode 100644 index 90272000d1d1c..0000000000000 --- a/airflow-core/newsfragments/53727.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add Airflow Deadlines feature in Airflow 3.1. See https://airflow.apache.org/docs/apache-airflow/stable/howto/deadline-alerts.html. diff --git a/airflow-core/newsfragments/53796.misc.rst b/airflow-core/newsfragments/53796.misc.rst deleted file mode 100644 index a582154dc3ae6..0000000000000 --- a/airflow-core/newsfragments/53796.misc.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``RemovedInAirflow4Warning`` warnings for ``airflow.security.permissions`` imports and ``access_control`` Dag attribute usage. diff --git a/airflow-core/newsfragments/54857.significant.rst b/airflow-core/newsfragments/54857.significant.rst deleted file mode 100644 index 84ba878db595f..0000000000000 --- a/airflow-core/newsfragments/54857.significant.rst +++ /dev/null @@ -1,14 +0,0 @@ -Remove ``get_task_group_children_getter`` and ``task_group_to_dict`` from task-sdk - -The ``get_task_group_children_getter`` and ``task_group_to_dict`` functions have been removed from the task-sdk (``airflow.sdk.definitions.taskgroup``) and moved to server-side API services. These functions are now internal to Airflow's API layer and should not be imported directly by users. - -* Types of change - - * [ ] Dag changes - * [ ] Config changes - * [ ] API changes - * [ ] CLI changes - * [ ] Behaviour changes - * [ ] Plugin changes - * [ ] Dependency changes - * [x] Code interface changes diff --git a/airflow-core/newsfragments/56583.significant.rst b/airflow-core/newsfragments/56583.significant.rst new file mode 100644 index 0000000000000..3e80bfe0cbb03 --- /dev/null +++ b/airflow-core/newsfragments/56583.significant.rst @@ -0,0 +1,49 @@ +Fix Connection & Variable access in API server contexts (plugins, log handlers) + +Previously, hooks used in API server contexts (plugins, middlewares, log handlers) would fail with an ``ImportError`` +for ``SUPERVISOR_COMMS``, because ``SUPERVISOR_COMMS`` only exists in task runner child processes. + +This has been fixed by implementing automatic context detection with three separate secrets backend chains: + +**Context Detection:** + +1. **Client contexts** (task runner in worker): Detected via ``SUPERVISOR_COMMS`` presence +2. **Server contexts** (API server, scheduler): Explicitly marked with ``_AIRFLOW_PROCESS_CONTEXT=server`` environment variable +3. **Fallback contexts** (supervisor, unknown contexts): Neither marker present, uses minimal safe chain + +**Backend Chains:** + +- **Client**: ``EnvironmentVariablesBackend`` → ``ExecutionAPISecretsBackend`` (routes to Execution API via SUPERVISOR_COMMS) +- **Server**: ``EnvironmentVariablesBackend`` → ``MetastoreBackend`` (direct database access) +- **Fallback**: ``EnvironmentVariablesBackend`` only (+ external backends from config like AWS Secrets Manager, Vault) + +The fallback chain is crucial for supervisor processes (worker-side, before task runner starts) which need to access +external secrets for remote logging setup but should not use ``MetastoreBackend`` (to maintain worker isolation). + +**Architecture Benefits:** + +- Workers (supervisor + task runner) never use ``MetastoreBackend``, maintaining strict isolation +- External secrets backends (AWS Secrets Manager, Vault, etc.) work in all three contexts +- Supervisor falls back to Execution API client for connections not found in external backends +- API server and scheduler have direct database access for optimal performance + +**Impact:** + +- Hooks like ``GCSHook``, ``S3Hook`` now work correctly in log handlers and plugins +- No code changes required for existing plugins or hooks +- Workers remain isolated from direct database access (network-level DB blocking fully supported) +- External secrets work everywhere (workers, supervisor, API server) +- Robust handling of unknown contexts with safe minimal chain + +See: `#56120 `__, `#56583 `__, `#51816 `__ + +* Types of change + + * [ ] Dag changes + * [ ] Config changes + * [ ] API changes + * [ ] CLI changes + * [ ] Behaviour changes + * [ ] Plugin changes + * [ ] Dependency changes + * [ ] Code interface changes diff --git a/airflow-core/newsfragments/56609.significant.rst b/airflow-core/newsfragments/56609.significant.rst new file mode 100644 index 0000000000000..b32e4c9611687 --- /dev/null +++ b/airflow-core/newsfragments/56609.significant.rst @@ -0,0 +1,14 @@ +Remove insecure dagReports API endpoint that executed user code in API server + +The ``/api/v2/dagReports`` endpoint has been removed because it loaded user DAG files directly in the API server process, violating Airflow's security architecture. This endpoint was not used in the UI and had no known consumers. Use the ``airflow dags report`` CLI command instead for DAG loading reports. + +* Types of change + + * [ ] Dag changes + * [ ] Config changes + * [x] API changes + * [ ] CLI changes + * [ ] Behaviour changes + * [ ] Plugin changes + * [ ] Dependency changes + * [ ] Code interface changes diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml index 7348391d7cb18..80874d9678cea 100644 --- a/airflow-core/pyproject.toml +++ b/airflow-core/pyproject.toml @@ -25,7 +25,7 @@ requires = [ "pluggy==1.6.0", "smmap==5.0.2", "tomli==2.2.1; python_version < '3.11'", - "trove-classifiers==2025.9.8.13", + "trove-classifiers==2025.9.11.17", ] build-backend = "hatchling.build" @@ -63,7 +63,7 @@ classifiers = [ ] # Version is defined in src/airflow/__init__.py and it is automatically synchronized by prek hook -version = "3.1.0" +version = "3.1.1" dependencies = [ "a2wsgi>=1.10.8", @@ -82,7 +82,7 @@ dependencies = [ "cryptography>=41.0.0", "deprecated>=1.2.13", "dill>=0.2.2", - "fastapi[standard-no-fastapi-cloud-cli]>=0.116.0", + "fastapi[standard-no-fastapi-cloud-cli]>=0.116.0,<0.118.0", "starlette>=0.45.0", "httpx>=0.25.0", 'importlib_metadata>=6.5;python_version<"3.12"', @@ -134,17 +134,21 @@ dependencies = [ "tenacity>=8.3.0", "termcolor>=3.0.0", "typing-extensions>=4.14.1", - # Universal Pathlib 0.2.4 adds extra validation for Paths and our integration with local file paths - # Does not work with it Tracked in https://github.com/fsspec/universal_pathlib/issues/276 - "universal-pathlib>=0.2.2,!=0.2.4", + # https://github.com/apache/airflow/issues/56369 , rework universal-pathlib usage + "universal-pathlib>=0.2.6,<0.3.0", "uuid6>=2024.7.10", - "apache-airflow-task-sdk<1.2.0,>=1.1.0", + "apache-airflow-task-sdk<1.2.0,>=1.1.1", # pre-installed providers - "apache-airflow-providers-common-compat>=1.6.0", - "apache-airflow-providers-common-io>=1.5.3", - "apache-airflow-providers-common-sql>=1.26.0", - "apache-airflow-providers-smtp>=2.0.2", - "apache-airflow-providers-standard>=0.4.0", + "apache-airflow-providers-common-compat>=1.7.4", + "apache-airflow-providers-common-io>=1.6.3", + "apache-airflow-providers-common-sql>=1.28.1", + "apache-airflow-providers-smtp>=2.3.1", + "apache-airflow-providers-standard>=1.9.0", + # Start of shared logging dependencies + "msgspec>=0.19.0", + "pygtrie>=2.5.0", + "structlog>=25.4.0", + # End of shared logging dependencies ] @@ -153,6 +157,7 @@ dependencies = [ "eventlet>=0.37.0", "gevent>=25.4.1", "greenlet>=3.1.0", + "greenback>=1.2.1", ] "graphviz" = [ # The graphviz package creates friction when installing on MacOS as it needs graphviz system package to @@ -211,8 +216,9 @@ exclude = [ ] [tool.hatch.build.targets.sdist.force-include] -"../shared/timezones/src/airflow_shared/timezones" = "src/airflow/_shared/timezones" +"../shared/logging/src/airflow_shared/logging" = "src/airflow/_shared/logging" "../shared/secrets_masker/src/airflow_shared/secrets_masker" = "src/airflow/_shared/secrets_masker" +"../shared/timezones/src/airflow_shared/timezones" = "src/airflow/_shared/timezones" [tool.hatch.build.targets.custom] path = "./hatch_build.py" @@ -280,6 +286,7 @@ apache-airflow-devel-common = { workspace = true } [tool.airflow] shared_distributions = [ - "apache-airflow-shared-timezones", + "apache-airflow-shared-logging", "apache-airflow-shared-secrets-masker", + "apache-airflow-shared-timezones", ] diff --git a/airflow-core/src/airflow/__init__.py b/airflow-core/src/airflow/__init__.py index 5c2d08b41c924..d4ca8ab685e86 100644 --- a/airflow-core/src/airflow/__init__.py +++ b/airflow-core/src/airflow/__init__.py @@ -25,7 +25,7 @@ # lib.) This is required by some IDEs to resolve the import paths. __path__ = __import__("pkgutil").extend_path(__path__, __name__) -__version__ = "3.1.0" +__version__ = "3.1.1" import os diff --git a/airflow-core/src/airflow/_shared/logging b/airflow-core/src/airflow/_shared/logging new file mode 120000 index 0000000000000..19c320ffcf9ca --- /dev/null +++ b/airflow-core/src/airflow/_shared/logging @@ -0,0 +1 @@ +../../../../shared/logging/src/airflow_shared/logging \ No newline at end of file diff --git a/airflow-core/src/airflow/api/common/mark_tasks.py b/airflow-core/src/airflow/api/common/mark_tasks.py index d424bab603a9b..5c0ed4b9f5fec 100644 --- a/airflow-core/src/airflow/api/common/mark_tasks.py +++ b/airflow-core/src/airflow/api/common/mark_tasks.py @@ -20,7 +20,7 @@ from __future__ import annotations from collections.abc import Collection, Iterable -from typing import TYPE_CHECKING, TypeAlias, cast +from typing import TYPE_CHECKING, TypeAlias from sqlalchemy import and_, or_, select from sqlalchemy.orm import lazyload @@ -228,9 +228,7 @@ def set_dag_run_state_to_success( if not run_id: raise ValueError(f"Invalid dag_run_id: {run_id}") - # TODO (GH-52141): 'tasks' in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - tasks = cast("list[Operator]", dag.tasks) + tasks = dag.tasks # Mark all task instances of the dag run to success - except for unfinished teardown as they need to complete work. teardown_tasks = [task for task in tasks if task.is_teardown] @@ -312,13 +310,7 @@ def _set_runing_task(task: Operator) -> Operator: task.dag = dag return task - # TODO (GH-52141): 'tasks' in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - running_tasks = [ - _set_runing_task(task) - for task in cast("list[Operator]", dag.tasks) - if task.task_id in task_ids_of_running_tis - ] + running_tasks = [_set_runing_task(task) for task in dag.tasks if task.task_id in task_ids_of_running_tis] # Mark non-finished tasks as SKIPPED. pending_tis: list[TaskInstance] = session.scalars( diff --git a/airflow-core/src/airflow/api/common/trigger_dag.py b/airflow-core/src/airflow/api/common/trigger_dag.py index fa793d221ec58..614140b58c4a9 100644 --- a/airflow-core/src/airflow/api/common/trigger_dag.py +++ b/airflow-core/src/airflow/api/common/trigger_dag.py @@ -92,10 +92,10 @@ def _trigger_dag( else: data_interval = None - run_id = run_id or DagRun.generate_run_id( + run_id = run_id or dag.timetable.generate_run_id( run_type=DagRunType.MANUAL, - logical_date=coerced_logical_date, run_after=timezone.coerce_datetime(run_after), + data_interval=data_interval, ) # This intentionally does not use 'session' in the current scope because it diff --git a/airflow-core/src/airflow/api_fastapi/app.py b/airflow-core/src/airflow/api_fastapi/app.py index f515be6992c60..3e76c4f8f2df3 100644 --- a/airflow-core/src/airflow/api_fastapi/app.py +++ b/airflow-core/src/airflow/api_fastapi/app.py @@ -29,7 +29,6 @@ init_config, init_error_handlers, init_flask_plugins, - init_middlewares, init_ui_plugins, init_views, ) @@ -49,6 +48,9 @@ # Define the full path on which the potential auth manager fastapi is mounted AUTH_MANAGER_FASTAPI_APP_PREFIX = f"{API_ROOT_PATH}auth" +# Fast API apps mounted under these prefixes are not allowed +RESERVED_URL_PREFIXES = ["/api/v2", "/ui", "/execution"] + log = logging.getLogger(__name__) app: FastAPI | None = None @@ -97,7 +99,6 @@ def create_app(apps: str = "all") -> FastAPI: init_ui_plugins(app) init_views(app) # Core views need to be the last routes added - it has a catch all route init_error_handlers(app) - init_middlewares(app) init_config(app) @@ -185,6 +186,12 @@ def init_plugins(app: FastAPI) -> None: if url_prefix is None: log.error("'url_prefix' key is missing for the fastapi app: %s", name) continue + if url_prefix == "": + log.error("'url_prefix' key is empty string for the fastapi app: %s", name) + continue + if any(url_prefix.startswith(prefix) for prefix in RESERVED_URL_PREFIXES): + log.error("Plugin %s attempted to use reserved url_prefix '%s'", name, url_prefix) + continue log.debug("Adding subapplication %s under prefix %s", name, url_prefix) app.mount(url_prefix, subapp) @@ -200,5 +207,9 @@ def init_plugins(app: FastAPI) -> None: log.error("'middleware' key is missing for the fastapi middleware: %s", name) continue + if not callable(middleware): + log.error("'middleware' value for %s is should be callable: %s", name, middleware) + continue + log.debug("Adding root middleware %s", name) app.add_middleware(middleware, *args, **kwargs) diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/routes/login.py b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/routes/login.py index f46674301ead1..372aecf603525 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/routes/login.py +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/routes/login.py @@ -94,6 +94,7 @@ def login_all_admins(request: Request) -> RedirectResponse: COOKIE_NAME_JWT_TOKEN, SimpleAuthManagerLogin.create_token_all_admins(), secure=secure, + httponly=True, ) return response diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json index 18780182ff402..5c2a403d1e15b 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@chakra-ui/react": "^3.25.0", "@tanstack/react-query": "^5.85.5", - "axios": "^1.11.0", + "axios": "^1.12.0", "next-themes": "^0.4.6", "react": "^19.1.1", "react-cookie": "^8.0.1", @@ -3669,9 +3669,9 @@ } }, "node_modules/axios": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", - "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.0.tgz", + "integrity": "sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json index dd681473cfd04..4867439f68315 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json @@ -17,7 +17,7 @@ "dependencies": { "@chakra-ui/react": "^3.25.0", "@tanstack/react-query": "^5.85.5", - "axios": "^1.11.0", + "axios": "^1.12.0", "next-themes": "^0.4.6", "react": "^19.1.1", "react-cookie": "^8.0.1", diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml index 7621169aa6a35..0f6e6c66950ef 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^5.85.5 version: 5.85.5(react@19.1.1) axios: - specifier: ^1.11.0 - version: 1.11.0 + specifier: ^1.12.0 + version: 1.12.0 next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -173,8 +173,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} engines: {node: '>=6.0.0'} hasBin: true @@ -182,8 +182,8 @@ packages: resolution: {integrity: sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.3': - resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} '@babel/template@7.27.1': @@ -198,16 +198,16 @@ packages: resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.3': - resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} '@babel/types@7.27.1': resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} '@chakra-ui/react@3.25.0': @@ -538,8 +538,8 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@jsdevtools/ono@7.1.3': resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} @@ -1203,8 +1203,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.0: - resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-styles@4.3.0: @@ -1215,8 +1215,8 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} anymatch@3.1.3: @@ -1283,8 +1283,8 @@ packages: resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} engines: {node: '>=4'} - axios@1.11.0: - resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} + axios@1.12.0: + resolution: {integrity: sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -1740,8 +1740,8 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -2594,8 +2594,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} strip-indent@3.0.0: @@ -2967,18 +2967,18 @@ snapshots: '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-globals@7.28.0': {} '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color @@ -2990,13 +2990,13 @@ snapshots: dependencies: '@babel/types': 7.27.1 - '@babel/parser@7.28.3': + '@babel/parser@7.28.4': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/runtime@7.27.1': {} - '@babel/runtime@7.28.3': {} + '@babel/runtime@7.28.4': {} '@babel/template@7.27.1': dependencies: @@ -3007,8 +3007,8 @@ snapshots: '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@babel/traverse@7.27.1': dependencies: @@ -3022,14 +3022,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/traverse@7.28.3': + '@babel/traverse@7.28.4': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -3039,7 +3039,7 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/types@7.28.2': + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 @@ -3061,7 +3061,7 @@ snapshots: '@emotion/babel-plugin@11.13.5': dependencies: '@babel/helper-module-imports': 7.27.1 - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 '@emotion/serialize': 1.3.3 @@ -3092,7 +3092,7 @@ snapshots: '@emotion/react@11.14.0(@types/react@19.1.11)(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 @@ -3304,7 +3304,7 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 @@ -3312,7 +3312,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/gen-mapping@0.3.8': dependencies: @@ -3333,7 +3333,7 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping@0.3.30': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 @@ -3498,7 +3498,7 @@ snapshots: '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -4296,7 +4296,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.0: {} + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: @@ -4304,7 +4304,7 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} anymatch@3.1.3: dependencies: @@ -4388,9 +4388,9 @@ snapshots: axe-core@4.10.3: {} - axios@1.11.0: + axios@1.12.0: dependencies: - follow-redirects: 1.15.9 + follow-redirects: 1.15.11 form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -4400,7 +4400,7 @@ snapshots: babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 cosmiconfig: 7.1.0 resolve: 1.22.10 @@ -4989,7 +4989,7 @@ snapshots: flatted@3.3.3: {} - follow-redirects@1.15.9: {} + follow-redirects@1.15.11: {} for-each@0.3.5: dependencies: @@ -5364,8 +5364,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 source-map-js: 1.2.1 optional: true @@ -5834,7 +5834,7 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 string.prototype.includes@2.0.1: dependencies: @@ -5890,9 +5890,9 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.1.2: dependencies: - ansi-regex: 6.2.0 + ansi-regex: 6.2.2 strip-indent@3.0.0: dependencies: @@ -6183,9 +6183,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 yallist@4.0.0: {} diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/login/Login.tsx b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/login/Login.tsx index 6aa65345361fa..7d3bb4733e076 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/login/Login.tsx +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/login/Login.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { Flex, Alert, CloseButton, Container, Heading, Span, Text } from "@chakra-ui/react"; +import { Alert, CloseButton, Container, Heading, Span, Text, Box, HStack } from "@chakra-ui/react"; import type { LoginResponse } from "openapi-gen/requests/types.gen"; import { useState } from "react"; import { useCookies } from "react-cookie"; @@ -78,58 +78,78 @@ export const Login = () => { }; return ( - - - - - Sign into Airflow - - - - {Boolean(error) && } - - Enter your username and password below: - - {isBannerDisabled === null && ( - - - - Simple auth manager enabled - - The Simple auth manager is intended for development and testing. If you're using it in - production, ensure that access is controlled through other means. Please read{" "} - - - the documentation - - {" "} - to learn more about simple auth manager. - - - { - localStorage.setItem(LOCAL_STORAGE_DISABLE_BANNER_KEY, "1"); - setIsBannerDisabled("1"); - }} - pos="relative" - top="-2" - /> - - )} - + + + + + Sign into Airflow + + + + {Boolean(error) && ( + + + + )} + + + Enter your username and password below: + + + + + {isBannerDisabled === null && ( + + + + Simple auth manager enabled + + The Simple auth manager is intended for development and testing. If you're using it in + production, ensure that access is controlled through other means. Please read{" "} + + + the documentation + + {" "} + to learn more about simple auth manager. + + + { + localStorage.setItem(LOCAL_STORAGE_DISABLE_BANNER_KEY, "1"); + setIsBannerDisabled("1"); + }} + pos="relative" + top="-2" + /> + + )} + + ); }; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/login/LoginForm.tsx b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/login/LoginForm.tsx index 69a6b4f14fc0a..0b466e02274e0 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/login/LoginForm.tsx +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/login/LoginForm.tsx @@ -54,7 +54,7 @@ export const LoginForm = ({ isPending, onLogin }: LoginFormProps) => { Username {/* eslint-disable-next-line jsx-a11y/no-autofocus */} - + )} rules={{ required: true }} @@ -66,13 +66,13 @@ export const LoginForm = ({ isPending, onLogin }: LoginFormProps) => { render={({ field, fieldState }) => ( Password - + )} rules={{ required: true }} /> - diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/main.tsx b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/main.tsx index 4356f0fb6040a..43e48541704d2 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/main.tsx +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/main.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { ChakraProvider, defaultSystem } from "@chakra-ui/react"; +import { ChakraProvider } from "@chakra-ui/react"; import { QueryClientProvider } from "@tanstack/react-query"; import { ThemeProvider } from "next-themes"; import { CookiesProvider } from "react-cookie"; @@ -24,11 +24,12 @@ import { createRoot } from "react-dom/client"; import { RouterProvider } from "react-router-dom"; import { router } from "src/router"; +import { system } from "src/theme"; import { queryClient } from "./queryClient"; createRoot(document.querySelector("#root") as HTMLDivElement).render( - + diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/theme.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/theme.ts new file mode 100644 index 0000000000000..7d40d21ef8093 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/src/theme.ts @@ -0,0 +1,407 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +/* THIS FILE IS A COPY OF THE AIRFLOW UI THEME FILE LOCATED IN + airflow-core/src/airflow/ui/src/theme.ts +*/ +/* eslint-disable perfectionist/sort-objects */ +/* eslint-disable max-lines */ +import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"; + +const generateSemanticTokens = (color: string, darkContrast: string = "white") => ({ + solid: { value: `{colors.${color}.600}` }, + contrast: { value: { _light: "white", _dark: darkContrast } }, + fg: { value: { _light: `{colors.${color}.800}`, _dark: `{colors.${color}.200}` } }, + muted: { value: { _light: `{colors.${color}.200}`, _dark: `{colors.${color}.800}` } }, + subtle: { value: { _light: `{colors.${color}.100}`, _dark: `{colors.${color}.900}` } }, + emphasized: { value: { _light: `{colors.${color}.300}`, _dark: `{colors.${color}.700}` } }, + focusRing: { value: { _light: `{colors.${color}.800}`, _dark: `{colors.${color}.200}` } }, +}); + +export const customConfig = defineConfig({ + // See https://chakra-ui.com/docs/theming/colors for more information on the colors used here. + theme: { + tokens: { + colors: { + black: { value: "oklch(0.23185 0.0323 266.44)" }, // Custom value for dark mode + brand: { + "50": { value: "oklch(0.98 0.006 248.717)" }, + "100": { value: "oklch(0.962 0.012 249.460)" }, + "200": { value: "oklch(0.923 0.023 255.082)" }, + "300": { value: "oklch(0.865 0.039 252.420)" }, + "400": { value: "oklch(0.705 0.066 256.378)" }, + "500": { value: "oklch(0.575 0.08 257.759)" }, + "600": { value: "oklch(0.469 0.084 257.657)" }, + "700": { value: "oklch(0.399 0.084 257.850)" }, + "800": { value: "oklch(0.324 0.072 260.329)" }, + "900": { value: "oklch(0.259 0.062 265.566)" }, + "950": { value: "oklch(0.179 0.05 265.487)" }, + }, + gray: { + // Values modified from original Tailwind to improve contrast in Chakra UI + "50": { value: "oklch(0.985 0.004 253)" }, // Original: oklch(0.985 0.002 247.839) + "100": { value: "oklch(0.955 0.006 253)" }, // Original: oklch(0.967 0.003 264.542) + "200": { value: "oklch(0.915 0.01 253)" }, // Original: oklch(0.928 0.006 264.531) + "300": { value: "oklch(0.85 0.016 253)" }, // Original: oklch(0.872 0.01 258.338) + "400": { value: "oklch(0.75 0.025 252)" }, // Original: oklch(0.707 0.022 261.325) + "500": { value: "oklch(0.63 0.042 252)" }, // Original: oklch(0.551 0.027 264.364) + "600": { value: "oklch(0.45 0.055 251)" }, // Original: oklch(0.446 0.03 256.802) + "700": { value: "oklch(0.35 0.045 251)" }, // Original: oklch(0.373 0.034 259.733) + "800": { value: "oklch(0.28 0.035 251)" }, // Original: oklch(0.278 0.033 256.848) + "900": { value: "oklch(0.18 0.03 251)" }, // Original: oklch(0.21 0.034 264.665) + "950": { value: "oklch(0.11 0.025 251)" }, // Original: oklch(0.13 0.028 261.692) + }, + // TAILWIND 4.0 COLORS + // See https://tailwindcss.com/docs/colors for more information on the colors used here. + red: { + "50": { value: "oklch(0.971 0.013 17.38)" }, + "100": { value: "oklch(0.936 0.032 17.717)" }, + "200": { value: "oklch(0.885 0.062 18.334)" }, + "300": { value: "oklch(0.808 0.114 19.571)" }, + "400": { value: "oklch(0.704 0.191 22.216)" }, + "500": { value: "oklch(0.637 0.237 25.331)" }, + "600": { value: "oklch(0.577 0.245 27.325)" }, + "700": { value: "oklch(0.505 0.213 27.518)" }, + "800": { value: "oklch(0.444 0.177 26.899)" }, + "900": { value: "oklch(0.396 0.141 25.723)" }, + "950": { value: "oklch(0.258 0.092 26.042)" }, + }, + // Values modified from original Tailwind to improve contrast in Chakra UI + orange: { + "50": { value: "oklch(0.982 0.013 83.915)" }, + "100": { value: "oklch(0.961 0.033 82.320)" }, + "200": { value: "oklch(0.918 0.065 79.975)" }, + "300": { value: "oklch(0.857 0.118 76.815)" }, + "400": { value: "oklch(0.7492 0.1439 62.081)" }, // Original: oklch(0.774 0.186 71.555) + "500": { value: "oklch(0.6462 0.1979 43.792)" }, // Original: oklch(0.705 0.213 47.604) + "600": { value: "oklch(0.5902 0.198 35.93)" }, // Original: oklch(0.632 0.214 41.185) + "700": { value: "oklch(0.553 0.184 41.777)" }, + "800": { value: "oklch(0.469 0.144 45.164)" }, + "900": { value: "oklch(0.414 0.110 48.717)" }, + "950": { value: "oklch(0.271 0.069 52.345)" }, + }, + amber: { + "50": { value: "oklch(0.987 0.022 95.277)" }, + "100": { value: "oklch(0.962 0.059 95.617)" }, + "200": { value: "oklch(0.924 0.12 95.746)" }, + "300": { value: "oklch(0.879 0.169 91.605)" }, + "400": { value: "oklch(0.828 0.189 84.429)" }, + "500": { value: "oklch(0.769 0.188 70.08)" }, + "600": { value: "oklch(0.666 0.179 58.318)" }, + "700": { value: "oklch(0.555 0.163 48.998)" }, + "800": { value: "oklch(0.473 0.137 46.201)" }, + "900": { value: "oklch(0.414 0.112 45.904)" }, + "950": { value: "oklch(0.279 0.077 45.635)" }, + }, + yellow: { + "50": { value: "oklch(0.987 0.026 102.212)" }, + "100": { value: "oklch(0.973 0.071 103.193)" }, + "200": { value: "oklch(0.945 0.129 101.54)" }, + "300": { value: "oklch(0.905 0.182 98.111)" }, + "400": { value: "oklch(0.852 0.199 91.936)" }, + "500": { value: "oklch(0.795 0.184 86.047)" }, + "600": { value: "oklch(0.681 0.162 75.834)" }, + "700": { value: "oklch(0.554 0.135 66.442)" }, + "800": { value: "oklch(0.476 0.114 61.907)" }, + "900": { value: "oklch(0.421 0.095 57.708)" }, + "950": { value: "oklch(0.286 0.066 53.813)" }, + }, + lime: { + "50": { value: "oklch(0.986 0.031 120.757)" }, + "100": { value: "oklch(0.967 0.067 122.328)" }, + "200": { value: "oklch(0.938 0.127 124.321)" }, + "300": { value: "oklch(0.897 0.196 126.665)" }, + "400": { value: "oklch(0.841 0.238 128.85)" }, + "500": { value: "oklch(0.768 0.233 130.85)" }, + "600": { value: "oklch(0.648 0.2 131.684)" }, + "700": { value: "oklch(0.532 0.157 131.589)" }, + "800": { value: "oklch(0.453 0.124 130.933)" }, + "900": { value: "oklch(0.405 0.101 131.063)" }, + "950": { value: "oklch(0.274 0.072 132.109)" }, + }, + green: { + // Values modified from original Tailwind to improve contrast in Chakra UI + "50": { value: "oklch(0.982 0.018 155.826)" }, + "100": { value: "oklch(0.962 0.044 156.743)" }, + "200": { value: "oklch(0.925 0.084 155.995)" }, + "300": { value: "oklch(0.75 0.18 153.0)" }, // Original: oklch(0.871 0.15 154.449) + "400": { value: "oklch(0.625 0.209 150.0)" }, // Original: oklch(0.792 0.209 151.711) + "500": { value: "oklch(0.528 0.219 149.579)" }, // Original: oklch(0.723 0.219 149.579) + "600": { value: "oklch(0.47 0.20 149.0)" }, // Original: oklch(0.627 0.194 149.214) + "700": { value: "oklch(0.40 0.16 149.5)" }, // Original: oklch(0.527 0.154 150.069) + "800": { value: "oklch(0.448 0.119 151.328)" }, + "900": { value: "oklch(0.393 0.095 152.535)" }, + "950": { value: "oklch(0.266 0.065 152.934)" }, + }, + emerald: { + "50": { value: "oklch(0.979 0.021 166.113)" }, + "100": { value: "oklch(0.95 0.052 163.051)" }, + "200": { value: "oklch(0.905 0.093 164.15)" }, + "300": { value: "oklch(0.845 0.143 164.978)" }, + "400": { value: "oklch(0.765 0.177 163.223)" }, + "500": { value: "oklch(0.696 0.17 162.48)" }, + "600": { value: "oklch(0.596 0.145 163.225)" }, + "700": { value: "oklch(0.508 0.118 165.612)" }, + "800": { value: "oklch(0.432 0.095 166.913)" }, + "900": { value: "oklch(0.378 0.077 168.94)" }, + "950": { value: "oklch(0.262 0.051 172.552)" }, + }, + teal: { + "50": { value: "oklch(0.984 0.014 180.72)" }, + "100": { value: "oklch(0.953 0.051 180.801)" }, + "200": { value: "oklch(0.91 0.096 180.426)" }, + "300": { value: "oklch(0.855 0.138 181.071)" }, + "400": { value: "oklch(0.777 0.152 181.912)" }, + "500": { value: "oklch(0.704 0.14 182.503)" }, + "600": { value: "oklch(0.6 0.118 184.704)" }, + "700": { value: "oklch(0.511 0.096 186.391)" }, + "800": { value: "oklch(0.437 0.078 188.216)" }, + "900": { value: "oklch(0.386 0.063 188.416)" }, + "950": { value: "oklch(0.277 0.046 192.524)" }, + }, + cyan: { + "50": { value: "oklch(0.984 0.019 200.873)" }, + "100": { value: "oklch(0.956 0.045 203.388)" }, + "200": { value: "oklch(0.917 0.08 205.041)" }, + "300": { value: "oklch(0.865 0.127 207.078)" }, + "400": { value: "oklch(0.789 0.154 211.53)" }, + "500": { value: "oklch(0.715 0.143 215.221)" }, + "600": { value: "oklch(0.609 0.126 221.723)" }, + "700": { value: "oklch(0.52 0.105 223.128)" }, + "800": { value: "oklch(0.45 0.085 224.283)" }, + "900": { value: "oklch(0.398 0.07 227.392)" }, + "950": { value: "oklch(0.302 0.056 229.695)" }, + }, + sky: { + "50": { value: "oklch(0.977 0.013 236.62)" }, + "100": { value: "oklch(0.951 0.026 236.824)" }, + "200": { value: "oklch(0.901 0.058 230.902)" }, + "300": { value: "oklch(0.828 0.111 230.318)" }, + "400": { value: "oklch(0.746 0.16 232.661)" }, + "500": { value: "oklch(0.685 0.169 237.323)" }, + "600": { value: "oklch(0.588 0.158 241.966)" }, + "700": { value: "oklch(0.5 0.134 242.749)" }, + "800": { value: "oklch(0.443 0.11 240.79)" }, + "900": { value: "oklch(0.391 0.09 240.876)" }, + "950": { value: "oklch(0.293 0.066 243.157)" }, + }, + blue: { + "50": { value: "oklch(0.97 0.014 254.604)" }, + "100": { value: "oklch(0.932 0.032 255.585)" }, + "200": { value: "oklch(0.882 0.059 254.128)" }, + "300": { value: "oklch(0.809 0.105 251.813)" }, + "400": { value: "oklch(0.707 0.165 254.624)" }, + "500": { value: "oklch(0.623 0.214 259.815)" }, + "600": { value: "oklch(0.546 0.245 262.881)" }, + "700": { value: "oklch(0.488 0.243 264.376)" }, + "800": { value: "oklch(0.424 0.199 265.638)" }, + "900": { value: "oklch(0.379 0.146 265.522)" }, + "950": { value: "oklch(0.282 0.091 267.935)" }, + }, + indigo: { + "50": { value: "oklch(0.962 0.018 272.314)" }, + "100": { value: "oklch(0.93 0.034 272.788)" }, + "200": { value: "oklch(0.87 0.065 274.039)" }, + "300": { value: "oklch(0.785 0.115 274.713)" }, + "400": { value: "oklch(0.673 0.182 276.935)" }, + "500": { value: "oklch(0.585 0.233 277.117)" }, + "600": { value: "oklch(0.511 0.262 276.966)" }, + "700": { value: "oklch(0.457 0.24 277.023)" }, + "800": { value: "oklch(0.398 0.195 277.366)" }, + "900": { value: "oklch(0.359 0.144 278.697)" }, + "950": { value: "oklch(0.257 0.09 281.288)" }, + }, + violet: { + "50": { value: "oklch(0.969 0.016 293.756)" }, + "100": { value: "oklch(0.943 0.029 294.588)" }, + "200": { value: "oklch(0.894 0.057 293.283)" }, + "300": { value: "oklch(0.811 0.111 293.571)" }, + "400": { value: "oklch(0.702 0.183 293.541)" }, + "500": { value: "oklch(0.606 0.25 292.717)" }, + "600": { value: "oklch(0.541 0.281 293.009)" }, + "700": { value: "oklch(0.491 0.27 292.581)" }, + "800": { value: "oklch(0.432 0.232 292.759)" }, + "900": { value: "oklch(0.38 0.189 293.745)" }, + "950": { value: "oklch(0.283 0.141 291.089)" }, + }, + purple: { + "50": { value: "oklch(0.977 0.014 308.299)" }, + "100": { value: "oklch(0.946 0.033 307.174)" }, + "200": { value: "oklch(0.902 0.063 306.703)" }, + "300": { value: "oklch(0.827 0.119 306.383)" }, + "400": { value: "oklch(0.714 0.203 305.504)" }, + "500": { value: "oklch(0.627 0.265 303.9)" }, + "600": { value: "oklch(0.558 0.288 302.321)" }, + "700": { value: "oklch(0.496 0.265 301.924)" }, + "800": { value: "oklch(0.438 0.218 303.724)" }, + "900": { value: "oklch(0.381 0.176 304.987)" }, + "950": { value: "oklch(0.291 0.149 302.717)" }, + }, + fuchsia: { + "50": { value: "oklch(0.977 0.017 320.058)" }, + "100": { value: "oklch(0.952 0.037 318.852)" }, + "200": { value: "oklch(0.903 0.076 319.62)" }, + "300": { value: "oklch(0.833 0.145 321.434)" }, + "400": { value: "oklch(0.74 0.238 322.16)" }, + "500": { value: "oklch(0.667 0.295 322.15)" }, + "600": { value: "oklch(0.591 0.293 322.896)" }, + "700": { value: "oklch(0.518 0.253 323.949)" }, + "800": { value: "oklch(0.452 0.211 324.591)" }, + "900": { value: "oklch(0.401 0.17 325.612)" }, + "950": { value: "oklch(0.293 0.136 325.661)" }, + }, + pink: { + "50": { value: "oklch(0.971 0.014 343.198)" }, + "100": { value: "oklch(0.948 0.028 342.258)" }, + "200": { value: "oklch(0.899 0.061 343.231)" }, + "300": { value: "oklch(0.823 0.12 346.018)" }, + "400": { value: "oklch(0.718 0.202 349.761)" }, + "500": { value: "oklch(0.656 0.241 354.308)" }, + "600": { value: "oklch(0.592 0.249 0.584)" }, + "700": { value: "oklch(0.525 0.223 3.958)" }, + "800": { value: "oklch(0.459 0.187 3.815)" }, + "900": { value: "oklch(0.408 0.153 2.432)" }, + "950": { value: "oklch(0.284 0.109 3.907)" }, + }, + rose: { + "50": { value: "oklch(0.969 0.015 12.422)" }, + "100": { value: "oklch(0.941 0.03 12.58)" }, + "200": { value: "oklch(0.892 0.058 10.001)" }, + "300": { value: "oklch(0.81 0.117 11.638)" }, + "400": { value: "oklch(0.712 0.194 13.428)" }, + "500": { value: "oklch(0.645 0.246 16.439)" }, + "600": { value: "oklch(0.586 0.253 17.585)" }, + "700": { value: "oklch(0.514 0.222 16.935)" }, + "800": { value: "oklch(0.455 0.188 13.697)" }, + "900": { value: "oklch(0.41 0.159 10.272)" }, + "950": { value: "oklch(0.271 0.105 12.094)" }, + }, + slate: { + "50": { value: "oklch(0.984 0.003 247.858)" }, + "100": { value: "oklch(0.968 0.007 247.896)" }, + "200": { value: "oklch(0.929 0.013 255.508)" }, + "300": { value: "oklch(0.869 0.022 252.894)" }, + "400": { value: "oklch(0.704 0.04 256.788)" }, + "500": { value: "oklch(0.554 0.046 257.417)" }, + "600": { value: "oklch(0.446 0.043 257.281)" }, + "700": { value: "oklch(0.372 0.044 257.287)" }, + "800": { value: "oklch(0.279 0.041 260.031)" }, + "900": { value: "oklch(0.208 0.042 265.755)" }, + "950": { value: "oklch(0.129 0.042 264.695)" }, + }, + zinc: { + "50": { value: "oklch(0.985 0 0)" }, + "100": { value: "oklch(0.967 0.001 286.375)" }, + "200": { value: "oklch(0.92 0.004 286.32)" }, + "300": { value: "oklch(0.871 0.006 286.286)" }, + "400": { value: "oklch(0.705 0.015 286.067)" }, + "500": { value: "oklch(0.552 0.016 285.938)" }, + "600": { value: "oklch(0.442 0.017 285.786)" }, + "700": { value: "oklch(0.37 0.013 285.805)" }, + "800": { value: "oklch(0.274 0.006 286.033)" }, + "900": { value: "oklch(0.21 0.006 285.885)" }, + "950": { value: "oklch(0.141 0.005 285.823)" }, + }, + neutral: { + "50": { value: "oklch(0.985 0 0)" }, + "100": { value: "oklch(0.97 0 0)" }, + "200": { value: "oklch(0.922 0 0)" }, + "300": { value: "oklch(0.87 0 0)" }, + "400": { value: "oklch(0.708 0 0)" }, + "500": { value: "oklch(0.556 0 0)" }, + "600": { value: "oklch(0.439 0 0)" }, + "700": { value: "oklch(0.371 0 0)" }, + "800": { value: "oklch(0.269 0 0)" }, + "900": { value: "oklch(0.205 0 0)" }, + "950": { value: "oklch(0.145 0 0)" }, + }, + stone: { + "50": { value: "oklch(0.985 0.001 106.423)" }, + "100": { value: "oklch(0.97 0.001 106.424)" }, + "200": { value: "oklch(0.923 0.003 48.717)" }, + "300": { value: "oklch(0.869 0.005 56.366)" }, + "400": { value: "oklch(0.709 0.01 56.259)" }, + "500": { value: "oklch(0.553 0.013 58.071)" }, + "600": { value: "oklch(0.444 0.011 73.639)" }, + "700": { value: "oklch(0.374 0.01 67.558)" }, + "800": { value: "oklch(0.268 0.007 34.298)" }, + "900": { value: "oklch(0.216 0.006 56.043)" }, + "950": { value: "oklch(0.147 0.004 49.25)" }, + }, + }, + }, + semanticTokens: { + colors: { + // Brand colors for consistent theming + brand: generateSemanticTokens("brand"), + // GENERIC STATE + danger: generateSemanticTokens("red"), + info: generateSemanticTokens("blue"), + warning: generateSemanticTokens("amber"), + error: generateSemanticTokens("red"), + // AIRFLOW TASK STATE + active: generateSemanticTokens("blue"), + success: generateSemanticTokens("green"), + failed: generateSemanticTokens("red"), + queued: generateSemanticTokens("stone"), + skipped: generateSemanticTokens("pink"), + up_for_reschedule: generateSemanticTokens("sky"), + up_for_retry: generateSemanticTokens("yellow"), + upstream_failed: generateSemanticTokens("orange"), + running: generateSemanticTokens("cyan"), + restarting: generateSemanticTokens("violet"), + deferred: generateSemanticTokens("purple"), + scheduled: generateSemanticTokens("zinc"), + none: generateSemanticTokens("gray"), + removed: generateSemanticTokens("slate"), + // TAILWIND 4.0 COLORS + red: generateSemanticTokens("red"), + orange: generateSemanticTokens("orange"), + amber: generateSemanticTokens("amber"), + yellow: generateSemanticTokens("yellow"), + lime: generateSemanticTokens("lime"), + green: generateSemanticTokens("green"), + emerald: generateSemanticTokens("emerald"), + teal: generateSemanticTokens("teal"), + cyan: generateSemanticTokens("cyan"), + sky: generateSemanticTokens("sky"), + blue: generateSemanticTokens("blue"), + indigo: generateSemanticTokens("indigo"), + violet: generateSemanticTokens("violet"), + purple: generateSemanticTokens("purple"), + fuchsia: generateSemanticTokens("fuchsia"), + pink: generateSemanticTokens("pink"), + rose: generateSemanticTokens("rose"), + slate: generateSemanticTokens("slate"), + gray: generateSemanticTokens("gray"), + zinc: generateSemanticTokens("zinc"), + neutral: generateSemanticTokens("neutral"), + stone: generateSemanticTokens("stone"), + }, + }, + }, +}); + +export const system = createSystem(defaultConfig, customConfig); + +// Utility function to resolve CSS variables to their computed values +// See: https://github.com/chakra-ui/panda/discussions/2200 +export const getComputedCSSVariableValue = (variable: string): string => + getComputedStyle(document.documentElement) + .getPropertyValue(variable.slice(4, variable.length - 1)) + .trim(); diff --git a/airflow-core/src/airflow/api_fastapi/common/parameters.py b/airflow-core/src/airflow/api_fastapi/common/parameters.py index f1d876f29b631..668e6721f8736 100644 --- a/airflow-core/src/airflow/api_fastapi/common/parameters.py +++ b/airflow-core/src/airflow/api_fastapi/common/parameters.py @@ -53,6 +53,7 @@ from airflow.models.dag_favorite import DagFavorite from airflow.models.dag_version import DagVersion from airflow.models.dagrun import DagRun +from airflow.models.errors import ParseImportError from airflow.models.hitl import HITLDetail from airflow.models.pool import Pool from airflow.models.taskinstance import TaskInstance @@ -282,9 +283,15 @@ def depends(cls, *args: Any, **kwargs: Any) -> Self: raise NotImplementedError("Use dynamic_depends, depends not implemented.") def dynamic_depends(self, default: str | None = None) -> Callable: + to_replace_attrs = list(self.to_replace.keys()) if self.to_replace else [] + + all_attrs = self.allowed_attrs + to_replace_attrs + def inner( order_by: list[str] = Query( - default=[default] if default is not None else [self.get_primary_key_string()] + default=[default] if default is not None else [self.get_primary_key_string()], + description=f"Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. " + f"Supported attributes: `{', '.join(all_attrs) if all_attrs else self.get_primary_key_string()}`", ), ) -> SortParam: return self.set_value(order_by) @@ -718,7 +725,10 @@ def to_orm(self, select: Select) -> Select: pending_actions_count_subquery = ( sql_select(func.count(HITLDetail.ti_id)) .join(TaskInstance, HITLDetail.ti_id == TaskInstance.id) - .where(HITLDetail.response_at.is_(None)) + .where( + HITLDetail.responded_at.is_(None), + TaskInstance.state == TaskInstanceState.DEFERRED, + ) .where(TaskInstance.dag_id == DagModel.dag_id) .scalar_subquery() ) @@ -898,6 +908,15 @@ def _transform_ti_states(states: list[str] | None) -> list[TaskInstanceState | N ), ] +QueryTIMapIndexFilter = Annotated[ + FilterParam[list[int]], + Depends( + filter_param_factory( + TaskInstance.map_index, list[int], FilterOptionEnum.ANY_EQUAL, default_factory=list + ) + ), +] + # XCom QueryXComKeyPatternSearch = Annotated[ _SearchParam, Depends(search_param_factory(XComModel.key, "xcom_key_pattern")) @@ -984,14 +1003,24 @@ def _optional_boolean(value: bool | None) -> bool | None: ) ), ] -QueryHITLDetailDagRunIdFilter = Annotated[ - FilterParam[str], +QueryHITLDetailTaskIdFilter = Annotated[ + FilterParam[str | None], Depends( filter_param_factory( - TaskInstance.run_id, - str, - filter_name="dag_run_id", - ), + TaskInstance.task_id, + str | None, + filter_name="task_id", + ) + ), +] +QueryHITLDetailMapIndexFilter = Annotated[ + FilterParam[int | None], + Depends( + filter_param_factory( + TaskInstance.map_index, + int | None, + filter_name="map_index", + ) ), ] QueryHITLDetailSubjectSearch = Annotated[ @@ -1026,11 +1055,11 @@ def _optional_boolean(value: bool | None) -> bool | None: FilterParam[list[str]], Depends( filter_param_factory( - HITLDetail.responded_user_id, + HITLDetail.responded_by_user_id, list[str], FilterOptionEnum.ANY_EQUAL, default_factory=list, - filter_name="responded_user_id", + filter_name="responded_by_user_id", ) ), ] @@ -1038,31 +1067,16 @@ def _optional_boolean(value: bool | None) -> bool | None: FilterParam[list[str]], Depends( filter_param_factory( - HITLDetail.responded_user_name, + HITLDetail.responded_by_user_name, list[str], FilterOptionEnum.ANY_EQUAL, default_factory=list, - filter_name="responded_user_name", - ) - ), -] -QueryHITLDetailDagIdFilter = Annotated[ - FilterParam[str | None], - Depends( - filter_param_factory( - TaskInstance.dag_id, - str | None, - filter_name="dag_id", + filter_name="responded_by_user_name", ) ), ] -QueryHITLDetailTaskIdFilter = Annotated[ - FilterParam[str | None], - Depends( - filter_param_factory( - TaskInstance.task_id, - str | None, - filter_name="task_id", - ) - ), + +# Parse Import Errors +QueryParseImportErrorFilenamePatternSearch = Annotated[ + _SearchParam, Depends(search_param_factory(ParseImportError.filename, "filename_pattern")) ] diff --git a/airflow-core/src/airflow/api_fastapi/core_api/app.py b/airflow-core/src/airflow/api_fastapi/core_api/app.py index 7cf4e0c92f646..5cb7c6570cdd8 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/app.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/app.py @@ -181,17 +181,6 @@ def init_error_handlers(app: FastAPI) -> None: app.add_exception_handler(handler.exception_cls, handler.exception_handler) -def init_middlewares(app: FastAPI) -> None: - from airflow.configuration import conf - - if "SimpleAuthManager" in conf.get("core", "auth_manager") and conf.getboolean( - "core", "simple_auth_manager_all_admins" - ): - from airflow.api_fastapi.auth.managers.simple.middleware import SimpleAllAdminMiddleware - - app.add_middleware(SimpleAllAdminMiddleware) - - def init_ui_plugins(app: FastAPI) -> None: """Initialize UI plugins.""" from airflow import plugins_manager diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/assets.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/assets.py index 8261cfa11ea7a..dd08cc16ec01d 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/assets.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/assets.py @@ -19,7 +19,7 @@ from datetime import datetime -from pydantic import AliasPath, Field, NonNegativeInt, field_validator +from pydantic import AliasPath, ConfigDict, Field, NonNegativeInt, field_validator from airflow._shared.secrets_masker import redact from airflow.api_fastapi.core_api.base import BaseModel, StrictBaseModel @@ -171,7 +171,4 @@ def set_from_rest_api(cls, v: dict) -> dict: v["from_rest_api"] = True return v - class Config: - """Pydantic config.""" - - extra = "forbid" + model_config = ConfigDict(extra="forbid") diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dag_run.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dag_run.py index ed7aac2ae000f..96c3a3a13ad0f 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dag_run.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dag_run.py @@ -26,7 +26,6 @@ from airflow._shared.timezones import timezone from airflow.api_fastapi.core_api.base import BaseModel, StrictBaseModel from airflow.api_fastapi.core_api.datamodels.dag_versions import DagVersionResponse -from airflow.models import DagRun from airflow.timetables.base import DataInterval from airflow.utils.state import DagRunState from airflow.utils.types import DagRunTriggeredByType, DagRunType @@ -106,12 +105,12 @@ class TriggerDAGRunPostBody(StrictBaseModel): note: str | None = None @model_validator(mode="after") - def check_data_intervals(cls, values): - if (values.data_interval_start is None) != (values.data_interval_end is None): + def check_data_intervals(self): + if (self.data_interval_start is None) != (self.data_interval_end is None): raise ValueError( "Either both data_interval_start and data_interval_end must be provided or both must be None" ) - return values + return self def validate_context(self, dag: SerializedDAG) -> dict: coerced_logical_date = timezone.coerce_datetime(self.logical_date) @@ -129,10 +128,10 @@ def validate_context(self, dag: SerializedDAG) -> dict: ) run_after = data_interval.end - run_id = self.dag_run_id or DagRun.generate_run_id( - run_type=DagRunType.SCHEDULED, - logical_date=coerced_logical_date, - run_after=run_after, + run_id = self.dag_run_id or dag.timetable.generate_run_id( + run_type=DagRunType.MANUAL, + run_after=timezone.coerce_datetime(run_after), + data_interval=data_interval, ) return { "run_id": run_id, @@ -143,14 +142,6 @@ def validate_context(self, dag: SerializedDAG) -> dict: "note": self.note, } - @model_validator(mode="after") - def validate_dag_run_id(self): - if not self.dag_run_id: - self.dag_run_id = DagRun.generate_run_id( - run_type=DagRunType.MANUAL, logical_date=self.logical_date, run_after=self.run_after - ) - return self - class DAGRunsBatchBody(StrictBaseModel): """List DAG Runs body for batch endpoint.""" diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dags.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dags.py index b14b8b18cbdc3..23aa4ec300f47 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dags.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dags.py @@ -19,7 +19,6 @@ import inspect from collections import abc -from collections.abc import Iterable from datetime import datetime, timedelta from typing import Any @@ -151,9 +150,9 @@ class DAGDetailsResponse(DAGResponse): start_date: datetime | None end_date: datetime | None is_paused_upon_creation: bool | None - params: abc.MutableMapping | None + params: abc.Mapping | None render_template_as_native_obj: bool - template_search_path: Iterable[str] | None + template_search_path: list[str] | None timezone: str | None last_parsed: datetime | None default_args: abc.Mapping | None @@ -177,7 +176,7 @@ def get_doc_md(cls, doc_md: str | None) -> str | None: @field_validator("params", mode="before") @classmethod - def get_params(cls, params: abc.MutableMapping | None) -> dict | None: + def get_params(cls, params: abc.Mapping | None) -> dict | None: """Convert params attribute to dict representation.""" if params is None: return None diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/hitl.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/hitl.py index ea0f045539ee6..aa4f44f212bd9 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/hitl.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/hitl.py @@ -37,13 +37,19 @@ class UpdateHITLDetailPayload(BaseModel): class HITLDetailResponse(BaseModel): """Response of updating a Human-in-the-loop detail.""" - responded_user_id: str - responded_user_name: str - response_at: datetime + responded_by: HITLUser + responded_at: datetime chosen_options: list[str] = Field(min_length=1) params_input: Mapping = Field(default_factory=dict) +class HITLUser(BaseModel): + """Schema for a Human-in-the-loop users.""" + + id: str + name: str + + class HITLDetail(BaseModel): """Schema for Human-in-the-loop detail.""" @@ -56,12 +62,12 @@ class HITLDetail(BaseModel): defaults: list[str] | None = None multiple: bool = False params: dict[str, Any] = Field(default_factory=dict) - respondents: list[str] | None = None + assigned_users: list[HITLUser] = Field(default_factory=list) + created_at: datetime # Response Content Detail - responded_user_id: str | None = None - responded_user_name: str | None = None - response_at: datetime | None = None + responded_by_user: HITLUser | None = None + responded_at: datetime | None = None chosen_options: list[str] | None = None params_input: dict[str, Any] = Field(default_factory=dict) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/task_instances.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/task_instances.py index 0b6edcf98e25b..ca6823a123afe 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/task_instances.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/task_instances.py @@ -191,7 +191,11 @@ class ClearTaskInstancesBody(StrictBaseModel): only_failed: bool = True only_running: bool = False reset_dag_runs: bool = True - task_ids: list[str | tuple[str, int]] | None = None + task_ids: list[str | tuple[str, int]] | None = Field( + default=None, + description="A list of `task_id` or [`task_id`, `map_index`]. " + "If only the `task_id` is provided for a mapped task, all of its map indices will be targeted.", + ) dag_run_id: str | None = None include_upstream: bool = False include_downstream: bool = False diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py index 0f22cd7226224..174bfbadf3030 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py @@ -38,11 +38,31 @@ class XComResponse(BaseModel): task_display_name: str = Field(validation_alias=AliasPath("task", "task_display_name")) +def _stringify_if_needed(value): + """ + Check whether value is JSON-encodable (recursively if needed); stringify it if not. + + The list of JSON-ecodable types are taken from Python documentation: + https://docs.python.org/3/library/json.html#json.JSONEncoder + """ + if value is None or isinstance(value, (str, int, float, bool)): + return value + if isinstance(value, dict): + return {str(k): _stringify_if_needed(v) for k, v in value.items()} + if isinstance(value, (list, tuple)): + return [_stringify_if_needed(v) for v in value] + return str(value) + + class XComResponseNative(XComResponse): """XCom response serializer with native return type.""" value: Any + @field_validator("value", mode="before") + def value_to_json_serializable(cls, v): + return _stringify_if_needed(v) + class XComResponseString(XComResponse): """XCom response serializer with string return type.""" diff --git a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml index a4d85b16dd3c0..cf1bf97bc82ed 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml +++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml @@ -251,9 +251,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, + next_dagrun, state, start_date, last_run_state, last_run_start_date`' default: - dag_id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `dag_id, dag_display_name, + next_dagrun, state, start_date, last_run_state, last_run_start_date`' - name: is_favorite in: query required: false @@ -547,9 +553,13 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id`' - name: dag_id in: query required: false @@ -625,9 +635,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `run_after, + logical_date, start_date, end_date`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `run_after, logical_date, + start_date, end_date`' - name: run_after_gte in: query required: false @@ -752,9 +768,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `run_after, + logical_date, start_date, end_date`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `run_after, logical_date, + start_date, end_date`' - name: run_after_gte in: query required: false @@ -1994,29 +2016,25 @@ components: additionalProperties: true type: object title: Params - respondents: - anyOf: - - items: - type: string - type: array - - type: 'null' - title: Respondents - responded_user_id: + assigned_users: + items: + $ref: '#/components/schemas/HITLUser' + type: array + title: Assigned Users + created_at: + type: string + format: date-time + title: Created At + responded_by_user: anyOf: - - type: string + - $ref: '#/components/schemas/HITLUser' - type: 'null' - title: Responded User Id - responded_user_name: - anyOf: - - type: string - - type: 'null' - title: Responded User Name - response_at: + responded_at: anyOf: - type: string format: date-time - type: 'null' - title: Response At + title: Responded At chosen_options: anyOf: - items: @@ -2037,8 +2055,23 @@ components: - task_instance - options - subject + - created_at title: HITLDetail description: Schema for Human-in-the-loop detail. + HITLUser: + properties: + id: + type: string + title: Id + name: + type: string + title: Name + type: object + required: + - id + - name + title: HITLUser + description: Schema for a Human-in-the-loop users. HTTPExceptionResponse: properties: detail: diff --git a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml index 7c23f712f1c7a..d68dba4a6d17c 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml +++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml @@ -80,9 +80,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, name, + uri, created_at, updated_at`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, name, uri, created_at, + updated_at`' responses: '200': description: Successful Response @@ -160,9 +166,13 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, name`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, name`' responses: '200': description: Successful Response @@ -275,9 +285,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `source_task_id, + source_dag_id, source_run_id, source_map_index, timestamp`' default: - timestamp title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `source_task_id, source_dag_id, + source_run_id, source_map_index, timestamp`' - name: asset_id in: query required: false @@ -916,9 +932,13 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id`' responses: '200': description: Successful Response @@ -1451,9 +1471,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `conn_id, + conn_type, description, host, port, id, connection_id`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `conn_id, conn_type, + description, host, port, id, connection_id`' - name: connection_id_pattern in: query required: false @@ -2206,9 +2232,17 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, state, + dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, + conf, duration, dag_run_id`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, state, dag_id, + run_id, logical_date, run_after, start_date, end_date, updated_at, conf, + duration, dag_run_id`' - name: run_id_pattern in: query required: false @@ -2336,7 +2370,8 @@ paths: summary: 'Experimental: Wait for a dag run to complete, and return task results if requested.' description: "\U0001F6A7 This is an experimental endpoint and may change or\ - \ be removed without notice." + \ be removed without notice.Successful response are streamed as newline-delimited\ + \ JSON (NDJSON). Each line is a JSON object representing the DAG run state." operationId: wait_dag_run_until_finished security: - OAuth2PasswordBearer: [] @@ -2607,53 +2642,6 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /api/v2/dagReports: - get: - tags: - - DagReport - summary: Get Dag Reports - description: Get DAG report. - operationId: get_dag_reports - security: - - OAuth2PasswordBearer: [] - - HTTPBearer: [] - parameters: - - name: subdir - in: query - required: true - schema: - type: string - title: Subdir - responses: - '200': - description: Successful Response - content: - application/json: - schema: {} - '401': - content: - application/json: - schema: - $ref: '#/components/schemas/HTTPExceptionResponse' - description: Unauthorized - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/HTTPExceptionResponse' - description: Forbidden - '400': - content: - application/json: - schema: - $ref: '#/components/schemas/HTTPExceptionResponse' - description: Bad Request - '422': - description: Validation Error - content: - application/json: - schema: - $ref: '#/components/schemas/HTTPValidationError' /api/v2/config: get: tags: @@ -2867,9 +2855,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `dag_id, warning_type, + message, timestamp`' default: - dag_id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `dag_id, warning_type, + message, timestamp`' responses: '200': description: Successful Response @@ -3131,9 +3125,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, + next_dagrun, state, start_date, last_run_state, last_run_start_date`' default: - dag_id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `dag_id, dag_display_name, + next_dagrun, state, start_date, last_run_state, last_run_start_date`' - name: is_favorite in: query required: false @@ -3704,9 +3704,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, dttm, + dag_id, task_id, run_id, event, logical_date, owner, extra, when, event_log_id`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, dttm, dag_id, + task_id, run_id, event, logical_date, owner, extra, when, event_log_id`' - name: dag_id in: query required: false @@ -4036,9 +4042,27 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, timestamp, + filename, bundle_name, stacktrace, import_error_id`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, timestamp, filename, + bundle_name, stacktrace, import_error_id`' + - name: filename_pattern + in: query + required: false + schema: + anyOf: + - type: string + - type: 'null' + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + title: Filename Pattern + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." responses: '200': description: Successful Response @@ -4178,9 +4202,17 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, dag_id, + state, job_type, start_date, end_date, latest_heartbeat, executor_class, + hostname, unixname`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, dag_id, state, + job_type, start_date, end_date, latest_heartbeat, executor_class, hostname, + unixname`' - name: job_state in: query required: false @@ -4523,9 +4555,14 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, pool, + name`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, pool, name`' - name: pool_name_pattern in: query required: false @@ -5378,9 +5415,7 @@ paths: description: Successful Response content: application/json: - schema: - type: 'null' - title: Response Delete Task Instance + schema: {} '401': content: application/json: @@ -5702,6 +5737,14 @@ paths: items: type: string title: Operator + - name: map_index + in: query + required: false + schema: + type: array + items: + type: integer + title: Map Index - name: limit in: query required: false @@ -5725,9 +5768,19 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, state, + duration, start_date, end_date, map_index, try_number, logical_date, run_after, + data_interval_start, data_interval_end, rendered_map_index, operator, + run_after, logical_date, data_interval_start, data_interval_end`' default: - map_index title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, state, duration, + start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, + data_interval_end, rendered_map_index, operator, run_after, logical_date, + data_interval_start, data_interval_end`' responses: '200': description: Successful Response @@ -6502,6 +6555,14 @@ paths: items: type: string title: Operator + - name: map_index + in: query + required: false + schema: + type: array + items: + type: integer + title: Map Index - name: limit in: query required: false @@ -6525,9 +6586,19 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, state, + duration, start_date, end_date, map_index, try_number, logical_date, run_after, + data_interval_start, data_interval_end, rendered_map_index, operator, + logical_date, run_after, data_interval_start, data_interval_end`' default: - map_index title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, state, duration, + start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, + data_interval_end, rendered_map_index, operator, logical_date, run_after, + data_interval_start, data_interval_end`' responses: '200': description: Successful Response @@ -7366,9 +7437,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `key, id, + _val, description, is_encrypted`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `key, id, _val, description, + is_encrypted`' - name: variable_key_pattern in: query required: false @@ -7702,9 +7779,7 @@ paths: description: Successful Response content: application/json: - schema: - type: 'null' - title: Response Reparse Dag File + schema: {} '401': content: application/json: @@ -7763,9 +7838,13 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `name`' default: - name title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `name`' - name: tag_name_pattern in: query required: false @@ -7921,9 +8000,15 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `id, version_number, + bundle_name, bundle_version`' default: - id title: Order By + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `id, version_number, + bundle_name, bundle_version`' responses: '200': description: Successful Response @@ -7955,10 +8040,10 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}: + /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails: patch: tags: - - HumanInTheLoop + - Task Instance summary: Update Hitl Detail description: Update a Human-in-the-loop detail. operationId: update_hitl_detail @@ -7985,11 +8070,10 @@ paths: type: string title: Task Id - name: map_index - in: query - required: false + in: path + required: true schema: type: integer - default: -1 title: Map Index requestBody: required: true @@ -8036,7 +8120,7 @@ paths: $ref: '#/components/schemas/HTTPValidationError' get: tags: - - HumanInTheLoop + - Task Instance summary: Get Hitl Detail description: Get a Human-in-the-loop detail of a specific task instance. operationId: get_hitl_detail @@ -8063,11 +8147,10 @@ paths: type: string title: Task Id - name: map_index - in: query - required: false + in: path + required: true schema: type: integer - default: -1 title: Map Index responses: '200': @@ -8100,10 +8183,10 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /api/v2/hitlDetails/: + /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/hitlDetails: get: tags: - - HumanInTheLoop + - Task Instance summary: Get Hitl Details description: Get Human-in-the-loop details. operationId: get_hitl_details @@ -8111,6 +8194,18 @@ paths: - OAuth2PasswordBearer: [] - HTTPBearer: [] parameters: + - name: dag_id + in: path + required: true + schema: + type: string + title: Dag Id + - name: dag_run_id + in: path + required: true + schema: + type: string + title: Dag Run Id - name: limit in: query required: false @@ -8134,17 +8229,18 @@ paths: type: array items: type: string + description: 'Attributes to order by, multi criteria sort is supported. + Prefix with `-` for descending order. Supported attributes: `ti_id, subject, + responded_at, created_at, responded_by_user_id, responded_by_user_name, + dag_id, run_id, run_after, rendered_map_index, task_instance_operator, + task_instance_state`' default: - ti_id title: Order By - - name: dag_id - in: query - required: false - schema: - anyOf: - - type: string - - type: 'null' - title: Dag Id + description: 'Attributes to order by, multi criteria sort is supported. Prefix + with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, + created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, + run_after, rendered_map_index, task_instance_operator, task_instance_state`' - name: dag_id_pattern in: query required: false @@ -8157,12 +8253,6 @@ paths: title: Dag Id Pattern description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ \ Regular expressions are **not** supported." - - name: dag_run_id - in: query - required: false - schema: - type: string - title: Dag Run Id - name: task_id in: query required: false @@ -8183,6 +8273,14 @@ paths: title: Task Id Pattern description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ \ Regular expressions are **not** supported." + - name: map_index + in: query + required: false + schema: + anyOf: + - type: integer + - type: 'null' + title: Map Index - name: state in: query required: false @@ -8199,22 +8297,22 @@ paths: - type: boolean - type: 'null' title: Response Received - - name: responded_user_id + - name: responded_by_user_id in: query required: false schema: type: array items: type: string - title: Responded User Id - - name: responded_user_name + title: Responded By User Id + - name: responded_by_user_name in: query required: false schema: type: array items: type: string - title: Responded User Name + title: Responded By User Name - name: subject_search in: query required: false @@ -8239,6 +8337,42 @@ paths: title: Body Search description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ \ Regular expressions are **not** supported." + - name: created_at_gte + in: query + required: false + schema: + anyOf: + - type: string + format: date-time + - type: 'null' + title: Created At Gte + - name: created_at_gt + in: query + required: false + schema: + anyOf: + - type: string + format: date-time + - type: 'null' + title: Created At Gt + - name: created_at_lte + in: query + required: false + schema: + anyOf: + - type: string + format: date-time + - type: 'null' + title: Created At Lte + - name: created_at_lt + in: query + required: false + schema: + anyOf: + - type: string + format: date-time + - type: 'null' + title: Created At Lt responses: '200': description: Successful Response @@ -9261,6 +9395,9 @@ components: type: array - type: 'null' title: Task Ids + description: A list of `task_id` or [`task_id`, `map_index`]. If only the + `task_id` is provided for a mapped task, all of its map indices will be + targeted. dag_run_id: anyOf: - type: string @@ -10855,29 +10992,25 @@ components: additionalProperties: true type: object title: Params - respondents: - anyOf: - - items: - type: string - type: array - - type: 'null' - title: Respondents - responded_user_id: - anyOf: - - type: string - - type: 'null' - title: Responded User Id - responded_user_name: + assigned_users: + items: + $ref: '#/components/schemas/HITLUser' + type: array + title: Assigned Users + created_at: + type: string + format: date-time + title: Created At + responded_by_user: anyOf: - - type: string + - $ref: '#/components/schemas/HITLUser' - type: 'null' - title: Responded User Name - response_at: + responded_at: anyOf: - type: string format: date-time - type: 'null' - title: Response At + title: Responded At chosen_options: anyOf: - items: @@ -10898,6 +11031,7 @@ components: - task_instance - options - subject + - created_at title: HITLDetail description: Schema for Human-in-the-loop detail. HITLDetailCollection: @@ -10918,16 +11052,12 @@ components: description: Schema for a collection of Human-in-the-loop details. HITLDetailResponse: properties: - responded_user_id: - type: string - title: Responded User Id - responded_user_name: - type: string - title: Responded User Name - response_at: + responded_by: + $ref: '#/components/schemas/HITLUser' + responded_at: type: string format: date-time - title: Response At + title: Responded At chosen_options: items: type: string @@ -10940,12 +11070,25 @@ components: title: Params Input type: object required: - - responded_user_id - - responded_user_name - - response_at + - responded_by + - responded_at - chosen_options title: HITLDetailResponse description: Response of updating a Human-in-the-loop detail. + HITLUser: + properties: + id: + type: string + title: Id + name: + type: string + title: Name + type: object + required: + - id + - name + title: HITLUser + description: Schema for a Human-in-the-loop users. HTTPExceptionResponse: properties: detail: diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/__init__.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/__init__.py index 6db86ce2327a6..0b501b4f99f71 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/__init__.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/__init__.py @@ -27,7 +27,6 @@ from airflow.api_fastapi.core_api.routes.public.config import config_router from airflow.api_fastapi.core_api.routes.public.connections import connections_router from airflow.api_fastapi.core_api.routes.public.dag_parsing import dag_parsing_router -from airflow.api_fastapi.core_api.routes.public.dag_report import dag_report_router from airflow.api_fastapi.core_api.routes.public.dag_run import dag_run_router from airflow.api_fastapi.core_api.routes.public.dag_sources import dag_sources_router from airflow.api_fastapi.core_api.routes.public.dag_stats import dag_stats_router @@ -37,7 +36,7 @@ from airflow.api_fastapi.core_api.routes.public.dags import dags_router from airflow.api_fastapi.core_api.routes.public.event_logs import event_logs_router from airflow.api_fastapi.core_api.routes.public.extra_links import extra_links_router -from airflow.api_fastapi.core_api.routes.public.hitl import hitl_router +from airflow.api_fastapi.core_api.routes.public.hitl import task_instances_hitl_router from airflow.api_fastapi.core_api.routes.public.import_error import import_error_router from airflow.api_fastapi.core_api.routes.public.job import job_router from airflow.api_fastapi.core_api.routes.public.log import task_instances_log_router @@ -65,7 +64,6 @@ authenticated_router.include_router(dag_run_router) authenticated_router.include_router(dag_sources_router) authenticated_router.include_router(dag_stats_router) -authenticated_router.include_router(dag_report_router) authenticated_router.include_router(config_router) authenticated_router.include_router(dag_warning_router) authenticated_router.include_router(dags_router) @@ -84,7 +82,7 @@ authenticated_router.include_router(dag_parsing_router) authenticated_router.include_router(dag_tags_router) authenticated_router.include_router(dag_versions_router) -authenticated_router.include_router(hitl_router) +authenticated_router.include_router(task_instances_hitl_router) # Include authenticated router in public router diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_report.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_report.py deleted file mode 100644 index 42539015b53d1..0000000000000 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_report.py +++ /dev/null @@ -1,75 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -from __future__ import annotations - -import ast -import os -from typing import cast - -from fastapi import Depends, HTTPException, status - -from airflow import settings -from airflow.api_fastapi.common.router import AirflowRouter -from airflow.api_fastapi.core_api.datamodels.dag_report import ( - DagReportCollectionResponse, - DagReportResponse, -) -from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc -from airflow.api_fastapi.core_api.security import ( - ReadableDagsFilterDep, - requires_access_dag, -) -from airflow.models.dagbag import DagBag - -dag_report_router = AirflowRouter(tags=["DagReport"], prefix="/dagReports") - - -@dag_report_router.get( - "", - responses=create_openapi_http_exception_doc( - [ - status.HTTP_400_BAD_REQUEST, - ] - ), - dependencies=[Depends(requires_access_dag(method="GET"))], -) -def get_dag_reports( - subdir: str, - readable_dags_filter: ReadableDagsFilterDep, -): - """Get DAG report.""" - fullpath = os.path.normpath(subdir) - if not fullpath.startswith(settings.DAGS_FOLDER): - raise HTTPException(status.HTTP_400_BAD_REQUEST, "subdir should be subpath of DAGS_FOLDER settings") - - dagbag = DagBag(fullpath) - - readable_dag_ids: set[str] | None = readable_dags_filter.value - if readable_dag_ids: - filtered_dagbag_stats = [ - file_load_stat - for file_load_stat in dagbag.dagbag_stats - if len(set(ast.literal_eval(file_load_stat.dags)) - readable_dag_ids) == 0 - ] - else: - filtered_dagbag_stats = [] - - return DagReportCollectionResponse( - dag_reports=cast("list[DagReportResponse]", filtered_dagbag_stats), - total_entries=len(filtered_dagbag_stats), - ) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py index 8056c6fbda41c..657d2df6955f8 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py @@ -21,7 +21,7 @@ from typing import Annotated, Literal, cast import structlog -from fastapi import Depends, HTTPException, Query, status +from fastapi import Depends, HTTPException, Query, Request, status from fastapi.exceptions import RequestValidationError from fastapi.responses import StreamingResponse from pydantic import ValidationError @@ -415,6 +415,7 @@ def trigger_dag_run( dag_bag: DagBagDep, user: GetUserDep, session: SessionDep, + request: Request, ) -> DAGRunResponse: """Trigger a DAG.""" dm = session.scalar(select(DagModel).where(~DagModel.is_stale, DagModel.dag_id == dag_id).limit(1)) @@ -427,6 +428,12 @@ def trigger_dag_run( f"DAG with dag_id: '{dag_id}' has import errors and cannot be triggered", ) + referer = request.headers.get("referer") + if referer: + triggered_by = DagRunTriggeredByType.UI + else: + triggered_by = DagRunTriggeredByType.REST_API + try: dag = get_latest_version_of_dag(dag_bag, dag_id, session) params = body.validate_context(dag) @@ -438,7 +445,7 @@ def trigger_dag_run( run_after=params["run_after"], conf=params["conf"], run_type=DagRunType.MANUAL, - triggered_by=DagRunTriggeredByType.REST_API, + triggered_by=triggered_by, triggering_user_name=user.get_name(), state=DagRunState.QUEUED, session=session, @@ -459,7 +466,7 @@ def trigger_dag_run( "/{dag_run_id}/wait", tags=["experimental"], summary="Experimental: Wait for a dag run to complete, and return task results if requested.", - description="🚧 This is an experimental endpoint and may change or be removed without notice.", + description="🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state.", responses={ **create_openapi_http_exception_doc([status.HTTP_404_NOT_FOUND]), status.HTTP_200_OK: { diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/extra_links.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/extra_links.py index 1dbbf0db8b70c..83d17b404ad82 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/extra_links.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/extra_links.py @@ -17,8 +17,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, cast - from fastapi import Depends, HTTPException, status from sqlalchemy.sql import select @@ -31,10 +29,6 @@ from airflow.exceptions import TaskNotFound from airflow.models import DagRun -if TYPE_CHECKING: - from airflow.models.mappedoperator import MappedOperator - from airflow.serialization.serialized_objects import SerializedBaseOperator - extra_links_router = AirflowRouter( tags=["Extra Links"], prefix="/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/links" ) @@ -62,8 +56,7 @@ def get_extra_links( dag = get_dag_for_run_or_latest_version(dag_bag, dag_run, dag_id, session) try: - # TODO (GH-52141): Make dag a db-backed object so it only returns db-backed tasks. - task = cast("MappedOperator | SerializedBaseOperator", dag.get_task(task_id)) + task = dag.get_task(task_id) except TaskNotFound: raise HTTPException(status.HTTP_404_NOT_FOUND, f"Task with ID = {task_id} not found") diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py index e04714e0a9137..d8635c7034351 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py @@ -28,9 +28,8 @@ from airflow.api_fastapi.common.db.common import SessionDep, paginated_select from airflow.api_fastapi.common.parameters import ( QueryHITLDetailBodySearch, - QueryHITLDetailDagIdFilter, QueryHITLDetailDagIdPatternSearch, - QueryHITLDetailDagRunIdFilter, + QueryHITLDetailMapIndexFilter, QueryHITLDetailRespondedUserIdFilter, QueryHITLDetailRespondedUserNameFilter, QueryHITLDetailResponseReceivedFilter, @@ -40,7 +39,9 @@ QueryLimit, QueryOffset, QueryTIStateFilter, + RangeFilter, SortParam, + datetime_range_filter_factory, ) from airflow.api_fastapi.common.router import AirflowRouter from airflow.api_fastapi.core_api.datamodels.hitl import ( @@ -53,10 +54,14 @@ from airflow.api_fastapi.core_api.security import GetUserDep, ReadableTIFilterDep, requires_access_dag from airflow.api_fastapi.logging.decorators import action_logging from airflow.models.dagrun import DagRun -from airflow.models.hitl import HITLDetail as HITLDetailModel +from airflow.models.hitl import HITLDetail as HITLDetailModel, HITLUser from airflow.models.taskinstance import TaskInstance as TI -hitl_router = AirflowRouter(tags=["HumanInTheLoop"], prefix="/hitlDetails") +task_instances_hitl_router = AirflowRouter( + tags=["Task Instance"], + prefix="/dags/{dag_id}/dagRuns/{dag_run_id}", +) +task_instance_hitl_path = "/taskInstances/{task_id}/{map_index}/hitlDetails" log = structlog.get_logger(__name__) @@ -100,8 +105,8 @@ def _get_task_instance_with_hitl_detail( return task_instance -@hitl_router.patch( - "/{dag_id}/{dag_run_id}/{task_id}", +@task_instances_hitl_router.patch( + task_instance_hitl_path, responses=create_openapi_http_exception_doc( [ status.HTTP_403_FORBIDDEN, @@ -144,20 +149,20 @@ def update_hitl_detail( user_id = user.get_id() user_name = user.get_name() - if hitl_detail_model.respondents: - if isinstance(user_id, int): - # FabAuthManager (ab_user) store user id as integer, but common interface is string type - user_id = str(user_id) - if user_id not in hitl_detail_model.respondents: + if isinstance(user_id, int): + # FabAuthManager (ab_user) store user id as integer, but common interface is string type + user_id = str(user_id) + hitl_user = HITLUser(id=user_id, name=user_name) + if hitl_detail_model.assigned_users: + if hitl_user not in hitl_detail_model.assigned_users: log.error("User=%s (id=%s) is not a respondent for the task", user_name, user_id) raise HTTPException( status.HTTP_403_FORBIDDEN, f"User={user_name} (id={user_id}) is not a respondent for the task.", ) - hitl_detail_model.responded_user_id = user_id - hitl_detail_model.responded_user_name = user_name - hitl_detail_model.response_at = timezone.utcnow() + hitl_detail_model.responded_by = hitl_user + hitl_detail_model.responded_at = timezone.utcnow() hitl_detail_model.chosen_options = update_hitl_detail_payload.chosen_options hitl_detail_model.params_input = update_hitl_detail_payload.params_input session.add(hitl_detail_model) @@ -165,8 +170,8 @@ def update_hitl_detail( return HITLDetailResponse.model_validate(hitl_detail_model) -@hitl_router.get( - "/{dag_id}/{dag_run_id}/{task_id}", +@task_instances_hitl_router.get( + task_instance_hitl_path, status_code=status.HTTP_200_OK, responses=create_openapi_http_exception_doc([status.HTTP_404_NOT_FOUND]), dependencies=[Depends(requires_access_dag(method="GET", access_entity=DagAccessEntity.HITL_DETAIL))], @@ -189,12 +194,14 @@ def get_hitl_detail( return task_instance.hitl_detail -@hitl_router.get( - "/", +@task_instances_hitl_router.get( + "/hitlDetails", status_code=status.HTTP_200_OK, dependencies=[Depends(requires_access_dag(method="GET", access_entity=DagAccessEntity.HITL_DETAIL))], ) def get_hitl_details( + dag_id: str, + dag_run_id: str, limit: QueryLimit, offset: QueryOffset, order_by: Annotated[ @@ -204,7 +211,10 @@ def get_hitl_details( allowed_attrs=[ "ti_id", "subject", - "response_at", + "responded_at", + "created_at", + "responded_by_user_id", + "responded_by_user_name", ], model=HITLDetailModel, to_replace={ @@ -213,25 +223,27 @@ def get_hitl_details( "run_after": DagRun.run_after, "rendered_map_index": TI.rendered_map_index, "task_instance_operator": TI.operator, + "task_instance_state": TI.state, }, ).dynamic_depends(), ), ], session: SessionDep, - # ti related filter + # permission filter readable_ti_filter: ReadableTIFilterDep, - dag_id: QueryHITLDetailDagIdFilter, + # ti related filter dag_id_pattern: QueryHITLDetailDagIdPatternSearch, - dag_run_id: QueryHITLDetailDagRunIdFilter, task_id: QueryHITLDetailTaskIdFilter, task_id_pattern: QueryHITLDetailTaskIdPatternSearch, + map_index: QueryHITLDetailMapIndexFilter, ti_state: QueryTIStateFilter, # hitl detail related filter response_received: QueryHITLDetailResponseReceivedFilter, - responded_user_id: QueryHITLDetailRespondedUserIdFilter, - responded_user_name: QueryHITLDetailRespondedUserNameFilter, + responded_by_user_id: QueryHITLDetailRespondedUserIdFilter, + responded_by_user_name: QueryHITLDetailRespondedUserNameFilter, subject_patten: QueryHITLDetailSubjectSearch, body_patten: QueryHITLDetailBodySearch, + created_at: Annotated[RangeFilter, Depends(datetime_range_filter_factory("created_at", HITLDetailModel))], ) -> HITLDetailCollection: """Get Human-in-the-loop details.""" query = ( @@ -244,23 +256,28 @@ def get_hitl_details( ) ) ) + if dag_id != "~": + query = query.where(TI.dag_id == dag_id) + if dag_run_id != "~": + query = query.where(TI.run_id == dag_run_id) hitl_detail_select, total_entries = paginated_select( statement=query, filters=[ - # ti related filter + # permission filter readable_ti_filter, - dag_id, + # ti related filter dag_id_pattern, - dag_run_id, task_id, task_id_pattern, + map_index, ti_state, # hitl detail related filter response_received, - responded_user_id, - responded_user_name, + responded_by_user_id, + responded_by_user_name, subject_patten, body_patten, + created_at, ], offset=offset, limit=limit, diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/import_error.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/import_error.py index a989a7eef168c..bb1e03a33aed8 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/import_error.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/import_error.py @@ -36,6 +36,7 @@ from airflow.api_fastapi.common.parameters import ( QueryLimit, QueryOffset, + QueryParseImportErrorFilenamePatternSearch, SortParam, ) from airflow.api_fastapi.common.router import AirflowRouter @@ -126,12 +127,14 @@ def get_import_errors( ).dynamic_depends() ), ], + filename_pattern: QueryParseImportErrorFilenamePatternSearch, session: SessionDep, user: GetUserDep, ) -> ImportErrorCollectionResponse: """Get all import errors.""" import_errors_select, total_entries = paginated_select( statement=select(ParseImportError), + filters=[filename_pattern], order_by=order_by, offset=offset, limit=limit, @@ -174,6 +177,7 @@ def get_import_errors( # Paginate the import errors query import_errors_select, total_entries = paginated_select( statement=import_errors_stmt, + filters=[filename_pattern], order_by=order_by, offset=offset, limit=limit, diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/plugins.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/plugins.py index fe700178f6bf4..3b5368f50d232 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/plugins.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/plugins.py @@ -17,9 +17,9 @@ from __future__ import annotations -from typing import cast - +import structlog from fastapi import Depends +from pydantic import ValidationError from airflow import plugins_manager from airflow.api_fastapi.auth.managers.models.resource_details import AccessView @@ -32,6 +32,8 @@ ) from airflow.api_fastapi.core_api.security import requires_access_view +logger = structlog.get_logger(__name__) + plugins_router = AirflowRouter(tags=["Plugin"], prefix="/plugins") @@ -44,9 +46,27 @@ def get_plugins( offset: QueryOffset, ) -> PluginCollectionResponse: plugins_info = sorted(plugins_manager.get_plugin_info(), key=lambda x: x["name"]) + valid_plugins: list[PluginResponse] = [] + for plugin_dict in plugins_info: + try: + # Validate each plugin individually + plugin = PluginResponse.model_validate(plugin_dict) + valid_plugins.append(plugin) + except ValidationError as e: + logger.warning( + "Skipping invalid plugin due to error", + plugin_name=plugin_dict.get("name", ""), + error=str(e), + ) + continue + + offset_value = offset.value or 0 + limit_value = limit.value if limit.value is not None else len(valid_plugins) + + paginated_plugins = valid_plugins[offset_value : offset_value + limit_value] return PluginCollectionResponse( - plugins=cast("list[PluginResponse]", plugins_info[offset.value :][: limit.value]), - total_entries=len(plugins_info), + plugins=paginated_plugins, + total_entries=len(valid_plugins), ) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py index 87d76fedc921f..d31a5f8ba8e73 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py @@ -42,6 +42,7 @@ QueryOffset, QueryTIDagVersionFilter, QueryTIExecutorFilter, + QueryTIMapIndexFilter, QueryTIOperatorFilter, QueryTIPoolFilter, QueryTIQueueFilter, @@ -149,6 +150,7 @@ def get_mapped_task_instances( version_number: QueryTIDagVersionFilter, try_number: QueryTITryNumberFilter, operator: QueryTIOperatorFilter, + map_index: QueryTIMapIndexFilter, limit: QueryLimit, offset: QueryOffset, order_by: Annotated[ @@ -220,6 +222,7 @@ def get_mapped_task_instances( version_number, try_number, operator, + map_index, ], order_by=order_by, offset=offset, @@ -412,6 +415,7 @@ def get_task_instances( version_number: QueryTIDagVersionFilter, try_number: QueryTITryNumberFilter, operator: QueryTIOperatorFilter, + map_index: QueryTIMapIndexFilter, limit: QueryLimit, offset: QueryOffset, order_by: Annotated[ @@ -491,6 +495,7 @@ def get_task_instances( readable_ti_filter, try_number, operator, + map_index, ], order_by=order_by, offset=offset, @@ -729,16 +734,25 @@ def post_clear_task_instances( task_ids = body.task_ids if task_ids is not None: - task_id = [task[0] if isinstance(task, tuple) else task for task in task_ids] - dag = dag.partial_subset( - task_ids=task_id, - include_downstream=downstream, - include_upstream=upstream, - ) + tasks = set(task_ids) + mapped_tasks_tuples = set(t for t in tasks if isinstance(t, tuple)) + # Unmapped tasks are expressed in their task_ids (without map_indexes) + unmapped_task_ids = set(t for t in tasks if not isinstance(t, tuple)) + + if upstream or downstream: + mapped_task_ids = set(tid for tid, _ in mapped_tasks_tuples) + relatives = dag.partial_subset( + task_ids=unmapped_task_ids | mapped_task_ids, + include_downstream=downstream, + include_upstream=upstream, + exclude_original=True, + ) + unmapped_task_ids = unmapped_task_ids | set(relatives.task_dict.keys()) - if len(dag.task_dict) > 1: - # If we had upstream/downstream etc then also include those! - task_ids.extend(tid for tid in dag.task_dict if tid != task_id) + mapped_tasks_list = [ + (tid, map_id) for tid, map_id in mapped_tasks_tuples if tid not in unmapped_task_ids + ] + task_ids = mapped_tasks_list + list(unmapped_task_ids) # Prepare common parameters common_params = { diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/assets.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/assets.py index ce476d94ffc07..a112bec9639d1 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/assets.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/assets.py @@ -18,7 +18,7 @@ from __future__ import annotations from fastapi import Depends, HTTPException, status -from sqlalchemy import and_, func, select +from sqlalchemy import and_, case, func, select from airflow.api_fastapi.common.dagbag import DagBagDep from airflow.api_fastapi.common.db.common import SessionDep @@ -53,6 +53,12 @@ def next_run_assets( AssetModel.uri, AssetModel.name, func.max(AssetEvent.timestamp).label("lastUpdate"), + func.max( + case( + (AssetDagRunQueue.asset_id.is_not(None), 1), + else_=0, + ) + ).label("queued"), ) .join(DagScheduleAssetReference, DagScheduleAssetReference.asset_id == AssetModel.id) .join( @@ -81,5 +87,9 @@ def next_run_assets( ) ] + for event in events: + if not event.pop("queued", None): + event["lastUpdate"] = None + data = {"asset_expression": dag_model.asset_expression, "events": events} return data diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/config.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/config.py index f4fe5d5c6658c..c0b7dd2e3b638 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/config.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/config.py @@ -21,6 +21,7 @@ from fastapi import Depends, status from airflow.api_fastapi.common.router import AirflowRouter +from airflow.api_fastapi.common.types import UIAlert from airflow.api_fastapi.core_api.datamodels.ui.config import ConfigResponse from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc from airflow.api_fastapi.core_api.security import requires_authenticated @@ -54,7 +55,8 @@ def get_configs() -> ConfigResponse: additional_config: dict[str, Any] = { "instance_name": conf.get("api", "instance_name", fallback="Airflow"), "test_connection": conf.get("core", "test_connection", fallback="Disabled"), - "dashboard_alert": DASHBOARD_UIALERTS, + # Expose "dashboard_alert" using a list comprehension so UIAlert instances can be expressed dynamically. + "dashboard_alert": [alert for alert in DASHBOARD_UIALERTS if isinstance(alert, UIAlert)], "show_external_log_redirect": task_log_reader.supports_external_link, "external_log_name": getattr(task_log_reader.log_handler, "log_name", None), } diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py index e953017a56b65..af4ed341f7fb7 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py @@ -67,6 +67,7 @@ from airflow.models import DagModel, DagRun from airflow.models.hitl import HITLDetail from airflow.models.taskinstance import TaskInstance +from airflow.utils.state import TaskInstanceState dags_router = AirflowRouter(prefix="/dags", tags=["DAG"]) @@ -201,7 +202,10 @@ def get_dags( HITLDetail, ) .join(TaskInstance, HITLDetail.ti_id == TaskInstance.id) - .where(HITLDetail.response_at.is_(None)) + .where( + HITLDetail.responded_at.is_(None), + TaskInstance.state == TaskInstanceState.DEFERRED, + ) .where(TaskInstance.dag_id.in_([dag.dag_id for dag in dags])) .order_by(TaskInstance.dag_id) ) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dashboard.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dashboard.py index dbbada8cf39c7..26c1b6582d76e 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dashboard.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dashboard.py @@ -127,7 +127,18 @@ def dag_stats( .subquery() ) - latest_runs = ( + # Active Dags need another query from DagModel, as a Dag may not have any runs but still be active + active_count_query = ( + select(func.count()) + .select_from(DagModel) + .where(DagModel.is_stale == false()) + .where(DagModel.is_paused == false()) + .where(DagModel.dag_id.in_(permitted_dag_ids)) + ) + active_count = session.execute(active_count_query).scalar_one() + + # Other metrics are based on latest DagRun states + latest_runs_cte = ( select( DagModel.dag_id, DagModel.is_paused, @@ -139,21 +150,22 @@ def dag_stats( (DagRun.dag_id == latest_dates_subq.c.dag_id) & (DagRun.logical_date == latest_dates_subq.c.max_logical_date), ) + .where(DagModel.is_stale == false()) .where(DagRun.dag_id.in_(permitted_dag_ids)) .cte() ) + combined_runs_query = select( + func.coalesce(func.sum(case((latest_runs_cte.c.state == DagRunState.FAILED, 1))), 0).label("failed"), + func.coalesce(func.sum(case((latest_runs_cte.c.state == DagRunState.RUNNING, 1))), 0).label( + "running" + ), + func.coalesce(func.sum(case((latest_runs_cte.c.state == DagRunState.QUEUED, 1))), 0).label("queued"), + ).select_from(latest_runs_cte) - combined_query = select( - func.coalesce(func.sum(case((latest_runs.c.is_paused == false(), 1))), 0).label("active"), - func.coalesce(func.sum(case((latest_runs.c.state == DagRunState.FAILED, 1))), 0).label("failed"), - func.coalesce(func.sum(case((latest_runs.c.state == DagRunState.RUNNING, 1))), 0).label("running"), - func.coalesce(func.sum(case((latest_runs.c.state == DagRunState.QUEUED, 1))), 0).label("queued"), - ).select_from(latest_runs) - - counts = session.execute(combined_query).first() + counts = session.execute(combined_runs_query).first() return DashboardDagStatsResponse( - active_dag_count=counts.active, + active_dag_count=active_count, failed_dag_count=counts.failed, running_dag_count=counts.running, queued_dag_count=counts.queued, diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py index 7ff49ac27c16d..0379bd957ca1a 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py @@ -18,11 +18,12 @@ from __future__ import annotations import collections -from typing import TYPE_CHECKING, Annotated +from typing import TYPE_CHECKING, Annotated, Any import structlog from fastapi import Depends, HTTPException, status from sqlalchemy import select +from sqlalchemy.orm import joinedload from airflow.api_fastapi.auth.managers.models.resource_details import DagAccessEntity from airflow.api_fastapi.common.db.common import SessionDep, paginated_select @@ -47,6 +48,7 @@ from airflow.api_fastapi.core_api.security import requires_access_dag from airflow.api_fastapi.core_api.services.ui.grid import ( _find_aggregates, + _get_aggs_for_node, _merge_node_dicts, ) from airflow.api_fastapi.core_api.services.ui.task_group import ( @@ -81,16 +83,23 @@ def _get_latest_serdag(dag_id, session): def _get_serdag(dag_id, dag_version_id, session) -> SerializedDagModel | None: # this is a simplification - we account for structure based on the first task - version = session.scalar(select(DagVersion).where(DagVersion.id == dag_version_id)) + version = session.scalar( + select(DagVersion) + .where(DagVersion.id == dag_version_id) + .options(joinedload(DagVersion.serialized_dag)) + ) if not version: version = session.scalar( select(DagVersion) .where( DagVersion.dag_id == dag_id, ) + .options(joinedload(DagVersion.serialized_dag)) .order_by(DagVersion.id) # ascending cus this is mostly for pre-3.0 upgrade .limit(1) ) + if not version: + return None if not (serdag := version.serialized_dag): log.error( "No serialized dag found", @@ -148,21 +157,25 @@ def get_dag_structure( task_group_sort = get_task_group_children_getter() if not run_ids: nodes = [task_group_to_dict_grid(x) for x in task_group_sort(latest_dag.task_group)] - return nodes + return [GridNodeResponse(**n) for n in nodes] serdags = session.scalars( select(SerializedDagModel).where( + # Even though dag_id is filtered in base_query, + # adding this line here can improve the performance of this endpoint + SerializedDagModel.dag_id == dag_id, + SerializedDagModel.id != latest_serdag.id, SerializedDagModel.dag_version_id.in_( select(TaskInstance.dag_version_id) .join(TaskInstance.dag_run) .where( DagRun.id.in_(run_ids), - SerializedDagModel.id != latest_serdag.id, ) - ) + .distinct() + ), ) ) - merged_nodes: list[GridNodeResponse] = [] + merged_nodes: list[dict[str, Any]] = [] dags = [latest_dag] for serdag in serdags: if serdag: @@ -171,7 +184,37 @@ def get_dag_structure( nodes = [task_group_to_dict_grid(x) for x in task_group_sort(dag.task_group)] _merge_node_dicts(merged_nodes, nodes) - return merged_nodes + # Ensure historical tasks (e.g. removed) that exist in TIs for the selected runs are represented + def _collect_ids(nodes: list[dict[str, Any]]) -> set[str]: + ids: set[str] = set() + for n in nodes: + nid = n.get("id") + if nid: + ids.add(nid) + children = n.get("children") + if children: + ids |= _collect_ids(children) # recurse + return ids + + existing_ids = _collect_ids(merged_nodes) + historical_task_ids = session.scalars( + select(TaskInstance.task_id) + .join(TaskInstance.dag_run) + .where(TaskInstance.dag_id == dag_id, DagRun.id.in_(run_ids)) + .distinct() + ) + for task_id in historical_task_ids: + if task_id not in existing_ids: + merged_nodes.append( + { + "id": task_id, + "label": task_id, + "is_mapped": None, + "children": None, + } + ) + + return [GridNodeResponse(**n) for n in merged_nodes] @grid_router.get( @@ -337,19 +380,47 @@ def get_grid_ti_summaries( assert serdag def get_node_sumaries(): + yielded_task_ids: set[str] = set() + + # Yield all nodes discoverable from the serialized DAG structure for node in _find_aggregates( node=serdag.dag.task_group, parent_node=None, ti_details=ti_details, ): - if node["type"] == "task": - node["child_states"] = None - node["min_start_date"] = None - node["max_end_date"] = None + if node["type"] in {"task", "mapped_task"}: + yielded_task_ids.add(node["task_id"]) + if node["type"] == "task": + node["child_states"] = None + node["min_start_date"] = None + node["max_end_date"] = None yield node + # For good history: add synthetic leaf nodes for task_ids that have TIs in this run + # but are not present in the current DAG structure (e.g. removed tasks) + missing_task_ids = set(ti_details.keys()) - yielded_task_ids + for task_id in sorted(missing_task_ids): + detail = ti_details[task_id] + # Create a leaf task node with aggregated state from its TIs + agg = _get_aggs_for_node(detail) + yield { + "task_id": task_id, + "type": "task", + "parent_id": None, + **agg, + # Align with leaf behavior + "child_states": None, + "min_start_date": None, + "max_end_date": None, + } + + task_instances = list(get_node_sumaries()) + # If a group id and a task id collide, prefer the group record + group_ids = {n.get("task_id") for n in task_instances if n.get("type") == "group"} + filtered = [n for n in task_instances if not (n.get("type") == "task" and n.get("task_id") in group_ids)] + return { # type: ignore[return-value] "run_id": run_id, "dag_id": dag_id, - "task_instances": list(get_node_sumaries()), + "task_instances": filtered, } diff --git a/airflow-core/src/airflow/api_fastapi/core_api/security.py b/airflow-core/src/airflow/api_fastapi/core_api/security.py index 84bd0ccdd2989..7bc7b155b68eb 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/security.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/security.py @@ -19,7 +19,7 @@ from collections.abc import Callable from pathlib import Path from typing import TYPE_CHECKING, Annotated, cast -from urllib.parse import ParseResult, urljoin, urlparse +from urllib.parse import ParseResult, unquote, urljoin, urlparse from fastapi import Depends, HTTPException, Request, status from fastapi.security import HTTPBearer, OAuth2PasswordBearer @@ -27,6 +27,7 @@ from pydantic import NonNegativeInt from airflow.api_fastapi.app import get_auth_manager +from airflow.api_fastapi.auth.managers.base_auth_manager import COOKIE_NAME_JWT_TOKEN from airflow.api_fastapi.auth.managers.models.base_user import BaseUser from airflow.api_fastapi.auth.managers.models.batch_apis import ( IsAuthorizedConnectionRequest, @@ -46,7 +47,14 @@ VariableDetails, ) from airflow.api_fastapi.core_api.base import OrmClause -from airflow.api_fastapi.core_api.datamodels.common import BulkAction, BulkBody +from airflow.api_fastapi.core_api.datamodels.common import ( + BulkAction, + BulkActionOnExistence, + BulkBody, + BulkCreateAction, + BulkDeleteAction, + BulkUpdateAction, +) from airflow.api_fastapi.core_api.datamodels.connections import ConnectionBody from airflow.api_fastapi.core_api.datamodels.pools import PoolBody from airflow.api_fastapi.core_api.datamodels.variables import VariableBody @@ -96,14 +104,22 @@ async def resolve_user_from_token(token_str: str | None) -> BaseUser: async def get_user( + request: Request, oauth_token: str | None = Depends(oauth2_scheme), bearer_credentials: HTTPAuthorizationCredentials | None = Depends(bearer_scheme), ) -> BaseUser: - token_str = None + # A user might have been already built by a middleware, if so, it is stored in `request.state.user` + user: BaseUser | None = getattr(request.state, "user", None) + if user: + return user + + token_str: str | None if bearer_credentials and bearer_credentials.scheme.lower() == "bearer": token_str = bearer_credentials.credentials elif oauth_token: token_str = oauth_token + else: + token_str = request.cookies.get(COOKIE_NAME_JWT_TOKEN) return await resolve_user_from_token(token_str) @@ -257,19 +273,22 @@ def inner( ) -> None: requests: list[IsAuthorizedPoolRequest] = [] for action in request.actions: - requests.extend( - [ - { - "method": MAP_BULK_ACTION_TO_AUTH_METHOD[action.action], + methods = _get_resource_methods_from_bulk_request(action) + for pool in action.entities: + pool_name = ( + cast("str", pool) if action.action == BulkAction.DELETE else cast("PoolBody", pool).pool + ) + # For each pool, build a `IsAuthorizedPoolRequest` + # The list of `IsAuthorizedPoolRequest` will then be sent using `batch_is_authorized_pool` + # Each `IsAuthorizedPoolRequest` is similar to calling `is_authorized_pool` + for method in methods: + req: IsAuthorizedPoolRequest = { + "method": method, "details": PoolDetails( - name=cast("str", pool) - if action.action == BulkAction.DELETE - else cast("PoolBody", pool).pool + name=pool_name, ), } - for pool in action.entities - ] - ) + requests.append(req) _requires_access( is_authorized_callback=lambda: get_auth_manager().batch_is_authorized_pool( @@ -307,19 +326,24 @@ def inner( ) -> None: requests: list[IsAuthorizedConnectionRequest] = [] for action in request.actions: - requests.extend( - [ - { - "method": MAP_BULK_ACTION_TO_AUTH_METHOD[action.action], + methods = _get_resource_methods_from_bulk_request(action) + for connection in action.entities: + connection_id = ( + cast("str", connection) + if action.action == BulkAction.DELETE + else cast("ConnectionBody", connection).connection_id + ) + # For each pool, build a `IsAuthorizedConnectionRequest` + # The list of `IsAuthorizedConnectionRequest` will then be sent using `batch_is_authorized_connection` + # Each `IsAuthorizedConnectionRequest` is similar to calling `is_authorized_connection` + for method in methods: + req: IsAuthorizedConnectionRequest = { + "method": method, "details": ConnectionDetails( - conn_id=cast("str", connection) - if action.action == BulkAction.DELETE - else cast("ConnectionBody", connection).connection_id + conn_id=connection_id, ), } - for connection in action.entities - ] - ) + requests.append(req) _requires_access( is_authorized_callback=lambda: get_auth_manager().batch_is_authorized_connection( @@ -373,19 +397,24 @@ def inner( ) -> None: requests: list[IsAuthorizedVariableRequest] = [] for action in request.actions: - requests.extend( - [ - { - "method": MAP_BULK_ACTION_TO_AUTH_METHOD[action.action], + methods = _get_resource_methods_from_bulk_request(action) + for variable in action.entities: + variable_key = ( + cast("str", variable) + if action.action == BulkAction.DELETE + else cast("VariableBody", variable).key + ) + # For each variable, build a `IsAuthorizedVariableRequest` + # The list of `IsAuthorizedVariableRequest` will then be sent using `batch_is_authorized_variable` + # Each `IsAuthorizedVariableRequest` is similar to calling `is_authorized_variable` + for method in methods: + req: IsAuthorizedVariableRequest = { + "method": method, "details": VariableDetails( - key=cast("str", entity) - if action.action == BulkAction.DELETE - else cast("VariableBody", entity).key + key=variable_key, ), } - for entity in action.entities - ] - ) + requests.append(req) _requires_access( is_authorized_callback=lambda: get_auth_manager().batch_is_authorized_variable( @@ -484,7 +513,7 @@ def is_safe_url(target_url: str, request: Request | None = None) -> bool: return True for base_url, parsed_base in parsed_bases: - parsed_target = urlparse(urljoin(base_url, target_url)) # Resolves relative URLs + parsed_target = urlparse(urljoin(base_url, unquote(target_url))) # Resolves relative URLs target_path = Path(parsed_target.path).resolve() @@ -494,3 +523,15 @@ def is_safe_url(target_url: str, request: Request | None = None) -> bool: if parsed_target.scheme in {"http", "https"} and parsed_target.netloc == parsed_base.netloc: return True return False + + +def _get_resource_methods_from_bulk_request( + action: BulkCreateAction | BulkUpdateAction | BulkDeleteAction, +) -> list[ResourceMethod]: + resource_methods: list[ResourceMethod] = [MAP_BULK_ACTION_TO_AUTH_METHOD[action.action]] + # If ``action_on_existence`` == ``overwrite``, we need to check the user has ``PUT`` access as well. + # With ``action_on_existence`` == ``overwrite``, a create request is actually an update request if the + # resource already exists, hence adding this check. + if action.action == BulkAction.CREATE and action.action_on_existence == BulkActionOnExistence.OVERWRITE: + resource_methods.append("PUT") + return resource_methods diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py index 1f64ffcefa866..acf333c64a884 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py @@ -85,16 +85,19 @@ def _find_aggregates( """Recursively fill the Task Group Map.""" node_id = node.node_id parent_id = parent_node.node_id if parent_node else None - details = ti_details[node_id] + # Do not mutate ti_details by accidental key creation + details = ti_details.get(node_id, []) if node is None: return if isinstance(node, MappedOperator): + # For unmapped tasks, reflect a single None state so UI shows one square + mapped_details = details or [{"state": None, "start_date": None, "end_date": None}] yield { "task_id": node_id, "type": "mapped_task", "parent_id": parent_id, - **_get_aggs_for_node(details), + **_get_aggs_for_node(mapped_details), } return diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/task_group.py b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/task_group.py index ed9a96718e9c6..1458641a3623f 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/task_group.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/task_group.py @@ -25,6 +25,7 @@ from airflow.configuration import conf from airflow.models.mappedoperator import MappedOperator, is_mapped +from airflow.sdk import TaskGroup from airflow.serialization.serialized_objects import SerializedBaseOperator @@ -40,9 +41,11 @@ def get_task_group_children_getter() -> Callable: def task_group_to_dict(task_item_or_group, parent_group_is_mapped=False): """Create a nested dict representation of this TaskGroup and its children used to construct the Graph.""" if isinstance(task := task_item_or_group, (SerializedBaseOperator, MappedOperator)): + # we explicitly want the short task ID here, not the full doted notation if in a group + task_display_name = task.task_display_name if task.task_display_name != task.task_id else task.label node_operator = { "id": task.task_id, - "label": task.label, + "label": task_display_name, "operator": task.operator_name, "type": "task", } @@ -54,7 +57,7 @@ def task_group_to_dict(task_item_or_group, parent_group_is_mapped=False): node_operator["is_mapped"] = True return node_operator - task_group = task_item_or_group + task_group: TaskGroup = task_item_or_group mapped = is_mapped(task_group) children = [ task_group_to_dict(child, parent_group_is_mapped=parent_group_is_mapped or mapped) @@ -71,7 +74,7 @@ def task_group_to_dict(task_item_or_group, parent_group_is_mapped=False): return { "id": task_group.group_id, - "label": task_group.label, + "label": task_group.group_display_name or task_group.label, "tooltip": task_group.tooltip, "is_mapped": mapped, "children": children, @@ -90,15 +93,17 @@ def task_group_to_dict_grid(task_item_or_group, parent_group_is_mapped=False): setup_teardown_type = "setup" elif task.is_teardown is True: setup_teardown_type = "teardown" + # we explicitly want the short task ID here, not the full doted notation if in a group + task_display_name = task.task_display_name if task.task_display_name != task.task_id else task.label return { "id": task.task_id, - "label": task.label, + "label": task_display_name, "is_mapped": mapped, "children": None, "setup_teardown_type": setup_teardown_type, } - task_group = task_item_or_group + task_group: TaskGroup = task_item_or_group task_group_sort = get_task_group_children_getter() mapped = is_mapped(task_group) children = [ @@ -108,7 +113,7 @@ def task_group_to_dict_grid(task_item_or_group, parent_group_is_mapped=False): return { "id": task_group.group_id, - "label": task_group.label, + "label": task_group.group_display_name or task_group.label, "is_mapped": mapped or None, "children": children or None, } diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/datamodels/hitl.py b/airflow-core/src/airflow/api_fastapi/execution_api/datamodels/hitl.py index 4162d2cf7717c..4cccbb69e712e 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/datamodels/hitl.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/datamodels/hitl.py @@ -26,6 +26,13 @@ from airflow.models.hitl import HITLDetail +class HITLUser(BaseModel): + """Schema for a Human-in-the-loop users.""" + + id: str + name: str + + class HITLDetailRequest(BaseModel): """Schema for the request part of a Human-in-the-loop detail for a specific task instance.""" @@ -36,7 +43,7 @@ class HITLDetailRequest(BaseModel): defaults: list[str] | None = None multiple: bool = False params: dict[str, Any] = Field(default_factory=dict) - respondents: list[str] | None = None + assigned_users: list[HITLUser] = Field(default_factory=list) class UpdateHITLDetailPayload(BaseModel): @@ -51,20 +58,27 @@ class HITLDetailResponse(BaseModel): """Schema for the response part of a Human-in-the-loop detail for a specific task instance.""" response_received: bool - responded_user_name: str | None - responded_user_id: str | None - response_at: datetime | None + responded_by_user: HITLUser | None = None + responded_at: datetime | None # It's empty if the user has not yet responded. chosen_options: list[str] | None params_input: dict[str, Any] = Field(default_factory=dict) @classmethod def from_hitl_detail_orm(cls, hitl_detail: HITLDetail) -> HITLDetailResponse: + hitl_user = ( + HITLUser( + id=hitl_detail.responded_by_user_id, + name=hitl_detail.responded_by_user_name, + ) + if hitl_detail.responded_by_user + else None + ) + return HITLDetailResponse( response_received=hitl_detail.response_received, - response_at=hitl_detail.response_at, - responded_user_id=hitl_detail.responded_user_id, - responded_user_name=hitl_detail.responded_user_name, + responded_at=hitl_detail.responded_at, + responded_by_user=hitl_user, chosen_options=hitl_detail.chosen_options, params_input=hitl_detail.params_input or {}, ) diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/hitl.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/hitl.py index c9efbda78f04a..50b9377d2f814 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/hitl.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/hitl.py @@ -71,14 +71,14 @@ def upsert_hitl_detail( defaults=payload.defaults, multiple=payload.multiple, params=payload.params, - respondents=payload.respondents, + assignees=[user.model_dump() for user in payload.assigned_users], ) session.add(hitl_detail_model) elif hitl_detail_model.response_received: # Cleanup the response part of HITLDetail as we only store one response for one task instance. # It normally happens after retry, we keep only the latest response. hitl_detail_model.responded_by = None - hitl_detail_model.response_at = None + hitl_detail_model.responded_at = None hitl_detail_model.chosen_options = None hitl_detail_model.params_input = {} session.add(hitl_detail_model) @@ -116,9 +116,8 @@ def update_hitl_detail( f"Human-in-the-loop detail for Task Instance with id {ti_id_str} already exists.", ) - hitl_detail_model.responded_user_id = HITLDetail.DEFAULT_USER_NAME - hitl_detail_model.responded_user_name = HITLDetail.DEFAULT_USER_NAME - hitl_detail_model.response_at = datetime.now(timezone.utc) + hitl_detail_model.responded_by = None + hitl_detail_model.responded_at = datetime.now(timezone.utc) hitl_detail_model.chosen_options = payload.chosen_options hitl_detail_model.params_input = payload.params_input session.add(hitl_detail_model) diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py index c30cf1e9c4c4b..67af09eeb3c9d 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py @@ -254,14 +254,7 @@ def ti_run( if dag := dag_bag.get_dag_for_run(dag_run=dr, session=session): upstream_map_indexes = dict( - _get_upstream_map_indexes( - # TODO (GH-52141): This get_task should return scheduler - # types instead, but currently it inherits SDK's DAG. - cast("MappedOperator | SerializedBaseOperator", dag.get_task(ti.task_id)), - ti.map_index, - ti.run_id, - session=session, - ) + _get_upstream_map_indexes(dag.get_task(ti.task_id), ti.map_index, ti.run_id, session=session) ) else: upstream_map_indexes = None @@ -444,7 +437,7 @@ def _create_ti_state_update_query_and_update_state( ti = session.get(TI, ti_id_str) updated_state = ti_patch_payload.state query = TI.duration_expression_update(ti_patch_payload.end_date, query, session.bind) - query = query.values(state=updated_state) + query = query.values(state=updated_state, next_method=None, next_kwargs=None) if updated_state == TerminalTIState.FAILED: # This is the only case needs extra handling for TITerminalStatePayload diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/variables.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/variables.py index e168598786617..d2f5d21349c44 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/variables.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/variables.py @@ -55,7 +55,7 @@ async def has_variable_access( @router.get( - "/{variable_key}", + "/{variable_key:path}", responses={ status.HTTP_401_UNAUTHORIZED: {"description": "Unauthorized"}, status.HTTP_403_FORBIDDEN: {"description": "Task does not have access to the variable"}, @@ -63,6 +63,9 @@ async def has_variable_access( ) def get_variable(variable_key: str) -> VariableResponse: """Get an Airflow Variable.""" + if not variable_key: + raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Not Found") + try: variable_value = Variable.get(variable_key) except KeyError: @@ -78,7 +81,7 @@ def get_variable(variable_key: str) -> VariableResponse: @router.put( - "/{variable_key}", + "/{variable_key:path}", status_code=status.HTTP_201_CREATED, responses={ status.HTTP_401_UNAUTHORIZED: {"description": "Unauthorized"}, @@ -87,12 +90,15 @@ def get_variable(variable_key: str) -> VariableResponse: ) def put_variable(variable_key: str, body: VariablePostBody): """Set an Airflow Variable.""" + if not variable_key: + raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Not Found") + Variable.set(key=variable_key, value=body.value, description=body.description) return {"message": "Variable successfully set"} @router.delete( - "/{variable_key}", + "/{variable_key:path}", status_code=status.HTTP_204_NO_CONTENT, responses={ status.HTTP_401_UNAUTHORIZED: {"description": "Unauthorized"}, @@ -101,4 +107,7 @@ def put_variable(variable_key: str, body: VariablePostBody): ) def delete_variable(variable_key: str): """Delete an Airflow Variable.""" + if not variable_key: + raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Not Found") + Variable.delete(key=variable_key) diff --git a/airflow-core/src/airflow/api_fastapi/main.py b/airflow-core/src/airflow/api_fastapi/main.py index 16419b9485ead..195f98a5bf328 100644 --- a/airflow-core/src/airflow/api_fastapi/main.py +++ b/airflow-core/src/airflow/api_fastapi/main.py @@ -19,6 +19,10 @@ import os +# Mark this as a server context before any airflow imports +# This ensures plugins loaded at import time get the correct secrets backend chain +os.environ["_AIRFLOW_PROCESS_CONTEXT"] = "server" + from airflow.api_fastapi.app import cached_app # There is no way to pass the apps to this file from Airflow CLI diff --git a/airflow-core/src/airflow/callbacks/callback_requests.py b/airflow-core/src/airflow/callbacks/callback_requests.py index e0666b397c235..d2bdf0968bc20 100644 --- a/airflow-core/src/airflow/callbacks/callback_requests.py +++ b/airflow-core/src/airflow/callbacks/callback_requests.py @@ -77,7 +77,7 @@ def is_failure_callback(self) -> bool: } -class EmailNotificationRequest(BaseCallbackRequest): +class EmailRequest(BaseCallbackRequest): """Email notification request for task failures/retries.""" ti: ti_datamodel.TaskInstance @@ -86,7 +86,7 @@ class EmailNotificationRequest(BaseCallbackRequest): """Whether this is for a failure or retry email""" context_from_server: ti_datamodel.TIRunContext """Task execution context from the Server""" - type: Literal["EmailNotificationRequest"] = "EmailNotificationRequest" + type: Literal["EmailRequest"] = "EmailRequest" class DagRunContext(BaseModel): @@ -108,6 +108,9 @@ class DagCallbackRequest(BaseCallbackRequest): CallbackRequest = Annotated[ - DagCallbackRequest | TaskCallbackRequest | EmailNotificationRequest, + DagCallbackRequest | TaskCallbackRequest | EmailRequest, Field(discriminator="type"), ] + +# Backwards compatibility alias +EmailNotificationRequest = EmailRequest diff --git a/airflow-core/src/airflow/callbacks/database_callback_sink.py b/airflow-core/src/airflow/callbacks/database_callback_sink.py index 390f762002263..e7e27cf86b50e 100644 --- a/airflow-core/src/airflow/callbacks/database_callback_sink.py +++ b/airflow-core/src/airflow/callbacks/database_callback_sink.py @@ -35,5 +35,5 @@ class DatabaseCallbackSink(BaseCallbackSink): @provide_session def send(self, callback: CallbackRequest, session: Session = NEW_SESSION) -> None: """Send callback for execution.""" - db_callback = DbCallbackRequest(callback=callback, priority_weight=10) + db_callback = DbCallbackRequest(callback=callback, priority_weight=1) session.add(db_callback) diff --git a/airflow-core/src/airflow/cli/commands/backfill_command.py b/airflow-core/src/airflow/cli/commands/backfill_command.py index 444bc35aea34a..a6b35d6d2391b 100644 --- a/airflow-core/src/airflow/cli/commands/backfill_command.py +++ b/airflow-core/src/airflow/cli/commands/backfill_command.py @@ -17,6 +17,7 @@ from __future__ import annotations +import json import logging import signal @@ -80,13 +81,22 @@ def create_backfill(args) -> None: except AirflowConfigException as e: log.warning("Failed to get user name from os: %s, not setting the triggering user", e) user = None + + # Parse dag_run_conf if provided + dag_run_conf = None + if args.dag_run_conf: + try: + dag_run_conf = json.loads(args.dag_run_conf) + except json.JSONDecodeError as e: + raise ValueError(f"Invalid JSON in --dag-run-conf: {e}") + _create_backfill( dag_id=args.dag_id, from_date=args.from_date, to_date=args.to_date, max_active_runs=args.max_active_runs, reverse=args.run_backwards, - dag_run_conf=args.dag_run_conf, + dag_run_conf=dag_run_conf, triggering_user_name=user, reprocess_behavior=reprocess_behavior, run_on_latest_version=args.run_on_latest_version, diff --git a/airflow-core/src/airflow/cli/commands/config_command.py b/airflow-core/src/airflow/cli/commands/config_command.py index 0c30ce111af65..b766351229cd6 100644 --- a/airflow-core/src/airflow/cli/commands/config_command.py +++ b/airflow-core/src/airflow/cli/commands/config_command.py @@ -640,6 +640,9 @@ def message(self) -> str | None: ConfigChange( config=ConfigParameter("scheduler", "allow_trigger_in_future"), ), + ConfigChange( + config=ConfigParameter("scheduler", "dag_stale_not_seen_duration"), + ), ConfigChange( config=ConfigParameter("scheduler", "catchup_by_default"), default_change=True, diff --git a/airflow-core/src/airflow/cli/commands/dag_processor_command.py b/airflow-core/src/airflow/cli/commands/dag_processor_command.py index c866763338ff1..9f054eb846755 100644 --- a/airflow-core/src/airflow/cli/commands/dag_processor_command.py +++ b/airflow-core/src/airflow/cli/commands/dag_processor_command.py @@ -22,7 +22,7 @@ from typing import Any from airflow.cli.commands.daemon_utils import run_command_with_daemon_option -from airflow.dag_processing.manager import DagFileProcessorManager, reload_configuration_for_dag_processing +from airflow.dag_processing.manager import DagFileProcessorManager from airflow.jobs.dag_processor_job_runner import DagProcessorJobRunner from airflow.jobs.job import Job, run_job from airflow.utils import cli as cli_utils @@ -50,7 +50,6 @@ def dag_processor(args): """Start Airflow Dag Processor Job.""" job_runner = _create_dag_processor_job_runner(args) - reload_configuration_for_dag_processing() run_command_with_daemon_option( args=args, process_name="dag-processor", diff --git a/airflow-core/src/airflow/cli/commands/scheduler_command.py b/airflow-core/src/airflow/cli/commands/scheduler_command.py index 15093fd24d0c7..f0437710f95b7 100644 --- a/airflow-core/src/airflow/cli/commands/scheduler_command.py +++ b/airflow-core/src/airflow/cli/commands/scheduler_command.py @@ -62,9 +62,9 @@ def _serve_logs(skip_serve_logs: bool = False): from airflow.utils.serve_logs import serve_logs sub_proc = None - executor_class, _ = ExecutorLoader.import_default_executor_cls() - if executor_class.serve_logs: - if skip_serve_logs is False: + if skip_serve_logs is False: + executor_class, _ = ExecutorLoader.import_default_executor_cls() + if executor_class.serve_logs: sub_proc = Process(target=serve_logs) sub_proc.start() try: diff --git a/airflow-core/src/airflow/cli/commands/task_command.py b/airflow-core/src/airflow/cli/commands/task_command.py index 5b54d76100a50..9b4cd4114f4dd 100644 --- a/airflow-core/src/airflow/cli/commands/task_command.py +++ b/airflow-core/src/airflow/cli/commands/task_command.py @@ -46,6 +46,7 @@ get_bagged_dag, get_dag_by_file_location, get_dags, + get_db_dag, suppress_logs_and_warning, ) from airflow.utils.helpers import ask_yesno @@ -82,7 +83,7 @@ def _generate_temporary_run_id() -> str: def _get_dag_run( *, - dag: DAG, + dag: SerializedDAG, create_if_necessary: CreateIfNecessary, logical_date_or_run_id: str | None = None, session: Session | None = None, @@ -144,9 +145,8 @@ def _get_dag_run( ) return dag_run, True if create_if_necessary == "db": - scheduler_dag = SerializedDAG.deserialize_dag(SerializedDAG.serialize_dag(dag)) # type: ignore[arg-type] dag_run = get_or_create_dagrun( - dag=scheduler_dag, + dag=dag, run_id=_generate_temporary_run_id(), logical_date=dag_run_logical_date, data_interval=data_interval, @@ -246,10 +246,7 @@ def task_failed_deps(args) -> None: Trigger Rule: Task's trigger rule 'all_success' requires all upstream tasks to have succeeded, but found 1 non-success(es). """ - dag = get_bagged_dag(args.bundle_name, args.dag_id) - # TODO (GH-52141): get_task in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - task = cast("Operator", dag.get_task(task_id=args.task_id)) + task = get_db_dag(args.bundle_name, args.dag_id).get_task(task_id=args.task_id) ti, _ = _get_ti(task, args.map_index, logical_date_or_run_id=args.logical_date_or_run_id) dep_context = DepContext(deps=SCHEDULER_QUEUED_DEPS) failed_deps = list(ti.get_failed_dep_statuses(dep_context=dep_context)) @@ -274,9 +271,7 @@ def task_state(args) -> None: """ if not (dag := SerializedDagModel.get_dag(args.dag_id)): raise SystemExit(f"Can not find dag {args.dag_id!r}") - # TODO (GH-52141): get_task in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - task = cast("Operator", dag.get_task(task_id=args.task_id)) + task = dag.get_task(task_id=args.task_id) ti, _ = _get_ti(task, args.map_index, logical_date_or_run_id=args.logical_date_or_run_id) print(ti.state) @@ -389,29 +384,35 @@ def task_test(args, dag: DAG | None = None) -> None: env_vars.update(args.env_vars) os.environ.update(env_vars) - dag = dag or get_bagged_dag(args.bundle_name, args.dag_id) + if dag: + sdk_dag = dag + scheduler_dag = SerializedDAG.from_dict(SerializedDAG.to_dict(dag)) + else: + sdk_dag = get_bagged_dag(args.bundle_name, args.dag_id) + scheduler_dag = get_db_dag(args.bundle_name, args.dag_id) - # TODO (GH-52141): get_task in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - task = cast("Operator", dag.get_task(task_id=args.task_id)) + sdk_task = sdk_dag.get_task(args.task_id) # Add CLI provided task_params to task.params if args.task_params: passed_in_params = json.loads(args.task_params) - task.params.update(passed_in_params) + sdk_task.params.update(passed_in_params) - if task.params and isinstance(task.params, ParamsDict): - task.params.validate() + if sdk_task.params and isinstance(sdk_task.params, ParamsDict): + sdk_task.params.validate() ti, dr_created = _get_ti( - task, args.map_index, logical_date_or_run_id=args.logical_date_or_run_id, create_if_necessary="db" + scheduler_dag.get_task(args.task_id), + args.map_index, + logical_date_or_run_id=args.logical_date_or_run_id, + create_if_necessary="db", ) try: # TODO: move bulk of this logic into the SDK: http://github.com/apache/airflow/issues/54658 from airflow.sdk._shared.secrets_masker import RedactedIO with redirect_stdout(RedactedIO()): - _run_task(ti=ti, task=task, run_triggerer=True) + _run_task(ti=ti, task=sdk_task, run_triggerer=True) if ti.state == State.FAILED and args.post_mortem: debugger = _guess_debugger() debugger.set_trace() @@ -434,9 +435,7 @@ def task_render(args, dag: DAG | None = None) -> None: dag = get_bagged_dag(args.bundle_name, args.dag_id) serialized_dag = SerializedDAG.deserialize_dag(SerializedDAG.serialize_dag(dag)) ti, _ = _get_ti( - # TODO (GH-52141): get_task in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - cast("Operator", serialized_dag.get_task(task_id=args.task_id)), + serialized_dag.get_task(task_id=args.task_id), args.map_index, logical_date_or_run_id=args.logical_date_or_run_id, create_if_necessary="memory", diff --git a/airflow-core/src/airflow/config_templates/airflow_local_settings.py b/airflow-core/src/airflow/config_templates/airflow_local_settings.py index 4c2cddb043c96..6270fba7ba3ba 100644 --- a/airflow-core/src/airflow/config_templates/airflow_local_settings.py +++ b/airflow-core/src/airflow/config_templates/airflow_local_settings.py @@ -43,16 +43,11 @@ "logging", "LOG_FORMATTER_CLASS", fallback="airflow.utils.log.timezone_aware.TimezoneAware" ) -COLORED_LOG_FORMAT: str = conf.get_mandatory_value("logging", "COLORED_LOG_FORMAT") - -COLORED_LOG: bool = conf.getboolean("logging", "COLORED_CONSOLE_LOG") - -COLORED_FORMATTER_CLASS: str = conf.get_mandatory_value("logging", "COLORED_FORMATTER_CLASS") - DAG_PROCESSOR_LOG_TARGET: str = conf.get_mandatory_value("logging", "DAG_PROCESSOR_LOG_TARGET") BASE_LOG_FOLDER: str = os.path.expanduser(conf.get_mandatory_value("logging", "BASE_LOG_FOLDER")) +# This isn't used anymore, but kept for compat of people who might have imported it DEFAULT_LOGGING_CONFIG: dict[str, Any] = { "version": 1, "disable_existing_loggers": False, @@ -61,10 +56,6 @@ "format": LOG_FORMAT, "class": LOG_FORMATTER_CLASS, }, - "airflow_coloured": { - "format": COLORED_LOG_FORMAT if COLORED_LOG else LOG_FORMAT, - "class": COLORED_FORMATTER_CLASS if COLORED_LOG else LOG_FORMATTER_CLASS, - }, "source_processor": { "format": DAG_PROCESSOR_LOG_FORMAT, "class": LOG_FORMATTER_CLASS, @@ -77,8 +68,9 @@ }, "handlers": { "console": { - "class": "airflow.utils.log.logging_mixin.RedirectStdHandler", - "formatter": "airflow_coloured", + "class": "logging.StreamHandler", + # "class": "airflow.utils.log.logging_mixin.RedirectStdHandler", + "formatter": "airflow", "stream": "sys.stdout", "filters": ["mask_secrets_core"], }, diff --git a/airflow-core/src/airflow/config_templates/config.yml b/airflow-core/src/airflow/config_templates/config.yml index 5da744041a2e3..a7bd041362209 100644 --- a/airflow-core/src/airflow/config_templates/config.yml +++ b/airflow-core/src/airflow/config_templates/config.yml @@ -828,29 +828,32 @@ logging: type: string example: ~ default: "True" - colored_log_format: - description: | - Log format for when Colored logs is enabled - version_added: 2.0.0 - type: string - example: ~ - default: >- - [%%(blue)s%%(asctime)s%%(reset)s] {{%%(blue)s%%(filename)s:%%(reset)s%%(lineno)d}} - %%(log_color)s%%(levelname)s%%(reset)s - %%(log_color)s%%(message)s%%(reset)s - colored_formatter_class: - description: | - Specifies the class utilized by Airflow to implement colored logging - version_added: 2.0.0 - type: string - example: ~ - default: "airflow.utils.log.colored_log.CustomTTYColoredFormatter" log_format: description: | Format of Log line + + *Changed in 3.1.0*: This can now contain color escape sequences ``%(blue)s`` etc which will only + result in colours if :ref:`config:logging__colored_console_log` is true. + version_added: 2.0.0 type: string + example: "[%%(asctime)s] {{%%(filename)s:%%(lineno)d}} %%(levelname)s - %%(message)s" + default: "" + callsite_parameters: + description: | + A comma separated list of information about the callsite (such as line number of filename etc) of + logger calls to include in each message. + + See :class:`structlog.processors.CallsiteParameter` for the possible values.The values should be the + constant names (``FUNC_NAME``) or the values (``func_name``) + + Including these in a log message adds a lot to the usability to the logs, but collecting these has a + (tiny) cost -- if you are super concerned with eking out every last ounce of performance you could + turn these off (by setting this value to an empty string) + version_added: 3.1.0 + type: string + default: "filename,lineno" example: ~ - default: "[%%(asctime)s] {{%%(filename)s:%%(lineno)d}} %%(levelname)s - %%(message)s" simple_log_format: description: | Defines the format of log messages for simple logging configuration @@ -1386,11 +1389,13 @@ api: default: "8080" workers: description: | - Number of workers to run on the API server + Number of workers to run on the API server. Should be roughly equal to the number of + cpu cores available. If you need to scale the API server, consider deploying multiple API + servers instead of increasing the number of workers. version_added: ~ type: integer example: ~ - default: "4" + default: "1" worker_timeout: description: | Number of seconds the API server waits before timing out on a worker @@ -1581,6 +1586,15 @@ workers: type: float example: ~ default: "90.0" + execution_api_timeout: + description: | + The timeout (in seconds) for HTTP requests from workers to the Execution API server. + This controls how long a worker will wait for a response from the API server before + timing out. Increase this value if you experience timeout errors under high load. + version_added: 3.1.1 + type: float + example: ~ + default: "5.0" socket_cleanup_timeout: description: | Number of seconds to wait after a task process exits before forcibly closing any @@ -2158,13 +2172,6 @@ scheduler: type: integer default: "20" see_also: ":ref:`scheduler:ha:tunables`" - dag_stale_not_seen_duration: - description: | - Time in seconds after which dags, which were not updated by Dag Processor are deactivated. - version_added: 2.4.0 - type: integer - example: ~ - default: "600" use_job_schedule: description: | Turn off scheduler use of cron intervals by setting this to ``False``. diff --git a/airflow-core/src/airflow/configuration.py b/airflow-core/src/airflow/configuration.py index 24a439e848e87..042d6c84834bc 100644 --- a/airflow-core/src/airflow/configuration.py +++ b/airflow-core/src/airflow/configuration.py @@ -1235,7 +1235,7 @@ def getlist(self, section: str, key: str, delimiter=",", **kwargs): val = self.get(section, key, **kwargs) if val is None: if "fallback" in kwargs: - return val + return kwargs["fallback"] raise AirflowConfigException( f"Failed to convert value None to list. " f'Please check "{key}" key in "{section}" section is set.' diff --git a/airflow-core/src/airflow/dag_processing/collection.py b/airflow-core/src/airflow/dag_processing/collection.py index ae247b1f00352..56de2fae758bf 100644 --- a/airflow-core/src/airflow/dag_processing/collection.py +++ b/airflow-core/src/airflow/dag_processing/collection.py @@ -27,10 +27,10 @@ from __future__ import annotations -import logging import traceback from typing import TYPE_CHECKING, NamedTuple, TypeVar +import structlog from sqlalchemy import delete, func, insert, select, tuple_, update from sqlalchemy.exc import OperationalError from sqlalchemy.orm import joinedload, load_only @@ -73,7 +73,7 @@ AssetT = TypeVar("AssetT", bound=BaseAsset) -log = logging.getLogger(__name__) +log = structlog.get_logger(__name__) def _create_orm_dags( diff --git a/airflow-core/src/airflow/dag_processing/manager.py b/airflow-core/src/airflow/dag_processing/manager.py index 2b81e10019a86..df4f84d0ce548 100644 --- a/airflow-core/src/airflow/dag_processing/manager.py +++ b/airflow-core/src/airflow/dag_processing/manager.py @@ -21,7 +21,6 @@ import contextlib import functools -import importlib import inspect import logging import os @@ -35,7 +34,6 @@ from collections.abc import Callable, Iterable, Iterator from dataclasses import dataclass, field from datetime import datetime, timedelta -from importlib import import_module from operator import attrgetter, itemgetter from pathlib import Path from typing import TYPE_CHECKING, Any, NamedTuple, cast @@ -47,7 +45,6 @@ from tabulate import tabulate from uuid6 import uuid7 -import airflow.models from airflow._shared.timezones import timezone from airflow.api_fastapi.execution_api.app import InProcessExecutionAPI from airflow.configuration import conf @@ -454,7 +451,9 @@ def _fetch_callbacks( callback_queue: list[CallbackRequest] = [] with prohibit_commit(session) as guard: query = select(DbCallbackRequest) - query = query.order_by(DbCallbackRequest.priority_weight.asc()).limit(self.max_callbacks_per_loop) + query = query.order_by(DbCallbackRequest.priority_weight.desc()).limit( + self.max_callbacks_per_loop + ) query = with_row_locks(query, of=DbCallbackRequest, session=session, skip_locked=True) callbacks = session.scalars(query) for callback in callbacks: @@ -802,8 +801,9 @@ def terminate_orphan_processes(self, present: set[DagFileInfo]): processor = self._processors.pop(file, None) if not processor: continue - self.log.warning("Stopping processor for %s", file) - Stats.decr("dag_processing.processes", tags={"file_path": file, "action": "stop"}) + file_name = str(file.rel_path) + self.log.warning("Stopping processor for %s", file_name) + Stats.decr("dag_processing.processes", tags={"file_path": file_name, "action": "stop"}) processor.kill(signal.SIGKILL) processor.logger_filehandle.close() self._file_stats.pop(file, None) @@ -818,6 +818,12 @@ def _collect_results(self, session: Session = NEW_SESSION): continue finished.append(file) + # Detect if this was callback-only processing + # For such-cases, we don't serialize the dags and hence send parsing_result as None. + is_callback_only = proc.had_callbacks and proc.parsing_result is None + if is_callback_only: + self.log.debug("Detected callback-only processing for %s", file) + # Collect the DAGS and import errors into the DB, emit metrics etc. self._file_stats[file] = process_parse_results( run_duration=time.monotonic() - proc.start_time, @@ -827,6 +833,7 @@ def _collect_results(self, session: Session = NEW_SESSION): bundle_version=self._bundle_versions[file.bundle_name], parsing_result=proc.parsing_result, session=session, + is_callback_only=is_callback_only, ) for file in finished: @@ -876,7 +883,7 @@ def _get_logger_for_dag_file(self, dag_file: DagFileInfo): log_file = init_log_file(log_filename) logger_filehandle = log_file.open("ab") underlying_logger = structlog.BytesLogger(logger_filehandle) - processors = logging_processors(enable_pretty_log=False)[0] + processors = logging_processors(json_output=True) return structlog.wrap_logger( underlying_logger, processors=processors, logger_name="processor" ).bind(), logger_filehandle @@ -916,7 +923,7 @@ def _start_new_processes(self): continue processor = self._create_process(file) - Stats.incr("dag_processing.processes", tags={"file_path": file, "action": "start"}) + Stats.incr("dag_processing.processes", tags={"file_path": str(file.rel_path), "action": "start"}) self._processors[file] = processor Stats.gauge("dag_processing.file_path_queue_size", len(self._file_queue)) @@ -1027,8 +1034,9 @@ def _kill_timed_out_processors(self): processor.pid, duration, ) - Stats.decr("dag_processing.processes", tags={"file_path": file, "action": "timeout"}) - Stats.incr("dag_processing.processor_timeouts", tags={"file_path": file}) + file_name = str(file.rel_path) + Stats.decr("dag_processing.processes", tags={"file_path": file_name, "action": "timeout"}) + Stats.incr("dag_processing.processor_timeouts", tags={"file_path": file_name}) processor.kill(signal.SIGKILL) processors_to_remove.append(file) @@ -1069,7 +1077,9 @@ def terminate(self): """Stop all running processors.""" for file, processor in self._processors.items(): # todo: AIP-66 what to do about file_path tag? replace with bundle name and rel path? - Stats.decr("dag_processing.processes", tags={"file_path": file, "action": "terminate"}) + Stats.decr( + "dag_processing.processes", tags={"file_path": str(file.rel_path), "action": "terminate"} + ) # SIGTERM, wait 5s, SIGKILL if still alive processor.kill(signal.SIGTERM, escalation_delay=5.0) @@ -1102,29 +1112,6 @@ def emit_metrics(self): ) -def reload_configuration_for_dag_processing(): - # Reload configurations and settings to avoid collision with parent process. - # Because this process may need custom configurations that cannot be shared, - # e.g. RotatingFileHandler. And it can cause connection corruption if we - # do not recreate the SQLA connection pool. - os.environ["CONFIG_PROCESSOR_MANAGER_LOGGER"] = "True" - os.environ["AIRFLOW__LOGGING__COLORED_CONSOLE_LOG"] = "False" - # Replicating the behavior of how logging module was loaded - # in logging_config.py - # TODO: This reloading should be removed when we fix our logging behaviour - # In case of "spawn" method of starting processes for multiprocessing, reinitializing of the - # SQLAlchemy engine causes extremely unexpected behaviour of messing with objects already loaded - # in a parent process (likely via resources shared in memory by the ORM libraries). - # This caused flaky tests in our CI for many months and has been discovered while - # iterating on https://github.com/apache/airflow/pull/19860 - # The issue that describes the problem and possible remediation is - # at https://github.com/apache/airflow/issues/19934 - importlib.reload(import_module(airflow.settings.LOGGING_CLASS_PATH.rsplit(".", 1)[0])) - importlib.reload(airflow.settings) - airflow.settings.initialize() - del os.environ["CONFIG_PROCESSOR_MANAGER_LOGGER"] - - def process_parse_results( run_duration: float, finish_time: datetime, @@ -1133,13 +1120,24 @@ def process_parse_results( bundle_version: str | None, parsing_result: DagFileParsingResult | None, session: Session, + *, + is_callback_only: bool = False, ) -> DagFileStat: """Take the parsing result and stats about the parser process and convert it into a DagFileStat.""" - stat = DagFileStat( - last_finish_time=finish_time, - last_duration=run_duration, - run_count=run_count + 1, - ) + if is_callback_only: + # Callback-only processing - don't update timestamps to avoid stale DAG detection issues + stat = DagFileStat( + last_duration=run_duration, + run_count=run_count, # Don't increment for callback-only processing + ) + Stats.incr("dag_processing.callback_only_count") + else: + # Actual DAG parsing or import error + stat = DagFileStat( + last_finish_time=finish_time, + last_duration=run_duration, + run_count=run_count + 1, + ) # TODO: AIP-66 emit metrics # file_name = Path(dag_file.path).stem @@ -1147,7 +1145,10 @@ def process_parse_results( # Stats.timing("dag_processing.last_duration", stat.last_duration, tags={"file_name": file_name}) if parsing_result is None: - stat.import_errors = 1 + # No DAGs were parsed - this happens for callback-only processing + # Don't treat this as an import error when it's callback-only + if not is_callback_only: + stat.import_errors = 1 else: # record DAGs and import errors to database import_errors = {} diff --git a/airflow-core/src/airflow/dag_processing/processor.py b/airflow-core/src/airflow/dag_processing/processor.py index d4c73e61fea56..527e5d8c0aa9a 100644 --- a/airflow-core/src/airflow/dag_processing/processor.py +++ b/airflow-core/src/airflow/dag_processing/processor.py @@ -31,7 +31,7 @@ from airflow.callbacks.callback_requests import ( CallbackRequest, DagCallbackRequest, - EmailNotificationRequest, + EmailRequest, TaskCallbackRequest, ) from airflow.configuration import conf @@ -43,13 +43,24 @@ GetConnection, GetPreviousDagRun, GetPrevSuccessfulDagRun, + GetTaskStates, + GetTICount, GetVariable, + GetXCom, + GetXComCount, + GetXComSequenceItem, + GetXComSequenceSlice, MaskSecret, OKResponse, PreviousDagRunResult, PrevSuccessfulDagRunResult, PutVariable, + TaskStatesResult, VariableResult, + XComCountResponse, + XComResult, + XComSequenceIndexResult, + XComSequenceSliceResult, ) from airflow.sdk.execution_time.supervisor import WatchedSubprocess from airflow.sdk.execution_time.task_runner import RuntimeTaskInstance, _send_task_error_email @@ -104,9 +115,15 @@ class DagFileParsingResult(BaseModel): | GetConnection | GetVariable | PutVariable + | GetTaskStates + | GetTICount | DeleteVariable | GetPrevSuccessfulDagRun | GetPreviousDagRun + | GetXCom + | GetXComCount + | GetXComSequenceItem + | GetXComSequenceSlice | MaskSecret, Field(discriminator="type"), ] @@ -115,10 +132,15 @@ class DagFileParsingResult(BaseModel): DagFileParseRequest | ConnectionResult | VariableResult + | TaskStatesResult | PreviousDagRunResult | PrevSuccessfulDagRunResult | ErrorResponse - | OKResponse, + | OKResponse + | XComCountResponse + | XComResult + | XComSequenceIndexResult + | XComSequenceSliceResult, Field(discriminator="type"), ] @@ -140,7 +162,7 @@ def _pre_import_airflow_modules(file_path: str, log: FilteringBoundLogger) -> No for module in iter_airflow_imports(file_path): try: importlib.import_module(module) - except ModuleNotFoundError as e: + except Exception as e: log.warning("Error when trying to pre-import module '%s' found in %s: %s", module, file_path, e) @@ -227,7 +249,7 @@ def _execute_callbacks( _execute_task_callbacks(dagbag, request, log) elif isinstance(request, DagCallbackRequest): _execute_dag_callbacks(dagbag, request, log) - elif isinstance(request, EmailNotificationRequest): + elif isinstance(request, EmailRequest): _execute_email_callbacks(dagbag, request, log) @@ -338,9 +360,7 @@ def get_callback_representation(callback): log.exception("Error in callback at index %d: %s", idx, callback_repr) -def _execute_email_callbacks( - dagbag: DagBag, request: EmailNotificationRequest, log: FilteringBoundLogger -) -> None: +def _execute_email_callbacks(dagbag: DagBag, request: EmailRequest, log: FilteringBoundLogger) -> None: """Execute email notification for task failure/retry.""" dag = dagbag.dags[request.ti.dag_id] task = dag.get_task(request.ti.task_id) @@ -422,6 +442,7 @@ class DagFileProcessorProcess(WatchedSubprocess): logger_filehandle: BinaryIO parsing_result: DagFileParsingResult | None = None decoder: ClassVar[TypeAdapter[ToManager]] = TypeAdapter[ToManager](ToManager) + had_callbacks: bool = False # Track if this process was started with callbacks to prevent stale DAG detection false positives client: Client """The HTTP client to use for communication with the API server.""" @@ -442,6 +463,7 @@ def start( # type: ignore[override] _pre_import_airflow_modules(os.fspath(path), logger) proc: Self = super().start(target=target, client=client, **kwargs) + proc.had_callbacks = bool(callbacks) # Track if this process had callbacks proc._on_child_started(callbacks, path, bundle_path) return proc @@ -459,7 +481,12 @@ def _on_child_started( self.send_msg(msg, request_id=0) def _handle_request(self, msg: ToManager, log: FilteringBoundLogger, req_id: int) -> None: - from airflow.sdk.api.datamodels._generated import ConnectionResponse, VariableResponse + from airflow.sdk.api.datamodels._generated import ( + ConnectionResponse, + TaskStatesResponse, + VariableResponse, + XComSequenceIndexResponse, + ) resp: BaseModel | None = None dump_opts = {} @@ -496,11 +523,62 @@ def _handle_request(self, msg: ToManager, log: FilteringBoundLogger, req_id: int dagrun_result = PrevSuccessfulDagRunResult.from_dagrun_response(dagrun_resp) resp = dagrun_result dump_opts = {"exclude_unset": True} + elif isinstance(msg, GetXCom): + xcom = self.client.xcoms.get( + msg.dag_id, msg.run_id, msg.task_id, msg.key, msg.map_index, msg.include_prior_dates + ) + xcom_result = XComResult.from_xcom_response(xcom) + resp = xcom_result + elif isinstance(msg, GetXComCount): + resp = self.client.xcoms.head(msg.dag_id, msg.run_id, msg.task_id, msg.key) + elif isinstance(msg, GetXComSequenceItem): + xcom = self.client.xcoms.get_sequence_item( + msg.dag_id, msg.run_id, msg.task_id, msg.key, msg.offset + ) + if isinstance(xcom, XComSequenceIndexResponse): + resp = XComSequenceIndexResult.from_response(xcom) + else: + resp = xcom + elif isinstance(msg, GetXComSequenceSlice): + xcoms = self.client.xcoms.get_sequence_slice( + msg.dag_id, + msg.run_id, + msg.task_id, + msg.key, + msg.start, + msg.stop, + msg.step, + msg.include_prior_dates, + ) + resp = XComSequenceSliceResult.from_response(xcoms) elif isinstance(msg, MaskSecret): # Use sdk masker in dag processor and triggerer because those use the task sdk machinery from airflow.sdk.log import mask_secret mask_secret(msg.value, msg.name) + elif isinstance(msg, GetTICount): + resp = self.client.task_instances.get_count( + dag_id=msg.dag_id, + map_index=msg.map_index, + task_ids=msg.task_ids, + task_group_id=msg.task_group_id, + logical_dates=msg.logical_dates, + run_ids=msg.run_ids, + states=msg.states, + ) + elif isinstance(msg, GetTaskStates): + task_states_map = self.client.task_instances.get_task_states( + dag_id=msg.dag_id, + map_index=msg.map_index, + task_ids=msg.task_ids, + task_group_id=msg.task_group_id, + logical_dates=msg.logical_dates, + run_ids=msg.run_ids, + ) + if isinstance(task_states_map, TaskStatesResponse): + resp = TaskStatesResult.from_api_response(task_states_map) + else: + resp = task_states_map else: log.error("Unhandled request", msg=msg) self.send_msg( diff --git a/airflow-core/src/airflow/example_dags/example_dag_decorator.py b/airflow-core/src/airflow/example_dags/example_dag_decorator.py index 9f6e637c9178e..c4c367f467324 100644 --- a/airflow-core/src/airflow/example_dags/example_dag_decorator.py +++ b/airflow-core/src/airflow/example_dags/example_dag_decorator.py @@ -51,11 +51,11 @@ def execute(self, context: Context): catchup=False, tags=["example"], ) -def example_dag_decorator(url: str = "http://httpbin.org/get"): +def example_dag_decorator(url: str = "https://httpbingo.org/get"): """ DAG to get IP address and echo it via BashOperator. - :param url: URL to get IP address from. Defaults to "http://httpbin.org/get". + :param url: URL to get IP address from. Defaults to "https://httpbingo.org/get". """ get_ip = GetRequestOperator(task_id="get_ip", url=url) diff --git a/airflow-core/src/airflow/executors/local_executor.py b/airflow-core/src/airflow/executors/local_executor.py index d85bb210e4d96..1c15fca7d9c1f 100644 --- a/airflow-core/src/airflow/executors/local_executor.py +++ b/airflow-core/src/airflow/executors/local_executor.py @@ -36,7 +36,6 @@ from airflow.executors import workloads from airflow.executors.base_executor import PARALLELISM, BaseExecutor -from airflow.utils.session import NEW_SESSION, provide_session from airflow.utils.state import TaskInstanceState # add logger to parameter of setproctitle to support logging @@ -48,8 +47,6 @@ setproctitle = lambda title, logger: real_setproctitle(title) if TYPE_CHECKING: - from sqlalchemy.orm import Session - TaskInstanceStateType = tuple[workloads.TaskInstance, TaskInstanceState, Exception | None] @@ -253,9 +250,10 @@ def end(self) -> None: def terminate(self): """Terminate the executor is not doing anything.""" - @provide_session - def queue_workload(self, workload: workloads.All, session: Session = NEW_SESSION): - self.activity_queue.put(workload) + def _process_workloads(self, workloads): + for workload in workloads: + self.activity_queue.put(workload) + del self.queued_tasks[workload.ti.key] with self._unread_messages: - self._unread_messages.value += 1 + self._unread_messages.value += len(workloads) self._check_workers() diff --git a/airflow-core/src/airflow/jobs/scheduler_job_runner.py b/airflow-core/src/airflow/jobs/scheduler_job_runner.py index e8778d17d1814..4557445151051 100644 --- a/airflow-core/src/airflow/jobs/scheduler_job_runner.py +++ b/airflow-core/src/airflow/jobs/scheduler_job_runner.py @@ -30,7 +30,7 @@ from datetime import date, datetime, timedelta from functools import lru_cache, partial from itertools import groupby -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, Any from sqlalchemy import and_, delete, desc, exists, func, inspect, or_, select, text, tuple_, update from sqlalchemy.exc import OperationalError @@ -43,11 +43,12 @@ from airflow.callbacks.callback_requests import ( DagCallbackRequest, DagRunContext, - EmailNotificationRequest, + EmailRequest, TaskCallbackRequest, ) from airflow.configuration import conf from airflow.dag_processing.bundles.base import BundleUsageTrackingManager +from airflow.exceptions import DagNotFound from airflow.executors import workloads from airflow.jobs.base_job_runner import BaseJobRunner from airflow.jobs.job import Job, JobState, perform_heartbeat @@ -89,17 +90,16 @@ from airflow.utils.types import DagRunTriggeredByType, DagRunType if TYPE_CHECKING: - import logging from types import FrameType from pendulum.datetime import DateTime from sqlalchemy.orm import Query, Session + from airflow._shared.logging.types import Logger from airflow.executors.base_executor import BaseExecutor from airflow.executors.executor_utils import ExecutorName - from airflow.models.mappedoperator import MappedOperator from airflow.models.taskinstance import TaskInstanceKey - from airflow.serialization.serialized_objects import SerializedBaseOperator, SerializedDAG + from airflow.serialization.serialized_objects import SerializedDAG from airflow.utils.sqlalchemy import CommitProhibitorGuard TI = TaskInstance @@ -189,7 +189,7 @@ def __init__( job: Job, num_runs: int = conf.getint("scheduler", "num_runs"), scheduler_idle_sleep_time: float = conf.getfloat("scheduler", "scheduler_idle_sleep_time"), - log: logging.Logger | None = None, + log: Logger | None = None, ): super().__init__(job) self.num_runs = num_runs @@ -198,7 +198,6 @@ def __init__( self._task_instance_heartbeat_timeout_secs = conf.getint( "scheduler", "task_instance_heartbeat_timeout" ) - self._dag_stale_not_seen_duration = conf.getint("scheduler", "dag_stale_not_seen_duration") self._task_queued_timeout = conf.getfloat("scheduler", "task_queued_timeout") self._enable_tracemalloc = conf.getboolean("scheduler", "enable_tracemalloc") @@ -910,16 +909,15 @@ def process_executor_events( # Get task from the Serialized DAG try: dag = scheduler_dag_bag.get_dag_for_run(dag_run=ti.dag_run, session=session) - cls.logger().error( - "DAG '%s' for task instance %s not found in serialized_dag table", - ti.dag_id, - ti, - ) - if TYPE_CHECKING: - assert dag - # TODO (GH-52141): get_task in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - task = cast("MappedOperator | SerializedBaseOperator", dag.get_task(ti.task_id)) + if not dag: + cls.logger().error( + "DAG '%s' for task instance %s not found in serialized_dag table", + ti.dag_id, + ti, + ) + raise DagNotFound(f"DAG '{ti.dag_id}' not found in serialized_dag table") + + task = dag.get_task(ti.task_id) except Exception: cls.logger().exception("Marking task instance %s as %s", ti, state) ti.set_state(state) @@ -935,6 +933,11 @@ def process_executor_events( bundle_version=ti.dag_version.bundle_version, ti=ti, msg=msg, + task_callback_type=( + TaskInstanceState.UP_FOR_RETRY + if ti.is_eligible_to_retry() + else TaskInstanceState.FAILED + ), context_from_server=TIRunContext( dag_run=DRDataModel.model_validate(ti.dag_run, from_attributes=True), max_tries=ti.max_tries, @@ -961,7 +964,7 @@ def process_executor_events( "Sending email request for task %s to DAG Processor", ti, ) - email_request = EmailNotificationRequest( + email_request = EmailRequest( filepath=ti.dag_model.relative_fileloc, bundle_name=ti.dag_version.bundle_name, bundle_version=ti.dag_version.bundle_version, @@ -1017,6 +1020,11 @@ def set_ti_span_attrs(cls, span, state, ti): span.add_event(name="airflow.task.ended", timestamp=datetime_to_nano(ti.end_date)) def _execute(self) -> int | None: + import os + + # Mark this as a server context for secrets backend detection + os.environ["_AIRFLOW_PROCESS_CONTEXT"] = "server" + self.log.info("Starting the scheduler") reset_signals = self.register_signals() @@ -2293,6 +2301,12 @@ def adopt_or_reset_orphaned_tasks(self, session: Session = NEW_SESSION) -> int: for ti in set(tis_to_adopt_or_reset) - set(to_reset): ti.queued_by_job_id = self.job.id + # If old ti from Airflow 2 and last_heartbeat_at is None, set last_heartbeat_at to now + if ti.last_heartbeat_at is None: + ti.last_heartbeat_at = timezone.utcnow() + # If old ti from Airflow 2 and dag_run.conf is None, set dag_run.conf to {} + if ti.dag_run.conf is None: + ti.dag_run.conf = {} Stats.incr("scheduler.orphaned_tasks.cleared", len(to_reset)) Stats.incr("scheduler.orphaned_tasks.adopted", len(tis_to_adopt_or_reset) - len(to_reset)) @@ -2389,6 +2403,13 @@ def _purge_task_instances_without_heartbeats( task_instance_heartbeat_timeout_message_details = ( self._generate_task_instance_heartbeat_timeout_message_details(ti) ) + if not ti.dag_version: + # If old ti from Airflow 2 and dag_version is None, skip heartbeat timeout handling. + self.log.warning( + "DAG Version not found for TaskInstance %s. Skipping heartbeat timeout handling.", + ti, + ) + continue request = TaskCallbackRequest( filepath=ti.dag_model.relative_fileloc, bundle_name=ti.dag_version.bundle_name, diff --git a/airflow-core/src/airflow/jobs/triggerer_job_runner.py b/airflow-core/src/airflow/jobs/triggerer_job_runner.py index 63deea50f450f..f5bc2d94d0601 100644 --- a/airflow-core/src/airflow/jobs/triggerer_job_runner.py +++ b/airflow-core/src/airflow/jobs/triggerer_job_runner.py @@ -27,7 +27,6 @@ from collections import deque from collections.abc import Generator, Iterable from contextlib import suppress -from datetime import datetime from socket import socket from traceback import format_exception from typing import TYPE_CHECKING, Annotated, Any, ClassVar, Literal, TypedDict @@ -697,7 +696,7 @@ def _process_log_messages_from_subprocess(self) -> Generator[None, bytes | bytea from airflow.sdk.log import logging_processors - processors, _ = logging_processors(enable_pretty_log=False) + processors = logging_processors(json_output=True) def get_logger(trigger_id: int) -> WrappedLogger: # TODO: Is a separate dict worth it, or should we make `self.running_triggers` a dict? @@ -723,16 +722,6 @@ def get_logger(trigger_id: int) -> WrappedLogger: # Log message about the TriggerRunner itself -- just output it log = fallback_log - if ts := event.get("timestamp"): - # We use msgspec to decode the timestamp as it does it orders of magnitude quicker than - # datetime.strptime - # - # We remove the timezone info here, as the json encoding has `+00:00`, and since the log came - # from a subprocess we know that the timezone of the log message is the same, so having some - # messages include tz (from subprocess) but others not (ones from supervisor process) is - # confusing. - event["timestamp"] = msgspec.json.decode(f'"{ts}"', type=datetime).replace(tzinfo=None) - if exc := event.pop("exception", None): # TODO: convert the dict back to a pretty stack trace event["error_detail"] = exc @@ -774,7 +763,10 @@ def send(self, msg: ToTriggerSupervisor) -> ToTriggerRunner | None: return async_to_sync(self.asend)(msg) async def _aread_frame(self): - len_bytes = await self._async_reader.readexactly(4) + try: + len_bytes = await self._async_reader.readexactly(4) + except ConnectionResetError: + asyncio.current_task().cancel("Supervisor closed") length = int.from_bytes(len_bytes, byteorder="big") if length >= 2**32: raise OverflowError(f"Refusing to receive messages larger than 4GiB {length=}") @@ -878,8 +870,10 @@ async def arun(self): await asyncio.sleep(1) # Every minute, log status if (now := time.monotonic()) - last_status >= 60: - count = len(self.triggers) - self.log.info("%i triggers currently running", count) + watchers = len([trigger for trigger in self.triggers.values() if trigger["is_watcher"]]) + triggers = len(self.triggers) - watchers + self.log.info("%i triggers currently running", triggers) + self.log.info("%i watchers currently running", watchers) last_status = now except Exception: @@ -964,6 +958,7 @@ async def create_triggers(self): "task": asyncio.create_task( self.run_trigger(trigger_id, trigger_instance), name=trigger_name ), + "is_watcher": isinstance(trigger_instance, events.BaseEventTrigger), "name": trigger_name, "events": 0, } @@ -1098,6 +1093,11 @@ async def block_watchdog(self): async def run_trigger(self, trigger_id, trigger): """Run a trigger (they are async generators) and push their events into our outbound event deque.""" + if not os.environ.get("AIRFLOW_DISABLE_GREENBACK_PORTAL", "").lower() == "true": + import greenback + + await greenback.ensure_portal() + bind_log_contextvars(trigger_id=trigger_id) name = self.triggers[trigger_id]["name"] diff --git a/airflow-core/src/airflow/logging_config.py b/airflow-core/src/airflow/logging_config.py index a391c1c6361a8..0875ac9be9092 100644 --- a/airflow-core/src/airflow/logging_config.py +++ b/airflow-core/src/airflow/logging_config.py @@ -20,7 +20,6 @@ import logging import warnings from importlib import import_module -from logging.config import dictConfig from typing import TYPE_CHECKING, Any from airflow.configuration import conf @@ -86,33 +85,56 @@ def load_logging_config() -> tuple[dict[str, Any], str]: def configure_logging(): + from airflow._shared.logging import configure_logging, init_log_folder, translate_config_values + logging_config, logging_class_path = load_logging_config() try: - # Ensure that the password masking filter is applied to the 'task' handler - # no matter what the user did. - if "filters" in logging_config and "mask_secrets" in logging_config["filters"]: - # But if they replace the logging config _entirely_, don't try to set this, it won't work - task_handler_config = logging_config["handlers"]["task"] - - task_handler_config.setdefault("filters", []) - - if "mask_secrets" not in task_handler_config["filters"]: - task_handler_config["filters"].append("mask_secrets") - + level: str = getattr( + logging_config, "LOG_LEVEL", conf.get("logging", "logging_level", fallback="INFO") + ).upper() + + colors = getattr( + logging_config, + "COLORED_LOG", + conf.getboolean("logging", "colored_console_log", fallback=True), + ) # Try to init logging - dictConfig(logging_config) + + log_fmt, callsite_params = translate_config_values( + log_format=getattr(logging_config, "LOG_FORMAT", conf.get("logging", "log_format", fallback="")), + callsite_params=conf.getlist("logging", "callsite_parameters", fallback=[]), + ) + configure_logging( + log_level=level, + stdlib_config=logging_config, + log_format=log_fmt, + callsite_parameters=callsite_params, + colors=colors, + ) except (ValueError, KeyError) as e: log.error("Unable to load the config, contains a configuration error.") # When there is an error in the config, escalate the exception # otherwise Airflow would silently fall back on the default config raise e - validate_logging_config(logging_config) + validate_logging_config() + + new_folder_permissions = int( + conf.get("logging", "file_task_handler_new_folder_permissions", fallback="0o775"), + 8, + ) + + base_log_folder = conf.get("logging", "base_log_folder") + + return init_log_folder( + base_log_folder, + new_folder_permissions=new_folder_permissions, + ) return logging_class_path -def validate_logging_config(logging_config): +def validate_logging_config(): """Validate the provided Logging Config.""" # Now lets validate the other logging-related settings task_log_reader = conf.get("logging", "task_log_reader") diff --git a/airflow-core/src/airflow/migrations/versions/0041_3_0_0_rename_dataset_as_asset.py b/airflow-core/src/airflow/migrations/versions/0041_3_0_0_rename_dataset_as_asset.py index 4d00f66c490e8..abe776f082bc0 100644 --- a/airflow-core/src/airflow/migrations/versions/0041_3_0_0_rename_dataset_as_asset.py +++ b/airflow-core/src/airflow/migrations/versions/0041_3_0_0_rename_dataset_as_asset.py @@ -31,6 +31,7 @@ import sqlalchemy as sa import sqlalchemy_jsonfield from alembic import op +from sqlalchemy import text from airflow.migrations.utils import mysql_drop_foreignkey_if_exists from airflow.settings import json @@ -101,14 +102,19 @@ def _rename_pk_constraint( def _drop_fkey_if_exists(table, constraint_name): - dialect = op.get_bind().dialect.name - if dialect == "sqlite": + conn = op.get_bind() + dialect_name = conn.dialect.name + + if dialect_name == "sqlite": + # SQLite requires foreign key constraints to be disabled during batch operations + conn.execute(text("PRAGMA foreign_keys=OFF")) try: with op.batch_alter_table(table, schema=None) as batch_op: batch_op.drop_constraint(op.f(constraint_name), type_="foreignkey") except ValueError: pass - elif dialect == "mysql": + conn.execute(text("PRAGMA foreign_keys=ON")) + elif dialect_name == "mysql": mysql_drop_foreignkey_if_exists(constraint_name, table, op) else: op.execute(f"ALTER TABLE {table} DROP CONSTRAINT IF EXISTS {constraint_name}") diff --git a/airflow-core/src/airflow/migrations/versions/0076_3_1_0_add_human_in_the_loop_response.py b/airflow-core/src/airflow/migrations/versions/0076_3_1_0_add_human_in_the_loop_response.py index 3e0ede0183ee1..3105d453e457e 100644 --- a/airflow-core/src/airflow/migrations/versions/0076_3_1_0_add_human_in_the_loop_response.py +++ b/airflow-core/src/airflow/migrations/versions/0076_3_1_0_add_human_in_the_loop_response.py @@ -32,6 +32,7 @@ from sqlalchemy import Boolean, Column, ForeignKeyConstraint, String, Text from sqlalchemy.dialects import postgresql +from airflow._shared.timezones import timezone from airflow.settings import json from airflow.utils.sqlalchemy import UtcDateTime @@ -59,10 +60,10 @@ def upgrade(): Column("defaults", sqlalchemy_jsonfield.JSONField(json=json), nullable=True), Column("multiple", Boolean, unique=False, default=False), Column("params", sqlalchemy_jsonfield.JSONField(json=json), nullable=False, default={}), - Column("respondents", sqlalchemy_jsonfield.JSONField(json=json), nullable=True), - Column("response_at", UtcDateTime, nullable=True), - Column("responded_user_id", String(128), nullable=True), - Column("responded_user_name", String(128), nullable=True), + Column("assignees", sqlalchemy_jsonfield.JSONField(json=json), nullable=True), + Column("created_at", UtcDateTime(timezone=True), nullable=False, default=timezone.utcnow), + Column("responded_at", UtcDateTime, nullable=True), + Column("responded_by", sqlalchemy_jsonfield.JSONField(json=json), nullable=True), Column("chosen_options", sqlalchemy_jsonfield.JSONField(json=json), nullable=True), Column("params_input", sqlalchemy_jsonfield.JSONField(json=json), nullable=False, default={}), ForeignKeyConstraint( diff --git a/airflow-core/src/airflow/migrations/versions/0084_3_1_0_add_last_parse_duration_to_dag_model.py b/airflow-core/src/airflow/migrations/versions/0084_3_1_0_add_last_parse_duration_to_dag_model.py index 2fd90d631e841..1a922d97deed5 100644 --- a/airflow-core/src/airflow/migrations/versions/0084_3_1_0_add_last_parse_duration_to_dag_model.py +++ b/airflow-core/src/airflow/migrations/versions/0084_3_1_0_add_last_parse_duration_to_dag_model.py @@ -29,6 +29,7 @@ import sqlalchemy as sa from alembic import op +from sqlalchemy import text # revision identifiers, used by Alembic. revision = "eaf332f43c7c" @@ -46,5 +47,15 @@ def upgrade(): def downgrade(): """Unapply add last_parse_duration to dag model.""" - with op.batch_alter_table("dag", schema=None) as batch_op: - batch_op.drop_column("last_parse_duration") + conn = op.get_bind() + dialect_name = conn.dialect.name + + if dialect_name == "sqlite": + # SQLite requires foreign key constraints to be disabled during batch operations + conn.execute(text("PRAGMA foreign_keys=OFF")) + with op.batch_alter_table("dag", schema=None) as batch_op: + batch_op.drop_column("last_parse_duration") + conn.execute(text("PRAGMA foreign_keys=ON")) + else: + with op.batch_alter_table("dag", schema=None) as batch_op: + batch_op.drop_column("last_parse_duration") diff --git a/airflow-core/src/airflow/migrations/versions/0085_3_1_0_downgrade_serialized_dag_version_to_v2.py b/airflow-core/src/airflow/migrations/versions/0085_3_1_0_downgrade_serialized_dag_version_to_v2.py new file mode 100644 index 0000000000000..3a5045dda5096 --- /dev/null +++ b/airflow-core/src/airflow/migrations/versions/0085_3_1_0_downgrade_serialized_dag_version_to_v2.py @@ -0,0 +1,199 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +Add backward compatibility for serialized DAG format v3 to v2. + +Revision ID: cc92b33c6709 +Revises: eaf332f43c7c +Create Date: 2025-09-22 22:50:48.035121 + +""" + +from __future__ import annotations + +from textwrap import dedent + +import sqlalchemy as sa +from alembic import context, op + +# revision identifiers, used by Alembic. +revision = "cc92b33c6709" +down_revision = "eaf332f43c7c" +branch_labels = None +depends_on = None +airflow_version = "3.1.0" + + +def upgrade(): + """Apply Downgrade Serialized Dag version to v2.""" + # No-op: Server handles v1/v2/v3 DAGs at runtime via conversion functions + pass + + +def downgrade(): + """Convert v3 serialized DAGs back to v2 format for compatibility with older Airflow versions.""" + if context.is_offline_mode(): + print( + dedent(""" + ------------ + -- Manual v3 to v2 DAG conversion required (offline mode) + -- + -- PostgreSQL: + -- UPDATE serialized_dag SET data = jsonb_set((data::jsonb - 'client_defaults'), '{__version}', '2')::json + -- WHERE id IN (SELECT id FROM serialized_dag WHERE data->>'__version' = '3' AND data_compressed IS NULL); + -- + -- MySQL/SQLite: + -- UPDATE serialized_dag SET data = JSON_SET(JSON_REMOVE(data, '$.client_defaults'), '$.__version', 2) + -- WHERE JSON_EXTRACT(data, '$.__version') = '3' AND data_compressed IS NULL; + -- + -- For compressed DAGs: run online migration. + ------------ + """) + ) + return + + import gzip + import json + + connection = op.get_bind() + dialect = connection.dialect.name + + if dialect == "postgresql": + # PostgreSQL - pre-filter v3 DAGs to avoid parsing all rows + connection.execute( + sa.text(""" + UPDATE serialized_dag + SET data = jsonb_set( + (data::jsonb - 'client_defaults'), + '{__version}', + '2' + )::json + WHERE id IN ( + SELECT id FROM serialized_dag + WHERE data->>'__version' = '3' + AND data_compressed IS NULL + ) + """) + ) + elif dialect == "mysql": + connection.execute( + sa.text(""" + UPDATE serialized_dag + SET data = JSON_SET( + JSON_REMOVE(data, '$.client_defaults'), + '$.__version', + 2 + ) + WHERE JSON_EXTRACT(data, '$.__version') = '3' + AND data_compressed IS NULL + """) + ) + else: + json_functions_available = False + try: + connection.execute(sa.text("SELECT JSON_SET('{}', '$.test', 'value')")).fetchone() + json_functions_available = True + print("SQLite JSON functions detected, using optimized SQL approach") + except Exception: + print("SQLite JSON functions not available, using Python fallback for JSON processing") + + if json_functions_available: + connection.execute( + sa.text(""" + UPDATE serialized_dag + SET data = JSON_SET( + JSON_REMOVE(data, '$.client_defaults'), + '$.__version', + 2 + ) + WHERE JSON_EXTRACT(data, '$.__version') = '3' + AND data_compressed IS NULL + """) + ) + else: + result = connection.execute( + sa.text(""" + SELECT id, data + FROM serialized_dag + WHERE data_compressed IS NULL + """) + ) + + for row in result: + dag_id, data_json = row + try: + if data_json is None: + continue + + dag_data = json.loads(data_json) + + if dag_data.get("__version") != 3: + continue + + if "client_defaults" in dag_data: + del dag_data["client_defaults"] + dag_data["__version"] = 2 + + new_json = json.dumps(dag_data) + connection.execute( + sa.text("UPDATE serialized_dag SET data = :data WHERE id = :id"), + {"data": new_json, "id": dag_id}, + ) + + except Exception as e: + print(f"Failed to downgrade uncompressed DAG {dag_id}: {e}") + continue + try: + result = connection.execute( + sa.text(""" + SELECT id, data_compressed + FROM serialized_dag + WHERE data_compressed IS NOT NULL + """) + ) + + for row in result: + dag_id, compressed_data = row + try: + if compressed_data is None: + continue + + decompressed = gzip.decompress(compressed_data) + dag_data = json.loads(decompressed) + + if dag_data.get("__version") != 3: + continue + + if "client_defaults" in dag_data: + del dag_data["client_defaults"] + dag_data["__version"] = 2 + + new_compressed = gzip.compress(json.dumps(dag_data).encode("utf-8")) + connection.execute( + sa.text("UPDATE serialized_dag SET data_compressed = :data WHERE id = :id"), + {"data": new_compressed, "id": dag_id}, + ) + + except Exception as e: + print(f"Failed to downgrade compressed DAG {dag_id}: {e}") + continue + + except Exception as e: + print(f"Failed to process compressed DAGs during downgrade: {e}") + raise diff --git a/airflow-core/src/airflow/models/dag.py b/airflow-core/src/airflow/models/dag.py index 316eaf3617313..4f6f22b2f8046 100644 --- a/airflow-core/src/airflow/models/dag.py +++ b/airflow-core/src/airflow/models/dag.py @@ -452,12 +452,25 @@ def next_dagrun_data_interval(self, value: tuple[datetime, datetime] | None) -> @property def deadline(self): """Get the deserialized deadline alert.""" - return DeadlineAlert.deserialize_deadline_alert(self._deadline) if self._deadline else None + if self._deadline is None: + return None + if isinstance(self._deadline, list): + return [DeadlineAlert.deserialize_deadline_alert(item) for item in self._deadline] + return DeadlineAlert.deserialize_deadline_alert(self._deadline) @deadline.setter def deadline(self, value): """Set and serialize the deadline alert.""" - self._deadline = value if isinstance(value, dict) else value.serialize_deadline_alert() + if value is None: + self._deadline = None + elif isinstance(value, list): + self._deadline = [ + item if isinstance(item, dict) else item.serialize_deadline_alert() for item in value + ] + elif isinstance(value, dict): + self._deadline = value + else: + self._deadline = value.serialize_deadline_alert() @property def timezone(self): diff --git a/airflow-core/src/airflow/models/dagrun.py b/airflow-core/src/airflow/models/dagrun.py index 26d1d42e524df..562fdc5e9fc82 100644 --- a/airflow-core/src/airflow/models/dagrun.py +++ b/airflow-core/src/airflow/models/dagrun.py @@ -1173,7 +1173,7 @@ def recalculate(self) -> _UnfinishedStates: self.notify_dagrun_state_changed(msg="task_failure") if execute_callbacks and dag.has_on_failure_callback: - self.handle_dag_callback(dag=dag, success=False, reason="task_failure") + self.handle_dag_callback(dag=cast("SDKDAG", dag), success=False, reason="task_failure") elif dag.has_on_failure_callback: callback = DagCallbackRequest( filepath=self.dag_model.relative_fileloc, @@ -1206,7 +1206,7 @@ def recalculate(self) -> _UnfinishedStates: self.notify_dagrun_state_changed(msg="success") if execute_callbacks and dag.has_on_success_callback: - self.handle_dag_callback(dag=dag, success=True, reason="success") + self.handle_dag_callback(dag=cast("SDKDAG", dag), success=True, reason="success") elif dag.has_on_success_callback: callback = DagCallbackRequest( filepath=self.dag_model.relative_fileloc, @@ -1222,9 +1222,13 @@ def recalculate(self) -> _UnfinishedStates: msg="success", ) - if (deadline := dag.deadline) and isinstance(deadline.reference, DeadlineReference.TYPES.DAGRUN): - # The dagrun has succeeded. If there wre any Deadlines for it which were not breached, they are no longer needed. - Deadline.prune_deadlines(session=session, conditions={DagRun.run_id: self.run_id}) + if dag.deadline: + # The dagrun has succeeded. If there were any Deadlines for it which were not breached, they are no longer needed. + if any( + isinstance(d.reference, DeadlineReference.TYPES.DAGRUN) + for d in cast("list", dag.deadline) + ): + Deadline.prune_deadlines(session=session, conditions={DagRun.run_id: self.run_id}) # if *all tasks* are deadlocked, the run failed elif unfinished.should_schedule and not are_runnable_tasks: @@ -1233,7 +1237,11 @@ def recalculate(self) -> _UnfinishedStates: self.notify_dagrun_state_changed(msg="all_tasks_deadlocked") if execute_callbacks and dag.has_on_failure_callback: - self.handle_dag_callback(dag=dag, success=False, reason="all_tasks_deadlocked") + self.handle_dag_callback( + dag=cast("SDKDAG", dag), + success=False, + reason="all_tasks_deadlocked", + ) elif dag.has_on_failure_callback: callback = DagCallbackRequest( filepath=self.dag_model.relative_fileloc, @@ -1302,9 +1310,7 @@ def _filter_tis_and_exclude_removed(dag: SerializedDAG, tis: list[TI]) -> Iterab """Populate ``ti.task`` while excluding those missing one, marking them as REMOVED.""" for ti in tis: try: - # TODO (GH-52141): get_task in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - ti.task = cast("Operator", dag.get_task(ti.task_id)) + ti.task = dag.get_task(ti.task_id) except TaskNotFound: if ti.state != TaskInstanceState.REMOVED: self.log.error("Failed to get task for ti %s. Marking it as removed.", ti) @@ -1535,7 +1541,12 @@ def _expand_mapped_task_if_needed(ti: TI) -> Iterable[TI] | None: ) ) revised_map_index_task_ids.add(schedulable.task.task_id) - ready_tis.append(schedulable) + + # _revise_map_indexes_if_mapped might mark the current task as REMOVED + # after calculating mapped task length, so we need to re-check + # the task state to ensure it's still schedulable + if schedulable.state in SCHEDULEABLE_STATES: + ready_tis.append(schedulable) # Check if any ti changed state tis_filter = TI.filter_for_tis(old_states) diff --git a/airflow-core/src/airflow/models/hitl.py b/airflow-core/src/airflow/models/hitl.py index 448939e2c6f61..b6bbb2bc402b0 100644 --- a/airflow-core/src/airflow/models/hitl.py +++ b/airflow-core/src/airflow/models/hitl.py @@ -16,16 +16,69 @@ # under the License. from __future__ import annotations +from typing import TYPE_CHECKING, Any, TypedDict + import sqlalchemy_jsonfield -from sqlalchemy import Boolean, Column, ForeignKeyConstraint, String, Text +from sqlalchemy import Boolean, Column, ForeignKeyConstraint, String, Text, func, literal from sqlalchemy.dialects import postgresql +from sqlalchemy.ext.compiler import compiles from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import relationship +from sqlalchemy.sql.functions import FunctionElement +from airflow._shared.timezones import timezone from airflow.models.base import Base from airflow.settings import json from airflow.utils.sqlalchemy import UtcDateTime +if TYPE_CHECKING: + from sqlalchemy.sql import ColumnElement + from sqlalchemy.sql.compiler import SQLCompiler + + +class JSONExtract(FunctionElement): + """ + Cross-dialect JSON key extractor. + + :meta: private + """ + + type = String() + inherit_cache = True + + def __init__(self, column: ColumnElement[Any], key: str, **kwargs: dict[str, Any]) -> None: + super().__init__(column, literal(key), **kwargs) + + +@compiles(JSONExtract, "postgresql") +def compile_postgres(element: JSONExtract, compiler: SQLCompiler, **kwargs: dict[str, Any]) -> str: + """ + Compile JSONExtract for PostgreSQL. + + :meta: private + """ + column, key = element.clauses + return compiler.process(func.json_extract_path_text(column, key), **kwargs) + + +@compiles(JSONExtract, "sqlite") +@compiles(JSONExtract, "mysql") +def compile_sqlite_mysql(element: JSONExtract, compiler: SQLCompiler, **kwargs: dict[str, Any]) -> str: + """ + Compile JSONExtract for SQLite/MySQL. + + :meta: private + """ + column, key = element.clauses + return compiler.process(func.json_extract(column, f"$.{key.value}"), **kwargs) + + +class HITLUser(TypedDict): + """Typed dict for saving a Human-in-the-loop user information.""" + + id: str + name: str + class HITLDetail(Base): """Human-in-the-loop request and corresponding response.""" @@ -44,12 +97,12 @@ class HITLDetail(Base): defaults = Column(sqlalchemy_jsonfield.JSONField(json=json), nullable=True) multiple = Column(Boolean, unique=False, default=False) params = Column(sqlalchemy_jsonfield.JSONField(json=json), nullable=False, default={}) - respondents = Column(sqlalchemy_jsonfield.JSONField(json=json), nullable=True) + assignees = Column(sqlalchemy_jsonfield.JSONField(json=json), nullable=True) + created_at = Column(UtcDateTime, default=timezone.utcnow, nullable=False) # Response Content Detail - response_at = Column(UtcDateTime, nullable=True) - responded_user_id = Column(String(128), nullable=True) - responded_user_name = Column(String(128), nullable=True) + responded_at = Column(UtcDateTime, nullable=True) + responded_by = Column(sqlalchemy_jsonfield.JSONField(json=json), nullable=True) chosen_options = Column( sqlalchemy_jsonfield.JSONField(json=json), nullable=True, @@ -74,10 +127,45 @@ class HITLDetail(Base): @hybrid_property def response_received(self) -> bool: - return self.response_at is not None + return self.responded_at is not None @response_received.expression # type: ignore[no-redef] def response_received(cls): - return cls.response_at.is_not(None) + return cls.responded_at.is_not(None) + + @hybrid_property + def responded_by_user_id(self) -> str | None: + return self.responded_by["id"] if self.responded_by else None + + @responded_by_user_id.expression # type: ignore[no-redef] + def responded_by_user_id(cls): + return JSONExtract(cls.responded_by, "id") - DEFAULT_USER_NAME = "Fallback to defaults" + @hybrid_property + def responded_by_user_name(self) -> str | None: + return self.responded_by["name"] if self.responded_by else None + + @responded_by_user_name.expression # type: ignore[no-redef] + def responded_by_user_name(cls): + return JSONExtract(cls.responded_by, "name") + + @hybrid_property + def assigned_users(self) -> list[HITLUser]: + if not self.assignees: + return [] + return [ + HITLUser( + id=assignee["id"], + name=assignee["name"], + ) + for assignee in self.assignees + ] + + @hybrid_property + def responded_by_user(self) -> HITLUser | None: + if self.responded_by is None: + return None + return HITLUser( + id=self.responded_by["id"], + name=self.responded_by["name"], + ) diff --git a/airflow-core/src/airflow/models/mappedoperator.py b/airflow-core/src/airflow/models/mappedoperator.py index 7c7988d3c9bd3..9e7a294e5b52c 100644 --- a/airflow-core/src/airflow/models/mappedoperator.py +++ b/airflow-core/src/airflow/models/mappedoperator.py @@ -114,6 +114,10 @@ class MappedOperator(DAGNode): dag: SerializedDAG = attrs.field(init=False) # type: ignore[assignment] task_group: SerializedTaskGroup = attrs.field(init=False) # type: ignore[assignment] + doc: str | None = attrs.field(init=False) + doc_json: str | None = attrs.field(init=False) + doc_rst: str | None = attrs.field(init=False) + doc_yaml: str | None = attrs.field(init=False) start_date: pendulum.DateTime | None = attrs.field(init=False, default=None) end_date: pendulum.DateTime | None = attrs.field(init=False, default=None) upstream_task_ids: set[str] = attrs.field(factory=set, init=False) @@ -136,6 +140,9 @@ class MappedOperator(DAGNode): is_mapped: ClassVar[bool] = True + def __repr__(self) -> str: + return f"" + @property def node_id(self) -> str: return self.task_id @@ -267,12 +274,16 @@ def priority_weight(self) -> int: @property def retry_delay(self) -> datetime.timedelta: - return self.partial_kwargs["retry_delay"] + return self.partial_kwargs.get("retry_delay", SerializedBaseOperator.retry_delay) @property def retry_exponential_backoff(self) -> bool: return bool(self.partial_kwargs.get("retry_exponential_backoff")) + @property + def max_retry_delay(self) -> datetime.timedelta | None: + return self.partial_kwargs.get("max_retry_delay") + @property def weight_rule(self) -> PriorityWeightStrategy: return validate_and_load_priority_weight_strategy( diff --git a/airflow-core/src/airflow/models/taskinstance.py b/airflow-core/src/airflow/models/taskinstance.py index 4d440bd38a042..e9806696e243b 100644 --- a/airflow-core/src/airflow/models/taskinstance.py +++ b/airflow-core/src/airflow/models/taskinstance.py @@ -27,7 +27,7 @@ from collections.abc import Collection, Iterable from datetime import timedelta from functools import cache -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, Any from urllib.parse import quote import attrs @@ -70,9 +70,6 @@ from airflow._shared.timezones import timezone from airflow.assets.manager import asset_manager from airflow.configuration import conf -from airflow.exceptions import ( - AirflowInactiveAssetInInletOrOutletException, -) from airflow.listeners.listener import get_listener_manager from airflow.models.asset import AssetEvent, AssetModel from airflow.models.base import Base, StringID, TaskInstanceDependencies @@ -120,7 +117,7 @@ from airflow.models.mappedoperator import MappedOperator from airflow.sdk import DAG from airflow.sdk.api.datamodels._generated import AssetProfile - from airflow.sdk.definitions.asset import AssetNameRef, AssetUniqueKey, AssetUriRef + from airflow.sdk.definitions.asset import AssetUniqueKey from airflow.sdk.types import RuntimeTaskInstanceProtocol from airflow.serialization.definitions.taskgroup import SerializedTaskGroup from airflow.serialization.serialized_objects import SerializedBaseOperator @@ -237,8 +234,7 @@ def clear_task_instances( log.warning("No serialized dag found for dag '%s'", dr.dag_id) task_id = ti.task_id if ti_dag and ti_dag.has_task(task_id): - # TODO (GH-52141): Make dag a db-backed object so it only returns db-backed tasks. - task = cast("Operator", ti_dag.get_task(task_id)) + task = ti_dag.get_task(task_id) ti.refresh_from_task(task) if TYPE_CHECKING: assert ti.task @@ -623,7 +619,7 @@ def log_url(self) -> str: base_url = conf.get("api", "base_url", fallback="http://localhost:8080/") map_index = f"/mapped/{self.map_index}" if self.map_index >= 0 else "" try_number = f"?try_number={self.try_number}" if self.try_number > 0 else "" - _log_uri = f"{base_url}dags/{self.dag_id}/runs/{run_id}/tasks/{self.task_id}{map_index}{try_number}" + _log_uri = f"{base_url.rstrip('/')}/dags/{self.dag_id}/runs/{run_id}/tasks/{self.task_id}{map_index}{try_number}" return _log_uri @@ -1076,8 +1072,6 @@ def _check_and_change_state_before_execution( ti: TaskInstance = task_instance task = task_instance.task - if TYPE_CHECKING: - assert isinstance(task, Operator) # TODO (GH-52141): This shouldn't be needed. ti.refresh_from_task(task, pool_override=pool) ti.test_mode = test_mode ti.refresh_from_db(session=session, lock_for_update=True) @@ -1277,9 +1271,16 @@ def _run_raw_task( log.info("[DAG TEST] Marking success for %s ", self.task_id) return None - taskrun_result = _run_task(ti=self, task=self.task) - if taskrun_result is not None and taskrun_result.error: + # TODO (TaskSDK): This is the old ti execution path. The only usage is + # in TI.run(...), someone needs to analyse if it's still actually used + # somewhere and fix it, likely by rewriting TI.run(...) to use the same + # mechanism as Operator.test(). + taskrun_result = _run_task(ti=self, task=self.task) # type: ignore[arg-type] + if taskrun_result is None: + return None + if taskrun_result.error: raise taskrun_result.error + self.task = taskrun_result.ti.task # type: ignore[assignment] return None @staticmethod @@ -1324,13 +1325,15 @@ def register_asset_changes_in_db( if "source_alias_name" not in event } - bad_asset_keys: set[AssetUniqueKey | AssetNameRef | AssetUriRef] = set() - for key in asset_keys: try: am = asset_models[key] except KeyError: - bad_asset_keys.add(key) + ti.log.warning( + 'Task has inactive assets "Asset(name=%s, uri=%s)" in inlets or outlets', + key.name, + key.uri, + ) continue ti.log.debug("register event for asset %s", am) asset_manager.register_asset_change( @@ -1347,7 +1350,9 @@ def register_asset_changes_in_db( try: am = asset_models_by_name[nref.name] except KeyError: - bad_asset_keys.add(nref) + ti.log.warning( + 'Task has inactive assets "Asset.ref(name=%s)" in inlets or outlets', nref.name + ) continue ti.log.debug("register event for asset name ref %s", am) asset_manager.register_asset_change( @@ -1363,7 +1368,9 @@ def register_asset_changes_in_db( try: am = asset_models_by_uri[uref.uri] except KeyError: - bad_asset_keys.add(uref) + ti.log.warning( + 'Task has inactive assets "Asset.ref(uri=%s)" in inlets or outlets', uref.uri + ) continue ti.log.debug("register event for asset uri ref %s", am) asset_manager.register_asset_change( @@ -1410,9 +1417,6 @@ def _asset_event_extras_from_aliases() -> dict[tuple[AssetUniqueKey, frozenset], session=session, ) - if bad_asset_keys: - raise AirflowInactiveAssetInInletOrOutletException(bad_asset_keys) - @provide_session def update_rtif(self, rendered_fields, session: Session = NEW_SESSION): from airflow.models.renderedtifields import RenderedTaskInstanceFields @@ -1455,9 +1459,11 @@ def run( assert original_task is not None assert original_task.dag is not None - self.task = SerializedDAG.deserialize_dag(SerializedDAG.serialize_dag(original_task.dag)).task_dict[ - original_task.task_id - ] + # We don't set up all tests well... + if not isinstance(original_task.dag, SerializedDAG): + serialized_dag = SerializedDAG.deserialize_dag(SerializedDAG.serialize_dag(original_task.dag)) + self.task = serialized_dag.get_task(original_task.task_id) + res = self.check_and_change_state_before_execution( verbose=verbose, ignore_all_deps=ignore_all_deps, diff --git a/airflow-core/src/airflow/models/xcom_arg.py b/airflow-core/src/airflow/models/xcom_arg.py index 75cccba50334d..bc9326b2b2f52 100644 --- a/airflow-core/src/airflow/models/xcom_arg.py +++ b/airflow-core/src/airflow/models/xcom_arg.py @@ -19,7 +19,7 @@ from collections.abc import Iterator, Sequence from functools import singledispatch -from typing import TYPE_CHECKING, Any, TypeAlias, cast +from typing import TYPE_CHECKING, Any, TypeAlias import attrs from sqlalchemy import func, or_, select @@ -92,8 +92,7 @@ class SchedulerPlainXComArg(SchedulerXComArg): @classmethod def _deserialize(cls, data: dict[str, Any], dag: SerializedDAG) -> Self: - # TODO (GH-52141): SerializedDAG should return scheduler operator instead. - return cls(cast("Operator", dag.get_task(data["task_id"])), data["key"]) + return cls(dag.get_task(data["task_id"]), data["key"]) def iter_references(self) -> Iterator[tuple[Operator, str]]: yield self.operator, self.key diff --git a/airflow-core/src/airflow/secrets/__init__.py b/airflow-core/src/airflow/secrets/__init__.py index 5ff034b247ec1..63de92c4f3f63 100644 --- a/airflow-core/src/airflow/secrets/__init__.py +++ b/airflow-core/src/airflow/secrets/__init__.py @@ -29,7 +29,7 @@ from airflow.utils.deprecation_tools import add_deprecated_classes -__all__ = ["BaseSecretsBackend", "DEFAULT_SECRETS_SEARCH_PATH", "DEFAULT_SECRETS_SEARCH_PATH_WORKERS"] +__all__ = ["BaseSecretsBackend", "DEFAULT_SECRETS_SEARCH_PATH"] from airflow.secrets.base_secrets import BaseSecretsBackend @@ -38,10 +38,6 @@ "airflow.secrets.metastore.MetastoreBackend", ] -DEFAULT_SECRETS_SEARCH_PATH_WORKERS = [ - "airflow.secrets.environment_variables.EnvironmentVariablesBackend", -] - __deprecated_classes = { "cache": { @@ -49,3 +45,26 @@ }, } add_deprecated_classes(__deprecated_classes, __name__) + + +def __getattr__(name): + if name == "DEFAULT_SECRETS_SEARCH_PATH_WORKERS": + import warnings + + warnings.warn( + "airflow.secrets.DEFAULT_SECRETS_SEARCH_PATH_WORKERS is moved to the Task SDK. " + "Use airflow.sdk.execution_time.secrets.DEFAULT_SECRETS_SEARCH_PATH_WORKERS instead.", + DeprecationWarning, + stacklevel=2, + ) + try: + from airflow.sdk.execution_time.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS + + return DEFAULT_SECRETS_SEARCH_PATH_WORKERS + except (ImportError, AttributeError): + # Back-compat for older Task SDK clients + return [ + "airflow.secrets.environment_variables.EnvironmentVariablesBackend", + ] + + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") diff --git a/airflow-core/src/airflow/serialization/definitions/taskgroup.py b/airflow-core/src/airflow/serialization/definitions/taskgroup.py index e26c6cfb4aeea..6c0add8cdfb92 100644 --- a/airflow-core/src/airflow/serialization/definitions/taskgroup.py +++ b/airflow-core/src/airflow/serialization/definitions/taskgroup.py @@ -45,7 +45,8 @@ class SerializedTaskGroup(DAGNode): group_display_name: str | None = attrs.field() prefix_group_id: bool = attrs.field() parent_group: SerializedTaskGroup | None = attrs.field() - dag: SerializedDAG = attrs.field() + # TODO (GH-52141): Replace DAGNode dependency. + dag: SerializedDAG = attrs.field() # type: ignore[assignment] tooltip: str = attrs.field() default_args: dict[str, Any] = attrs.field(factory=dict) @@ -61,6 +62,9 @@ class SerializedTaskGroup(DAGNode): is_mapped: ClassVar[bool] = False + def __repr__(self) -> str: + return f"" + @staticmethod def _iter_child(child): """Iterate over the children of this TaskGroup.""" @@ -234,6 +238,10 @@ def topological_sort(self) -> list[DAGNode]: if tg.node_id in graph_unsorted: break tg = tg.parent_group + + if tg: + # We are already going to visit that TG + break else: del graph_unsorted[node.node_id] graph_sorted.append(node) @@ -257,6 +265,9 @@ class SerializedMappedTaskGroup(SerializedTaskGroup): is_mapped: ClassVar[bool] = True + def __repr__(self) -> str: + return f"" + @methodtools.lru_cache(maxsize=None) def get_parse_time_mapped_ti_count(self) -> int: """ diff --git a/airflow-core/src/airflow/serialization/schema.json b/airflow-core/src/airflow/serialization/schema.json index 0ce253e2262c2..d79c7477297e6 100644 --- a/airflow-core/src/airflow/serialization/schema.json +++ b/airflow-core/src/airflow/serialization/schema.json @@ -175,8 +175,8 @@ "value": { "$ref": "#/definitions/dict" } } }, - "catchup": { "type": "boolean" }, - "fail_fast": { "type": "boolean" }, + "catchup": { "type": "boolean", "default": false }, + "fail_fast": { "type": "boolean", "default": false }, "fileloc": { "type" : "string"}, "relative_fileloc": { "type" : "string"}, "_processor_dags_folder": { @@ -190,13 +190,17 @@ "deadline": { "anyOf": [ { "$ref": "#/definitions/dict" }, + { + "type": "array", + "items": { "$ref": "#/definitions/dict" } + }, { "type": "null" } ] }, "_concurrency": { "type" : "number"}, - "max_active_tasks": { "type" : "number"}, - "max_active_runs": { "type" : "number"}, - "max_consecutive_failed_dag_runs": { "type" : "number"}, + "max_active_tasks": { "type" : "number", "default": 16}, + "max_active_runs": { "type" : "number", "default": 16}, + "max_consecutive_failed_dag_runs": { "type" : "number", "default": 0}, "default_args": { "$ref": "#/definitions/dict" }, "start_date": { "$ref": "#/definitions/datetime" }, "end_date": { "$ref": "#/definitions/datetime" }, @@ -204,9 +208,9 @@ "doc_md": { "type" : "string"}, "access_control": {"$ref": "#/definitions/dict" }, "is_paused_upon_creation": { "type": "boolean" }, - "has_on_success_callback": { "type": "boolean" }, - "has_on_failure_callback": { "type": "boolean" }, - "render_template_as_native_obj": { "type": "boolean" }, + "has_on_success_callback": { "type": "boolean", "default": false }, + "has_on_failure_callback": { "type": "boolean", "default": false }, + "render_template_as_native_obj": { "type": "boolean", "default": false }, "tags": { "type": "array" }, "task_group": {"anyOf": [ { "type": "null" }, @@ -214,7 +218,7 @@ ]}, "edge_info": { "$ref": "#/definitions/edge_info" }, "dag_dependencies": { "$ref": "#/definitions/dag_dependencies" }, - "disable_bundle_versioning": {"type": "boolean"} + "disable_bundle_versioning": {"type": "boolean", "default": false } }, "required": [ "dag_id", @@ -279,7 +283,7 @@ "pool": { "type": "string", "default": "default_pool" }, "pool_slots": { "type": "number", "default": 1 }, "execution_timeout": { "$ref": "#/definitions/timedelta" }, - "retry_delay": { "$ref": "#/definitions/timedelta" }, + "retry_delay": { "$ref": "#/definitions/timedelta", "default": 300.0 }, "retry_exponential_backoff": { "type": "boolean", "default": false }, "max_retry_delay": { "$ref": "#/definitions/timedelta" }, "params": { "$ref": "#/definitions/params" }, diff --git a/airflow-core/src/airflow/serialization/serialized_objects.py b/airflow-core/src/airflow/serialization/serialized_objects.py index 3e75993b2e2eb..aed682f433744 100644 --- a/airflow-core/src/airflow/serialization/serialized_objects.py +++ b/airflow-core/src/airflow/serialization/serialized_objects.py @@ -28,6 +28,7 @@ import logging import math import re +import sys import weakref from collections.abc import Collection, Iterable, Iterator, Mapping, Sequence from functools import cached_property, lru_cache @@ -58,7 +59,13 @@ from airflow._shared.timezones.timezone import coerce_datetime, from_timestamp, parse_timezone, utcnow from airflow.callbacks.callback_requests import DagCallbackRequest, TaskCallbackRequest from airflow.configuration import conf as airflow_conf -from airflow.exceptions import AirflowException, DeserializationError, SerializationError, TaskDeferred +from airflow.exceptions import ( + AirflowException, + DeserializationError, + SerializationError, + TaskDeferred, + TaskNotFound, +) from airflow.models.connection import Connection from airflow.models.dag import DagModel from airflow.models.dag_version import DagVersion @@ -125,6 +132,7 @@ from airflow.models.mappedoperator import MappedOperator as SerializedMappedOperator from airflow.models.taskinstance import TaskInstance from airflow.sdk import BaseOperatorLink + from airflow.sdk.definitions.edges import EdgeInfoType from airflow.serialization.json_schema import Validator from airflow.task.trigger_rule import TriggerRule from airflow.ti_deps.deps.base_ti_dep import BaseTIDep @@ -609,7 +617,7 @@ class BaseSerialization: _CONSTRUCTOR_PARAMS: dict[str, Parameter] = {} - SERIALIZER_VERSION = 2 + SERIALIZER_VERSION = 3 @classmethod def to_json(cls, var: Any) -> str: @@ -915,8 +923,13 @@ def deserialize(cls, encoded_var: Any) -> Any: elif type_ == DAT.DATETIME: return from_timestamp(var) elif type_ == DAT.POD: - if not _has_kubernetes(): - raise RuntimeError("Cannot deserialize POD objects without kubernetes libraries installed!") + # Attempt to import kubernetes for deserialization. Using attempt_import=True allows + # lazy loading of kubernetes libraries only when actually needed for POD deserialization. + if not _has_kubernetes(attempt_import=True): + raise RuntimeError( + "Cannot deserialize POD objects without kubernetes libraries. " + "Please install the cncf.kubernetes provider." + ) pod = PodGenerator.deserialize_model_dict(var) return pod elif type_ == DAT.TIMEDELTA: @@ -1087,21 +1100,7 @@ def _deserialize_params_dict(cls, encoded_params: list[tuple[str, dict]]) -> Par return ParamsDict(op_params) @classmethod - def get_operator_optional_fields_from_schema(cls) -> set[str]: - schema_loader = cls._json_schema - - if schema_loader is None: - return set() - - schema_data = schema_loader.schema - operator_def = schema_data.get("definitions", {}).get("operator", {}) - operator_fields = set(operator_def.get("properties", {}).keys()) - required_fields = set(operator_def.get("required", [])) - - optional_fields = operator_fields - required_fields - return optional_fields - - @classmethod + @lru_cache(maxsize=4) # Cache for "operator", "dag", and a few others def get_schema_defaults(cls, object_type: str) -> dict[str, Any]: """ Extract default values from JSON schema for any object type. @@ -1141,10 +1140,6 @@ def detect_task_dependencies(task: SdkOperator) -> list[DagDependency]: from airflow.providers.standard.operators.trigger_dagrun import TriggerDagRunOperator from airflow.providers.standard.sensors.external_task import ExternalTaskSensor - # TODO (GH-52141): Separate MappedOperator implementation to get rid of this. - if TYPE_CHECKING: - assert isinstance(task.operator_class, type) - deps = [] if isinstance(task, TriggerDagRunOperator): deps.append( @@ -1301,7 +1296,7 @@ class SerializedBaseOperator(DAGNode, BaseSerialization): resources: dict[str, Any] | None = None retries: int = 0 - retry_delay: datetime.timedelta + retry_delay: datetime.timedelta = datetime.timedelta(seconds=300) retry_exponential_backoff: bool = False run_as_user: str | None = None @@ -1350,11 +1345,15 @@ def __eq__(self, other: Any) -> bool: getattr(self, c, None) == getattr(other, c, None) for c in BaseOperator._comps ) + def __repr__(self) -> str: + return f"" + @property def node_id(self) -> str: return self.task_id - def get_dag(self) -> DAG | None: + # TODO (GH-52141): Replace DAGNode with a scheduler type. + def get_dag(self) -> SerializedDAG | None: # type: ignore[override] return self.dag @property @@ -1401,7 +1400,8 @@ def get_extra_links(self, ti: TaskInstance, name: str) -> str | None: link = self.operator_extra_link_dict.get(name) or self.global_operator_extra_link_dict.get(name) if not link: return None - return link.get_link(self, ti_key=ti.key) # type: ignore[arg-type] # TODO: GH-52141 - BaseOperatorLink.get_link expects BaseOperator but receives SerializedBaseOperator + # TODO: GH-52141 - BaseOperatorLink.get_link expects BaseOperator but receives SerializedBaseOperator. + return link.get_link(self, ti_key=ti.key) # type: ignore[arg-type] @property def operator_name(self) -> str: @@ -1422,6 +1422,8 @@ def expand_start_trigger_args(self, *, context: Context) -> StartTriggerArgs | N @property def weight_rule(self) -> PriorityWeightStrategy: + if isinstance(self._weight_rule, PriorityWeightStrategy): + return self._weight_rule return validate_and_load_priority_weight_strategy(self._weight_rule) def __getattr__(self, name): @@ -1708,6 +1710,22 @@ def set_task_dag_references(task: SerializedOperator | MappedOperator, dag: Seri # Bypass set_upstream etc here - it does more than we want dag.task_dict[task_id].upstream_task_ids.add(task.task_id) + @classmethod + @lru_cache(maxsize=1) # Only one type: "operator" + def get_operator_optional_fields_from_schema(cls) -> set[str]: + schema_loader = cls._json_schema + + if schema_loader is None: + return set() + + schema_data = schema_loader.schema + operator_def = schema_data.get("definitions", {}).get("operator", {}) + operator_fields = set(operator_def.get("properties", {}).keys()) + required_fields = set(operator_def.get("required", [])) + + optional_fields = operator_fields - required_fields + return optional_fields + @classmethod def deserialize_operator( cls, @@ -1809,7 +1827,7 @@ def detect_dependencies(cls, op: SdkOperator) -> set[DagDependency]: return deps @classmethod - def _matches_client_defaults(cls, var: Any, attrname: str, op: DAGNode) -> bool: + def _matches_client_defaults(cls, var: Any, attrname: str) -> bool: """ Check if a field value matches client_defaults and should be excluded. @@ -1818,7 +1836,6 @@ def _matches_client_defaults(cls, var: Any, attrname: str, op: DAGNode) -> bool: :param var: The value to check :param attrname: The attribute name - :param op: The operator instance :return: True if value matches client_defaults and should be excluded """ try: @@ -1846,7 +1863,7 @@ def _is_excluded(cls, var: Any, attrname: str, op: DAGNode): :return: True if a variable is excluded, False otherwise. """ # Check if value matches client_defaults (hierarchical defaults optimization) - if cls._matches_client_defaults(var, attrname, op): + if cls._matches_client_defaults(var, attrname): return True schema_defaults = cls.get_schema_defaults("operator") @@ -2045,19 +2062,26 @@ def generate_client_defaults(cls) -> dict[str, Any]: for k, v in OPERATOR_DEFAULTS.items(): if k not in cls.get_serialized_fields(): continue - # Exclude values that are the same as the schema defaults - if k in schema_defaults and schema_defaults[k] == v: - continue # Exclude values that are None or empty collections if v is None or v in [[], (), set(), {}]: continue + # Check schema defaults first with raw value comparison (fast path) + if k in schema_defaults and schema_defaults[k] == v: + continue + # Use the existing serialize method to ensure consistent format serialized_value = cls.serialize(v) # Extract just the value part, consistent with serialize_to_json behavior if isinstance(serialized_value, dict) and Encoding.TYPE in serialized_value: serialized_value = serialized_value[Encoding.VAR] + + # For cases where raw comparison failed but serialized values might match + # (e.g., timedelta vs float), check again with serialized value + if k in schema_defaults and schema_defaults[k] == serialized_value: + continue + client_defaults[k] = serialized_value return client_defaults @@ -2331,7 +2355,7 @@ def _create_orm_dagrun( return run -class SerializedDAG(DAG, BaseSerialization): +class SerializedDAG(BaseSerialization): """ A JSON serializable representation of DAG. @@ -2342,16 +2366,71 @@ class SerializedDAG(DAG, BaseSerialization): _decorated_fields: ClassVar[set[str]] = {"default_args", "access_control"} - # TODO (GH-52141): These should contain serialized containers, but currently - # this class inherits from an SDK one. - task_group: SerializedTaskGroup # type: ignore[assignment] - task_dict: dict[str, SerializedBaseOperator | SerializedMappedOperator] # type: ignore[assignment] + access_control: dict[str, dict[str, Collection[str]]] | None = None + catchup: bool + dag_id: str + dag_display_name: str + dagrun_timeout: datetime.timedelta | None + deadline: list[DeadlineAlert] | DeadlineAlert | None + default_args: dict[str, Any] + description: str | None + disable_bundle_versioning: bool + doc_md: str | None + edge_info: dict[str, dict[str, EdgeInfoType]] + end_date: datetime.datetime | None + fail_fast: bool + has_on_failure_callback: bool + has_on_success_callback: bool + is_paused_upon_creation: bool | None + max_active_runs: int + max_active_tasks: int + max_consecutive_failed_dag_runs: int + owner_links: dict[str, str] + params: ParamsDict # TODO (GH-52141): Should use a scheduler-specific type. + partial: bool + render_template_as_native_obj: bool + start_date: datetime.datetime | None + tags: set[str] + task_dict: dict[str, SerializedOperator] + task_group: SerializedTaskGroup + template_searchpath: tuple[str, ...] | None + timetable: Timetable + timezone: FixedTimezone | Timezone last_loaded: datetime.datetime # this will only be set at serialization time # it's only use is for determining the relative fileloc based only on the serialize dag _processor_dags_folder: str + def __init__(self, *, dag_id: str) -> None: + self.catchup = False # Schema default + self.dag_id = self.dag_display_name = dag_id + self.dagrun_timeout = None + self.deadline = None + self.default_args = {} + self.description = None + self.disable_bundle_versioning = False + self.doc_md = None + self.edge_info = {} + self.end_date = None + self.fail_fast = False + self.has_on_failure_callback = False + self.has_on_success_callback = False + self.is_paused_upon_creation = None + self.max_active_runs = 16 # Schema default + self.max_active_tasks = 16 # Schema default + self.max_consecutive_failed_dag_runs = 0 # Schema default + self.owner_links = {} + self.params = ParamsDict() + self.partial = False + self.render_template_as_native_obj = False + self.start_date = None + self.tags = set() + self.template_searchpath = None + + def __repr__(self) -> str: + return f"" + @staticmethod def __get_constructor_defaults(): param_to_attr = { @@ -2368,6 +2447,39 @@ def __get_constructor_defaults(): _json_schema: ClassVar[Validator] = lazy_object_proxy.Proxy(load_dag_schema) + @classmethod + def get_serialized_fields(cls) -> frozenset[str]: + return frozenset( + { + "access_control", + "catchup", + "dag_display_name", + "dag_id", + "dagrun_timeout", + "deadline", + "default_args", + "description", + "disable_bundle_versioning", + "doc_md", + "edge_info", + "end_date", + "fail_fast", + "fileloc", + "is_paused_upon_creation", + "max_active_runs", + "max_active_tasks", + "max_consecutive_failed_dag_runs", + "owner_links", + "relative_fileloc", + "render_template_as_native_obj", + "start_date", + "tags", + "task_group", + "timetable", + "timezone", + } + ) + @classmethod def serialize_dag(cls, dag: DAG) -> dict: """Serialize a DAG into a JSON object.""" @@ -2385,7 +2497,11 @@ def serialize_dag(cls, dag: DAG) -> dict: serialized_dag["dag_dependencies"] = [x.__dict__ for x in sorted(dag_deps)] serialized_dag["task_group"] = TaskGroupSerialization.serialize_task_group(dag.task_group) - serialized_dag["deadline"] = dag.deadline.serialize_deadline_alert() if dag.deadline else None + serialized_dag["deadline"] = ( + [deadline.serialize_deadline_alert() for deadline in dag.deadline] + if isinstance(dag.deadline, list) + else None + ) # Edge info in the JSON exactly matches our internal structure serialized_dag["edge_info"] = dag.edge_info @@ -2409,7 +2525,8 @@ def deserialize_dag( """Deserializes a DAG from a JSON object.""" if "dag_id" not in encoded_dag: raise DeserializationError( - message="Encoded dag object has no dag_id key. You may need to run `airflow dags reserialize`." + message="Encoded dag object has no dag_id key. " + "You may need to run `airflow dags reserialize`." ) dag_id = encoded_dag["dag_id"] @@ -2428,7 +2545,7 @@ def _deserialize_dag_internal( cls, encoded_dag: dict[str, Any], client_defaults: dict[str, Any] | None = None ) -> SerializedDAG: """Handle the main Dag deserialization logic.""" - dag = SerializedDAG(dag_id=encoded_dag["dag_id"], schedule=None) + dag = SerializedDAG(dag_id=encoded_dag["dag_id"]) dag.last_loaded = utcnow() # Note: Context is passed explicitly through method parameters, no class attributes needed @@ -2501,7 +2618,14 @@ def _deserialize_dag_internal( dag.has_on_failure_callback = True if "deadline" in encoded_dag and encoded_dag["deadline"] is not None: - dag.deadline = DeadlineAlert.deserialize_deadline_alert(encoded_dag["deadline"]) + dag.deadline = ( + [ + DeadlineAlert.deserialize_deadline_alert(deadline_data) + for deadline_data in encoded_dag["deadline"] + ] + if encoded_dag["deadline"] + else None + ) keys_to_set_none = dag.get_serialized_fields() - encoded_dag.keys() - cls._CONSTRUCTOR_PARAMS.keys() for k in keys_to_set_none: @@ -2520,8 +2644,38 @@ def _is_excluded(cls, var: Any, attrname: str, op: DAGNode): return False if attrname == "dag_display_name" and var == op.dag_id: return True + + # DAG schema defaults exclusion (same pattern as SerializedBaseOperator) + dag_schema_defaults = cls.get_schema_defaults("dag") + if attrname in dag_schema_defaults: + if dag_schema_defaults[attrname] == var: + return True + + optional_fields = cls.get_dag_optional_fields_from_schema() + if var is None: + return True + if attrname in optional_fields: + if var in [[], (), set(), {}]: + return True + return super()._is_excluded(var, attrname, op) + @classmethod + @lru_cache(maxsize=1) # Only one type: "dag" + def get_dag_optional_fields_from_schema(cls) -> set[str]: + schema_loader = cls._json_schema + + if schema_loader is None: + return set() + + schema_data = schema_loader.schema + operator_def = schema_data.get("definitions", {}).get("dag", {}) + operator_fields = set(operator_def.get("properties", {}).keys()) + required_fields = set(operator_def.get("required", [])) + + optional_fields = operator_fields - required_fields + return optional_fields + @classmethod def to_dict(cls, var: Any) -> dict: """Stringifies DAGs and operators contained by var and returns a dict of var.""" @@ -2672,14 +2826,22 @@ def _create_compat_timetable(value): # Set on the root TG dag_dict["task_group"]["group_display_name"] = "" + @staticmethod + def conversion_v2_to_v3(ser_obj: dict): + # V2 to V3 changes are minimal - mainly client_defaults optimization and + # field presence differences. Only version bump needed. + ser_obj["__version"] = 3 + @classmethod def from_dict(cls, serialized_obj: dict) -> SerializedDAG: """Deserializes a python dict in to the DAG and operators it contains.""" ver = serialized_obj.get("__version", "") - if ver not in (1, 2): + if ver not in (1, 2, 3): raise ValueError(f"Unsure how to deserialize version {ver!r}") if ver == 1: cls.conversion_v1_to_v2(serialized_obj) + if ver == 2: + cls.conversion_v2_to_v3(serialized_obj) # Extract client_defaults for hierarchical defaults resolution client_defaults = serialized_obj.get("client_defaults", {}) @@ -2736,18 +2898,45 @@ def bulk_write_to_db( dag_op.update_dag_asset_expression(orm_dags=orm_dags, orm_assets=orm_assets) session.flush() - # TODO (GH-52141): This needs to take scheduler types, but currently it inherits SDK's DAG. - # TODO (GH-52141): This shouldn't need to be writable, but SDK's DAG defines it as such. - @property # type: ignore[misc] - def tasks(self) -> Sequence[SerializedOperator]: # type: ignore[override] + @property + def tasks(self) -> Sequence[SerializedOperator]: return list(self.task_dict.values()) + @property + def task_ids(self) -> list[str]: + return list(self.task_dict) + + @property + def roots(self) -> list[SerializedOperator]: + return [task for task in self.tasks if not task.upstream_list] + + @property + def owner(self) -> str: + return ", ".join({t.owner for t in self.tasks}) + + @property + def timetable_summary(self) -> str: + return self.timetable.summary + + def has_task(self, task_id: str) -> bool: + return task_id in self.task_dict + + def get_task(self, task_id: str) -> SerializedOperator: + if task_id in self.task_dict: + return self.task_dict[task_id] + raise TaskNotFound(f"Task {task_id} not found") + + @property + def task_group_dict(self): + return {k: v for k, v in self.task_group.get_task_group_dict().items() if k is not None} + def partial_subset( self, task_ids: str | Iterable[str], include_downstream: bool = False, include_upstream: bool = True, include_direct_upstream: bool = False, + exclude_original: bool = False, ): from airflow.models.mappedoperator import MappedOperator as SerializedMappedOperator @@ -2798,6 +2987,8 @@ def _deepcopy_task(t) -> SerializedOperator: return copy.deepcopy(t, memo) # Compiling the unique list of tasks that made the cut + if exclude_original: + matched_tasks = [] dag.task_dict = { t.task_id: _deepcopy_task(t) for t in itertools.chain(matched_tasks, also_include, direct_upstreams) @@ -3096,19 +3287,21 @@ def create_dagrun( session=session, ) - if self.deadline and isinstance(self.deadline.reference, DeadlineReference.TYPES.DAGRUN): - session.add( - Deadline( - deadline_time=self.deadline.reference.evaluate_with( - session=session, - interval=self.deadline.interval, - dag_id=self.dag_id, - run_id=run_id, - ), - callback=self.deadline.callback, - dagrun_id=orm_dagrun.id, - ) - ) + if self.deadline: + for deadline in cast("list", self.deadline): + if isinstance(deadline.reference, DeadlineReference.TYPES.DAGRUN): + session.add( + Deadline( + deadline_time=deadline.reference.evaluate_with( + session=session, + interval=deadline.interval, + dag_id=self.dag_id, + run_id=run_id, + ), + callback=deadline.callback, + dagrun_id=orm_dagrun.id, + ) + ) return orm_dagrun @@ -3143,9 +3336,7 @@ def set_task_instance_state( """ from airflow.api.common.mark_tasks import set_state - # TODO (GH-52141): get_task in scheduler needs to return scheduler types - # instead, but currently it inherits SDK's DAG. - task = cast("SerializedOperator", self.get_task(task_id)) + task = self.get_task(task_id) task.dag = self tasks_to_set_state: list[SerializedOperator | tuple[SerializedOperator, int]] @@ -3523,6 +3714,14 @@ def _coerce_dag(dag): for dag in dags ) + def get_edge_info(self, upstream_task_id: str, downstream_task_id: str) -> EdgeInfoType: + """Return edge information for the given pair of tasks or an empty edge if there is no information.""" + # Note - older serialized dags may not have edge_info being a dict at all + empty = cast("EdgeInfoType", {}) + if self.edge_info: + return self.edge_info.get(upstream_task_id, {}).get(downstream_task_id, empty) + return empty + class TaskGroupSerialization(BaseSerialization): """JSON serializable representation of a task group.""" @@ -3615,11 +3814,23 @@ class SerializedAssetWatcher(AssetWatcher): trigger: dict -def _has_kubernetes() -> bool: +def _has_kubernetes(attempt_import: bool = False) -> bool: + """ + Check if kubernetes libraries are available. + + :param attempt_import: If true, attempt to import kubernetes libraries if not already loaded. If + False, only check if already in sys.modules (avoids expensive import). + :return: True if kubernetes libraries are available, False otherwise. + """ global HAS_KUBERNETES if "HAS_KUBERNETES" in globals(): return HAS_KUBERNETES + # Check if kubernetes is already imported before triggering expensive import + if "kubernetes.client" not in sys.modules and not attempt_import: + HAS_KUBERNETES = False + return False + # Loading kube modules is expensive, so delay it until the last moment try: @@ -3650,16 +3861,33 @@ class LazyDeserializedDAG(pydantic.BaseModel): last_loaded: datetime.datetime | None = None NULLABLE_PROPERTIES: ClassVar[set[str]] = { - "is_paused_upon_creation", + # Non attr fields that should be nullable, or attrs with a different default "owner", + "owner_links", "dag_display_name", + "has_on_success_callback", + "has_on_failure_callback", + "tags", + # Attr properties that are nullable, or have a default that loads from config "description", - "relative_fileloc", + "start_date", + "end_date", + "template_searchpath", + "user_defined_macros", + "user_defined_filters", "max_active_tasks", "max_active_runs", "max_consecutive_failed_dag_runs", - "owner_links", + "dagrun_timeout", + "deadline", + "catchup", + "doc_md", "access_control", + "is_paused_upon_creation", + "jinja_environment_kwargs", + "relative_fileloc", + "disable_bundle_versioning", + "last_loaded", } @classmethod diff --git a/airflow-core/src/airflow/serialization/serializers/pydantic.py b/airflow-core/src/airflow/serialization/serializers/pydantic.py index 91db381264315..b07cc634176af 100644 --- a/airflow-core/src/airflow/serialization/serializers/pydantic.py +++ b/airflow-core/src/airflow/serialization/serializers/pydantic.py @@ -46,7 +46,7 @@ def serialize(o: object) -> tuple[U, str, int, bool]: if not is_pydantic_model(o): return "", "", 0, False - data = o.model_dump() # type: ignore + data = o.model_dump(mode="json") # type: ignore return data, qualname(o), __version__, True diff --git a/airflow-core/src/airflow/settings.py b/airflow-core/src/airflow/settings.py index 733a539b34423..5a87384487641 100644 --- a/airflow-core/src/airflow/settings.py +++ b/airflow-core/src/airflow/settings.py @@ -633,6 +633,21 @@ def prepare_syspath_for_config_and_plugins(): sys.path.append(PLUGINS_FOLDER) +def __getattr__(name: str): + """Handle deprecated module attributes.""" + if name == "MASK_SECRETS_IN_LOGS": + import warnings + + warnings.warn( + "settings.MASK_SECRETS_IN_LOGS has been removed. This shim returns default value of False. " + "Use SecretsMasker.enable_log_masking(), disable_log_masking(), or is_log_masking_enabled() instead.", + DeprecationWarning, + stacklevel=2, + ) + return False + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + + def import_local_settings(): """Import airflow_local_settings.py files to allow overriding any configs in settings.py file.""" try: diff --git a/airflow-core/src/airflow/ti_deps/dep_context.py b/airflow-core/src/airflow/ti_deps/dep_context.py index 056b633f36122..1feafdd041ae1 100644 --- a/airflow-core/src/airflow/ti_deps/dep_context.py +++ b/airflow-core/src/airflow/ti_deps/dep_context.py @@ -18,7 +18,7 @@ from __future__ import annotations import contextlib -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING import attr @@ -29,9 +29,7 @@ from sqlalchemy.orm.session import Session from airflow.models.dagrun import DagRun - from airflow.models.mappedoperator import MappedOperator from airflow.models.taskinstance import TaskInstance - from airflow.serialization.serialized_objects import SerializedBaseOperator @attr.define @@ -100,9 +98,7 @@ def ensure_finished_tis(self, dag_run: DagRun, session: Session) -> list[TaskIns if getattr(ti, "task", None) is not None or (dag := dag_run.dag) is None: continue with contextlib.suppress(TaskNotFound): - # TODO (GH-52141): get_task in scheduler should contain scheduler - # types instead, but currently it inherits SDK's DAG. - ti.task = cast("MappedOperator | SerializedBaseOperator", dag.get_task(ti.task_id)) + ti.task = dag.get_task(ti.task_id) self.finished_tis = finished_tis else: finished_tis = self.finished_tis diff --git a/airflow-core/src/airflow/timetables/_cron.py b/airflow-core/src/airflow/timetables/_cron.py index e62f96de77029..632c00ae2dc2d 100644 --- a/airflow-core/src/airflow/timetables/_cron.py +++ b/airflow-core/src/airflow/timetables/_cron.py @@ -71,17 +71,52 @@ def __init__(self, cron: str, timezone: str | Timezone | FixedTimezone) -> None: self._timezone = timezone try: - descriptor = ExpressionDescriptor( - expression=self._expression, casing_type=CasingTypeEnum.Sentence, use_24hour_time_format=True - ) # checking for more than 5 parameters in Cron and avoiding evaluation for now, # as Croniter has inconsistent evaluation with other libraries if len(croniter(self._expression).expanded) > 5: raise FormatException() - interval_description: str = descriptor.get_description() + + self.description = self._describe_with_dom_dow_fix(self._expression) + except (CroniterBadCronError, FormatException, MissingFieldException): - interval_description = "" - self.description: str = interval_description + self.description = "" + + def _describe_with_dom_dow_fix(self, expression: str) -> str: + """ + Return cron description with fix for DOM+DOW conflicts. + + If both DOM and DOW are restricted, explain them as OR. + """ + cron_fields = expression.split() + + if len(cron_fields) < 5: + return ExpressionDescriptor( + expression, casing_type=CasingTypeEnum.Sentence, use_24hour_time_format=True + ).get_description() + + dom = cron_fields[2] + dow = cron_fields[4] + + if dom != "*" and dow != "*": + # Case: conflict → DOM OR DOW + cron_fields_dom = cron_fields.copy() + cron_fields_dom[4] = "*" + day_of_month_desc = ExpressionDescriptor( + " ".join(cron_fields_dom), casing_type=CasingTypeEnum.Sentence, use_24hour_time_format=True + ).get_description() + + cron_fields_dow = cron_fields.copy() + cron_fields_dow[2] = "*" + day_of_week_desc = ExpressionDescriptor( + " ".join(cron_fields_dow), casing_type=CasingTypeEnum.Sentence, use_24hour_time_format=True + ).get_description() + + return f"{day_of_month_desc} (or) {day_of_week_desc}" + + # no conflict → return normal description + return ExpressionDescriptor( + expression, casing_type=CasingTypeEnum.Sentence, use_24hour_time_format=True + ).get_description() def __eq__(self, other: object) -> bool: """ diff --git a/airflow-core/src/airflow/ui/dev/index.html b/airflow-core/src/airflow/ui/dev/index.html index f77a08175d1cd..10afd373f8fae 100644 --- a/airflow-core/src/airflow/ui/dev/index.html +++ b/airflow-core/src/airflow/ui/dev/index.html @@ -1,6 +1,6 @@ - + diff --git a/airflow-core/src/airflow/ui/index.html b/airflow-core/src/airflow/ui/index.html index e3f4f943f2530..952a8d3becb42 100644 --- a/airflow-core/src/airflow/ui/index.html +++ b/airflow-core/src/airflow/ui/index.html @@ -1,5 +1,5 @@ - + diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts index 457aac893eef9..0c08df317b811 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts @@ -1,7 +1,7 @@ // generated with @7nohe/openapi-react-query-codegen@1.6.2 import { UseQueryResult } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagParsingService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskService, VariableService, VersionService, XcomService } from "../requests/services.gen"; +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagParsingService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskService, VariableService, VersionService, XcomService } from "../requests/services.gen"; import { DagRunState, DagWarningType } from "../requests/types.gen"; export type AssetServiceGetAssetsDefaultResponse = Awaited>; export type AssetServiceGetAssetsQueryResult = UseQueryResult; @@ -205,12 +205,6 @@ export const useDagStatsServiceGetDagStatsKey = "DagStatsServiceGetDagStats"; export const UseDagStatsServiceGetDagStatsKeyFn = ({ dagIds }: { dagIds?: string[]; } = {}, queryKey?: Array) => [useDagStatsServiceGetDagStatsKey, ...(queryKey ?? [{ dagIds }])]; -export type DagReportServiceGetDagReportsDefaultResponse = Awaited>; -export type DagReportServiceGetDagReportsQueryResult = UseQueryResult; -export const useDagReportServiceGetDagReportsKey = "DagReportServiceGetDagReports"; -export const UseDagReportServiceGetDagReportsKeyFn = ({ subdir }: { - subdir: string; -}, queryKey?: Array) => [useDagReportServiceGetDagReportsKey, ...(queryKey ?? [{ subdir }])]; export type ConfigServiceGetConfigDefaultResponse = Awaited>; export type ConfigServiceGetConfigQueryResult = UseQueryResult; export const useConfigServiceGetConfigKey = "ConfigServiceGetConfig"; @@ -382,7 +376,7 @@ export const UseTaskInstanceServiceGetTaskInstanceKeyFn = ({ dagId, dagRunId, ta export type TaskInstanceServiceGetMappedTaskInstancesDefaultResponse = Awaited>; export type TaskInstanceServiceGetMappedTaskInstancesQueryResult = UseQueryResult; export const useTaskInstanceServiceGetMappedTaskInstancesKey = "TaskInstanceServiceGetMappedTaskInstances"; -export const UseTaskInstanceServiceGetMappedTaskInstancesKeyFn = ({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const UseTaskInstanceServiceGetMappedTaskInstancesKeyFn = ({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -399,6 +393,7 @@ export const UseTaskInstanceServiceGetMappedTaskInstancesKeyFn = ({ dagId, dagRu logicalDateGte?: string; logicalDateLt?: string; logicalDateLte?: string; + mapIndex?: number[]; offset?: number; operator?: string[]; orderBy?: string[]; @@ -420,7 +415,7 @@ export const UseTaskInstanceServiceGetMappedTaskInstancesKeyFn = ({ dagId, dagRu updatedAtLt?: string; updatedAtLte?: string; versionNumber?: number[]; -}, queryKey?: Array) => [useTaskInstanceServiceGetMappedTaskInstancesKey, ...(queryKey ?? [{ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }])]; +}, queryKey?: Array) => [useTaskInstanceServiceGetMappedTaskInstancesKey, ...(queryKey ?? [{ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }])]; export type TaskInstanceServiceGetTaskInstanceDependenciesByMapIndexDefaultResponse = Awaited>; export type TaskInstanceServiceGetTaskInstanceDependenciesByMapIndexQueryResult = UseQueryResult; export const useTaskInstanceServiceGetTaskInstanceDependenciesByMapIndexKey = "TaskInstanceServiceGetTaskInstanceDependenciesByMapIndex"; @@ -469,7 +464,7 @@ export const UseTaskInstanceServiceGetMappedTaskInstanceKeyFn = ({ dagId, dagRun export type TaskInstanceServiceGetTaskInstancesDefaultResponse = Awaited>; export type TaskInstanceServiceGetTaskInstancesQueryResult = UseQueryResult; export const useTaskInstanceServiceGetTaskInstancesKey = "TaskInstanceServiceGetTaskInstances"; -export const UseTaskInstanceServiceGetTaskInstancesKeyFn = ({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const UseTaskInstanceServiceGetTaskInstancesKeyFn = ({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -486,6 +481,7 @@ export const UseTaskInstanceServiceGetTaskInstancesKeyFn = ({ dagId, dagRunId, d logicalDateGte?: string; logicalDateLt?: string; logicalDateLte?: string; + mapIndex?: number[]; offset?: number; operator?: string[]; orderBy?: string[]; @@ -508,7 +504,7 @@ export const UseTaskInstanceServiceGetTaskInstancesKeyFn = ({ dagId, dagRunId, d updatedAtLt?: string; updatedAtLte?: string; versionNumber?: number[]; -}, queryKey?: Array) => [useTaskInstanceServiceGetTaskInstancesKey, ...(queryKey ?? [{ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }])]; +}, queryKey?: Array) => [useTaskInstanceServiceGetTaskInstancesKey, ...(queryKey ?? [{ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }])]; export type TaskInstanceServiceGetTaskInstanceTryDetailsDefaultResponse = Awaited>; export type TaskInstanceServiceGetTaskInstanceTryDetailsQueryResult = UseQueryResult; export const useTaskInstanceServiceGetTaskInstanceTryDetailsKey = "TaskInstanceServiceGetTaskInstanceTryDetails"; @@ -552,6 +548,39 @@ export const UseTaskInstanceServiceGetExternalLogUrlKeyFn = ({ dagId, dagRunId, taskId: string; tryNumber: number; }, queryKey?: Array) => [useTaskInstanceServiceGetExternalLogUrlKey, ...(queryKey ?? [{ dagId, dagRunId, mapIndex, taskId, tryNumber }])]; +export type TaskInstanceServiceGetHitlDetailDefaultResponse = Awaited>; +export type TaskInstanceServiceGetHitlDetailQueryResult = UseQueryResult; +export const useTaskInstanceServiceGetHitlDetailKey = "TaskInstanceServiceGetHitlDetail"; +export const UseTaskInstanceServiceGetHitlDetailKeyFn = ({ dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}, queryKey?: Array) => [useTaskInstanceServiceGetHitlDetailKey, ...(queryKey ?? [{ dagId, dagRunId, mapIndex, taskId }])]; +export type TaskInstanceServiceGetHitlDetailsDefaultResponse = Awaited>; +export type TaskInstanceServiceGetHitlDetailsQueryResult = UseQueryResult; +export const useTaskInstanceServiceGetHitlDetailsKey = "TaskInstanceServiceGetHitlDetails"; +export const UseTaskInstanceServiceGetHitlDetailsKeyFn = ({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + createdAtGt?: string; + createdAtGte?: string; + createdAtLt?: string; + createdAtLte?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + mapIndex?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}, queryKey?: Array) => [useTaskInstanceServiceGetHitlDetailsKey, ...(queryKey ?? [{ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }])]; export type ImportErrorServiceGetImportErrorDefaultResponse = Awaited>; export type ImportErrorServiceGetImportErrorQueryResult = UseQueryResult; export const useImportErrorServiceGetImportErrorKey = "ImportErrorServiceGetImportError"; @@ -561,11 +590,12 @@ export const UseImportErrorServiceGetImportErrorKeyFn = ({ importErrorId }: { export type ImportErrorServiceGetImportErrorsDefaultResponse = Awaited>; export type ImportErrorServiceGetImportErrorsQueryResult = UseQueryResult; export const useImportErrorServiceGetImportErrorsKey = "ImportErrorServiceGetImportErrors"; -export const UseImportErrorServiceGetImportErrorsKeyFn = ({ limit, offset, orderBy }: { +export const UseImportErrorServiceGetImportErrorsKeyFn = ({ filenamePattern, limit, offset, orderBy }: { + filenamePattern?: string; limit?: number; offset?: number; orderBy?: string[]; -} = {}, queryKey?: Array) => [useImportErrorServiceGetImportErrorsKey, ...(queryKey ?? [{ limit, offset, orderBy }])]; +} = {}, queryKey?: Array) => [useImportErrorServiceGetImportErrorsKey, ...(queryKey ?? [{ filenamePattern, limit, offset, orderBy }])]; export type JobServiceGetJobsDefaultResponse = Awaited>; export type JobServiceGetJobsQueryResult = UseQueryResult; export const useJobServiceGetJobsKey = "JobServiceGetJobs"; @@ -705,34 +735,6 @@ export const UseDagVersionServiceGetDagVersionsKeyFn = ({ bundleName, bundleVers orderBy?: string[]; versionNumber?: number; }, queryKey?: Array) => [useDagVersionServiceGetDagVersionsKey, ...(queryKey ?? [{ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }])]; -export type HumanInTheLoopServiceGetHitlDetailDefaultResponse = Awaited>; -export type HumanInTheLoopServiceGetHitlDetailQueryResult = UseQueryResult; -export const useHumanInTheLoopServiceGetHitlDetailKey = "HumanInTheLoopServiceGetHitlDetail"; -export const UseHumanInTheLoopServiceGetHitlDetailKeyFn = ({ dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}, queryKey?: Array) => [useHumanInTheLoopServiceGetHitlDetailKey, ...(queryKey ?? [{ dagId, dagRunId, mapIndex, taskId }])]; -export type HumanInTheLoopServiceGetHitlDetailsDefaultResponse = Awaited>; -export type HumanInTheLoopServiceGetHitlDetailsQueryResult = UseQueryResult; -export const useHumanInTheLoopServiceGetHitlDetailsKey = "HumanInTheLoopServiceGetHitlDetails"; -export const UseHumanInTheLoopServiceGetHitlDetailsKeyFn = ({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedUserId?: string[]; - respondedUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}, queryKey?: Array) => [useHumanInTheLoopServiceGetHitlDetailsKey, ...(queryKey ?? [{ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }])]; export type MonitorServiceGetHealthDefaultResponse = Awaited>; export type MonitorServiceGetHealthQueryResult = UseQueryResult; export const useMonitorServiceGetHealthKey = "MonitorServiceGetHealth"; @@ -870,12 +872,12 @@ export type TaskInstanceServicePatchTaskInstanceByMapIndexMutationResult = Await export type TaskInstanceServiceBulkTaskInstancesMutationResult = Awaited>; export type TaskInstanceServicePatchTaskInstanceDryRunByMapIndexMutationResult = Awaited>; export type TaskInstanceServicePatchTaskInstanceDryRunMutationResult = Awaited>; +export type TaskInstanceServiceUpdateHitlDetailMutationResult = Awaited>; export type PoolServicePatchPoolMutationResult = Awaited>; export type PoolServiceBulkPoolsMutationResult = Awaited>; export type XcomServiceUpdateXcomEntryMutationResult = Awaited>; export type VariableServicePatchVariableMutationResult = Awaited>; export type VariableServiceBulkVariablesMutationResult = Awaited>; -export type HumanInTheLoopServiceUpdateHitlDetailMutationResult = Awaited>; export type AssetServiceDeleteAssetQueuedEventsMutationResult = Awaited>; export type AssetServiceDeleteDagAssetQueuedEventsMutationResult = Awaited>; export type AssetServiceDeleteDagAssetQueuedEventMutationResult = Awaited>; diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts index 75803561cfa32..841f09b719b24 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts @@ -1,7 +1,7 @@ // generated with @7nohe/openapi-react-query-codegen@1.6.2 import { type QueryClient } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskService, VariableService, VersionService, XcomService } from "../requests/services.gen"; +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskService, VariableService, VersionService, XcomService } from "../requests/services.gen"; import { DagRunState, DagWarningType } from "../requests/types.gen"; import * as Common from "./common"; /** @@ -14,7 +14,7 @@ import * as Common from "./common"; * @param data.uriPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @param data.dagIds * @param data.onlyActive -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name, uri, created_at, updated_at` * @returns AssetCollectionResponse Successful Response * @throws ApiError */ @@ -34,7 +34,7 @@ export const ensureUseAssetServiceGetAssetsData = (queryClient: QueryClient, { d * @param data.limit * @param data.offset * @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name` * @returns AssetAliasCollectionResponse Successful Response * @throws ApiError */ @@ -61,7 +61,7 @@ export const ensureUseAssetServiceGetAssetAliasData = (queryClient: QueryClient, * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `source_task_id, source_dag_id, source_run_id, source_map_index, timestamp` * @param data.assetId * @param data.sourceDagId * @param data.sourceTaskId @@ -156,7 +156,7 @@ export const ensureUseAssetServiceNextRunAssetsData = (queryClient: QueryClient, * @param data.dagId * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id` * @returns BackfillCollectionResponse Successful Response * @throws ApiError */ @@ -181,7 +181,7 @@ export const ensureUseBackfillServiceGetBackfillData = (queryClient: QueryClient * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id` * @param data.dagId * @param data.active * @returns BackfillCollectionResponse Successful Response @@ -211,7 +211,7 @@ export const ensureUseConnectionServiceGetConnectionData = (queryClient: QueryCl * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `conn_id, conn_type, description, host, port, id, connection_id` * @param data.connectionIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns ConnectionCollectionResponse Successful Response * @throws ApiError @@ -286,7 +286,7 @@ export const ensureUseDagRunServiceGetUpstreamAssetEventsData = (queryClient: Qu * @param data.runType * @param data.state * @param data.dagVersion -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` * @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @param data.triggeringUserNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns DAGRunCollectionResponse Successful Response @@ -325,7 +325,7 @@ export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { }) => queryClient.ensureQueryData({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ dagId, dagVersion, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ dagId, dagVersion, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. -* 🚧 This is an experimental endpoint and may change or be removed without notice. +* 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. * @param data The data for the request. * @param data.dagId * @param data.dagRunId @@ -342,7 +342,7 @@ export const ensureUseDagRunServiceWaitDagRunUntilFinishedData = (queryClient: Q }) => queryClient.ensureQueryData({ queryKey: Common.UseDagRunServiceWaitDagRunUntilFinishedKeyFn({ dagId, dagRunId, interval, result }), queryFn: () => DagRunService.waitDagRunUntilFinished({ dagId, dagRunId, interval, result }) }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. -* 🚧 This is an experimental endpoint and may change or be removed without notice. +* 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. * @param data The data for the request. * @param data.dagId * @param data.dagRunId @@ -384,17 +384,6 @@ export const ensureUseDagStatsServiceGetDagStatsData = (queryClient: QueryClient dagIds?: string[]; } = {}) => queryClient.ensureQueryData({ queryKey: Common.UseDagStatsServiceGetDagStatsKeyFn({ dagIds }), queryFn: () => DagStatsService.getDagStats({ dagIds }) }); /** -* Get Dag Reports -* Get DAG report. -* @param data The data for the request. -* @param data.subdir -* @returns unknown Successful Response -* @throws ApiError -*/ -export const ensureUseDagReportServiceGetDagReportsData = (queryClient: QueryClient, { subdir }: { - subdir: string; -}) => queryClient.ensureQueryData({ queryKey: Common.UseDagReportServiceGetDagReportsKeyFn({ subdir }), queryFn: () => DagReportService.getDagReports({ subdir }) }); -/** * Get Config * @param data The data for the request. * @param data.section @@ -435,7 +424,7 @@ export const ensureUseConfigServiceGetConfigsData = (queryClient: QueryClient) = * @param data.warningType * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, warning_type, message, timestamp` * @returns DAGWarningCollectionResponse Successful Response * @throws ApiError */ @@ -474,7 +463,7 @@ export const ensureUseDagWarningServiceListDagWarningsData = (queryClient: Query * @param data.dagRunEndDateLte * @param data.dagRunEndDateLt * @param data.dagRunState -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` * @param data.isFavorite * @returns DAGCollectionResponse Successful Response * @throws ApiError @@ -535,7 +524,7 @@ export const ensureUseDagServiceGetDagDetailsData = (queryClient: QueryClient, { * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `name` * @param data.tagNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns DAGTagCollectionResponse Successful Response * @throws ApiError @@ -565,7 +554,7 @@ export const ensureUseDagServiceGetDagTagsData = (queryClient: QueryClient, { li * @param data.lastDagRunState * @param data.bundleName * @param data.bundleVersion -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` * @param data.isFavorite * @param data.hasAssetSchedule Filter Dags with asset-based scheduling * @param data.assetDependency Filter Dags by asset dependency (name or URI) @@ -622,7 +611,7 @@ export const ensureUseEventLogServiceGetEventLogData = (queryClient: QueryClient * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, dttm, dag_id, task_id, run_id, event, logical_date, owner, extra, when, event_log_id` * @param data.dagId * @param data.taskId * @param data.runId @@ -750,13 +739,14 @@ export const ensureUseTaskInstanceServiceGetTaskInstanceData = (queryClient: Que * @param data.versionNumber * @param data.tryNumber * @param data.operator +* @param data.mapIndex * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator, run_after, logical_date, data_interval_start, data_interval_end` * @returns TaskInstanceCollectionResponse Successful Response * @throws ApiError */ -export const ensureUseTaskInstanceServiceGetMappedTaskInstancesData = (queryClient: QueryClient, { dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const ensureUseTaskInstanceServiceGetMappedTaskInstancesData = (queryClient: QueryClient, { dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -773,6 +763,7 @@ export const ensureUseTaskInstanceServiceGetMappedTaskInstancesData = (queryClie logicalDateGte?: string; logicalDateLt?: string; logicalDateLte?: string; + mapIndex?: number[]; offset?: number; operator?: string[]; orderBy?: string[]; @@ -794,7 +785,7 @@ export const ensureUseTaskInstanceServiceGetMappedTaskInstancesData = (queryClie updatedAtLt?: string; updatedAtLte?: string; versionNumber?: number[]; -}) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetMappedTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }), queryFn: () => TaskInstanceService.getMappedTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) }); +}) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetMappedTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }), queryFn: () => TaskInstanceService.getMappedTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) }); /** * Get Task Instance Dependencies * Get dependencies blocking task from getting scheduled. @@ -921,13 +912,14 @@ export const ensureUseTaskInstanceServiceGetMappedTaskInstanceData = (queryClien * @param data.versionNumber * @param data.tryNumber * @param data.operator +* @param data.mapIndex * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator, logical_date, run_after, data_interval_start, data_interval_end` * @returns TaskInstanceCollectionResponse Successful Response * @throws ApiError */ -export const ensureUseTaskInstanceServiceGetTaskInstancesData = (queryClient: QueryClient, { dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const ensureUseTaskInstanceServiceGetTaskInstancesData = (queryClient: QueryClient, { dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -944,6 +936,7 @@ export const ensureUseTaskInstanceServiceGetTaskInstancesData = (queryClient: Qu logicalDateGte?: string; logicalDateLt?: string; logicalDateLte?: string; + mapIndex?: number[]; offset?: number; operator?: string[]; orderBy?: string[]; @@ -966,7 +959,7 @@ export const ensureUseTaskInstanceServiceGetTaskInstancesData = (queryClient: Qu updatedAtLt?: string; updatedAtLte?: string; versionNumber?: number[]; -}) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }), queryFn: () => TaskInstanceService.getTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) }); +}) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }), queryFn: () => TaskInstanceService.getTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) }); /** * Get Task Instance Try Details * Get task instance details by try number. @@ -1049,6 +1042,70 @@ export const ensureUseTaskInstanceServiceGetExternalLogUrlData = (queryClient: Q tryNumber: number; }) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetExternalLogUrlKeyFn({ dagId, dagRunId, mapIndex, taskId, tryNumber }), queryFn: () => TaskInstanceService.getExternalLogUrl({ dagId, dagRunId, mapIndex, taskId, tryNumber }) }); /** +* Get Hitl Detail +* Get a Human-in-the-loop detail of a specific task instance. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @returns HITLDetail Successful Response +* @throws ApiError +*/ +export const ensureUseTaskInstanceServiceGetHitlDetailData = (queryClient: QueryClient, { dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }), queryFn: () => TaskInstanceService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) }); +/** +* Get Hitl Details +* Get Human-in-the-loop details. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.limit +* @param data.offset +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, run_after, rendered_map_index, task_instance_operator, task_instance_state` +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskId +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.mapIndex +* @param data.state +* @param data.responseReceived +* @param data.respondedByUserId +* @param data.respondedByUserName +* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.createdAtGte +* @param data.createdAtGt +* @param data.createdAtLte +* @param data.createdAtLt +* @returns HITLDetailCollection Successful Response +* @throws ApiError +*/ +export const ensureUseTaskInstanceServiceGetHitlDetailsData = (queryClient: QueryClient, { bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + createdAtGt?: string; + createdAtGte?: string; + createdAtLt?: string; + createdAtLte?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + mapIndex?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }), queryFn: () => TaskInstanceService.getHitlDetails({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) }); +/** * Get Import Error * Get an import error. * @param data The data for the request. @@ -1065,15 +1122,17 @@ export const ensureUseImportErrorServiceGetImportErrorData = (queryClient: Query * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, timestamp, filename, bundle_name, stacktrace, import_error_id` +* @param data.filenamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns ImportErrorCollectionResponse Successful Response * @throws ApiError */ -export const ensureUseImportErrorServiceGetImportErrorsData = (queryClient: QueryClient, { limit, offset, orderBy }: { +export const ensureUseImportErrorServiceGetImportErrorsData = (queryClient: QueryClient, { filenamePattern, limit, offset, orderBy }: { + filenamePattern?: string; limit?: number; offset?: number; orderBy?: string[]; -} = {}) => queryClient.ensureQueryData({ queryKey: Common.UseImportErrorServiceGetImportErrorsKeyFn({ limit, offset, orderBy }), queryFn: () => ImportErrorService.getImportErrors({ limit, offset, orderBy }) }); +} = {}) => queryClient.ensureQueryData({ queryKey: Common.UseImportErrorServiceGetImportErrorsKeyFn({ filenamePattern, limit, offset, orderBy }), queryFn: () => ImportErrorService.getImportErrors({ filenamePattern, limit, offset, orderBy }) }); /** * Get Jobs * Get all jobs. @@ -1089,7 +1148,7 @@ export const ensureUseImportErrorServiceGetImportErrorsData = (queryClient: Quer * @param data.endDateLt * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, dag_id, state, job_type, start_date, end_date, latest_heartbeat, executor_class, hostname, unixname` * @param data.jobState * @param data.jobType * @param data.hostname @@ -1150,7 +1209,7 @@ export const ensureUsePoolServiceGetPoolData = (queryClient: QueryClient, { pool * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, pool, name` * @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns PoolCollectionResponse Successful Response * @throws ApiError @@ -1291,7 +1350,7 @@ export const ensureUseVariableServiceGetVariableData = (queryClient: QueryClient * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `key, id, _val, description, is_encrypted` * @param data.variableKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns VariableCollectionResponse Successful Response * @throws ApiError @@ -1327,7 +1386,7 @@ export const ensureUseDagVersionServiceGetDagVersionData = (queryClient: QueryCl * @param data.versionNumber * @param data.bundleName * @param data.bundleVersion -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, version_number, bundle_name, bundle_version` * @returns DAGVersionCollectionResponse Successful Response * @throws ApiError */ @@ -1341,60 +1400,6 @@ export const ensureUseDagVersionServiceGetDagVersionsData = (queryClient: QueryC versionNumber?: number; }) => queryClient.ensureQueryData({ queryKey: Common.UseDagVersionServiceGetDagVersionsKeyFn({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }), queryFn: () => DagVersionService.getDagVersions({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }) }); /** -* Get Hitl Detail -* Get a Human-in-the-loop detail of a specific task instance. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.mapIndex -* @returns HITLDetail Successful Response -* @throws ApiError -*/ -export const ensureUseHumanInTheLoopServiceGetHitlDetailData = (queryClient: QueryClient, { dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}) => queryClient.ensureQueryData({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }), queryFn: () => HumanInTheLoopService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) }); -/** -* Get Hitl Details -* Get Human-in-the-loop details. -* @param data The data for the request. -* @param data.limit -* @param data.offset -* @param data.orderBy -* @param data.dagId -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.dagRunId -* @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.state -* @param data.responseReceived -* @param data.respondedUserId -* @param data.respondedUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @returns HITLDetailCollection Successful Response -* @throws ApiError -*/ -export const ensureUseHumanInTheLoopServiceGetHitlDetailsData = (queryClient: QueryClient, { bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedUserId?: string[]; - respondedUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}) => queryClient.ensureQueryData({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }), queryFn: () => HumanInTheLoopService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) }); -/** * Get Health * @returns HealthInfoResponse Successful Response * @throws ApiError @@ -1505,7 +1510,7 @@ export const ensureUseStructureServiceStructureDataData = (queryClient: QueryCli * @param data.dagId * @param data.offset * @param data.limit -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `run_after, logical_date, start_date, end_date` * @param data.runAfterGte * @param data.runAfterGt * @param data.runAfterLte @@ -1534,7 +1539,7 @@ export const ensureUseGridServiceGetDagStructureData = (queryClient: QueryClient * @param data.dagId * @param data.offset * @param data.limit -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `run_after, logical_date, start_date, end_date` * @param data.runAfterGte * @param data.runAfterGt * @param data.runAfterLte diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts index 180eb82621082..f5bb69b23ef7b 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts @@ -1,7 +1,7 @@ // generated with @7nohe/openapi-react-query-codegen@1.6.2 import { type QueryClient } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskService, VariableService, VersionService, XcomService } from "../requests/services.gen"; +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskService, VariableService, VersionService, XcomService } from "../requests/services.gen"; import { DagRunState, DagWarningType } from "../requests/types.gen"; import * as Common from "./common"; /** @@ -14,7 +14,7 @@ import * as Common from "./common"; * @param data.uriPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @param data.dagIds * @param data.onlyActive -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name, uri, created_at, updated_at` * @returns AssetCollectionResponse Successful Response * @throws ApiError */ @@ -34,7 +34,7 @@ export const prefetchUseAssetServiceGetAssets = (queryClient: QueryClient, { dag * @param data.limit * @param data.offset * @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name` * @returns AssetAliasCollectionResponse Successful Response * @throws ApiError */ @@ -61,7 +61,7 @@ export const prefetchUseAssetServiceGetAssetAlias = (queryClient: QueryClient, { * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `source_task_id, source_dag_id, source_run_id, source_map_index, timestamp` * @param data.assetId * @param data.sourceDagId * @param data.sourceTaskId @@ -156,7 +156,7 @@ export const prefetchUseAssetServiceNextRunAssets = (queryClient: QueryClient, { * @param data.dagId * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id` * @returns BackfillCollectionResponse Successful Response * @throws ApiError */ @@ -181,7 +181,7 @@ export const prefetchUseBackfillServiceGetBackfill = (queryClient: QueryClient, * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id` * @param data.dagId * @param data.active * @returns BackfillCollectionResponse Successful Response @@ -211,7 +211,7 @@ export const prefetchUseConnectionServiceGetConnection = (queryClient: QueryClie * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `conn_id, conn_type, description, host, port, id, connection_id` * @param data.connectionIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns ConnectionCollectionResponse Successful Response * @throws ApiError @@ -286,7 +286,7 @@ export const prefetchUseDagRunServiceGetUpstreamAssetEvents = (queryClient: Quer * @param data.runType * @param data.state * @param data.dagVersion -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` * @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @param data.triggeringUserNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns DAGRunCollectionResponse Successful Response @@ -325,7 +325,7 @@ export const prefetchUseDagRunServiceGetDagRuns = (queryClient: QueryClient, { d }) => queryClient.prefetchQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ dagId, dagVersion, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ dagId, dagVersion, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. -* 🚧 This is an experimental endpoint and may change or be removed without notice. +* 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. * @param data The data for the request. * @param data.dagId * @param data.dagRunId @@ -342,7 +342,7 @@ export const prefetchUseDagRunServiceWaitDagRunUntilFinished = (queryClient: Que }) => queryClient.prefetchQuery({ queryKey: Common.UseDagRunServiceWaitDagRunUntilFinishedKeyFn({ dagId, dagRunId, interval, result }), queryFn: () => DagRunService.waitDagRunUntilFinished({ dagId, dagRunId, interval, result }) }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. -* 🚧 This is an experimental endpoint and may change or be removed without notice. +* 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. * @param data The data for the request. * @param data.dagId * @param data.dagRunId @@ -384,17 +384,6 @@ export const prefetchUseDagStatsServiceGetDagStats = (queryClient: QueryClient, dagIds?: string[]; } = {}) => queryClient.prefetchQuery({ queryKey: Common.UseDagStatsServiceGetDagStatsKeyFn({ dagIds }), queryFn: () => DagStatsService.getDagStats({ dagIds }) }); /** -* Get Dag Reports -* Get DAG report. -* @param data The data for the request. -* @param data.subdir -* @returns unknown Successful Response -* @throws ApiError -*/ -export const prefetchUseDagReportServiceGetDagReports = (queryClient: QueryClient, { subdir }: { - subdir: string; -}) => queryClient.prefetchQuery({ queryKey: Common.UseDagReportServiceGetDagReportsKeyFn({ subdir }), queryFn: () => DagReportService.getDagReports({ subdir }) }); -/** * Get Config * @param data The data for the request. * @param data.section @@ -435,7 +424,7 @@ export const prefetchUseConfigServiceGetConfigs = (queryClient: QueryClient) => * @param data.warningType * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, warning_type, message, timestamp` * @returns DAGWarningCollectionResponse Successful Response * @throws ApiError */ @@ -474,7 +463,7 @@ export const prefetchUseDagWarningServiceListDagWarnings = (queryClient: QueryCl * @param data.dagRunEndDateLte * @param data.dagRunEndDateLt * @param data.dagRunState -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` * @param data.isFavorite * @returns DAGCollectionResponse Successful Response * @throws ApiError @@ -535,7 +524,7 @@ export const prefetchUseDagServiceGetDagDetails = (queryClient: QueryClient, { d * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `name` * @param data.tagNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns DAGTagCollectionResponse Successful Response * @throws ApiError @@ -565,7 +554,7 @@ export const prefetchUseDagServiceGetDagTags = (queryClient: QueryClient, { limi * @param data.lastDagRunState * @param data.bundleName * @param data.bundleVersion -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` * @param data.isFavorite * @param data.hasAssetSchedule Filter Dags with asset-based scheduling * @param data.assetDependency Filter Dags by asset dependency (name or URI) @@ -622,7 +611,7 @@ export const prefetchUseEventLogServiceGetEventLog = (queryClient: QueryClient, * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, dttm, dag_id, task_id, run_id, event, logical_date, owner, extra, when, event_log_id` * @param data.dagId * @param data.taskId * @param data.runId @@ -750,13 +739,14 @@ export const prefetchUseTaskInstanceServiceGetTaskInstance = (queryClient: Query * @param data.versionNumber * @param data.tryNumber * @param data.operator +* @param data.mapIndex * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator, run_after, logical_date, data_interval_start, data_interval_end` * @returns TaskInstanceCollectionResponse Successful Response * @throws ApiError */ -export const prefetchUseTaskInstanceServiceGetMappedTaskInstances = (queryClient: QueryClient, { dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const prefetchUseTaskInstanceServiceGetMappedTaskInstances = (queryClient: QueryClient, { dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -773,6 +763,7 @@ export const prefetchUseTaskInstanceServiceGetMappedTaskInstances = (queryClient logicalDateGte?: string; logicalDateLt?: string; logicalDateLte?: string; + mapIndex?: number[]; offset?: number; operator?: string[]; orderBy?: string[]; @@ -794,7 +785,7 @@ export const prefetchUseTaskInstanceServiceGetMappedTaskInstances = (queryClient updatedAtLt?: string; updatedAtLte?: string; versionNumber?: number[]; -}) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetMappedTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }), queryFn: () => TaskInstanceService.getMappedTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) }); +}) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetMappedTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }), queryFn: () => TaskInstanceService.getMappedTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) }); /** * Get Task Instance Dependencies * Get dependencies blocking task from getting scheduled. @@ -921,13 +912,14 @@ export const prefetchUseTaskInstanceServiceGetMappedTaskInstance = (queryClient: * @param data.versionNumber * @param data.tryNumber * @param data.operator +* @param data.mapIndex * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator, logical_date, run_after, data_interval_start, data_interval_end` * @returns TaskInstanceCollectionResponse Successful Response * @throws ApiError */ -export const prefetchUseTaskInstanceServiceGetTaskInstances = (queryClient: QueryClient, { dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const prefetchUseTaskInstanceServiceGetTaskInstances = (queryClient: QueryClient, { dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -944,6 +936,7 @@ export const prefetchUseTaskInstanceServiceGetTaskInstances = (queryClient: Quer logicalDateGte?: string; logicalDateLt?: string; logicalDateLte?: string; + mapIndex?: number[]; offset?: number; operator?: string[]; orderBy?: string[]; @@ -966,7 +959,7 @@ export const prefetchUseTaskInstanceServiceGetTaskInstances = (queryClient: Quer updatedAtLt?: string; updatedAtLte?: string; versionNumber?: number[]; -}) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }), queryFn: () => TaskInstanceService.getTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) }); +}) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }), queryFn: () => TaskInstanceService.getTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) }); /** * Get Task Instance Try Details * Get task instance details by try number. @@ -1049,6 +1042,70 @@ export const prefetchUseTaskInstanceServiceGetExternalLogUrl = (queryClient: Que tryNumber: number; }) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetExternalLogUrlKeyFn({ dagId, dagRunId, mapIndex, taskId, tryNumber }), queryFn: () => TaskInstanceService.getExternalLogUrl({ dagId, dagRunId, mapIndex, taskId, tryNumber }) }); /** +* Get Hitl Detail +* Get a Human-in-the-loop detail of a specific task instance. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @returns HITLDetail Successful Response +* @throws ApiError +*/ +export const prefetchUseTaskInstanceServiceGetHitlDetail = (queryClient: QueryClient, { dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }), queryFn: () => TaskInstanceService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) }); +/** +* Get Hitl Details +* Get Human-in-the-loop details. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.limit +* @param data.offset +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, run_after, rendered_map_index, task_instance_operator, task_instance_state` +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskId +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.mapIndex +* @param data.state +* @param data.responseReceived +* @param data.respondedByUserId +* @param data.respondedByUserName +* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.createdAtGte +* @param data.createdAtGt +* @param data.createdAtLte +* @param data.createdAtLt +* @returns HITLDetailCollection Successful Response +* @throws ApiError +*/ +export const prefetchUseTaskInstanceServiceGetHitlDetails = (queryClient: QueryClient, { bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + createdAtGt?: string; + createdAtGte?: string; + createdAtLt?: string; + createdAtLte?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + mapIndex?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }), queryFn: () => TaskInstanceService.getHitlDetails({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) }); +/** * Get Import Error * Get an import error. * @param data The data for the request. @@ -1065,15 +1122,17 @@ export const prefetchUseImportErrorServiceGetImportError = (queryClient: QueryCl * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, timestamp, filename, bundle_name, stacktrace, import_error_id` +* @param data.filenamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns ImportErrorCollectionResponse Successful Response * @throws ApiError */ -export const prefetchUseImportErrorServiceGetImportErrors = (queryClient: QueryClient, { limit, offset, orderBy }: { +export const prefetchUseImportErrorServiceGetImportErrors = (queryClient: QueryClient, { filenamePattern, limit, offset, orderBy }: { + filenamePattern?: string; limit?: number; offset?: number; orderBy?: string[]; -} = {}) => queryClient.prefetchQuery({ queryKey: Common.UseImportErrorServiceGetImportErrorsKeyFn({ limit, offset, orderBy }), queryFn: () => ImportErrorService.getImportErrors({ limit, offset, orderBy }) }); +} = {}) => queryClient.prefetchQuery({ queryKey: Common.UseImportErrorServiceGetImportErrorsKeyFn({ filenamePattern, limit, offset, orderBy }), queryFn: () => ImportErrorService.getImportErrors({ filenamePattern, limit, offset, orderBy }) }); /** * Get Jobs * Get all jobs. @@ -1089,7 +1148,7 @@ export const prefetchUseImportErrorServiceGetImportErrors = (queryClient: QueryC * @param data.endDateLt * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, dag_id, state, job_type, start_date, end_date, latest_heartbeat, executor_class, hostname, unixname` * @param data.jobState * @param data.jobType * @param data.hostname @@ -1150,7 +1209,7 @@ export const prefetchUsePoolServiceGetPool = (queryClient: QueryClient, { poolNa * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, pool, name` * @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns PoolCollectionResponse Successful Response * @throws ApiError @@ -1291,7 +1350,7 @@ export const prefetchUseVariableServiceGetVariable = (queryClient: QueryClient, * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `key, id, _val, description, is_encrypted` * @param data.variableKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns VariableCollectionResponse Successful Response * @throws ApiError @@ -1327,7 +1386,7 @@ export const prefetchUseDagVersionServiceGetDagVersion = (queryClient: QueryClie * @param data.versionNumber * @param data.bundleName * @param data.bundleVersion -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, version_number, bundle_name, bundle_version` * @returns DAGVersionCollectionResponse Successful Response * @throws ApiError */ @@ -1341,60 +1400,6 @@ export const prefetchUseDagVersionServiceGetDagVersions = (queryClient: QueryCli versionNumber?: number; }) => queryClient.prefetchQuery({ queryKey: Common.UseDagVersionServiceGetDagVersionsKeyFn({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }), queryFn: () => DagVersionService.getDagVersions({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }) }); /** -* Get Hitl Detail -* Get a Human-in-the-loop detail of a specific task instance. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.mapIndex -* @returns HITLDetail Successful Response -* @throws ApiError -*/ -export const prefetchUseHumanInTheLoopServiceGetHitlDetail = (queryClient: QueryClient, { dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}) => queryClient.prefetchQuery({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }), queryFn: () => HumanInTheLoopService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) }); -/** -* Get Hitl Details -* Get Human-in-the-loop details. -* @param data The data for the request. -* @param data.limit -* @param data.offset -* @param data.orderBy -* @param data.dagId -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.dagRunId -* @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.state -* @param data.responseReceived -* @param data.respondedUserId -* @param data.respondedUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @returns HITLDetailCollection Successful Response -* @throws ApiError -*/ -export const prefetchUseHumanInTheLoopServiceGetHitlDetails = (queryClient: QueryClient, { bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedUserId?: string[]; - respondedUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}) => queryClient.prefetchQuery({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }), queryFn: () => HumanInTheLoopService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) }); -/** * Get Health * @returns HealthInfoResponse Successful Response * @throws ApiError @@ -1505,7 +1510,7 @@ export const prefetchUseStructureServiceStructureData = (queryClient: QueryClien * @param data.dagId * @param data.offset * @param data.limit -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `run_after, logical_date, start_date, end_date` * @param data.runAfterGte * @param data.runAfterGt * @param data.runAfterLte @@ -1534,7 +1539,7 @@ export const prefetchUseGridServiceGetDagStructure = (queryClient: QueryClient, * @param data.dagId * @param data.offset * @param data.limit -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `run_after, logical_date, start_date, end_date` * @param data.runAfterGte * @param data.runAfterGt * @param data.runAfterLte diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts index 1b133994fecf5..981558da7100c 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts @@ -1,7 +1,7 @@ // generated with @7nohe/openapi-react-query-codegen@1.6.2 import { UseMutationOptions, UseQueryOptions, useMutation, useQuery } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagParsingService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskService, VariableService, VersionService, XcomService } from "../requests/services.gen"; +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagParsingService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskService, VariableService, VersionService, XcomService } from "../requests/services.gen"; import { BackfillPostBody, BulkBody_BulkTaskInstanceBody_, BulkBody_ConnectionBody_, BulkBody_PoolBody_, BulkBody_VariableBody_, ClearTaskInstancesBody, ConnectionBody, CreateAssetEventsBody, DAGPatchBody, DAGRunClearBody, DAGRunPatchBody, DAGRunsBatchBody, DagRunState, DagWarningType, PatchTaskInstanceBody, PoolBody, PoolPatchBody, TaskInstancesBatchBody, TriggerDAGRunPostBody, UpdateHITLDetailPayload, VariableBody, XComCreateBody, XComUpdateBody } from "../requests/types.gen"; import * as Common from "./common"; /** @@ -14,7 +14,7 @@ import * as Common from "./common"; * @param data.uriPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @param data.dagIds * @param data.onlyActive -* @param data.orderBy +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name, uri, created_at, updated_at` * @returns AssetCollectionResponse Successful Response * @throws ApiError */ @@ -34,7 +34,7 @@ export const useAssetServiceGetAssets = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ dagId, dagVersion, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ dagId, dagVersion, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. -* 🚧 This is an experimental endpoint and may change or be removed without notice. +* 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. * @param data The data for the request. * @param data.dagId * @param data.dagRunId @@ -342,7 +342,7 @@ export const useDagRunServiceWaitDagRunUntilFinished = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagRunServiceWaitDagRunUntilFinishedKeyFn({ dagId, dagRunId, interval, result }, queryKey), queryFn: () => DagRunService.waitDagRunUntilFinished({ dagId, dagRunId, interval, result }) as TData, ...options }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. -* 🚧 This is an experimental endpoint and may change or be removed without notice. +* 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. * @param data The data for the request. * @param data.dagId * @param data.dagRunId @@ -384,17 +384,6 @@ export const useDagStatsServiceGetDagStats = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagStatsServiceGetDagStatsKeyFn({ dagIds }, queryKey), queryFn: () => DagStatsService.getDagStats({ dagIds }) as TData, ...options }); /** -* Get Dag Reports -* Get DAG report. -* @param data The data for the request. -* @param data.subdir -* @returns unknown Successful Response -* @throws ApiError -*/ -export const useDagReportServiceGetDagReports = = unknown[]>({ subdir }: { - subdir: string; -}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagReportServiceGetDagReportsKeyFn({ subdir }, queryKey), queryFn: () => DagReportService.getDagReports({ subdir }) as TData, ...options }); -/** * Get Config * @param data The data for the request. * @param data.section @@ -435,7 +424,7 @@ export const useConfigServiceGetConfigs = = unknown[]>({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const useTaskInstanceServiceGetMappedTaskInstances = = unknown[]>({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -773,6 +763,7 @@ export const useTaskInstanceServiceGetMappedTaskInstances = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseTaskInstanceServiceGetMappedTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }, queryKey), queryFn: () => TaskInstanceService.getMappedTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) as TData, ...options }); +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseTaskInstanceServiceGetMappedTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }, queryKey), queryFn: () => TaskInstanceService.getMappedTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) as TData, ...options }); /** * Get Task Instance Dependencies * Get dependencies blocking task from getting scheduled. @@ -921,13 +912,14 @@ export const useTaskInstanceServiceGetMappedTaskInstance = = unknown[]>({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const useTaskInstanceServiceGetTaskInstances = = unknown[]>({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -944,6 +936,7 @@ export const useTaskInstanceServiceGetTaskInstances = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }, queryKey), queryFn: () => TaskInstanceService.getTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) as TData, ...options }); +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }, queryKey), queryFn: () => TaskInstanceService.getTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) as TData, ...options }); /** * Get Task Instance Try Details * Get task instance details by try number. @@ -1049,6 +1042,70 @@ export const useTaskInstanceServiceGetExternalLogUrl = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseTaskInstanceServiceGetExternalLogUrlKeyFn({ dagId, dagRunId, mapIndex, taskId, tryNumber }, queryKey), queryFn: () => TaskInstanceService.getExternalLogUrl({ dagId, dagRunId, mapIndex, taskId, tryNumber }) as TData, ...options }); /** +* Get Hitl Detail +* Get a Human-in-the-loop detail of a specific task instance. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @returns HITLDetail Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceGetHitlDetail = = unknown[]>({ dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }, queryKey), queryFn: () => TaskInstanceService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) as TData, ...options }); +/** +* Get Hitl Details +* Get Human-in-the-loop details. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.limit +* @param data.offset +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, run_after, rendered_map_index, task_instance_operator, task_instance_state` +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskId +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.mapIndex +* @param data.state +* @param data.responseReceived +* @param data.respondedByUserId +* @param data.respondedByUserName +* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.createdAtGte +* @param data.createdAtGt +* @param data.createdAtLte +* @param data.createdAtLt +* @returns HITLDetailCollection Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceGetHitlDetails = = unknown[]>({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + createdAtGt?: string; + createdAtGte?: string; + createdAtLt?: string; + createdAtLte?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + mapIndex?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => TaskInstanceService.getHitlDetails({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) as TData, ...options }); +/** * Get Import Error * Get an import error. * @param data The data for the request. @@ -1065,15 +1122,17 @@ export const useImportErrorServiceGetImportError = = unknown[]>({ limit, offset, orderBy }: { +export const useImportErrorServiceGetImportErrors = = unknown[]>({ filenamePattern, limit, offset, orderBy }: { + filenamePattern?: string; limit?: number; offset?: number; orderBy?: string[]; -} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseImportErrorServiceGetImportErrorsKeyFn({ limit, offset, orderBy }, queryKey), queryFn: () => ImportErrorService.getImportErrors({ limit, offset, orderBy }) as TData, ...options }); +} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseImportErrorServiceGetImportErrorsKeyFn({ filenamePattern, limit, offset, orderBy }, queryKey), queryFn: () => ImportErrorService.getImportErrors({ filenamePattern, limit, offset, orderBy }) as TData, ...options }); /** * Get Jobs * Get all jobs. @@ -1089,7 +1148,7 @@ export const useImportErrorServiceGetImportErrors = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagVersionServiceGetDagVersionsKeyFn({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }, queryKey), queryFn: () => DagVersionService.getDagVersions({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }) as TData, ...options }); /** -* Get Hitl Detail -* Get a Human-in-the-loop detail of a specific task instance. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.mapIndex -* @returns HITLDetail Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceGetHitlDetail = = unknown[]>({ dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }, queryKey), queryFn: () => HumanInTheLoopService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) as TData, ...options }); -/** -* Get Hitl Details -* Get Human-in-the-loop details. -* @param data The data for the request. -* @param data.limit -* @param data.offset -* @param data.orderBy -* @param data.dagId -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.dagRunId -* @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.state -* @param data.responseReceived -* @param data.respondedUserId -* @param data.respondedUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @returns HITLDetailCollection Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceGetHitlDetails = = unknown[]>({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedUserId?: string[]; - respondedUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => HumanInTheLoopService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) as TData, ...options }); -/** * Get Health * @returns HealthInfoResponse Successful Response * @throws ApiError @@ -1505,7 +1510,7 @@ export const useStructureServiceStructureData = (options?: Omit({ mutationFn: ({ dagId, dagRunId, mapIndex, requestBody, taskId, updateMask }) => TaskInstanceService.patchTaskInstanceDryRun({ dagId, dagRunId, mapIndex, requestBody, taskId, updateMask }) as unknown as Promise, ...options }); /** +* Update Hitl Detail +* Update a Human-in-the-loop detail. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @param data.requestBody +* @returns HITLDetailResponse Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceUpdateHitlDetail = (options?: Omit, "mutationFn">) => useMutation({ mutationFn: ({ dagId, dagRunId, mapIndex, requestBody, taskId }) => TaskInstanceService.updateHitlDetail({ dagId, dagRunId, mapIndex, requestBody, taskId }) as unknown as Promise, ...options }); +/** * Patch Pool * Update a Pool. * @param data The data for the request. @@ -2230,31 +2260,6 @@ export const useVariableServiceBulkVariables = ({ mutationFn: ({ requestBody }) => VariableService.bulkVariables({ requestBody }) as unknown as Promise, ...options }); /** -* Update Hitl Detail -* Update a Human-in-the-loop detail. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.requestBody -* @param data.mapIndex -* @returns HITLDetailResponse Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceUpdateHitlDetail = (options?: Omit, "mutationFn">) => useMutation({ mutationFn: ({ dagId, dagRunId, mapIndex, requestBody, taskId }) => HumanInTheLoopService.updateHitlDetail({ dagId, dagRunId, mapIndex, requestBody, taskId }) as unknown as Promise, ...options }); -/** * Delete Asset Queued Events * Delete queued asset events for an asset. * @param data The data for the request. @@ -2354,7 +2359,7 @@ export const useDagServiceDeleteDag = (options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ dagId, dagVersion, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ dagId, dagVersion, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. -* 🚧 This is an experimental endpoint and may change or be removed without notice. +* 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. * @param data The data for the request. * @param data.dagId * @param data.dagRunId @@ -342,7 +342,7 @@ export const useDagRunServiceWaitDagRunUntilFinishedSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagRunServiceWaitDagRunUntilFinishedKeyFn({ dagId, dagRunId, interval, result }, queryKey), queryFn: () => DagRunService.waitDagRunUntilFinished({ dagId, dagRunId, interval, result }) as TData, ...options }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. -* 🚧 This is an experimental endpoint and may change or be removed without notice. +* 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. * @param data The data for the request. * @param data.dagId * @param data.dagRunId @@ -384,17 +384,6 @@ export const useDagStatsServiceGetDagStatsSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagStatsServiceGetDagStatsKeyFn({ dagIds }, queryKey), queryFn: () => DagStatsService.getDagStats({ dagIds }) as TData, ...options }); /** -* Get Dag Reports -* Get DAG report. -* @param data The data for the request. -* @param data.subdir -* @returns unknown Successful Response -* @throws ApiError -*/ -export const useDagReportServiceGetDagReportsSuspense = = unknown[]>({ subdir }: { - subdir: string; -}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagReportServiceGetDagReportsKeyFn({ subdir }, queryKey), queryFn: () => DagReportService.getDagReports({ subdir }) as TData, ...options }); -/** * Get Config * @param data The data for the request. * @param data.section @@ -435,7 +424,7 @@ export const useConfigServiceGetConfigsSuspense = = unknown[]>({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const useTaskInstanceServiceGetMappedTaskInstancesSuspense = = unknown[]>({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -773,6 +763,7 @@ export const useTaskInstanceServiceGetMappedTaskInstancesSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseTaskInstanceServiceGetMappedTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }, queryKey), queryFn: () => TaskInstanceService.getMappedTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) as TData, ...options }); +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseTaskInstanceServiceGetMappedTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }, queryKey), queryFn: () => TaskInstanceService.getMappedTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) as TData, ...options }); /** * Get Task Instance Dependencies * Get dependencies blocking task from getting scheduled. @@ -921,13 +912,14 @@ export const useTaskInstanceServiceGetMappedTaskInstanceSuspense = = unknown[]>({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { +export const useTaskInstanceServiceGetTaskInstancesSuspense = = unknown[]>({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }: { dagId: string; dagRunId: string; durationGt?: number; @@ -944,6 +936,7 @@ export const useTaskInstanceServiceGetTaskInstancesSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }, queryKey), queryFn: () => TaskInstanceService.getTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) as TData, ...options }); +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }, queryKey), queryFn: () => TaskInstanceService.getTaskInstances({ dagId, dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator, orderBy, pool, queue, runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte, startDateLt, startDateLte, state, taskDisplayNamePattern, taskId, tryNumber, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte, versionNumber }) as TData, ...options }); /** * Get Task Instance Try Details * Get task instance details by try number. @@ -1049,6 +1042,70 @@ export const useTaskInstanceServiceGetExternalLogUrlSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseTaskInstanceServiceGetExternalLogUrlKeyFn({ dagId, dagRunId, mapIndex, taskId, tryNumber }, queryKey), queryFn: () => TaskInstanceService.getExternalLogUrl({ dagId, dagRunId, mapIndex, taskId, tryNumber }) as TData, ...options }); /** +* Get Hitl Detail +* Get a Human-in-the-loop detail of a specific task instance. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @returns HITLDetail Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceGetHitlDetailSuspense = = unknown[]>({ dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }, queryKey), queryFn: () => TaskInstanceService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) as TData, ...options }); +/** +* Get Hitl Details +* Get Human-in-the-loop details. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.limit +* @param data.offset +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, run_after, rendered_map_index, task_instance_operator, task_instance_state` +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskId +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.mapIndex +* @param data.state +* @param data.responseReceived +* @param data.respondedByUserId +* @param data.respondedByUserName +* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.createdAtGte +* @param data.createdAtGt +* @param data.createdAtLte +* @param data.createdAtLt +* @returns HITLDetailCollection Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceGetHitlDetailsSuspense = = unknown[]>({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + createdAtGt?: string; + createdAtGte?: string; + createdAtLt?: string; + createdAtLte?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + mapIndex?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => TaskInstanceService.getHitlDetails({ bodySearch, createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, mapIndex, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) as TData, ...options }); +/** * Get Import Error * Get an import error. * @param data The data for the request. @@ -1065,15 +1122,17 @@ export const useImportErrorServiceGetImportErrorSuspense = = unknown[]>({ limit, offset, orderBy }: { +export const useImportErrorServiceGetImportErrorsSuspense = = unknown[]>({ filenamePattern, limit, offset, orderBy }: { + filenamePattern?: string; limit?: number; offset?: number; orderBy?: string[]; -} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseImportErrorServiceGetImportErrorsKeyFn({ limit, offset, orderBy }, queryKey), queryFn: () => ImportErrorService.getImportErrors({ limit, offset, orderBy }) as TData, ...options }); +} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseImportErrorServiceGetImportErrorsKeyFn({ filenamePattern, limit, offset, orderBy }, queryKey), queryFn: () => ImportErrorService.getImportErrors({ filenamePattern, limit, offset, orderBy }) as TData, ...options }); /** * Get Jobs * Get all jobs. @@ -1089,7 +1148,7 @@ export const useImportErrorServiceGetImportErrorsSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagVersionServiceGetDagVersionsKeyFn({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }, queryKey), queryFn: () => DagVersionService.getDagVersions({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }) as TData, ...options }); /** -* Get Hitl Detail -* Get a Human-in-the-loop detail of a specific task instance. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.mapIndex -* @returns HITLDetail Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceGetHitlDetailSuspense = = unknown[]>({ dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }, queryKey), queryFn: () => HumanInTheLoopService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) as TData, ...options }); -/** -* Get Hitl Details -* Get Human-in-the-loop details. -* @param data The data for the request. -* @param data.limit -* @param data.offset -* @param data.orderBy -* @param data.dagId -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.dagRunId -* @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.state -* @param data.responseReceived -* @param data.respondedUserId -* @param data.respondedUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @returns HITLDetailCollection Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceGetHitlDetailsSuspense = = unknown[]>({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedUserId?: string[]; - respondedUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => HumanInTheLoopService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedUserId, respondedUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) as TData, ...options }); -/** * Get Health * @returns HealthInfoResponse Successful Response * @throws ApiError @@ -1505,7 +1510,7 @@ export const useStructureServiceStructureDataSuspense = { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v2/dagReports', - query: { - subdir: data.subdir - }, - errors: { - 400: 'Bad Request', - 401: 'Unauthorized', - 403: 'Forbidden', - 422: 'Validation Error' - } - }); - } - -} - export class ConfigService { /** * Get Config @@ -1352,7 +1325,7 @@ export class DagWarningService { * @param data.warningType * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, warning_type, message, timestamp` * @returns DAGWarningCollectionResponse Successful Response * @throws ApiError */ @@ -1406,7 +1379,7 @@ export class DagService { * @param data.dagRunEndDateLte * @param data.dagRunEndDateLt * @param data.dagRunState - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` * @param data.isFavorite * @returns DAGCollectionResponse Successful Response * @throws ApiError @@ -1657,7 +1630,7 @@ export class DagService { * @param data The data for the request. * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `name` * @param data.tagNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns DAGTagCollectionResponse Successful Response * @throws ApiError @@ -1699,7 +1672,7 @@ export class DagService { * @param data.lastDagRunState * @param data.bundleName * @param data.bundleVersion - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` * @param data.isFavorite * @param data.hasAssetSchedule Filter Dags with asset-based scheduling * @param data.assetDependency Filter Dags by asset dependency (name or URI) @@ -1793,7 +1766,7 @@ export class EventLogService { * @param data The data for the request. * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, dttm, dag_id, task_id, run_id, event, logical_date, owner, extra, when, event_log_id` * @param data.dagId * @param data.taskId * @param data.runId @@ -1991,7 +1964,7 @@ export class TaskInstanceService { * @param data.dagRunId * @param data.taskId * @param data.mapIndex - * @returns null Successful Response + * @returns unknown Successful Response * @throws ApiError */ public static deleteTaskInstance(data: DeleteTaskInstanceData): CancelablePromise { @@ -2053,9 +2026,10 @@ export class TaskInstanceService { * @param data.versionNumber * @param data.tryNumber * @param data.operator + * @param data.mapIndex * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator, run_after, logical_date, data_interval_start, data_interval_end` * @returns TaskInstanceCollectionResponse Successful Response * @throws ApiError */ @@ -2100,6 +2074,7 @@ export class TaskInstanceService { version_number: data.versionNumber, try_number: data.tryNumber, operator: data.operator, + map_index: data.mapIndex, limit: data.limit, offset: data.offset, order_by: data.orderBy @@ -2347,9 +2322,10 @@ export class TaskInstanceService { * @param data.versionNumber * @param data.tryNumber * @param data.operator + * @param data.mapIndex * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator, logical_date, run_after, data_interval_start, data_interval_end` * @returns TaskInstanceCollectionResponse Successful Response * @throws ApiError */ @@ -2395,6 +2371,7 @@ export class TaskInstanceService { version_number: data.versionNumber, try_number: data.tryNumber, operator: data.operator, + map_index: data.mapIndex, limit: data.limit, offset: data.offset, order_by: data.orderBy @@ -2710,6 +2687,131 @@ export class TaskInstanceService { }); } + /** + * Update Hitl Detail + * Update a Human-in-the-loop detail. + * @param data The data for the request. + * @param data.dagId + * @param data.dagRunId + * @param data.taskId + * @param data.mapIndex + * @param data.requestBody + * @returns HITLDetailResponse Successful Response + * @throws ApiError + */ + public static updateHitlDetail(data: UpdateHitlDetailData): CancelablePromise { + return __request(OpenAPI, { + method: 'PATCH', + url: '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails', + path: { + dag_id: data.dagId, + dag_run_id: data.dagRunId, + task_id: data.taskId, + map_index: data.mapIndex + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 401: 'Unauthorized', + 403: 'Forbidden', + 404: 'Not Found', + 409: 'Conflict', + 422: 'Validation Error' + } + }); + } + + /** + * Get Hitl Detail + * Get a Human-in-the-loop detail of a specific task instance. + * @param data The data for the request. + * @param data.dagId + * @param data.dagRunId + * @param data.taskId + * @param data.mapIndex + * @returns HITLDetail Successful Response + * @throws ApiError + */ + public static getHitlDetail(data: GetHitlDetailData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails', + path: { + dag_id: data.dagId, + dag_run_id: data.dagRunId, + task_id: data.taskId, + map_index: data.mapIndex + }, + errors: { + 401: 'Unauthorized', + 403: 'Forbidden', + 404: 'Not Found', + 422: 'Validation Error' + } + }); + } + + /** + * Get Hitl Details + * Get Human-in-the-loop details. + * @param data The data for the request. + * @param data.dagId + * @param data.dagRunId + * @param data.limit + * @param data.offset + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, run_after, rendered_map_index, task_instance_operator, task_instance_state` + * @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.taskId + * @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.mapIndex + * @param data.state + * @param data.responseReceived + * @param data.respondedByUserId + * @param data.respondedByUserName + * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.createdAtGte + * @param data.createdAtGt + * @param data.createdAtLte + * @param data.createdAtLt + * @returns HITLDetailCollection Successful Response + * @throws ApiError + */ + public static getHitlDetails(data: GetHitlDetailsData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/hitlDetails', + path: { + dag_id: data.dagId, + dag_run_id: data.dagRunId + }, + query: { + limit: data.limit, + offset: data.offset, + order_by: data.orderBy, + dag_id_pattern: data.dagIdPattern, + task_id: data.taskId, + task_id_pattern: data.taskIdPattern, + map_index: data.mapIndex, + state: data.state, + response_received: data.responseReceived, + responded_by_user_id: data.respondedByUserId, + responded_by_user_name: data.respondedByUserName, + subject_search: data.subjectSearch, + body_search: data.bodySearch, + created_at_gte: data.createdAtGte, + created_at_gt: data.createdAtGt, + created_at_lte: data.createdAtLte, + created_at_lt: data.createdAtLt + }, + errors: { + 401: 'Unauthorized', + 403: 'Forbidden', + 422: 'Validation Error' + } + }); + } + } export class ImportErrorService { @@ -2743,7 +2845,8 @@ export class ImportErrorService { * @param data The data for the request. * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, timestamp, filename, bundle_name, stacktrace, import_error_id` + * @param data.filenamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns ImportErrorCollectionResponse Successful Response * @throws ApiError */ @@ -2754,7 +2857,8 @@ export class ImportErrorService { query: { limit: data.limit, offset: data.offset, - order_by: data.orderBy + order_by: data.orderBy, + filename_pattern: data.filenamePattern }, errors: { 401: 'Unauthorized', @@ -2782,7 +2886,7 @@ export class JobService { * @param data.endDateLt * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, dag_id, state, job_type, start_date, end_date, latest_heartbeat, executor_class, hostname, unixname` * @param data.jobState * @param data.jobType * @param data.hostname @@ -2954,7 +3058,7 @@ export class PoolService { * @param data The data for the request. * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, pool, name` * @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns PoolCollectionResponse Successful Response * @throws ApiError @@ -3374,7 +3478,7 @@ export class VariableService { * @param data The data for the request. * @param data.limit * @param data.offset - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `key, id, _val, description, is_encrypted` * @param data.variableKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns VariableCollectionResponse Successful Response * @throws ApiError @@ -3450,7 +3554,7 @@ export class DagParsingService { * Request re-parsing a DAG file. * @param data The data for the request. * @param data.fileToken - * @returns null Successful Response + * @returns unknown Successful Response * @throws ApiError */ public static reparseDagFile(data: ReparseDagFileData): CancelablePromise { @@ -3510,7 +3614,7 @@ export class DagVersionService { * @param data.versionNumber * @param data.bundleName * @param data.bundleVersion - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, version_number, bundle_name, bundle_version` * @returns DAGVersionCollectionResponse Successful Response * @throws ApiError */ @@ -3540,126 +3644,6 @@ export class DagVersionService { } -export class HumanInTheLoopService { - /** - * Update Hitl Detail - * Update a Human-in-the-loop detail. - * @param data The data for the request. - * @param data.dagId - * @param data.dagRunId - * @param data.taskId - * @param data.requestBody - * @param data.mapIndex - * @returns HITLDetailResponse Successful Response - * @throws ApiError - */ - public static updateHitlDetail(data: UpdateHitlDetailData): CancelablePromise { - return __request(OpenAPI, { - method: 'PATCH', - url: '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}', - path: { - dag_id: data.dagId, - dag_run_id: data.dagRunId, - task_id: data.taskId - }, - query: { - map_index: data.mapIndex - }, - body: data.requestBody, - mediaType: 'application/json', - errors: { - 401: 'Unauthorized', - 403: 'Forbidden', - 404: 'Not Found', - 409: 'Conflict', - 422: 'Validation Error' - } - }); - } - - /** - * Get Hitl Detail - * Get a Human-in-the-loop detail of a specific task instance. - * @param data The data for the request. - * @param data.dagId - * @param data.dagRunId - * @param data.taskId - * @param data.mapIndex - * @returns HITLDetail Successful Response - * @throws ApiError - */ - public static getHitlDetail(data: GetHitlDetailData): CancelablePromise { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}', - path: { - dag_id: data.dagId, - dag_run_id: data.dagRunId, - task_id: data.taskId - }, - query: { - map_index: data.mapIndex - }, - errors: { - 401: 'Unauthorized', - 403: 'Forbidden', - 404: 'Not Found', - 422: 'Validation Error' - } - }); - } - - /** - * Get Hitl Details - * Get Human-in-the-loop details. - * @param data The data for the request. - * @param data.limit - * @param data.offset - * @param data.orderBy - * @param data.dagId - * @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - * @param data.dagRunId - * @param data.taskId - * @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - * @param data.state - * @param data.responseReceived - * @param data.respondedUserId - * @param data.respondedUserName - * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - * @returns HITLDetailCollection Successful Response - * @throws ApiError - */ - public static getHitlDetails(data: GetHitlDetailsData = {}): CancelablePromise { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v2/hitlDetails/', - query: { - limit: data.limit, - offset: data.offset, - order_by: data.orderBy, - dag_id: data.dagId, - dag_id_pattern: data.dagIdPattern, - dag_run_id: data.dagRunId, - task_id: data.taskId, - task_id_pattern: data.taskIdPattern, - state: data.state, - response_received: data.responseReceived, - responded_user_id: data.respondedUserId, - responded_user_name: data.respondedUserName, - subject_search: data.subjectSearch, - body_search: data.bodySearch - }, - errors: { - 401: 'Unauthorized', - 403: 'Forbidden', - 422: 'Validation Error' - } - }); - } - -} - export class MonitorService { /** * Get Health @@ -3883,7 +3867,7 @@ export class GridService { * @param data.dagId * @param data.offset * @param data.limit - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `run_after, logical_date, start_date, end_date` * @param data.runAfterGte * @param data.runAfterGt * @param data.runAfterLte @@ -3926,7 +3910,7 @@ export class GridService { * @param data.dagId * @param data.offset * @param data.limit - * @param data.orderBy + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `run_after, logical_date, start_date, end_date` * @param data.runAfterGte * @param data.runAfterGt * @param data.runAfterLte diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts index c1320c1c63512..c7df52ea691dd 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts @@ -380,6 +380,9 @@ export type ClearTaskInstancesBody = { only_failed?: boolean; only_running?: boolean; reset_dag_runs?: boolean; + /** + * A list of `task_id` or [`task_id`, `map_index`]. If only the `task_id` is provided for a mapped task, all of its map indices will be targeted. + */ task_ids?: Array<(string | [ string, number @@ -940,10 +943,10 @@ export type HITLDetail = { params?: { [key: string]: unknown; }; - respondents?: Array<(string)> | null; - responded_user_id?: string | null; - responded_user_name?: string | null; - response_at?: string | null; + assigned_users?: Array; + created_at: string; + responded_by_user?: HITLUser | null; + responded_at?: string | null; chosen_options?: Array<(string)> | null; params_input?: { [key: string]: unknown; @@ -963,15 +966,22 @@ export type HITLDetailCollection = { * Response of updating a Human-in-the-loop detail. */ export type HITLDetailResponse = { - responded_user_id: string; - responded_user_name: string; - response_at: string; + responded_by: HITLUser; + responded_at: string; chosen_options: Array<(string)>; params_input?: { [key: string]: unknown; }; }; +/** + * Schema for a Human-in-the-loop users. + */ +export type HITLUser = { + id: string; + name: string; +}; + /** * HTTPException Model used for error response. */ @@ -1970,6 +1980,9 @@ export type GetAssetsData = { namePattern?: string | null; offset?: number; onlyActive?: boolean; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name, uri, created_at, updated_at` + */ orderBy?: Array<(string)>; /** * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. @@ -1986,6 +1999,9 @@ export type GetAssetAliasesData = { */ namePattern?: string | null; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name` + */ orderBy?: Array<(string)>; }; @@ -2001,6 +2017,9 @@ export type GetAssetEventsData = { assetId?: number | null; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `source_task_id, source_dag_id, source_run_id, source_map_index, timestamp` + */ orderBy?: Array<(string)>; sourceDagId?: string | null; sourceMapIndex?: number | null; @@ -2088,6 +2107,9 @@ export type ListBackfillsData = { dagId: string; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id` + */ orderBy?: Array<(string)>; }; @@ -2134,6 +2156,9 @@ export type ListBackfillsUiData = { dagId?: string | null; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id` + */ orderBy?: Array<(string)>; }; @@ -2166,6 +2191,9 @@ export type GetConnectionsData = { connectionIdPattern?: string | null; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `conn_id, conn_type, description, host, port, id, connection_id` + */ orderBy?: Array<(string)>; }; @@ -2244,6 +2272,9 @@ export type GetDagRunsData = { logicalDateLt?: string | null; logicalDateLte?: string | null; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` + */ orderBy?: Array<(string)>; runAfterGt?: string | null; runAfterGte?: string | null; @@ -2314,12 +2345,6 @@ export type GetDagStatsData = { export type GetDagStatsResponse = DagStatsCollectionResponse; -export type GetDagReportsData = { - subdir: string; -}; - -export type GetDagReportsResponse = unknown; - export type GetConfigData = { accept?: 'application/json' | 'text/plain' | '*/*'; section?: string | null; @@ -2341,6 +2366,9 @@ export type ListDagWarningsData = { dagId?: string | null; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, warning_type, message, timestamp` + */ orderBy?: Array<(string)>; warningType?: DagWarningType | null; }; @@ -2384,6 +2412,9 @@ export type GetDagsData = { lastDagRunState?: DagRunState | null; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` + */ orderBy?: Array<(string)>; owners?: Array<(string)>; paused?: boolean | null; @@ -2452,6 +2483,9 @@ export type UnfavoriteDagResponse = void; export type GetDagTagsData = { limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `name` + */ orderBy?: Array<(string)>; /** * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. @@ -2492,6 +2526,9 @@ export type GetDagsUiData = { lastDagRunState?: DagRunState | null; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` + */ orderBy?: Array<(string)>; owners?: Array<(string)>; paused?: boolean | null; @@ -2531,6 +2568,9 @@ export type GetEventLogsData = { limit?: number; mapIndex?: number | null; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, dttm, dag_id, task_id, run_id, event, logical_date, owner, extra, when, event_log_id` + */ orderBy?: Array<(string)>; owner?: string | null; /** @@ -2587,7 +2627,7 @@ export type DeleteTaskInstanceData = { taskId: string; }; -export type DeleteTaskInstanceResponse = null; +export type DeleteTaskInstanceResponse = unknown; export type GetMappedTaskInstancesData = { dagId: string; @@ -2606,8 +2646,12 @@ export type GetMappedTaskInstancesData = { logicalDateGte?: string | null; logicalDateLt?: string | null; logicalDateLte?: string | null; + mapIndex?: Array<(number)>; offset?: number; operator?: Array<(string)>; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator, run_after, logical_date, data_interval_start, data_interval_end` + */ orderBy?: Array<(string)>; pool?: Array<(string)>; queue?: Array<(string)>; @@ -2704,8 +2748,12 @@ export type GetTaskInstancesData = { logicalDateGte?: string | null; logicalDateLt?: string | null; logicalDateLte?: string | null; + mapIndex?: Array<(number)>; offset?: number; operator?: Array<(string)>; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator, logical_date, run_after, data_interval_start, data_interval_end` + */ orderBy?: Array<(string)>; pool?: Array<(string)>; queue?: Array<(string)>; @@ -2821,6 +2869,64 @@ export type GetExternalLogUrlData = { export type GetExternalLogUrlResponse = ExternalLogUrlResponse; +export type UpdateHitlDetailData = { + dagId: string; + dagRunId: string; + mapIndex: number; + requestBody: UpdateHITLDetailPayload; + taskId: string; +}; + +export type UpdateHitlDetailResponse = HITLDetailResponse; + +export type GetHitlDetailData = { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}; + +export type GetHitlDetailResponse = HITLDetail; + +export type GetHitlDetailsData = { + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + bodySearch?: string | null; + createdAtGt?: string | null; + createdAtGte?: string | null; + createdAtLt?: string | null; + createdAtLte?: string | null; + dagId: string; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + dagIdPattern?: string | null; + dagRunId: string; + limit?: number; + mapIndex?: number | null; + offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, run_after, rendered_map_index, task_instance_operator, task_instance_state` + */ + orderBy?: Array<(string)>; + respondedByUserId?: Array<(string)>; + respondedByUserName?: Array<(string)>; + responseReceived?: boolean | null; + state?: Array<(string)>; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + subjectSearch?: string | null; + taskId?: string | null; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + taskIdPattern?: string | null; +}; + +export type GetHitlDetailsResponse = HITLDetailCollection; + export type GetImportErrorData = { importErrorId: number; }; @@ -2828,8 +2934,15 @@ export type GetImportErrorData = { export type GetImportErrorResponse = ImportErrorResponse; export type GetImportErrorsData = { + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + filenamePattern?: string | null; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, timestamp, filename, bundle_name, stacktrace, import_error_id` + */ orderBy?: Array<(string)>; }; @@ -2847,6 +2960,9 @@ export type GetJobsData = { jobType?: string | null; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, dag_id, state, job_type, start_date, end_date, latest_heartbeat, executor_class, hostname, unixname` + */ orderBy?: Array<(string)>; startDateGt?: string | null; startDateGte?: string | null; @@ -2888,6 +3004,9 @@ export type PatchPoolResponse = PoolResponse; export type GetPoolsData = { limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, pool, name` + */ orderBy?: Array<(string)>; /** * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. @@ -3021,6 +3140,9 @@ export type PatchVariableResponse = VariableResponse; export type GetVariablesData = { limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `key, id, _val, description, is_encrypted` + */ orderBy?: Array<(string)>; /** * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. @@ -3046,7 +3168,7 @@ export type ReparseDagFileData = { fileToken: string; }; -export type ReparseDagFileResponse = null; +export type ReparseDagFileResponse = unknown; export type GetDagVersionData = { dagId: string; @@ -3061,61 +3183,14 @@ export type GetDagVersionsData = { dagId: string; limit?: number; offset?: number; - orderBy?: Array<(string)>; - versionNumber?: number; -}; - -export type GetDagVersionsResponse = DAGVersionCollectionResponse; - -export type UpdateHitlDetailData = { - dagId: string; - dagRunId: string; - mapIndex?: number; - requestBody: UpdateHITLDetailPayload; - taskId: string; -}; - -export type UpdateHitlDetailResponse = HITLDetailResponse; - -export type GetHitlDetailData = { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}; - -export type GetHitlDetailResponse = HITLDetail; - -export type GetHitlDetailsData = { /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, version_number, bundle_name, bundle_version` */ - bodySearch?: string | null; - dagId?: string | null; - /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - */ - dagIdPattern?: string | null; - dagRunId?: string; - limit?: number; - offset?: number; orderBy?: Array<(string)>; - respondedUserId?: Array<(string)>; - respondedUserName?: Array<(string)>; - responseReceived?: boolean | null; - state?: Array<(string)>; - /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - */ - subjectSearch?: string | null; - taskId?: string | null; - /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - */ - taskIdPattern?: string | null; + versionNumber?: number; }; -export type GetHitlDetailsResponse = HITLDetailCollection; +export type GetDagVersionsResponse = DAGVersionCollectionResponse; export type GetHealthResponse = HealthInfoResponse; @@ -3171,6 +3246,9 @@ export type GetDagStructureData = { dagId: string; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `run_after, logical_date, start_date, end_date` + */ orderBy?: Array<(string)>; runAfterGt?: string | null; runAfterGte?: string | null; @@ -3189,6 +3267,9 @@ export type GetGridRunsData = { dagId: string; limit?: number; offset?: number; + /** + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `run_after, logical_date, start_date, end_date` + */ orderBy?: Array<(string)>; runAfterGt?: string | null; runAfterGte?: string | null; @@ -4340,33 +4421,6 @@ export type $OpenApiTs = { }; }; }; - '/api/v2/dagReports': { - get: { - req: GetDagReportsData; - res: { - /** - * Successful Response - */ - 200: unknown; - /** - * Bad Request - */ - 400: HTTPExceptionResponse; - /** - * Unauthorized - */ - 401: HTTPExceptionResponse; - /** - * Forbidden - */ - 403: HTTPExceptionResponse; - /** - * Validation Error - */ - 422: HTTPValidationError; - }; - }; - }; '/api/v2/config': { get: { req: GetConfigData; @@ -4895,7 +4949,7 @@ export type $OpenApiTs = { /** * Successful Response */ - 200: null; + 200: unknown; /** * Unauthorized */ @@ -5386,6 +5440,85 @@ export type $OpenApiTs = { }; }; }; + '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails': { + patch: { + req: UpdateHitlDetailData; + res: { + /** + * Successful Response + */ + 200: HITLDetailResponse; + /** + * Unauthorized + */ + 401: HTTPExceptionResponse; + /** + * Forbidden + */ + 403: HTTPExceptionResponse; + /** + * Not Found + */ + 404: HTTPExceptionResponse; + /** + * Conflict + */ + 409: HTTPExceptionResponse; + /** + * Validation Error + */ + 422: HTTPValidationError; + }; + }; + get: { + req: GetHitlDetailData; + res: { + /** + * Successful Response + */ + 200: HITLDetail; + /** + * Unauthorized + */ + 401: HTTPExceptionResponse; + /** + * Forbidden + */ + 403: HTTPExceptionResponse; + /** + * Not Found + */ + 404: HTTPExceptionResponse; + /** + * Validation Error + */ + 422: HTTPValidationError; + }; + }; + }; + '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/hitlDetails': { + get: { + req: GetHitlDetailsData; + res: { + /** + * Successful Response + */ + 200: HITLDetailCollection; + /** + * Unauthorized + */ + 401: HTTPExceptionResponse; + /** + * Forbidden + */ + 403: HTTPExceptionResponse; + /** + * Validation Error + */ + 422: HTTPValidationError; + }; + }; + }; '/api/v2/importErrors/{import_error_id}': { get: { req: GetImportErrorData; @@ -6024,7 +6157,7 @@ export type $OpenApiTs = { /** * Successful Response */ - 201: null; + 201: unknown; /** * Unauthorized */ @@ -6098,85 +6231,6 @@ export type $OpenApiTs = { }; }; }; - '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}': { - patch: { - req: UpdateHitlDetailData; - res: { - /** - * Successful Response - */ - 200: HITLDetailResponse; - /** - * Unauthorized - */ - 401: HTTPExceptionResponse; - /** - * Forbidden - */ - 403: HTTPExceptionResponse; - /** - * Not Found - */ - 404: HTTPExceptionResponse; - /** - * Conflict - */ - 409: HTTPExceptionResponse; - /** - * Validation Error - */ - 422: HTTPValidationError; - }; - }; - get: { - req: GetHitlDetailData; - res: { - /** - * Successful Response - */ - 200: HITLDetail; - /** - * Unauthorized - */ - 401: HTTPExceptionResponse; - /** - * Forbidden - */ - 403: HTTPExceptionResponse; - /** - * Not Found - */ - 404: HTTPExceptionResponse; - /** - * Validation Error - */ - 422: HTTPValidationError; - }; - }; - }; - '/api/v2/hitlDetails/': { - get: { - req: GetHitlDetailsData; - res: { - /** - * Successful Response - */ - 200: HITLDetailCollection; - /** - * Unauthorized - */ - 401: HTTPExceptionResponse; - /** - * Forbidden - */ - 403: HTTPExceptionResponse; - /** - * Validation Error - */ - 422: HTTPValidationError; - }; - }; - }; '/api/v2/monitor/health': { get: { res: { diff --git a/airflow-core/src/airflow/ui/package.json b/airflow-core/src/airflow/ui/package.json index 7981915048101..36964757d12ae 100644 --- a/airflow-core/src/airflow/ui/package.json +++ b/airflow-core/src/airflow/ui/package.json @@ -24,12 +24,14 @@ "@tanstack/react-table": "^8.21.3", "@tanstack/react-virtual": "^3.13.8", "@types/debounce-promise": "^3.1.9", + "@types/react-resizable": "^3.0.8", "@uiw/codemirror-themes-all": "^4.23.12", "@uiw/react-codemirror": "^4.23.12", "@visx/group": "^3.12.0", "@visx/shape": "^3.12.0", "@xyflow/react": "^12.4.4", - "axios": "^1.11.0", + "anser": "^2.3.2", + "axios": "^1.12.0", "chakra-react-select": "6.1.0", "chart.js": "^4.4.9", "chartjs-adapter-dayjs-4": "^1.0.4", @@ -41,11 +43,11 @@ "i18next": "^25.1.2", "i18next-browser-languagedetector": "^8.1.0", "i18next-http-backend": "^3.0.2", - "next-themes": "^0.3.0", + "next-themes": "^0.4.6", "node-sql-parser": "^5.3.10", - "react": "^18.3.1", + "react": "^19.1.1", "react-chartjs-2": "^5.3.0", - "react-dom": "^18.3.1", + "react-dom": "^19.1.1", "react-hook-form": "^7.56.1", "react-hotkeys-hook": "^4.6.1", "react-i18next": "^15.5.1", @@ -53,6 +55,7 @@ "react-innertext": "^1.1.5", "react-json-view": "^1.21.3", "react-markdown": "^9.1.0", + "react-resizable": "^3.0.5", "react-resizable-panels": "^2.1.7", "react-router-dom": "^6.30.0", "react-syntax-highlighter": "^15.6.1", @@ -85,7 +88,7 @@ "eslint-plugin-perfectionist": "^4.12.3", "eslint-plugin-prettier": "^5.2.6", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-unicorn": "^55.0.0", "globals": "^15.15.0", diff --git a/airflow-core/src/airflow/ui/pnpm-lock.yaml b/airflow-core/src/airflow/ui/pnpm-lock.yaml index 6f7806f784bee..0c69b23216971 100644 --- a/airflow-core/src/airflow/ui/pnpm-lock.yaml +++ b/airflow-core/src/airflow/ui/pnpm-lock.yaml @@ -13,46 +13,52 @@ importers: version: 2.3.4 '@chakra-ui/react': specifier: ^3.20.0 - version: 3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@codemirror/lang-json': specifier: ^6.0.1 version: 6.0.1 '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@18.3.19)(react@18.3.1) + version: 11.14.0(@types/react@18.3.19)(react@19.1.1) '@tanstack/react-query': specifier: ^5.75.1 - version: 5.75.4(react@18.3.1) + version: 5.75.4(react@19.1.1) '@tanstack/react-table': specifier: ^8.21.3 - version: 8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 8.21.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@tanstack/react-virtual': specifier: ^3.13.8 - version: 3.13.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.13.8(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@types/debounce-promise': specifier: ^3.1.9 version: 3.1.9 + '@types/react-resizable': + specifier: ^3.0.8 + version: 3.0.8 '@uiw/codemirror-themes-all': specifier: ^4.23.12 version: 4.23.12(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.4) '@uiw/react-codemirror': specifier: ^4.23.12 - version: 4.23.12(@babel/runtime@7.26.10)(@codemirror/autocomplete@6.18.2(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.4)(@lezer/common@1.2.3))(@codemirror/language@6.11.0)(@codemirror/lint@6.8.2)(@codemirror/search@6.5.6)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.4)(codemirror@6.0.1(@lezer/common@1.2.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.23.12(@babel/runtime@7.28.4)(@codemirror/autocomplete@6.18.2(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.4)(@lezer/common@1.2.3))(@codemirror/language@6.11.0)(@codemirror/lint@6.8.2)(@codemirror/search@6.5.6)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.4)(codemirror@6.0.1(@lezer/common@1.2.3))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@visx/group': specifier: ^3.12.0 - version: 3.12.0(react@18.3.1) + version: 3.12.0(react@19.1.1) '@visx/shape': specifier: ^3.12.0 - version: 3.12.0(react@18.3.1) + version: 3.12.0(react@19.1.1) '@xyflow/react': specifier: ^12.4.4 - version: 12.4.4(@types/react@18.3.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 12.4.4(@types/react@18.3.19)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + anser: + specifier: ^2.3.2 + version: 2.3.2 axios: - specifier: ^1.11.0 - version: 1.11.0 + specifier: ^1.12.0 + version: 1.12.0 chakra-react-select: specifier: 6.1.0 - version: 6.1.0(@chakra-ui/react@3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.19)(next-themes@0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 6.1.0(@chakra-ui/react@3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@18.3.19)(next-themes@0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) chart.js: specifier: ^4.4.9 version: 4.4.9 @@ -84,65 +90,68 @@ importers: specifier: ^3.0.2 version: 3.0.2 next-themes: - specifier: ^0.3.0 - version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) node-sql-parser: specifier: ^5.3.10 version: 5.3.10 react: - specifier: ^18.3.1 - version: 18.3.1 + specifier: ^19.1.1 + version: 19.1.1 react-chartjs-2: specifier: ^5.3.0 - version: 5.3.0(chart.js@4.4.9)(react@18.3.1) + version: 5.3.0(chart.js@4.4.9)(react@19.1.1) react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) + specifier: ^19.1.1 + version: 19.1.1(react@19.1.1) react-hook-form: specifier: ^7.56.1 - version: 7.56.2(react@18.3.1) + version: 7.56.2(react@19.1.1) react-hotkeys-hook: specifier: ^4.6.1 - version: 4.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.6.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-i18next: specifier: ^15.5.1 - version: 15.5.1(i18next@25.1.2(typescript@5.8.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + version: 15.5.1(i18next@25.1.2(typescript@5.8.3))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.8.3) react-icons: specifier: ^5.5.0 - version: 5.5.0(react@18.3.1) + version: 5.5.0(react@19.1.1) react-innertext: specifier: ^1.1.5 - version: 1.1.5(@types/react@18.3.19)(react@18.3.1) + version: 1.1.5(@types/react@18.3.19)(react@19.1.1) react-json-view: specifier: ^1.21.3 - version: 1.21.3(@types/react@18.3.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.21.3(@types/react@18.3.19)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-markdown: specifier: ^9.1.0 - version: 9.1.0(@types/react@18.3.19)(react@18.3.1) + version: 9.1.0(@types/react@18.3.19)(react@19.1.1) + react-resizable: + specifier: ^3.0.5 + version: 3.0.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-resizable-panels: specifier: ^2.1.7 - version: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.1.7(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-router-dom: specifier: ^6.30.0 - version: 6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 6.30.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-syntax-highlighter: specifier: ^15.6.1 - version: 15.6.1(react@18.3.1) + version: 15.6.1(react@19.1.1) remark-gfm: specifier: ^4.0.1 version: 4.0.1 use-debounce: specifier: ^10.0.4 - version: 10.0.4(react@18.3.1) + version: 10.0.4(react@19.1.1) usehooks-ts: specifier: ^3.1.1 - version: 3.1.1(react@18.3.1) + version: 3.1.1(react@19.1.1) yaml: specifier: ^2.6.1 version: 2.8.0 zustand: specifier: ^5.0.4 - version: 5.0.4(@types/react@18.3.19)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + version: 5.0.4(@types/react@18.3.19)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) devDependencies: '@7nohe/openapi-react-query-codegen': specifier: ^1.6.2 @@ -164,7 +173,7 @@ importers: version: 6.6.3 '@testing-library/react': specifier: ^16.3.0 - version: 16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@18.3.5(@types/react@18.3.19))(@types/react@18.3.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@18.3.5(@types/react@18.3.19))(@types/react@18.3.19)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@trivago/prettier-plugin-sort-imports': specifier: ^4.3.0 version: 4.3.0(prettier@3.5.3) @@ -211,8 +220,8 @@ importers: specifier: ^7.37.5 version: 7.37.5(eslint@9.26.0(jiti@1.21.7)) eslint-plugin-react-hooks: - specifier: ^4.6.2 - version: 4.6.2(eslint@9.26.0(jiti@1.21.7)) + specifier: ^5.2.0 + version: 5.2.0(eslint@9.26.0(jiti@1.21.7)) eslint-plugin-react-refresh: specifier: ^0.4.20 version: 0.4.20(eslint@9.26.0(jiti@1.21.7)) @@ -342,6 +351,10 @@ packages: resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + '@babel/template@7.26.9': resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} engines: {node: '>=6.9.0'} @@ -1165,8 +1178,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/lodash@4.17.16': - resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -1194,6 +1207,9 @@ packages: peerDependencies: '@types/react': ^18.0.0 + '@types/react-resizable@3.0.8': + resolution: {integrity: sha512-Pcvt2eGA7KNXldt1hkhVhAgZ8hK41m0mp89mFgQi7LAAEZiaLgm4fHJ5zbJZ/4m2LVaAyYrrRRv1LHDcrGQanA==} + '@types/react-syntax-highlighter@15.5.13': resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==} @@ -1749,9 +1765,17 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + anser@2.3.2: + resolution: {integrity: sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -1840,6 +1864,7 @@ packages: atlassian-openapi@1.0.21: resolution: {integrity: sha512-1OnnoY2CQYHgXrce/06BltL7fox+uVY7brHUInyFbMpTURjTNIGXfLQxVDRo/2On7ryyKzkX7FfNApYhXw7f+w==} + deprecated: 'DEPRECATED: atlassian-openapi has moved to @atlassian/atlassian-openapi. The latest version is 1.0.6. Please update your dependency.' available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} @@ -1849,8 +1874,8 @@ packages: resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} engines: {node: '>=4'} - axios@1.11.0: - resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} + axios@1.12.0: + resolution: {integrity: sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -2035,6 +2060,10 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + code-block-writer@13.0.3: resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} @@ -2263,8 +2292,8 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - destr@2.0.3: - resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -2282,8 +2311,8 @@ packages: dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} - dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} dunder-proto@1.0.1: @@ -2436,11 +2465,11 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-react-hooks@4.6.2: - resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} engines: {node: '>=10'} peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 eslint-plugin-react-refresh@0.4.20: resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} @@ -2614,8 +2643,8 @@ packages: peerDependencies: react: ^15.0.2 || ^16.0.0 || ^17.0.0 - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -3154,8 +3183,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.1.0: - resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + lru-cache@11.2.1: + resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} engines: {node: 20 || >=22} lz-string@1.5.0: @@ -3387,8 +3416,8 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.7.4: - resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3426,14 +3455,14 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - next-themes@0.3.0: - resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==} + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} peerDependencies: - react: ^16.8 || ^17 || ^18 - react-dom: ^16.8 || ^17 || ^18 + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - node-fetch-native@1.6.6: - resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -3729,10 +3758,16 @@ packages: chart.js: ^4.1.1 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + react-dom@19.1.1: + resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} peerDependencies: - react: ^18.3.1 + react: ^19.1.1 + + react-draggable@4.5.0: + resolution: {integrity: sha512-VC+HBLEZ0XJxnOxVAZsdRi8rD04Iz3SiiKOoYzamjylUcju/hP9np/aZdLHf/7WOD268WMoNJMvYfB5yAK45cw==} + peerDependencies: + react: '>= 16.3.0' + react-dom: '>= 16.3.0' react-hook-form@7.56.2: resolution: {integrity: sha512-vpfuHuQMF/L6GpuQ4c3ZDo+pRYxIi40gQqsCmmfUBwm+oqvBhKhwghCuj2o00YCgSfU6bR9KC/xnQGWm3Gr08A==} @@ -3800,6 +3835,11 @@ packages: react: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react-resizable@3.0.5: + resolution: {integrity: sha512-vKpeHhI5OZvYn82kXOs1bC8aOXktGU5AmKAgaZS4F5JPburCtbmDPqE7Pzp+1kN4+Wb81LlF33VpGwWwtXem+w==} + peerDependencies: + react: '>= 16.3' + react-router-dom@6.30.0: resolution: {integrity: sha512-x30B78HV5tFk8ex0ITwzC9TTZMua4jGyA9IUlH1JLQYQTFyxr/ZxwOJq7evg1JX1qGVUcvhsmQSKdPncQrjTgA==} engines: {node: '>=14.0.0'} @@ -3824,8 +3864,8 @@ packages: peerDependencies: react: '>= 0.14.0' - react-textarea-autosize@8.5.8: - resolution: {integrity: sha512-iUiIj70JefrTuSJ4LbVFiSqWiHHss5L63L717bqaWHMgkm9sz6eEvro4vZ3uQfGJbevzwT6rHOszHKA8RkhRMg==} + react-textarea-autosize@8.5.9: + resolution: {integrity: sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==} engines: {node: '>=10'} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3836,8 +3876,8 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + react@19.1.1: + resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} engines: {node: '>=0.10.0'} read-pkg-up@7.0.1: @@ -3951,8 +3991,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} @@ -4266,12 +4306,12 @@ packages: engines: {node: '>=14.17'} hasBin: true - ua-parser-js@1.0.40: - resolution: {integrity: sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==} + ua-parser-js@1.0.41: + resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} hasBin: true - ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} @@ -4353,6 +4393,15 @@ packages: '@types/react': optional: true + use-isomorphic-layout-effect@1.2.1: + resolution: {integrity: sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + use-latest@1.3.0: resolution: {integrity: sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==} peerDependencies: @@ -4632,7 +4681,7 @@ snapshots: '@types/json-schema': 7.0.15 js-yaml: 4.1.0 - '@ark-ui/react@5.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@ark-ui/react@5.12.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@internationalized/date': 3.8.1 '@zag-js/accordion': 1.15.0 @@ -4673,7 +4722,7 @@ snapshots: '@zag-js/qr-code': 1.15.0 '@zag-js/radio-group': 1.15.0 '@zag-js/rating-group': 1.15.0 - '@zag-js/react': 1.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@zag-js/react': 1.15.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@zag-js/select': 1.15.0 '@zag-js/signature-pad': 1.15.0 '@zag-js/slider': 1.15.0 @@ -4692,8 +4741,8 @@ snapshots: '@zag-js/tree-view': 1.15.0 '@zag-js/types': 1.15.0 '@zag-js/utils': 1.15.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) '@babel/code-frame@7.26.2': dependencies: @@ -4759,6 +4808,8 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 + '@babel/runtime@7.28.4': {} + '@babel/template@7.26.9': dependencies: '@babel/code-frame': 7.26.2 @@ -4819,19 +4870,19 @@ snapshots: '@chakra-ui/anatomy@2.3.4': {} - '@chakra-ui/react@3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@chakra-ui/react@3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@ark-ui/react': 5.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ark-ui/react': 5.12.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@emotion/is-prop-valid': 1.3.1 - '@emotion/react': 11.14.0(@types/react@18.3.19)(react@18.3.1) + '@emotion/react': 11.14.0(@types/react@18.3.19)(react@19.1.1) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) '@emotion/utils': 1.4.2 '@pandacss/is-valid-prop': 0.53.6 csstype: 3.1.3 fast-safe-stringify: 2.1.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) '@codemirror/autocomplete@6.18.2(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.4)(@lezer/common@1.2.3)': dependencies: @@ -4922,17 +4973,17 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@18.3.19)(react@18.3.1)': + '@emotion/react@11.14.0(@types/react@18.3.19)(react@19.1.1)': dependencies: '@babel/runtime': 7.26.10 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 18.3.1 + react: 19.1.1 optionalDependencies: '@types/react': 18.3.19 transitivePeerDependencies: @@ -4950,9 +5001,9 @@ snapshots: '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@18.3.1)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.1.1)': dependencies: - react: 18.3.1 + react: 19.1.1 '@emotion/utils@1.4.2': {} @@ -5406,22 +5457,22 @@ snapshots: '@tanstack/query-core@5.75.4': {} - '@tanstack/react-query@5.75.4(react@18.3.1)': + '@tanstack/react-query@5.75.4(react@19.1.1)': dependencies: '@tanstack/query-core': 5.75.4 - react: 18.3.1 + react: 19.1.1 - '@tanstack/react-table@8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tanstack/react-table@8.21.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@tanstack/table-core': 8.21.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@tanstack/react-virtual@3.13.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tanstack/react-virtual@3.13.8(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@tanstack/virtual-core': 3.13.8 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) '@tanstack/table-core@8.21.3': {} @@ -5430,7 +5481,7 @@ snapshots: '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.28.4 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -5448,12 +5499,12 @@ snapshots: lodash: 4.17.21 redent: 3.0.0 - '@testing-library/react@16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@18.3.5(@types/react@18.3.19))(@types/react@18.3.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@testing-library/react@16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@18.3.5(@types/react@18.3.19))(@types/react@18.3.19)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.26.10 '@testing-library/dom': 10.4.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) optionalDependencies: '@types/react': 18.3.19 '@types/react-dom': 18.3.5(@types/react@18.3.19) @@ -5558,7 +5609,7 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/lodash@4.17.16': {} + '@types/lodash@4.17.20': {} '@types/mdast@4.0.4': dependencies: @@ -5582,6 +5633,10 @@ snapshots: dependencies: '@types/react': 18.3.19 + '@types/react-resizable@3.0.8': + dependencies: + '@types/react': 18.3.19 + '@types/react-syntax-highlighter@15.5.13': dependencies: '@types/react': 18.3.19 @@ -6093,17 +6148,17 @@ snapshots: '@codemirror/state': 6.5.2 '@codemirror/view': 6.36.4 - '@uiw/react-codemirror@4.23.12(@babel/runtime@7.26.10)(@codemirror/autocomplete@6.18.2(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.4)(@lezer/common@1.2.3))(@codemirror/language@6.11.0)(@codemirror/lint@6.8.2)(@codemirror/search@6.5.6)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.4)(codemirror@6.0.1(@lezer/common@1.2.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-codemirror@4.23.12(@babel/runtime@7.28.4)(@codemirror/autocomplete@6.18.2(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.4)(@lezer/common@1.2.3))(@codemirror/language@6.11.0)(@codemirror/lint@6.8.2)(@codemirror/search@6.5.6)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.4)(codemirror@6.0.1(@lezer/common@1.2.3))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.28.4 '@codemirror/commands': 6.8.1 '@codemirror/state': 6.5.2 '@codemirror/theme-one-dark': 6.1.2 '@codemirror/view': 6.36.4 '@uiw/codemirror-extensions-basic-setup': 4.23.12(@codemirror/autocomplete@6.18.2(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.4)(@lezer/common@1.2.3))(@codemirror/commands@6.8.1)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.2)(@codemirror/search@6.5.6)(@codemirror/state@6.5.2)(@codemirror/view@6.36.4) codemirror: 6.0.1(@lezer/common@1.2.3) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) transitivePeerDependencies: - '@codemirror/autocomplete' - '@codemirror/language' @@ -6117,32 +6172,32 @@ snapshots: '@types/d3-shape': 1.3.12 d3-shape: 1.3.7 - '@visx/group@3.12.0(react@18.3.1)': + '@visx/group@3.12.0(react@19.1.1)': dependencies: '@types/react': 18.3.19 classnames: 2.5.1 prop-types: 15.8.1 - react: 18.3.1 + react: 19.1.1 '@visx/scale@3.12.0': dependencies: '@visx/vendor': 3.12.0 - '@visx/shape@3.12.0(react@18.3.1)': + '@visx/shape@3.12.0(react@19.1.1)': dependencies: '@types/d3-path': 1.0.11 '@types/d3-shape': 1.3.12 - '@types/lodash': 4.17.16 + '@types/lodash': 4.17.20 '@types/react': 18.3.19 '@visx/curve': 3.12.0 - '@visx/group': 3.12.0(react@18.3.1) + '@visx/group': 3.12.0(react@19.1.1) '@visx/scale': 3.12.0 classnames: 2.5.1 d3-path: 1.0.9 d3-shape: 1.3.7 lodash: 4.17.21 prop-types: 15.8.1 - react: 18.3.1 + react: 19.1.1 '@visx/vendor@3.12.0': dependencies: @@ -6232,13 +6287,13 @@ snapshots: loupe: 3.1.3 tinyrainbow: 1.2.0 - '@xyflow/react@12.4.4(@types/react@18.3.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@xyflow/react@12.4.4(@types/react@18.3.19)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@xyflow/system': 0.0.52 classcat: 5.0.5 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - zustand: 4.5.6(@types/react@18.3.19)(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + zustand: 4.5.6(@types/react@18.3.19)(react@19.1.1) transitivePeerDependencies: - '@types/react' - immer @@ -6575,14 +6630,14 @@ snapshots: '@zag-js/types': 1.15.0 '@zag-js/utils': 1.15.0 - '@zag-js/react@1.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@zag-js/react@1.15.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@zag-js/core': 1.15.0 '@zag-js/store': 1.15.0 '@zag-js/types': 1.15.0 '@zag-js/utils': 1.15.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) '@zag-js/rect-utils@1.15.0': {} @@ -6763,6 +6818,8 @@ snapshots: acorn@8.14.1: {} + acorn@8.15.0: {} + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -6770,6 +6827,8 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + anser@2.3.2: {} + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -6879,9 +6938,9 @@ snapshots: axe-core@4.10.3: {} - axios@1.11.0: + axios@1.12.0: dependencies: - follow-redirects: 1.15.9 + follow-redirects: 1.15.11 form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -6948,10 +7007,10 @@ snapshots: chokidar: 3.6.0 confbox: 0.1.8 defu: 6.1.4 - dotenv: 16.4.7 + dotenv: 16.6.1 giget: 1.2.5 jiti: 1.21.7 - mlly: 1.7.4 + mlly: 1.8.0 ohash: 1.1.6 pathe: 1.1.2 perfect-debounce: 1.0.0 @@ -6995,12 +7054,12 @@ snapshots: loupe: 3.1.3 pathval: 2.0.0 - chakra-react-select@6.1.0(@chakra-ui/react@3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.19)(next-themes@0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + chakra-react-select@6.1.0(@chakra-ui/react@3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@18.3.19)(next-themes@0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@chakra-ui/react': 3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-themes: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-select: 5.10.1(@types/react@18.3.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@chakra-ui/react': 3.20.0(@emotion/react@11.14.0(@types/react@18.3.19)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + next-themes: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-select: 5.10.1(@types/react@18.3.19)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) transitivePeerDependencies: - '@types/react' - react-dom @@ -7081,6 +7140,8 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clsx@2.1.1: {} + code-block-writer@13.0.3: {} codemirror@6.0.1(@lezer/common@1.2.3): @@ -7304,7 +7365,7 @@ snapshots: dequal@2.0.3: {} - destr@2.0.3: {} + destr@2.0.5: {} devlop@1.1.0: dependencies: @@ -7323,7 +7384,7 @@ snapshots: '@babel/runtime': 7.26.10 csstype: 3.1.3 - dotenv@16.4.7: {} + dotenv@16.6.1: {} dunder-proto@1.0.1: dependencies: @@ -7559,7 +7620,7 @@ snapshots: optionalDependencies: eslint-config-prettier: 10.1.2(eslint@9.26.0(jiti@1.21.7)) - eslint-plugin-react-hooks@4.6.2(eslint@9.26.0(jiti@1.21.7)): + eslint-plugin-react-hooks@5.2.0(eslint@9.26.0(jiti@1.21.7)): dependencies: eslint: 9.26.0(jiti@1.21.7) @@ -7784,7 +7845,7 @@ snapshots: object-assign: 4.1.1 promise: 7.3.1 setimmediate: 1.0.5 - ua-parser-js: 1.0.40 + ua-parser-js: 1.0.41 transitivePeerDependencies: - encoding @@ -7826,15 +7887,15 @@ snapshots: flatted@3.3.3: {} - flux@4.0.4(react@18.3.1): + flux@4.0.4(react@19.1.1): dependencies: fbemitter: 3.0.0 fbjs: 3.0.5 - react: 18.3.1 + react: 19.1.1 transitivePeerDependencies: - encoding - follow-redirects@1.15.9: {} + follow-redirects@1.15.11: {} for-each@0.3.5: dependencies: @@ -7910,7 +7971,7 @@ snapshots: citty: 0.1.6 consola: 3.4.2 defu: 6.1.4 - node-fetch-native: 1.6.6 + node-fetch-native: 1.6.7 nypm: 0.5.4 pathe: 2.0.3 tar: 6.2.1 @@ -8394,7 +8455,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.1.0: {} + lru-cache@11.2.1: {} lz-string@1.5.0: {} @@ -8818,12 +8879,12 @@ snapshots: mkdirp@3.0.1: {} - mlly@1.7.4: + mlly@1.8.0: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.5.4 + ufo: 1.6.1 ms@2.1.3: {} @@ -8864,12 +8925,12 @@ snapshots: neo-async@2.6.2: {} - next-themes@0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-themes@0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - node-fetch-native@1.6.6: {} + node-fetch-native@1.6.7: {} node-fetch@2.7.0: dependencies: @@ -8898,7 +8959,7 @@ snapshots: pathe: 2.0.3 pkg-types: 1.3.1 tinyexec: 0.3.2 - ufo: 1.5.4 + ufo: 1.6.1 object-assign@4.1.1: {} @@ -9047,7 +9108,7 @@ snapshots: path-scurry@2.0.0: dependencies: - lru-cache: 11.1.0 + lru-cache: 11.2.1 minipass: 7.1.2 path-to-regexp@6.3.0: {} @@ -9077,7 +9138,7 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.7.4 + mlly: 1.8.0 pathe: 2.0.3 pluralize@8.0.0: {} @@ -9165,7 +9226,7 @@ snapshots: rc9@2.1.2: dependencies: defu: 6.1.4 - destr: 2.0.3 + destr: 2.0.5 react-base16-styling@0.6.0: dependencies: @@ -9174,64 +9235,70 @@ snapshots: lodash.flow: 3.5.0 pure-color: 1.3.0 - react-chartjs-2@5.3.0(chart.js@4.4.9)(react@18.3.1): + react-chartjs-2@5.3.0(chart.js@4.4.9)(react@19.1.1): dependencies: chart.js: 4.4.9 - react: 18.3.1 + react: 19.1.1 - react-dom@18.3.1(react@18.3.1): + react-dom@19.1.1(react@19.1.1): dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 + react: 19.1.1 + scheduler: 0.26.0 + + react-draggable@4.5.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + dependencies: + clsx: 2.1.1 + prop-types: 15.8.1 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - react-hook-form@7.56.2(react@18.3.1): + react-hook-form@7.56.2(react@19.1.1): dependencies: - react: 18.3.1 + react: 19.1.1 - react-hotkeys-hook@4.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-hotkeys-hook@4.6.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - react-i18next@15.5.1(i18next@25.1.2(typescript@5.8.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3): + react-i18next@15.5.1(i18next@25.1.2(typescript@5.8.3))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.8.3): dependencies: '@babel/runtime': 7.26.10 html-parse-stringify: 3.0.1 i18next: 25.1.2(typescript@5.8.3) - react: 18.3.1 + react: 19.1.1 optionalDependencies: - react-dom: 18.3.1(react@18.3.1) + react-dom: 19.1.1(react@19.1.1) typescript: 5.8.3 - react-icons@5.5.0(react@18.3.1): + react-icons@5.5.0(react@19.1.1): dependencies: - react: 18.3.1 + react: 19.1.1 - react-innertext@1.1.5(@types/react@18.3.19)(react@18.3.1): + react-innertext@1.1.5(@types/react@18.3.19)(react@19.1.1): dependencies: '@types/react': 18.3.19 - react: 18.3.1 + react: 19.1.1 react-is@16.13.1: {} react-is@17.0.2: {} - react-json-view@1.21.3(@types/react@18.3.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-json-view@1.21.3(@types/react@18.3.19)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - flux: 4.0.4(react@18.3.1) - react: 18.3.1 + flux: 4.0.4(react@19.1.1) + react: 19.1.1 react-base16-styling: 0.6.0 - react-dom: 18.3.1(react@18.3.1) + react-dom: 19.1.1(react@19.1.1) react-lifecycles-compat: 3.0.4 - react-textarea-autosize: 8.5.8(@types/react@18.3.19)(react@18.3.1) + react-textarea-autosize: 8.5.9(@types/react@18.3.19)(react@19.1.1) transitivePeerDependencies: - '@types/react' - encoding react-lifecycles-compat@3.0.4: {} - react-markdown@9.1.0(@types/react@18.3.19)(react@18.3.1): + react-markdown@9.1.0(@types/react@18.3.19)(react@19.1.1): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 @@ -9240,7 +9307,7 @@ snapshots: hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 mdast-util-to-hast: 13.2.0 - react: 18.3.1 + react: 19.1.1 remark-parse: 11.0.0 remark-rehype: 11.1.1 unified: 11.0.5 @@ -9249,71 +9316,77 @@ snapshots: transitivePeerDependencies: - supports-color - react-resizable-panels@2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-resizable-panels@2.1.7(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + dependencies: + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + react-resizable@3.0.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + prop-types: 15.8.1 + react: 19.1.1 + react-draggable: 4.5.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + transitivePeerDependencies: + - react-dom - react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-router-dom@6.30.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@remix-run/router': 1.23.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-router: 6.30.0(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-router: 6.30.0(react@19.1.1) - react-router@6.30.0(react@18.3.1): + react-router@6.30.0(react@19.1.1): dependencies: '@remix-run/router': 1.23.0 - react: 18.3.1 + react: 19.1.1 - react-select@5.10.1(@types/react@18.3.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-select@5.10.1(@types/react@18.3.19)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@babel/runtime': 7.26.10 '@emotion/cache': 11.14.0 - '@emotion/react': 11.14.0(@types/react@18.3.19)(react@18.3.1) + '@emotion/react': 11.14.0(@types/react@18.3.19)(react@19.1.1) '@floating-ui/dom': 1.6.13 '@types/react-transition-group': 4.4.12(@types/react@18.3.19) memoize-one: 6.0.0 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - use-isomorphic-layout-effect: 1.2.0(@types/react@18.3.19)(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-transition-group: 4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + use-isomorphic-layout-effect: 1.2.0(@types/react@18.3.19)(react@19.1.1) transitivePeerDependencies: - '@types/react' - supports-color - react-syntax-highlighter@15.6.1(react@18.3.1): + react-syntax-highlighter@15.6.1(react@19.1.1): dependencies: '@babel/runtime': 7.26.10 highlight.js: 10.7.3 highlightjs-vue: 1.0.0 lowlight: 1.20.0 prismjs: 1.30.0 - react: 18.3.1 + react: 19.1.1 refractor: 3.6.0 - react-textarea-autosize@8.5.8(@types/react@18.3.19)(react@18.3.1): + react-textarea-autosize@8.5.9(@types/react@18.3.19)(react@19.1.1): dependencies: - '@babel/runtime': 7.26.10 - react: 18.3.1 - use-composed-ref: 1.4.0(@types/react@18.3.19)(react@18.3.1) - use-latest: 1.3.0(@types/react@18.3.19)(react@18.3.1) + '@babel/runtime': 7.28.4 + react: 19.1.1 + use-composed-ref: 1.4.0(@types/react@18.3.19)(react@19.1.1) + use-latest: 1.3.0(@types/react@18.3.19)(react@19.1.1) transitivePeerDependencies: - '@types/react' - react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-transition-group@4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@babel/runtime': 7.26.10 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - react@18.3.1: - dependencies: - loose-envify: 1.4.0 + react@19.1.1: {} read-pkg-up@7.0.1: dependencies: @@ -9492,9 +9565,7 @@ snapshots: safer-buffer@2.1.2: {} - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 + scheduler@0.26.0: {} semver@5.7.2: {} @@ -9855,9 +9926,9 @@ snapshots: typescript@5.8.3: {} - ua-parser-js@1.0.40: {} + ua-parser-js@1.0.41: {} - ufo@1.5.4: {} + ufo@1.6.1: {} uglify-js@3.19.3: optional: true @@ -9927,37 +9998,43 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - use-composed-ref@1.4.0(@types/react@18.3.19)(react@18.3.1): + use-composed-ref@1.4.0(@types/react@18.3.19)(react@19.1.1): dependencies: - react: 18.3.1 + react: 19.1.1 optionalDependencies: '@types/react': 18.3.19 - use-debounce@10.0.4(react@18.3.1): + use-debounce@10.0.4(react@19.1.1): + dependencies: + react: 19.1.1 + + use-isomorphic-layout-effect@1.2.0(@types/react@18.3.19)(react@19.1.1): dependencies: - react: 18.3.1 + react: 19.1.1 + optionalDependencies: + '@types/react': 18.3.19 - use-isomorphic-layout-effect@1.2.0(@types/react@18.3.19)(react@18.3.1): + use-isomorphic-layout-effect@1.2.1(@types/react@18.3.19)(react@19.1.1): dependencies: - react: 18.3.1 + react: 19.1.1 optionalDependencies: '@types/react': 18.3.19 - use-latest@1.3.0(@types/react@18.3.19)(react@18.3.1): + use-latest@1.3.0(@types/react@18.3.19)(react@19.1.1): dependencies: - react: 18.3.1 - use-isomorphic-layout-effect: 1.2.0(@types/react@18.3.19)(react@18.3.1) + react: 19.1.1 + use-isomorphic-layout-effect: 1.2.1(@types/react@18.3.19)(react@19.1.1) optionalDependencies: '@types/react': 18.3.19 - use-sync-external-store@1.4.0(react@18.3.1): + use-sync-external-store@1.4.0(react@19.1.1): dependencies: - react: 18.3.1 + react: 19.1.1 - usehooks-ts@3.1.1(react@18.3.1): + usehooks-ts@3.1.1(react@19.1.1): dependencies: lodash.debounce: 4.0.8 - react: 18.3.1 + react: 19.1.1 validate-npm-package-license@3.0.4: dependencies: @@ -10168,17 +10245,17 @@ snapshots: zod@3.24.4: {} - zustand@4.5.6(@types/react@18.3.19)(react@18.3.1): + zustand@4.5.6(@types/react@18.3.19)(react@19.1.1): dependencies: - use-sync-external-store: 1.4.0(react@18.3.1) + use-sync-external-store: 1.4.0(react@19.1.1) optionalDependencies: '@types/react': 18.3.19 - react: 18.3.1 + react: 19.1.1 - zustand@5.0.4(@types/react@18.3.19)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): + zustand@5.0.4(@types/react@18.3.19)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): optionalDependencies: '@types/react': 18.3.19 - react: 18.3.1 - use-sync-external-store: 1.4.0(react@18.3.1) + react: 19.1.1 + use-sync-external-store: 1.4.0(react@19.1.1) zwitch@2.0.4: {} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/admin.json index 21e002ba0cd6a..f409e3969d50b 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/admin.json @@ -84,7 +84,6 @@ "tooltip": "حذف الموَّصلات المحددة" }, "formActions": { - "reset": "إعادة تعيين", "save": "حفظ" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/common.json index 813a4487cba11..db99947efc813 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/common.json @@ -123,16 +123,12 @@ "any": "أي", "or": "أو" }, + "filter": "فلتر", "filters": { - "dagDisplayNamePlaceholder": "تصفية حسب الDag", - "keyPlaceholder": "تصفية حسب مفتاح XCom", - "logicalDateFromPlaceholder": "من التاريخ المنطقي", - "logicalDateToPlaceholder": "إلى التاريخ المنطقي", - "mapIndexPlaceholder": "تصفية حسب فهرس الخريطة", - "runAfterFromPlaceholder": "من تشغيل بعد", - "runAfterToPlaceholder": "إلى تشغيل بعد", - "runIdPlaceholder": "تصفية حسب معرف التشغيل", - "taskIdPlaceholder": "تصفية حسب معرف المهمة" + "logicalDateFrom": "من التاريخ المنطقي", + "logicalDateTo": "إلى التاريخ المنطقي", + "runAfterFrom": "من تشغيل بعد", + "runAfterTo": "إلى تشغيل بعد" }, "logicalDate": "التاريخ المنطقي", "logout": "تسجيل الخروج", @@ -178,6 +174,7 @@ "running": "قيد التشغيل", "scheduled": "مجدول" }, + "reset": "إعادة تعيين", "runId": "معرف التشغيل", "runTypes": { "asset_triggered": "مُشغل بواسطة الأصل", @@ -192,7 +189,6 @@ }, "tooltip": "اضغط {{hotkey}} للتمرير إلى {{direction}}" }, - "seconds": "ثواني", "security": { "actions": "إجراءات", "permissions": "صلاحيات", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/components.json index 4975e2114b793..0b1c5d74aa9c8 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/components.json @@ -10,8 +10,6 @@ "allRuns": "جميع التشغيلات", "backwards": "تشغيل رجعي", "dateRange": "نطاق التاريخ", - "dateRangeFrom": "من", - "dateRangeTo": "إلى", "errorStartDateBeforeEndDate": "يجب أن يكون تاريخ البدء قبل تاريخ الانتهاء", "maxRuns": "الحد الأقصى للتشغيلات النشطة", "missingAndErroredRuns": "تشغيلات مفقودة وخاطئة", @@ -118,6 +116,11 @@ "taskGroup": "مجموعة المهام" }, "limitedList": "+{{count}} المزيد", + "limitedList.allItems": "جميع العناصر {{count}}:", + "limitedList.clickToInteract": "انقر على علامة لتصفية Dags", + "limitedList.clickToOpenFull": "انقر \"+{{count}} المزيد\" لعرض القائمة الكاملة", + "limitedList.copyPasteText": "يمكنك نسخ ولصق النص أعلاه", + "limitedList.showingItems": "عرض {{count}} عنصرًا", "logs": { "file": "ملف", "location": "سطر {{line}} في {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ca/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/ca/admin.json index a8a6a26c8e950..4b1ae13fff63c 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ca/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ca/admin.json @@ -72,7 +72,6 @@ "tooltip": "Eliminar connexions seleccionades" }, "formActions": { - "reset": "Restablir", "save": "Desar" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json index 9330bc9aafbbf..7edcd6ae1b610 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json @@ -99,16 +99,12 @@ "any": "Qualsevol", "or": "O" }, + "filter": "Filtre", "filters": { - "dagDisplayNamePlaceholder": "Filtrar per Dag", - "keyPlaceholder": "Filtrar per clau XCom", - "logicalDateFromPlaceholder": "Data Lògica Des de", - "logicalDateToPlaceholder": "Data Lògica Fins a", - "mapIndexPlaceholder": "Filtrar per Índex del Mapa", - "runAfterFromPlaceholder": "Executar Després de", - "runAfterToPlaceholder": "Executar Després de", - "runIdPlaceholder": "Filtrar per ID d'Execució", - "taskIdPlaceholder": "Filtrar per ID de Tasca" + "logicalDateFrom": "Data Lògica Des de", + "logicalDateTo": "Data Lògica Fins a", + "runAfterFrom": "Executar Després de", + "runAfterTo": "Executar Després de" }, "logicalDate": "Data Lògica", "logout": "Tancar sessió", @@ -150,6 +146,7 @@ "running": "Executant-se", "scheduled": "Programat" }, + "reset": "Restablir", "runId": "ID de l'execució", "runTypes": { "asset_triggered": "Executat per Asset", @@ -164,7 +161,6 @@ }, "tooltip": "Prem {{hotkey}} per desplaçar-te cap a {{direction}}" }, - "seconds": "{{count}}s", "security": { "actions": "Accions", "permissions": "Permisos", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ca/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/ca/components.json index 295f9c0877887..d5e7b5c197c12 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ca/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ca/components.json @@ -6,8 +6,6 @@ "allRuns": "Totes les execucions", "backwards": "Executar enrere", "dateRange": "Interval de dates", - "dateRangeFrom": "Des de", - "dateRangeTo": "Fins", "errorStartDateBeforeEndDate": "La data d'inici ha de ser anterior a la data de finalització", "maxRuns": "Màxim d'execucions actives", "missingAndErroredRuns": "Execucions absents i amb errors", @@ -90,6 +88,11 @@ "taskGroup": "Grup de tasques" }, "limitedList": "+{{count}} més", + "limitedList.allItems": "Tots els {{count}} elements:", + "limitedList.clickToInteract": "Fes clic en una etiqueta per filtrar els Dags", + "limitedList.clickToOpenFull": "Fes clic a \"+{{count}} més\" per veure la llista completa", + "limitedList.copyPasteText": "Pots copiar i enganxar el text de dalt", + "limitedList.showingItems": "Mostrant {{count}} elements", "logs": { "file": "Fitxer", "location": "línia {{line}} a {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/de/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/de/admin.json index a5299dc13a9d7..6435b9e63bab4 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/de/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/de/admin.json @@ -72,7 +72,6 @@ "tooltip": "Ausgewählte Verbindungen löschen" }, "formActions": { - "reset": "Zurücksetzen", "save": "Speichern" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/de/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/de/common.json index ea9788de85b66..fe14e8e0d6713 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/de/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/de/common.json @@ -99,17 +99,12 @@ "any": "Jeder", "or": "ODER" }, + "filter": "Filter", "filters": { - "dagDisplayNamePlaceholder": "Nach Dag filtern", - "keyPlaceholder": "Nach Task Kommunikation (XCom) Schlüssel filtern", - "logicalDateFromPlaceholder": "Logisches Datum Von", - "logicalDateToPlaceholder": "Logisches Datum Bis", - "mapIndexPlaceholder": "Nach Planungs-Index filtern", - "runAfterFromPlaceholder": "Gelaufen-nach von filtern", - "runAfterToPlaceholder": "Gelaufen-nach bis filtern", - "runIdPlaceholder": "Nach Lauf ID filtern", - "taskIdPlaceholder": "Nach Task ID filtern", - "triggeringUserPlaceholder": "Nach auslösendem Benutzer filtern" + "logicalDateFrom": "Logisches Datum Von", + "logicalDateTo": "Logisches Datum Bis", + "runAfterFrom": "Gelaufen-nach von filtern", + "runAfterTo": "Gelaufen-nach bis filtern" }, "logicalDate": "Logisches Datum", "logout": "Abmelden", @@ -151,6 +146,7 @@ "running": "Laufende", "scheduled": "Geplant" }, + "reset": "Zurücksetzen", "runId": "Lauf Id", "runTypes": { "asset_triggered": "Durch Datenset (Asset) ausgelöst", @@ -165,7 +161,6 @@ }, "tooltip": "Tastenkombination {{hotkey}} zum scrollen nach {{direction}}" }, - "seconds": "{{count}}s", "security": { "actions": "Aktionen", "permissions": "Berechtigungen", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/de/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/de/components.json index 95abe63ea6367..3e4166ba90804 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/de/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/de/components.json @@ -6,8 +6,6 @@ "allRuns": "Alle Läufe", "backwards": "Verarbeitung in Rückwärtiger Reihenfolge", "dateRange": "Datumsbereich", - "dateRangeFrom": "Von", - "dateRangeTo": "Bis", "errorStartDateBeforeEndDate": "Das Startdatum muss vor dem Enddatum liegen.", "maxRuns": "Anzahl aktiver paralleler Läufe", "missingAndErroredRuns": "Fehlende und fehlgeschlagene Läufe", @@ -90,6 +88,14 @@ "taskGroup": "Task Gruppe" }, "limitedList": "+{{count}} mehr", + "limitedList.allItems": "Alle {{count}} Einträge:", + "limitedList.allTags_one": "Alle Markierungen ({{count}})", + "limitedList.allTags_other": "Alle Markierungen ({{count}})", + "limitedList.clickToInteract": "Klicken Sie auf eine Markierung, um Dags zu filtern", + "limitedList.clickToOpenFull": "Klicken Sie auf \"+{{count}} mehr\" für die vollständige Ansicht", + "limitedList.copyPasteText": "Sie können den obigen Text kopieren und einfügen", + "limitedList.showingItems_one": "{{count}} Eintrag wird angezeigt", + "limitedList.showingItems_other": "{{count}} Einträge werden angezeigt", "logs": { "file": "Datei", "location": "Zeile {{line}} in {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json index 7f0b2c603bb99..1803e2ea630aa 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json @@ -10,6 +10,7 @@ "hourly": "Stündlich", "legend": { "less": "Weniger", + "mixed": "Mittel", "more": "Mehr" }, "navigation": { @@ -19,6 +20,7 @@ "previousYear": "Vorheriges Jahr" }, "noData": "Keine Daten verfügbar", + "noFailedRuns": "Keine fehlgeschlagenen Läufe", "noRuns": "Keine Läufe", "totalRuns": "Gesamtzahl der Läufe", "week": "Kalenderwoche {{weekNumber}}", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/admin.json new file mode 100644 index 0000000000000..6358cf5e4e5c3 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/admin.json @@ -0,0 +1,166 @@ +{ + "columns": { + "description": "Περιγραφή", + "key": "Κλειδί", + "name": "Όνομα", + "value": "Τιμή" + }, + "config": { + "columns": { + "section": "Ενότητα" + }, + "title": "Ρυθμίσεις Airflow" + }, + "connections": { + "add": "Προσθήκη Σύνδεσης", + "columns": { + "connectionId": "ID Σύνδεσης", + "connectionType": "Τύπος Σύνδεσης", + "host": "Ξενιστής", + "port": "Θύρα" + }, + "connection_one": "Σύνδεση", + "connection_other": "Συνδέσεις", + "delete": { + "deleteConnection_one": "Διαγραφή 1 σύνδεσης", + "deleteConnection_other": "Διαγραφή {{count}} συνδέσεων", + "firstConfirmMessage_one": "Πρόκειται να διαγράψετε την ακόλουθη σύνδεση:", + "firstConfirmMessage_other": "Πρόκειται να διαγράψετε τις ακόλουθες συνδέσεις:", + "title": "Διαγραφή Σύνδεσης" + }, + "edit": "Επεξεργασία Σύνδεσης", + "form": { + "connectionIdRequired": "Το ID Σύνδεσης είναι υποχρεωτικό", + "connectionIdRequirement": "Το ID Σύνδεσης δεν μπορεί να περιέχει μόνο κενά", + "connectionTypeRequired": "Ο Τύπος Σύνδεσης είναι υποχρεωτικός", + "extraFields": "Επιπλέον Πεδία", + "extraFieldsJson": "Επιπλέον Πεδία JSON", + "helperText": "Λείπει ο Τύπος Σύνδεσης; Βεβαιωθείτε ότι έχετε εγκαταστήσει το ανάλογο πακέτο Airflow Παρόχων.", + "helperTextForRedactedFields": "Τα πεδία που έχουν αποκρυφθεί ('***') θα παραμείνουν αμετάβλητα αν δεν τροποποιηθούν.", + "selectConnectionType": "Επιλέξτε Τύπο Σύνδεσης", + "standardFields": "Βασικά Πεδία" + }, + "nothingFound": { + "description": "Οι συνδέσεις που ορίζονται μέσω μεταβλητών περιβάλλοντος ή διαχειριστών μυστικών δεν εμφανίζονται εδώ.", + "documentationLink": "Μάθετε περισσότερα στην τεκμηρίωση του Airflow.", + "learnMore": "Αυτές επιλύονται κατά το χρόνο εκτέλεσης και δεν είναι ορατές στο UI.", + "title": "Δεν βρέθηκε σύνδεση!" + }, + "searchPlaceholder": "Αναζήτηση Συνδέσεων", + "test": "Δοκιμή Σύνδεσης", + "testDisabled": "Η λειτουργία δοκιμής σύνδεσης είναι απενεργοποιημένη. Επικοινωνήστε με τον διαχειριστή για να την ενεργοποιήσει.", + "typeMeta": { + "error": "Αποτυχία ανάκτησης μεταδεδομένων τύπου σύνδεσης", + "standardFields": { + "description": "Περιγραφή", + "host": "Ξενιστής", + "login": "Όνομα Χρήστη", + "password": "Κωδικός", + "port": "Θύρα", + "url_schema": "Σχήμα" + } + } + }, + "deleteActions": { + "button": "Διαγραφή", + "modal": { + "confirmButton": "Ναι, Διαγραφή", + "secondConfirmMessage": "Αυτή η ενέργεια είναι μόνιμη και δεν μπορεί να αναιρεθεί.", + "thirdConfirmMessage": " Είστε σίγουροι ότι θέλετε να συνεχίσετε;" + }, + "selected": "Επιλεγμένα", + "tooltip": "Διαγραφή επιλεγμένων συνδέσεων" + }, + "formActions": { + "save": "Αποθήκευση" + }, + "plugins": { + "columns": { + "source": "Πηγή" + }, + "importError_one": "Σφάλμα Εισαγωγής Πρόσθετου", + "importError_other": "Σφάλματα Εισαγωγής Πρόσθετων", + "searchPlaceholder": "Αναζήτηση κατά αρχείο" + }, + "pools": { + "add": "Προσθήκη Pool", + "deferredSlotsIncluded": "Συμπεριλαμβάνονται Αναβληθέντα Slots", + "delete": { + "title": "Διαγραφή Pool", + "warning": "Αυτό θα αφαιρέσει όλα τα μεταδεδομένα που σχετίζονται με το pool και μπορεί να επηρεάσει εργασίες που το χρησιμοποιούν." + }, + "edit": "Επεξεργασία Pool", + "form": { + "checkbox": "Επιλέξτε για να συμπεριλάβετε αναβληθείσες εργασίες στον υπολογισμό των διαθέσιμων slots του pool", + "description": "Περιγραφή", + "includeDeferred": "Συμπερίληψη Αναβληθέντων", + "nameMaxLength": "Το όνομα μπορεί να περιέχει έως 256 χαρακτήρες", + "nameRequired": "Το όνομα είναι υποχρεωτικό", + "slots": "Slots" + }, + "noPoolsFound": "Δεν βρέθηκαν pools", + "pool_one": "Pool", + "pool_other": "Pools", + "searchPlaceholder": "Αναζήτηση Pools", + "sort": { + "asc": "Όνομα (A-Z)", + "desc": "Όνομα (Ω-Α)", + "placeholder": "Ταξινόμηση κατά" + } + }, + "providers": { + "columns": { + "packageName": "Όνομα Πακέτου", + "version": "Έκδοση" + } + }, + "variables": { + "add": "Προσθήκη Μεταβλητής", + "columns": { + "isEncrypted": "Είναι Κρυπτογραφημένη" + }, + "delete": { + "deleteVariable_one": "Διαγραφή 1 μεταβλητής", + "deleteVariable_other": "Διαγραφή {{count}} μεταβλητών", + "firstConfirmMessage_one": "Πρόκειται να διαγράψετε την ακόλουθη μεταβλητή:", + "firstConfirmMessage_other": "Πρόκειται να διαγράψετε τις ακόλουθες μεταβλητές:", + "title": "Διαγραφή Μεταβλητής", + "tooltip": "Διαγραφή επιλεγμένων μεταβλητών" + }, + "edit": "Επεξεργασία Μεταβλητής", + "export": "Εξαγωγή", + "exportTooltip": "Εξαγωγή επιλεγμένων μεταβλητών", + "form": { + "invalidJson": "Μη έγκυρο JSON", + "keyMaxLength": "Το κλειδί μπορεί να περιέχει έως 250 χαρακτήρες", + "keyRequired": "Το κλειδί είναι υποχρεωτικό", + "valueRequired": "Η τιμή είναι υποχρεωτική" + }, + "import": { + "button": "Εισαγωγή", + "conflictResolution": "Επιλέξτε Τρόπο Επίλυσης Συγκρούσεων Μεταβλητών", + "errorParsingJsonFile": "Σφάλμα Ανάλυσης Αρχείου JSON: Ανεβάστε ένα αρχείο JSON που περιέχει μεταβλητές (π.χ., {\"key\": \"value\", ...}).", + "options": { + "fail": { + "description": "Η εισαγωγή αποτυγχάνει αν εντοπιστούν υπάρχουσες μεταβλητές.", + "title": "Αποτυχία" + }, + "overwrite": { + "description": "Αντικαθιστά τη μεταβλητή σε περίπτωση σύγκρουσης.", + "title": "Αντικατάσταση" + }, + "skip": { + "description": "Παραλείπει την εισαγωγή μεταβλητών που υπάρχουν ήδη.", + "title": "Παράλειψη" + } + }, + "title": "Εισαγωγή Μεταβλητών", + "upload": "Ανέβασμα Αρχείου JSON", + "uploadPlaceholder": "Ανεβάστε ένα αρχείο JSON που περιέχει μεταβλητές (π.χ., {\"key\": \"value\", ...})" + }, + "noRowsMessage": "Δεν βρέθηκαν μεταβλητές", + "searchPlaceholder": "Αναζήτηση Κλειδιών", + "variable_one": "Μεταβλητή", + "variable_other": "Μεταβλητές" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/assets.json new file mode 100644 index 0000000000000..27d565581af85 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/assets.json @@ -0,0 +1,30 @@ +{ + "consumingDags": "Καταναλωτικά Dags", + "createEvent": { + "button": "Δημιουργία Συμβάντος", + "manual": { + "description": "Χειροκίνητη δημιουργία Συμβάντος Οντότητας", + "extra": "Επιπλέον Πληροφορίες Συμβάντος Οντότητας", + "label": "Χειροκίνητα" + }, + "materialize": { + "description": "Εκκίνηση του Dag ανάντη αυτής της οντότητας", + "descriptionWithDag": "Εκκίνηση του Dag ανάντη αυτής της οντότητας: {{dagName}}", + "label": "Υλοποίηση", + "unpauseDag": "Αναίρεση παύσης του {{dagName}} κατά την εκκίνηση" + }, + "success": { + "manualDescription": "Η χειροκίνητη δημιουργία συμβάντος οντότητας ήταν επιτυχής.", + "manualTitle": "Το Συμβάν Οντότητας Δημιουργήθηκε", + "materializeDescription": "Το ανάντη Dag {{dagId}} εκκινήθηκε με επιτυχία.", + "materializeTitle": "Υλοποίηση Οντότητας" + }, + "title": "Δημιουργία Συμβάντος Οντότητας για {{name}}" + }, + "group": "Ομάδα", + "lastAssetEvent": "Τελευταίο Συμβάν Οντότητας", + "name": "Όνομα", + "producingTasks": "Παραγωγή Εργασιών", + "scheduledDags": "Προγραμματισμένα Dags", + "searchPlaceholder": "Αναζήτηση Οντοτήτων" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/browse.json new file mode 100644 index 0000000000000..712d4d6bd4258 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/browse.json @@ -0,0 +1,26 @@ +{ + "auditLog": { + "actions": { + "collapseAllExtra": "Σύμπτυξη όλων των επιπλέον json", + "expandAllExtra": "Ανάπτυξη όλων των επιπλέον json" + }, + "columns": { + "event": "Συμβάν", + "extra": "Επιπλέον", + "user": "Χρήστης", + "when": "Πότε" + }, + "filters": { + "eventType": "Τύπος Συμβάντος" + }, + "title": "Καταγραφή Ελέγχου" + }, + "xcom": { + "columns": { + "dag": "Dag", + "key": "Κλειδί", + "value": "Τιμή" + }, + "title": "XCom" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/common.json new file mode 100644 index 0000000000000..f3b725d02fd98 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/common.json @@ -0,0 +1,319 @@ +{ + "admin": { + "Config": "Ρυθμίσεις", + "Connections": "Συνδέσεις", + "Plugins": "Πρόσθετα", + "Pools": "Pools", + "Providers": "Πάροχοι", + "Variables": "Μεταβλητές" + }, + "allOperators": "Όλοι οι Τελεστές", + "appearance": { + "appearance": "Εμφάνιση", + "darkMode": "Σκούρο Θέμα", + "lightMode": "Φωτεινό Θέμα", + "systemMode": "Σύμφωνα με το σύστημα" + }, + "asset_one": "Οντότητα", + "asset_other": "Οντότητες", + "assetEvent_one": "Συμβάν Οντότητας", + "assetEvent_other": "Συμβάντα Οντοτήτων", + "backfill_one": "Backfill", + "backfill_other": "Backfills", + "browse": { + "auditLog": "Καταγραφή Ελέγχου", + "requiredActions": "Απαιτούμενες Ενέργειες", + "xcoms": "XComs" + }, + "collapseDetailsPanel": "Σύμπτυξη Πίνακα Λεπτομερειών", + "createdAssetEvent_one": "Δημιουργήθηκε Συμβάν Οντότητας", + "createdAssetEvent_other": "Δημιουργήθηκαν Συμβάντα Οντοτήτων", + "dag_one": "Dag", + "dag_other": "Dags", + "dagDetails": { + "catchup": "Catchup", + "dagRunTimeout": "Χρονικό Όριο Εκτέλεσης Dag", + "defaultArgs": "Προεπιλεγμένες Παράμετροι", + "description": "Περιγραφή", + "documentation": "Τεκμηρίωση Dag", + "fileLocation": "Τοποθεσία Αρχείου", + "hasTaskConcurrencyLimits": "Περιορισμοί ταυτόχρονων Εργασιών", + "lastExpired": "Τελευταία Λήξη", + "lastParseDuration": "Διάρκεια Τελευταίας Ανάλυσης", + "lastParsed": "Τελευταία Ανάλυση", + "latestDagVersion": "Τελευταία Έκδοση Dag", + "latestRun": "Τελευταία Εκτέλεση", + "maxActiveRuns": "Μέγιστες Ενεργές Εκτελέσεις", + "maxActiveTasks": "Μέγιστες Ενεργές Εργασίες", + "maxConsecutiveFailedDagRuns": "Μέγιστες Διαδοχικές Αποτυχημένες Εκτελέσεις Dag", + "nextRun": "Επόμενη Εκτέλεση", + "owner": "Ιδιοκτήτης", + "params": "Παράμετροι", + "schedule": "Πρόγραμμα", + "tags": "Ετικέτες" + }, + "dagId": "Dag ID", + "dagRun": { + "conf": "Ρυθμίσεις", + "dagVersions": "Έκδοση(εις) Dag", + "dataIntervalEnd": "Τέλος Διαστήματος Δεδομένων", + "dataIntervalStart": "Έναρξη Διαστήματος Δεδομένων", + "lastSchedulingDecision": "Τελευταία Απόφαση Προγραμματισμού", + "queuedAt": "Σε Ουρά Στις", + "runAfter": "Εκτέλεση Μετά", + "runType": "Τύπος Εκτέλεσης", + "sourceAssetEvent": "Συμβάν Πηγής Οντότητας", + "triggeredBy": "Ενεργοποιήθηκε Από", + "triggeringUser": "Όνομα Χρήστη Ενεργοποίησης" + }, + "dagRun_one": "Εκτέλεση Dag", + "dagRun_other": "Εκτελέσεις Dag", + "dagRunId": "ID Εκτέλεσης Dag", + "dagWarnings": "Προειδοποιήσεις/Σφάλματα Dag", + "defaultToGraphView": "Προεπιλογή σε γραφική προβολή", + "defaultToGridView": "Προεπιλογή σε πλέγμα", + "direction": "Κατεύθυνση", + "docs": { + "documentation": "Τεκμηρίωση", + "githubRepo": "Αποθετήριο GitHub", + "restApiReference": "REST API Αναφορά" + }, + "duration": "Διάρκεια", + "endDate": "Ημερομηνία Λήξης", + "error": { + "back": "Πίσω", + "defaultMessage": "Παρουσιάστηκε απρόσμενο σφάλμα", + "home": "Αρχική", + "notFound": "Η σελίδα δεν βρέθηκε", + "title": "Σφάλμα" + }, + "expand": { + "collapse": "Σύμπτυξη", + "expand": "Ανάπτυξη", + "hotkey": "e", + "tooltip": "Πατήστε {{hotkey}} για εναλλαγή ανάπτυξης" + }, + "expression": { + "all": "Όλα", + "and": "ΚΑΙ", + "any": "Οποιοδήποτε", + "or": "Ή" + }, + "filter": "Φίλτρο", + "filters": { + "durationFrom": "Διάρκεια Από", + "durationTo": "Διάρκεια Έως", + "logicalDateFrom": "Λογική Ημερομηνία Από", + "logicalDateTo": "Λογική Ημερομηνία Έως", + "runAfterFrom": "Εκτέλεση Μετά Από", + "runAfterTo": "Εκτέλεση Μετά Έως" + }, + "logicalDate": "Λογική Ημερομηνία", + "logout": "Αποσύνδεση", + "logoutConfirmation": "Πρόκειται να αποσυνδεθείτε από την εφαρμογή.", + "mapIndex": "Δείκτης Χάρτη", + "modal": { + "cancel": "Ακύρωση", + "confirm": "Επιβεβαίωση", + "delete": { + "button": "Διαγραφή", + "confirmation": "Είστε σίγουροι ότι θέλετε να διαγράψετε το {{resourceName}}; Αυτή η ενέργεια δεν μπορεί να αναιρεθεί." + } + }, + "nav": { + "admin": "Διαχείριση", + "assets": "Οντότητες", + "browse": "Περιήγηση", + "dags": "Dags", + "docs": "Τεκμηρίωση", + "home": "Αρχική", + "legacyFabViews": "Παλιές Προβολές", + "plugins": "Πρόσθετα", + "security": "Ασφάλεια" + }, + "noItemsFound": "Δεν βρέθηκε {{modelName}}", + "note": { + "add": "Προσθήκη σημείωσης", + "dagRun": "Σημείωση Εκτέλεσης Dag", + "label": "Σημείωση", + "placeholder": "Προσθέστε μια σημείωση...", + "taskInstance": "Σημείωση Εκτέλεσης Εργασίας" + }, + "pools": { + "deferred": "Αναβληθέν", + "open": "Ανοιχτό", + "pools_one": "pool", + "pools_other": "pools", + "queued": "Σε Ουρά", + "running": "Εκτελείται", + "scheduled": "Προγραμματισμένο" + }, + "reset": "Επαναφορά", + "runId": "ID Εκτέλεσης", + "runTypes": { + "asset_triggered": "Ενεργοποιήθηκε από Οντότητα", + "backfill": "Backfill", + "manual": "Χειροκίνητο", + "scheduled": "Προγραμματισμένο" + }, + "scroll": { + "direction": { + "bottom": "κάτω", + "top": "πάνω" + }, + "tooltip": "Πατήστε {{hotkey}} για κύλιση προς τα {{direction}}" + }, + "seconds": "{{count}}δ", + "security": { + "actions": "Ενέργειες", + "permissions": "Δικαιώματα", + "resources": "Πόροι", + "roles": "Ρόλοι", + "users": "Χρήστες" + }, + "selectLanguage": "Επιλογή Γλώσσας", + "showDetailsPanel": "Εμφάνιση Πίνακα Λεπτομερειών", + "source": { + "hide": "Απόκρυψη Πηγαίου Κώδικα", + "hotkey": "s", + "show": "Εμφάνιση Πηγαίου Κώδικα" + }, + "sourceAssetEvent_one": "Συμβάν Πηγής Οντότητας", + "sourceAssetEvent_other": "Συμβάντα Πηγής Οντοτήτων", + "startDate": "Ημερομηνία Έναρξης", + "state": "Κατάσταση", + "states": { + "deferred": "Αναβληθέν", + "failed": "Αποτυχία", + "no_status": "Χωρίς Κατάσταση", + "none": "Χωρίς Κατάσταση", + "planned": "Προγραμματισμένο", + "queued": "Σε Ουρά", + "removed": "Αφαιρέθηκε", + "restarting": "Επανεκκίνηση", + "running": "Εκτελείται", + "scheduled": "Προγραμματισμένο", + "skipped": "Παραλείφθηκε", + "success": "Επιτυχία", + "up_for_reschedule": "Προς Επαναπρογραμματισμό", + "up_for_retry": "Προς Επανάληψη", + "upstream_failed": "Αποτυχία Ανάντη" + }, + "table": { + "completedAt": "Ολοκληρώθηκε στις", + "createdAt": "Δημιουργήθηκε στις", + "filterByTag": "Φιλτράρισμα Dags κατά ετικέτα", + "filterColumns": "Φιλτράρισμα στηλών πίνακα", + "filterReset_one": "Επαναφορά φίλτρου", + "filterReset_other": "Επαναφορά φίλτρων", + "from": "Από", + "maxActiveRuns": "Μέγιστες Ενεργές Εκτελέσεις", + "noTagsFound": "Δεν βρέθηκαν ετικέτες", + "tagMode": { + "all": "Όλα", + "any": "Οποιοδήποτε" + }, + "tagPlaceholder": "Φιλτράρισμα κατά ετικέτα", + "to": "Έως" + }, + "task": { + "documentation": "Τεκμηρίωση Εργασίας", + "lastInstance": "Τελευταία Εκτέλεση", + "operator": "Τελεστής", + "triggerRule": "Κανόνας Ενεργοποίησης" + }, + "task_one": "Εργασία", + "task_other": "Εργασίες", + "taskGroup": "Ομάδα Εργασιών", + "taskId": "ID Εργασίας", + "taskInstance": { + "dagVersion": "Έκδοση Dag", + "executor": "Εκτελεστής", + "executorConfig": "Ρυθμίσεις Εκτελεστή", + "hostname": "Όνομα Υπολογιστή", + "maxTries": "Μέγιστες Προσπάθειες", + "pid": "PID", + "pool": "Pool", + "poolSlots": "Θέσεις Pool", + "priorityWeight": "Βάρος Προτεραιότητας", + "queue": "Ουρά", + "queuedWhen": "Σε Ουρά Στις", + "scheduledWhen": "Προγραμματίστηκε Στις", + "triggerer": { + "assigned": "Ανατεθειμένος triggerer", + "class": "Κλάση Trigger", + "createdAt": "Χρόνος δημιουργίας trigger", + "id": "ID Trigger", + "latestHeartbeat": "Τελευταίος παλμός triggerer", + "title": "Πληροφορίες Triggerer" + }, + "unixname": "Όνομα Unix" + }, + "taskInstance_one": "Εκτέλεση Εργασίας", + "taskInstance_other": "Εκτελέσεις Εργασίας", + "timeRange": { + "last12Hours": "Τελευταίες 12 Ώρες", + "last24Hours": "Τελευταίες 24 Ώρες", + "lastHour": "Τελευταία Ώρα", + "pastWeek": "Προηγούμενη Εβδομάδα" + }, + "timestamp": { + "hide": "Απόκρυψη Χρονικών Σημάνσεων", + "hotkey": "t", + "show": "Εμφάνιση Χρονικών Σημάνσεων" + }, + "timezone": "Ζώνη Ώρας", + "timezoneModal": { + "current-timezone": "Τρέχουσα ώρα σε", + "placeholder": "Επιλέξτε ζώνη ώρας", + "title": "Επιλογή Ζώνης Ώρας", + "utc": "UTC (Συντονισμένη Παγκόσμια Ώρα)" + }, + "toaster": { + "bulkDelete": { + "error": "Αποτυχία μαζικής διαγραφής {{resourceName}}", + "success": { + "description": "{{count}} {{resourceName}} διαγράφηκαν με επιτυχία. Κλειδιά: {{keys}}", + "title": "Υποβλήθηκε αίτημα μαζικής διαγραφής {{resourceName}}" + } + }, + "create": { + "error": "Αποτυχία δημιουργίας {{resourceName}}", + "success": { + "description": "Το {{resourceName}} δημιουργήθηκε με επιτυχία.", + "title": "Υποβλήθηκε αίτημα δημιουργίας {{resourceName}}" + } + }, + "delete": { + "error": "Αποτυχία διαγραφής {{resourceName}}", + "success": { + "description": "Το {{resourceName}} διαγράφηκε με επιτυχία.", + "title": "Υποβλήθηκε αίτημα διαγραφής {{resourceName}}" + } + }, + "import": { + "error": "Αποτυχία εισαγωγής {{resourceName}}", + "success": { + "description": "{{count}} {{resourceName}} εισήχθησαν με επιτυχία.", + "title": "Υποβλήθηκε αίτημα εισαγωγής {{resourceName}}" + } + }, + "update": { + "error": "Αποτυχία ενημέρωσης {{resourceName}}", + "success": { + "description": "Το {{resourceName}} ενημερώθηκε με επιτυχία.", + "title": "Υποβλήθηκε αίτημα ενημέρωσης {{resourceName}}" + } + } + }, + "total": "Σύνολο {{state}}", + "triggered": "Ενεργοποιήθηκε", + "tryNumber": "Αριθμός Προσπάθειας", + "user": "Χρήστης", + "wrap": { + "hotkey": "w", + "tooltip": "Πατήστε {{hotkey}} για εναλλαγή αναδίπλωσης", + "unwrap": "Ξεδίπλωμα", + "wrap": "Αναδίπλωση" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/components.json new file mode 100644 index 0000000000000..36399b813fdfc --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/components.json @@ -0,0 +1,134 @@ +{ + "backfill": { + "affected_one": "1 εκτέλεση θα ενεργοποιηθεί.", + "affected_other": "{{count}} εκτελέσεις θα ενεργοποιηθούν.", + "affectedNone": "Δεν βρέθηκαν εκτελέσεις που να ταιριάζουν με τα κριτήρια.", + "allRuns": "Όλες οι Εκτελέσεις", + "backwards": "Αντίστροφη Εκτέλεση", + "dateRange": "Εύρος Ημερομηνιών", + "errorStartDateBeforeEndDate": "Η ημερομηνία έναρξης πρέπει να είναι πριν την ημερομηνία λήξης", + "maxRuns": "Μέγιστες Ενεργές Εκτελέσεις", + "missingAndErroredRuns": "Εκτελέσεις που λείπουν ή απέτυχαν", + "missingRuns": "Εκτελέσεις που λείπουν", + "reprocessBehavior": "Συμπεριφορά Επανεπεξεργασίας", + "run": "Εκτέλεση Backfill", + "selectDescription": "Εκτελέστε αυτό το Dag για ένα εύρος ημερομηνιών", + "selectLabel": "Backfill", + "title": "Εκτέλεση Backfill", + "toaster": { + "success": { + "description": "Οι εργασίες backfill ενεργοποιήθηκαν με επιτυχία.", + "title": "Το Backfill δημιουργήθηκε" + } + }, + "tooltip": "Το Backfill απαιτεί πρόγραμμα", + "unpause": "Αναίρεση παύσης του {{dag_display_name}} κατά την ενεργοποίηση", + "validation": { + "datesRequired": "Πρέπει να δοθούν και η ημερομηνία έναρξης και λήξης του διαστήματος δεδομένων.", + "startBeforeEnd": "Η ημερομηνία έναρξης πρέπει να είναι μικρότερη ή ίση με την ημερομηνία λήξης." + } + }, + "banner": { + "backfillInProgress": "Το Backfill είναι σε εξέλιξη", + "cancel": "Ακύρωση backfill", + "pause": "Παύση backfill", + "unpause": "Αναίρεση παύσης backfill" + }, + "clipboard": { + "copy": "Αντιγραφή" + }, + "close": "Κλείσιμο", + "configForm": { + "advancedOptions": "Προχωρημένες Επιλογές", + "configJson": "Ρυθμίσεις JSON", + "invalidJson": "Μη έγκυρη μορφή JSON: {{errorMessage}}" + }, + "dagWarnings": { + "error_one": "1 Σφάλμα", + "error_other": "{{count}} Σφάλματα", + "errorAndWarning": "1 Σφάλμα και {{warningText}}", + "warning_one": "1 Προειδοποίηση", + "warning_other": "{{count}} Προειδοποιήσεις" + }, + "durationChart": { + "duration": "Διάρκεια (δευτερόλεπτα)", + "lastDagRun_one": "Τελευταία Εκτέλεση Dag", + "lastDagRun_other": "Τελευταίες {{count}} Εκτελέσεις Dag", + "lastTaskInstance_one": "Τελευταία Εκτέλεση Εργασίας", + "lastTaskInstance_other": "Τελευταίες {{count}} Εκτελέσεις Εργασίας", + "queuedDuration": "Διάρκεια σε Ουρά", + "runAfter": "Εκτέλεση Μετά", + "runDuration": "Διάρκεια Εκτέλεσης" + }, + "fileUpload": { + "files_one": "{{count}} αρχείο", + "files_other": "{{count}} αρχεία" + }, + "flexibleForm": { + "placeholder": "Επιλέξτε Τιμή", + "placeholderArray": "Εισάγετε κάθε συμβολοσειρά σε νέα γραμμή", + "placeholderExamples": "Ξεκινήστε να πληκτρολογείτε για να δείτε επιλογές", + "placeholderMulti": "Επιλέξτε μία ή περισσότερες τιμές", + "validationErrorArrayNotArray": "Η τιμή πρέπει να είναι πίνακας.", + "validationErrorArrayNotNumbers": "Όλα τα στοιχεία του πίνακα πρέπει να είναι αριθμοί.", + "validationErrorArrayNotObject": "Όλα τα στοιχεία του πίνακα πρέπει να είναι αντικείμενα.", + "validationErrorRequired": "Αυτό το πεδίο είναι υποχρεωτικό" + }, + "graph": { + "directionDown": "Από Πάνω προς Κάτω", + "directionLeft": "Από Δεξιά προς Αριστερά", + "directionRight": "Από Αριστερά προς Δεξιά", + "directionUp": "Από Κάτω προς Πάνω", + "downloadImage": "Λήψη εικόνας γραφήματος", + "downloadImageError": "Αποτυχία λήψης εικόνας γραφήματος.", + "downloadImageErrorTitle": "Αποτυχία Λήψης", + "otherDagRuns": "+Άλλες Εκτελέσεις Dag", + "taskCount_one": "{{count}} Εργασία", + "taskCount_other": "{{count}} Εργασίες", + "taskGroup": "Ομάδα Εργασιών" + }, + "limitedList": "+{{count}} ακόμα", + "logs": { + "file": "Αρχείο", + "location": "γραμμή {{line}} στο {{name}}" + }, + "reparseDag": "Επαναανάλυση Dag", + "sortedAscending": "αύξουσα ταξινόμηση", + "sortedDescending": "φθίνουσα ταξινόμηση", + "sortedUnsorted": "μη ταξινομημένο", + "taskTries": "Προσπάθειες Εργασίας", + "toggleCardView": "Εμφάνιση κάρτας", + "toggleTableView": "Εμφάνιση πίνακα", + "triggerDag": { + "button": "Ενεργοποίηση", + "loading": "Φόρτωση πληροφοριών Dag...", + "loadingFailed": "Αποτυχία φόρτωσης πληροφοριών Dag. Παρακαλώ δοκιμάστε ξανά.", + "runIdHelp": "Προαιρετικό - θα δημιουργηθεί αν δεν δοθεί", + "selectDescription": "Ενεργοποιήστε μία εκτέλεση αυτού του Dag", + "selectLabel": "Μονή Εκτέλεση", + "title": "Ενεργοποίηση Dag", + "toaster": { + "success": { + "description": "Η εκτέλεση Dag ενεργοποιήθηκε με επιτυχία.", + "title": "Η Εκτέλεση Dag Ενεργοποιήθηκε" + } + }, + "unpause": "Αναίρεση παύσης του {{dagDisplayName}} κατά την ενεργοποίηση" + }, + "trimText": { + "details": "Λεπτομέρειες", + "empty": "Κενό", + "noContent": "Δεν υπάρχουν διαθέσιμα δεδομένα." + }, + "versionDetails": { + "bundleLink": "Σύνδεσμος Πακέτου", + "bundleName": "Όνομα Πακέτου", + "bundleVersion": "Έκδοση Πακέτου", + "createdAt": "Δημιουργήθηκε στις", + "versionId": "ID Έκδοσης" + }, + "versionSelect": { + "dagVersion": "Έκδοση Dag", + "versionCode": "v{{versionCode}}" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json new file mode 100644 index 0000000000000..12f472a19473b --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json @@ -0,0 +1,154 @@ +{ + "allRuns": "Όλες οι Εκτελέσεις", + "blockingDeps": { + "dependency": "Εξάρτηση", + "reason": "Αιτία", + "title": "Εξαρτήσεις που εμποδίζουν τον προγραμματισμό της εργασίας" + }, + "calendar": { + "daily": "Καθημερινά", + "hourly": "Ωριαία", + "legend": { + "less": "Λιγότερο", + "mixed": "Μικτό", + "more": "Περισσότερο" + }, + "navigation": { + "nextMonth": "Επόμενος μήνας", + "nextYear": "Επόμενο έτος", + "previousMonth": "Προηγούμενος μήνας", + "previousYear": "Προηγούμενο έτος" + }, + "noData": "Δεν υπάρχουν διαθέσιμα δεδομένα", + "noFailedRuns": "No failed runs", + "noRuns": "Δεν υπάρχουν εκτελέσεις", + "totalRuns": "Σύνολο Εκτελέσεων", + "week": "Εβδομάδα {{weekNumber}}", + "weekdays": { + "friday": "Παρ", + "monday": "Δευ", + "saturday": "Σαβ", + "sunday": "Κυρ", + "thursday": "Πεμ", + "tuesday": "Τρι", + "wednesday": "Τετ" + } + }, + "code": { + "bundleUrl": "Σύνδεσμος Πακέτου", + "noCode": "Δεν βρέθηκε Κώδικας", + "parseDuration": "Διάρκεια Ανάλυσης:", + "parsedAt": "Αναλύθηκε στις:" + }, + "extraLinks": "Επιπλέον Σύνδεσμοι", + "grid": { + "buttons": { + "resetToLatest": "Επαναφορά στα πιο πρόσφατα", + "toggleGroup": "Εναλλαγή ομάδας" + } + }, + "header": { + "buttons": { + "advanced": "Για προχωρημένους", + "dagDocs": "Τεκμήρια Dag" + } + }, + "logs": { + "allLevels": "Όλα τα Επίπεδα Καταγραφής", + "allSources": "Όλες οι Πηγές", + "critical": "ΚΡΙΣΙΜΟ", + "debug": "DEBUG", + "error": "ΣΦΑΛΜΑ", + "fullscreen": { + "button": "Πλήρης οθόνη", + "tooltip": "Πατήστε {{hotkey}} για πλήρη οθόνη" + }, + "info": "INFO", + "noTryNumber": "Χωρίς αριθμό προσπάθειας", + "settings": "Ρυθμίσεις Καταγραφής", + "viewInExternal": "Προβολή καταγραφών στο {{name}} (προσπάθεια {{attempt}})", + "warning": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ" + }, + "navigation": { + "navigation": "Πλοήγηση: Shift+{{arrow}}", + "toggleGroup": "Εναλλαγή ομάδας: Space" + }, + "overview": { + "buttons": { + "failedRun_one": "Αποτυχημένη Εκτέλεση", + "failedRun_other": "Αποτυχημένες Εκτελέσεις", + "failedTask_one": "Αποτυχημένη Εργασία", + "failedTask_other": "Αποτυχημένες Εργασίες", + "failedTaskInstance_one": "Αποτυχημένη Στιγμιαία Κατάσταση Εργασίας", + "failedTaskInstance_other": "Αποτυχημένες Στιγμιαίες Καταστάσεις Εργασίας" + }, + "charts": { + "assetEvent_one": "Δημιουργήθηκε Συμβάν Οντότητας", + "assetEvent_other": "Δημιουργήθηκαν Συμβάντα Οντοτήτων" + }, + "failedLogs": { + "hideLogs": "Απόκρυψη Καταγραφών", + "showLogs": "Εμφάνιση Καταγραφών", + "title": "Πρόσφατες Καταγραφές Αποτυχημένων Εργασιών", + "viewFullLogs": "Προβολή πλήρων καταγραφών" + } + }, + "panel": { + "buttons": { + "options": "Επιλογές", + "showGantt": "Εμφάνιση Gantt", + "showGraphShortcut": "Εμφάνιση Γραφήματος (Πατήστε g)", + "showGridShortcut": "Εμφάνιση Πλέγματος (Πατήστε g)" + }, + "dagRuns": { + "label": "Αριθμός Εκτελέσεων Dag" + }, + "dependencies": { + "label": "Εξαρτήσεις", + "options": { + "allDagDependencies": "Όλες οι Εξαρτήσεις Dag", + "externalConditions": "Εξωτερικές συνθήκες", + "onlyTasks": "Μόνο εργασίες" + }, + "placeholder": "Εξαρτήσεις" + }, + "graphDirection": { + "label": "Κατεύθυνση Γραφήματος" + } + }, + "paramsFailed": "Αποτυχία φόρτωσης παραμέτρων", + "parse": { + "toaster": { + "error": { + "description": "Το αίτημα ανάλυσης Dag απέτυχε. Ενδέχεται να υπάρχουν εκκρεμή αιτήματα ανάλυσης προς επεξεργασία.", + "title": "Αποτυχία Επανανάλυσης Dag" + }, + "success": { + "description": "Το Dag θα επαναναλυθεί σύντομα.", + "title": "Το αίτημα επανανάλυσης υποβλήθηκε επιτυχώς" + } + } + }, + "tabs": { + "assetEvents": "Συμβάντα Οντοτήτων", + "auditLog": "Καταγραφή Ελέγχου", + "backfills": "Backfills", + "calendar": "Ημερολόγιο", + "code": "Κώδικας", + "details": "Λεπτομέρειες", + "logs": "Καταγραφές", + "mappedTaskInstances_one": "Στιγμιαία Κατάσταση Εργασίας [{{count}}]", + "mappedTaskInstances_other": "Στιγμιαίες Καταστάσεις Εργασίας [{{count}}]", + "overview": "Επισκόπηση", + "renderedTemplates": "Αποδοθέντα Πρότυπα", + "requiredActions": "Απαιτούμενες Ενέργειες", + "runs": "Εκτελέσεις", + "taskInstances": "Στιγμιαίες Καταστάσεις Εργασίας", + "tasks": "Εργασίες", + "xcom": "XCom" + }, + "taskGroups": { + "collapseAll": "Σύμπτυξη όλων των ομάδων εργασιών", + "expandAll": "Ανάπτυξη όλων των ομάδων εργασιών" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/dags.json new file mode 100644 index 0000000000000..7b127ac0af95d --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/dags.json @@ -0,0 +1,96 @@ +{ + "assetSchedule": "{{count}} από {{total}} οντότητες ενημερώθηκαν", + "dagActions": { + "delete": { + "button": "Διαγραφή Dag", + "warning": "Αυτό θα αφαιρέσει όλα τα μεταδεδομένα που σχετίζονται με το Dag, συμπεριλαμβανομένων των Εκτελέσεων και των Εργασιών." + } + }, + "favoriteDag": "Αγαπημένο Dag", + "filters": { + "allRunTypes": "Όλοι οι τύποι Εκτελέσεων", + "allStates": "Όλες οι καταστάσεις", + "favorite": { + "all": "Όλα", + "favorite": "Αγαπημένο", + "unfavorite": "Μη αγαπημένα" + }, + "paused": { + "active": "Ενεργό", + "all": "Όλα", + "paused": "Σε παύση" + }, + "runIdPatternFilter": "Αναζήτηση Εκτελέσεων Dag" + }, + "ownerLink": "Σύνδεσμος κατόχου για {{owner}}", + "runAndTaskActions": { + "affectedTasks": { + "noItemsFound": "Δεν βρέθηκαν εργασίες.", + "title": "Επηρεαζόμενες Εργασίες: {{count}}" + }, + "clear": { + "button": "Εκκαθάριση {{type}}", + "buttonTooltip": "Πατήστε shift+c για εκκαθάριση", + "error": "Αποτυχία εκκαθάρισης {{type}}", + "title": "Εκκαθάριση {{type}}" + }, + "delete": { + "button": "Διαγραφή {{type}}", + "dialog": { + "resourceName": "{{type}} {{id}}", + "title": "Διαγραφή {{type}}", + "warning": "Αυτό θα αφαιρέσει όλα τα μεταδεδομένα που σχετίζονται με το {{type}}." + }, + "error": "Σφάλμα κατά τη διαγραφή του {{type}}", + "success": { + "description": "Το αίτημα διαγραφής του {{type}} ολοκληρώθηκε με επιτυχία.", + "title": "Το {{type}} διαγράφηκε με επιτυχία" + } + }, + "markAs": { + "button": "Σήμανση {{type}} ως...", + "buttonTooltip": { + "failed": "Πατήστε shift+f για σήμανση ως αποτυχία", + "success": "Πατήστε shift+s για σήμανση ως επιτυχία" + }, + "title": "Σήμανση {{type}} ως {{state}}" + }, + "options": { + "downstream": "Kάθοδος", + "existingTasks": "Εκκαθάριση υπαρχουσών εργασιών", + "future": "Μελλοντικές", + "onlyFailed": "Εκκαθάριση μόνο αποτυχημένων εργασιών", + "past": "Παρελθόν", + "queueNew": "Προσθήκη νέων εργασιών στην ουρά", + "runOnLatestVersion": "Εκτέλεση με την τελευταία έκδοση του bundle", + "upstream": "Άνοδος" + } + }, + "search": { + "advanced": "Σύνθετη Αναζήτηση", + "clear": "Εκκαθάριση αναζήτησης", + "dags": "Αναζήτηση Dags", + "hotkey": "+K", + "tasks": "Αναζήτηση Εργασιών" + }, + "sort": { + "displayName": { + "asc": "Ταξινόμηση κατά Όνομα (A-Z)", + "desc": "Ταξινόμηση κατά Όνομα (Z-A)" + }, + "lastRunStartDate": { + "asc": "Ταξινόμηση κατά Ημερομηνία Έναρξης Τελευταίας Εκτέλεσης (Παλαιότερο-Νεότερο)", + "desc": "Ταξινόμηση κατά Ημερομηνία Έναρξης Τελευταίας Εκτέλεσης (Νεότερο-Παλαιότερο)" + }, + "lastRunState": { + "asc": "Ταξινόμηση κατά Κατάσταση Τελευταίας Εκτέλεσης (A-Z)", + "desc": "Ταξινόμηση κατά Κατάσταση Τελευταίας Εκτέλεσης (Z-A)" + }, + "nextDagRun": { + "asc": "Ταξινόμηση κατά Επόμενη Εκτέλεση Dag (Παλαιότερο-Νεότερο)", + "desc": "Ταξινόμηση κατά Επόμενη Εκτέλεση Dag (Νεότερο-Παλαιότερο)" + }, + "placeholder": "Ταξινόμηση κατά" + }, + "unfavoriteDag": "Αφαίρεση από τα αγαπημένα Dag" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/dashboard.json new file mode 100644 index 0000000000000..1ff8e42424699 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/dashboard.json @@ -0,0 +1,45 @@ +{ + "favorite": { + "favoriteDags_one": "Πρώτο αγαπημένο Dag ({{count}})", + "favoriteDags_other": "Πρώτα αγαπημένα Dag ({{count}})", + "noDagRuns": "Δεν υπάρχει ακόμη DagRun για αυτό το dag.", + "noFavoriteDags": "Δεν υπάρχουν αγαπημένα ακόμα. Κάντε κλικ στο εικονίδιο αστεριού δίπλα σε ένα Dag στη λίστα για να το προσθέσετε στα αγαπημένα σας." + }, + "group": "Ομάδα", + "health": { + "dagProcessor": "Επεξεργαστής Dag", + "health": "Υγεία", + "healthy": "Υγιές", + "lastHeartbeat": "Τελευταίος Παλμός", + "metaDatabase": "Μετα-Βάση Δεδομένων", + "scheduler": "Προγραμματιστής", + "status": "Κατάσταση", + "triggerer": "Ενεργοποιητής", + "unhealthy": "Μη υγιές" + }, + "history": "Ιστορικό", + "importErrors": { + "dagImportError_one": "Σφάλμα Εισαγωγής Dag", + "dagImportError_other": "Σφάλματα Εισαγωγής Dag", + "searchByFile": "Αναζήτηση κατά αρχείο", + "timestamp": "Χρονοσήμανση" + }, + "managePools": "Διαχείριση Pools", + "noAssetEvents": "Δεν βρέθηκαν Συμβάντα Οντοτήτων.", + "poolSlots": "Θέσεις Pool", + "sortBy": { + "newestFirst": "Νεότερα Πρώτα", + "oldestFirst": "Παλαιότερα Πρώτα" + }, + "source": "Πηγή", + "stats": { + "activeDags": "Ενεργά Dag", + "failedDags": "Αποτυχημένα Dag", + "queuedDags": "Dag σε Ουρά", + "requiredActions": "Απαιτούμενες Ενέργειες", + "runningDags": "Εκτελούμενα Dag", + "stats": "Στατιστικά" + }, + "uri": "URI", + "welcome": "Καλώς ήρθατε" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/hitl.json new file mode 100644 index 0000000000000..d93ea3c216fe8 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/hitl.json @@ -0,0 +1,34 @@ +{ + "filters": { + "response": { + "all": "Όλα", + "pending": "Σε εκκρεμότητα", + "received": "Εξετασμένα" + } + }, + "requiredAction_one": "Απαιτούμενη Ενέργεια", + "requiredAction_other": "Απαιτούμενες Ενέργειες", + "requiredActionCount_one": "Απαιτούμενη Ενέργεια ({{count}})", + "requiredActionCount_other": "Απαιτούμενες Ενέργειες ({{count}})", + "requiredActionState": "Κατάσταση Απαιτούμενης Ενέργειας", + "response": { + "error": "Αποτυχημένη απάντηση", + "optionsDescription": "Επιλέξτε τις επιλογές σας για αυτήν την εκτέλεση εργασίας", + "optionsLabel": "Επιλογές", + "received": "Η απάντηση ελήφθη στις ", + "respond": "Απάντηση", + "success": "Η απάντηση για το {{taskId}} ήταν επιτυχής", + "title": "Εκτέλεση Εργασίας με Παρέμβαση Χρήστη - {{taskId}}" + }, + "state": { + "approvalReceived": "Έγκριση Ελήφθη", + "approvalRequired": "Απαιτείται Έγκριση", + "choiceReceived": "Επιλογή Ελήφθη", + "choiceRequired": "Απαιτείται Επιλογή", + "noResponseReceived": "Δεν Ελήφθη Απάντηση", + "rejectionReceived": "Απόρριψη Ελήφθη", + "responseReceived": "Απάντηση Ελήφθη", + "responseRequired": "Απαιτείται Απάντηση" + }, + "subject": "Θέμα" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/tasks.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/tasks.json new file mode 100644 index 0000000000000..8067fd67ad5a3 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/tasks.json @@ -0,0 +1,10 @@ +{ + "mapped": "Χαρτογραφημένο", + "notMapped": "Μη χαρτογραφημένο", + "retries": "Επαναλήψεις", + "searchTasks": "Αναζήτηση εργασιών", + "selectMapped": "Επιλογή χαρτογραφημένων", + "selectOperator": "Επιλογή τελεστή", + "selectRetryValues": "Επιλογή τιμών επανάληψης", + "selectTriggerRules": "Επιλογή κανόνων ενεργοποίησης" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/admin.json index 0eb5df5b8a22d..894fd382f2c1d 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/admin.json @@ -72,7 +72,6 @@ "tooltip": "Delete selected connections" }, "formActions": { - "reset": "Reset", "save": "Save" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json index defe64cce63c1..bcf197f1ddd62 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json @@ -99,17 +99,12 @@ "any": "Any", "or": "OR" }, + "filter": "Filter", "filters": { - "dagDisplayNamePlaceholder": "Filter by Dag", - "keyPlaceholder": "Filter by XCom key", - "logicalDateFromPlaceholder": "Logical Date From", - "logicalDateToPlaceholder": "Logical Date To", - "mapIndexPlaceholder": "Filter by Map Index", - "runAfterFromPlaceholder": "Run After From", - "runAfterToPlaceholder": "Run After To", - "runIdPlaceholder": "Filter by Run ID", - "taskIdPlaceholder": "Filter by Task ID", - "triggeringUserPlaceholder": "Filter by triggering user" + "logicalDateFrom": "Logical Date From", + "logicalDateTo": "Logical Date To", + "runAfterFrom": "Run After From", + "runAfterTo": "Run After To" }, "logicalDate": "Logical Date", "logout": "Logout", @@ -151,6 +146,7 @@ "running": "Running", "scheduled": "Scheduled" }, + "reset": "Reset", "runId": "Run ID", "runTypes": { "asset_triggered": "Asset Triggered", @@ -165,7 +161,6 @@ }, "tooltip": "Press {{hotkey}} to scroll to {{direction}}" }, - "seconds": "{{count}}s", "security": { "actions": "Actions", "permissions": "Permissions", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/components.json index 3a56657187a36..eed0d7784c716 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/components.json @@ -6,8 +6,6 @@ "allRuns": "All Runs", "backwards": "Run Backwards", "dateRange": "Date Range", - "dateRangeFrom": "From", - "dateRangeTo": "To", "errorStartDateBeforeEndDate": "Start Date must be before the End Date", "maxRuns": "Max Active Runs", "missingAndErroredRuns": "Missing and Errored Runs", @@ -88,6 +86,14 @@ "taskGroup": "Task Group" }, "limitedList": "+{{count}} more", + "limitedList.allItems": "All {{count}} items:", + "limitedList.allTags_one": "All Tags (1)", + "limitedList.allTags_other": "All Tags ({{count}})", + "limitedList.clickToInteract": "Click a tag to filter Dags", + "limitedList.clickToOpenFull": "Click \"+{{count}} more\" to open full view", + "limitedList.copyPasteText": "You can copy and paste the text above", + "limitedList.showingItems_one": "Showing 1 item", + "limitedList.showingItems_other": "Showing {{count}} items", "logs": { "file": "File", "location": "line {{line}} in {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json index fd1eef88f9518..8085fcb942d81 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json @@ -10,6 +10,7 @@ "hourly": "Hourly", "legend": { "less": "Less", + "mixed": "Mixed", "more": "More" }, "navigation": { @@ -19,6 +20,7 @@ "previousYear": "Previous year" }, "noData": "No data available", + "noFailedRuns": "No failed runs", "noRuns": "No runs", "totalRuns": "Total Runs", "week": "Week {{weekNumber}}", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/admin.json index 48e33e4fb28c3..92b0a632dad9b 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/admin.json @@ -75,7 +75,6 @@ "tooltip": "Eliminar conexiones seleccionadas" }, "formActions": { - "reset": "Restablecer", "save": "Guardar" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/common.json index 4c6784f9ef614..9424d92f62d39 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/common.json @@ -44,6 +44,7 @@ "fileLocation": "Ubicación del Archivo", "hasTaskConcurrencyLimits": "Tiene límites de concurrencia de áreas", "lastExpired": "Último Expirado", + "lastParseDuration": "Duración del último parseo", "lastParsed": "Último Parseado", "latestDagVersion": "Última Versión del Dag", "latestRun": "Última Ejecución", @@ -104,16 +105,12 @@ "any": "Cualquiera", "or": "O" }, + "filter": "Filtro", "filters": { - "dagDisplayNamePlaceholder": "Filtrar por Dag", - "keyPlaceholder": "Filtrar por Clave de XCom", - "logicalDateFromPlaceholder": "Fecha Lógica Desde", - "logicalDateToPlaceholder": "Fecha Lógica Hasta", - "mapIndexPlaceholder": "Filtrar por Índice de Mapa", - "runAfterFromPlaceholder": "Ejecutar Después Desde", - "runAfterToPlaceholder": "Ejecutar Después Hasta", - "runIdPlaceholder": "Filtrar por ID de Ejecución", - "taskIdPlaceholder": "Filtrar por ID de Tarea" + "logicalDateFrom": "Fecha Lógica Desde", + "logicalDateTo": "Fecha Lógica Hasta", + "runAfterFrom": "Ejecutar Después Desde", + "runAfterTo": "Ejecutar Después Hasta" }, "logicalDate": "Fecha Lógica", "logout": "Cerrar Sesión", @@ -156,6 +153,7 @@ "running": "En Ejecución", "scheduled": "Programado" }, + "reset": "Restablecer", "runId": "ID de la corrida", "runTypes": { "asset_triggered": "Asset Activado", @@ -170,7 +168,6 @@ }, "tooltip": "Presiona {{hotkey}} para desplazarte a {{direction}}" }, - "seconds": "{{count}}s", "security": { "actions": "Acciones", "permissions": "Permisos", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/components.json index 52d40f4b79f84..20f31033ee064 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/components.json @@ -7,8 +7,6 @@ "allRuns": "Todas las Ejecuciones", "backwards": "Ejecutar Hacia Atrás", "dateRange": "Rango de Fechas", - "dateRangeFrom": "Desde", - "dateRangeTo": "Hasta", "errorStartDateBeforeEndDate": "La Fecha Inicial debe ser antes de la Fecha Final", "maxRuns": "Máximo de Ejecuciones Activas", "missingAndErroredRuns": "Ejecutaciones Faltantes y con Errores", @@ -97,6 +95,11 @@ "taskGroup": "Grupo de Tareas" }, "limitedList": "+{{count}} más", + "limitedList.allItems": "Todos los {{count}} elementos:", + "limitedList.clickToInteract": "Haz clic en una etiqueta para filtrar Dags", + "limitedList.clickToOpenFull": "Haz clic en \"+{{count}} más\" para ver la lista completa", + "limitedList.copyPasteText": "Puedes copiar y pegar el texto de arriba", + "limitedList.showingItems": "Mostrando {{count}} elementos", "logs": { "file": "Archivo", "location": "línea {{line}} en {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json index eb7f127a60ac9..6b2bde8d47570 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json @@ -35,6 +35,7 @@ "code": { "bundleUrl": "URL del Bundle", "noCode": "No se encontró código", + "parseDuration": "Duración del parseo:", "parsedAt": "Parseado en:" }, "extraLinks": "Enlaces Extra", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/tasks.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/tasks.json new file mode 100644 index 0000000000000..391e18c578d6f --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/tasks.json @@ -0,0 +1,10 @@ +{ + "mapped": "Mapeado", + "notMapped": "No mapeado", + "retries": "Reintentos", + "searchTasks": "Buscar tareas", + "selectMapped": "Seleccionar mapeados", + "selectOperator": "Seleccionar operadores", + "selectRetryValues": "Seleccionar valores de reintento", + "selectTriggerRules": "Seleccionar reglas de Trigger" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/admin.json index a926dc7a07737..ebd444b1666c2 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/admin.json @@ -19,11 +19,14 @@ "host": "Hôte", "port": "Port" }, + "connection_many": "Connexions", "connection_one": "Connexion", "connection_other": "Connexions", "delete": { + "deleteConnection_many": "Supprimer {{count}} connexions", "deleteConnection_one": "Supprimer 1 connexion", "deleteConnection_other": "Supprimer {{count}} connexions", + "firstConfirmMessage_many": "Vous êtes sur le point de supprimer les connexions suivantes :", "firstConfirmMessage_one": "Vous êtes sur le point de supprimer la connexion suivante :", "firstConfirmMessage_other": "Vous êtes sur le point de supprimer les connexions suivantes :", "title": "Supprimer la Connexion" @@ -72,13 +75,13 @@ "tooltip": "Supprimer les connexions sélectionnées" }, "formActions": { - "reset": "Réinitialiser", "save": "Sauvegarder" }, "plugins": { "columns": { "source": "Source" }, + "importError_many": "Erreurs d'importation de plugin", "importError_one": "Erreur d'importation de plugin", "importError_other": "Erreurs d'importation de plugins", "searchPlaceholder": "Rechercher par fichier" @@ -100,6 +103,7 @@ "slots": "Slots" }, "noPoolsFound": "Aucun pool trouvé", + "pool_many": "Pools", "pool_one": "Pool", "pool_other": "Pools", "searchPlaceholder": "Rechercher des Pools", @@ -121,8 +125,10 @@ "isEncrypted": "Est chiffrée" }, "delete": { + "deleteVariable_many": "Supprimer {{count}} Variables", "deleteVariable_one": "Supprimer 1 Variable", "deleteVariable_other": "Supprimer {{count}} Variables", + "firstConfirmMessage_many": "Vous êtes sur le point de supprimer les variables suivantes :", "firstConfirmMessage_one": "Vous êtes sur le point de supprimer la variable suivante :", "firstConfirmMessage_other": "Vous êtes sur le point de supprimer les variables suivantes :", "title": "Supprimer la Variable", @@ -161,6 +167,7 @@ }, "noRowsMessage": "Aucune variable trouvée", "searchPlaceholder": "Rechercher des Variables", + "variable_many": "Variables", "variable_one": "Variable", "variable_other": "Variables" } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/common.json index e118dbf035839..fe2002b5c0f68 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/common.json @@ -7,10 +7,20 @@ "Providers": "Providers", "Variables": "Variables" }, + "allOperators": "Tous les opérateurs", + "appearance": { + "appearance": "Apparence", + "darkMode": "Mode sombre", + "lightMode": "Mode clair", + "systemMode": "Suivre les paramètres du système" + }, + "asset_many": "Assets", "asset_one": "Asset", "asset_other": "Assets", + "assetEvent_many": "Événements d'Asset", "assetEvent_one": "Événement d'Asset", "assetEvent_other": "Événements d'Asset", + "backfill_many": "Rattrapages", "backfill_one": "Rattrapage", "backfill_other": "Rattrapages", "browse": { @@ -19,8 +29,10 @@ "xcoms": "XComs" }, "collapseDetailsPanel": "Replier le panneau des détails", + "createdAssetEvent_many": "Événements d'Asset créés", "createdAssetEvent_one": "Événement d'Asset créé", "createdAssetEvent_other": "Événements d'Asset créés", + "dag_many": "Dags", "dag_one": "Dag", "dag_other": "Dags", "dagDetails": { @@ -32,6 +44,7 @@ "fileLocation": "Emplacement du fichier", "hasTaskConcurrencyLimits": "Limites de concurrence par tâche", "lastExpired": "Date d'expiration", + "lastParseDuration": "Dernière durée d'analyse", "lastParsed": "Dernière analyse", "latestDagVersion": "Dernière version du Dag", "latestRun": "Dernière exécution", @@ -58,6 +71,7 @@ "triggeredBy": "Déclenché par", "triggeringUser": "Nom de l'utilisateur déclencheur" }, + "dagRun_many": "Exécutions de Dag", "dagRun_one": "Exécution de Dag", "dagRun_other": "Exécutions de Dag", "dagRunId": "ID d'exécution du Dag", @@ -91,16 +105,12 @@ "any": "N'importe lequel", "or": "Ou" }, + "filter": "Filtre", "filters": { - "dagDisplayNamePlaceholder": "Filtrer par Dag", - "keyPlaceholder": "Filtrer par clé XCom", - "logicalDateFromPlaceholder": "Date logique de début", - "logicalDateToPlaceholder": "Date logique de fin", - "mapIndexPlaceholder": "Filtrer par Map Index", - "runAfterFromPlaceholder": "Exécuté après - de", - "runAfterToPlaceholder": "Exécuté après - à", - "runIdPlaceholder": "Filtrer par ID d'exécution", - "taskIdPlaceholder": "Filtrer par ID de tâche" + "logicalDateFrom": "Date logique de début", + "logicalDateTo": "Date logique de fin", + "runAfterFrom": "Exécuté après - de", + "runAfterTo": "Exécuté après - à" }, "logicalDate": "Date logique", "logout": "Déconnexion", @@ -136,12 +146,14 @@ "pools": { "deferred": "Différé", "open": "Libre", + "pools_many": "Pools", "pools_one": "Pool", "pools_other": "Pools", "queued": "En file", "running": "En cours", "scheduled": "Planifié" }, + "reset": "Réinitialiser", "runId": "ID d'exécution", "runTypes": { "asset_triggered": "Déclenché par Asset", @@ -156,7 +168,6 @@ }, "tooltip": "Appuyez sur {{hotkey}} pour faire défiler vers le {{direction}}" }, - "seconds": "{{count}}s", "security": { "actions": "Actions", "permissions": "Permissions", @@ -171,6 +182,7 @@ "hotkey": "s", "show": "Afficher la source" }, + "sourceAssetEvent_many": "Événements sources", "sourceAssetEvent_one": "Événement source", "sourceAssetEvent_other": "Événements sources", "startDate": "Date de début", @@ -180,6 +192,7 @@ "failed": "Échoué", "no_status": "Aucun statut", "none": "Aucun statut", + "planned": "Planifié", "queued": "En file", "removed": "Supprimé", "restarting": "Redémarrage", @@ -196,6 +209,7 @@ "createdAt": "Créé à", "filterByTag": "Filtrer les Dags par tag", "filterColumns": "Filtrer les colonnes du tableau", + "filterReset_many": "Réinitialiser les filtres", "filterReset_one": "Réinitialiser le filtre", "filterReset_other": "Réinitialiser les filtres", "from": "De", @@ -214,6 +228,7 @@ "operator": "Opérateur", "triggerRule": "Règle de déclenchement" }, + "task_many": "Tâches", "task_one": "Tâche", "task_other": "Tâches", "taskGroup": "Groupe de tâches", @@ -241,6 +256,7 @@ }, "unixname": "Nom Unix" }, + "taskInstance_many": "Instances de tâche", "taskInstance_one": "Instance de tâche", "taskInstance_other": "Instances de tâche", "timeRange": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/components.json index abd0ec1a816ec..d38f4bc9702c0 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/components.json @@ -1,13 +1,12 @@ { "backfill": { + "affected_many": "{{count}} exécutions seront déclenchées.", "affected_one": "1 exécution sera déclenchée.", "affected_other": "{{count}} exécutions seront déclenchées.", "affectedNone": "Aucune exécution ne correspond aux critères sélectionnés.", "allRuns": "Toutes les exécutions", "backwards": "Exécuter à rebours", "dateRange": "Plage de dates", - "dateRangeFrom": "De", - "dateRangeTo": "À", "errorStartDateBeforeEndDate": "La date de début doit être antérieure à la date de fin", "maxRuns": "Nombre maximum d'exécutions actives", "missingAndErroredRuns": "Exécutions manquantes et en erreur", @@ -46,16 +45,20 @@ "invalidJson": "Format JSON invalide : {{errorMessage}}" }, "dagWarnings": { + "error_many": "{{count}} erreurs", "error_one": "1 erreur", "error_other": "{{count}} erreurs", "errorAndWarning": "1 erreur et {{warningText}}", + "warning_many": "{{count}} avertissements", "warning_one": "1 avertissement", "warning_other": "{{count}} avertissements" }, "durationChart": { "duration": "Durée (secondes)", + "lastDagRun_many": "Dernières {{count}} exécutions du Dag", "lastDagRun_one": "Dernière exécution du Dag", "lastDagRun_other": "Dernières {{count}} exécutions du Dag", + "lastTaskInstance_many": "Dernières {{count}} Task Instances", "lastTaskInstance_one": "Dernière Task Instance", "lastTaskInstance_other": "Dernières {{count}} Task Instances", "queuedDuration": "Durée en file d'attente", @@ -63,6 +66,7 @@ "runDuration": "Durée d'exécution" }, "fileUpload": { + "files_many": "{{count}} fichiers", "files_one": "{{count}} fichier", "files_other": "{{count}} fichiers" }, @@ -85,11 +89,17 @@ "downloadImageError": "Échec du téléchargement de l'image du graphe.", "downloadImageErrorTitle": "Échec du téléchargement", "otherDagRuns": "+Autres exécutions du Dag", + "taskCount_many": "{{count}} tâches", "taskCount_one": "{{count}} tâche", "taskCount_other": "{{count}} tâches", "taskGroup": "Groupe de tâches" }, "limitedList": "+{{count}} supplémentaires", + "limitedList.allItems": "Tous les {{count}} éléments :", + "limitedList.clickToInteract": "Cliquez sur une étiquette pour filtrer les Dags", + "limitedList.clickToOpenFull": "Cliquez sur \"+{{count}} supplémentaires\" pour ouvrir la vue complète", + "limitedList.copyPasteText": "Vous pouvez copier et coller le texte ci-dessus", + "limitedList.showingItems": "Affichage de {{count}} éléments", "logs": { "file": "Fichier", "location": "ligne {{line}} dans {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json index 37b7835696106..e3c1b9d93dc56 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json @@ -5,9 +5,37 @@ "reason": "Raison", "title": "Dépendances bloquant la planification de la tâche" }, + "calendar": { + "daily": "Quotidien", + "hourly": "Toutes les heures", + "legend": { + "less": "Moins", + "more": "Plus" + }, + "navigation": { + "nextMonth": "Mois suivant", + "nextYear": "Année suivante", + "previousMonth": "Mois précédent", + "previousYear": "Année précédente" + }, + "noData": "Aucune donnée disponible", + "noRuns": "Aucun Run", + "totalRuns": "Total des Runs", + "week": "Semaine {{weekNumber}}", + "weekdays": { + "friday": "Ven", + "monday": "Lun", + "saturday": "Sam", + "sunday": "Dim", + "thursday": "Jeu", + "tuesday": "Mar", + "wednesday": "Mer" + } + }, "code": { "bundleUrl": "URL du bundle", "noCode": "Aucun code trouvé", + "parseDuration": "Durée d'analyse :", "parsedAt": "Analysé le :" }, "extraLinks": "Liens supplémentaires", @@ -40,24 +68,29 @@ "warning": "AVERTISSEMENT" }, "navigation": { - "jump": "Sauter : Maj+{{arrow}}", "navigation": "Navigation : {{arrow}}", "toggleGroup": "Basculer le groupe : Espace" }, "overview": { "buttons": { + "failedRun_many": "Runs échoués", "failedRun_one": "Run échoué", "failedRun_other": "Runs échoués", + "failedTask_many": "Tâches échouées", "failedTask_one": "Tâche échouée", "failedTask_other": "Tâches échouées", + "failedTaskInstance_many": "Task Instances échouées", "failedTaskInstance_one": "Task Instance échouée", "failedTaskInstance_other": "Task Instances échouées" }, "charts": { + "assetEvent_many": "Événements d'actif créés", "assetEvent_one": "Événement d'actif créé", "assetEvent_other": "Événements d'actif créés" }, "failedLogs": { + "hideLogs": "Masquer les journaux", + "showLogs": "Afficher les journaux", "title": "Journaux des tâches échouées récemment", "viewFullLogs": "Voir les journaux complets" } @@ -66,8 +99,8 @@ "buttons": { "options": "Options", "showGantt": "Afficher le Gantt", - "showGraph": "Afficher le graphe", - "showGrid": "Afficher la grille" + "showGraphShortcut": "Afficher le graphe (Appuyez sur g)", + "showGridShortcut": "Afficher la grille (Appuyez sur g)" }, "dagRuns": { "label": "Nombre de Runs du Dag" @@ -102,9 +135,11 @@ "assetEvents": "Événements d'actifs", "auditLog": "Journal d'audit", "backfills": "Rattrappages", + "calendar": "Calendrier", "code": "Code", "details": "Détails", "logs": "Journaux", + "mappedTaskInstances_many": "Task Instances [{{count}}]", "mappedTaskInstances_one": "Task Instance [{{count}}]", "mappedTaskInstances_other": "Task Instances [{{count}}]", "overview": "Aperçu", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dashboard.json index 67289ee983f8d..fa60bff6a234c 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dashboard.json @@ -1,5 +1,6 @@ { "favorite": { + "favoriteDags_many": "{{count}} premiers Dags favoris", "favoriteDags_one": "{{count}} premier Dag favori", "favoriteDags_other": "{{count}} premiers Dags favoris", "noDagRuns": "Il n'y a pas encore d'exécution pour ce Dag.", @@ -19,6 +20,7 @@ }, "history": "Historique", "importErrors": { + "dagImportError_many": "Erreurs d'importation de Dag", "dagImportError_one": "Erreur d'importation de Dag", "dagImportError_other": "Erreurs d'importation de Dag", "searchByFile": "Rechercher par fichier", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/hitl.json index 3c03176bc69df..1efd0752cc261 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/hitl.json @@ -1,6 +1,17 @@ { + "filters": { + "response": { + "all": "Tous", + "pending": "En attente", + "received": "Reçue" + } + }, + "requiredAction_many": "Actions requises", "requiredAction_one": "Actions requises", "requiredAction_other": "Actions requises", + "requiredActionCount_many": "Actions requises ({{count}})", + "requiredActionCount_one": "Action requise ({{count}})", + "requiredActionCount_other": "Actions requises ({{count}})", "requiredActionState": "État de l'action requise", "response": { "error": "Échec de la réponse", @@ -16,6 +27,7 @@ "approvalRequired": "Approbation requise", "choiceReceived": "Choix reçu", "choiceRequired": "Choix requis", + "noResponseReceived": "Aucune réponse reçue", "rejectionReceived": "Rejet reçu", "responseReceived": "Réponse reçue", "responseRequired": "Réponse requise" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/tasks.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/tasks.json new file mode 100644 index 0000000000000..2971c37e527b7 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/tasks.json @@ -0,0 +1,10 @@ +{ + "mapped": "Mappé", + "notMapped": "Non mappé", + "retries": "Éssaies", + "searchTasks": "Rechercher des tâches", + "selectMapped": "Sélectionner mappé", + "selectOperator": "Sélectionner des opérateurs", + "selectRetryValues": "Sélectionner des valeurs des essaies", + "selectTriggerRules": "Sélectionner des règles de déclenchement" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/admin.json index 5024088b35c28..67773ad2d2b54 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/admin.json @@ -75,7 +75,6 @@ "tooltip": "מחק חיבורים נבחרים" }, "formActions": { - "reset": "אתחל", "save": "שמור" }, "plugins": { @@ -147,7 +146,7 @@ "import": { "button": "ייבא", "conflictResolution": "בחר מנגנון ליישוב קונפליקט משתנים", - "errorParsingJsonFile": "שגיאה בפירסור קובץ JSON: העלה קובץ JSON המכיל משתנים (לדוגמה, {\"key\": \"value\", ...}).", + "errorParsingJsonFile": "שגיאה בניתוח קובץ JSON: העלה קובץ JSON המכיל משתנים (לדוגמה, {\"key\": \"value\", ...}).", "options": { "fail": { "description": "הכשלת הייבוא אם מזוהים משתנים קיימים.", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/assets.json index 64c57f2029ce6..db33727e72f09 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/assets.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/assets.json @@ -3,7 +3,7 @@ "createEvent": { "button": "יצירת אירוע", "manual": { - "description": "יצירה ידנית של אירוע בכנס", + "description": "יצירה ידנית של אירוע בנכס", "extra": "תוכן אירוע בנכס", "label": "ידני" }, diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/common.json index 85a434bc5b993..4df731bdc5dfe 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/common.json @@ -44,6 +44,7 @@ "fileLocation": "מיקום קובץ", "hasTaskConcurrencyLimits": "מגבלות על משימות במקביל", "lastExpired": "פג תוקף לאחרונה", + "lastParseDuration": "משך זמן הניתוח האחרון", "lastParsed": "ניתוח אחרון", "latestDagVersion": "גרסת Dag אחרונה", "latestRun": "ריצה אחרונה", @@ -104,16 +105,12 @@ "any": "כלשהו", "or": "או" }, + "filter": "מסנן", "filters": { - "dagDisplayNamePlaceholder": "סנן לפי Dag", - "keyPlaceholder": "סנן לפי מפתח XCom", - "logicalDateFromPlaceholder": "תאריך לוגי מ-", - "logicalDateToPlaceholder": "תאריך לוגי עד", - "mapIndexPlaceholder": "סנן לפי אינדקס מיפוי", - "runAfterFromPlaceholder": "ריצה לאחר (מתאריך)", - "runAfterToPlaceholder": "ריצה לאחר (עד תאריך)", - "runIdPlaceholder": "סנן לפי מזהה ריצה", - "taskIdPlaceholder": "סנן לפי מזהה משימה" + "logicalDateFrom": "תאריך לוגי מ-", + "logicalDateTo": "תאריך לוגי עד", + "runAfterFrom": "ריצה לאחר (מתאריך)", + "runAfterTo": "ריצה לאחר (עד תאריך)" }, "logicalDate": "תאריך לוגי", "logout": "התנתק", @@ -147,15 +144,16 @@ "taskInstance": "הערת משימה" }, "pools": { - "deferred": "נדחה לתזמון עתידי", + "deferred": "בהשהייה", "open": "פתוח", "pools_one": "מאגר משאבים", "pools_other": "מאגרי משאבים", "pools_two": "מאגרי משאבים", "queued": "בתור", - "running": "בביצוע", + "running": "בריצה", "scheduled": "מתוזמן" }, + "reset": "אתחל", "runId": "מזהה ריצה", "runTypes": { "asset_triggered": "הופעל על-ידי נכס", @@ -170,7 +168,6 @@ }, "tooltip": "לחץ {{hotkey}} לגלילה ל{{direction}}" }, - "seconds": "{{count}} שניות", "security": { "actions": "פעולות", "permissions": "הרשאות", @@ -191,20 +188,20 @@ "startDate": "תאריך התחלה", "state": "מצב", "states": { - "deferred": "נדחה", - "failed": "נכשל", + "deferred": "בהשהייה", + "failed": "נכשלו", "no_status": "ללא סטטוס", "none": "ללא סטטוס", - "planned": "מתוכנן", + "planned": "בתכנון", "queued": "בתור", - "removed": "הוסר", - "restarting": "מופעל מחדש", - "running": "בביצוע", - "scheduled": "מתוזמן", - "skipped": "דולג", - "success": "הצליח", - "up_for_reschedule": "ממתין לתזמון מחדש", - "up_for_retry": "ממתין לניסיון חוזר", + "removed": "הוסרו", + "restarting": "בהפעלה מחדש", + "running": "בריצה", + "scheduled": "בתזמון", + "skipped": "דולגו", + "success": "הצליחו", + "up_for_reschedule": "בהמתנה לתזמון מחדש", + "up_for_retry": "בהמתנה לניסיון חוזר", "upstream_failed": "משימות קודמות נכשלו" }, "table": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/components.json index 43dd3a9964aaf..424d5f675b14d 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/components.json @@ -7,8 +7,6 @@ "allRuns": "כל ההרצות", "backwards": "הרץ לאחור", "dateRange": "טווח תאריכים", - "dateRangeFrom": "מתאריך", - "dateRangeTo": "עד תאריך", "errorStartDateBeforeEndDate": "תאריך ההתחלה חייב להיות לפני תאריך הסיום", "maxRuns": "מספר ריצות מקבילות מירבי", "missingAndErroredRuns": "הרצות חסרות ושגויות", @@ -97,6 +95,11 @@ "taskGroup": "קבוצת משימות" }, "limitedList": "+ {{count}} נוספים", + "limitedList.allItems": "כל {{count}} הפריטים:", + "limitedList.clickToInteract": "לחץ על תגית כדי לסנן Dags", + "limitedList.clickToOpenFull": "לחץ על \"+{{count}} נוספים\" כדי לפתוח את התצוגה המלאה", + "limitedList.copyPasteText": "ניתן להעתיק ולהדביק את הטקסט שמעל", + "limitedList.showingItems": "מציג {{count}} פריטים", "logs": { "file": "קובץ", "location": "שורה {{line}} ב{{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json index e110a798f6bb7..33d8cf62129e4 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json @@ -35,7 +35,8 @@ "code": { "bundleUrl": "כתובת החבילה", "noCode": "לא נמצא קוד", - "parsedAt": "נקרא בשעה:" + "parseDuration": "משך זמן הניתוח:", + "parsedAt": "נותח בשעה:" }, "extraLinks": "קישורים נוספים", "grid": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/dashboard.json index 7f962b05cebe3..304b985f64ffc 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/dashboard.json @@ -8,7 +8,7 @@ }, "group": "קבוצה", "health": { - "dagProcessor": "Dag מנתח", + "dagProcessor": "מנתח Dags", "health": "תקינות", "healthy": "תקין", "lastHeartbeat": "פעימה אחרונה", @@ -35,8 +35,8 @@ }, "source": "מקור", "stats": { - "activeDags": "Dags פעיל", - "failedDags": "Dags בכשלון", + "activeDags": "Dags פעילים", + "failedDags": "Dags נכשלו", "queuedDags": "Dags בתור", "requiredActions": "פעולות נדרשות", "runningDags": "Dags בריצה", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hi/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/hi/admin.json index 8a12c76d4d218..590ad3eac82ba 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/hi/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/hi/admin.json @@ -72,7 +72,6 @@ "tooltip": "चयनित कनेक्शन्स हटाएं" }, "formActions": { - "reset": "रीसेट करें", "save": "सेव करें" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hi/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/hi/common.json index 53cc2469791e0..a506b9198b85c 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/hi/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/hi/common.json @@ -92,16 +92,12 @@ "any": "कोई भी", "or": "या" }, + "filter": "फ़िल्टर", "filters": { - "dagDisplayNamePlaceholder": "डैग द्वारा फ़िल्टर करें", - "keyPlaceholder": "XCom कुंजी द्वारा फ़िल्टर करें", - "logicalDateFromPlaceholder": "तार्किक तिथि से", - "logicalDateToPlaceholder": "तार्किक तिथि तक", - "mapIndexPlaceholder": "मैप इंडेक्स द्वारा फ़िल्टर करें", - "runAfterFromPlaceholder": "रन आफ़्टर से", - "runAfterToPlaceholder": "रन आफ़्टर तक", - "runIdPlaceholder": "रन ID द्वारा फ़िल्टर करें", - "taskIdPlaceholder": "टास्क ID द्वारा फ़िल्टर करें" + "logicalDateFrom": "तार्किक तिथि से", + "logicalDateTo": "तार्किक तिथि तक", + "runAfterFrom": "रन आफ़्टर से", + "runAfterTo": "रन आफ़्टर तक" }, "logicalDate": "तार्किक तिथि", "logout": "लॉग आउट", @@ -143,6 +139,7 @@ "running": "चल रहा", "scheduled": "निर्धारित" }, + "reset": "रीसेट करें", "runId": "रन ID", "runTypes": { "asset_triggered": "एसेट द्वारा ट्रिगर", @@ -157,7 +154,6 @@ }, "tooltip": "{{direction}} तक स्क्रॉल करने के लिए {{hotkey}} दबाएं" }, - "seconds": "{{count}}सेकंड", "security": { "actions": "क्रियाएं", "permissions": "अनुमतियां", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hi/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/hi/components.json index e84d1da7745b3..4efe768e9bebf 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/hi/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/hi/components.json @@ -6,8 +6,6 @@ "allRuns": "सभी रन्स", "backwards": "पीछे की ओर चलाएं", "dateRange": "तिथि रेंज", - "dateRangeFrom": "से", - "dateRangeTo": "तक", "errorStartDateBeforeEndDate": "प्रारंभ तिथि समाप्ति तिथि से पहले होनी चाहिए", "maxRuns": "अधिकतम सक्रिय रन्स", "missingAndErroredRuns": "गुम और त्रुटि वाले रन्स", @@ -90,6 +88,11 @@ "taskGroup": "टास्क ग्रुप" }, "limitedList": "+{{count}} और", + "limitedList.allItems": "सभी {{count}} आइटम:", + "limitedList.clickToInteract": "टैग पर क्लिक करके Dags फ़िल्टर करें", + "limitedList.clickToOpenFull": "\"+{{count}} और\" पर क्लिक करके पूरी सूची खोलें", + "limitedList.copyPasteText": "आप ऊपर दिए गए पाठ को कॉपी और पेस्ट कर सकते हैं", + "limitedList.showingItems": "{{count}} आइटम दिखाए जा रहे हैं", "logs": { "file": "फ़ाइल", "location": "{{name}} में लाइन {{line}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hu/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/hu/admin.json index eaea0f27ecff9..4cf8aa1536994 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/hu/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/hu/admin.json @@ -72,7 +72,6 @@ "tooltip": "Kijelölt kapcsolatok törlése" }, "formActions": { - "reset": "Alaphelyzetbe állítás", "save": "Mentés" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hu/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/hu/common.json index 2c777a339ecf2..f26a1540f08ac 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/hu/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/hu/common.json @@ -92,16 +92,12 @@ "any": "Bármely", "or": "VAGY" }, + "filter": "Szűrő", "filters": { - "dagDisplayNamePlaceholder": "Szűrés Dag szerint", - "keyPlaceholder": "Szűrés XCom kulcs szerint", - "logicalDateFromPlaceholder": "Logikai dátum -tól", - "logicalDateToPlaceholder": "Logikai dátum -ig", - "mapIndexPlaceholder": "Szűrés Map Index szerint", - "runAfterFromPlaceholder": "Futás ekkortól", - "runAfterToPlaceholder": "Futás eddig", - "runIdPlaceholder": "Szűrés futás azonosító szerint", - "taskIdPlaceholder": "Szűrés feladat azonosító szerint" + "logicalDateFrom": "Logikai dátum -tól", + "logicalDateTo": "Logikai dátum -ig", + "runAfterFrom": "Futás ekkortól", + "runAfterTo": "Futás eddig" }, "logicalDate": "Logikai dátum", "logout": "Kijelentkezés", @@ -143,6 +139,7 @@ "running": "Fut", "scheduled": "Ütemezett" }, + "reset": "Alaphelyzetbe állítás", "runId": "Futás azonosító", "runTypes": { "asset_triggered": "Adatkészlet által indított", @@ -157,7 +154,6 @@ }, "tooltip": "Nyomd meg a(z) {{hotkey}} gombot a görgetéshez ide: {{direction}}" }, - "seconds": "{{count}} mp", "security": { "actions": "Műveletek", "permissions": "Jogosultságok", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hu/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/hu/components.json index f89188343dc23..ded34869e9dac 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/hu/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/hu/components.json @@ -6,8 +6,6 @@ "allRuns": "Összes futás", "backwards": "Futtatás visszafelé", "dateRange": "Dátumtartomány", - "dateRangeFrom": "Kezdő dátum", - "dateRangeTo": "Befejező dátum", "errorStartDateBeforeEndDate": "A kezdő dátumnak a befejező dátum előtt kell lennie.", "maxRuns": "Maximális aktív futások", "missingAndErroredRuns": "Hiányzó és hibás futások", @@ -90,6 +88,11 @@ "taskGroup": "Feladatcsoport" }, "limitedList": "+{{count}} további", + "limitedList.allItems": "Összes {{count}} elem:", + "limitedList.clickToInteract": "Kattintson egy címkére a Dag-ok szűréséhez", + "limitedList.clickToOpenFull": "Kattintson a \"+{{count}} további\" gombra a teljes nézethez", + "limitedList.copyPasteText": "A fenti szöveg másolható és beilleszthető", + "limitedList.showingItems": "{{count}} elem megjelenítése", "logs": { "file": "Fájl", "location": "{{name}} fájl {{line}}. sora" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/admin.json new file mode 100644 index 0000000000000..2937ba21fd63a --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/admin.json @@ -0,0 +1,182 @@ +{ + "columns": { + "description": "Descrizione", + "key": "Chiave", + "name": "Nome", + "value": "Valore" + }, + "config": { + "columns": { + "section": "Sezione" + }, + "title": "Configurazione di Airflow" + }, + "connections": { + "add": "Aggiungi Connessione", + "columns": { + "connectionId": "ID Connessione", + "connectionType": "Tipo di Connessione", + "host": "Host", + "port": "Port" + }, + "connection_many": "Connessioni", + "connection_one": "Connessione", + "connection_other": "Connessioni", + "connection_zero": "Nessuna connessione", + "delete": { + "deleteConnection_many": "Elimina {{count}} connessioni", + "deleteConnection_one": "Elimina 1 connessione", + "deleteConnection_other": "Elimina {{count}} connessioni", + "deleteConnection_zero": "Nessuna connessione da eliminare", + "firstConfirmMessage_many": "Stai per eliminare le seguenti connessioni:", + "firstConfirmMessage_one": "Stai per eliminare la seguente connessione:", + "firstConfirmMessage_other": "Stai per eliminare le seguenti connessioni:", + "firstConfirmMessage_zero": "Nessuna connessione da eliminare:", + "title": "Elimina Connessione" + }, + "edit": "Modifica Connessione", + "form": { + "connectionIdRequired": "L'ID della connessione è obbligatorio", + "connectionIdRequirement": "L'ID della connessione non può contenere solo spazi", + "connectionTypeRequired": "Il tipo di connessione è obbligatorio", + "extraFields": "Campi Extra", + "extraFieldsJson": "Campi Extra JSON", + "helperText": "Il tipo di connessione è mancante? Assicurati di aver installato il pacchetto corrispondente di Airflow Providers.", + "helperTextForRedactedFields": "I campi redatti ('***') rimarranno invariati se non modificati.", + "selectConnectionType": "Seleziona Tipo di Connessione", + "standardFields": "Campi Standard" + }, + "nothingFound": { + "description": "Le connessioni definite tramite variabili d'ambiente o gestori di segreti non sono elencate qui.", + "documentationLink": "Scopri di più nella documentazione di Airflow.", + "learnMore": "Queste sono risolte in fase di runtime e non sono visibili nell'interfaccia utente.", + "title": "Nessuna connessione trovata!" + }, + "searchPlaceholder": "Cercare Connessioni", + "test": "Test Connessione", + "testDisabled": "La funzione di test della connessione è disabilitata. Per favore contatta un amministratore per abilitarla.", + "typeMeta": { + "error": "Impossibile recuperare il tipo di connessione", + "standardFields": { + "description": "Descrizione", + "host": "Host", + "login": "Login", + "password": "Password", + "port": "Porta", + "url_schema": "Schema" + } + } + }, + "deleteActions": { + "button": "Elimina", + "modal": { + "confirmButton": "Sì, Elimina", + "secondConfirmMessage": "Questa azione è permanente e non può essere annullata.", + "thirdConfirmMessage": "Confermi di voler procedere?" + }, + "selected": "Selezionato", + "tooltip": "Elimina le connessioni selezionate" + }, + "formActions": { + "save": "Salva" + }, + "plugins": { + "columns": { + "source": "Fonte" + }, + "importError_many": "Errori di Importazione Plugin", + "importError_one": "Errore di Importazione Plugin", + "importError_other": "Errori di Importazione Plugin", + "importError_zero": "Nessun errore di importazione plugin", + "searchPlaceholder": "Cercare per file" + }, + "pools": { + "add": "Aggiungi Pool", + "deferredSlotsIncluded": "Slots Deferiti Inclusi", + "delete": { + "title": "Elimina Pool", + "warning": "Questo rimuoverà tutti i metadati relativi al pool e potrebbe influenzare le tare che lo utilizzano." + }, + "edit": "Modifica Pool", + "form": { + "checkbox": "Seleziona per includere le tare deferite quando si calcolano gli slot liberi del pool", + "description": "Descrizione", + "includeDeferred": "Includi Deferiti", + "nameMaxLength": "Il nome può contenere un massimo di 256 caratteri", + "nameRequired": "Il nome è obbligatorio", + "slots": "Slot" + }, + "noPoolsFound": "Nessun pool trovato", + "pool_many": "Pools", + "pool_one": "Pool", + "pool_other": "Pools", + "pool_zero": "Nessun pool", + "searchPlaceholder": "Cercare Pools", + "sort": { + "asc": "Nome (A-Z)", + "desc": "Nome (Z-A)", + "placeholder": "Ordina per" + } + }, + "providers": { + "columns": { + "packageName": "Nome del Pacchetto", + "version": "Versione" + } + }, + "variables": { + "add": "Aggiungi Variabile", + "columns": { + "isEncrypted": "È Crittografata" + }, + "delete": { + "deleteVariable_many": "Elimina {{count}} Variabili", + "deleteVariable_one": "Elimina 1 Variabile", + "deleteVariable_other": "Elimina {{count}} Variabili", + "deleteVariable_zero": "Nessuna variabile da eliminare", + "firstConfirmMessage_many": "Stai per eliminare le seguenti variabili:", + "firstConfirmMessage_one": "Stai per eliminare la seguente variabile:", + "firstConfirmMessage_other": "Stai per eliminare le seguenti variabili:", + "firstConfirmMessage_zero": "Nessuna variabile da eliminare:", + "title": "Elimina Variabile", + "tooltip": "Elimina le variabili selezionate" + }, + "edit": "Modifica Variabile", + "export": "Esporta", + "exportTooltip": "Esporta le variabili selezionate", + "form": { + "invalidJson": "JSON non valido", + "keyMaxLength": "La chiave può contenere un massimo di 250 caratteri", + "keyRequired": "La chiave è obbligatoria", + "valueRequired": "Il valore è obbligatorio" + }, + "import": { + "button": "Importa", + "conflictResolution": "Seleziona la risoluzione dei conflitti delle variabili", + "errorParsingJsonFile": "Errore nell'analisi del file JSON: Carica un file JSON contenente le variabili (es. {\"key\": \"value\", ...}).", + "options": { + "fail": { + "description": "Fallisce l'importazione se vengono rilevate variabili esistenti.", + "title": "Fallisci" + }, + "overwrite": { + "description": "Sovrascrive la variabile in caso di conflitto.", + "title": "Sovrascrivi" + }, + "skip": { + "description": "Salta l'importazione delle variabili che già esistono.", + "title": "Salta" + } + }, + "title": "Importa Variabili", + "upload": "Carica un File JSON", + "uploadPlaceholder": "Carica un file JSON contenente le variabili (es. {\"key\": \"value\", ...})" + }, + "noRowsMessage": "Nessuna variabile trovata", + "searchPlaceholder": "Cercare Chiavi", + "variable_many": "Variabili", + "variable_one": "Variabile", + "variable_other": "Variabili", + "variable_zero": "Nessuna variabile" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/assets.json new file mode 100644 index 0000000000000..bb94a3cf908f1 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/assets.json @@ -0,0 +1,30 @@ +{ + "consumingDags": "Dag Consumatori", + "createEvent": { + "button": "Creare un Evento", + "manual": { + "description": "Crea manualmente un Evento Asset", + "extra": "Extra dell'Evento Asset", + "label": "Manuale" + }, + "materialize": { + "description": "Attiva il Dag upstream di questo asset", + "descriptionWithDag": "Attiva il Dag upstream di questo asset: {{dagName}}", + "label": "Materializza", + "unpauseDag": "Riattiva {{dagName}} al momento del trigger" + }, + "success": { + "manualDescription": "La creazione manuale dell'evento asset è avvenuta con successo.", + "manualTitle": "Evento Asset Creato", + "materializeDescription": "Il Dag upstream {{dagId}} è stato attivato con successo.", + "materializeTitle": "Materializzazione dell'Asset" + }, + "title": "Creare Evento Asset per {{name}}" + }, + "group": "Gruppo", + "lastAssetEvent": "Ultimo Evento Asset", + "name": "Nome", + "producingTasks": "Task Produttori", + "scheduledDags": "Dag Programmati", + "searchPlaceholder": "Cercare Assets" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/browse.json new file mode 100644 index 0000000000000..75e8251efb050 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/browse.json @@ -0,0 +1,26 @@ +{ + "auditLog": { + "actions": { + "collapseAllExtra": "Collassa tutti i json extra", + "expandAllExtra": "Espandi tutti i json extra" + }, + "columns": { + "event": "Evento", + "extra": "Extra", + "user": "Utente", + "when": "Quando" + }, + "filters": { + "eventType": "Tipo di Evento" + }, + "title": "Registro di Controllo (Logs)" + }, + "xcom": { + "columns": { + "dag": "Dag", + "key": "Chiave", + "value": "Valore" + }, + "title": "XCom" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/common.json new file mode 100644 index 0000000000000..306359ac1068f --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/common.json @@ -0,0 +1,338 @@ +{ + "admin": { + "Config": "Configurazione", + "Connections": "Connessioni", + "Plugins": "Plugins", + "Pools": "Pools", + "Providers": "Provider", + "Variables": "Variabili" + }, + "allOperators": "Tutti gli Operatori", + "appearance": { + "appearance": "Aspetto", + "darkMode": "Modalità scura", + "lightMode": "Modalità chiara", + "systemMode": "Segui impostazioni di sistema" + }, + "asset_many": "Assets", + "asset_one": "Asset", + "asset_other": "Assets", + "asset_zero": "Nessun asset", + "assetEvent_many": "Eventi Asset", + "assetEvent_one": "Evento Asset", + "assetEvent_other": "Eventi Asset", + "assetEvent_zero": "Nessun evento asset", + "backfill_many": "Backfills", + "backfill_one": "Backfill", + "backfill_other": "Backfills", + "backfill_zero": "Nessun backfill", + "browse": { + "auditLog": "Registro di Controllo (Logs)", + "requiredActions": "Azioni Richieste", + "xcoms": "XComs" + }, + "collapseDetailsPanel": "Collassa i Dettagli", + "createdAssetEvent_many": "Eventi Asset Creati", + "createdAssetEvent_one": "Evento Asset Creato", + "createdAssetEvent_other": "Eventi Asset Creati", + "createdAssetEvent_zero": "Nessun evento asset creato", + "dag_many": "Dags", + "dag_one": "Dag", + "dag_other": "Dags", + "dag_zero": "Nessun Dag", + "dagDetails": { + "catchup": "Catchup", + "dagRunTimeout": "Timeout del Run del Dag", + "defaultArgs": "Argomenti di Default", + "description": "Descrizione", + "documentation": "Documentazione del Dag", + "fileLocation": "Percorso del File", + "hasTaskConcurrencyLimits": "Ha Limiti di Concorrenza dei Task", + "lastExpired": "Ultimo Scaduto", + "lastParseDuration": "Durata dell'ultimo parsing", + "lastParsed": "Ultimo Parsed", + "latestDagVersion": "Ultima Versione del Dag", + "latestRun": "Ultimo Run del Dag", + "maxActiveRuns": "Numero massimo di Runs attive", + "maxActiveTasks": "Numero massimo di Tasks attive", + "maxConsecutiveFailedDagRuns": "Numero massimo di Runs falliti consecutivi del Dag", + "nextRun": "Prossimo Run", + "owner": "Proprietario", + "params": "Parametri", + "schedule": "Programmazione", + "tags": "Tag" + }, + "dagId": "ID del Dag", + "dagRun": { + "conf": "Conf", + "dagVersions": "Versioni del Dag", + "dataIntervalEnd": "Data Intervallo Fine", + "dataIntervalStart": "Data Intervallo Inizio", + "lastSchedulingDecision": "Ultima Decisione di Programmazione", + "queuedAt": "In Coda il", + "runAfter": "Esegui dopo", + "runType": "Tipo di Run", + "sourceAssetEvent": "Evento Asset di Origine", + "triggeredBy": "Triggered da", + "triggeringUser": "Nome Utente che ha Attivato" + }, + "dagRun_many": "Run del Dag", + "dagRun_one": "Run del Dag", + "dagRun_other": "Run del Dag", + "dagRun_zero": "Nessun run del Dag", + "dagRunId": "ID del Run del Dag", + "dagWarnings": "Avvisi/Errori del Dag", + "defaultToGraphView": "Default to vista grafica", + "defaultToGridView": "Default to vista griglia", + "direction": "Direzione", + "docs": { + "documentation": "Documentazione", + "githubRepo": "Repository GitHub", + "restApiReference": "Riferimento API REST" + }, + "duration": "Durata", + "endDate": "Data di Fine", + "error": { + "back": "Indietro", + "defaultMessage": "Si è verificato un errore imprevisto", + "home": "Home", + "notFound": "Pagina non trovata", + "title": "Errore" + }, + "expand": { + "collapse": "Collassa", + "expand": "Espandi", + "hotkey": "e", + "tooltip": "Premi {{hotkey}} per attivare/disattivare espansione" + }, + "expression": { + "all": "Tutti", + "and": "E", + "any": "Qualunque", + "or": "O" + }, + "filter": "Filtro", + "filters": { + "logicalDateFrom": "Data Logica Da", + "logicalDateTo": "Data Logica A", + "runAfterFrom": "Esegui Dopo Da", + "runAfterTo": "Esegui Dopo A" + }, + "logicalDate": "Data Logica", + "logout": "Esci", + "logoutConfirmation": "Stai per uscire dall'applicazione.", + "mapIndex": "Mappa Index", + "modal": { + "cancel": "Annulla", + "confirm": "Conferma", + "delete": { + "button": "Elimina", + "confirmation": "Confermi di voler eliminare {{resourceName}}? Questa azione non può essere annullata." + } + }, + "nav": { + "admin": "Amministrazione", + "assets": "Asset", + "browse": "Sfoglia", + "dags": "Dag", + "docs": "Documentazione", + "home": "Home", + "legacyFabViews": "Legacy View", + "plugins": "Plugins", + "security": "Sicurezza" + }, + "noItemsFound": "Nessun {{modelName}} trovato", + "note": { + "add": "Aggiungi una nota", + "dagRun": "Nota del Run del Dag", + "label": "Note", + "placeholder": "Aggiungi una nota...", + "taskInstance": "Nota dell'Istanza di Task" + }, + "pools": { + "deferred": "In Attesa", + "open": "Aperto", + "pools_many": "Pools", + "pools_one": "Pool", + "pools_other": "Pools", + "pools_zero": "Nessun pool", + "queued": "In Coda", + "running": "In Esecuzione", + "scheduled": "Programmato" + }, + "reset": "Resetta", + "runId": "ID del Run", + "runTypes": { + "asset_triggered": "Asset Triggered", + "backfill": "Backfill", + "manual": "Manuale", + "scheduled": "Programmato" + }, + "scroll": { + "direction": { + "bottom": "In basso", + "top": "In alto" + }, + "tooltip": "Premi {{hotkey}} per scorrere a {{direction}}" + }, + "security": { + "actions": "Azioni", + "permissions": "Permessi", + "resources": "Risorse", + "roles": "Ruoli", + "users": "Utenti" + }, + "selectLanguage": "Seleziona la Lingua", + "showDetailsPanel": "Mostra il Pannello dei Dettagli", + "source": { + "hide": "Nascondi Sorgente", + "hotkey": "s", + "show": "Mostra Sorgente" + }, + "sourceAssetEvent_many": "Eventi Asset di Origine", + "sourceAssetEvent_one": "Evento Asset di Origine", + "sourceAssetEvent_other": "Eventi Asset di Origine", + "sourceAssetEvent_zero": "Nessun evento asset di origine", + "startDate": "Data di Inizio", + "state": "Stato", + "states": { + "deferred": "In Attesa", + "failed": "Fallito", + "no_status": "Nessun Stato", + "none": "Nessun Stato", + "planned": "Pianificato", + "queued": "In Coda", + "removed": "Rimosso", + "restarting": "Riavviato", + "running": "In Esecuzione", + "scheduled": "Programmato", + "skipped": "Saltato", + "success": "Successo", + "up_for_reschedule": "Da Reschedulare", + "up_for_retry": "Da Riavviare", + "upstream_failed": "Upstream Fallito" + }, + "table": { + "completedAt": "Completato il", + "createdAt": "Creato il", + "filterByTag": "Filtra Dag per tag", + "filterColumns": "Filtra le colonne della tabella", + "filterReset_many": "Resetta filtri", + "filterReset_one": "Resetta filtro", + "filterReset_other": "Resetta filtri", + "filterReset_zero": "Nessun filtro da resettare", + "from": "Da", + "maxActiveRuns": "Numero massimo di Runs attive", + "noTagsFound": "Nessun tag trovato", + "tagMode": { + "all": "Tutti", + "any": "Qualunque" + }, + "tagPlaceholder": "Filtra per tag", + "to": "A" + }, + "task": { + "documentation": "Documentazione del Task", + "lastInstance": "Ultima Istanza", + "operator": "Operatore", + "triggerRule": "Regola di Trigger" + }, + "task_many": "Tasks", + "task_one": "Task", + "task_other": "Tasks", + "task_zero": "Nessun task", + "taskGroup": "Gruppo di Task", + "taskId": "ID del Task", + "taskInstance": { + "dagVersion": "Versione del Dag", + "executor": "Executor", + "executorConfig": "Configurazione dell'Executor", + "hostname": "Nome delHost", + "maxTries": "Numero massimo di Tentativi", + "pid": "PID", + "pool": "Pool", + "poolSlots": "Slot del Pool", + "priorityWeight": "Peso di Priorità", + "queue": "Coda", + "queuedWhen": "In Coda il", + "scheduledWhen": "Programmato il", + "triggerer": { + "assigned": "Triggerer Assegnato", + "class": "Classe del Trigger", + "createdAt": "Creato il", + "id": "ID del Trigger", + "latestHeartbeat": "Ultimo Heartbeat del Trigger", + "title": "Info del Trigger" + }, + "unixname": "Nome Unix" + }, + "taskInstance_many": "Istanze di Task", + "taskInstance_one": "Istanza di Task", + "taskInstance_other": "Istanze di Task", + "taskInstance_zero": "Nessuna istanza di task", + "timeRange": { + "last12Hours": "Ultimi 12 Ore", + "last24Hours": "Ultimi 24 Ore", + "lastHour": "Ultima Ora", + "pastWeek": "Settimana Scorsa" + }, + "timestamp": { + "hide": "Nascondi Timestamp", + "hotkey": "t", + "show": "Mostra Timestamp" + }, + "timezone": "Fuso Orario", + "timezoneModal": { + "current-timezone": "Ora corrente in", + "placeholder": "Seleziona un fuso orario", + "title": "Seleziona il Fuso Orario", + "utc": "UTC (Tempo Coordinato Universale)" + }, + "toaster": { + "bulkDelete": { + "error": "Eliminazione in Massa di {{resourceName}} Fallita", + "success": { + "description": "{{count}} {{resourceName}} sono stati eliminati con successo. Chiavi: {{keys}}", + "title": "Eliminazione in Massa di {{resourceName}} Richiesta Inviata" + } + }, + "create": { + "error": "Creazione di {{resourceName}} Fallita", + "success": { + "description": "{{resourceName}} è stato creato con successo.", + "title": "Creazione di {{resourceName}} Richiesta Inviata" + } + }, + "delete": { + "error": "Eliminazione di {{resourceName}} Fallita", + "success": { + "description": "{{resourceName}} è stato eliminato con successo.", + "title": "Eliminazione di {{resourceName}} Richiesta Inviata" + } + }, + "import": { + "error": "Importazione di {{resourceName}} Fallita", + "success": { + "description": "{{count}} {{resourceName}} sono stati importati con successo.", + "title": "Importazione di {{resourceName}} Richiesta Inviata" + } + }, + "update": { + "error": "Aggiornamento di {{resourceName}} Fallita", + "success": { + "description": "{{resourceName}} è stato aggiornato con successo.", + "title": "Aggiornamento di {{resourceName}} Richiesta Inviata" + } + } + }, + "total": "Totale {{state}}", + "triggered": "Triggered", + "tryNumber": "Numero di Tentativo", + "user": "Utente", + "wrap": { + "hotkey": "w", + "tooltip": "Premi {{hotkey}} per abilitare il wrap", + "unwrap": "Disabilita il wrap", + "wrap": "Abilita il wrap" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/components.json new file mode 100644 index 0000000000000..e8903d951a2a8 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/components.json @@ -0,0 +1,153 @@ +{ + "backfill": { + "affected_many": "{{count}} runs verranno attivati.", + "affected_one": "1 run verrà attivato.", + "affected_other": "{{count}} runs verranno attivati.", + "affected_zero": "Nessun run verrà attivato.", + "affectedNone": "Nessun run corrispondente ai criteri selezionati.", + "allRuns": "Tutti i Run", + "backwards": "Run all'indietro", + "dateRange": "Intervallo di Date", + "errorStartDateBeforeEndDate": "La Data di Inizio deve essere precedente alla Data di Fine", + "maxRuns": "Numero massimo di Runs attive", + "missingAndErroredRuns": "Run Mancanti ed Errati", + "missingRuns": "Run Mancanti", + "reprocessBehavior": "Comportamento di Reprocesso", + "run": "Correre Backfill", + "selectDescription": "Esegui questo Dag per un intervallo di date", + "selectLabel": "Backfill", + "title": "Correre Backfill", + "toaster": { + "success": { + "description": "Backfill jobs sono stati attivati con successo.", + "title": "Backfill generato" + } + }, + "tooltip": "Backfill richiede un programma", + "unpause": "Sospendi {{dag_display_name}} al trigger", + "validation": { + "datesRequired": "Devi fornire sia la Data di Inizio che la Data di Fine.", + "startBeforeEnd": "La Data di Inizio deve essere precedente o uguale alla Data di Fine." + } + }, + "banner": { + "backfillInProgress": "Backfill in corso", + "cancel": "Annulla backfill", + "pause": "Sospendi backfill", + "unpause": "Sospendi backfill" + }, + "clipboard": { + "copy": "Copia" + }, + "close": "Chiudi", + "configForm": { + "advancedOptions": "Opzioni Avanzate", + "configJson": "Configurazione JSON", + "invalidJson": "Formato JSON non valido: {{errorMessage}}" + }, + "dagWarnings": { + "error_many": "{{count}} Errori", + "error_one": "1 Errore", + "error_other": "{{count}} Errori", + "error_zero": "Nessun errore", + "errorAndWarning": "1 Errore e {{warningText}}", + "warning_many": "{{count}} Avvisi", + "warning_one": "1 Avviso", + "warning_other": "{{count}} Avvisi", + "warning_zero": "Nessun avviso" + }, + "durationChart": { + "duration": "Durata (secondi)", + "lastDagRun_many": "Ultimi {{count}} Runs del Dag", + "lastDagRun_one": "Ultimo Run del Dag", + "lastDagRun_other": "Ultimi {{count}} Runs del Dag", + "lastDagRun_zero": "Nessun run del Dag", + "lastTaskInstance_many": "Ultime {{count}} Istanze di Task", + "lastTaskInstance_one": "Ultima Istanza di Task", + "lastTaskInstance_other": "Ultime {{count}} Istanze di Task", + "lastTaskInstance_zero": "Nessuna istanza di task", + "queuedDuration": "Durata in coda", + "runAfter": "Esegui dopo", + "runDuration": "Durata del Run" + }, + "fileUpload": { + "files_many": "{{count}} file", + "files_one": "1 file", + "files_other": "{{count}} file", + "files_zero": "Nessun file" + }, + "flexibleForm": { + "placeholder": "Seleziona Valore", + "placeholderArray": "Inserisci ogni stringa su una nuova riga", + "placeholderExamples": "Inizia a digitare per vedere le opzioni", + "placeholderMulti": "Seleziona uno o più valori", + "validationErrorArrayNotArray": "Il valore deve essere un array.", + "validationErrorArrayNotNumbers": "Tutti gli elementi dell'array devono essere numeri.", + "validationErrorArrayNotObject": "Tutti gli elementi dell'array devono essere oggetti.", + "validationErrorRequired": "Questo campo è obbligatorio" + }, + "graph": { + "directionDown": "Da Superiore a Inferiore", + "directionLeft": "Da Destra a Sinistra", + "directionRight": "Da Sinistra a Destra", + "directionUp": "Da Inferiore a Superiore", + "downloadImage": "Scarica l'immagine del grafico", + "downloadImageError": "Impossibile scaricare l'immagine del grafico.", + "downloadImageErrorTitle": "Scaricamento Fallito", + "otherDagRuns": "+Altri Runs del Dag", + "taskCount_many": "{{count}} Tasks", + "taskCount_one": "{{count}} Task", + "taskCount_other": "{{count}} Tasks", + "taskCount_zero": "Nessun task", + "taskGroup": "Task Group" + }, + "limitedList": "+{{count}} altro", + "limitedList.allItems": "Tutti i {{count}} elementi:", + "limitedList.clickToInteract": "Fai clic su un'etichetta per filtrare i Dag", + "limitedList.clickToOpenFull": "Fai clic su \"+{{count}} altro\" per visualizzare tutto", + "limitedList.copyPasteText": "Puoi copiare e incollare il testo sopra", + "limitedList.showingItems": "Visualizzazione di {{count}} elementi", + "logs": { + "file": "File", + "location": "linea {{line}} in {{name}}" + }, + "reparseDag": "Reparse Dag", + "sortedAscending": "ordinato in ordine crescente", + "sortedDescending": "ordinato in ordine decrescente", + "sortedUnsorted": "non ordinato", + "taskTries": "Tentativi di Task", + "toggleCardView": "Mostra la vista in card", + "toggleTableView": "Mostra la vista in tabella", + "triggerDag": { + "button": "Trigger", + "loading": "Caricamento informazioni del Dag...", + "loadingFailed": "Impossibile caricare le informazioni del Dag. Per favore, riprova.", + "runIdHelp": "Opzionale - verrà generato se non fornito", + "selectDescription": "Triggera un singolo run di questo Dag", + "selectLabel": "Singolo Run", + "title": "Trigger del Dag", + "toaster": { + "success": { + "description": "Il run del Dag è stato attivato con successo.", + "title": "Run del Dag attivato" + } + }, + "unpause": "Sospendi {{dagDisplayName}} al trigger" + }, + "trimText": { + "details": "Dettagli", + "empty": "Vuoto", + "noContent": "Nessun contenuto disponibile." + }, + "versionDetails": { + "bundleLink": "Link del Bundle", + "bundleName": "Nome del Bundle", + "bundleVersion": "Versione del Bundle", + "createdAt": "Creato il", + "versionId": "ID della Versione" + }, + "versionSelect": { + "dagVersion": "Versione del Dag", + "versionCode": "v{{versionCode}}" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/dag.json new file mode 100644 index 0000000000000..90d6bdd6dc190 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/dag.json @@ -0,0 +1,162 @@ +{ + "allRuns": "Tutti i Run", + "blockingDeps": { + "dependency": "Dipendenza", + "reason": "Motivo", + "title": "Dipendenze che bloccano la Task da essere pianificata" + }, + "calendar": { + "daily": "Giornaliero", + "hourly": "Orario", + "legend": { + "less": "Meno", + "more": "Più" + }, + "navigation": { + "nextMonth": "Mese successivo", + "nextYear": "Anno successivo", + "previousMonth": "Mese precedente", + "previousYear": "Anno precedente" + }, + "noData": "Nessun dato disponibile", + "noRuns": "Nessun run", + "totalRuns": "Run Totali", + "week": "Settimana {{weekNumber}}", + "weekdays": { + "friday": "Ven", + "monday": "Lun", + "saturday": "Sab", + "sunday": "Dom", + "thursday": "Gio", + "tuesday": "Mar", + "wednesday": "Mer" + } + }, + "code": { + "bundleUrl": "URL del Bundle", + "noCode": "Nessun Codice Trovato", + "parseDuration": "Durata del parsing", + "parsedAt": "Parsato il:" + }, + "extraLinks": "Extra Links", + "grid": { + "buttons": { + "resetToLatest": "Resetta al più recente", + "toggleGroup": "Attiva/Disattiva gruppo" + } + }, + "header": { + "buttons": { + "advanced": "Avanzato", + "dagDocs": "Documentazione sul Dag" + } + }, + "logs": { + "allLevels": "Tutti i Livelli di Log", + "allSources": "Tutte le Fonti", + "critical": "CRITICO", + "debug": "DEBUG", + "error": "ERRORE", + "fullscreen": { + "button": "Schermo Intero", + "tooltip": "Premi {{hotkey}} per schermo intero" + }, + "info": "INFO", + "noTryNumber": "Nessun numero di tentativo", + "settings": "Impostazioni Log", + "viewInExternal": "Visualizza i logs in {{name}} (tentativo {{attempt}})", + "warning": "AVVISO" + }, + "navigation": { + "navigation": "Navigazione: Shift+{{arrow}}", + "toggleGroup": "Attiva/Disattiva gruppo: Spazio" + }, + "overview": { + "buttons": { + "failedRun_many": "Run falliti", + "failedRun_one": "Run fallito", + "failedRun_other": "Run falliti", + "failedRun_zero": "Nessun Run fallito", + "failedTask_many": "Task falliti", + "failedTask_one": "Task fallito", + "failedTask_other": "Task falliti", + "failedTask_zero": "Nessun Task fallito", + "failedTaskInstance_many": "Istanze di Task fallite", + "failedTaskInstance_one": "Istanza di Task fallita", + "failedTaskInstance_other": "Istanze di Task fallite", + "failedTaskInstance_zero": "Nessuna istanza di Task fallita" + }, + "charts": { + "assetEvent_many": "Eventi di Asset Creati", + "assetEvent_one": "Evento di Asset Creato", + "assetEvent_other": "Eventi di Asset Creati", + "assetEvent_zero": "Nessun evento di asset creato" + }, + "failedLogs": { + "hideLogs": "Nascondi Logs", + "showLogs": "Mostra Logs", + "title": "Logs delle Task fallite recenti", + "viewFullLogs": "Visualizza i logs completi" + } + }, + "panel": { + "buttons": { + "options": "Opzioni", + "showGantt": "Mostra Gantt", + "showGraphShortcut": "Mostra Grafico (Premi g)", + "showGridShortcut": "Mostra Griglia (Premi g)" + }, + "dagRuns": { + "label": "Numero di Runs del Dag" + }, + "dependencies": { + "label": "Dipendenze", + "options": { + "allDagDependencies": "Tutte le Dipendenze del Dag", + "externalConditions": "Condizioni Esterne", + "onlyTasks": "Solo le Task" + }, + "placeholder": "Dipendenze" + }, + "graphDirection": { + "label": "Direzione del Grafico" + } + }, + "paramsFailed": "Impossibile caricare i parametri", + "parse": { + "toaster": { + "error": { + "description": "La richiesta di parsing del Dag è fallita. Potrebbero esserci richieste di parsing in sospeso da processare.", + "title": "Parsing del Dag fallito" + }, + "success": { + "description": "Il Dag dovrebbe essere riparsat presto.", + "title": "Richiesta di riparsing inviata con successo" + } + } + }, + "tabs": { + "assetEvents": "Eventi di Asset", + "auditLog": "Registro di Controllo (Logs)", + "backfills": "Backfills", + "calendar": "Calendario", + "code": "Codice", + "details": "Dettagli", + "logs": "Logs", + "mappedTaskInstances_many": "Istanze di Task [{{count}}]", + "mappedTaskInstances_one": "Istanza di Task [{{count}}]", + "mappedTaskInstances_other": "Istanze di Task [{{count}}]", + "mappedTaskInstances_zero": "Nessuna istanza di task mappata", + "overview": "Panoramica", + "renderedTemplates": "Template Renderizzato", + "requiredActions": "Azioni Richieste", + "runs": "Run", + "taskInstances": "Istanze di Task", + "tasks": "Tasks", + "xcom": "XCom" + }, + "taskGroups": { + "collapseAll": "Collassa tutti i gruppi di task", + "expandAll": "Espandi tutti i gruppi di task" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/dags.json new file mode 100644 index 0000000000000..0cb4eac8ac761 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/dags.json @@ -0,0 +1,97 @@ +{ + "assetSchedule": "{{count}} di {{total}} assets aggiornati", + "dagActions": { + "delete": { + "button": "Elimina Dag", + "warning": "Questo rimuoverà tutti i metadati relativi al Dag, compresi i Run e le Task." + } + }, + "favoriteDag": "Dag Preferito", + "filters": { + "allRunTypes": "Tutti i Tipi di Run", + "allStates": "Tutti gli Stati", + "favorite": { + "all": "Tutti", + "favorite": "Preferito", + "unfavorite": "Rimuovi dai preferiti" + }, + "paused": { + "active": "Attivo", + "all": "Tutti", + "paused": "In Pausa" + }, + "runIdPatternFilter": "Cercare Dag Runs", + "triggeringUserNameFilter": "Cercare per Utente che ha Attivato" + }, + "ownerLink": "Link dell'Owner per {{owner}}", + "runAndTaskActions": { + "affectedTasks": { + "noItemsFound": "Nessuna task trovata.", + "title": "Task interessati: {{count}}" + }, + "clear": { + "button": "Pulisci {{type}}", + "buttonTooltip": "Premi shift+c per pulire", + "error": "Impossibile pulire {{type}}", + "title": "Pulisci {{type}}" + }, + "delete": { + "button": "Elimina {{type}}", + "dialog": { + "resourceName": "{{type}} {{id}}", + "title": "Elimina {{type}}", + "warning": "Questo rimuoverà tutti i metadati relativi a {{type}}." + }, + "error": "Errore nell'eliminazione di {{type}}", + "success": { + "description": "La richiesta di eliminazione di {{type}} è stata completata con successo.", + "title": "{{type}} Eliminato con Successo" + } + }, + "markAs": { + "button": "Marca {{type}} come...", + "buttonTooltip": { + "failed": "Premi shift+f per marcare come fallito", + "success": "Premi shift+s per marcare come successo" + }, + "title": "Marca {{type}} come {{state}}" + }, + "options": { + "downstream": "Downstream", + "existingTasks": "Pulisci le task esistenti", + "future": "Futuro", + "onlyFailed": "Pulisci solo le task fallite", + "past": "Passato", + "queueNew": "Inserisci nuove task", + "runOnLatestVersion": "Esegui con l'ultima versione del bundle", + "upstream": "Upstream" + } + }, + "search": { + "advanced": "RiCercare Avanzata", + "clear": "Pulisci la ricerca", + "dags": "Cercare Dag", + "hotkey": "+K", + "tasks": "Cercare Task" + }, + "sort": { + "displayName": { + "asc": "Ordina per Nome (A-Z)", + "desc": "Ordina per Nome (Z-A)" + }, + "lastRunStartDate": { + "asc": "Ordina per Data di Inizio del Run più Recente (Prima-Ultimo)", + "desc": "Ordina per Data di Inizio del Run più Recente (Ultimo-Prima)" + }, + "lastRunState": { + "asc": "Ordina per Stato del Run più Recente (A-Z)", + "desc": "Ordina per Stato del Run più Recente (Z-A)" + }, + "nextDagRun": { + "asc": "Ordina per Next Dag Run (Prima-Ultimo)", + "desc": "Ordina per Next Dag Run (Ultimo-Prima)" + }, + "placeholder": "Ordina per" + }, + "unfavoriteDag": "Rimuovi Dag dai Preferiti" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/dashboard.json new file mode 100644 index 0000000000000..8533c24047a49 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/dashboard.json @@ -0,0 +1,49 @@ +{ + "favorite": { + "favoriteDags_many": "{{count}} Dags preferiti", + "favoriteDags_one": "Primo {{count}} Dag preferito", + "favoriteDags_other": "Primi {{count}} Dags preferiti", + "favoriteDags_zero": "Nessun Dag preferito", + "noDagRuns": "Non ci sono ancora DagRun per questo dag.", + "noFavoriteDags": "Nessun preferito ancora. Clicca sull'icona stella accanto a un Dag nella lista per aggiungerlo ai tuoi preferiti." + }, + "group": "Gruppo", + "health": { + "dagProcessor": "Processore del Dag", + "health": "Salute", + "healthy": "Sano", + "lastHeartbeat": "Ultimo Heartbeat", + "metaDatabase": "Database di metadati", + "scheduler": "Pianificatrice", + "status": "Stato", + "triggerer": "Triggerer", + "unhealthy": "Malato" + }, + "history": "Cronologia", + "importErrors": { + "dagImportError_many": "Errori di Importazione Dag", + "dagImportError_one": "Errore di Importazione Dag", + "dagImportError_other": "Errori di Importazione Dag", + "dagImportError_zero": "Nessun errore di importazione Dag", + "searchByFile": "Cercare per file", + "timestamp": "Timestamp" + }, + "managePools": "Gestisci Pools", + "noAssetEvents": "Nessun evento di asset trovato.", + "poolSlots": "Slot del Pool", + "sortBy": { + "newestFirst": "Più Recenti", + "oldestFirst": "Più Vecchi" + }, + "source": "Fonte", + "stats": { + "activeDags": "Dags Attivi", + "failedDags": "Dags Falliti", + "queuedDags": "Dags In Attesa", + "requiredActions": "Azioni Richieste", + "runningDags": "Dags In Esecuzione", + "stats": "Statistiche" + }, + "uri": "Uri", + "welcome": "Benvenuto" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/hitl.json new file mode 100644 index 0000000000000..5a76d6035d7e8 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/hitl.json @@ -0,0 +1,38 @@ +{ + "filters": { + "response": { + "all": "Tutte", + "pending": "In attesa", + "received": "Ricevute" + } + }, + "requiredAction_many": "Azioni richieste", + "requiredAction_one": "Azione richiesta", + "requiredAction_other": "Azioni richieste", + "requiredAction_zero": "Nessuna azione richiesta", + "requiredActionCount_many": "Azioni richieste ({{count}})", + "requiredActionCount_one": "Azione richiesta ({{count}})", + "requiredActionCount_other": "Azioni richieste ({{count}})", + "requiredActionCount_zero": "Nessuna azione richiesta", + "requiredActionState": "Stato dell'Azione richiesta", + "response": { + "error": "Errore nella Risposta", + "optionsDescription": "Scegli le tue opzioni per questa istanza di task", + "optionsLabel": "Opzioni", + "received": "Risposta ricevuta il ", + "respond": "Rispondi", + "success": "Risposta di {{taskId}} riuscita", + "title": "Istanza di Task Umana - {{taskId}}" + }, + "state": { + "approvalReceived": "Approvazione ricevuta", + "approvalRequired": "Approvazione richiesta", + "choiceReceived": "Scelta ricevuta", + "choiceRequired": "Scelta richiesta", + "noResponseReceived": "Nessuna risposta ricevuta", + "rejectionReceived": "Rifiuto ricevuto", + "responseReceived": "Risposta ricevuta", + "responseRequired": "Risposta richiesta" + }, + "subject": "Oggetto" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/it/tasks.json b/airflow-core/src/airflow/ui/public/i18n/locales/it/tasks.json new file mode 100644 index 0000000000000..eff98e212b664 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/it/tasks.json @@ -0,0 +1,10 @@ +{ + "mapped": "Mappato", + "notMapped": "Non mappato", + "retries": "Tentativi", + "searchTasks": "Cercare attività", + "selectMapped": "Seleziona mappato", + "selectOperator": "Seleziona operatore", + "selectRetryValues": "Seleziona valori di Retry", + "selectTriggerRules": "Seleziona regole di Trigger" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/admin.json index 5acf37c678506..9e6be8a1ee554 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/admin.json @@ -72,7 +72,6 @@ "tooltip": "선택된 커넥션들 삭제" }, "formActions": { - "reset": "초기화", "save": "저장" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/common.json index bd391224d51d2..a909e2495ef4f 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/common.json @@ -8,6 +8,12 @@ "Variables": "변수들" }, "allOperators": "모든 오퍼레이터", + "appearance": { + "appearance": "외관", + "darkMode": "다크 모드", + "lightMode": "라이트 모드", + "systemMode": "시스템 설정 따르기" + }, "asset_one": "에셋", "asset_other": "에셋들", "assetEvent_one": "에셋 이벤트", @@ -33,6 +39,7 @@ "fileLocation": "파일 위치", "hasTaskConcurrencyLimits": "태스크 동시성 제한 존재 여부", "lastExpired": "마지막 만료 시점", + "lastParseDuration": "마지막 파싱 기간", "lastParsed": "마지막 파싱 시점", "latestDagVersion": "최신 Dag 버전", "latestRun": "최근 실행", @@ -92,16 +99,12 @@ "any": "모든", "or": "또는" }, + "filter": "필터", "filters": { - "dagDisplayNamePlaceholder": "Dag로 필터링", - "keyPlaceholder": "XCom 키로 필터링", - "logicalDateFromPlaceholder": "논리적 날짜 (시작)", - "logicalDateToPlaceholder": "논리적 날짜 (종료)", - "mapIndexPlaceholder": "맵 인덱스로 필터링", - "runAfterFromPlaceholder": "실행 이후 (시작)", - "runAfterToPlaceholder": "실행 이후 (종료)", - "runIdPlaceholder": "실행 ID로 필터링", - "taskIdPlaceholder": "작업 ID로 필터링" + "logicalDateFrom": "논리적 날짜 (시작)", + "logicalDateTo": "논리적 날짜 (종료)", + "runAfterFrom": "실행 이후 (시작)", + "runAfterTo": "실행 이후 (종료)" }, "logicalDate": "논리적 날짜", "logout": "로그아웃", @@ -143,6 +146,7 @@ "running": "실행 중", "scheduled": "예약됨" }, + "reset": "초기화", "runId": "실행 ID", "runTypes": { "asset_triggered": "에셋 트리거", @@ -157,7 +161,6 @@ }, "tooltip": "{{hotkey}}를 눌러 {{direction}}로 스크롤" }, - "seconds": "{{count}}초", "security": { "actions": "작업", "permissions": "권한", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/components.json index 3395f29de4452..e4dfd34a9f500 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/components.json @@ -6,8 +6,6 @@ "allRuns": "모든 실행", "backwards": "거꾸로 실행", "dateRange": "날짜 범위", - "dateRangeFrom": "시작", - "dateRangeTo": "종료", "errorStartDateBeforeEndDate": "시작일은 종료일보다 빨라야 합니다.", "maxRuns": "최대 활성 실행 수", "missingAndErroredRuns": "누락되었거나 오류가 발생한 실행", @@ -88,6 +86,11 @@ "taskGroup": "작업 그룹" }, "limitedList": "+{{count}}개 더 보기", + "limitedList.allItems": "모든 {{count}}개 항목:", + "limitedList.clickToInteract": "태그를 클릭하여 Dag를 필터링하세요", + "limitedList.clickToOpenFull": "\"+{{count}}개 더 보기\"를 클릭하여 전체 보기 열기", + "limitedList.copyPasteText": "위의 텍스트를 복사하여 붙여넣을 수 있습니다", + "limitedList.showingItems": "{{count}}개 항목 표시 중", "logs": { "file": "파일", "location": "{{name}}의 {{line}}번째 줄" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json index 2bdcff01f452f..554d8d5263e1a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json @@ -35,7 +35,8 @@ "code": { "bundleUrl": "번들 URL", "noCode": "코드를 찾을 수 없습니다.", - "parsedAt": "구문 분석 시간:" + "parseDuration": "파싱 기간:", + "parsedAt": "파싱 시간:" }, "extraLinks": "추가 링크", "grid": { @@ -84,6 +85,8 @@ "assetEvent_other": "생성된 에셋 이벤트" }, "failedLogs": { + "hideLogs": "로그 숨기기", + "showLogs": "로그 보기", "title": "최근 실패한 작업 로그", "viewFullLogs": "전체 로그 보기" } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/hitl.json index 488a6504f8e7a..8b78496ce6d9e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/hitl.json @@ -8,6 +8,8 @@ }, "requiredAction_one": "필수 작업", "requiredAction_other": "필수 작업들", + "requiredActionCount_one": "필수 작업 ({{count}})", + "requiredActionCount_other": "필수 작업들 ({{count}})", "requiredActionState": "필수 작업 상태", "response": { "error": "응답 실패", @@ -23,6 +25,7 @@ "approvalRequired": "승인 필요", "choiceReceived": "선택 수신됨", "choiceRequired": "선택 필요", + "noResponseReceived": "응답 없음", "rejectionReceived": "거절 수신됨", "responseReceived": "응답 수신됨", "responseRequired": "응답 필요" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/admin.json index e584a54c77849..39d3b73bdcaa5 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/admin.json @@ -72,8 +72,7 @@ "tooltip": "Verwijder geselecteerde connecties" }, "formActions": { - "reset": "Reset", - "save": "Opsalaan" + "save": "Opslaan" }, "plugins": { "columns": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/common.json index 95707d92beb14..04136a9510fbf 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/common.json @@ -39,6 +39,7 @@ "fileLocation": "Bestandslocatie", "hasTaskConcurrencyLimits": "Heeft Task Concurrency limieten", "lastExpired": "Laatst verlopen", + "lastParseDuration": "Laatste parse duur", "lastParsed": "Laatst geparsed", "latestDagVersion": "Laatste Dag versie", "latestRun": "Laatste Run", @@ -98,16 +99,12 @@ "any": "Elk", "or": "Of" }, + "filter": "Filter", "filters": { - "dagDisplayNamePlaceholder": "Filter op Dag", - "keyPlaceholder": "Filter op XCom sleutel", - "logicalDateFromPlaceholder": "Van logische datum", - "logicalDateToPlaceholder": "Tot logische datum", - "mapIndexPlaceholder": "Filter op Map Index", - "runAfterFromPlaceholder": "Van Run na", - "runAfterToPlaceholder": "Tot Run na", - "runIdPlaceholder": "Filter op Run ID", - "taskIdPlaceholder": "Filter op Task ID" + "logicalDateFrom": "Van logische datum", + "logicalDateTo": "Tot logische datum", + "runAfterFrom": "Van Run na", + "runAfterTo": "Tot Run na" }, "logicalDate": "Logische datum", "logout": "Uitloggen", @@ -149,6 +146,7 @@ "running": "Lopend", "scheduled": "Gepland" }, + "reset": "Reset", "runId": "Run ID", "runTypes": { "asset_triggered": "Asset Triggered", @@ -163,7 +161,6 @@ }, "tooltip": "Druk op {{hotkey}} om te scrollen naar {{direction}}" }, - "seconds": "{{count}}s", "security": { "actions": "Acties", "permissions": "Permissies", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json index b3b6e82d10f6f..83785a7112a41 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json @@ -1,13 +1,11 @@ { "backfill": { - "affected_one": "1 run zal getriggered worden.", - "affected_other": "{{count}} Runs zullen getriggered worden.", + "affected_one": "1 run zal getriggerd worden.", + "affected_other": "{{count}} Runs zullen getriggerd worden.", "affectedNone": "Geen Runs komen overeen met de geselecteerde criteria.", "allRuns": "Alle Runs", "backwards": "Run achterstevoren", "dateRange": "Datumbereik", - "dateRangeFrom": "Van", - "dateRangeTo": "Tot", "errorStartDateBeforeEndDate": "Startdatum moet voor de einddatum", "maxRuns": "Maximaal aantal actieve Runs", "missingAndErroredRuns": "Missende en mislukte Runs", @@ -90,6 +88,11 @@ "taskGroup": "Task Group" }, "limitedList": "+{{count}} meer", + "limitedList.allItems": "Alle {{count}} items:", + "limitedList.clickToInteract": "Klik op een label om Dags te filteren", + "limitedList.clickToOpenFull": "Klik op \"+{{count}} meer\" om de volledige lijst te openen", + "limitedList.copyPasteText": "Je kunt de bovenstaande tekst kopiëren en plakken", + "limitedList.showingItems": "{{count}} items weergegeven", "logs": { "file": "Bestand", "location": "regel {{line}} in {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json index 07a30b10bbfe3..ad1a937e6afff 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json @@ -35,7 +35,8 @@ "code": { "bundleUrl": "Bundle URL", "noCode": "Geen code gevonden", - "parsedAt": "Parsed at:" + "parseDuration": "Parse duur:", + "parsedAt": "Geparsed op:" }, "extraLinks": "Extra Links", "grid": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/admin.json index 3328d86ee87b1..d9ee05ce801a6 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/admin.json @@ -78,7 +78,6 @@ "tooltip": "Usuń wybrane połączenia" }, "formActions": { - "reset": "Resetuj", "save": "Zapisz" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/common.json index f5f657e40c8c5..04ca807223bc1 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/common.json @@ -111,17 +111,12 @@ "any": "Dowolne", "or": "LUB" }, + "filter": "Filtr", "filters": { - "dagDisplayNamePlaceholder": "Filtruj według Daga", - "keyPlaceholder": "Filtruj według klucza XCom", - "logicalDateFromPlaceholder": "Data logiczna od", - "logicalDateToPlaceholder": "Data logiczna do", - "mapIndexPlaceholder": "Filtruj według indeksu mapowania", - "runAfterFromPlaceholder": "Uruchom po (od)", - "runAfterToPlaceholder": "Uruchom po (do)", - "runIdPlaceholder": "Filtruj według identyfikatora uruchomienia", - "taskIdPlaceholder": "Filtruj według identyfikatora zadania", - "triggeringUserPlaceholder": "Filtruj według uruchamiającego użytkownika" + "logicalDateFrom": "Data logiczna od", + "logicalDateTo": "Data logiczna do", + "runAfterFrom": "Uruchom po (od)", + "runAfterTo": "Uruchom po (do)" }, "logicalDate": "Data logiczna", "logout": "Wyloguj", @@ -165,6 +160,7 @@ "running": "W trakcie", "scheduled": "Zaplanowane" }, + "reset": "Resetuj", "runId": "Identyfikator wykonania", "runTypes": { "asset_triggered": "Uruchomiony przez zasób", @@ -179,7 +175,6 @@ }, "tooltip": "Naciśnij {{hotkey}}, aby przewinąć do {{direction}}" }, - "seconds": "{{count}}s", "security": { "actions": "Akcje", "permissions": "Uprawnienia", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/components.json index 0dc4b8699757d..932d7d87bf7fb 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/components.json @@ -8,8 +8,6 @@ "allRuns": "Wszystkie wykonania", "backwards": "Uruchom wstecz", "dateRange": "Zakres dat", - "dateRangeFrom": "Od", - "dateRangeTo": "Do", "errorStartDateBeforeEndDate": "Data początkowa musi być wcześniejsza niż data końcowa", "maxRuns": "Maksymalna liczba aktywnych wykonań", "missingAndErroredRuns": "Brakujące i błędne wykonania", @@ -104,6 +102,18 @@ "taskGroup": "Grupa zadań" }, "limitedList": "+{{count}} więcej", + "limitedList.allItems": "Wszystkie {{count}} elementy:", + "limitedList.allTags_few": "Wszystkie tagi ({{count}})", + "limitedList.allTags_many": "Wszystkie tagi ({{count}})", + "limitedList.allTags_one": "Wszystkie tagi (1)", + "limitedList.allTags_other": "Wszystkie tagi ({{count}})", + "limitedList.clickToInteract": "Kliknij etykietę, aby przefiltrować Dagi", + "limitedList.clickToOpenFull": "Kliknij \"+{{count}} więcej\", aby zobaczyć pełną listę", + "limitedList.copyPasteText": "Możesz skopiować i wkleić powyższy tekst", + "limitedList.showingItems_few": "Wyświetlanie {{count}} elementów", + "limitedList.showingItems_many": "Wyświetlanie {{count}} elementów", + "limitedList.showingItems_one": "Wyświetlanie 1 elementu", + "limitedList.showingItems_other": "Wyświetlanie {{count}} elementów", "logs": { "file": "Plik", "location": "linia {{line}} w {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dags.json index 9ca67b21a5be2..61b1f1fe712c4 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dags.json @@ -20,8 +20,7 @@ "all": "Wszystkie", "paused": "Wstrzymane" }, - "runIdPatternFilter": "Szukaj Wykonań Dagów", - "triggeringUserNameFilter": "Szukaj według użytkownika wywołującego" + "runIdPatternFilter": "Szukaj Wykonań Dagów" }, "ownerLink": "Link do właściciela {{owner}}", "runAndTaskActions": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/hitl.json index 428f1313ce1ed..c5023a8ad121d 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/hitl.json @@ -1,5 +1,8 @@ { "filters": { + "body": "Treść", + "createdAtFrom": "Utworzono od", + "createdAtTo": "Utworzono do", "response": { "all": "Wszystkie", "pending": "Oczekujące", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/admin.json new file mode 100644 index 0000000000000..86b74854eff21 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/admin.json @@ -0,0 +1,182 @@ +{ + "columns": { + "description": "Descrição", + "key": "Chave", + "name": "Nome", + "value": "Valor" + }, + "config": { + "columns": { + "section": "Secção" + }, + "title": "Configuração do Airflow" + }, + "connections": { + "add": "Adicionar Conexão", + "columns": { + "connectionId": "ID da Conexão", + "connectionType": "Tipo de Conexão", + "host": "Host", + "port": "Porta" + }, + "connection_many": "Conexões", + "connection_one": "Conexão", + "connection_other": "Conexões", + "connection_zero": "Nenhuma conexão", + "delete": { + "deleteConnection_many": "Excluir {{count}} conexões", + "deleteConnection_one": "Excluir 1 conexão", + "deleteConnection_other": "Excluir {{count}} conexões", + "deleteConnection_zero": "Nenhuma conexão para excluir", + "firstConfirmMessage_many": "Você está prestes a excluir as seguintes conexões:", + "firstConfirmMessage_one": "Você está prestes a excluir a seguinte conexão:", + "firstConfirmMessage_other": "Você está prestes a excluir as seguintes conexões:", + "firstConfirmMessage_zero": "Nenhuma conexão para excluir", + "title": "Excluir Conexão" + }, + "edit": "Editar Conexão", + "form": { + "connectionIdRequired": "ID da Conexão é obrigatório", + "connectionIdRequirement": "ID da Conexão não pode conter somente espaços", + "connectionTypeRequired": "Tipo de Conexão é obrigatório", + "extraFields": "Campos Extra", + "extraFieldsJson": "Campos Extra JSON", + "helperText": "Tipo de conexão faltando? Certifique-se de ter instalado o pacote do provider correspondente ao Airflow.", + "helperTextForRedactedFields": "Os campos redigidos ('***') permanecerão inalterados se não forem modificados.", + "selectConnectionType": "Selecionar Tipo de Conexão", + "standardFields": "Campos Padrão" + }, + "nothingFound": { + "description": "Conexões definidas via variáveis de ambiente ou gerenciadores de segredos não estão listadas aqui.", + "documentationLink": "Saiba mais na documentação do Airflow.", + "learnMore": "Estas são resolvidas em tempo de execução e não são visíveis na interface do usuário.", + "title": "Nenhuma conexão encontrada!" + }, + "searchPlaceholder": "Pesquisar Conexões", + "test": "Testar Conexão", + "testDisabled": "A funcionalidade de teste de conexão está desativada. Por favor, contate um administrador para ativá-la.", + "typeMeta": { + "error": "Falha ao recuperar Meta do Tipo de Conexão", + "standardFields": { + "description": "Descrição", + "host": "Host", + "login": "Login", + "password": "Senha", + "port": "Porta", + "url_schema": "Esquema" + } + } + }, + "deleteActions": { + "button": "Excluir", + "modal": { + "confirmButton": "Sim, Excluir", + "secondConfirmMessage": "Esta ação é permanente e não pode ser desfeita.", + "thirdConfirmMessage": "Tem certeza que deseja prosseguir?" + }, + "selected": "Selecionado", + "tooltip": "Excluir conexões selecionadas" + }, + "formActions": { + "save": "Salvar" + }, + "plugins": { + "columns": { + "source": "Origem" + }, + "importError_many": "Erros de Importação de Plugins", + "importError_one": "Erro de Importação de Plugin", + "importError_other": "Erros de Importação de Plugins", + "importError_zero": "Nenhum erro de importação de plugin", + "searchPlaceholder": "Pesquisar por arquivo" + }, + "pools": { + "add": "Adicionar Pool", + "deferredSlotsIncluded": "Slots Deferidos Incluídos", + "delete": { + "title": "Excluir Pool", + "warning": "Isso removerá todas as metadados relacionados ao pool e pode afetar as tarefas usando este pool." + }, + "edit": "Editar Pool", + "form": { + "checkbox": "Marcar para incluir tarefas deferidas ao calcular slots abertos do pool", + "description": "Descrição", + "includeDeferred": "Incluir Deferidos", + "nameMaxLength": "Nome pode conter um máximo de 256 caracteres", + "nameRequired": "Nome é obrigatório", + "slots": "Slots" + }, + "noPoolsFound": "Nenhum pool encontrado", + "pool_many": "Pools", + "pool_one": "Pool", + "pool_other": "Pools", + "pool_zero": "Nenhum pool", + "searchPlaceholder": "Pesquisar Pools", + "sort": { + "asc": "Nome (A-Z)", + "desc": "Nome (Z-A)", + "placeholder": "Ordenar por" + } + }, + "providers": { + "columns": { + "packageName": "Nome do Pacote", + "version": "Versão" + } + }, + "variables": { + "add": "Adicionar Variável", + "columns": { + "isEncrypted": "Está Encriptado" + }, + "delete": { + "deleteVariable_many": "Excluir {{count}} Variáveis", + "deleteVariable_one": "Excluir 1 Variável", + "deleteVariable_other": "Excluir {{count}} Variáveis", + "deleteVariable_zero": "Nenhuma variável para excluir", + "firstConfirmMessage_many": "Você está prestes a excluir as seguintes variáveis:", + "firstConfirmMessage_one": "Você está prestes a excluir a seguinte variável:", + "firstConfirmMessage_other": "Você está prestes a excluir as seguintes variáveis:", + "firstConfirmMessage_zero": "Nenhuma variável para excluir", + "title": "Excluir Variável", + "tooltip": "Excluir variáveis selecionadas" + }, + "edit": "Editar Variável", + "export": "Exportar", + "exportTooltip": "Exportar variáveis selecionadas", + "form": { + "invalidJson": "JSON Inválido", + "keyMaxLength": "Chave pode conter um máximo de 250 caracteres", + "keyRequired": "Chave é obrigatória", + "valueRequired": "Valor é obrigatório" + }, + "import": { + "button": "Importar", + "conflictResolution": "Selecionar Resolução de Conflito de Variável", + "errorParsingJsonFile": "Erro ao Analisar Arquivo JSON: Upload um arquivo JSON contendo variáveis (exemplo: {\"key\": \"value\", ...}).", + "options": { + "fail": { + "description": "Falha na importação se forem detetadas variáveis que já existem.", + "title": "Falha" + }, + "overwrite": { + "description": "Sobreescreve a variável em caso de conflito.", + "title": "Sobreescrever" + }, + "skip": { + "description": "Ignora a importação de variáveis que já existem.", + "title": "Ignorar" + } + }, + "title": "Importar Variáveis", + "upload": "Upload um Arquivo JSON", + "uploadPlaceholder": "Upload um arquivo JSON contendo variáveis (exemplo: {\"key\": \"value\", ...})" + }, + "noRowsMessage": "Nenhuma variável encontrada", + "searchPlaceholder": "Pesquisar Chaves", + "variable_many": "Variáveis", + "variable_one": "Variável", + "variable_other": "Variáveis", + "variable_zero": "Nenhuma variável" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/assets.json new file mode 100644 index 0000000000000..f40bb8e70c986 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/assets.json @@ -0,0 +1,30 @@ +{ + "consumingDags": "Consumindo DAGs", + "createEvent": { + "button": "Criar Evento", + "manual": { + "description": "Manualmente criar um Evento de Asset", + "extra": "Evento de Asset Extra", + "label": "Manual" + }, + "materialize": { + "description": "Ativar o DAG acima deste Asset", + "descriptionWithDag": "Ativar o DAG acima deste Asset: {{dagName}}", + "label": "Materializar", + "unpauseDag": "Despausar {{dagName}} ao ativar" + }, + "success": { + "manualDescription": "Criação de evento de Asset manual foi bem-sucedida.", + "manualTitle": "Evento de Asset Criado", + "materializeDescription": "DAG acima {{dagId}} foi ativado com sucesso.", + "materializeTitle": "Materializando Asset" + }, + "title": "Criar Evento de Asset para {{name}}" + }, + "group": "Grupo", + "lastAssetEvent": "Último Evento de Asset", + "name": "Nome", + "producingTasks": "Produzindo Tarefas", + "scheduledDags": "DAGs Programados", + "searchPlaceholder": "Pesquisar Assets" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/browse.json new file mode 100644 index 0000000000000..d22701bfabc8c --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/browse.json @@ -0,0 +1,26 @@ +{ + "auditLog": { + "actions": { + "collapseAllExtra": "Recolher todos os extra json", + "expandAllExtra": "Expandir todos os extra json" + }, + "columns": { + "event": "Evento", + "extra": "Extra", + "user": "Usuário", + "when": "Quando" + }, + "filters": { + "eventType": "Tipo de Evento" + }, + "title": "Log de Auditoria" + }, + "xcom": { + "columns": { + "dag": "DAG", + "key": "Chave", + "value": "Valor" + }, + "title": "XCom" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/common.json new file mode 100644 index 0000000000000..8ab097b993ce4 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/common.json @@ -0,0 +1,338 @@ +{ + "admin": { + "Config": "Configuração", + "Connections": "Conexões", + "Plugins": "Plugins", + "Pools": "Pools", + "Providers": "Providers", + "Variables": "Variáveis" + }, + "allOperators": "Todos os Operadores", + "appearance": { + "appearance": "Aparência", + "darkMode": "Modo Escuro", + "lightMode": "Modo Claro", + "systemMode": "Seguir Configuração do Sistema" + }, + "asset_many": "Assets", + "asset_one": "Asset", + "asset_other": "Assets", + "asset_zero": "Nenhum asset", + "assetEvent_many": "Eventos de Asset", + "assetEvent_one": "Evento de Asset", + "assetEvent_other": "Eventos de Asset", + "assetEvent_zero": "Nenhum evento de asset", + "backfill_many": "Backfills", + "backfill_one": "Backfill", + "backfill_other": "Backfills", + "backfill_zero": "Nenhum backfill", + "browse": { + "auditLog": "Log de Auditoria", + "requiredActions": "Ações Necessárias", + "xcoms": "XComs" + }, + "collapseDetailsPanel": "Recolher Painel de Detalhes", + "createdAssetEvent_many": "Eventos de Asset Criados", + "createdAssetEvent_one": "Evento de Asset Criado", + "createdAssetEvent_other": "Eventos de Asset Criados", + "createdAssetEvent_zero": "Nenhum evento de asset criado", + "dag_many": "DAGs", + "dag_one": "DAG", + "dag_other": "DAGs", + "dag_zero": "Nenhum DAG", + "dagDetails": { + "catchup": "Catchup", + "dagRunTimeout": "Tempo Limite da Execução do DAG", + "defaultArgs": "Argumentos Padrão", + "description": "Descrição", + "documentation": "Documentação do DAG", + "fileLocation": "Local do Arquivo", + "hasTaskConcurrencyLimits": "Tem Limite de Concorrência de Tarefas", + "lastExpired": "Último Expirado", + "lastParseDuration": "Duração do Último Parse", + "lastParsed": "Último Parseado", + "latestDagVersion": "Última Versão do DAG", + "latestRun": "Última Execução", + "maxActiveRuns": "Máximo de Execuções Ativas", + "maxActiveTasks": "Máximo de Tarefas Ativas", + "maxConsecutiveFailedDagRuns": "Máximo de Execuções Consecutivas Falhadas", + "nextRun": "Próxima Execução", + "owner": "Proprietário", + "params": "Parâmetros", + "schedule": "Agendamento", + "tags": "Etiquetas" + }, + "dagId": "ID do DAG", + "dagRun": { + "conf": "Conf", + "dagVersions": "Versão(s) do DAG", + "dataIntervalEnd": "Fim do Intervalo de Dados", + "dataIntervalStart": "Início do Intervalo de Dados", + "lastSchedulingDecision": "Última Decisão de Agendamento", + "queuedAt": "Enfileirado Em", + "runAfter": "Executar Depois", + "runType": "Tipo de Execução", + "sourceAssetEvent": "Evento de Asset de Origem", + "triggeredBy": "Acionado por", + "triggeringUser": "Nome do Usuário que Disparou" + }, + "dagRun_many": "Execuções do DAG", + "dagRun_one": "Execução do DAG", + "dagRun_other": "Execuções do DAG", + "dagRun_zero": "Nenhuma execução do DAG", + "dagRunId": "ID da Execução do DAG", + "dagWarnings": "Avisos/Erros do DAG", + "defaultToGraphView": "Padrão para visualização gráfica", + "defaultToGridView": "Padrão para visualização em grade", + "direction": "Direção", + "docs": { + "documentation": "Documentação", + "githubRepo": "Repositório GitHub", + "restApiReference": "Referência da API REST" + }, + "duration": "Duração", + "endDate": "Data Final", + "error": { + "back": "Voltar", + "defaultMessage": "Ocorreu um erro inesperado", + "home": "Início", + "notFound": "Página Não Encontrada", + "title": "Erro" + }, + "expand": { + "collapse": "Recolher", + "expand": "Expandir", + "hotkey": "Pressione {{hotkey}} para expandir ou recolher", + "tooltip": "Pressione {{hotkey}} para expandir ou recolher a secção" + }, + "expression": { + "all": "Todos", + "and": "E", + "any": "Qualquer", + "or": "OU" + }, + "filter": "Filtro", + "filters": { + "logicalDateFrom": "Data Lógica De", + "logicalDateTo": "Data Lógica Para", + "runAfterFrom": "Executar Depois De", + "runAfterTo": "Executar Depois Para" + }, + "logicalDate": "Data Lógica", + "logout": "Sair", + "logoutConfirmation": "Você está prestes a sair do aplicativo.", + "mapIndex": "Índice do Mapa", + "modal": { + "cancel": "Cancelar", + "confirm": "Confirmar", + "delete": { + "button": "Excluir", + "confirmation": "Tem certeza que deseja excluir {{resourceName}}? Esta ação não pode ser desfeita." + } + }, + "nav": { + "admin": "Administração", + "assets": "Assets", + "browse": "Navegar", + "dags": "DAGs", + "docs": "Documentação", + "home": "Início", + "legacyFabViews": "Visualizações Legacy FAB", + "plugins": "Plugins", + "security": "Segurança" + }, + "noItemsFound": "Nenhum {{modelName}} encontrado", + "note": { + "add": "Adicionar uma nota", + "dagRun": "Nota da Execução do DAG", + "label": "Nota", + "placeholder": "Adicionar uma nota...", + "taskInstance": "Nota da Instância de Tarefa" + }, + "pools": { + "deferred": "Deferido", + "open": "Aberto", + "pools_many": "pools", + "pools_one": "pool", + "pools_other": "pools", + "pools_zero": "nenhum pool", + "queued": "Enfileirado", + "running": "Executando", + "scheduled": "Agendado" + }, + "reset": "Resetar", + "runId": "ID da Execução", + "runTypes": { + "asset_triggered": "Asset Acionado", + "backfill": "Backfill", + "manual": "Manual", + "scheduled": "Agendado" + }, + "scroll": { + "direction": { + "bottom": "Inferior", + "top": "Superior" + }, + "tooltip": "Pressione {{hotkey}} para rolar para {{direction}}" + }, + "security": { + "actions": "Ações", + "permissions": "Permissões", + "resources": "Recursos", + "roles": "Funções", + "users": "Usuários" + }, + "selectLanguage": "Selecionar Idioma", + "showDetailsPanel": "Mostrar Painel de Detalhes", + "source": { + "hide": "Ocultar", + "hotkey": "Pressione {{hotkey}} para ocultar/mostrar", + "show": "Mostrar" + }, + "sourceAssetEvent_many": "Eventos de Asset de Origem", + "sourceAssetEvent_one": "Evento de Asset de Origem", + "sourceAssetEvent_other": "Eventos de Asset de Origem", + "sourceAssetEvent_zero": "Nenhum evento de asset de origem", + "startDate": "Data Inicial", + "state": "Estado", + "states": { + "deferred": "Deferido", + "failed": "Falha", + "no_status": "Sem Status", + "none": "Sem Status", + "planned": "Planejado", + "queued": "Enfileirado", + "removed": "Removido", + "restarting": "Reiniciando", + "running": "Executando", + "scheduled": "Agendado", + "skipped": "Pulado", + "success": "Sucesso", + "up_for_reschedule": "Pronto para reagendar", + "up_for_retry": "Pronto para tentar novamente", + "upstream_failed": "Falha no upstream" + }, + "table": { + "completedAt": "Concluído em", + "createdAt": "Criado em", + "filterByTag": "Filtrar DAGs por tag", + "filterColumns": "Filtrar colunas da tabela", + "filterReset_many": "Resetar filtros", + "filterReset_one": "Resetar filtro", + "filterReset_other": "Resetar filtros", + "filterReset_zero": "Nenhum filtro para resetar", + "from": "De", + "maxActiveRuns": "Máximo de Execuções Ativas", + "noTagsFound": "Nenhuma tag encontrada", + "tagMode": { + "all": "Todos", + "any": "Qualquer" + }, + "tagPlaceholder": "Filtrar por tag", + "to": "Para" + }, + "task": { + "documentation": "Documentação da Tarefa", + "lastInstance": "Última Instância", + "operator": "Operador", + "triggerRule": "Regra de Trigger" + }, + "task_many": "Tarefas", + "task_one": "Tarefa", + "task_other": "Tarefas", + "task_zero": "Nenhuma tarefa", + "taskGroup": "Grupo de Tarefas", + "taskId": "ID da Tarefa", + "taskInstance": { + "dagVersion": "Versão do DAG", + "executor": "Executor", + "executorConfig": "Configuração do Executor", + "hostname": "Hostname", + "maxTries": "Máximo de Tentativas", + "pid": "PID", + "pool": "Pool", + "poolSlots": "Slots do Pool", + "priorityWeight": "Prioridade", + "queue": "Fila", + "queuedWhen": "Enfileirado em", + "scheduledWhen": "Agendado em", + "triggerer": { + "assigned": "Triggerer atribuído", + "class": "Classe do Trigger", + "createdAt": "Tempo de criação do Trigger", + "id": "ID do Trigger", + "latestHeartbeat": "Último heartbeat do Trigger", + "title": "Informações do Trigger" + }, + "unixname": "Nome do Unix" + }, + "taskInstance_many": "Instâncias de Tarefa", + "taskInstance_one": "Instância de Tarefa", + "taskInstance_other": "Instâncias de Tarefa", + "taskInstance_zero": "Nenhuma instância de tarefa", + "timeRange": { + "last12Hours": "Últimas 12 Horas", + "last24Hours": "Últimas 24 Horas", + "lastHour": "Última Hora", + "pastWeek": "Semana Passada" + }, + "timestamp": { + "hide": "Ocultar", + "hotkey": "Pressione {{hotkey}} para ocultar/mostrar", + "show": "Mostrar" + }, + "timezone": "Fuso Horário", + "timezoneModal": { + "current-timezone": "Hora atual em", + "placeholder": "Selecionar um fuso horário", + "title": "Selecionar Fuso Horário", + "utc": "UTC (Tempo Universal Coordenado)" + }, + "toaster": { + "bulkDelete": { + "error": "Exclusão em Massa de {{resourceName}} Falhou", + "success": { + "description": "{{count}} {{resourceName}} foram excluídos com sucesso. Chaves: {{keys}}", + "title": "Exclusão em Massa de {{resourceName}} Submetida" + } + }, + "create": { + "error": "Criação de {{resourceName}} Falhou", + "success": { + "description": "{{resourceName}} foi criado com sucesso.", + "title": "Criação de {{resourceName}} Submetida" + } + }, + "delete": { + "error": "Exclusão de {{resourceName}} Falhou", + "success": { + "description": "{{resourceName}} foi excluído com sucesso.", + "title": "Exclusão de {{resourceName}} Submetida" + } + }, + "import": { + "error": "Importação de {{resourceName}} Falhou", + "success": { + "description": "{{count}} {{resourceName}} foram importados com sucesso.", + "title": "Importação de {{resourceName}} Submetida" + } + }, + "update": { + "error": "Atualização de {{resourceName}} Falhou", + "success": { + "description": "{{resourceName}} foi atualizado com sucesso.", + "title": "Atualização de {{resourceName}} Submetida" + } + } + }, + "total": "Total {{state}}", + "triggered": "Acionado", + "tryNumber": "Número de Tentativas", + "user": "Usuário", + "wrap": { + "hotkey": "Pressione {{hotkey}} para expandir ou recolher", + "tooltip": "Pressione {{hotkey}} para expandir ou recolher a secção", + "unwrap": "Expandir", + "wrap": "Recolher" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/components.json new file mode 100644 index 0000000000000..ae83855677a6c --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/components.json @@ -0,0 +1,153 @@ +{ + "backfill": { + "affected_many": "{{count}} execuções serão acionadas.", + "affected_one": "1 execução será acionada.", + "affected_other": "{{count}} execuções serão acionadas.", + "affected_zero": "Nenhuma execução será acionada.", + "affectedNone": "Nenhuma execução correspondente aos critérios selecionados.", + "allRuns": "Todas as Execuções", + "backwards": "Executar para trás", + "dateRange": "Intervalo de Data", + "errorStartDateBeforeEndDate": "A Data Inicial deve ser antes da Data Final", + "maxRuns": "Máximo de Execuções Ativas", + "missingAndErroredRuns": "Execuções Faltando e com Erro", + "missingRuns": "Execuções Faltando", + "reprocessBehavior": "Comportamento de Reprocessamento", + "run": "Executar Backfill", + "selectDescription": "Executar este DAG para um intervalo de datas", + "selectLabel": "Backfill", + "title": "Executar Backfill", + "toaster": { + "success": { + "description": "Backfill jobs foram acionados com sucesso.", + "title": "Backfill gerado" + } + }, + "tooltip": "Backfill requer um agendamento", + "unpause": "Despausar {{dag_display_name}} ao acionar", + "validation": { + "datesRequired": "Ambas as datas de início e fim do intervalo devem ser fornecidas.", + "startBeforeEnd": "A Data Inicial do Intervalo deve ser menor ou igual à Data Final do Intervalo." + } + }, + "banner": { + "backfillInProgress": "Backfill em progresso", + "cancel": "Cancelar backfill", + "pause": "Pausar backfill", + "unpause": "Despausar backfill" + }, + "clipboard": { + "copy": "Copiar" + }, + "close": "Fechar", + "configForm": { + "advancedOptions": "Opções Avançadas", + "configJson": "Configuração JSON", + "invalidJson": "Formato JSON inválido: {{errorMessage}}" + }, + "dagWarnings": { + "error_many": "{{count}} Erros", + "error_one": "1 Erro", + "error_other": "{{count}} Erros", + "error_zero": "Nenhum erro", + "errorAndWarning": "1 Erro e {{warningText}}", + "warning_many": "{{count}} Avisos", + "warning_one": "1 Aviso", + "warning_other": "{{count}} Avisos", + "warning_zero": "Nenhum aviso" + }, + "durationChart": { + "duration": "Duração (segundos)", + "lastDagRun_many": "Últimas {{count}} Execuções do DAG", + "lastDagRun_one": "Última Execução do DAG", + "lastDagRun_other": "Últimas {{count}} Execuções do DAG", + "lastDagRun_zero": "Nenhuma execução do DAG", + "lastTaskInstance_many": "Últimas {{count}} Instâncias de Tarefa", + "lastTaskInstance_one": "Última Instância de Tarefa", + "lastTaskInstance_other": "Últimas {{count}} Instâncias de Tarefa", + "lastTaskInstance_zero": "Nenhuma instância de tarefa", + "queuedDuration": "Duração da Fila", + "runAfter": "Executar Depois", + "runDuration": "Duração da Execução" + }, + "fileUpload": { + "files_many": "{{count}} arquivos", + "files_one": "1 arquivo", + "files_other": "{{count}} arquivos", + "files_zero": "Nenhum arquivo" + }, + "flexibleForm": { + "placeholder": "Selecionar Valor", + "placeholderArray": "Digite cada string em uma nova linha", + "placeholderExamples": "Comece a digitar para ver opções", + "placeholderMulti": "Selecione um ou vários valores", + "validationErrorArrayNotArray": "O valor deve ser um array.", + "validationErrorArrayNotNumbers": "Todos os elementos do array devem ser números.", + "validationErrorArrayNotObject": "Todos os elementos do array devem ser objetos.", + "validationErrorRequired": "Este campo é obrigatório" + }, + "graph": { + "directionDown": "Superior para Inferior", + "directionLeft": "Direita para Esquerda", + "directionRight": "Esquerda para Direita", + "directionUp": "Inferior para Superior", + "downloadImage": "Baixar imagem do gráfico", + "downloadImageError": "Falha ao baixar a imagem do gráfico.", + "downloadImageErrorTitle": "Download Falhou", + "otherDagRuns": "+Outras Execuções do DAG", + "taskCount_many": "{{count}} Tarefas", + "taskCount_one": "{{count}} Tarefa", + "taskCount_other": "{{count}} Tarefas", + "taskCount_zero": "Nenhuma tarefa", + "taskGroup": "Grupo de Tarefas" + }, + "limitedList": "+{{count}} mais", + "limitedList.allItems": "Todos os {{count}} itens:", + "limitedList.clickToInteract": "Clique em uma etiqueta para filtrar os Dags", + "limitedList.clickToOpenFull": "Clique em \"+{{count}} mais\" para ver a lista completa", + "limitedList.copyPasteText": "Você pode copiar e colar o texto acima", + "limitedList.showingItems": "Exibindo {{count}} itens", + "logs": { + "file": "Arquivo", + "location": "linha {{line}} em {{name}}" + }, + "reparseDag": "Reparse DAG", + "sortedAscending": "Ordenado em ordem crescente", + "sortedDescending": "Ordenado em ordem decrescente", + "sortedUnsorted": "Não ordenado", + "taskTries": "Tentativas de Tarefa", + "toggleCardView": "Mostrar visualização de cartão", + "toggleTableView": "Mostrar visualização de tabela", + "triggerDag": { + "button": "Acionar", + "loading": "Carregando informações do DAG...", + "loadingFailed": "Falha ao carregar informações do DAG. Por favor, tente novamente.", + "runIdHelp": "Opcional - será gerado se não for fornecido", + "selectDescription": "Acionar uma única execução deste DAG", + "selectLabel": "Execução Única", + "title": "Acionar DAG", + "toaster": { + "success": { + "description": "A execução do DAG foi acionada com sucesso.", + "title": "Execução do DAG acionada" + } + }, + "unpause": "Despausar {{dagDisplayName}} ao acionar" + }, + "trimText": { + "details": "Detalhes", + "empty": "Vazio", + "noContent": "Nenhum conteúdo disponível." + }, + "versionDetails": { + "bundleLink": "Link do Bundle", + "bundleName": "Nome do Bundle", + "bundleVersion": "Versão do Bundle", + "createdAt": "Criado em", + "versionId": "ID da Versão" + }, + "versionSelect": { + "dagVersion": "Versão do DAG", + "versionCode": "v{{versionCode}}" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dag.json new file mode 100644 index 0000000000000..c4a4a58b92a7a --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dag.json @@ -0,0 +1,162 @@ +{ + "allRuns": "Todas as Execuções", + "blockingDeps": { + "dependency": "Dependência", + "reason": "Motivo", + "title": "Dependências Bloqueando Tarefa de Ser Agendada" + }, + "calendar": { + "daily": "Diário", + "hourly": "Por Hora", + "legend": { + "less": "Menos", + "more": "Mais" + }, + "navigation": { + "nextMonth": "Próximo mês", + "nextYear": "Próximo ano", + "previousMonth": "Mês anterior", + "previousYear": "Ano anterior" + }, + "noData": "Nenhum dado disponível", + "noRuns": "Nenhuma execução", + "totalRuns": "Total de Execuções", + "week": "Semana {{weekNumber}}", + "weekdays": { + "friday": "Sex", + "monday": "Seg", + "saturday": "Sáb", + "sunday": "Dom", + "thursday": "Qui", + "tuesday": "Ter", + "wednesday": "Qua" + } + }, + "code": { + "bundleUrl": "URL do Bundle", + "noCode": "Nenhum Código Encontrado", + "parseDuration": "Duração do Processamento:", + "parsedAt": "Processado em:" + }, + "extraLinks": "Links Extra", + "grid": { + "buttons": { + "resetToLatest": "Redefinir para a Última", + "toggleGroup": "Alternar Grupo" + } + }, + "header": { + "buttons": { + "advanced": "Avançado", + "dagDocs": "Documentação do DAG" + } + }, + "logs": { + "allLevels": "Todos os Níveis de Log", + "allSources": "Todas as Fontes", + "critical": "CRÍTICO", + "debug": "DEBUG", + "error": "ERRO", + "fullscreen": { + "button": "Tela cheia", + "tooltip": "Pressione {{hotkey}} para tela cheia" + }, + "info": "INFO", + "noTryNumber": "Nenhum número de tentativa", + "settings": "Configurações", + "viewInExternal": "Ver logs em {{name}} (tentativa {{attempt}})", + "warning": "AVISO" + }, + "navigation": { + "navigation": "Navegação: Shift+{{arrow}}", + "toggleGroup": "Alternar grupo: Espaço" + }, + "overview": { + "buttons": { + "failedRun_many": "Execuções Falhadas", + "failedRun_one": "Execução Falhada", + "failedRun_other": "Execuções Falhadas", + "failedRun_zero": "Nenhuma execução falhada", + "failedTask_many": "Tarefas Falhadas", + "failedTask_one": "Tarefa Falhada", + "failedTask_other": "Tarefas Falhadas", + "failedTask_zero": "Nenhuma tarefa falhada", + "failedTaskInstance_many": "Instâncias de Tarefa Falhadas", + "failedTaskInstance_one": "Instância de Tarefa Falhada", + "failedTaskInstance_other": "Instâncias de Tarefa Falhadas", + "failedTaskInstance_zero": "Nenhuma instância de tarefa falhada" + }, + "charts": { + "assetEvent_many": "Eventos de Asset Criados", + "assetEvent_one": "Evento de Asset Criado", + "assetEvent_other": "Eventos de Asset Criados", + "assetEvent_zero": "Nenhum evento de asset criado" + }, + "failedLogs": { + "hideLogs": "Ocultar Logs", + "showLogs": "Mostrar Logs", + "title": "Logs Recentes de Tarefas Falhadas", + "viewFullLogs": "Ver logs completos" + } + }, + "panel": { + "buttons": { + "options": "Opções", + "showGantt": "Mostrar Gantt", + "showGraphShortcut": "Mostrar Gráfico (Pressione g)", + "showGridShortcut": "Mostrar Grade (Pressione g)" + }, + "dagRuns": { + "label": "Número de Execuções do DAG" + }, + "dependencies": { + "label": "Dependências", + "options": { + "allDagDependencies": "Todas as Dependências do DAG", + "externalConditions": "Condições Externas", + "onlyTasks": "Somente Tarefas" + }, + "placeholder": "Dependências" + }, + "graphDirection": { + "label": "Direção do Gráfico" + } + }, + "paramsFailed": "Falha ao carregar parâmetros", + "parse": { + "toaster": { + "error": { + "description": "Falha ao processar o DAG. Pode haver solicitações de processamento pendentes ainda não processadas.", + "title": "Falha ao Reprocessar o DAG" + }, + "success": { + "description": "O DAG deve ser reprocessado em breve.", + "title": "Solicitação de Reprocessamento Enviada com Sucesso" + } + } + }, + "tabs": { + "assetEvents": "Asset Events", + "auditLog": "Log de Auditoria", + "backfills": "Backfills", + "calendar": "Calendário", + "code": "Código", + "details": "Detalhes", + "logs": "Logs", + "mappedTaskInstances_many": "Instâncias de Tarefa [{{count}}]", + "mappedTaskInstances_one": "Instância de Tarefa [{{count}}]", + "mappedTaskInstances_other": "Instâncias de Tarefa [{{count}}]", + "mappedTaskInstances_zero": "Nenhuma instância de tarefa mapeada", + "overview": "Visão Geral", + "renderedTemplates": "Modelos Renderizados", + "requiredActions": "Ações Necessárias", + "runs": "Execuções", + "taskInstances": "Instâncias de Tarefa", + "tasks": "Tarefas", + "xcom": "XCom" + }, + "taskGroups": { + "collapseAll": "Recolher todos os grupos de tarefas", + "expandAll": "Expandir todos os grupos de tarefas" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dags.json new file mode 100644 index 0000000000000..683cf090a8b15 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dags.json @@ -0,0 +1,97 @@ +{ + "assetSchedule": "{{count}} de {{total}} ativos atualizados", + "dagActions": { + "delete": { + "button": "Excluir DAG", + "warning": "Isso removerá todas as metadados relacionados ao DAG, incluindo Execuções e Tarefas." + } + }, + "favoriteDag": "DAG Favorito", + "filters": { + "allRunTypes": "Todos os Tipos de Execução", + "allStates": "Todos os Estados", + "favorite": { + "all": "Todos", + "favorite": "Favorito", + "unfavorite": "Remover dos Favoritos" + }, + "paused": { + "active": "Ativo", + "all": "Todos", + "paused": "Pausado" + }, + "runIdPatternFilter": "Pesquisar Execuções de DAG", + "triggeringUserNameFilter": "Pesquisar por Usuário que Disparou" + }, + "ownerLink": "Link do Proprietário para {{owner}}", + "runAndTaskActions": { + "affectedTasks": { + "noItemsFound": "Nenhuma tarefa encontrada.", + "title": "Tarefas Afetadas: {{count}}" + }, + "clear": { + "button": "Limpar {{type}}", + "buttonTooltip": "Pressione shift+c para limpar", + "error": "Falha ao limpar {{type}}", + "title": "Limpar {{type}}" + }, + "delete": { + "button": "Excluir {{type}}", + "dialog": { + "resourceName": "{{type}} {{id}}", + "title": "Excluir {{type}}", + "warning": "Isso removerá todas as metadados relacionados ao {{type}}." + }, + "error": "Erro ao excluir {{type}}", + "success": { + "description": "A solicitação de exclusão do {{type}} foi bem-sucedida.", + "title": "{{type}} Excluído com Sucesso" + } + }, + "markAs": { + "button": "Marcar {{type}} como...", + "buttonTooltip": { + "failed": "Pressione shift+f para marcar como falha", + "success": "Pressione shift+s para marcar como sucesso" + }, + "title": "Marcar {{type}} como {{state}}" + }, + "options": { + "downstream": "Downstream", + "existingTasks": "Limpar tarefas existentes", + "future": "Futuro", + "onlyFailed": "Limpar somente tarefas falhadas", + "past": "Passado", + "queueNew": "Enfileirar novas tarefas", + "runOnLatestVersion": "Executar com a versão mais recente do pacote", + "upstream": "Upstream" + } + }, + "search": { + "advanced": "Pesquisa Avançada", + "clear": "Limpar pesquisa", + "dags": "Pesquisar DAGs", + "hotkey": "+K", + "tasks": "Pesquisar Tarefas" + }, + "sort": { + "displayName": { + "asc": "Ordenar por Nome (A-Z)", + "desc": "Ordenar por Nome (Z-A)" + }, + "lastRunStartDate": { + "asc": "Ordenar por Data de Início da Última Execução (Mais Antiga-Mais Recente)", + "desc": "Ordenar por Data de Início da Última Execução (Mais Recente-Mais Antiga)" + }, + "lastRunState": { + "asc": "Ordenar por Estado da Última Execução (A-Z)", + "desc": "Ordenar por Estado da Última Execução (Z-A)" + }, + "nextDagRun": { + "asc": "Ordenar por Próxima Execução do DAG (Mais Antiga-Mais Recente)", + "desc": "Ordenar por Próxima Execução do DAG (Mais Recente-Mais Antiga)" + }, + "placeholder": "Ordenar por" + }, + "unfavoriteDag": "Remover DAG dos Favoritos" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dashboard.json new file mode 100644 index 0000000000000..725875494a1bc --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dashboard.json @@ -0,0 +1,49 @@ +{ + "favorite": { + "favoriteDags_many": "Primeiros {{count}} DAGs favoritos", + "favoriteDags_one": "Primeiro {{count}} DAG favorito", + "favoriteDags_other": "Primeiros {{count}} DAGs favoritos", + "favoriteDags_zero": "Nenhum DAG favorito", + "noDagRuns": "Ainda não há DagRun para este dag.", + "noFavoriteDags": "Nenhum favorito ainda. Clique no ícone de estrela ao lado de um DAG na lista para adicioná-lo aos seus favoritos." + }, + "group": "Grupo", + "health": { + "dagProcessor": "Processador de DAG", + "health": "Saúde", + "healthy": "Saúde", + "lastHeartbeat": "Último Heartbeat", + "metaDatabase": "Base de Dados de Metadados", + "scheduler": "Agendador", + "status": "Estado", + "triggerer": "Disparador", + "unhealthy": "Não saudável" + }, + "history": "Histórico", + "importErrors": { + "dagImportError_many": "Erros de Importação de DAG", + "dagImportError_one": "Erro de Importação de DAG", + "dagImportError_other": "Erros de Importação de DAG", + "dagImportError_zero": "Nenhum erro de importação de DAG", + "searchByFile": "Pesquisar por arquivo", + "timestamp": "Timestamp" + }, + "managePools": "Gerenciar Pools", + "noAssetEvents": "Nenhum Evento de Asset encontrado.", + "poolSlots": "Slots de Pool", + "sortBy": { + "newestFirst": "Mais Recentes Primeiro", + "oldestFirst": "Mais Antigos Primeiro" + }, + "source": "Fonte", + "stats": { + "activeDags": "DAGs Ativos", + "failedDags": "DAGs Falhados", + "queuedDags": "DAGs em Fila", + "requiredActions": "Ações Necessárias", + "runningDags": "DAGs em Execução", + "stats": "Estatísticas" + }, + "uri": "URI", + "welcome": "Bem-vindo" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/hitl.json new file mode 100644 index 0000000000000..c63027cdea479 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/hitl.json @@ -0,0 +1,38 @@ +{ + "filters": { + "response": { + "all": "Todas", + "pending": "Pendente", + "received": "Revisadas" + } + }, + "requiredAction_many": "Ações Necessárias", + "requiredAction_one": "Ação Necessária", + "requiredAction_other": "Ações Necessárias", + "requiredAction_zero": "Nenhuma ação necessária", + "requiredActionCount_many": "Ações Necessárias ({{count}})", + "requiredActionCount_one": "Ação Necessária ({{count}})", + "requiredActionCount_other": "Ações Necessárias ({{count}})", + "requiredActionCount_zero": "Nenhuma ação necessária", + "requiredActionState": "Estado da Ação Necessária", + "response": { + "error": "Falha na resposta", + "optionsDescription": "Escolha suas opções para esta instância de tarefa", + "optionsLabel": "Opções", + "received": "Resposta recebida em ", + "respond": "Responder", + "success": "Resposta de {{taskId}} bem-sucedida", + "title": "Instância de Tarefa Humana - {{taskId}}" + }, + "state": { + "approvalReceived": "Aprovação Recebida", + "approvalRequired": "Aprovação Necessária", + "choiceReceived": "Escolha Recebida", + "choiceRequired": "Escolha Necessária", + "noResponseReceived": "Nenhuma Resposta Recebida", + "rejectionReceived": "Rejeição Recebida", + "responseReceived": "Resposta Recebida", + "responseRequired": "Resposta Necessária" + }, + "subject": "Assunto" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/tasks.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/tasks.json new file mode 100644 index 0000000000000..d15d2dd10ce28 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/tasks.json @@ -0,0 +1,10 @@ +{ + "mapped": "Mapeado", + "notMapped": "Não mapeado", + "retries": "Tentativas", + "searchTasks": "Pesquisar tarefas", + "selectMapped": "Selecionar mapeado", + "selectOperator": "Selecionar operadores", + "selectRetryValues": "Selecionar valores de tentativa", + "selectTriggerRules": "Selecionar regras de gatilho" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/admin.json new file mode 100644 index 0000000000000..cbfa9705abace --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/admin.json @@ -0,0 +1,166 @@ +{ + "columns": { + "description": "คำอธิบาย", + "key": "คีย์", + "name": "ชื่อ", + "value": "ค่า" + }, + "config": { + "columns": { + "section": "ส่วน" + }, + "title": "การตั้งค่า Airflow" + }, + "connections": { + "add": "เพิ่มการเชื่อมต่อ", + "columns": { + "connectionId": "ID การเชื่อมต่อ", + "connectionType": "ประเภทการเชื่อมต่อ", + "host": "โฮสต์", + "port": "พอร์ต" + }, + "connection_one": "การเชื่อมต่อ", + "connection_other": "การเชื่อมต่อทั้งหมด", + "delete": { + "deleteConnection_one": "ลบการเชื่อมต่อ 1 รายการ", + "deleteConnection_other": "ลบการเชื่อมต่อ {{count}} รายการ", + "firstConfirmMessage_one": "คุณกำลังจะลบการเชื่อมต่อดังต่อไปนี้:", + "firstConfirmMessage_other": "คุณกำลังจะลบการเชื่อมต่อดังต่อไปนี้:", + "title": "ลบการเชื่อมต่อ" + }, + "edit": "แก้ไขการเชื่อมต่อ", + "form": { + "connectionIdRequired": "กรุณาระบุ ID การเชื่อมต่อ", + "connectionIdRequirement": "ID การเชื่อมต่อไม่สามารถมีช่องว่างได้", + "connectionTypeRequired": "กรุณาระบุประเภทการเชื่อมต่อ", + "extraFields": "ฟิลด์เพิ่มเติม", + "extraFieldsJson": "ฟิลด์เพิ่มเติมในรูปแบบ JSON", + "helperText": "ไม่พบประเภทการเชื่อมต่อ? โปรดตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง Airflow Providers Package ที่เกี่ยวข้องแล้ว", + "helperTextForRedactedFields": "ฟิลด์ที่ถูกซ่อน ('***') จะไม่ถูกเปลี่ยนแปลงหากไม่ได้แก้ไข", + "selectConnectionType": "เลือกประเภทการเชื่อมต่อ", + "standardFields": "ฟิลด์มาตรฐาน" + }, + "nothingFound": { + "description": "การเชื่อมต่อที่ตั้งค่าผ่าน environment variables หรือ secrets managers จะไม่ปรากฏที่นี่", + "documentationLink": "ดูรายละเอียดเพิ่มเติมได้ในเอกสารของ Airflow", + "learnMore": "ค่าการเชื่อมต่อเหล่านี้จะถูกประมวลผลตอน runtime และจะไม่แสดงในหน้า UI", + "title": "ไม่พบการเชื่อมต่อ!" + }, + "searchPlaceholder": "ค้นหาการเชื่อมต่อ", + "test": "ทดสอบการเชื่อมต่อ", + "testDisabled": "ฟีเจอร์ทดสอบการเชื่อมต่อถูกปิดใช้งาน โปรดติดต่อผู้ดูแลระบบเพื่อเปิดใช้งาน", + "typeMeta": { + "error": "ไม่สามารถดึงข้อมูล Connection Type Meta ได้", + "standardFields": { + "description": "คำอธิบาย", + "host": "โฮสต์", + "login": "เข้าสู่ระบบ", + "password": "รหัสผ่าน", + "port": "พอร์ต", + "url_schema": "สคีมา" + } + } + }, + "deleteActions": { + "button": "ลบ", + "modal": { + "confirmButton": "ใช่, ลบ", + "secondConfirmMessage": "การกระทำนี้เป็นการถาวรและไม่สามารถย้อนกลับได้", + "thirdConfirmMessage": "คุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?" + }, + "selected": "ที่เลือกไว้", + "tooltip": "ลบการเชื่อมต่อที่เลือก" + }, + "formActions": { + "save": "บันทึก" + }, + "plugins": { + "columns": { + "source": "แหล่งที่มา" + }, + "importError_one": "เกิดข้อผิดพลาดในการนำเข้าปลั๊กอิน", + "importError_other": "เกิดข้อผิดพลาดในการนำเข้าปลั๊กอิน", + "searchPlaceholder": "ค้นหาตามไฟล์" + }, + "pools": { + "add": "เพิ่มพูล", + "deferredSlotsIncluded": "รวมช่องที่ถูกเลื่อนแล้ว", + "delete": { + "title": "ลบพูล", + "warning": "การกระทำนี้จะลบเมทาดาต้าทั้งหมดที่เกี่ยวข้องกับพูลและอาจส่งผลกระทบต่องานที่ใช้พูลนี้" + }, + "edit": "แก้ไขพูล", + "form": { + "checkbox": "เลือกเพื่อรวมงานที่ถูกเลื่อนเมื่อคำนวณจำนวนช่องว่างในพูล", + "description": "คำอธิบาย", + "includeDeferred": "รวมงานที่ถูกเลื่อน", + "nameMaxLength": "ชื่อยาวได้ไม่เกิน 256 ตัวอักษร", + "nameRequired": "กรุณาระบุชื่อ", + "slots": "จำนวนช่อง" + }, + "noPoolsFound": "ไม่พบพูล", + "pool_one": "พูล", + "pool_other": "พูลทั้งหมด", + "searchPlaceholder": "ค้นหาพูล", + "sort": { + "asc": "ชื่อ (A-Z)", + "desc": "ชื่อ (Z-A)", + "placeholder": "เรียงตาม" + } + }, + "providers": { + "columns": { + "packageName": "ชื่อแพ็กเกจ", + "version": "เวอร์ชัน" + } + }, + "variables": { + "add": "เพิ่มตัวแปร", + "columns": { + "isEncrypted": "ถูกเข้ารหัสหรือไม่" + }, + "delete": { + "deleteVariable_one": "ลบตัวแปร 1 รายการ", + "deleteVariable_other": "ลบตัวแปร {{count}} รายการ", + "firstConfirmMessage_one": "คุณกำลังจะลบตัวแปรดังต่อไปนี้:", + "firstConfirmMessage_other": "คุณกำลังจะลบตัวแปรดังต่อไปนี้:", + "title": "ลบตัวแปร", + "tooltip": "ลบตัวแปรที่เลือก" + }, + "edit": "แก้ไขตัวแปร", + "export": "ส่งออก", + "exportTooltip": "ส่งออกตัวแปรที่เลือก", + "form": { + "invalidJson": "JSON ไม่ถูกต้อง", + "keyMaxLength": "คีย์ยาวได้ไม่เกิน 250 ตัวอักษร", + "keyRequired": "กรุณาระบุคีย์", + "valueRequired": "กรุณาระบุค่า" + }, + "import": { + "button": "นำเข้า", + "conflictResolution": "เลือกวิธีจัดการเมื่อมีตัวแปรซ้ำ", + "errorParsingJsonFile": "เกิดข้อผิดพลาดในการอ่านไฟล์ JSON: โปรดอัปโหลดไฟล์ JSON ที่มีตัวแปร (เช่น {\"key\": \"value\", ...})", + "options": { + "fail": { + "description": "หยุดการนำเข้าหากพบตัวแปรที่มีอยู่แล้ว", + "title": "ล้มเหลว" + }, + "overwrite": { + "description": "เขียนทับตัวแปรในกรณีที่มีความขัดแย้ง", + "title": "เขียนทับ" + }, + "skip": { + "description": "ข้ามการนำเข้าตัวแปรที่มีอยู่แล้ว", + "title": "ข้าม" + } + }, + "title": "นำเข้าตัวแปร", + "upload": "อัปโหลดไฟล์ JSON", + "uploadPlaceholder": "อัปโหลดไฟล์ JSON ที่มีตัวแปร (เช่น {\"key\": \"value\", ...})" + }, + "noRowsMessage": "ไม่พบตัวแปร", + "searchPlaceholder": "ค้นหาคีย์", + "variable_one": "ตัวแปร", + "variable_other": "ตัวแปรทั้งหมด" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/assets.json new file mode 100644 index 0000000000000..7991401f30344 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/assets.json @@ -0,0 +1,30 @@ +{ + "consumingDags": "Dags ที่ใช้", + "createEvent": { + "button": "สร้างอีเวนต์", + "manual": { + "description": "สร้างอีเวนต์ให้กับ Asset ด้วยตนเอง", + "extra": "ข้อมูลเพิ่มเติมของอีเวนต์ Asset", + "label": "สร้างด้วยตนเอง" + }, + "materialize": { + "description": "ทริกเกอร์ Dag ต้นทางของ Asset นี้", + "descriptionWithDag": "ทริกเกอร์ Dag ต้นทางของ Asset นี้: {{dagName}}", + "label": "สร้างจากต้นทาง (Materialize)", + "unpauseDag": "ยกเลิกการหยุดพัก {{dagName}} เมื่อทริกเกอร์" + }, + "success": { + "manualDescription": "สร้างอีเวนต์ให้กับ Asset ด้วยตนเองสำเร็จแล้ว", + "manualTitle": "สร้างอีเวนต์ให้กับ Asset แล้ว", + "materializeDescription": "Dag ต้นทาง {{dagId}} ถูกทริกเกอร์สำเร็จแล้ว", + "materializeTitle": "กำลังสร้าง Asset" + }, + "title": "สร้างอีเวนต์ให้กับ Asset สำหรับ {{name}}" + }, + "group": "กลุ่ม", + "lastAssetEvent": "อีเวนต์ของ Asset ล่าสุด", + "name": "ชื่อ", + "producingTasks": "งานที่ถูกสร้าง", + "scheduledDags": "Dags ที่ถูกตั้งเวลา", + "searchPlaceholder": "ค้นหา Assets" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/browse.json new file mode 100644 index 0000000000000..cd391bfaaeadd --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/browse.json @@ -0,0 +1,26 @@ +{ + "auditLog": { + "actions": { + "collapseAllExtra": "ย่อข้อมูล JSON เพิ่มเติมทั้งหมด", + "expandAllExtra": "ขยายข้อมูล JSON เพิ่มเติมทั้งหมด" + }, + "columns": { + "event": "อีเวนต์", + "extra": "เพิ่มเติม", + "user": "ผู้ใช้", + "when": "เมื่อไหร่" + }, + "filters": { + "eventType": "ประเภทของอีเวนต์" + }, + "title": "บันทึกการตรวจสอบ (Audit Log)" + }, + "xcom": { + "columns": { + "dag": "Dag", + "key": "คีย์", + "value": "ค่า" + }, + "title": "XCom" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/common.json new file mode 100644 index 0000000000000..543603805bdb4 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/common.json @@ -0,0 +1,318 @@ +{ + "admin": { + "Config": "การตั้งค่า", + "Connections": "การเชื่อมต่อ", + "Plugins": "ปลั๊กอิน", + "Pools": "พูล", + "Providers": "ผู้ให้บริการ", + "Variables": "ตัวแปร" + }, + "allOperators": "ตัวดำเนินการทั้งหมด", + "appearance": { + "appearance": "การแสดงผล", + "darkMode": "โหมดมืด", + "lightMode": "โหมดสว่าง", + "systemMode": "ตามการตั้งค่าของระบบ" + }, + "asset_one": "Asset", + "asset_other": "Assets", + "assetEvent_one": "อีเวนต์ของ Asset", + "assetEvent_other": "อีเวนต์ของ Assets", + "backfill_one": "Backfill", + "backfill_other": "Backfills", + "browse": { + "auditLog": "บันทึกการตรวจสอบ (Audit Log)", + "requiredActions": "การดำเนินการที่จำเป็น", + "xcoms": "XComs" + }, + "collapseDetailsPanel": "ย่อแผงรายละเอียด", + "createdAssetEvent_one": "อีเวนต์ของ Asset ที่สร้างแล้ว", + "createdAssetEvent_other": "อีเวนต์ของ Assets ที่สร้างแล้ว", + "dag_one": "Dag", + "dag_other": "Dags", + "dagDetails": { + "catchup": "Catchup", + "dagRunTimeout": "ระยะหมดเวลาของ DAG Run", + "defaultArgs": "ค่า Arguments เริ่มต้น", + "description": "คำอธิบาย", + "documentation": "เอกสารประกอบ Dag", + "fileLocation": "ตำแหน่งไฟล์", + "hasTaskConcurrencyLimits": "มีการจำกัดจำนวนงานที่ทำพร้อมกัน", + "lastExpired": "หมดอายุครั้งล่าสุด", + "lastParseDuration": "ระยะเวลาการประมวลผลล่าสุด", + "lastParsed": "การประมวลผลครั้งล่าสุด", + "latestDagVersion": "เวอร์ชัน Dag ล่าสุด", + "latestRun": "การทำงานครั้งล่าสุด", + "maxActiveRuns": "จำนวน Dag Run ที่ทำงานพร้อมกันสูงสุด", + "maxActiveTasks": "จำนวนงานที่ทำงานพร้อมกันสูงสุด", + "maxConsecutiveFailedDagRuns": "จำนวน Dag Run ที่ล้มเหลวต่อเนื่องสูงสุด", + "nextRun": "การทำงานครั้งถัดไป", + "owner": "เจ้าของ", + "params": "พารามิเตอร์", + "schedule": "เวลาทำงาน", + "tags": "แท็ก" + }, + "dagId": "Dag ID", + "dagRun": { + "conf": "การตั้งค่า (Conf)", + "dagVersions": "เวอร์ชันของ Dag", + "dataIntervalEnd": "สิ้นสุดช่วงข้อมูล", + "dataIntervalStart": "เริ่มต้นช่วงข้อมูล", + "lastSchedulingDecision": "การตัดสินใจกำหนดเวลาล่าสุด", + "queuedAt": "เข้าคิวเมื่อ", + "runAfter": "ทำงานหลังจาก", + "runType": "ประเภทการทำงาน", + "sourceAssetEvent": "อีเวนต์ของ Asset ต้นทาง", + "triggeredBy": "ทริกเกอร์โดย", + "triggeringUser": "ชื่อผู้ใช้ที่ทริกเกอร์" + }, + "dagRun_one": "Dag Run", + "dagRun_other": "Dag Runs", + "dagRunId": "Dag Run ID", + "dagWarnings": "คำเตือน/ข้อผิดพลาดของ Dag", + "defaultToGraphView": "ค่าเริ่มต้นเป็นมุมมองกราฟ", + "defaultToGridView": "ค่าเริ่มต้นเป็นมุมมองกริด", + "direction": "ทิศทาง", + "docs": { + "documentation": "เอกสารประกอบ", + "githubRepo": "GitHub Repo", + "restApiReference": "เอกสารอ้างอิง REST API" + }, + "duration": "ระยะเวลา", + "endDate": "วันที่สิ้นสุด", + "error": { + "back": "ย้อนกลับ", + "defaultMessage": "เกิดข้อผิดพลาดที่ไม่คาดคิดขึ้น", + "home": "หน้าแรก", + "notFound": "ไม่พบหน้านี้", + "title": "เกิดข้อผิดพลาด" + }, + "expand": { + "collapse": "ย่อ", + "expand": "ขยาย", + "hotkey": "e", + "tooltip": "กด {{hotkey}} เพื่อสลับการขยาย" + }, + "expression": { + "all": "ทั้งหมด", + "and": "และ", + "any": "อย่างใดอย่างหนึ่ง", + "or": "หรือ" + }, + "filter": "ตัวกรอง", + "filters": { + "durationFrom": "ระยะเวลาตั้งแต่", + "durationTo": "ระยะเวลาถึง", + "logicalDateFrom": "วันที่ตามกำหนดทำงานตั้งแต่", + "logicalDateTo": "วันที่ตามกำหนดทำงานถึง", + "runAfterFrom": "ทำงานตั้งแต่", + "runAfterTo": "ทำงานถึง" + }, + "logicalDate": "วันที่ตามกำหนดทำงาน", + "logout": "ออกจากระบบ", + "logoutConfirmation": "คุณกำลังจะออกจากระบบแอปพลิเคชัน", + "mapIndex": "ดัชนีแผนที่", + "modal": { + "cancel": "ยกเลิก", + "confirm": "ยืนยัน", + "delete": { + "button": "ลบ", + "confirmation": "คุณแน่ใจหรือไม่ว่าต้องการลบ {{resourceName}}? การดำเนินการนี้ไม่สามารถย้อนกลับได้" + } + }, + "nav": { + "admin": "ผู้ดูแลระบบ", + "assets": "Assets", + "browse": "เรียกดู", + "dags": "Dags", + "docs": "เอกสาร", + "home": "หน้าแรก", + "legacyFabViews": "มุมมองแบบเก่า", + "plugins": "ปลั๊กอิน", + "security": "ความปลอดภัย" + }, + "noItemsFound": "ไม่พบ {{modelName}}", + "note": { + "add": "เพิ่มโน้ต", + "dagRun": "โน้ตของ Dag Run", + "label": "โน้ต", + "placeholder": "เพิ่มโน้ต...", + "taskInstance": "โน้ตของ Task Instance" + }, + "pools": { + "deferred": "เลื่อนออกไป", + "open": "เปิด", + "pools_one": "พูล", + "pools_other": "พูล", + "queued": "เข้าคิวแล้ว", + "running": "กำลังทำงาน", + "scheduled": "กำหนดเวลาทำงานแล้ว" + }, + "reset": "รีเซ็ต", + "runId": "Run ID", + "runTypes": { + "asset_triggered": "ทริกเกอร์โดย Asset", + "backfill": "Backfill", + "manual": "ทำด้วยตนเอง", + "scheduled": "กำหนดเวลาทำงานแล้ว" + }, + "scroll": { + "direction": { + "bottom": "ล่างสุด", + "top": "บนสุด" + }, + "tooltip": "กด {{hotkey}} เพื่อเลื่อนไปที่ {{direction}}" + }, + "security": { + "actions": "การดำเนินการ", + "permissions": "สิทธิ์", + "resources": "ทรัพยากร", + "roles": "บทบาท", + "users": "ผู้ใช้" + }, + "selectLanguage": "เลือกภาษา", + "showDetailsPanel": "แสดงแผงรายละเอียด", + "source": { + "hide": "ซ่อนแหล่งที่มา", + "hotkey": "s", + "show": "แสดงแหล่งที่มา" + }, + "sourceAssetEvent_one": "อีเวนต์ของ Asset ต้นทาง", + "sourceAssetEvent_other": "อีเวนต์ของ Asset ต้นทาง", + "startDate": "วันที่เริ่มต้น", + "state": "สถานะ", + "states": { + "deferred": "เลื่อนออกไป", + "failed": "ล้มเหลว", + "no_status": "ไม่มีสถานะ", + "none": "ยังไม่กำหนดสถานะ", + "planned": "วางแผนแล้ว", + "queued": "เข้าคิวแล้ว", + "removed": "ถูกลบแล้ว", + "restarting": "กำลังเริ่มใหม่", + "running": "กำลังทำงาน", + "scheduled": "กำหนดเวลาทำงานแล้ว", + "skipped": "ข้าม", + "success": "สำเร็จ", + "up_for_reschedule": "รอการกำหนดเวลาทำงานใหม่", + "up_for_retry": "รอการลองใหม่", + "upstream_failed": "ต้นทางล้มเหลว" + }, + "table": { + "completedAt": "เสร็จสิ้นเมื่อ", + "createdAt": "สร้างเมื่อ", + "filterByTag": "กรอง Dags ตามแท็ก", + "filterColumns": "กรองคอลัมน์ตาราง", + "filterReset_one": "รีเซ็ตตัวกรอง", + "filterReset_other": "รีเซ็ตตัวกรอง", + "from": "จาก", + "maxActiveRuns": "จำนวน Dag Run ที่ทำงานพร้อมกันสูงสุด", + "noTagsFound": "ไม่พบแท็ก", + "tagMode": { + "all": "ทั้งหมด", + "any": "อย่างใดอย่างหนึ่ง" + }, + "tagPlaceholder": "กรองตามแท็ก", + "to": "ถึง" + }, + "task": { + "documentation": "เอกสารประกอบงาน", + "lastInstance": "อินสแตนซ์ล่าสุด", + "operator": "ตัวดำเนินการ", + "triggerRule": "กฎการทริกเกอร์" + }, + "task_one": "งาน", + "task_other": "งาน", + "taskGroup": "กลุ่มงาน", + "taskId": "Task ID", + "taskInstance": { + "dagVersion": "เวอร์ชัน Dag", + "executor": "Executor", + "executorConfig": "การตั้งค่า Executor", + "hostname": "ชื่อโฮสต์", + "maxTries": "จำนวนครั้งสูงสุด", + "pid": "PID", + "pool": "พูล", + "poolSlots": "ช่องในพูล", + "priorityWeight": "น้ำหนักความสำคัญ", + "queue": "คิว", + "queuedWhen": "เข้าคิวเมื่อ", + "scheduledWhen": "กำหนดเวลาทำงานเมื่อ", + "triggerer": { + "assigned": "Triggerer ที่ถูกกำหนด", + "class": "คลาส Trigger", + "createdAt": "เวลาสร้าง Trigger", + "id": "Trigger ID", + "latestHeartbeat": "Heartbeat ล่าสุดของ Triggerer", + "title": "ข้อมูล Triggerer" + }, + "unixname": "ชื่อ Unix" + }, + "taskInstance_one": "Task Instance", + "taskInstance_other": "Task Instances", + "timeRange": { + "last12Hours": "12 ชั่วโมงล่าสุด", + "last24Hours": "24 ชั่วโมงล่าสุด", + "lastHour": "ชั่วโมงล่าสุด", + "pastWeek": "สัปดาห์ที่ผ่านมา" + }, + "timestamp": { + "hide": "ซ่อนเวลา", + "hotkey": "t", + "show": "แสดงเวลา" + }, + "timezone": "เขตเวลา", + "timezoneModal": { + "current-timezone": "เวลาปัจจุบันของ", + "placeholder": "เลือกเขตเวลา", + "title": "เลือกเขตเวลา", + "utc": "UTC (เวลาสากล)" + }, + "toaster": { + "bulkDelete": { + "error": "คำขอลบจำนวนมากของ {{resourceName}} ล้มเหลว", + "success": { + "description": "{{count}} {{resourceName}} ถูกลบเรียบร้อยแล้ว คีย์: {{keys}}", + "title": "ส่งคำขอลบจำนวนมากของ {{resourceName}} แล้ว" + } + }, + "create": { + "error": "คำขอสร้าง {{resourceName}} ล้มเหลว", + "success": { + "description": "{{resourceName}} ถูกสร้างเรียบร้อยแล้ว", + "title": "ส่งคำขอสร้าง {{resourceName}} แล้ว" + } + }, + "delete": { + "error": "คำขอลบ {{resourceName}} ล้มเหลว", + "success": { + "description": "{{resourceName}} ถูกลบเรียบร้อยแล้ว", + "title": "ส่งคำขอลบ {{resourceName}} แล้ว" + } + }, + "import": { + "error": "คำขอนำเข้า {{resourceName}} ล้มเหลว", + "success": { + "description": "{{count}} {{resourceName}} ถูกนำเข้าเรียบร้อยแล้ว", + "title": "ส่งคำขอนำเข้า {{resourceName}} แล้ว" + } + }, + "update": { + "error": "คำขออัปเดต {{resourceName}} ล้มเหลว", + "success": { + "description": "{{resourceName}} ถูกอัปเดตเรียบร้อยแล้ว", + "title": "ส่งคำขออัปเดต {{resourceName}} แล้ว" + } + } + }, + "total": "รวม {{state}}", + "triggered": "ทริกเกอร์แล้ว", + "tryNumber": "จำนวนครั้งที่ลอง", + "user": "ผู้ใช้", + "wrap": { + "hotkey": "w", + "tooltip": "กด {{hotkey}} เพื่อสลับการตัดบรรทัด", + "unwrap": "ไม่ตัดบรรทัด", + "wrap": "ตัดบรรทัด" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/components.json new file mode 100644 index 0000000000000..e696d62493941 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/components.json @@ -0,0 +1,132 @@ +{ + "backfill": { + "affected_one": "จะมีการทริกเกอร์ให้ทำงาน 1 ครั้ง", + "affected_other": "จะมีการทริกเกอร์ให้ทำงาน {{count}} ครั้ง", + "affectedNone": "ไม่มีการทำงานที่ตรงกับเงื่อนไขที่เลือก", + "allRuns": "ทุกการทำงาน", + "backwards": "ทำงานแบบย้อนกลับ", + "dateRange": "ช่วงวันที่", + "errorStartDateBeforeEndDate": "วันที่เริ่มต้นต้องมาก่อนวันที่สิ้นสุด", + "maxRuns": "จำนวนการทำงานที่ทำพร้อมกันสูงสุด", + "missingAndErroredRuns": "การทำงานที่หายไปและเกิดข้อผิดพลาด", + "missingRuns": "การทำงานที่หายไป", + "reprocessBehavior": "พฤติกรรมการประมวลผลซ้ำ", + "run": "สั่ง Backfill", + "selectDescription": "สั่งให้ Dag นี้ทำงานตามช่วงเวลาที่กำหนด", + "selectLabel": "Backfill", + "title": "สั่ง Backfill", + "toaster": { + "success": { + "description": "งาน Backfill ถูกทริกเกอร์สำเร็จแล้ว", + "title": "สร้าง Backfill แล้ว" + } + }, + "tooltip": "Backfill ต้องการการกำหนดเวลาทำงาน (schedule)", + "unpause": "ยกเลิกการหยุดพัก {{dag_display_name}} เมื่อทริกเกอร์", + "validation": { + "datesRequired": "จำเป็นต้องระบุวันเริ่มต้นและวันสิ้นสุดทั้งสองวัน", + "startBeforeEnd": "วันเริ่มต้นต้องน้อยกว่าหรือเท่ากับวันสิ้นสุด" + } + }, + "banner": { + "backfillInProgress": "Backfill กำลังทำงานอยู่", + "cancel": "ยกเลิก Backfill", + "pause": "หยุดพัก Backfill", + "unpause": "ยกเลิกการหยุดพัก Backfill" + }, + "clipboard": { + "copy": "คัดลอก" + }, + "close": "ปิด", + "configForm": { + "advancedOptions": "ตัวเลือกขั้นสูง", + "configJson": "การตั้งค่า JSON", + "invalidJson": "รูปแบบ JSON ไม่ถูกต้อง: {{errorMessage}}" + }, + "dagWarnings": { + "error_one": "1 ข้อผิดพลาด", + "errorAndWarning": "1 ข้อผิดพลาดและ {{warningText}}", + "warning_one": "1 คำเตือน", + "warning_other": "{{count}} คำเตือน" + }, + "durationChart": { + "duration": "ระยะเวลา (วินาที)", + "lastDagRun_one": "Dag Run ล่าสุด", + "lastDagRun_other": "Dag Runs {{count}} ครั้งล่าสุด", + "lastTaskInstance_one": "Task Instance ล่าสุด", + "lastTaskInstance_other": "Task Instances {{count}} ครั้งล่าสุด", + "queuedDuration": "ระยะเวลาที่รอคิว", + "runAfter": "ทำงานหลังจาก", + "runDuration": "ระยะเวลาการทำงาน" + }, + "fileUpload": { + "files_other": "{{count}} ไฟล์" + }, + "flexibleForm": { + "placeholder": "เลือกค่า", + "placeholderArray": "กรอกค่าแยกกันในบรรทัดใหม่", + "placeholderExamples": "เริ่มพิมพ์เพื่อดูตัวเลือก", + "placeholderMulti": "เลือกค่าเดียวหรือหลายค่า", + "validationErrorArrayNotArray": "ค่าต้องเป็น Array", + "validationErrorArrayNotNumbers": "สมาชิกทั้งหมดใน Array ต้องเป็นตัวเลข", + "validationErrorArrayNotObject": "สมาชิกทั้งหมดใน Array ต้องเป็น Object", + "validationErrorRequired": "จำเป็นต้องกรอกช่องนี้" + }, + "graph": { + "directionDown": "จากบนลงล่าง", + "directionLeft": "จากขวาไปซ้าย", + "directionRight": "จากซ้ายไปขวา", + "directionUp": "จากล่างขึ้นบน", + "downloadImage": "ดาวน์โหลดรูปภาพกราฟ", + "downloadImageError": "ไม่สามารถดาวน์โหลดรูปภาพกราฟได้", + "downloadImageErrorTitle": "ดาวน์โหลดล้มเหลว", + "otherDagRuns": "+Dag Runs อื่น ๆ", + "taskCount_one": "{{count}} งาน", + "taskCount_other": "{{count}} งาน", + "taskGroup": "กลุ่มงาน" + }, + "limitedList": "+{{count}} เพิ่มเติม", + "logs": { + "file": "ไฟล์", + "location": "บรรทัด {{line}} ใน {{name}}" + }, + "reparseDag": "ประมวลผล Dag ใหม่", + "sortedAscending": "เรียงจากน้อยไปมาก", + "sortedDescending": "เรียงจากมากไปน้อย", + "sortedUnsorted": "ไม่เรียงลำดับ", + "taskTries": "จำนวนครั้งที่ทำงาน", + "toggleCardView": "แสดงมุมมองแบบการ์ด", + "toggleTableView": "แสดงมุมมองแบบตาราง", + "triggerDag": { + "button": "ทริกเกอร์", + "loading": "กำลังโหลดข้อมูล Dag...", + "loadingFailed": "โหลดข้อมูล Dag ไม่สำเร็จ กรุณาลองใหม่", + "runIdHelp": "ไม่บังคับ - จะถูกสร้างอัตโนมัติหากไม่ระบุ", + "selectDescription": "ทริกเกอร์ Dag นี้สำหรับการทำงานครั้งเดียว", + "selectLabel": "ทำงานครั้งเดียว", + "title": "ทริกเกอร์ Dag", + "toaster": { + "success": { + "description": "Dag Run ถูกทริกเกอร์สำเร็จแล้ว", + "title": "ทริกเกอร์ Dag Run แล้ว" + } + }, + "unpause": "ยกเลิกการหยุดพัก {{dagDisplayName}} เมื่อทริกเกอร์" + }, + "trimText": { + "details": "รายละเอียด", + "empty": "ว่างเปล่า", + "noContent": "ไม่มีเนื้อหา" + }, + "versionDetails": { + "bundleLink": "ลิงก์ Bundle", + "bundleName": "ชื่อ Bundle", + "bundleVersion": "เวอร์ชัน Bundle", + "createdAt": "สร้างเมื่อ", + "versionId": "ID เวอร์ชัน" + }, + "versionSelect": { + "dagVersion": "เวอร์ชัน Dag", + "versionCode": "v{{versionCode}}" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/dag.json new file mode 100644 index 0000000000000..5c59ecd6908a1 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/dag.json @@ -0,0 +1,154 @@ +{ + "allRuns": "การทำงานทั้งหมด", + "blockingDeps": { + "dependency": "การพึ่งพา", + "reason": "เหตุผล", + "title": "การพึ่งพาที่บล็อกงานไม่ให้ถูกกำหนดเวลาทำงาน" + }, + "calendar": { + "daily": "รายวัน", + "hourly": "รายชั่วโมง", + "legend": { + "less": "น้อย", + "mixed": "ผสม", + "more": "มาก" + }, + "navigation": { + "nextMonth": "เดือนถัดไป", + "nextYear": "ปีถัดไป", + "previousMonth": "เดือนก่อนหน้า", + "previousYear": "ปีก่อนหน้า" + }, + "noData": "ไม่มีข้อมูล", + "noFailedRuns": "ไม่มีการทำงานที่ล้มเหลว", + "noRuns": "ไม่มีการทำงาน", + "totalRuns": "การทำงานทั้งหมด", + "week": "สัปดาห์ที่ {{weekNumber}}", + "weekdays": { + "friday": "ศ.", + "monday": "จ.", + "saturday": "ส.", + "sunday": "อา.", + "thursday": "พฤ.", + "tuesday": "อ.", + "wednesday": "พ." + } + }, + "code": { + "bundleUrl": "URL ของ Bundle", + "noCode": "ไม่พบโค้ด", + "parseDuration": "ระยะเวลาการประมวลผล:", + "parsedAt": "ประมวลผลเมื่อ:" + }, + "extraLinks": "ลิงก์เพิ่มเติม", + "grid": { + "buttons": { + "resetToLatest": "รีเซ็ตเป็นล่าสุด", + "toggleGroup": "สลับกลุ่ม" + } + }, + "header": { + "buttons": { + "advanced": "ขั้นสูง", + "dagDocs": "เอกสาร Dag" + } + }, + "logs": { + "allLevels": "ทุกระดับ Log", + "allSources": "ทุกแหล่งที่มา", + "critical": "ร้ายแรง (CRITICAL)", + "debug": "ดีบัก (DEBUG)", + "error": "ข้อผิดพลาด (ERROR)", + "fullscreen": { + "button": "เต็มจอ", + "tooltip": "กด {{hotkey}} เพื่อเข้าสู่โหมดเต็มจอ" + }, + "info": "ข้อมูล (INFO)", + "noTryNumber": "ไม่มีหมายเลขการลอง", + "settings": "การตั้งค่า Log", + "viewInExternal": "ดู log ใน {{name}} (ความพยายามครั้งที่ {{attempt}})", + "warning": "คำเตือน (WARNING)" + }, + "navigation": { + "navigation": "การนำทาง: Shift+{{arrow}}", + "toggleGroup": "สลับกลุ่ม: Space" + }, + "overview": { + "buttons": { + "failedRun_one": "การทำงานที่ล้มเหลว", + "failedRun_other": "การทำงานที่ล้มเหลว", + "failedTask_one": "งานที่ล้มเหลว", + "failedTask_other": "งานที่ล้มเหลว", + "failedTaskInstance_one": "Task Instance ที่ล้มเหลว", + "failedTaskInstance_other": "Task Instances ที่ล้มเหลว" + }, + "charts": { + "assetEvent_one": "การสร้างอีเวนต์ให้กับ Asset", + "assetEvent_other": "การสร้างอีเวนต์ให้กับ Asset" + }, + "failedLogs": { + "hideLogs": "ซ่อน Logs", + "showLogs": "แสดง Logs", + "title": "Logs ของงานที่ล้มเหลวล่าสุด", + "viewFullLogs": "ดู Logs แบบเต็ม" + } + }, + "panel": { + "buttons": { + "options": "ตัวเลือก", + "showGantt": "แสดง Gantt", + "showGraphShortcut": "แสดงกราฟ (กด g)", + "showGridShortcut": "แสดงกริด (กด g)" + }, + "dagRuns": { + "label": "จำนวน Dag Runs" + }, + "dependencies": { + "label": "การพึ่งพา", + "options": { + "allDagDependencies": "การพึ่งพาของ Dag ทั้งหมด", + "externalConditions": "เงื่อนไขภายนอก", + "onlyTasks": "เฉพาะงาน" + }, + "placeholder": "การพึ่งพา" + }, + "graphDirection": { + "label": "ทิศทางของกราฟ" + } + }, + "paramsFailed": "โหลดพารามิเตอร์ไม่สำเร็จ", + "parse": { + "toaster": { + "error": { + "description": "การร้องขอประมวลผล Dag ล้มเหลว อาจมีคำขอการประมวลผลที่รอดำเนินการอยู่", + "title": "การประมวลผล DAG ล้มเหลว" + }, + "success": { + "description": "DAG จะถูกประมวลผลใหม่ในเร็ว ๆ นี้", + "title": "ส่งคำขอประมวลผลใหม่สำเร็จแล้ว" + } + } + }, + "tabs": { + "assetEvents": "อีเวนต์ของ Asset", + "auditLog": "บันทึกการตรวจสอบ", + "backfills": "Backfills", + "calendar": "ปฏิทิน", + "code": "โค้ด", + "details": "รายละเอียด", + "logs": "Logs", + "mappedTaskInstances_one": "Task Instance [{{count}}]", + "mappedTaskInstances_other": "Task Instances [{{count}}]", + "overview": "ภาพรวม", + "renderedTemplates": "เทมเพลตที่เรนเดอร์แล้ว", + "requiredActions": "การดำเนินการที่จำเป็น", + "runs": "การทำงาน", + "taskInstances": "Task Instances", + "tasks": "งาน", + "xcom": "XCom" + }, + "taskGroups": { + "collapseAll": "ย่อกลุ่มงานทั้งหมด", + "expandAll": "ขยายกลุ่มงานทั้งหมด" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/dags.json new file mode 100644 index 0000000000000..9b1ce043e8f34 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/dags.json @@ -0,0 +1,96 @@ +{ + "assetSchedule": "{{count}} จาก {{total}} รายการ Assets อัปเดตแล้ว", + "dagActions": { + "delete": { + "button": "ลบ Dag", + "warning": "การดำเนินการนี้จะลบเมทาดาต้าทั้งหมดที่เกี่ยวข้องกับ Dag รวมถึงการทำงานและรายละเอียดงานด้วย" + } + }, + "favoriteDag": "ชื่นชอบ Dag", + "filters": { + "allRunTypes": "ประเภทการทำงานทั้งหมด", + "allStates": "สถานะทั้งหมด", + "favorite": { + "all": "ทั้งหมด", + "favorite": "รายการโปรด", + "unfavorite": "ไม่ใช่รายการโปรด" + }, + "paused": { + "active": "ใช้งาน", + "all": "ทั้งหมด", + "paused": "หยุดชั่วคราว" + }, + "runIdPatternFilter": "ค้นหา Dag Runs" + }, + "ownerLink": "ลิงก์เจ้าของสำหรับ {{owner}}", + "runAndTaskActions": { + "affectedTasks": { + "noItemsFound": "ไม่พบงาน", + "title": "งานที่ได้รับผลกระทบ: {{count}}" + }, + "clear": { + "button": "ล้าง {{type}}", + "buttonTooltip": "กด shift+c เพื่อล้าง", + "error": "ล้าง {{type}} ไม่สำเร็จ", + "title": "ล้าง {{type}}" + }, + "delete": { + "button": "ลบ {{type}}", + "dialog": { + "resourceName": "{{type}} {{id}}", + "title": "ลบ {{type}}", + "warning": "การดำเนินการนี้จะลบเมทาดาต้าทั้งหมดที่เกี่ยวข้องกับ {{type}}" + }, + "error": "เกิดข้อผิดพลาดในการลบ {{type}}", + "success": { + "description": "คำขอการลบ {{type}} สำเร็จ", + "title": "ลบ {{type}} สำเร็จแล้ว" + } + }, + "markAs": { + "button": "ทำเครื่องหมาย {{type}} เป็น...", + "buttonTooltip": { + "failed": "กด shift+f เพื่อทำเครื่องหมายว่าล้มเหลว", + "success": "กด shift+s เพื่อทำเครื่องหมายว่าสำเร็จ" + }, + "title": "ทำเครื่องหมาย {{type}} เป็น {{state}}" + }, + "options": { + "downstream": "งานถัดไป", + "existingTasks": "ล้างงานที่มีอยู่แล้ว", + "future": "งานในอนาคต", + "onlyFailed": "ล้างเฉพาะงานที่ล้มเหลว", + "past": "งานในอดีต", + "queueNew": "จัดคิวงานใหม่", + "runOnLatestVersion": "ทำงานด้วยเวอร์ชันล่าสุดของชุดรวม (Bundle)", + "upstream": "งานก่อนหน้า" + } + }, + "search": { + "advanced": "การค้นหาขั้นสูง", + "clear": "ล้างการค้นหา", + "dags": "ค้นหา Dags", + "hotkey": "+K", + "tasks": "ค้นหางาน (Tasks)" + }, + "sort": { + "displayName": { + "asc": "จัดเรียงตามชื่อที่แสดง (A-Z)", + "desc": "จัดเรียงตามชื่อที่แสดง (Z-A)" + }, + "lastRunStartDate": { + "asc": "จัดเรียงตามวันที่เริ่มทำงานครั้งล่าสุด (เก่าสุด-ใหม่สุด)", + "desc": "จัดเรียงตามวันที่เริ่มทำงานครั้งล่าสุด (ใหม่สุด-เก่าสุด)" + }, + "lastRunState": { + "asc": "จัดเรียงตามสถานะการทำงานครั้งล่าสุด (A-Z)", + "desc": "จัดเรียงตามสถานะการทำงานครั้งล่าสุด (Z-A)" + }, + "nextDagRun": { + "asc": "จัดเรียงตาม Dag Run ถัดไป (เก่าสุด-ใหม่สุด)", + "desc": "จัดเรียงตาม Dag Run ถัดไป (ใหม่สุด-เก่าสุด)" + }, + "placeholder": "จัดเรียงตาม" + }, + "unfavoriteDag": "เลิกชื่นชอบ Dag" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/dashboard.json new file mode 100644 index 0000000000000..b06545e12c37b --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/dashboard.json @@ -0,0 +1,45 @@ +{ + "favorite": { + "favoriteDags_one": "Dag รายการโปรด {{count}} รายการแรก", + "favoriteDags_other": "Dags รายการโปรด {{count}} รายการแรก", + "noDagRuns": "ยังไม่มี DagRun สำหรับ Dag นี้", + "noFavoriteDags": "ยังไม่มีรายการโปรด คลิกไอคอนรูปดาวด้านข้าง Dag ในรายการเพื่อเพิ่มเป็นรายการโปรดของคุณ" + }, + "group": "กลุ่ม", + "health": { + "dagProcessor": "Dag Processor", + "health": "สถานะสุขภาพ", + "healthy": "ปกติ", + "lastHeartbeat": "สัญญาณล่าสุด", + "metaDatabase": "MetaDatabase", + "scheduler": "Scheduler", + "status": "สถานะ", + "triggerer": "Triggerer", + "unhealthy": "ไม่ปกติ" + }, + "history": "ประวัติ", + "importErrors": { + "dagImportError_one": "เกิดข้อผิดพลาดในการนำเข้า Dag", + "dagImportError_other": "เกิดข้อผิดพลาดในการนำเข้า Dags", + "searchByFile": "ค้นหาตามไฟล์", + "timestamp": "เวลา" + }, + "managePools": "จัดการพูล", + "noAssetEvents": "ไม่พบอีเวนต์ของ Asset", + "poolSlots": "จำนวนช่องในพูล", + "sortBy": { + "newestFirst": "ใหม่สุดก่อน", + "oldestFirst": "เก่าสุดก่อน" + }, + "source": "แหล่งที่มา", + "stats": { + "activeDags": "Dags ที่ทำงานอยู่", + "failedDags": "Dags ที่ล้มเหลว", + "queuedDags": "Dags ที่ถูกจัดคิว", + "requiredActions": "การดำเนินการที่จำเป็น", + "runningDags": "Dags ที่กำลังทำงาน", + "stats": "สถิติ" + }, + "uri": "Uri", + "welcome": "ยินดีต้อนรับ" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/hitl.json new file mode 100644 index 0000000000000..3d8fb5a847ee3 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/hitl.json @@ -0,0 +1,34 @@ +{ + "filters": { + "response": { + "all": "ทั้งหมด", + "pending": "รอดำเนินการ", + "received": "ตรวจสอบแล้ว" + } + }, + "requiredAction_one": "การดำเนินการที่จำเป็น", + "requiredAction_other": "การดำเนินการที่จำเป็น", + "requiredActionCount_one": "การดำเนินการที่จำเป็น ({{count}})", + "requiredActionCount_other": "การดำเนินการที่จำเป็น ({{count}})", + "requiredActionState": "สถานะการดำเนินการที่จำเป็น", + "response": { + "error": "การตอบสนองล้มเหลว", + "optionsDescription": "เลือกตัวเลือกของคุณสำหรับ Task Instance นี้", + "optionsLabel": "ตัวเลือก", + "received": "ได้รับการตอบสนองเมื่อ ", + "respond": "ตอบสนอง", + "success": "การตอบสนองของ {{taskId}} สำเร็จ", + "title": "Human Task Instance - {{taskId}}" + }, + "state": { + "approvalReceived": "ได้รับการอนุมัติแล้ว", + "approvalRequired": "ต้องการการอนุมัติ", + "choiceReceived": "ได้รับตัวเลือกแล้ว", + "choiceRequired": "ต้องการตัวเลือก", + "noResponseReceived": "ไม่ได้รับการตอบสนอง", + "rejectionReceived": "ได้รับการปฏิเสธแล้ว", + "responseReceived": "ได้รับการตอบสนองแล้ว", + "responseRequired": "ต้องการการตอบสนอง" + }, + "subject": "หัวเรื่อง" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/tasks.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/tasks.json new file mode 100644 index 0000000000000..ca5cf8f716bff --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/tasks.json @@ -0,0 +1,10 @@ +{ + "mapped": "ถูกแม็ปแล้ว", + "notMapped": "ยังไม่ได้แม็ป", + "retries": "การลองใหม่", + "searchTasks": "ค้นหางาน", + "selectMapped": "เลือกการแม็ป", + "selectOperator": "เลือกตัวดำเนินการ", + "selectRetryValues": "เลือกค่าการลองใหม่", + "selectTriggerRules": "เลือกกฎการทริกเกอร์" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/admin.json index 6298c9f2b295a..2c8ce1749b71e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/admin.json @@ -72,7 +72,6 @@ "tooltip": "Seçilen bağlantıları sil" }, "formActions": { - "reset": "Sıfırla", "save": "Kaydet" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json index 3b37fa8487990..5d96412a92ed9 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json @@ -39,6 +39,7 @@ "fileLocation": "Dosya Konumu", "hasTaskConcurrencyLimits": "Görev Eş Zamanlılık Limitleri Var", "lastExpired": "Son Süresi Dolan", + "lastParseDuration": "Son Atrıştırma Süresi", "lastParsed": "Son Ayrıştırılan", "latestDagVersion": "En Son Dag Versiyonu", "latestRun": "En Son Çalışma", @@ -98,16 +99,12 @@ "any": "Herhangi", "or": "VEYA" }, + "filter": "Filtre", "filters": { - "dagDisplayNamePlaceholder": "Dag adına göre filtrele", - "keyPlaceholder": "XCom anahtarına göre filtrele", - "logicalDateFromPlaceholder": "Mantıksal tarih başlangıcı", - "logicalDateToPlaceholder": "Mantıksal tarih bitişi", - "mapIndexPlaceholder": "Harita indeksine göre filtrele", - "runAfterFromPlaceholder": "Şu tarihten sonra çalıştır (başlangıç)", - "runAfterToPlaceholder": "Şu tarihten sonra çalıştır (bitiş)", - "runIdPlaceholder": "Çalıştırma kimliğine göre filtrele", - "taskIdPlaceholder": "Görev kimliğine göre filtrele" + "logicalDateFrom": "Mantıksal tarih başlangıcı", + "logicalDateTo": "Mantıksal tarih bitişi", + "runAfterFrom": "Şu tarihten sonra çalıştır (başlangıç)", + "runAfterTo": "Şu tarihten sonra çalıştır (bitiş)" }, "logicalDate": "Mantıksal Tarih", "logout": "Çıkış", @@ -149,6 +146,7 @@ "running": "Çalışıyor", "scheduled": "Planlanmış" }, + "reset": "Sıfırla", "runId": "Çalıştırma Kimliği", "runTypes": { "asset_triggered": "Varlık Tetiklemeli", @@ -163,7 +161,6 @@ }, "tooltip": "{{direction}} kaydırmak için {{hotkey}} tuşuna basın" }, - "seconds": "{{count}}sn", "security": { "actions": "Eylemler", "permissions": "İzinler", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/components.json index c2733b504e221..69d80a7672ba9 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/components.json @@ -6,8 +6,6 @@ "allRuns": "Bütün Dag Çalıştırmaları", "backwards": "Geriye Dönük Çalıştır", "dateRange": "Tarih Aralığı", - "dateRangeFrom": "Başlangıç", - "dateRangeTo": "Bitiş", "errorStartDateBeforeEndDate": "Başlangıç Tarihi, Bitiş Tarihinden önce olmalıdır", "maxRuns": "Maksimum Aktif Çalıştırma", "missingAndErroredRuns": "Eksik ve Hata Almış Dag Çalıştırmaları", @@ -90,6 +88,11 @@ "taskGroup": "Görev Grubu" }, "limitedList": "+{{count}} daha", + "limitedList.allItems": "Tüm {{count}} öğeler:", + "limitedList.clickToInteract": "Bir etikete tıklayarak Dag'leri filtreleyin", + "limitedList.clickToOpenFull": "\"+{{count}} daha\" tıklayarak tam görünümü açın", + "limitedList.copyPasteText": "Yukarıdaki metni kopyalayıp yapıştırabilirsiniz", + "limitedList.showingItems": "{{count}} öğe gösteriliyor", "logs": { "file": "Dosya", "location": "{{name}} içinde satır {{line}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json index 2e538ae3e6e74..4c16236e3b46e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json @@ -35,7 +35,8 @@ "code": { "bundleUrl": "Paket URL'i", "noCode": "Kod Bulunamadı", - "parsedAt": "Ayrıştırılma zamanı:" + "parseDuration": "Ayrıştırılma süresi:", + "parsedAt": "Ayrıştırıldı:" }, "extraLinks": "Ek Bağlantılar", "grid": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/admin.json new file mode 100644 index 0000000000000..c8853ac873caf --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/admin.json @@ -0,0 +1,166 @@ +{ + "columns": { + "description": "描述", + "key": "键", + "name": "名称", + "value": "值" + }, + "config": { + "columns": { + "section": "段落" + }, + "title": "Airflow 配置" + }, + "connections": { + "add": "添加连接", + "columns": { + "connectionId": "连接 ID", + "connectionType": "连接类型", + "host": "主机地址", + "port": "端口" + }, + "connection_one": "连接", + "connection_other": "连接", + "delete": { + "deleteConnection_one": "删除 1 个连接", + "deleteConnection_other": "删除 {{count}} 个连接", + "firstConfirmMessage_one": "您即将删除以下连接:", + "firstConfirmMessage_other": "您即将删除以下连接:", + "title": "删除连接" + }, + "edit": "编辑连接", + "form": { + "connectionIdRequired": "连接 ID 是必填的", + "connectionIdRequirement": "连接 ID 不能只包含空格", + "connectionTypeRequired": "连接类型是必填的", + "extraFields": "额外字段", + "extraFieldsJson": "额外字段 JSON", + "helperText": "找不到连接类型?请确保您已安装对应的 Airflow Providers 套件。", + "helperTextForRedactedFields": "已遮蔽的字段 ('***') 若未修改,将保持不变。", + "selectConnectionType": "选择连接类型", + "standardFields": "标准字段" + }, + "nothingFound": { + "description": "通过环境变量或密钥管理器定义的连接不会列在此处。", + "documentationLink": "在 Airflow 文件中了解更多。", + "learnMore": "这些连接会在执行时解析,不会在 UI 显示。", + "title": "找不到连接" + }, + "searchPlaceholder": "搜索连接", + "test": "测试连接", + "testDisabled": "测试连接功能已停用。请联系管理员以启用。", + "typeMeta": { + "error": "获取连接类型元数据失败", + "standardFields": { + "description": "描述", + "host": "主机地址", + "login": "登录", + "password": "密码", + "port": "端口", + "url_schema": "Schema" + } + } + }, + "deleteActions": { + "button": "删除", + "modal": { + "confirmButton": "确定删除", + "secondConfirmMessage": "此操作无法恢复。", + "thirdConfirmMessage": "您确定要继续吗?" + }, + "selected": "已选择", + "tooltip": "删除所选连接" + }, + "formActions": { + "save": "保存" + }, + "plugins": { + "columns": { + "source": "来源" + }, + "importError_one": "插件导入错误", + "importError_other": "插件导入错误", + "searchPlaceholder": "搜索文件" + }, + "pools": { + "add": "新增资源池", + "deferredSlotsIncluded": "包含延迟任务", + "delete": { + "title": "删除资源池", + "warning": "这将删除所有与此资源池相关的系统数据,可能会影响使用此资源池的任务。" + }, + "edit": "编辑资源池", + "form": { + "checkbox": "计算可用资源池配额时,将包含延迟的任务", + "description": "描述", + "includeDeferred": "包含延迟任务", + "nameMaxLength": "名称最多只能包含 256 个字符", + "nameRequired": "名称是必填的", + "slots": "配额" + }, + "noPoolsFound": "找不到资源池", + "pool_one": "资源池", + "pool_other": "资源池", + "searchPlaceholder": "搜索资源池", + "sort": { + "asc": "名称 (A-Z)", + "desc": "名称 (Z-A)", + "placeholder": "排序方式" + } + }, + "providers": { + "columns": { + "packageName": "插件名称", + "version": "版本" + } + }, + "variables": { + "add": "新增变量", + "columns": { + "isEncrypted": "是否加密" + }, + "delete": { + "deleteVariable_one": "删除 1 个变量", + "deleteVariable_other": "删除 {{count}} 个变量", + "firstConfirmMessage_one": "您即将删除以下变量:", + "firstConfirmMessage_other": "您即将删除以下变量:", + "title": "删除变量", + "tooltip": "删除所选变量" + }, + "edit": "编辑变量", + "export": "导出", + "exportTooltip": "导出所选变量", + "form": { + "invalidJson": "无效的 JSON", + "keyMaxLength": "键最多只能包含 250 个字符", + "keyRequired": "键是必填的", + "valueRequired": "值是必填的" + }, + "import": { + "button": "导入", + "conflictResolution": "选择变量冲突解决方式", + "errorParsingJsonFile": "解析 JSON 文件时发生错误:请上传包含变量的 JSON 文件 (例如:{\"key\": \"value\", ...})。", + "options": { + "fail": { + "description": "如果检测到任何已存在的变量,则导入失败。", + "title": "严格模式" + }, + "overwrite": { + "description": "发生冲突时覆盖变量。", + "title": "覆盖模式" + }, + "skip": { + "description": "忽略导入已存在的变量。", + "title": "非严格模式" + } + }, + "title": "导入变量", + "upload": "上传 JSON 文件", + "uploadPlaceholder": "上传包含变量的 JSON 文件 (例如:{\"key\": \"value\", ...})" + }, + "noRowsMessage": "找不到变量", + "searchPlaceholder": "搜索键", + "variable_one": "变量", + "variable_other": "变量" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/assets.json new file mode 100644 index 0000000000000..059726de65f7a --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/assets.json @@ -0,0 +1,30 @@ +{ + "consumingDags": "消费者 Dags", + "createEvent": { + "button": "创建事件", + "manual": { + "description": "手动创建资源事件", + "extra": "资源事件额外信息", + "label": "手动" + }, + "materialize": { + "description": "触发此资源上游的 Dag", + "descriptionWithDag": "触发此资源上游的 Dag: {{dagName}}", + "label": "物化", + "unpauseDag": "触发时取消暂停 {{dagName}}" + }, + "success": { + "manualDescription": "已成功手动创建资源事件。", + "manualTitle": "已创建资源事件", + "materializeDescription": "已成功触发上游 Dag {{dagId}}。", + "materializeTitle": "正在物化资源" + }, + "title": "为 {{name}} 创建资源事件" + }, + "group": "分组", + "lastAssetEvent": "最后资源事件", + "name": "名称", + "producingTasks": "生产任务", + "scheduledDags": "已调度的 Dags", + "searchPlaceholder": "搜索资源" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/browse.json new file mode 100644 index 0000000000000..8c9a21b4817e5 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/browse.json @@ -0,0 +1,26 @@ +{ + "auditLog": { + "actions": { + "collapseAllExtra": "收起所有额外 JSON", + "expandAllExtra": "展开所有额外 JSON" + }, + "columns": { + "event": "事件", + "extra": "额外信息", + "user": "用户", + "when": "时间" + }, + "filters": { + "eventType": "事件类型" + }, + "title": "审计日志" + }, + "xcom": { + "columns": { + "dag": "Dag", + "key": "键", + "value": "值" + }, + "title": "XCom" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/common.json new file mode 100644 index 0000000000000..eef029cc5aeaf --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/common.json @@ -0,0 +1,316 @@ +{ + "admin": { + "Config": "配置", + "Connections": "连接", + "Plugins": "插件", + "Pools": "资源池", + "Providers": "Providers", + "Variables": "变量" + }, + "allOperators": "全部操作器", + "appearance": { + "appearance": "外观", + "darkMode": "深色模式", + "lightMode": "浅色模式", + "systemMode": "跟随系统设置" + }, + "asset_one": "资源", + "asset_other": "资源", + "assetEvent_one": "资源事件", + "assetEvent_other": "资源事件", + "backfill_one": "回填", + "backfill_other": "回填", + "browse": { + "auditLog": "审计日志", + "requiredActions": "待响应的任务实例", + "xcoms": "XComs" + }, + "collapseDetailsPanel": "收起详细信息", + "createdAssetEvent_one": "已创建资源事件", + "createdAssetEvent_other": "已创建资源事件", + "dag_one": "Dag", + "dag_other": "Dags", + "dagDetails": { + "catchup": "自动回填", + "dagRunTimeout": "Dag 执行超时", + "defaultArgs": "默认参数", + "description": "描述", + "documentation": "Dag 文档", + "fileLocation": "文件位置", + "hasTaskConcurrencyLimits": "有任务并发数限制", + "lastExpired": "最后过期时间", + "lastParseDuration": "最后解析耗时", + "lastParsed": "最后解析时间", + "latestDagVersion": "最新 Dag 版本", + "latestRun": "上次 Dag 执行", + "maxActiveRuns": "活跃执行数上限", + "maxActiveTasks": "活跃任务数上限", + "maxConsecutiveFailedDagRuns": "连续失败执行数上限", + "nextRun": "下次 Dag 执行", + "owner": "拥有者", + "params": "参数", + "schedule": "调度", + "tags": "标签" + }, + "dagId": "Dag ID", + "dagRun": { + "conf": "配置", + "dagVersions": "Dag 版本", + "dataIntervalEnd": "数据区间结束", + "dataIntervalStart": "数据区间起始", + "lastSchedulingDecision": "最后调度决策", + "queuedAt": "开始排队时间", + "runAfter": "最早可执行时间", + "runType": "执行类型", + "sourceAssetEvent": "来源资源事件", + "triggeredBy": "触发者", + "triggeringUser": "触发用户名称" + }, + "dagRun_one": "Dag 执行", + "dagRun_other": "Dag 执行", + "dagRunId": "Dag 执行 ID", + "dagWarnings": "Dag 警告 / 错误", + "defaultToGraphView": "默认使用图形视图", + "defaultToGridView": "默认使用网格视图", + "direction": "书写方向", + "docs": { + "documentation": "文档", + "githubRepo": "GitHub 仓库", + "restApiReference": "REST API 参考" + }, + "duration": "执行时间", + "endDate": "结束日期", + "error": { + "back": "返回", + "defaultMessage": "发生未预期的错误", + "home": "首页", + "notFound": "找不到页面", + "title": "错误" + }, + "expand": { + "collapse": "收起", + "expand": "展开", + "hotkey": "e", + "tooltip": "按下 {{hotkey}} 切换展开" + }, + "expression": { + "all": "全部", + "and": "且", + "any": "任何", + "or": "或" + }, + "filter": "筛选", + "filters": { + "logicalDateFrom": "逻辑日期起始", + "logicalDateTo": "逻辑结束日期", + "runAfterFrom": "执行时间起始", + "runAfterTo": "执行时间结束" + }, + "logicalDate": "逻辑日期", + "logout": "退出登录", + "logoutConfirmation": "确定要退出登录吗?", + "mapIndex": "映射索引", + "modal": { + "cancel": "取消", + "confirm": "确认", + "delete": { + "button": "删除", + "confirmation": "确定要删除 {{resourceName}} 吗?此操作无法还原。" + } + }, + "nav": { + "admin": "管理", + "assets": "资源", + "browse": "浏览", + "dags": "Dags", + "docs": "文档", + "home": "首页", + "legacyFabViews": "旧版视图", + "plugins": "插件", + "security": "安全" + }, + "noItemsFound": "找不到 {{modelName}}", + "note": { + "add": "添加笔记", + "dagRun": "Dag 执行笔记", + "label": "笔记", + "placeholder": "添加笔记...", + "taskInstance": "任务实例笔记" + }, + "pools": { + "deferred": "已延后", + "open": "开放", + "pools_one": "资源池", + "pools_other": "资源池", + "queued": "排队中", + "running": "执行中", + "scheduled": "已调度" + }, + "reset": "重置", + "runId": "执行 ID", + "runTypes": { + "asset_triggered": "资源触发", + "backfill": "回填", + "manual": "手动触发", + "scheduled": "已调度" + }, + "scroll": { + "direction": { + "bottom": "最下方", + "top": "最上方" + }, + "tooltip": "按 {{hotkey}} 滚动到{{direction}}" + }, + "security": { + "actions": "操作", + "permissions": "权限", + "resources": "资源", + "roles": "角色", + "users": "用户" + }, + "selectLanguage": "选择语言", + "showDetailsPanel": "显示详细信息", + "source": { + "hide": "隐藏来源", + "hotkey": "s", + "show": "显示来源" + }, + "sourceAssetEvent_one": "来源资源事件", + "sourceAssetEvent_other": "来源资源事件", + "startDate": "开始日期", + "state": "状态", + "states": { + "deferred": "已延后", + "failed": "失败", + "no_status": "无状态", + "none": "无状态", + "planned": "已计划", + "queued": "排队中", + "removed": "已移除", + "restarting": "重启中", + "running": "执行中", + "scheduled": "已调度", + "skipped": "已跳过", + "success": "成功", + "up_for_reschedule": "等待重新调度", + "up_for_retry": "等待重试", + "upstream_failed": "上游任务失败" + }, + "table": { + "completedAt": "完成时间", + "createdAt": "创建时间", + "filterByTag": "按标签筛选 Dags", + "filterColumns": "筛选表格列", + "filterReset_one": "重置筛选", + "filterReset_other": "重置筛选", + "from": "开始时间", + "maxActiveRuns": "最大活跃执行数", + "noTagsFound": "找不到标签", + "tagMode": { + "all": "全部", + "any": "任何" + }, + "tagPlaceholder": "按标签筛选", + "to": "结束时间" + }, + "task": { + "documentation": "任务文档", + "lastInstance": "最后实例", + "operator": "任务操作器", + "triggerRule": "触发规则" + }, + "task_one": "任务", + "task_other": "任务", + "taskGroup": "任务分组", + "taskId": "任务 ID", + "taskInstance": { + "dagVersion": "Dag 版本", + "executor": "执行器", + "executorConfig": "执行器配置", + "hostname": "主机名称", + "maxTries": "最大尝试次数", + "pid": "PID", + "pool": "资源池", + "poolSlots": "资源池配额", + "priorityWeight": "优先级权重", + "queue": "排队", + "queuedWhen": "开始排队时间", + "scheduledWhen": "开始调度时间", + "triggerer": { + "assigned": "指派的触发器", + "class": "触发器类别", + "createdAt": "触发器创建时间", + "id": "触发器 ID", + "latestHeartbeat": "最新触发器心跳时间", + "title": "触发器信息" + }, + "unixname": "Unix 名称" + }, + "taskInstance_one": "任务实例", + "taskInstance_other": "任务实例", + "timeRange": { + "last12Hours": "最近 12 小时", + "last24Hours": "最近 24 小时", + "lastHour": "最近 1 小时", + "pastWeek": "过去一周" + }, + "timestamp": { + "hide": "隐藏时间戳", + "hotkey": "t", + "show": "显示时间戳" + }, + "timezone": "时区", + "timezoneModal": { + "current-timezone": "当前时区", + "placeholder": "搜索时区", + "title": "选择时区", + "utc": "UTC" + }, + "toaster": { + "bulkDelete": { + "error": "批量删除 {{resourceName}} 请求失败", + "success": { + "description": "已成功删除 {{count}} 个 {{resourceName}}。键:{{keys}}", + "title": "已提交批量删除 {{resourceName}} 请求" + } + }, + "create": { + "error": "创建 {{resourceName}} 请求失败", + "success": { + "description": "{{resourceName}} 已成功创建。", + "title": "已提交创建 {{resourceName}} 请求" + } + }, + "delete": { + "error": "删除 {{resourceName}} 请求失败", + "success": { + "description": "{{resourceName}} 已成功删除。", + "title": "已提交删除 {{resourceName}} 请求" + } + }, + "import": { + "error": "导入 {{resourceName}} 请求失败", + "success": { + "description": "已成功导入 {{count}} 个 {{resourceName}}。", + "title": "已提交导入 {{resourceName}} 请求" + } + }, + "update": { + "error": "更新 {{resourceName}} 请求失败", + "success": { + "description": "{{resourceName}} 已成功更新。", + "title": "已提交更新 {{resourceName}} 请求" + } + } + }, + "total": "总计 {{state}}", + "triggered": "已触发", + "tryNumber": "尝试次数", + "user": "用户", + "wrap": { + "hotkey": "w", + "tooltip": "按 {{hotkey}} 切换换行", + "unwrap": "不换行", + "wrap": "换行" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json new file mode 100644 index 0000000000000..e7255110e8f3b --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json @@ -0,0 +1,137 @@ +{ + "backfill": { + "affected_one": "将会触发 1 次执行。", + "affected_other": "将会触发 {{count}} 次执行。", + "affectedNone": "没有符合条件的执行。", + "allRuns": "所有执行", + "backwards": "反向执行", + "dateRange": "日期范围", + "errorStartDateBeforeEndDate": "开始日期必须早于结束日期。", + "maxRuns": "活跃执行数上限", + "missingAndErroredRuns": "遗漏和错误的执行", + "missingRuns": "遗漏的执行", + "reprocessBehavior": "重新处理行为", + "run": "执行回填", + "selectDescription": "为指定的日期范围补上 Dag 执行", + "selectLabel": "回填", + "title": "执行回填", + "toaster": { + "success": { + "description": "已成功触发回填作业。", + "title": "已触发 Dag 执行" + } + }, + "tooltip": "回填功能需要 Dag 具有调度", + "unpause": "触发时取消暂停 {{dag_display_name}}", + "validation": { + "datesRequired": "必须提供数据区间的开始与结束日期。", + "startBeforeEnd": "数据区间起始日期必须早于或等于结束日期。" + } + }, + "banner": { + "backfillInProgress": "回填正在进行中", + "cancel": "取消回填", + "pause": "暂停回填", + "unpause": "取消暂停回填" + }, + "clipboard": { + "copy": "复制" + }, + "close": "关闭", + "configForm": { + "advancedOptions": "高级选项", + "configJson": "配置 JSON", + "invalidJson": "无效的 JSON 格式: {{errorMessage}}" + }, + "dagWarnings": { + "error_one": "1 个错误", + "errorAndWarning": "1 个错误与 {{warningText}}", + "warning_one": "1 个警告", + "warning_other": "{{count}} 个警告" + }, + "durationChart": { + "duration": "持续时间 (秒)", + "lastDagRun_one": "最近 1 次 Dag 执行", + "lastDagRun_other": "最近 {{count}} 次 Dag 执行", + "lastTaskInstance_one": "最近 1 次任务实例", + "lastTaskInstance_other": "最近 {{count}} 次任务实例", + "queuedDuration": "排队等候时间", + "runAfter": "最早可执行时间", + "runDuration": "执行持续时间" + }, + "fileUpload": { + "files_other": "{{count}} 个文件" + }, + "flexibleForm": { + "placeholder": "请选择一个值", + "placeholderArray": "请逐行输入,每行输入一个字符串", + "placeholderExamples": "开始输入以查看选项", + "placeholderMulti": "可选择单一或多个值", + "validationErrorArrayNotArray": "值必须是数组格式。", + "validationErrorArrayNotNumbers": "数组中的所有元素都必须是数字。", + "validationErrorArrayNotObject": "数组中的所有元素都必须是对象。", + "validationErrorRequired": "此为必填字段" + }, + "graph": { + "directionDown": "由上到下", + "directionLeft": "由右到左", + "directionRight": "由左到右", + "directionUp": "由下到上", + "downloadImage": "下载图表图片", + "downloadImageError": "下载图表图片失败。", + "downloadImageErrorTitle": "下载失败", + "otherDagRuns": "+ 其他 Dag 执行", + "taskCount_one": "1 个任务", + "taskCount_other": "{{count}} 个任务", + "taskGroup": "任务分组" + }, + "limitedList": "+ 其他 {{count}} 项", + "limitedList.allItems": "所有 {{count}} 项:", + "limitedList.clickToInteract": "点击标签以筛选 DAGs", + "limitedList.clickToOpenFull": "点击 \"+{{count}} 更多\" 打开完整视图", + "limitedList.copyPasteText": "你可以复制并粘贴上方文本", + "limitedList.showingItems": "显示 {{count}} 项", + "logs": { + "file": "文件", + "location": "第 {{line}} 行,位于 {{name}}" + }, + "reparseDag": "重新解析 Dag", + "sortedAscending": "递增排序", + "sortedDescending": "递减排序", + "sortedUnsorted": "未排序", + "taskTries": "任务尝试次数", + "toggleCardView": "显示卡片视图", + "toggleTableView": "显示表格视图", + "triggerDag": { + "button": "触发", + "loading": "正在加载 Dag 信息...", + "loadingFailed": "加载 Dag 信息失败,请重试。", + "runIdHelp": "选填 - 若未提供将会自动生成", + "selectDescription": "触发此 Dag 单次执行", + "selectLabel": "单次执行", + "title": "触发 Dag", + "toaster": { + "success": { + "description": "已成功触发 Dag 执行。", + "title": "已触发 Dag 执行" + } + }, + "unpause": "触发时取消暂停 {{dagDisplayName}}" + }, + "trimText": { + "details": "详细信息", + "empty": "空值", + "noContent": "无可用内容。" + }, + "versionDetails": { + "bundleLink": "套件包链接", + "bundleName": "套件包名称", + "bundleVersion": "套件包版本", + "createdAt": "创建时间", + "versionId": "版本 ID" + }, + "versionSelect": { + "dagVersion": "Dag 版本", + "versionCode": "v{{versionCode}}" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json new file mode 100644 index 0000000000000..6f9a498f7a2c2 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json @@ -0,0 +1,152 @@ +{ + "allRuns": "所有执行", + "blockingDeps": { + "dependency": "依赖 ", + "reason": "原因", + "title": "依赖阻碍任务调度" + }, + "calendar": { + "daily": "每日", + "hourly": "每小时", + "legend": { + "less": "更少", + "more": "更多" + }, + "navigation": { + "nextMonth": "下个月", + "nextYear": "下一年", + "previousMonth": "上个月", + "previousYear": "上一年" + }, + "noData": "无数据", + "noRuns": "未执行", + "totalRuns": "总执行次数", + "week": "第 {{weekNumber}} 周", + "weekdays": { + "friday": "周五", + "monday": "周一", + "saturday": "周六", + "sunday": "周日", + "thursday": "周四", + "tuesday": "周二", + "wednesday": "周三" + } + }, + "code": { + "bundleUrl": "套件包链接", + "noCode": "找不到代码", + "parseDuration": "解析耗时:", + "parsedAt": "解析时间:" + }, + "extraLinks": "额外链接", + "grid": { + "buttons": { + "resetToLatest": "重置为最新", + "toggleGroup": "切换分组状态" + } + }, + "header": { + "buttons": { + "advanced": "高级功能", + "dagDocs": "Dag 文档" + } + }, + "logs": { + "allLevels": "所有日志等级", + "allSources": "所有来源", + "critical": "CRITICAL", + "debug": "DEBUG", + "error": "ERROR", + "fullscreen": { + "button": "全屏", + "tooltip": "按下 {{hotkey}} 进入全屏" + }, + "info": "INFO", + "noTryNumber": "没有重试次数", + "settings": "日志设置", + "viewInExternal": "在 {{name}} 中查看日志(重试 {{attempt}})", + "warning": "WARNING" + }, + "navigation": { + "navigation": "导航: {{arrow}}", + "toggleGroup": "展开/收起分组: 空格键" + }, + "overview": { + "buttons": { + "failedRun_one": "失败的执行", + "failedRun_other": "失败的执行", + "failedTask_one": "失败的任务", + "failedTask_other": "失败的任务", + "failedTaskInstance_one": "失败的任务实例", + "failedTaskInstance_other": "失败的任务实例" + }, + "charts": { + "assetEvent_one": "已创建资源事件", + "assetEvent_other": "已创建资源事件" + }, + "failedLogs": { + "hideLogs": "隐藏日志", + "showLogs": "显示日志", + "title": "最近失败任务的日志", + "viewFullLogs": "查看完整日志" + } + }, + "panel": { + "buttons": { + "options": "选项", + "showGantt": "显示甘特图", + "showGraphShortcut": "显示图表(按 g)", + "showGridShortcut": "显示网格(按 g)" + }, + "dagRuns": { + "label": "Dag 执行次数" + }, + "dependencies": { + "label": "依赖项", + "options": { + "allDagDependencies": "所有 Dag 依赖项", + "externalConditions": "外部条件", + "onlyTasks": "仅限任务" + }, + "placeholder": "依赖项" + }, + "graphDirection": { + "label": "图表方向" + } + }, + "paramsFailed": "加载参数失败", + "parse": { + "toaster": { + "error": { + "description": "Dag 解析请求失败。可能还有待处理的解析请求。", + "title": "Dag 重新解析失败" + }, + "success": { + "description": "Dag 即将重新解析。", + "title": "已成功提交重新解析请求" + } + } + }, + "tabs": { + "assetEvents": "资源事件", + "auditLog": "审计日志", + "backfills": "回填", + "calendar": "日历", + "code": "代码", + "details": "详细信息", + "logs": "日志", + "mappedTaskInstances_one": "任务实例 [{{count}}]", + "mappedTaskInstances_other": "任务实例 [{{count}}]", + "overview": "总览", + "renderedTemplates": "渲染后的模板", + "requiredActions": "待响应的任务实例", + "runs": "执行记录", + "taskInstances": "任务实例", + "tasks": "任务", + "xcom": "XCom" + }, + "taskGroups": { + "collapseAll": "收起所有任务分组", + "expandAll": "展开所有任务分组" + } +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dags.json new file mode 100644 index 0000000000000..b8e4f0929d4e0 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dags.json @@ -0,0 +1,97 @@ +{ + "assetSchedule": "{{count}} / {{total}} 个资源事件已更新", + "dagActions": { + "delete": { + "button": "删除 Dag", + "warning": "这将会删除所有与此 Dag 相关的系统数据,包括 Dag 执行与任务。" + } + }, + "favoriteDag": "将 Dag 加入收藏", + "filters": { + "allRunTypes": "全部执行类型", + "allStates": "全部状态", + "favorite": { + "all": "全部", + "favorite": "已加入收藏", + "unfavorite": "未加入收藏" + }, + "paused": { + "active": "已启用", + "all": "全部", + "paused": "暂停" + }, + "runIdPatternFilter": "搜索 Dag 执行", + "triggeringUserNameFilter": "搜索触发用户名称" + }, + "ownerLink": "拥有者 {{owner}} 的地址", + "runAndTaskActions": { + "affectedTasks": { + "noItemsFound": "找不到任务。", + "title": "受影响的任务: {{count}}" + }, + "clear": { + "button": "清除 {{type}}", + "buttonTooltip": "按下 shift+c 清除", + "error": "清除 {{type}} 时发生错误", + "title": "清除 {{type}}" + }, + "delete": { + "button": "删除 {{type}}", + "dialog": { + "resourceName": "{{type}} {{id}}", + "title": "删除 {{type}}", + "warning": "这将会删除所有与此 {{type}} 相关的系统数据。" + }, + "error": "删除 {{type}} 时发生错误", + "success": { + "description": "{{type}} 删除请求成功。", + "title": "{{type}} 删除成功" + } + }, + "markAs": { + "button": "标记 {{type}} 为...", + "buttonTooltip": { + "failed": "按下 shift+f 标记为失败", + "success": "按下 shift+s 标记为成功" + }, + "title": "标记为 {{type}} 为 {{state}}" + }, + "options": { + "downstream": "下游", + "existingTasks": "清除现有任务", + "future": "未来", + "onlyFailed": "只清除失败任务", + "past": "过去", + "queueNew": "加入新任务到队列", + "runOnLatestVersion": "执行最新套件包版本", + "upstream": "上游" + } + }, + "search": { + "advanced": "高级搜索", + "clear": "清除搜索", + "dags": "搜索 Dags", + "hotkey": "+K", + "tasks": "搜索任务" + }, + "sort": { + "displayName": { + "asc": "按显示名称排序 (A-Z)", + "desc": "按显示名称排序 (Z-A)" + }, + "lastRunStartDate": { + "asc": "按上次开始执行日期排序 (从新到旧)", + "desc": "按上次开始执行日期排序 (从新到旧)" + }, + "lastRunState": { + "asc": "按上次执行状态排序 (A-Z)", + "desc": "按上次执行状态排序 (Z-A)" + }, + "nextDagRun": { + "asc": "按下次执行时间排序 (由近而远)", + "desc": "按下次执行时间排序 (由远而近)" + }, + "placeholder": "排序方式" + }, + "unfavoriteDag": "将 Dag 移出收藏" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dashboard.json new file mode 100644 index 0000000000000..89022de3eb740 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dashboard.json @@ -0,0 +1,45 @@ +{ + "favorite": { + "favoriteDags_one": "第 {{ count }} 个收藏的 Dag", + "favoriteDags_other": "前 {{ count }} 个收藏的 Dag", + "noDagRuns": "此 Dag 尚未被触发过。", + "noFavoriteDags": "尚无收藏的 Dag。请点击 Dag 列表旁的星号图示,将 Dag 加入收藏。" + }, + "group": "分组", + "health": { + "dagProcessor": "Dag 处理器", + "health": "健康状态", + "healthy": "健康", + "lastHeartbeat": "最后心跳", + "metaDatabase": "系统数据库", + "scheduler": "调度器", + "status": "状态", + "triggerer": "触发器", + "unhealthy": "健康状态异常" + }, + "history": "历史记录", + "importErrors": { + "dagImportError_one": "Dag 导入错误", + "dagImportError_other": "Dag 导入错误", + "searchByFile": "依文件搜索", + "timestamp": "时间戳" + }, + "managePools": "管理资源池", + "noAssetEvents": "未找到资源事件", + "poolSlots": "资源池配额", + "sortBy": { + "newestFirst": "由新到旧", + "oldestFirst": "由旧到新" + }, + "source": "来源", + "stats": { + "activeDags": "已启用的 Dags", + "failedDags": "失败的 Dags", + "queuedDags": "排队的 Dags", + "requiredActions": "待操作的任务实例", + "runningDags": "执行中的 Dags", + "stats": "统计" + }, + "uri": "Uri", + "welcome": "欢迎" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/hitl.json new file mode 100644 index 0000000000000..0c4cc910c60a4 --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/hitl.json @@ -0,0 +1,34 @@ +{ + "filters": { + "response": { + "all": "全部", + "pending": "待响应", + "received": "已响应" + } + }, + "requiredAction_one": "待操作的任务实例", + "requiredAction_other": "待操作的任务实例", + "requiredActionCount_one": "待操作的任务实例 ({{count}})", + "requiredActionCount_other": "待操作的任务实例 ({{count}})", + "requiredActionState": "待操作的任务实例状态", + "response": { + "error": "响应失败", + "optionsDescription": "请为此任务实例选择一个选项", + "optionsLabel": "选项", + "received": "收到响应的时间:", + "respond": "发送响应", + "success": "任务 {{taskId}} 响应成功", + "title": "人类参与流程任务实例 - {{taskId}}" + }, + "state": { + "approvalReceived": "已批准", + "approvalRequired": "需要批准", + "choiceReceived": "已选择", + "choiceRequired": "需要选择", + "noResponseReceived": "未收到响应", + "rejectionReceived": "已拒绝", + "responseReceived": "已响应", + "responseRequired": "需要响应" + }, + "subject": "标题" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/tasks.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/tasks.json new file mode 100644 index 0000000000000..2ba125e591a4d --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/tasks.json @@ -0,0 +1,10 @@ +{ + "mapped": "已映射", + "notMapped": "未映射", + "retries": "重试", + "searchTasks": "搜索任务", + "selectMapped": "选择已映射", + "selectOperator": "选择操作器", + "selectRetryValues": "选择重试值", + "selectTriggerRules": "选择触发规则" +} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/admin.json index fa2e576915ad1..9102c578a6720 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/admin.json @@ -72,7 +72,6 @@ "tooltip": "刪除所選連線" }, "formActions": { - "reset": "重置", "save": "儲存" }, "plugins": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json index 8f86cac6900e5..3a69da77f9743 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json @@ -99,17 +99,12 @@ "any": "任何", "or": "或" }, + "filter": "篩選", "filters": { - "dagDisplayNamePlaceholder": "依 Dag 名稱篩選", - "keyPlaceholder": "依 XCom 鍵篩選", - "logicalDateFromPlaceholder": "邏輯日期起始", - "logicalDateToPlaceholder": "邏輯日期結束", - "mapIndexPlaceholder": "依映射索引篩選", - "runAfterFromPlaceholder": "執行時間起始", - "runAfterToPlaceholder": "執行時間結束", - "runIdPlaceholder": "依執行 ID 篩選", - "taskIdPlaceholder": "依任務 ID 篩選", - "triggeringUserPlaceholder": "依觸發使用者篩選" + "logicalDateFrom": "從邏輯日期", + "logicalDateTo": "到邏輯日期", + "runAfterFrom": "從最早可執行時間", + "runAfterTo": "到最早可執行時間" }, "logicalDate": "邏輯日期", "logout": "登出", @@ -151,6 +146,7 @@ "running": "執行中", "scheduled": "已排程" }, + "reset": "重置", "runId": "執行 ID", "runTypes": { "asset_triggered": "資源觸發", @@ -165,7 +161,6 @@ }, "tooltip": "按 {{hotkey}} 捲動到{{direction}}" }, - "seconds": "{{count}} 秒", "security": { "actions": "操作", "permissions": "權限", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/components.json index 77075ae59494d..c655e241acda4 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/components.json @@ -2,12 +2,10 @@ "backfill": { "affected_one": "將會觸發 1 次執行。", "affected_other": "將會觸發 {{count}} 次執行。", - "affectedNone": "沒有符合條件的執行。", + "affectedNone": "無符合條件的執行。", "allRuns": "所有執行", "backwards": "反向執行", "dateRange": "日期範圍", - "dateRangeFrom": "從", - "dateRangeTo": "到", "errorStartDateBeforeEndDate": "開始日期必須早於結束日期。", "maxRuns": "活躍執行數上限", "missingAndErroredRuns": "遺漏和錯誤的執行", @@ -88,6 +86,11 @@ "taskGroup": "任務群組" }, "limitedList": "+ 其他 {{count}} 項", + "limitedList.allItems": "所有 {{count}} 個項目:", + "limitedList.clickToInteract": "點擊標籤以篩選 Dags", + "limitedList.clickToOpenFull": "點擊 \"+{{count}} 更多\" 以開啟完整檢視", + "limitedList.copyPasteText": "你可以複製並貼上上方文字", + "limitedList.showingItems": "顯示 {{count}} 個項目", "logs": { "file": "檔案", "location": "第 {{line}} 行,位於 {{name}}" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json index f1e3c8630982b..5f4925c2d8fe9 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json @@ -10,6 +10,7 @@ "hourly": "每小時", "legend": { "less": "較少", + "mixed": "混合", "more": "較多" }, "navigation": { @@ -19,7 +20,8 @@ "previousYear": "上一年" }, "noData": "沒有可用的資料", - "noRuns": "沒有執行", + "noFailedRuns": "無失敗的執行", + "noRuns": "無執行", "totalRuns": "總執行數", "week": "第 {{weekNumber}} 週", "weekdays": { @@ -62,7 +64,7 @@ "tooltip": "按下 {{hotkey}} 進入全螢幕" }, "info": "INFO", - "noTryNumber": "沒有嘗試次數", + "noTryNumber": "無嘗試次數", "settings": "日誌設定", "viewInExternal": "在 {{name}} 中檢視日誌(嘗試 {{attempt}})", "warning": "WARNING" diff --git a/airflow-core/src/airflow/ui/src/components/AnsiRenderer.tsx b/airflow-core/src/airflow/ui/src/components/AnsiRenderer.tsx new file mode 100644 index 0000000000000..aea00ca4afa1b --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/AnsiRenderer.tsx @@ -0,0 +1,235 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { chakra } from "@chakra-ui/react"; +import Anser, { type AnserJsonEntry } from "anser"; +import * as React from "react"; + +const fixBackspace = (inputText: string): string => { + let tmp = inputText; + + do { + const previous = tmp; + + // eslint-disable-next-line no-control-regex + tmp = tmp.replaceAll(/[^\n]\u0008/gmu, ""); + if (tmp.length >= previous.length) { + break; + } + } while (tmp.length > 0); + + return tmp; +}; + +const ansiToJSON = (input: string, useClasses: boolean = false): Array => { + const processedInput = fixBackspace(input.replaceAll("\r", "")); + + return Anser.ansiToJson(processedInput, { + json: true, + remove_empty: true, + use_classes: useClasses, + }); +}; + +const createClass = (bundle: AnserJsonEntry): string | undefined => { + let classNames = ""; + + if (bundle.bg) { + classNames += `${bundle.bg}-bg `; + } + if (bundle.fg) { + classNames += `${bundle.fg}-fg `; + } + if (bundle.decoration) { + classNames += `ansi-${bundle.decoration} `; + } + + if (classNames === "") { + return undefined; + } + + return classNames.slice(0, classNames.length - 1); +}; + +// Map RGB values to Chakra UI semantic tokens +// These are the standard ANSI color RGB values that anser library outputs +const rgbToChakraColorMap: Record = { + "0, 0, 0": "gray.900", // Black (30m) + "0, 0, 187": "blue.fg", // Blue (34m) + "0, 187, 0": "green.fg", // Green (32m) + "0, 187, 187": "cyan.fg", // Cyan (36m) + "0, 255, 0": "green.400", // Bright Green (92m) + "85, 85, 85": "black", // Bright Black/Gray (90m) + "85, 85, 255": "blue.400", // Bright Blue (94m) + "85, 255, 255": "cyan.400", // Bright Cyan (96m) + "187, 0, 0": "red.fg", // Red (31m) + "187, 0, 187": "purple.fg", // Magenta (35m) + "187, 187, 0": "yellow.fg", // Yellow (33m) + "187, 187, 187": "gray.100", // White (37m) + "255, 85, 85": "red.400", // Bright Red (91m) + "255, 85, 255": "purple.400", // Bright Magenta (95m) + "255, 255, 85": "yellow.400", // Bright Yellow (93m) + "255, 255, 255": "white", // Bright White (97m) +}; + +const createChakraProps = (bundle: AnserJsonEntry) => { + const props: Record = {}; + + // Handle background colors + if (bundle.bg) { + const bgColor = rgbToChakraColorMap[bundle.bg]; + + props.bg = bgColor ?? `rgb(${bundle.bg})`; + } + + // Handle foreground colors + if (bundle.fg) { + const fgColor = rgbToChakraColorMap[bundle.fg]; + + props.color = fgColor ?? `rgb(${bundle.fg})`; + } + + // Handle text decorations + switch (bundle.decoration) { + case "blink": + props.textDecoration = "blink"; + break; + case "bold": + props.fontWeight = "bold"; + break; + case "dim": + props.opacity = "0.5"; + break; + case "hidden": + props.visibility = "hidden"; + break; + case "italic": + props.fontStyle = "italic"; + break; + case "reverse": + // Could implement reverse video if needed + break; + case "strikethrough": + props.textDecoration = "line-through"; + break; + case "underline": + props.textDecoration = "underline"; + break; + // eslint-disable-next-line unicorn/no-useless-switch-case + case null: + default: + break; + } + + return props; +}; + +const convertBundleIntoReact = (options: { + bundle: AnserJsonEntry; + key: number; + linkify: boolean; + useClasses: boolean; +}): JSX.Element => { + const { bundle, key, linkify, useClasses } = options; + const style = useClasses ? undefined : createChakraProps(bundle); + const className = useClasses ? createClass(bundle) : undefined; + + if (!linkify) { + if (useClasses) { + return ( + + {bundle.content} + + ); + } + + return ( + + {bundle.content} + + ); + } + + const content: Array = []; + const linkRegex = + /(?\s|^)(?https?:\/\/(?:www\.|(?!www))[^\s.]+\.\S{2,}|www\.\S+\.\S{2,})/gu; + + let index = 0; + let match: RegExpExecArray | null; + + while ((match = linkRegex.exec(bundle.content)) !== null) { + const { groups } = match; + const pre = groups?.whitespace ?? ""; + const url = groups?.url ?? ""; + const startIndex = match.index + pre.length; + + if (startIndex > index) { + content.push(bundle.content.slice(index, startIndex)); + } + + const href = url.startsWith("www.") ? `http://${url}` : url; + + content.push( + + {url} + , + ); + + index = linkRegex.lastIndex; + } + + if (index < bundle.content.length) { + content.push(bundle.content.slice(index)); + } + + if (useClasses) { + return ( + + {content} + + ); + } + + return ( + + {content} + + ); +}; + +type AnsiRendererProps = { + readonly children?: string; + readonly className?: string; + readonly linkify?: boolean; + readonly useClasses?: boolean; +}; + +export const AnsiRenderer: React.FC = ({ + children = "", + className, + linkify = false, + useClasses = false, +}) => ( + + {ansiToJSON(children, useClasses).map((bundle, index) => + convertBundleIntoReact({ bundle, key: index, linkify, useClasses }), + )} + +); + +export default AnsiRenderer; diff --git a/airflow-core/src/airflow/ui/src/components/AssetExpression/AssetNode.tsx b/airflow-core/src/airflow/ui/src/components/AssetExpression/AssetNode.tsx index 518517da17ca6..6289309ec59f4 100644 --- a/airflow-core/src/airflow/ui/src/components/AssetExpression/AssetNode.tsx +++ b/airflow-core/src/airflow/ui/src/components/AssetExpression/AssetNode.tsx @@ -34,7 +34,7 @@ export const AssetNode = ({ => ({ card: ({ row }) => , @@ -43,6 +44,7 @@ type AssetEventProps = { readonly isLoading?: boolean; readonly setOrderBy?: (order: string) => void; readonly setTableUrlState?: (state: TableState) => void; + readonly showFilters?: boolean; readonly tableUrlState?: TableState; readonly titleKey?: string; }; @@ -53,6 +55,7 @@ export const AssetEvents = ({ isLoading, setOrderBy, setTableUrlState, + showFilters = false, tableUrlState, titleKey, ...rest @@ -66,10 +69,10 @@ export const AssetEvents = ({ }); return ( - + - + {data?.total_entries ?? " "} @@ -101,6 +104,7 @@ export const AssetEvents = ({ )} + {showFilters ? : null} = [ + SearchParamsKeys.START_DATE, + SearchParamsKeys.END_DATE, + SearchParamsKeys.DAG_ID, + SearchParamsKeys.TASK_ID, +]; + +export const AssetEventsFilter = () => { + const { filterConfigs, handleFiltersChange, searchParams } = useFiltersHandler(FILTER_KEYS); + + const initialValues = useMemo(() => { + const values: Record = {}; + + FILTER_KEYS.forEach((key) => { + const value = searchParams.get(key); + + if (value !== null && value.trim() !== "") { + values[key] = value; + } + }); + + return values; + }, [searchParams]); + + return ( + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/components/Banner/BackfillBanner.tsx b/airflow-core/src/airflow/ui/src/components/Banner/BackfillBanner.tsx index 3b05ac63a0ddd..522a541fc40ff 100644 --- a/airflow-core/src/airflow/ui/src/components/Banner/BackfillBanner.tsx +++ b/airflow-core/src/airflow/ui/src/components/Banner/BackfillBanner.tsx @@ -29,6 +29,8 @@ import { useBackfillServicePauseBackfill, useBackfillServiceUnpauseBackfill, } from "openapi/queries"; +import type { BackfillResponse } from "openapi/requests/types.gen"; +import { useAutoRefresh } from "src/utils"; import Time from "../Time"; import { Button, ProgressBar } from "../ui"; @@ -38,9 +40,9 @@ type Props = { }; const buttonProps = { - _hover: { bg: "blue.contrast", color: "blue.muted" }, - borderColor: "blue.contrast", - color: "blue.contrast", + _hover: { bg: "info.contrast", color: "info.muted" }, + borderColor: "info.contrast", + color: "info.contrast", rounded: "full", size: "xs", variant: "outline", @@ -48,10 +50,21 @@ const buttonProps = { const BackfillBanner = ({ dagId }: Props) => { const { t: translate } = useTranslation("components"); - const { data, isLoading } = useBackfillServiceListBackfillsUi({ - dagId, - }); - const [backfill] = data?.backfills.filter((bf) => bf.completed_at === null) ?? []; + const refetchInterval = useAutoRefresh({ dagId }); + + const { data, isLoading } = useBackfillServiceListBackfillsUi( + { + dagId, + }, + undefined, + { + refetchInterval: (query) => + query.state.data?.backfills.some((bf: BackfillResponse) => bf.completed_at === null && !bf.is_paused) + ? refetchInterval + : false, + }, + ); + const [backfill] = data?.backfills.filter((bf: BackfillResponse) => bf.completed_at === null) ?? []; const queryClient = useQueryClient(); const onSuccess = async () => { @@ -64,7 +77,6 @@ const BackfillBanner = ({ dagId }: Props) => { const { isPending: isUnPausePending, mutate: unpauseMutate } = useBackfillServiceUnpauseBackfill({ onSuccess, }); - const { isPending: isStopPending, mutate: stopPending } = useBackfillServiceCancelBackfill({ onSuccess }); const togglePause = () => { @@ -90,7 +102,7 @@ const BackfillBanner = ({ dagId }: Props) => { } return ( - + {translate("banner.backfillInProgress")}: diff --git a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx index 3b3c9fe5f0eb3..f7005a290fba8 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx +++ b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx @@ -129,7 +129,7 @@ const ClearRunDialog = ({ dagRun, onClose, open }: Props) => { ) : undefined} - diff --git a/airflow-core/src/airflow/ui/src/components/DisplayMarkdownButton.tsx b/airflow-core/src/airflow/ui/src/components/DisplayMarkdownButton.tsx index 667366c725ff8..3eab57b658141 100644 --- a/airflow-core/src/airflow/ui/src/components/DisplayMarkdownButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/DisplayMarkdownButton.tsx @@ -20,9 +20,12 @@ import { Box, Heading, VStack } from "@chakra-ui/react"; import { type ReactElement, useState } from "react"; import { Button, Dialog } from "src/components/ui"; +import { ResizableWrapper } from "src/components/ui/ResizableWrapper"; import ReactMarkdown from "./ReactMarkdown"; +const STORAGE_KEY = "airflow-markdown-dialog-size"; + const DisplayMarkdownButton = ({ header, icon, @@ -48,14 +51,16 @@ const DisplayMarkdownButton = ({ open={isDocsOpen} size="md" > - - - {header} - - - - {mdContent} - + + + + {header} + + + + {mdContent} + + diff --git a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx index b3a0b6ae1a4d0..c0fd7cf796b97 100644 --- a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx +++ b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { Box, Heading } from "@chakra-ui/react"; +import { Box, Heading, useToken } from "@chakra-ui/react"; import { Chart as ChartJS, CategoryScale, @@ -35,7 +35,8 @@ import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import type { TaskInstanceResponse, GridRunsResponse } from "openapi/requests/types.gen"; -import { system } from "src/theme"; +import { getComputedCSSVariableValue } from "src/theme"; +import { DEFAULT_DATETIME_FORMAT } from "src/utils/datetimeUtils"; ChartJS.register( CategoryScale, @@ -67,13 +68,30 @@ export const DurationChart = ({ }) => { const { t: translate } = useTranslation(["components", "common"]); const navigate = useNavigate(); + const [queuedColorToken] = useToken("colors", ["queued.solid"]); + + // Get states and create color tokens for them + const states = entries?.map((entry) => entry.state).filter(Boolean) ?? []; + const stateColorTokens = useToken( + "colors", + states.map((state) => `${state}.solid`), + ); if (!entries) { return undefined; } + // Create a mapping of state to color for easy lookup + const stateColorMap: Record = {}; + + states.forEach((state, index) => { + if (state) { + stateColorMap[state] = getComputedCSSVariableValue(stateColorTokens[index] ?? "oklch(0.5 0 0)"); + } + }); + const runAnnotation = { - borderColor: "green", + borderColor: "grey", borderWidth: 1, label: { content: (ctx: PartialEventContext) => average(ctx, 1).toFixed(2), @@ -107,7 +125,7 @@ export const DurationChart = ({ data={{ datasets: [ { - backgroundColor: system.tokens.categoryMap.get("colors")?.get("queued.600")?.value as string, + backgroundColor: getComputedCSSVariableValue(queuedColorToken ?? "oklch(0.5 0 0)"), data: entries.map((entry: RunResponse) => { switch (kind) { case "Dag Run": { @@ -135,7 +153,7 @@ export const DurationChart = ({ { backgroundColor: entries.map( (entry: RunResponse) => - system.tokens.categoryMap.get("colors")?.get(`${entry.state}.600`)?.value as string, + (entry.state ? stateColorMap[entry.state] : undefined) ?? "oklch(0.5 0 0)", ), data: entries.map((entry: RunResponse) => entry.start_date === null ? 0 : Number(getDuration(entry.start_date, entry.end_date)), @@ -143,7 +161,7 @@ export const DurationChart = ({ label: translate("durationChart.runDuration"), }, ], - labels: entries.map((entry: RunResponse) => dayjs(entry.run_after).format("YYYY-MM-DD, hh:mm:ss")), + labels: entries.map((entry: RunResponse) => dayjs(entry.run_after).format(DEFAULT_DATETIME_FORMAT)), }} datasetIdKey="id" options={{ diff --git a/airflow-core/src/airflow/ui/src/components/EditableMarkdownArea.tsx b/airflow-core/src/airflow/ui/src/components/EditableMarkdownArea.tsx index a77bfcd617e93..1b8c3c7d64910 100644 --- a/airflow-core/src/airflow/ui/src/components/EditableMarkdownArea.tsx +++ b/airflow-core/src/airflow/ui/src/components/EditableMarkdownArea.tsx @@ -18,6 +18,7 @@ */ import { Box, VStack, Editable, Text } from "@chakra-ui/react"; import type { ChangeEvent } from "react"; +import { useState, useRef } from "react"; import ReactMarkdown from "./ReactMarkdown"; @@ -31,36 +32,53 @@ const EditableMarkdownArea = ({ readonly onBlur?: () => void; readonly placeholder?: string | null; readonly setMdContent: (value: string) => void; -}) => ( - - ) => setMdContent(event.target.value)} - value={mdContent ?? ""} - > - { + const [currentValue, setCurrentValue] = useState(mdContent ?? ""); + const prevMdContentRef = useRef(mdContent); + + // Sync local state with prop changes + if (mdContent !== prevMdContentRef.current) { + setCurrentValue(mdContent ?? ""); + prevMdContentRef.current = mdContent; + } + + return ( + + ) => { + const { value } = event.target; + + setCurrentValue(value); + setMdContent(value); + }} + value={currentValue} > - {Boolean(mdContent) ? ( - {mdContent} - ) : ( - {placeholder} - )} - - - - -); + + {Boolean(currentValue) ? ( + {currentValue} + ) : ( + {placeholder} + )} + + + + + ); +}; export default EditableMarkdownArea; diff --git a/airflow-core/src/airflow/ui/src/components/EditableMarkdownButton.tsx b/airflow-core/src/airflow/ui/src/components/EditableMarkdownButton.tsx index c4234895aaf24..239720f61f219 100644 --- a/airflow-core/src/airflow/ui/src/components/EditableMarkdownButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/EditableMarkdownButton.tsx @@ -70,7 +70,7 @@ const EditableMarkdownButton = ({ /> {Boolean(mdContent?.trim()) && ( - + {header} @@ -101,7 +101,7 @@ const EditableMarkdownButton = ({ /> + + + {availableConfigs.map((config) => ( + addFilter(config)} value={config.key}> + + {getFilterIcon(config)} + {config.label} + + + ))} + + + )} + {filters.length > 0 && ( + + )} + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/FilterPill.tsx b/airflow-core/src/airflow/ui/src/components/FilterBar/FilterPill.tsx new file mode 100644 index 0000000000000..ef789617f203b --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/FilterPill.tsx @@ -0,0 +1,161 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { Box, HStack } from "@chakra-ui/react"; +import React from "react"; +import { useEffect, useRef, useState } from "react"; +import { MdClose } from "react-icons/md"; + +import { getDefaultFilterIcon } from "./defaultIcons"; +import type { FilterState, FilterValue } from "./types"; + +type FilterPillProps = { + readonly children: React.ReactNode; + readonly displayValue: React.ReactNode | string; + readonly filter: FilterState; + readonly hasValue: boolean; + readonly onChange: (value: FilterValue) => void; + readonly onRemove: () => void; +}; + +export const FilterPill = ({ + children, + displayValue, + filter, + hasValue, + onChange, + onRemove, +}: FilterPillProps) => { + const isEmpty = filter.value === null || filter.value === undefined || String(filter.value).trim() === ""; + const [isEditing, setIsEditing] = useState(isEmpty); + const inputRef = useRef(null); + const blurTimeoutRef = useRef(undefined); + + const handlePillClick = () => setIsEditing(true); + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.key === "Enter" || event.key === "Escape") { + setIsEditing(false); + } + }; + + const handleBlur = () => { + blurTimeoutRef.current = setTimeout(() => setIsEditing(false), 150); + }; + + const handleFocus = () => { + if (blurTimeoutRef.current) { + clearTimeout(blurTimeoutRef.current); + blurTimeoutRef.current = undefined; + } + }; + + useEffect(() => { + if (isEditing && inputRef.current) { + const input = inputRef.current; + const focusInput = () => { + input.focus(); + try { + input.select(); + } catch { + // NumberInputField doesn't support select() + } + }; + + requestAnimationFrame(focusInput); + } + }, [isEditing]); + + useEffect( + () => () => { + if (blurTimeoutRef.current) { + clearTimeout(blurTimeoutRef.current); + } + }, + [], + ); + + const childrenWithProps = React.Children.map(children, (child) => { + if (React.isValidElement(child)) { + return React.cloneElement(child, { + onBlur: handleBlur, + onChange, + onFocus: handleFocus, + onKeyDown: handleKeyDown, + ref: inputRef, + ...child.props, + } as Record); + } + + return child; + }); + + if (isEditing) { + return childrenWithProps; + } + + return ( + + + {filter.config.icon ?? getDefaultFilterIcon(filter.config.type)} + + {filter.config.label}: {displayValue} + + + { + event.stopPropagation(); + onRemove(); + }} + transition="all 0.2s" + w={6} + > + + + + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/defaultIcons.tsx b/airflow-core/src/airflow/ui/src/components/FilterBar/defaultIcons.tsx new file mode 100644 index 0000000000000..338b89422b789 --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/defaultIcons.tsx @@ -0,0 +1,30 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { MdCalendarToday, MdNumbers, MdTextFields, MdArrowDropDown } from "react-icons/md"; + +import type { FilterConfig } from "./types"; + +export const defaultFilterIcons = { + date: , + number: , + select: , + text: , +} as const; + +export const getDefaultFilterIcon = (type: FilterConfig["type"]) => defaultFilterIcons[type]; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/filters/DateFilter.tsx b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/DateFilter.tsx new file mode 100644 index 0000000000000..6bd7b02a8ddfd --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/DateFilter.tsx @@ -0,0 +1,54 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import dayjs from "dayjs"; + +import { DateTimeInput } from "src/components/DateTimeInput"; + +import { FilterPill } from "../FilterPill"; +import type { FilterPluginProps } from "../types"; + +export const DateFilter = ({ filter, onChange, onRemove }: FilterPluginProps) => { + const hasValue = filter.value !== null && filter.value !== undefined && String(filter.value).trim() !== ""; + const displayValue = hasValue ? dayjs(String(filter.value)).format("MMM DD, YYYY, hh:mm A") : ""; + + const handleDateChange = (event: React.ChangeEvent) => { + const { value } = event.target; + + onChange(value || undefined); + }; + + return ( + + + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/filters/NumberFilter.tsx b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/NumberFilter.tsx new file mode 100644 index 0000000000000..d8a89895c0d3f --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/NumberFilter.tsx @@ -0,0 +1,112 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { useState, useEffect, forwardRef } from "react"; + +import { NumberInputField, NumberInputRoot } from "src/components/ui/NumberInput"; + +import { FilterPill } from "../FilterPill"; +import type { FilterPluginProps } from "../types"; + +const NumberInputWithRef = forwardRef< + HTMLInputElement, + { + readonly max?: number; + readonly min?: number; + readonly onBlur?: () => void; + readonly onFocus?: () => void; + readonly onKeyDown?: (event: React.KeyboardEvent) => void; + readonly onValueChange: (details: { value: string }) => void; + readonly placeholder?: string; + readonly value: string; + } +>((props, ref) => { + const { max, min, onBlur, onFocus, onKeyDown, onValueChange, placeholder, value } = props; + + return ( + + + + ); +}); + +NumberInputWithRef.displayName = "NumberInputWithRef"; + +export const NumberFilter = ({ filter, onChange, onRemove }: FilterPluginProps) => { + const hasValue = filter.value !== null && filter.value !== undefined && filter.value !== ""; + + const [inputValue, setInputValue] = useState(filter.value?.toString() ?? ""); + + useEffect(() => { + setInputValue(filter.value?.toString() ?? ""); + }, [filter.value]); + + const handleValueChange = ({ value }: { value: string }) => { + setInputValue(value); + + if (value === "") { + onChange(undefined); + + return; + } + + // Allow user to input negative sign for negative number + if (value === "-") { + return; + } + + const parsedValue = Number(value); + + if (!isNaN(parsedValue)) { + onChange(parsedValue); + } + }; + + return ( + + + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/filters/SelectFilter.tsx b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/SelectFilter.tsx new file mode 100644 index 0000000000000..79374b27c23a4 --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/SelectFilter.tsx @@ -0,0 +1,108 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { createListCollection, Box, Text } from "@chakra-ui/react"; + +import { Select } from "src/components/ui"; + +import { FilterPill } from "../FilterPill"; +import type { FilterPluginProps, FilterConfig } from "../types"; + +type SelectOption = { + label: string; + value: string; +}; + +type SelectFilterConfig = { + options: Array; +}; + +export const SelectFilter = ({ filter, onChange, onRemove }: FilterPluginProps) => { + const config = filter.config as FilterConfig & SelectFilterConfig; + + const handleValueChange = ({ value }: { value: Array }) => { + const [newValue] = value; + + onChange(newValue); + + // Trigger blur to close the editing mode after selection + setTimeout(() => { + const activeElement = document.activeElement as HTMLElement; + + activeElement.blur(); + }, 0); + }; + + const hasValue = filter.value !== null && filter.value !== undefined && filter.value !== ""; + const displayValue = config.options.find((option) => option.value === String(filter.value))?.label; + + return ( + + + + {filter.config.label}: + + + + + + + {config.options.map((option) => ( + + {option.label} + + ))} + + + + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx new file mode 100644 index 0000000000000..8cca8cf08532e --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx @@ -0,0 +1,63 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { useRef } from "react"; +import { useHotkeys } from "react-hotkeys-hook"; + +import { InputWithAddon } from "../../ui"; +import { FilterPill } from "../FilterPill"; +import type { FilterPluginProps } from "../types"; + +export const TextSearchFilter = ({ filter, onChange, onRemove }: FilterPluginProps) => { + const inputRef = useRef(null); + + const hasValue = filter.value !== null && filter.value !== undefined && String(filter.value).trim() !== ""; + + const handleInputChange = (event: React.ChangeEvent) => { + const newValue = event.target.value; + + onChange(newValue || undefined); + }; + + useHotkeys( + "mod+k", + () => { + if (!filter.config.hotkeyDisabled) { + inputRef.current?.focus(); + } + }, + { enabled: !filter.config.hotkeyDisabled, preventDefault: true }, + ); + + return ( + + + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/index.ts b/airflow-core/src/airflow/ui/src/components/FilterBar/index.ts new file mode 100644 index 0000000000000..fa3c5c7621da0 --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/index.ts @@ -0,0 +1,25 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +export { FilterBar } from "./FilterBar"; +export { FilterPill } from "./FilterPill"; +export { defaultFilterIcons, getDefaultFilterIcon } from "./defaultIcons"; +export { DateFilter } from "./filters/DateFilter"; +export { NumberFilter } from "./filters/NumberFilter"; +export { TextSearchFilter } from "./filters/TextSearchFilter"; +export type * from "./types"; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/types.ts b/airflow-core/src/airflow/ui/src/components/FilterBar/types.ts new file mode 100644 index 0000000000000..0f997c90671b6 --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/types.ts @@ -0,0 +1,54 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import type React from "react"; + +export type FilterValue = Date | number | string | null | undefined; + +export type FilterConfig = { + readonly defaultValue?: FilterValue; + readonly hotkeyDisabled?: boolean; + readonly icon?: React.ReactNode; + readonly key: string; + readonly label: string; + readonly max?: number; + readonly min?: number; + readonly options?: Array<{ label: React.ReactNode | string; value: string }>; + readonly placeholder?: string; + readonly required?: boolean; + readonly type: "date" | "number" | "select" | "text"; +}; + +export type FilterState = { + readonly config: FilterConfig; + readonly id: string; + readonly value: FilterValue; +}; + +export type FilterBarProps = { + readonly configs: Array; + readonly initialValues?: Record; + readonly maxVisibleFilters?: number; + readonly onFiltersChange: (filters: Record) => void; +}; + +export type FilterPluginProps = { + readonly filter: FilterState; + readonly onChange: (value: FilterValue) => void; + readonly onRemove: () => void; +}; diff --git a/airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldBool.tsx b/airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldBool.tsx index f9a94253df1b6..6cced8977db11 100644 --- a/airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldBool.tsx +++ b/airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldBool.tsx @@ -35,7 +35,7 @@ export const FieldBool = ({ name, namespace = "default" }: FlexibleFormElementPr return ( export const FieldSelector = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => { // FUTURE: Add support for other types as described in AIP-68 via Plugins - const { initialParamDict } = useParamStore(namespace); - const param = initialParamDict[name] ?? paramPlaceholder; + const { initialParamDict, paramsDict } = useParamStore(namespace); + + // Use current paramsDict (which has actual values) for type inference, fall back to initialParamDict for schema + const currentParam = paramsDict[name]; + const initialParam = initialParamDict[name] ?? paramPlaceholder; + + // Create a param object that combines the schema from initialParamDict with the value from paramsDict + const param: ParamSpec = { + ...initialParam, + value: currentParam?.value ?? initialParam.value, + }; + const fieldType = inferType(param); if (isFieldBool(fieldType)) { diff --git a/airflow-core/src/airflow/ui/src/components/Graph/DownloadButton.tsx b/airflow-core/src/airflow/ui/src/components/Graph/DownloadButton.tsx index e1ff71d0add3b..2218e611984b7 100644 --- a/airflow-core/src/airflow/ui/src/components/Graph/DownloadButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/Graph/DownloadButton.tsx @@ -17,7 +17,7 @@ * under the License. */ import { IconButton } from "@chakra-ui/react"; -import { Panel, useReactFlow, getNodesBounds, getViewportForBounds } from "@xyflow/react"; +import { Panel, useReactFlow } from "@xyflow/react"; import { toPng } from "html-to-image"; import { useTranslation } from "react-i18next"; import { FiDownload } from "react-icons/fi"; @@ -26,24 +26,23 @@ import { toaster } from "src/components/ui"; export const DownloadButton = ({ name }: { readonly name: string }) => { const { t: translate } = useTranslation("components"); - const { getNodes, getZoom } = useReactFlow(); - const onClick = () => { - const nodesBounds = getNodesBounds(getNodes()); + const { fitView } = useReactFlow(); + + const onClick = async () => { + // Ensure the graph fits before taking screenshot + await fitView({ duration: 0, padding: 0.1 }); // Method obtained from https://reactflow.dev/examples/misc/download-image const container = document.querySelector(".react-flow__viewport"); if (container instanceof HTMLElement) { const dimensions = { height: container.clientHeight, width: container.clientWidth }; - const zoom = getZoom(); - const viewport = getViewportForBounds(nodesBounds, dimensions.width, dimensions.height, zoom, zoom, 2); toPng(container, { height: dimensions.height, style: { height: `${dimensions.height}px`, - transform: `translate(${viewport.x}px, ${viewport.y}px) scale(${viewport.zoom})`, width: `${dimensions.width}px`, }, width: dimensions.width, @@ -69,7 +68,10 @@ export const DownloadButton = ({ name }: { readonly name: string }) => { { + void onClick(); + }} size="xs" title={translate("graph.downloadImage")} variant="ghost" diff --git a/airflow-core/src/airflow/ui/src/components/Graph/Edge.tsx b/airflow-core/src/airflow/ui/src/components/Graph/Edge.tsx index 83f4c84caa0da..156384d11384a 100644 --- a/airflow-core/src/airflow/ui/src/components/Graph/Edge.tsx +++ b/airflow-core/src/airflow/ui/src/components/Graph/Edge.tsx @@ -22,17 +22,12 @@ import { LinePath } from "@visx/shape"; import type { Edge as EdgeType } from "@xyflow/react"; import type { ElkPoint } from "elkjs"; -import { useColorMode } from "src/context/colorMode"; - import type { EdgeData } from "./reactflowUtils"; type Props = EdgeType; const CustomEdge = ({ data }: Props) => { - const { colorMode } = useColorMode(); - - // corresponds to the "border.inverted" semantic token - const [lightStroke, darkStroke] = useToken("colors", ["gray.800", "gray.200"]); + const [strokeColor] = useToken("colors", ["border.inverted"]); if (data === undefined) { return undefined; @@ -65,7 +60,7 @@ const CustomEdge = ({ data }: Props) => { point.x} diff --git a/airflow-core/src/airflow/ui/src/components/Graph/TaskNode.tsx b/airflow-core/src/airflow/ui/src/components/Graph/TaskNode.tsx index 5f84881418d90..803a19959ea72 100644 --- a/airflow-core/src/airflow/ui/src/components/Graph/TaskNode.tsx +++ b/airflow-core/src/airflow/ui/src/components/Graph/TaskNode.tsx @@ -116,7 +116,7 @@ export const TaskNode = ({ )} {isGroup ? ( + + + + + + {translate("limitedList.allItems", { count: items.length })} + + + + {interactive ? ( + + {items.map((item, index) => ( + + {item} + + ))} + + ) : ( + + {items.map((item, index) => ( + + {item} + + ))} + + )} + + + + {interactive + ? translate("limitedList.clickToInteract") + : translate("limitedList.copyPasteText")} + + + + ) ) : undefined} diff --git a/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsDialog.tsx b/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsDialog.tsx index c91f05d4e95ba..370f10920de5a 100644 --- a/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsDialog.tsx +++ b/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsDialog.tsx @@ -62,7 +62,7 @@ const MarkRunAsDialog = ({ dagRun, onClose, open, state }: Props) => { )} diff --git a/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDagsButton.tsx b/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDagsButton.tsx index 2080ca100c71a..9a6cdafae5d7c 100644 --- a/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDagsButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDagsButton.tsx @@ -47,7 +47,13 @@ export const SearchDagsButton = () => { return ( - diff --git a/airflow-core/src/airflow/ui/src/components/ui/InputWithAddon.tsx b/airflow-core/src/airflow/ui/src/components/ui/InputWithAddon.tsx new file mode 100644 index 0000000000000..b5a49e6cdf82d --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/ui/InputWithAddon.tsx @@ -0,0 +1,68 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import type { InputProps } from "@chakra-ui/react"; +import { Box, Input, Text } from "@chakra-ui/react"; +import * as React from "react"; + +export type InputWithAddonProps = { + readonly label: string; + readonly width?: string; +} & InputProps; + +export const InputWithAddon = React.forwardRef((props, ref) => { + const { label, width = "220px", ...inputProps } = props; + + return ( + + + {label}: + + + + ); +}); + +InputWithAddon.displayName = "InputWithAddon"; diff --git a/airflow-core/src/airflow/ui/src/components/ui/ResizableWrapper.tsx b/airflow-core/src/airflow/ui/src/components/ui/ResizableWrapper.tsx new file mode 100644 index 0000000000000..26bdde642e0f9 --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/ui/ResizableWrapper.tsx @@ -0,0 +1,79 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { Box } from "@chakra-ui/react"; +import { forwardRef } from "react"; +import type { ReactNode } from "react"; +import { ResizableBox } from "react-resizable"; +import "react-resizable/css/styles.css"; + +import { usePersistentResizableState } from "src/utils/usePersistentResizableState"; + +const ResizeHandle = forwardRef((props, ref) => ( + +)); + +type ResizableWrapperProps = { + readonly children: ReactNode; + readonly defaultSize?: { height: number; width: number }; + readonly maxConstraints?: [width: number, height: number]; + readonly storageKey: string; +}; + +const DEFAULT_SIZE = { height: 400, width: 500 }; +const MAX_SIZE: [number, number] = [1200, 800]; + +export const ResizableWrapper = ({ + children, + defaultSize = DEFAULT_SIZE, + maxConstraints = MAX_SIZE, + storageKey, +}: ResizableWrapperProps) => { + const { handleResize, handleResizeStop, size } = usePersistentResizableState(storageKey, defaultSize); + + return ( + } + height={size.height} + maxConstraints={maxConstraints} + minConstraints={[DEFAULT_SIZE.width, DEFAULT_SIZE.height]} + onResize={handleResize} + onResizeStop={handleResizeStop} + resizeHandles={["se"]} + style={{ + backgroundColor: "inherit", + borderRadius: "inherit", + overflow: "hidden", + position: "relative", + }} + width={size.width} + > + {children} + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/components/ui/SegmentedControl.tsx b/airflow-core/src/airflow/ui/src/components/ui/SegmentedControl.tsx index bcb8797f2be2f..3ab69b4065e11 100644 --- a/airflow-core/src/airflow/ui/src/components/ui/SegmentedControl.tsx +++ b/airflow-core/src/airflow/ui/src/components/ui/SegmentedControl.tsx @@ -48,11 +48,21 @@ const SegmentedControl = ({ defaultValues, multiple = false, onChange, options } useEffect(() => onChange?.(selectedOptions), [onChange, selectedOptions]); return ( - + {options.map(({ disabled, label, value }: Option) => ( diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/TimezoneSelector.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/TimezoneSelector.tsx index 7a458f668c3a2..1ab91744cb324 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/TimezoneSelector.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/TimezoneSelector.tsx @@ -25,6 +25,7 @@ import React, { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { useTimezone } from "src/context/timezone"; +import { DEFAULT_DATETIME_FORMAT } from "src/utils/datetimeUtils"; import type { Option as TimezoneOption } from "src/utils/option"; dayjs.extend(utc); @@ -60,7 +61,7 @@ const TimezoneSelector: React.FC = () => { useEffect(() => { const updateTime = () => { - setCurrentTime(dayjs().tz(selectedTimezone).format("YYYY-MM-DD HH:mm:ss")); + setCurrentTime(dayjs().tz(selectedTimezone).format(DEFAULT_DATETIME_FORMAT)); }; updateTime(); diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx index a2b99016d9179..c8cc8108945a8 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx @@ -27,6 +27,7 @@ import { FiGlobe, FiEye, FiChevronRight, + FiChevronLeft, FiMonitor, } from "react-icons/fi"; import { MdOutlineAccountTree } from "react-icons/md"; @@ -52,7 +53,7 @@ const COLOR_MODES = { type ColorMode = (typeof COLOR_MODES)[keyof typeof COLOR_MODES]; export const UserSettingsButton = ({ externalViews }: { readonly externalViews: Array }) => { - const { t: translate } = useTranslation(); + const { i18n, t: translate } = useTranslation(); const { selectedTheme, setColorMode } = useColorMode(); const { onClose: onCloseTimezone, onOpen: onOpenTimezone, open: isOpenTimezone } = useDisclosure(); const { onClose: onCloseLogout, onOpen: onOpenLogout, open: isOpenLogout } = useDisclosure(); @@ -61,6 +62,8 @@ export const UserSettingsButton = ({ externalViews }: { readonly externalViews: const theme = selectedTheme ?? COLOR_MODES.SYSTEM; + const isRTL = i18n.dir() === "rtl"; + return ( @@ -75,7 +78,11 @@ export const UserSettingsButton = ({ externalViews }: { readonly externalViews: {translate("appearance.appearance")} - + {isRTL ? ( + + ) : ( + + )} ))} - + {translate("logout")} diff --git a/airflow-core/src/airflow/ui/src/main.tsx b/airflow-core/src/airflow/ui/src/main.tsx index 41f5d1bd0f6b1..a98de89b4868e 100644 --- a/airflow-core/src/airflow/ui/src/main.tsx +++ b/airflow-core/src/airflow/ui/src/main.tsx @@ -25,6 +25,7 @@ import * as ReactDOM from "react-dom"; import { createRoot } from "react-dom/client"; import { I18nextProvider } from "react-i18next"; import { RouterProvider } from "react-router-dom"; +import * as ReactRouterDOM from "react-router-dom"; import * as ReactJSXRuntime from "react/jsx-runtime"; import type { HTTPExceptionResponse } from "openapi/requests/types.gen"; @@ -36,7 +37,6 @@ import { getRedirectPath } from "src/utils/links.ts"; import i18n from "./i18n/config"; import { client } from "./queryClient"; import { system } from "./theme"; -import { clearToken, tokenHandler } from "./utils/tokenHandler"; // Set React, ReactDOM, and ReactJSXRuntime on globalThis to share them with the dynamically imported React plugins. // Only one instance of React should be used. @@ -44,6 +44,7 @@ import { clearToken, tokenHandler } from "./utils/tokenHandler"; Reflect.set(globalThis, "React", React); Reflect.set(globalThis, "ReactDOM", ReactDOM); Reflect.set(globalThis, "ReactJSXRuntime", ReactJSXRuntime); +Reflect.set(globalThis, "ReactRouterDOM", ReactRouterDOM); // redirect to login page if the API responds with unauthorized or forbidden errors axios.interceptors.response.use( @@ -53,7 +54,6 @@ axios.interceptors.response.use( error.response?.status === 401 || (error.response?.status === 403 && error.response.data.detail === "Invalid JWT token") ) { - clearToken(); const params = new URLSearchParams(); params.set("next", globalThis.location.href); @@ -66,21 +66,10 @@ axios.interceptors.response.use( }, ); -axios.interceptors.request.use(tokenHandler); - -const html = document.documentElement; -const updateHtml = (lng: string) => { - html.setAttribute("dir", i18n.dir(lng)); - html.setAttribute("lang", lng); -}; - -updateHtml(i18n.language); -i18n.on("languageChanged", updateHtml); - createRoot(document.querySelector("#root") as HTMLDivElement).render( - + diff --git a/airflow-core/src/airflow/ui/src/mocks/handlers/log.ts b/airflow-core/src/airflow/ui/src/mocks/handlers/log.ts index ec34c9dffd315..b9ed6b734480b 100644 --- a/airflow-core/src/airflow/ui/src/mocks/handlers/log.ts +++ b/airflow-core/src/airflow/ui/src/mocks/handlers/log.ts @@ -17,53 +17,55 @@ * under the License. */ -/* eslint-disable unicorn/no-null */ +/* eslint-disable unicorn/no-null,max-lines */ import { http, HttpResponse, type HttpHandler } from "msw"; +const ti = { + dag_id: "log_grouping", + dag_run_id: "", + dag_version: { + bundle_name: "dags-folder", + bundle_url: null, + bundle_version: null, + created_at: "2025-02-18T12:06:45.723238Z", + dag_id: "log_grouping", + id: "019518f4-1adb-7223-a917-45fe08b78947", + version_number: 1, + }, + duration: 0.203_977, + end_date: "2025-02-18T12:19:56.467235Z", + executor: null, + executor_config: "{}", + hostname: "laptop", + id: "01951900-16f6-7c1c-ae66-91bdfe9e0cfd", + logical_date: null, + map_index: -1, + max_tries: 0, + note: null, + operator: "_PythonDecoratedOperator", + pid: 20_703, + pool: "default_pool", + pool_slots: 1, + priority_weight: 1, + queue: "default", + queued_when: "2025-02-18T12:19:52.311873Z", + rendered_fields: { op_args: "()", op_kwargs: {}, templates_dict: null }, + rendered_map_index: null, + run_after: "2025-02-18T12:19:51.120210Z", + scheduled_when: "2025-02-18T12:19:52.289327Z", + start_date: "2025-02-18T12:19:56.263258Z", + state: "success", + task_display_name: "generate", + task_id: "generate", + trigger: null, + triggerer_job: null, + try_number: 1, + unixname: "testname", +}; + export const handlers: Array = [ http.get("/api/v2/dags/log_grouping/dagRuns/manual__2025-02-18T12:19/taskInstances/generate/-1", () => - HttpResponse.json({ - dag_id: "log_grouping", - dag_run_id: "manual__2025-02-18T12:19", - dag_version: { - bundle_name: "dags-folder", - bundle_url: null, - bundle_version: null, - created_at: "2025-02-18T12:06:45.723238Z", - dag_id: "log_grouping", - id: "019518f4-1adb-7223-a917-45fe08b78947", - version_number: 1, - }, - duration: 0.203_977, - end_date: "2025-02-18T12:19:56.467235Z", - executor: null, - executor_config: "{}", - hostname: "laptop", - id: "01951900-16f6-7c1c-ae66-91bdfe9e0cfd", - logical_date: null, - map_index: -1, - max_tries: 0, - note: null, - operator: "_PythonDecoratedOperator", - pid: 20_703, - pool: "default_pool", - pool_slots: 1, - priority_weight: 1, - queue: "default", - queued_when: "2025-02-18T12:19:52.311873Z", - rendered_fields: { op_args: "()", op_kwargs: {}, templates_dict: null }, - rendered_map_index: null, - run_after: "2025-02-18T12:19:51.120210Z", - scheduled_when: "2025-02-18T12:19:52.289327Z", - start_date: "2025-02-18T12:19:56.263258Z", - state: "success", - task_display_name: "generate", - task_id: "generate", - trigger: null, - triggerer_job: null, - try_number: 1, - unixname: "testname", - }), + HttpResponse.json({ ...ti, dag_run_id: "manual__2025-02-18T12:19" }), ), http.get("/api/v2/dags/log_grouping/dagRuns/manual__2025-02-18T12:19/taskInstances/generate/logs/1", () => HttpResponse.json({ @@ -191,4 +193,104 @@ export const handlers: Array = [ continuation_token: null, }), ), + http.get("/api/v2/dags/log_grouping/dagRuns/manual__2025-02-18T12:19/taskInstances/log_source/-1", () => + HttpResponse.json({ + ...ti, + dag_run_id: "manual__2025-02-18T12:19", + task_display_name: "log_source", + task_id: "log_source", + }), + ), + http.get("/api/v2/dags/log_grouping/dagRuns/manual__2025-02-18T12:19/taskInstances/log_source/logs/1", () => + HttpResponse.json({ + content: [ + { + event: "::group::Log message source details", + sources: [ + "/root/airflow/logs/dag_id=log_grouping/run_id=manual__2025-02-18T12:19/task_id=log_source/attempt=1.log", + ], + timestamp: null, + }, + { event: "::endgroup::", timestamp: null }, + { + event: "DAG bundles loaded: dags-folder, example_dags", + filename: "manager.py", + level: "info", + lineno: 179, + logger: "airflow.dag_processing.bundles.manager.DagBundlesManager", + timestamp: "2025-09-11T17:44:52.567095Z", + }, + { + event: + "Filling up the DagBag from /opt/airflow/airflow-core/src/airflow/example_dags/standard/example_python_decorator.py", + filename: "dagbag.py", + level: "info", + lineno: 593, + logger: "airflow.models.dagbag.DagBag", + timestamp: "2025-09-11T17:44:52.567407Z", + }, + { + event: "Task instance is in running state", + level: "info", + logger: "task.stdout", + timestamp: "2025-09-11T17:44:52.597476Z", + }, + { + event: " Previous state of the Task instance: TaskInstanceState.QUEUED", + level: "info", + logger: "task.stdout", + timestamp: "2025-09-11T17:44:52.597589Z", + }, + { + event: "Current task name:log_sql_query", + level: "info", + logger: "task.stdout", + timestamp: "2025-09-11T17:44:52.597626Z", + }, + { + event: "Dag name:example_python_decorator", + level: "info", + logger: "task.stdout", + timestamp: "2025-09-11T17:44:52.597657Z", + }, + { + event: + "Python task decorator query: CREATE TABLE Orders (\n order_id INT PRIMARY KEY,\n name TEXT,\n description TEXT\n)", + filename: "example_python_decorator.py", + level: "info", + lineno: 60, + logger: "unusual_prefix_7bb6f64024e819254594fca018f7123719f205f5_example_python_decorator", + timestamp: "2025-09-11T17:44:52.598196Z", + }, + { + event: "Done. Returned value was: None", + filename: "python.py", + level: "info", + lineno: 218, + logger: + "airflow.task.operators.airflow.providers.standard.decorators.python._PythonDecoratedOperator", + timestamp: "2025-09-11T17:44:52.598300Z", + }, + { + event: "Task instance in success state", + level: "info", + logger: "task.stdout", + timestamp: "2025-09-11T17:44:52.607859Z", + }, + { + event: " Previous state of the Task instance: TaskInstanceState.RUNNING", + level: "info", + logger: "task.stdout", + timestamp: "2025-09-11T17:44:52.607929Z", + }, + { + event: "Task operator:", + level: "info", + logger: "task.stdout", + timestamp: "2025-09-11T17:44:52.607985Z", + }, + ], + continuation_token: null, + }), + ), ]; diff --git a/airflow-core/src/airflow/ui/src/pages/Asset/AssetGraph.tsx b/airflow-core/src/airflow/ui/src/pages/Asset/AssetGraph.tsx index 370a77a8f5408..f00c00b85023d 100644 --- a/airflow-core/src/airflow/ui/src/pages/Asset/AssetGraph.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Asset/AssetGraph.tsx @@ -28,6 +28,7 @@ import type { CustomNodeProps } from "src/components/Graph/reactflowUtils"; import { useGraphLayout } from "src/components/Graph/useGraphLayout"; import { useColorMode } from "src/context/colorMode"; import { useDependencyGraph } from "src/queries/useDependencyGraph"; +import { getReactFlowThemeStyle } from "src/theme"; export const AssetGraph = ({ asset }: { readonly asset?: AssetResponse }) => { const { assetId } = useParams(); @@ -45,7 +46,7 @@ export const AssetGraph = ({ asset }: { readonly asset?: AssetResponse }) => { node.id === `asset:${assetId}` ? { ...node, data: { ...node.data, isSelected: true } } : node, ); - const [selectedDarkColor, selectedLightColor] = useToken("colors", ["gray.200", "gray.800"]); + const [selectedDarkColor, selectedLightColor] = useToken("colors", ["bg.muted", "bg.emphasized"]); const selectedColor = colorMode === "dark" ? selectedDarkColor : selectedLightColor; @@ -74,6 +75,7 @@ export const AssetGraph = ({ asset }: { readonly asset?: AssetResponse }) => { nodesDraggable={false} nodeTypes={nodeTypes} onlyRenderVisibleElements + style={getReactFlowThemeStyle(colorMode)} > diff --git a/airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx b/airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx index 51a1442fcc90b..e499afda799bf 100644 --- a/airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx @@ -22,12 +22,14 @@ import { useCallback } from "react"; import { useTranslation } from "react-i18next"; import { PanelGroup, Panel, PanelResizeHandle } from "react-resizable-panels"; import { useParams } from "react-router-dom"; +import { useSearchParams } from "react-router-dom"; import { useAssetServiceGetAsset, useAssetServiceGetAssetEvents } from "openapi/queries"; import { AssetEvents } from "src/components/Assets/AssetEvents"; import { BreadcrumbStats } from "src/components/BreadcrumbStats"; import { useTableURLState } from "src/components/DataTable/useTableUrlState"; import { ProgressBar } from "src/components/ui"; +import { SearchParamsKeys } from "src/constants/searchParams"; import { AssetGraph } from "./AssetGraph"; import { CreateAssetEvent } from "./CreateAssetEvent"; @@ -59,12 +61,18 @@ export const AssetLayout = () => { }, ]; + const { DAG_ID, END_DATE, START_DATE, TASK_ID } = SearchParamsKeys; + const [searchParams] = useSearchParams(); const { data, isLoading: isLoadingEvents } = useAssetServiceGetAssetEvents( { assetId: asset?.id, limit: pagination.pageSize, offset: pagination.pageIndex * pagination.pageSize, orderBy, + sourceDagId: searchParams.get(DAG_ID) ?? undefined, + sourceTaskId: searchParams.get(TASK_ID) ?? undefined, + timestampGte: searchParams.get(START_DATE) ?? undefined, + timestampLte: searchParams.get(END_DATE) ?? undefined, }, undefined, { enabled: Boolean(asset?.id) }, @@ -127,6 +135,7 @@ export const AssetLayout = () => { isLoading={isLoadingEvents} setOrderBy={setOrderBy} setTableUrlState={setTableURLState} + showFilters={true} tableUrlState={tableURLState} /> diff --git a/airflow-core/src/airflow/ui/src/pages/Asset/CreateAssetEvent.tsx b/airflow-core/src/airflow/ui/src/pages/Asset/CreateAssetEvent.tsx index 10b00c9310acb..ecd5f5c67ba98 100644 --- a/airflow-core/src/airflow/ui/src/pages/Asset/CreateAssetEvent.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Asset/CreateAssetEvent.tsx @@ -39,7 +39,7 @@ export const CreateAssetEvent = ({ asset, withText = true }: Props) => { } onClick={onOpen} diff --git a/airflow-core/src/airflow/ui/src/pages/Asset/CreateAssetEventModal.tsx b/airflow-core/src/airflow/ui/src/pages/Asset/CreateAssetEventModal.tsx index 7f5f212469d86..500c82ded1c78 100644 --- a/airflow-core/src/airflow/ui/src/pages/Asset/CreateAssetEventModal.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Asset/CreateAssetEventModal.tsx @@ -206,7 +206,7 @@ export const CreateAssetEventModal = ({ asset, onClose, open }: Props) => { ) : undefined} {eventType === "materialize" && dag?.is_paused ? ( - setUnpause(!unpause)}> + setUnpause(!unpause)}> {translate("createEvent.materialize.unpauseDag", { dagName: dag.dag_display_name })} ) : undefined} @@ -214,7 +214,7 @@ export const CreateAssetEventModal = ({ asset, onClose, open }: Props) => { @@ -60,7 +66,7 @@ const DeleteConnectionsButton = ({ clearSelections, deleteKeys: connectionIds }: - + {translate("connections.delete.firstConfirmMessage", { count: connectionIds.length })}
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/Calendar.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/Calendar.tsx index 8bf4b8b590536..634ff609e35e7 100644 --- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/Calendar.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/Calendar.tsx @@ -183,14 +183,14 @@ export const Calendar = () => { - diff --git a/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx b/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx index 50161446b2893..2a3bbefbb3a74 100644 --- a/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx @@ -16,11 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import { ButtonGroup, Code, Flex, Heading, IconButton, useDisclosure, VStack } from "@chakra-ui/react"; +import { Code, Flex, Heading, useDisclosure, VStack } from "@chakra-ui/react"; import type { ColumnDef } from "@tanstack/react-table"; import dayjs from "dayjs"; import { useTranslation } from "react-i18next"; -import { MdCompress, MdExpand } from "react-icons/md"; import { useParams, useSearchParams } from "react-router-dom"; import { useEventLogServiceGetEventLogs } from "openapi/queries"; @@ -28,6 +27,7 @@ import type { EventLogResponse } from "openapi/requests/types.gen"; import { DataTable } from "src/components/DataTable"; import { useTableURLState } from "src/components/DataTable/useTableUrlState"; import { ErrorAlert } from "src/components/ErrorAlert"; +import { ExpandCollapseButtons } from "src/components/ExpandCollapseButtons"; import RenderedJsonField from "src/components/RenderedJsonField"; import Time from "src/components/Time"; import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams"; @@ -208,35 +208,20 @@ export const Events = () => { ); return ( - + + {dagId === undefined && runId === undefined && taskId === undefined ? ( + {translate("auditLog.title")} + ) : undefined} - {dagId === undefined && runId === undefined && taskId === undefined ? ( - {translate("auditLog.title")} - ) : undefined} - - - - - - - - + + - - { - const { t: translate } = useTranslation(["browse", "common", "components"]); - const [searchParams, setSearchParams] = useSearchParams(); - const { setTableURLState, tableURLState } = useTableURLState(); - - const { pagination, sorting } = tableURLState; - - const resetPagination = useCallback(() => { - setTableURLState({ - pagination: { ...pagination, pageIndex: 0 }, - sorting, - }); - }, [pagination, setTableURLState, sorting]); - - const afterFilter = searchParams.get(AFTER_PARAM); - const beforeFilter = searchParams.get(BEFORE_PARAM); - const dagIdFilter = searchParams.get(DAG_ID_PARAM); - const eventTypeFilter = searchParams.get(EVENT_TYPE_PARAM); - const mapIndexFilter = searchParams.get(MAP_INDEX_PARAM); - const runIdFilter = searchParams.get(RUN_ID_PARAM); - const taskIdFilter = searchParams.get(TASK_ID_PARAM); - const tryNumberFilter = searchParams.get(TRY_NUMBER_PARAM); - const userFilter = searchParams.get(USER_PARAM); - - const updateSearchParams = useCallback( - (paramName: string, value: string) => { - if (value) { - searchParams.set(paramName, value); - } else { - searchParams.delete(paramName); + const searchParamKeys = useMemo((): Array => { + const keys: Array = [ + SearchParamsKeys.AFTER, + SearchParamsKeys.BEFORE, + SearchParamsKeys.EVENT_TYPE, + SearchParamsKeys.USER, + SearchParamsKeys.MAP_INDEX, + SearchParamsKeys.TRY_NUMBER, + ]; + + // Only add DAG ID filter if not in URL context + if (urlDagId === undefined) { + keys.push(SearchParamsKeys.DAG_ID); + } + + // Only add Run ID filter if not in URL context + if (urlRunId === undefined) { + keys.push(SearchParamsKeys.RUN_ID); + } + + // Only add Task ID filter if not in URL context + if (urlTaskId === undefined) { + keys.push(SearchParamsKeys.TASK_ID); + } + + return keys; + }, [urlDagId, urlRunId, urlTaskId]); + + const { filterConfigs, handleFiltersChange, searchParams } = useFiltersHandler(searchParamKeys); + + const initialValues = useMemo(() => { + const values: Record = {}; + + filterConfigs.forEach((config) => { + const value = searchParams.get(config.key); + + if (value !== null && value !== "") { + if (config.type === "number") { + const parsedValue = Number(value); + + values[config.key] = isNaN(parsedValue) ? value : parsedValue; + } else { + values[config.key] = value; + } } - resetPagination(); - setSearchParams(searchParams); - }, - [resetPagination, searchParams, setSearchParams], - ); - - const onClearFilters = useCallback(() => { - searchParams.delete(AFTER_PARAM); - searchParams.delete(BEFORE_PARAM); - searchParams.delete(DAG_ID_PARAM); - searchParams.delete(EVENT_TYPE_PARAM); - searchParams.delete(MAP_INDEX_PARAM); - searchParams.delete(RUN_ID_PARAM); - searchParams.delete(TASK_ID_PARAM); - searchParams.delete(TRY_NUMBER_PARAM); - searchParams.delete(USER_PARAM); - resetPagination(); - setSearchParams(searchParams); - }, [resetPagination, searchParams, setSearchParams]); - - const handleSearchChange = useCallback( - (paramName: string) => (value: string) => { - updateSearchParams(paramName, value); - }, - [updateSearchParams], - ); - - const handleDateTimeChange = useCallback( - (paramName: string) => (event: React.ChangeEvent) => { - const { value } = event.target; - - updateSearchParams(paramName, value); - }, - [updateSearchParams], - ); + }); - const filterCount = getFilterCount({ - after: afterFilter, - before: beforeFilter, - dagId: dagIdFilter, - eventType: eventTypeFilter, - mapIndex: mapIndexFilter, - runId: runIdFilter, - taskId: taskIdFilter, - tryNumber: tryNumberFilter, - user: userFilter, - }); + return values; + }, [searchParams, filterConfigs]); return ( - - - {/* Timestamp Range Filters */} - - - {translate("components:backfill.dateRangeFrom")} - - - - - - {translate("components:backfill.dateRangeTo")} - - - - - {/* Event Type Filter */} - - - - - {/* User Filter */} - - - - - {/* DAG ID Filter - Hide if URL already has dagId */} - {urlDagId === undefined && ( - - - - )} - - {/* Task ID Filter - Hide if URL already has taskId */} - {urlTaskId === undefined && ( - - - - )} - - {/* Run ID Filter - Hide if URL already has runId */} - {urlRunId === undefined && ( - - - - )} - - {/* Map Index Filter */} - - - - - {/* Try Number Filter */} - - - - - - - - - + ); }; diff --git a/airflow-core/src/airflow/ui/src/pages/HITLTaskInstances/HITLFilters.tsx b/airflow-core/src/airflow/ui/src/pages/HITLTaskInstances/HITLFilters.tsx new file mode 100644 index 0000000000000..84aec7292c81e --- /dev/null +++ b/airflow-core/src/airflow/ui/src/pages/HITLTaskInstances/HITLFilters.tsx @@ -0,0 +1,84 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { VStack } from "@chakra-ui/react"; +import { useMemo } from "react"; +import { useParams, useSearchParams } from "react-router-dom"; + +import { FilterBar, type FilterValue } from "src/components/FilterBar"; +import { SearchParamsKeys } from "src/constants/searchParams"; +import { useFiltersHandler, type FilterableSearchParamsKeys } from "src/utils"; + +export const HITLFilters = ({ onResponseChange }: { readonly onResponseChange: () => void }) => { + const { dagId = "~", taskId = "~" } = useParams(); + const [urlSearchParams] = useSearchParams(); + const responseReceived = urlSearchParams.get(SearchParamsKeys.RESPONSE_RECEIVED); + + const searchParamKeys = useMemo((): Array => { + const keys: Array = []; + + if (dagId === "~") { + keys.push(SearchParamsKeys.DAG_DISPLAY_NAME_PATTERN); + } + + if (taskId === "~") { + keys.push(SearchParamsKeys.TASK_ID_PATTERN); + } + + keys.push(SearchParamsKeys.RESPONSE_RECEIVED); + + return keys; + }, [dagId, taskId]); + + const { filterConfigs, handleFiltersChange, searchParams } = useFiltersHandler(searchParamKeys); + + const initialValues = useMemo(() => { + const values: Record = {}; + + filterConfigs.forEach((config) => { + const value = searchParams.get(config.key); + + if (value !== null && value !== "") { + if (config.type === "number") { + const parsedValue = Number(value); + + values[config.key] = isNaN(parsedValue) ? value : parsedValue; + } else { + values[config.key] = value; + } + } + }); + + values[SearchParamsKeys.RESPONSE_RECEIVED] = responseReceived; + + return values; + }, [filterConfigs, responseReceived, searchParams]); + + return ( + + { + onResponseChange(); + handleFiltersChange(filters); + }} + /> + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/pages/HITLTaskInstances/HITLResponseForm.tsx b/airflow-core/src/airflow/ui/src/pages/HITLTaskInstances/HITLResponseForm.tsx index 1f45dae5fc744..3aeb0f6d741cd 100644 --- a/airflow-core/src/airflow/ui/src/pages/HITLTaskInstances/HITLResponseForm.tsx +++ b/airflow-core/src/airflow/ui/src/pages/HITLTaskInstances/HITLResponseForm.tsx @@ -27,6 +27,7 @@ import { FlexibleForm } from "src/components/FlexibleForm/FlexibleForm"; import Time from "src/components/Time"; import { useParamStore } from "src/queries/useParamStore"; import { useUpdateHITLDetail } from "src/queries/useUpdateHITLDetail"; +import { DEFAULT_DATETIME_FORMAT } from "src/utils/datetimeUtils"; import { getHITLParamsDict, getHITLFormData, getPreloadHITLFormData } from "src/utils/hitl"; type HITLResponseFormProps = { @@ -97,7 +98,10 @@ export const HITLResponseForm = ({ hitlDetail }: HITLResponseFormProps) => { {hitlDetail.response_received ? ( {translate("response.received")} - ) : undefined} { {shouldRenderOptionButton || isApprovalTask ? ( hitlDetail.options.map((option) => ( diff --git a/airflow-core/src/airflow/ui/src/pages/Pools/DeletePoolButton.tsx b/airflow-core/src/airflow/ui/src/pages/Pools/DeletePoolButton.tsx index bc2c47e8e3804..b268d323104da 100644 --- a/airflow-core/src/airflow/ui/src/pages/Pools/DeletePoolButton.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Pools/DeletePoolButton.tsx @@ -40,7 +40,7 @@ const DeletePoolButton = ({ poolName, withText = false }: Props) => { <> } onClick={onOpen} text={translate("pools.delete.warning")} diff --git a/airflow-core/src/airflow/ui/src/pages/Pools/PoolBarCard.tsx b/airflow-core/src/airflow/ui/src/pages/Pools/PoolBarCard.tsx index 2e0403592c3ef..d1d416e9c7e12 100644 --- a/airflow-core/src/airflow/ui/src/pages/Pools/PoolBarCard.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Pools/PoolBarCard.tsx @@ -55,7 +55,7 @@ const PoolBarCard = ({ pool }: PoolBarCardProps) => { {pool.description ?? ( - + {pool.description} )} @@ -63,7 +63,7 @@ const PoolBarCard = ({ pool }: PoolBarCardProps) => {
- + diff --git a/airflow-core/src/airflow/ui/src/pages/Pools/PoolForm.tsx b/airflow-core/src/airflow/ui/src/pages/Pools/PoolForm.tsx index a95252c97f791..37260eca66e20 100644 --- a/airflow-core/src/airflow/ui/src/pages/Pools/PoolForm.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Pools/PoolForm.tsx @@ -41,7 +41,7 @@ type PoolFormProps = { }; const PoolForm = ({ error, initialPool, isPending, manageMutate, setError }: PoolFormProps) => { - const { t: translate } = useTranslation("admin"); + const { t: translate } = useTranslation(["admin", "common"]); const { control, formState: { isDirty, isValid }, @@ -109,7 +109,7 @@ const PoolForm = ({ error, initialPool, isPending, manageMutate, setError }: Poo render={({ field }) => ( {translate("pools.form.includeDeferred")} - + {translate("pools.form.checkbox")} @@ -122,12 +122,12 @@ const PoolForm = ({ error, initialPool, isPending, manageMutate, setError }: Poo {isDirty ? ( ) : undefined} diff --git a/airflow-core/src/airflow/ui/src/pages/Variables/ImportVariablesForm.tsx b/airflow-core/src/airflow/ui/src/pages/Variables/ImportVariablesForm.tsx index 87713f4c5eb5d..5f863f356ef06 100644 --- a/airflow-core/src/airflow/ui/src/pages/Variables/ImportVariablesForm.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Variables/ImportVariablesForm.tsx @@ -154,7 +154,7 @@ const ImportVariablesForm = ({ onClose }: ImportVariablesFormProps) => { {isParsing ? (
- Parsing file... + Parsing file...
) : undefined} @@ -186,11 +186,11 @@ const ImportVariablesForm = ({ onClose }: ImportVariablesFormProps) => { {isPending ? (
- +
) : undefined} -
diff --git a/airflow-core/src/airflow/ui/src/pages/Variables/ManageVariable/AddVariableButton.tsx b/airflow-core/src/airflow/ui/src/pages/Variables/ManageVariable/AddVariableButton.tsx index 8ffb8a45f804b..c45c8075eb460 100644 --- a/airflow-core/src/airflow/ui/src/pages/Variables/ManageVariable/AddVariableButton.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Variables/ManageVariable/AddVariableButton.tsx @@ -50,7 +50,7 @@ const AddVariableButton = ({ disabled }: Props) => { return ( <> - diff --git a/airflow-core/src/airflow/ui/src/pages/Variables/ManageVariable/DeleteVariableButton.tsx b/airflow-core/src/airflow/ui/src/pages/Variables/ManageVariable/DeleteVariableButton.tsx index 9445bca6a5a0c..5bce2200d7a7e 100644 --- a/airflow-core/src/airflow/ui/src/pages/Variables/ManageVariable/DeleteVariableButton.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Variables/ManageVariable/DeleteVariableButton.tsx @@ -40,6 +40,7 @@ const DeleteVariableButton = ({ deleteKey: variableKey, disabled }: Props) => { <> } onClick={() => { @@ -60,7 +61,7 @@ const DeleteVariableButton = ({ deleteKey: variableKey, disabled }: Props) => { - + {translate("variables.delete.firstConfirmMessage_one")}
@@ -72,7 +73,7 @@ const DeleteVariableButton = ({ deleteKey: variableKey, disabled }: Props) => {
) : undefined} diff --git a/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx b/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx index 1609e1961dac8..0e66988437693 100644 --- a/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx +++ b/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { Box, Heading, Link } from "@chakra-ui/react"; +import { Box, Heading, Link, Flex, useDisclosure } from "@chakra-ui/react"; import type { ColumnDef } from "@tanstack/react-table"; import { useTranslation } from "react-i18next"; import { Link as RouterLink, useParams, useSearchParams } from "react-router-dom"; @@ -26,6 +26,7 @@ import type { XComResponse } from "openapi/requests/types.gen"; import { DataTable } from "src/components/DataTable"; import { useTableURLState } from "src/components/DataTable/useTableUrlState"; import { ErrorAlert } from "src/components/ErrorAlert"; +import { ExpandCollapseButtons } from "src/components/ExpandCollapseButtons"; import { TruncatedText } from "src/components/TruncatedText"; import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams"; import { getTaskInstanceLink } from "src/utils/links"; @@ -41,7 +42,7 @@ const { TASK_ID_PATTERN: TASK_ID_PATTERN_PARAM, }: SearchParamsKeysType = SearchParamsKeys; -const columns = (translate: (key: string) => string): Array> => [ +const columns = (translate: (key: string) => string, open: boolean): Array> => [ { accessorKey: "key", enableSorting: false, @@ -98,6 +99,7 @@ const columns = (translate: (key: string) => string): Array { const { setTableURLState, tableURLState } = useTableURLState(); const { pagination } = tableURLState; const [searchParams] = useSearchParams(); + const { onClose, onOpen, open } = useDisclosure(); const filteredKey = searchParams.get(KEY_PATTERN_PARAM); const filteredDagDisplayName = searchParams.get(DAG_DISPLAY_NAME_PATTERN_PARAM); @@ -122,7 +125,6 @@ export const XCom = () => { const filteredTaskId = searchParams.get(TASK_ID_PATTERN_PARAM); const { LOGICAL_DATE_GTE, LOGICAL_DATE_LTE, RUN_AFTER_GTE, RUN_AFTER_LTE } = SearchParamsKeys; - const logicalDateGte = searchParams.get(LOGICAL_DATE_GTE); const logicalDateLte = searchParams.get(LOGICAL_DATE_LTE); const runAfterGte = searchParams.get(RUN_AFTER_GTE); @@ -158,11 +160,19 @@ export const XCom = () => { {translate("xcom.title")} ) : undefined} - + + + + { ); }; -export const XComEntry = ({ dagId, mapIndex, runId, taskId, xcomKey }: XComEntryProps) => { +export const XComEntry = ({ dagId, mapIndex, open = false, runId, taskId, xcomKey }: XComEntryProps) => { const { data, isLoading } = useXcomServiceGetXcomEntry({ dagId, dagRunId: runId, @@ -88,7 +89,11 @@ export const XComEntry = ({ dagId, mapIndex, runId, taskId, xcomKey }: XComEntry ) : ( {isObjectOrArray ? ( - + ) : ( {renderTextWithLinks(valueFormatted)} )} diff --git a/airflow-core/src/airflow/ui/src/pages/XCom/XComFilters.tsx b/airflow-core/src/airflow/ui/src/pages/XCom/XComFilters.tsx index c7f36cfdd1c9f..4b7fec38b288b 100644 --- a/airflow-core/src/airflow/ui/src/pages/XCom/XComFilters.tsx +++ b/airflow-core/src/airflow/ui/src/pages/XCom/XComFilters.tsx @@ -16,206 +16,74 @@ * specific language governing permissions and limitations * under the License. */ -import { Box, Button, HStack, Text, VStack } from "@chakra-ui/react"; -import { useCallback, useMemo, useState } from "react"; -import { useTranslation } from "react-i18next"; -import { LuX } from "react-icons/lu"; -import { useSearchParams, useParams } from "react-router-dom"; +import { VStack } from "@chakra-ui/react"; +import { useMemo } from "react"; +import { useParams } from "react-router-dom"; -import { useTableURLState } from "src/components/DataTable/useTableUrlState"; -import { DateTimeInput } from "src/components/DateTimeInput"; -import { SearchBar } from "src/components/SearchBar"; -import { NumberInputField, NumberInputRoot } from "src/components/ui/NumberInput"; +import { FilterBar, type FilterValue } from "src/components/FilterBar"; import { SearchParamsKeys } from "src/constants/searchParams"; - -const FILTERS = [ - { - hotkeyDisabled: false, - key: SearchParamsKeys.KEY_PATTERN, - translationKey: "keyPlaceholder", - type: "search", - }, - { - hotkeyDisabled: true, - key: SearchParamsKeys.DAG_DISPLAY_NAME_PATTERN, - translationKey: "dagDisplayNamePlaceholder", - type: "search", - }, - { - hotkeyDisabled: true, - key: SearchParamsKeys.RUN_ID_PATTERN, - translationKey: "runIdPlaceholder", - type: "search", - }, - { - hotkeyDisabled: true, - key: SearchParamsKeys.TASK_ID_PATTERN, - translationKey: "taskIdPlaceholder", - type: "search", - }, - { - hotkeyDisabled: true, - key: SearchParamsKeys.MAP_INDEX, - translationKey: "mapIndexPlaceholder", - type: "number", - }, - { - key: SearchParamsKeys.LOGICAL_DATE_GTE, - translationKey: "logicalDateFromPlaceholder", - type: "datetime", - }, - { - key: SearchParamsKeys.LOGICAL_DATE_LTE, - translationKey: "logicalDateToPlaceholder", - type: "datetime", - }, - { - key: SearchParamsKeys.RUN_AFTER_GTE, - translationKey: "runAfterFromPlaceholder", - type: "datetime", - }, - { - key: SearchParamsKeys.RUN_AFTER_LTE, - translationKey: "runAfterToPlaceholder", - type: "datetime", - }, -] as const satisfies ReadonlyArray<{ - readonly hotkeyDisabled?: boolean; - readonly key: string; - readonly translationKey: string; - readonly type: "datetime" | "number" | "search"; -}>; +import { useFiltersHandler, type FilterableSearchParamsKeys } from "src/utils"; export const XComFilters = () => { - const [searchParams, setSearchParams] = useSearchParams(); const { dagId = "~", mapIndex = "-1", runId = "~", taskId = "~" } = useParams(); - const { setTableURLState, tableURLState } = useTableURLState(); - const { pagination, sorting } = tableURLState; - const { t: translate } = useTranslation(["browse", "common"]); - const [resetKey, setResetKey] = useState(0); - const visibleFilters = useMemo( - () => - FILTERS.filter((filter) => { - switch (filter.key) { - case SearchParamsKeys.DAG_DISPLAY_NAME_PATTERN: - return dagId === "~"; - case SearchParamsKeys.KEY_PATTERN: - case SearchParamsKeys.LOGICAL_DATE_GTE: - case SearchParamsKeys.LOGICAL_DATE_LTE: - case SearchParamsKeys.RUN_AFTER_GTE: - case SearchParamsKeys.RUN_AFTER_LTE: - return true; - case SearchParamsKeys.MAP_INDEX: - return mapIndex === "-1"; - case SearchParamsKeys.RUN_ID_PATTERN: - return runId === "~"; - case SearchParamsKeys.TASK_ID_PATTERN: - return taskId === "~"; - default: - return true; - } - }), - [dagId, mapIndex, runId, taskId], - ); + const searchParamKeys = useMemo((): Array => { + const keys: Array = [ + SearchParamsKeys.KEY_PATTERN, + SearchParamsKeys.LOGICAL_DATE_GTE, + SearchParamsKeys.LOGICAL_DATE_LTE, + SearchParamsKeys.RUN_AFTER_GTE, + SearchParamsKeys.RUN_AFTER_LTE, + ]; - const handleFilterChange = useCallback( - (paramKey: string) => (value: string) => { - if (value === "") { - searchParams.delete(paramKey); - } else { - searchParams.set(paramKey, value); - } - setTableURLState({ - pagination: { ...pagination, pageIndex: 0 }, - sorting, - }); - setSearchParams(searchParams); - }, - [pagination, searchParams, setSearchParams, setTableURLState, sorting], - ); + if (dagId === "~") { + keys.push(SearchParamsKeys.DAG_DISPLAY_NAME_PATTERN); + } - const filterCount = useMemo( - () => - visibleFilters.filter((filter) => { - const value = searchParams.get(filter.key); + if (runId === "~") { + keys.push(SearchParamsKeys.RUN_ID_PATTERN); + } - return value !== null && value !== ""; - }).length, - [searchParams, visibleFilters], - ); + if (taskId === "~") { + keys.push(SearchParamsKeys.TASK_ID_PATTERN); + } - const handleResetFilters = useCallback(() => { - visibleFilters.forEach((filter) => { - searchParams.delete(filter.key); - }); - setTableURLState({ - pagination: { ...pagination, pageIndex: 0 }, - sorting, - }); - setSearchParams(searchParams); - setResetKey((prev) => prev + 1); - }, [pagination, searchParams, setSearchParams, setTableURLState, sorting, visibleFilters]); + if (mapIndex === "-1") { + keys.push(SearchParamsKeys.MAP_INDEX); + } - const renderFilterInput = (filter: (typeof FILTERS)[number]) => { - const { key, translationKey, type } = filter; + return keys; + }, [dagId, mapIndex, runId, taskId]); - return ( - - - {type !== "search" && {translate(`common:filters.${translationKey}`)}} - - {type === "search" ? ( - (() => { - const { hotkeyDisabled } = filter; + const { filterConfigs, handleFiltersChange, searchParams } = useFiltersHandler(searchParamKeys); + + const initialValues = useMemo(() => { + const values: Record = {}; + + filterConfigs.forEach((config) => { + const value = searchParams.get(config.key); + + if (value !== null && value !== "") { + if (config.type === "number") { + const parsedValue = Number(value); + + values[config.key] = isNaN(parsedValue) ? value : parsedValue; + } else { + values[config.key] = value; + } + } + }); - return ( - - ); - })() - ) : type === "datetime" ? ( - handleFilterChange(key)(event.target.value)} - value={searchParams.get(key) ?? ""} - /> - ) : ( - handleFilterChange(key)(details.value)} - value={searchParams.get(key) ?? ""} - > - - - )} - - ); - }; + return values; + }, [searchParams, filterConfigs]); return ( - - {visibleFilters.map(renderFilterInput)} - - -   - - {filterCount > 0 && ( - - )} - - + ); }; diff --git a/airflow-core/src/airflow/ui/src/queries/useClearTaskInstances.ts b/airflow-core/src/airflow/ui/src/queries/useClearTaskInstances.ts index ed3431bba08e3..b20dae1075f07 100644 --- a/airflow-core/src/airflow/ui/src/queries/useClearTaskInstances.ts +++ b/airflow-core/src/airflow/ui/src/queries/useClearTaskInstances.ts @@ -26,6 +26,7 @@ import { useTaskInstanceServicePostClearTaskInstances, UseGridServiceGetGridRunsKeyFn, UseGridServiceGetGridTiSummariesKeyFn, + useGridServiceGetGridTiSummariesKey, } from "openapi/queries"; import type { ClearTaskInstancesBody, TaskInstanceCollectionResponse } from "openapi/requests/types.gen"; import { toaster } from "src/components/ui"; @@ -78,6 +79,10 @@ export const useClearTaskInstances = ({ ), ]; + // Check if this clear operation affects multiple DAG runs + const { include_future: includeFuture, include_past: includePast } = variables.requestBody; + const affectsMultipleRuns = includeFuture === true || includePast === true; + const queryKeys = [ ...taskInstanceKeys, UseDagRunServiceGetDagRunKeyFn({ dagId, dagRunId }), @@ -85,7 +90,9 @@ export const useClearTaskInstances = ({ [useClearTaskInstancesDryRunKey, dagId], [usePatchTaskInstanceDryRunKey, dagId, dagRunId], UseGridServiceGetGridRunsKeyFn({ dagId }, [{ dagId }]), - UseGridServiceGetGridTiSummariesKeyFn({ dagId, runId: dagRunId }, [{ dagId, runId: dagRunId }]), + affectsMultipleRuns + ? [useGridServiceGetGridTiSummariesKey, { dagId }] + : UseGridServiceGetGridTiSummariesKeyFn({ dagId, runId: dagRunId }), ]; await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); diff --git a/airflow-core/src/airflow/ui/src/queries/useDeleteDagRun.ts b/airflow-core/src/airflow/ui/src/queries/useDeleteDagRun.ts index 9535d31ae4831..c5c7532055105 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDeleteDagRun.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDeleteDagRun.ts @@ -24,7 +24,7 @@ import { useDagRunServiceGetDagRunsKey, UseDagRunServiceGetDagRunKeyFn, useTaskInstanceServiceGetTaskInstancesKey, - useHumanInTheLoopServiceGetHitlDetailsKey, + useTaskInstanceServiceGetHitlDetailsKey, } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -51,7 +51,7 @@ export const useDeleteDagRun = ({ dagId, dagRunId, onSuccessConfirm }: DeleteDag UseDagRunServiceGetDagRunKeyFn({ dagId, dagRunId }), [useDagRunServiceGetDagRunsKey], [useTaskInstanceServiceGetTaskInstancesKey], - [useHumanInTheLoopServiceGetHitlDetailsKey], + [useTaskInstanceServiceGetHitlDetailsKey], ]; await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); diff --git a/airflow-core/src/airflow/ui/src/queries/useDeleteTaskInstance.ts b/airflow-core/src/airflow/ui/src/queries/useDeleteTaskInstance.ts index 1ea27d22186ca..545168280e169 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDeleteTaskInstance.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDeleteTaskInstance.ts @@ -26,7 +26,7 @@ import { useDagRunServiceGetDagRunsKey, UseDagRunServiceGetDagRunKeyFn, UseGridServiceGetGridTiSummariesKeyFn, - useHumanInTheLoopServiceGetHitlDetailsKey, + useTaskInstanceServiceGetHitlDetailsKey, } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -63,7 +63,7 @@ export const useDeleteTaskInstance = ({ [useDagRunServiceGetDagRunsKey], [useTaskInstanceServiceGetTaskInstancesKey], [useTaskInstanceServiceGetTaskInstanceKey, { dagId, dagRunId, mapIndex, taskId }], - [useHumanInTheLoopServiceGetHitlDetailsKey], + [useTaskInstanceServiceGetHitlDetailsKey], ]; await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); diff --git a/airflow-core/src/airflow/ui/src/queries/useGridRuns.ts b/airflow-core/src/airflow/ui/src/queries/useGridRuns.ts index af077b7b1affb..90b31563f9432 100644 --- a/airflow-core/src/airflow/ui/src/queries/useGridRuns.ts +++ b/airflow-core/src/airflow/ui/src/queries/useGridRuns.ts @@ -33,7 +33,7 @@ export const useGridRuns = ({ }) => { const { dagId = "" } = useParams(); - const defaultRefetchInterval = useAutoRefresh({ dagId }); + const refetchInterval = useAutoRefresh({ dagId }); const { data: GridRuns, ...rest } = useGridServiceGetGridRuns( { @@ -47,7 +47,7 @@ export const useGridRuns = ({ { placeholderData: (prev) => prev, refetchInterval: (query) => - query.state.data?.some((run) => isStatePending(run.state)) && defaultRefetchInterval, + query.state.data?.some((run) => isStatePending(run.state)) && refetchInterval, }, ); diff --git a/airflow-core/src/airflow/ui/src/queries/useGridStructure.ts b/airflow-core/src/airflow/ui/src/queries/useGridStructure.ts index f312b028e6739..a6b7f99fdf935 100644 --- a/airflow-core/src/airflow/ui/src/queries/useGridStructure.ts +++ b/airflow-core/src/airflow/ui/src/queries/useGridStructure.ts @@ -23,7 +23,7 @@ import type { DagRunType } from "openapi/requests/types.gen"; import { useAutoRefresh } from "src/utils"; export const useGridStructure = ({ - hasActiveRun = undefined, + hasActiveRun, limit, runType, triggeringUser, @@ -47,7 +47,6 @@ export const useGridStructure = ({ }, undefined, { - placeholderData: (prev) => prev, refetchInterval: hasActiveRun ? refetchInterval : false, }, ); diff --git a/airflow-core/src/airflow/ui/src/queries/useGridTISummaries.ts b/airflow-core/src/airflow/ui/src/queries/useGridTISummaries.ts index 877719a0ab78c..51f07ce99e50b 100644 --- a/airflow-core/src/airflow/ui/src/queries/useGridTISummaries.ts +++ b/airflow-core/src/airflow/ui/src/queries/useGridTISummaries.ts @@ -22,10 +22,12 @@ import { isStatePending, useAutoRefresh } from "src/utils"; export const useGridTiSummaries = ({ dagId, + enabled, runId, state, }: { dagId: string; + enabled?: boolean; runId: string; state?: TaskInstanceState | null | undefined; }) => { @@ -38,7 +40,7 @@ export const useGridTiSummaries = ({ }, undefined, { - enabled: Boolean(runId) && Boolean(dagId), + enabled: Boolean(runId) && Boolean(dagId) && enabled, placeholderData: (prev) => prev, refetchInterval: (query) => ((state !== undefined && isStatePending(state)) || diff --git a/airflow-core/src/airflow/ui/src/queries/usePatchTaskInstance.ts b/airflow-core/src/airflow/ui/src/queries/usePatchTaskInstance.ts index bc2747b1a575b..c1ae88cacb166 100644 --- a/airflow-core/src/airflow/ui/src/queries/usePatchTaskInstance.ts +++ b/airflow-core/src/airflow/ui/src/queries/usePatchTaskInstance.ts @@ -26,6 +26,7 @@ import { useTaskInstanceServicePatchTaskInstance, UseGridServiceGetGridRunsKeyFn, UseGridServiceGetGridTiSummariesKeyFn, + useGridServiceGetGridTiSummariesKey, } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -58,7 +59,19 @@ export const usePatchTaskInstance = ({ }); }; - const onSuccessFn = async () => { + const onSuccessFn = async ( + _: unknown, + variables: { + dagId: string; + dagRunId: string; + requestBody: { include_future?: boolean; include_past?: boolean }; + taskId: string; + }, + ) => { + // Check if this patch operation affects multiple DAG runs + const { include_future: includeFuture, include_past: includePast } = variables.requestBody; + const affectsMultipleRuns = includeFuture === true || includePast === true; + const queryKeys = [ UseTaskInstanceServiceGetTaskInstanceKeyFn({ dagId, dagRunId, taskId }), UseTaskInstanceServiceGetMappedTaskInstanceKeyFn({ dagId, dagRunId, mapIndex, taskId }), @@ -66,7 +79,9 @@ export const usePatchTaskInstance = ({ [usePatchTaskInstanceDryRunKey, dagId, dagRunId, { mapIndex, taskId }], [useClearTaskInstancesDryRunKey, dagId], UseGridServiceGetGridRunsKeyFn({ dagId }, [{ dagId }]), - UseGridServiceGetGridTiSummariesKeyFn({ dagId, runId: dagRunId }, [{ dagId, runId: dagRunId }]), + affectsMultipleRuns + ? [useGridServiceGetGridTiSummariesKey, { dagId }] + : UseGridServiceGetGridTiSummariesKeyFn({ dagId, runId: dagRunId }), ]; await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); diff --git a/airflow-core/src/airflow/ui/src/queries/useUpdateHITLDetail.ts b/airflow-core/src/airflow/ui/src/queries/useUpdateHITLDetail.ts index 03d3246cc6ba2..f9dca74b2818b 100644 --- a/airflow-core/src/airflow/ui/src/queries/useUpdateHITLDetail.ts +++ b/airflow-core/src/airflow/ui/src/queries/useUpdateHITLDetail.ts @@ -23,9 +23,9 @@ import { useTranslation } from "react-i18next"; import { UseDagRunServiceGetDagRunKeyFn, useDagRunServiceGetDagRunsKey, - useHumanInTheLoopServiceGetHitlDetailsKey, - useHumanInTheLoopServiceGetHitlDetailKey, - useHumanInTheLoopServiceUpdateHitlDetail, + useTaskInstanceServiceGetHitlDetailsKey, + useTaskInstanceServiceGetHitlDetailKey, + useTaskInstanceServiceUpdateHitlDetail, useTaskInstanceServiceGetTaskInstanceKey, useTaskInstanceServiceGetTaskInstancesKey, } from "openapi/queries"; @@ -52,8 +52,8 @@ export const useUpdateHITLDetail = ({ [useDagRunServiceGetDagRunsKey], [useTaskInstanceServiceGetTaskInstancesKey, { dagId, dagRunId }], [useTaskInstanceServiceGetTaskInstanceKey, { dagId, dagRunId, mapIndex, taskId }], - [useHumanInTheLoopServiceGetHitlDetailsKey, { dagIdPattern: dagId, dagRunId }], - [useHumanInTheLoopServiceGetHitlDetailKey, { dagId, dagRunId }], + [useTaskInstanceServiceGetHitlDetailsKey, { dagIdPattern: dagId, dagRunId }], + [useTaskInstanceServiceGetHitlDetailKey, { dagId, dagRunId }], ]; await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); @@ -72,7 +72,7 @@ export const useUpdateHITLDetail = ({ }); }; - const { isPending, mutate } = useHumanInTheLoopServiceUpdateHitlDetail({ + const { isPending, mutate } = useTaskInstanceServiceUpdateHitlDetail({ onError, onSuccess, }); @@ -82,7 +82,7 @@ export const useUpdateHITLDetail = ({ mutate({ dagId, dagRunId, - mapIndex, + mapIndex: mapIndex ?? -1, requestBody: { chosen_options: updateHITLResponseRequestBody.chosen_options ?? [], params_input: updateHITLResponseRequestBody.params_input ?? {}, diff --git a/airflow-core/src/airflow/ui/src/queryClient.ts b/airflow-core/src/airflow/ui/src/queryClient.ts index f090a7c7939c0..7ebc52c55d5ea 100644 --- a/airflow-core/src/airflow/ui/src/queryClient.ts +++ b/airflow-core/src/airflow/ui/src/queryClient.ts @@ -26,18 +26,29 @@ if (OpenAPI.BASE.endsWith("/")) { OpenAPI.BASE = OpenAPI.BASE.slice(0, -1); } +const RETRY_COUNT = 3; + +const retryFunction = (failureCount: number, error: unknown) => { + const { status } = error as { status?: number }; + + // Do not retry for client errors (4xx). 429 should be eventually retried though. + if (status !== undefined && status >= 400 && status < 500 && status !== 429) { + return false; + } + + return failureCount < RETRY_COUNT; +}; + export const client = new QueryClient({ defaultOptions: { mutations: { - retry: 1, - retryDelay: 500, + retry: retryFunction, }, queries: { initialDataUpdatedAt: new Date().setMinutes(-6), // make sure initial data is already expired refetchOnMount: true, // Refetches stale queries, not "always" refetchOnWindowFocus: false, - retry: 1, - retryDelay: 500, + retry: retryFunction, staleTime: 5 * 60 * 1000, // 5 minutes }, }, diff --git a/airflow-core/src/airflow/ui/src/router.tsx b/airflow-core/src/airflow/ui/src/router.tsx index 24003542b0d62..052096eaa1d5f 100644 --- a/airflow-core/src/airflow/ui/src/router.tsx +++ b/airflow-core/src/airflow/ui/src/router.tsx @@ -65,7 +65,7 @@ import { client } from "./queryClient"; const pluginRoute = { element: , - path: "plugin/:page", + path: "plugin/:page/*", }; export const taskInstanceRoutes = [ diff --git a/airflow-core/src/airflow/ui/src/theme.ts b/airflow-core/src/airflow/ui/src/theme.ts index 88bac3fd19299..bd8206c11d338 100644 --- a/airflow-core/src/airflow/ui/src/theme.ts +++ b/airflow-core/src/airflow/ui/src/theme.ts @@ -18,7 +18,10 @@ */ /* eslint-disable perfectionist/sort-objects */ + +/* eslint-disable max-lines */ import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"; +import type { CSSProperties } from "react"; const generateSemanticTokens = (color: string, darkContrast: string = "white") => ({ solid: { value: `{colors.${color}.600}` }, @@ -30,147 +33,394 @@ const generateSemanticTokens = (color: string, darkContrast: string = "white") = focusRing: { value: { _light: `{colors.${color}.800}`, _dark: `{colors.${color}.200}` } }, }); -const customConfig = defineConfig({ +export const customConfig = defineConfig({ + // See https://chakra-ui.com/docs/theming/colors for more information on the colors used here. theme: { tokens: { colors: { - // Default green was too light - success: { - "50": { value: "#E0FFE0" }, - "100": { value: "#C2FFC2" }, - "200": { value: "#80FF80" }, - "300": { value: "#42FF42" }, - "400": { value: "#22C55E" }, - "500": { value: "#16A34A" }, - "600": { value: "#008000" }, - "700": { value: "#006100" }, - "800": { value: "#004200" }, - "900": { value: "#001F00" }, - "950": { value: "#000F00" }, - }, - failed: defaultConfig.theme?.tokens?.colors?.red ?? {}, - // Default gray was too dark - queued: { - "50": { value: "#F5F5F5" }, - "100": { value: "#EBEBEB" }, - "200": { value: "#D4D4D4" }, - "300": { value: "#BFBFBF" }, - "400": { value: "#ABABAB" }, - "500": { value: "#969696" }, - "600": { value: "#808080" }, - "700": { value: "#616161" }, - "800": { value: "#404040" }, - "900": { value: "#212121" }, - "950": { value: "#0F0F0F" }, - }, - skipped: defaultConfig.theme?.tokens?.colors?.pink ?? {}, - up_for_reschedule: defaultConfig.theme?.tokens?.colors?.cyan ?? {}, - up_for_retry: defaultConfig.theme?.tokens?.colors?.yellow ?? {}, - upstream_failed: defaultConfig.theme?.tokens?.colors?.orange ?? {}, - // lime - running: { - "50": { value: "#EFFBEF" }, - "100": { value: "#DEF7DE" }, - "200": { value: "#B9EEB9" }, - "300": { value: "#98E698" }, - "400": { value: "#78DE78" }, - "500": { value: "#53D553" }, - "600": { value: "#32CD32" }, - "700": { value: "#269C26" }, - "800": { value: "#196719" }, - "900": { value: "#0D350D" }, - "950": { value: "#061906" }, - }, - // violet - restarting: { - "50": { value: "#F6EBFF" }, - "100": { value: "#EDD6FF" }, - "200": { value: "#D9A8FF" }, - "300": { value: "#C880FF" }, - "400": { value: "#B657FF" }, - "500": { value: "#A229FF" }, - "600": { value: "#8F00FF" }, - "700": { value: "#6E00C2" }, - "800": { value: "#480080" }, - "900": { value: "#260042" }, - "950": { value: "#11001F" }, - }, - // mediumpurple - deferred: { - "50": { value: "#F6F3FC" }, - "100": { value: "#EDE7F9" }, - "200": { value: "#DACEF3" }, - "300": { value: "#C8B6ED" }, - "400": { value: "#B9A1E7" }, - "500": { value: "#A689E1" }, - "600": { value: "#9370DB" }, - "700": { value: "#6432C8" }, - "800": { value: "#412182" }, - "900": { value: "#211041" }, - "950": { value: "#100821" }, - }, - // tan - scheduled: { - "50": { value: "#FBF8F4" }, - "100": { value: "#F8F3ED" }, - "200": { value: "#F1E7DA" }, - "300": { value: "#E8D9C4" }, - "400": { value: "#E1CDB2" }, - "500": { value: "#DAC1A0" }, - "600": { value: "#D2B48C" }, - "700": { value: "#B9894B" }, - "800": { value: "#7D5C31" }, - "900": { value: "#3E2E18" }, - "950": { value: "#21180D" }, - }, - // lightblue - none: { - "50": { value: "#F7FBFD" }, - "100": { value: "#F3F9FB" }, - "200": { value: "#E4F2F7" }, - "300": { value: "#D8ECF3" }, - "400": { value: "#C8E5EE" }, - "500": { value: "#BDDFEB" }, - "600": { value: "#ADD8E6" }, - "700": { value: "#5FB2CE" }, - "800": { value: "#30819C" }, - "900": { value: "#18414E" }, - "950": { value: "#0C2027" }, - }, - // lightgrey - removed: { - "50": { value: "#FCFCFC" }, - "100": { value: "#F7F7F7" }, - "200": { value: "#F0F0F0" }, - "300": { value: "#E8E8E8" }, - "400": { value: "#E0E0E0" }, - "500": { value: "#DBDBDB" }, - "600": { value: "#D3D3D3" }, - "700": { value: "#9E9E9E" }, - "800": { value: "#696969" }, - "900": { value: "#363636" }, - "950": { value: "#1A1A1A" }, + black: { value: "oklch(0.23185 0.0323 266.44)" }, // Custom value for dark mode + brand: { + "50": { value: "oklch(0.98 0.006 248.717)" }, + "100": { value: "oklch(0.962 0.012 249.460)" }, + "200": { value: "oklch(0.923 0.023 255.082)" }, + "300": { value: "oklch(0.865 0.039 252.420)" }, + "400": { value: "oklch(0.705 0.066 256.378)" }, + "500": { value: "oklch(0.575 0.08 257.759)" }, + "600": { value: "oklch(0.469 0.084 257.657)" }, + "700": { value: "oklch(0.399 0.084 257.850)" }, + "800": { value: "oklch(0.324 0.072 260.329)" }, + "900": { value: "oklch(0.259 0.062 265.566)" }, + "950": { value: "oklch(0.179 0.05 265.487)" }, + }, + gray: { + // Values modified from original Tailwind to improve contrast in Chakra UI + "50": { value: "oklch(0.985 0.004 253)" }, // Original: oklch(0.985 0.002 247.839) + "100": { value: "oklch(0.955 0.006 253)" }, // Original: oklch(0.967 0.003 264.542) + "200": { value: "oklch(0.915 0.01 253)" }, // Original: oklch(0.928 0.006 264.531) + "300": { value: "oklch(0.85 0.016 253)" }, // Original: oklch(0.872 0.01 258.338) + "400": { value: "oklch(0.75 0.025 252)" }, // Original: oklch(0.707 0.022 261.325) + "500": { value: "oklch(0.63 0.042 252)" }, // Original: oklch(0.551 0.027 264.364) + "600": { value: "oklch(0.45 0.055 251)" }, // Original: oklch(0.446 0.03 256.802) + "700": { value: "oklch(0.35 0.045 251)" }, // Original: oklch(0.373 0.034 259.733) + "800": { value: "oklch(0.28 0.035 251)" }, // Original: oklch(0.278 0.033 256.848) + "900": { value: "oklch(0.18 0.03 251)" }, // Original: oklch(0.21 0.034 264.665) + "950": { value: "oklch(0.11 0.025 251)" }, // Original: oklch(0.13 0.028 261.692) + }, + // TAILWIND 4.0 COLORS + // See https://tailwindcss.com/docs/colors for more information on the colors used here. + red: { + "50": { value: "oklch(0.971 0.013 17.38)" }, + "100": { value: "oklch(0.936 0.032 17.717)" }, + "200": { value: "oklch(0.885 0.062 18.334)" }, + "300": { value: "oklch(0.808 0.114 19.571)" }, + "400": { value: "oklch(0.704 0.191 22.216)" }, + "500": { value: "oklch(0.637 0.237 25.331)" }, + "600": { value: "oklch(0.577 0.245 27.325)" }, + "700": { value: "oklch(0.505 0.213 27.518)" }, + "800": { value: "oklch(0.444 0.177 26.899)" }, + "900": { value: "oklch(0.396 0.141 25.723)" }, + "950": { value: "oklch(0.258 0.092 26.042)" }, + }, + // Values modified from original Tailwind to improve contrast in Chakra UI + orange: { + "50": { value: "oklch(0.982 0.013 83.915)" }, + "100": { value: "oklch(0.961 0.033 82.320)" }, + "200": { value: "oklch(0.918 0.065 79.975)" }, + "300": { value: "oklch(0.857 0.118 76.815)" }, + "400": { value: "oklch(0.7492 0.1439 62.081)" }, // Original: oklch(0.774 0.186 71.555) + "500": { value: "oklch(0.6462 0.1979 43.792)" }, // Original: oklch(0.705 0.213 47.604) + "600": { value: "oklch(0.5902 0.198 35.93)" }, // Original: oklch(0.632 0.214 41.185) + "700": { value: "oklch(0.553 0.184 41.777)" }, + "800": { value: "oklch(0.469 0.144 45.164)" }, + "900": { value: "oklch(0.414 0.110 48.717)" }, + "950": { value: "oklch(0.271 0.069 52.345)" }, + }, + amber: { + "50": { value: "oklch(0.987 0.022 95.277)" }, + "100": { value: "oklch(0.962 0.059 95.617)" }, + "200": { value: "oklch(0.924 0.12 95.746)" }, + "300": { value: "oklch(0.879 0.169 91.605)" }, + "400": { value: "oklch(0.828 0.189 84.429)" }, + "500": { value: "oklch(0.769 0.188 70.08)" }, + "600": { value: "oklch(0.666 0.179 58.318)" }, + "700": { value: "oklch(0.555 0.163 48.998)" }, + "800": { value: "oklch(0.473 0.137 46.201)" }, + "900": { value: "oklch(0.414 0.112 45.904)" }, + "950": { value: "oklch(0.279 0.077 45.635)" }, + }, + yellow: { + "50": { value: "oklch(0.987 0.026 102.212)" }, + "100": { value: "oklch(0.973 0.071 103.193)" }, + "200": { value: "oklch(0.945 0.129 101.54)" }, + "300": { value: "oklch(0.905 0.182 98.111)" }, + "400": { value: "oklch(0.852 0.199 91.936)" }, + "500": { value: "oklch(0.795 0.184 86.047)" }, + "600": { value: "oklch(0.681 0.162 75.834)" }, + "700": { value: "oklch(0.554 0.135 66.442)" }, + "800": { value: "oklch(0.476 0.114 61.907)" }, + "900": { value: "oklch(0.421 0.095 57.708)" }, + "950": { value: "oklch(0.286 0.066 53.813)" }, + }, + lime: { + "50": { value: "oklch(0.986 0.031 120.757)" }, + "100": { value: "oklch(0.967 0.067 122.328)" }, + "200": { value: "oklch(0.938 0.127 124.321)" }, + "300": { value: "oklch(0.897 0.196 126.665)" }, + "400": { value: "oklch(0.841 0.238 128.85)" }, + "500": { value: "oklch(0.768 0.233 130.85)" }, + "600": { value: "oklch(0.648 0.2 131.684)" }, + "700": { value: "oklch(0.532 0.157 131.589)" }, + "800": { value: "oklch(0.453 0.124 130.933)" }, + "900": { value: "oklch(0.405 0.101 131.063)" }, + "950": { value: "oklch(0.274 0.072 132.109)" }, + }, + green: { + // Values modified from original Tailwind to improve contrast in Chakra UI + "50": { value: "oklch(0.982 0.018 155.826)" }, + "100": { value: "oklch(0.962 0.044 156.743)" }, + "200": { value: "oklch(0.925 0.084 155.995)" }, + "300": { value: "oklch(0.75 0.18 153.0)" }, // Original: oklch(0.871 0.15 154.449) + "400": { value: "oklch(0.625 0.209 150.0)" }, // Original: oklch(0.792 0.209 151.711) + "500": { value: "oklch(0.528 0.219 149.579)" }, // Original: oklch(0.723 0.219 149.579) + "600": { value: "oklch(0.47 0.20 149.0)" }, // Original: oklch(0.627 0.194 149.214) + "700": { value: "oklch(0.40 0.16 149.5)" }, // Original: oklch(0.527 0.154 150.069) + "800": { value: "oklch(0.448 0.119 151.328)" }, + "900": { value: "oklch(0.393 0.095 152.535)" }, + "950": { value: "oklch(0.266 0.065 152.934)" }, + }, + emerald: { + "50": { value: "oklch(0.979 0.021 166.113)" }, + "100": { value: "oklch(0.95 0.052 163.051)" }, + "200": { value: "oklch(0.905 0.093 164.15)" }, + "300": { value: "oklch(0.845 0.143 164.978)" }, + "400": { value: "oklch(0.765 0.177 163.223)" }, + "500": { value: "oklch(0.696 0.17 162.48)" }, + "600": { value: "oklch(0.596 0.145 163.225)" }, + "700": { value: "oklch(0.508 0.118 165.612)" }, + "800": { value: "oklch(0.432 0.095 166.913)" }, + "900": { value: "oklch(0.378 0.077 168.94)" }, + "950": { value: "oklch(0.262 0.051 172.552)" }, + }, + teal: { + "50": { value: "oklch(0.984 0.014 180.72)" }, + "100": { value: "oklch(0.953 0.051 180.801)" }, + "200": { value: "oklch(0.91 0.096 180.426)" }, + "300": { value: "oklch(0.855 0.138 181.071)" }, + "400": { value: "oklch(0.777 0.152 181.912)" }, + "500": { value: "oklch(0.704 0.14 182.503)" }, + "600": { value: "oklch(0.6 0.118 184.704)" }, + "700": { value: "oklch(0.511 0.096 186.391)" }, + "800": { value: "oklch(0.437 0.078 188.216)" }, + "900": { value: "oklch(0.386 0.063 188.416)" }, + "950": { value: "oklch(0.277 0.046 192.524)" }, + }, + cyan: { + "50": { value: "oklch(0.984 0.019 200.873)" }, + "100": { value: "oklch(0.956 0.045 203.388)" }, + "200": { value: "oklch(0.917 0.08 205.041)" }, + "300": { value: "oklch(0.865 0.127 207.078)" }, + "400": { value: "oklch(0.789 0.154 211.53)" }, + "500": { value: "oklch(0.715 0.143 215.221)" }, + "600": { value: "oklch(0.609 0.126 221.723)" }, + "700": { value: "oklch(0.52 0.105 223.128)" }, + "800": { value: "oklch(0.45 0.085 224.283)" }, + "900": { value: "oklch(0.398 0.07 227.392)" }, + "950": { value: "oklch(0.302 0.056 229.695)" }, + }, + sky: { + "50": { value: "oklch(0.977 0.013 236.62)" }, + "100": { value: "oklch(0.951 0.026 236.824)" }, + "200": { value: "oklch(0.901 0.058 230.902)" }, + "300": { value: "oklch(0.828 0.111 230.318)" }, + "400": { value: "oklch(0.746 0.16 232.661)" }, + "500": { value: "oklch(0.685 0.169 237.323)" }, + "600": { value: "oklch(0.588 0.158 241.966)" }, + "700": { value: "oklch(0.5 0.134 242.749)" }, + "800": { value: "oklch(0.443 0.11 240.79)" }, + "900": { value: "oklch(0.391 0.09 240.876)" }, + "950": { value: "oklch(0.293 0.066 243.157)" }, + }, + blue: { + "50": { value: "oklch(0.97 0.014 254.604)" }, + "100": { value: "oklch(0.932 0.032 255.585)" }, + "200": { value: "oklch(0.882 0.059 254.128)" }, + "300": { value: "oklch(0.809 0.105 251.813)" }, + "400": { value: "oklch(0.707 0.165 254.624)" }, + "500": { value: "oklch(0.623 0.214 259.815)" }, + "600": { value: "oklch(0.546 0.245 262.881)" }, + "700": { value: "oklch(0.488 0.243 264.376)" }, + "800": { value: "oklch(0.424 0.199 265.638)" }, + "900": { value: "oklch(0.379 0.146 265.522)" }, + "950": { value: "oklch(0.282 0.091 267.935)" }, + }, + indigo: { + "50": { value: "oklch(0.962 0.018 272.314)" }, + "100": { value: "oklch(0.93 0.034 272.788)" }, + "200": { value: "oklch(0.87 0.065 274.039)" }, + "300": { value: "oklch(0.785 0.115 274.713)" }, + "400": { value: "oklch(0.673 0.182 276.935)" }, + "500": { value: "oklch(0.585 0.233 277.117)" }, + "600": { value: "oklch(0.511 0.262 276.966)" }, + "700": { value: "oklch(0.457 0.24 277.023)" }, + "800": { value: "oklch(0.398 0.195 277.366)" }, + "900": { value: "oklch(0.359 0.144 278.697)" }, + "950": { value: "oklch(0.257 0.09 281.288)" }, + }, + violet: { + "50": { value: "oklch(0.969 0.016 293.756)" }, + "100": { value: "oklch(0.943 0.029 294.588)" }, + "200": { value: "oklch(0.894 0.057 293.283)" }, + "300": { value: "oklch(0.811 0.111 293.571)" }, + "400": { value: "oklch(0.702 0.183 293.541)" }, + "500": { value: "oklch(0.606 0.25 292.717)" }, + "600": { value: "oklch(0.541 0.281 293.009)" }, + "700": { value: "oklch(0.491 0.27 292.581)" }, + "800": { value: "oklch(0.432 0.232 292.759)" }, + "900": { value: "oklch(0.38 0.189 293.745)" }, + "950": { value: "oklch(0.283 0.141 291.089)" }, + }, + purple: { + "50": { value: "oklch(0.977 0.014 308.299)" }, + "100": { value: "oklch(0.946 0.033 307.174)" }, + "200": { value: "oklch(0.902 0.063 306.703)" }, + "300": { value: "oklch(0.827 0.119 306.383)" }, + "400": { value: "oklch(0.714 0.203 305.504)" }, + "500": { value: "oklch(0.627 0.265 303.9)" }, + "600": { value: "oklch(0.558 0.288 302.321)" }, + "700": { value: "oklch(0.496 0.265 301.924)" }, + "800": { value: "oklch(0.438 0.218 303.724)" }, + "900": { value: "oklch(0.381 0.176 304.987)" }, + "950": { value: "oklch(0.291 0.149 302.717)" }, + }, + fuchsia: { + "50": { value: "oklch(0.977 0.017 320.058)" }, + "100": { value: "oklch(0.952 0.037 318.852)" }, + "200": { value: "oklch(0.903 0.076 319.62)" }, + "300": { value: "oklch(0.833 0.145 321.434)" }, + "400": { value: "oklch(0.74 0.238 322.16)" }, + "500": { value: "oklch(0.667 0.295 322.15)" }, + "600": { value: "oklch(0.591 0.293 322.896)" }, + "700": { value: "oklch(0.518 0.253 323.949)" }, + "800": { value: "oklch(0.452 0.211 324.591)" }, + "900": { value: "oklch(0.401 0.17 325.612)" }, + "950": { value: "oklch(0.293 0.136 325.661)" }, + }, + pink: { + "50": { value: "oklch(0.971 0.014 343.198)" }, + "100": { value: "oklch(0.948 0.028 342.258)" }, + "200": { value: "oklch(0.899 0.061 343.231)" }, + "300": { value: "oklch(0.823 0.12 346.018)" }, + "400": { value: "oklch(0.718 0.202 349.761)" }, + "500": { value: "oklch(0.656 0.241 354.308)" }, + "600": { value: "oklch(0.592 0.249 0.584)" }, + "700": { value: "oklch(0.525 0.223 3.958)" }, + "800": { value: "oklch(0.459 0.187 3.815)" }, + "900": { value: "oklch(0.408 0.153 2.432)" }, + "950": { value: "oklch(0.284 0.109 3.907)" }, + }, + rose: { + "50": { value: "oklch(0.969 0.015 12.422)" }, + "100": { value: "oklch(0.941 0.03 12.58)" }, + "200": { value: "oklch(0.892 0.058 10.001)" }, + "300": { value: "oklch(0.81 0.117 11.638)" }, + "400": { value: "oklch(0.712 0.194 13.428)" }, + "500": { value: "oklch(0.645 0.246 16.439)" }, + "600": { value: "oklch(0.586 0.253 17.585)" }, + "700": { value: "oklch(0.514 0.222 16.935)" }, + "800": { value: "oklch(0.455 0.188 13.697)" }, + "900": { value: "oklch(0.41 0.159 10.272)" }, + "950": { value: "oklch(0.271 0.105 12.094)" }, + }, + slate: { + "50": { value: "oklch(0.984 0.003 247.858)" }, + "100": { value: "oklch(0.968 0.007 247.896)" }, + "200": { value: "oklch(0.929 0.013 255.508)" }, + "300": { value: "oklch(0.869 0.022 252.894)" }, + "400": { value: "oklch(0.704 0.04 256.788)" }, + "500": { value: "oklch(0.554 0.046 257.417)" }, + "600": { value: "oklch(0.446 0.043 257.281)" }, + "700": { value: "oklch(0.372 0.044 257.287)" }, + "800": { value: "oklch(0.279 0.041 260.031)" }, + "900": { value: "oklch(0.208 0.042 265.755)" }, + "950": { value: "oklch(0.129 0.042 264.695)" }, + }, + zinc: { + "50": { value: "oklch(0.985 0 0)" }, + "100": { value: "oklch(0.967 0.001 286.375)" }, + "200": { value: "oklch(0.92 0.004 286.32)" }, + "300": { value: "oklch(0.871 0.006 286.286)" }, + "400": { value: "oklch(0.705 0.015 286.067)" }, + "500": { value: "oklch(0.552 0.016 285.938)" }, + "600": { value: "oklch(0.442 0.017 285.786)" }, + "700": { value: "oklch(0.37 0.013 285.805)" }, + "800": { value: "oklch(0.274 0.006 286.033)" }, + "900": { value: "oklch(0.21 0.006 285.885)" }, + "950": { value: "oklch(0.141 0.005 285.823)" }, + }, + neutral: { + "50": { value: "oklch(0.985 0 0)" }, + "100": { value: "oklch(0.97 0 0)" }, + "200": { value: "oklch(0.922 0 0)" }, + "300": { value: "oklch(0.87 0 0)" }, + "400": { value: "oklch(0.708 0 0)" }, + "500": { value: "oklch(0.556 0 0)" }, + "600": { value: "oklch(0.439 0 0)" }, + "700": { value: "oklch(0.371 0 0)" }, + "800": { value: "oklch(0.269 0 0)" }, + "900": { value: "oklch(0.205 0 0)" }, + "950": { value: "oklch(0.145 0 0)" }, + }, + stone: { + "50": { value: "oklch(0.985 0.001 106.423)" }, + "100": { value: "oklch(0.97 0.001 106.424)" }, + "200": { value: "oklch(0.923 0.003 48.717)" }, + "300": { value: "oklch(0.869 0.005 56.366)" }, + "400": { value: "oklch(0.709 0.01 56.259)" }, + "500": { value: "oklch(0.553 0.013 58.071)" }, + "600": { value: "oklch(0.444 0.011 73.639)" }, + "700": { value: "oklch(0.374 0.01 67.558)" }, + "800": { value: "oklch(0.268 0.007 34.298)" }, + "900": { value: "oklch(0.216 0.006 56.043)" }, + "950": { value: "oklch(0.147 0.004 49.25)" }, }, }, }, semanticTokens: { colors: { - success: generateSemanticTokens("success"), - failed: defaultConfig.theme?.semanticTokens?.colors?.red ?? {}, - queued: generateSemanticTokens("queued"), - skipped: defaultConfig.theme?.semanticTokens?.colors?.pink ?? {}, - up_for_reschedule: defaultConfig.theme?.semanticTokens?.colors?.cyan ?? {}, - up_for_retry: defaultConfig.theme?.semanticTokens?.colors?.yellow ?? {}, - upstream_failed: defaultConfig.theme?.semanticTokens?.colors?.orange ?? {}, - running: generateSemanticTokens("running"), - restarting: generateSemanticTokens("restarting"), - deferred: generateSemanticTokens("deferred"), - scheduled: generateSemanticTokens("scheduled"), - none: generateSemanticTokens("none", "black"), - removed: generateSemanticTokens("removed", "black"), + // Brand colors for consistent theming + brand: generateSemanticTokens("brand"), + // GENERIC STATE + danger: generateSemanticTokens("red"), + info: generateSemanticTokens("blue"), + warning: generateSemanticTokens("amber"), + error: generateSemanticTokens("red"), + // AIRFLOW TASK STATE + active: generateSemanticTokens("blue"), + success: generateSemanticTokens("green"), + failed: generateSemanticTokens("red"), + queued: generateSemanticTokens("stone"), + skipped: generateSemanticTokens("pink"), + up_for_reschedule: generateSemanticTokens("sky"), + up_for_retry: generateSemanticTokens("yellow"), + upstream_failed: generateSemanticTokens("orange"), + running: generateSemanticTokens("cyan"), + restarting: generateSemanticTokens("violet"), + deferred: generateSemanticTokens("purple"), + scheduled: generateSemanticTokens("zinc"), + none: generateSemanticTokens("gray"), + removed: generateSemanticTokens("slate"), + // TAILWIND 4.0 COLORS + red: generateSemanticTokens("red"), + orange: generateSemanticTokens("orange"), + amber: generateSemanticTokens("amber"), + yellow: generateSemanticTokens("yellow"), + lime: generateSemanticTokens("lime"), + green: generateSemanticTokens("green"), + emerald: generateSemanticTokens("emerald"), + teal: generateSemanticTokens("teal"), + cyan: generateSemanticTokens("cyan"), + sky: generateSemanticTokens("sky"), + blue: generateSemanticTokens("blue"), + indigo: generateSemanticTokens("indigo"), + violet: generateSemanticTokens("violet"), + purple: generateSemanticTokens("purple"), + fuchsia: generateSemanticTokens("fuchsia"), + pink: generateSemanticTokens("pink"), + rose: generateSemanticTokens("rose"), + slate: generateSemanticTokens("slate"), + gray: generateSemanticTokens("gray"), + zinc: generateSemanticTokens("zinc"), + neutral: generateSemanticTokens("neutral"), + stone: generateSemanticTokens("stone"), }, }, }, }); export const system = createSystem(defaultConfig, customConfig); + +// Utility function to resolve CSS variables to their computed values +// See: https://github.com/chakra-ui/panda/discussions/2200 +export const getComputedCSSVariableValue = (variable: string): string => + getComputedStyle(document.documentElement) + .getPropertyValue(variable.slice(4, variable.length - 1)) + .trim(); + +// Returns ReactFlow style props using Chakra UI CSS variables +export const getReactFlowThemeStyle = (colorMode: "dark" | "light"): CSSProperties => + ({ + // Background + "--xy-background-color": + colorMode === "dark" ? "var(--chakra-colors-brand-950)" : "var(--chakra-colors-brand-50)", + "--xy-background-pattern-color": + colorMode === "dark" ? "var(--chakra-colors-gray-200)" : "var(--chakra-colors-gray-800)", + + // Controls + "--xy-controls-button-background-color": + colorMode === "dark" ? "var(--chakra-colors-gray-800)" : "var(--chakra-colors-white)", + "--xy-controls-button-background-color-hover": + colorMode === "dark" ? "var(--chakra-colors-gray-700)" : "var(--chakra-colors-gray-100)", + + // MiniMap + "--xy-minimap-background-color": "var(--chakra-colors-bg)", + }) as CSSProperties; diff --git a/airflow-core/src/airflow/ui/src/utils/AppWrapper.tsx b/airflow-core/src/airflow/ui/src/utils/AppWrapper.tsx index 5e5e1c01aa879..6e1799e8cf369 100644 --- a/airflow-core/src/airflow/ui/src/utils/AppWrapper.tsx +++ b/airflow-core/src/airflow/ui/src/utils/AppWrapper.tsx @@ -27,7 +27,13 @@ type Props = { }; export const AppWrapper = ({ initialEntries }: Props) => { - const router = createMemoryRouter(routerConfig, { basename: "/", initialEntries }); + // Strip the config loader from tests + const config = routerConfig.map((route) => ({ + ...route, + loader: undefined, + })); + + const router = createMemoryRouter(config, { basename: "/", initialEntries }); return ( diff --git a/airflow-core/src/airflow/ui/src/utils/TrimText.tsx b/airflow-core/src/airflow/ui/src/utils/TrimText.tsx index 3ae671d529a45..89d1d96719f42 100644 --- a/airflow-core/src/airflow/ui/src/utils/TrimText.tsx +++ b/airflow-core/src/airflow/ui/src/utils/TrimText.tsx @@ -90,7 +90,7 @@ export const TrimText = ({ {formattedKey}
{ - it("handles durations less than 10 seconds", () => { + it("handles durations less than 60 seconds", () => { const start = "2024-03-14T10:00:00.000Z"; - const end = "2024-03-14T10:00:05.500Z"; + const end = "2024-03-14T10:00:05.5111111Z"; - expect(getDuration(start, end)).toBe("5.50s"); + expect(getDuration(start, end)).toBe("00:00:05.511"); }); it("handles durations spanning multiple days", () => { @@ -49,8 +49,10 @@ describe("getDuration", () => { expect(getDuration(start, end)).toBe("02:30:00"); }); - it("handles null or undefined dates", () => { - expect(getDuration(null, null)).toBe("00:00:00"); - expect(getDuration(undefined, undefined)).toBe("00:00:00"); + it("handles small, null or undefined values", () => { + // eslint-disable-next-line unicorn/no-null + expect(getDuration(null, null)).toBe(undefined); + expect(getDuration(undefined, undefined)).toBe(undefined); + expect(renderDuration(0.000_01)).toBe(undefined); }); }); diff --git a/airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts b/airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts index bcc1f65731635..abd598e3debce 100644 --- a/airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts +++ b/airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts @@ -23,20 +23,20 @@ import tz from "dayjs/plugin/timezone"; dayjs.extend(dayjsDuration); dayjs.extend(tz); -export const renderDuration = (durationSeconds: number | null | undefined): string => { - if ( - durationSeconds === null || - durationSeconds === undefined || - isNaN(durationSeconds) || - durationSeconds <= 0 - ) { - return "00:00:00"; +export const DEFAULT_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss"; +export const DEFAULT_DATETIME_FORMAT_WITH_TZ = `${DEFAULT_DATETIME_FORMAT} z`; + +export const renderDuration = (durationSeconds: number | null | undefined): string | undefined => { + if (durationSeconds === null || durationSeconds === undefined || durationSeconds <= 0.01) { + return undefined; } - if (durationSeconds < 10) { - return `${durationSeconds.toFixed(2)}s`; + // If under 60 seconds, render milliseconds + if (durationSeconds < 60) { + return dayjs.duration(Number(durationSeconds.toFixed(3)), "seconds").format("HH:mm:ss.SSS"); } + // If under 1 day, render as HH:mm:ss otherwise include the number of days return durationSeconds < 86_400 ? dayjs.duration(durationSeconds, "seconds").format("HH:mm:ss") : dayjs.duration(durationSeconds, "seconds").format("D[d]HH:mm:ss"); @@ -51,7 +51,7 @@ export const getDuration = (startDate?: string | null, endDate?: string | null) export const formatDate = ( date: number | string | null | undefined, timezone: string, - format: string = "YYYY-MM-DD HH:mm:ss", + format: string = DEFAULT_DATETIME_FORMAT, ) => { if (date === null || date === undefined || !dayjs(date).isValid()) { return dayjs().tz(timezone).format(format); diff --git a/airflow-core/src/airflow/ui/src/utils/index.ts b/airflow-core/src/airflow/ui/src/utils/index.ts index d1badfb8f0033..c8d15c7cdb597 100644 --- a/airflow-core/src/airflow/ui/src/utils/index.ts +++ b/airflow-core/src/airflow/ui/src/utils/index.ts @@ -21,4 +21,5 @@ export { capitalize } from "./capitalize"; export { getDuration, renderDuration } from "./datetimeUtils"; export { getMetaKey } from "./getMetaKey"; export { useContainerWidth } from "./useContainerWidth"; +export { useFiltersHandler, type FilterableSearchParamsKeys } from "./useFiltersHandler"; export * from "./query"; diff --git a/airflow-core/src/airflow/ui/src/utils/query.ts b/airflow-core/src/airflow/ui/src/utils/query.ts index 5becaa0ac29fd..6a0b072ca5947 100644 --- a/airflow-core/src/airflow/ui/src/utils/query.ts +++ b/airflow-core/src/airflow/ui/src/utils/query.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { useDagServiceGetDagDetails } from "openapi/queries"; +import { useDagRunServiceGetDagRuns, useDagServiceGetDagDetails } from "openapi/queries"; import type { TaskInstanceState } from "openapi/requests/types.gen"; import { useConfig } from "src/queries/useConfig"; @@ -30,7 +30,14 @@ export const isStatePending = (state?: TaskInstanceState | null) => state === "restarting" || !Boolean(state); -export const useAutoRefresh = ({ dagId, isPaused }: { dagId?: string; isPaused?: boolean }) => { +// checkPendingRuns=false assumes that the component is already handling pending, setting to true will have useAutoRefresh handle it +export const useAutoRefresh = ({ + checkPendingRuns = false, + dagId, +}: { + checkPendingRuns?: boolean; + dagId?: string; +}) => { const autoRefreshInterval = useConfig("auto_refresh_interval") as number | undefined; const { data: dag } = useDagServiceGetDagDetails( { @@ -40,9 +47,28 @@ export const useAutoRefresh = ({ dagId, isPaused }: { dagId?: string; isPaused?: { enabled: dagId !== undefined }, ); - const paused = isPaused ?? dag?.is_paused; + const { data: dagRunData } = useDagRunServiceGetDagRuns( + { + dagId: dagId ?? "~", + state: ["running", "queued"], + }, + undefined, + // Scale back refetching to 10x longer if there are no pending runs (eg: every 3 secs for active runs, otherwise 30 secs) + { + enabled: checkPendingRuns, + refetchInterval: (query) => + autoRefreshInterval !== undefined && + ((query.state.data?.dag_runs ?? []).length > 0 + ? autoRefreshInterval * 1000 + : autoRefreshInterval * 10 * 1000), + }, + ); + + const pendingRuns = checkPendingRuns ? (dagRunData?.dag_runs ?? []).length >= 1 : true; + + const paused = Boolean(dagId) ? dag?.is_paused : false; - const canRefresh = autoRefreshInterval !== undefined && !paused; + const canRefresh = autoRefreshInterval !== undefined && !paused && pendingRuns; // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion return (canRefresh ? autoRefreshInterval * 1000 : false) as number | false; diff --git a/airflow-core/src/airflow/ui/src/utils/slots.tsx b/airflow-core/src/airflow/ui/src/utils/slots.tsx index 37f2b8956d92d..66a055ebc34b9 100644 --- a/airflow-core/src/airflow/ui/src/utils/slots.tsx +++ b/airflow-core/src/airflow/ui/src/utils/slots.tsx @@ -35,27 +35,27 @@ export const slotConfigs: Array = [ { key: "open_slots", color: "success", - icon: , + icon: , }, { key: "running_slots", color: "running", - icon: , + icon: , }, { key: "queued_slots", color: "queued", - icon: , + icon: , }, { key: "scheduled_slots", color: "scheduled", - icon: , + icon: , }, { key: "deferred_slots", color: "deferred", - icon: , + icon: , }, ]; diff --git a/airflow-core/src/airflow/ui/src/utils/tokenHandler.test.ts b/airflow-core/src/airflow/ui/src/utils/tokenHandler.test.ts deleted file mode 100644 index 8359bc193a1c5..0000000000000 --- a/airflow-core/src/airflow/ui/src/utils/tokenHandler.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -/*! - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import type { InternalAxiosRequestConfig } from "axios"; -import { afterEach, describe, it, vi, expect, beforeAll } from "vitest"; - -import { TOKEN_STORAGE_KEY, tokenHandler } from "./tokenHandler"; - -describe("TokenFlow Interceptor", () => { - beforeAll(() => { - Object.defineProperty(document, "cookie", { - writable: true, - }); - }); - - it("Should read from the cookie, persist to the localStorage and remove from the cookie", () => { - const token = "test-token"; - - document.cookie = `_token=${token};`; - - const setItemMock = vi.spyOn(localStorage, "setItem"); - - const headers = {}; - - const config = { headers }; - - const { headers: updatedHeaders } = tokenHandler(config as InternalAxiosRequestConfig); - - expect(setItemMock).toHaveBeenCalledOnce(); - expect(setItemMock).toHaveBeenCalledWith(TOKEN_STORAGE_KEY, token); - expect(updatedHeaders).toEqual({ Authorization: `Bearer ${token}` }); - expect(document.cookie).toContain("_token=; expires="); - }); -}); - -afterEach(() => { - vi.restoreAllMocks(); - vi.unstubAllGlobals(); -}); diff --git a/airflow-core/src/airflow/ui/src/utils/tokenHandler.ts b/airflow-core/src/airflow/ui/src/utils/tokenHandler.ts deleted file mode 100644 index 8e256ddab0c03..0000000000000 --- a/airflow-core/src/airflow/ui/src/utils/tokenHandler.ts +++ /dev/null @@ -1,51 +0,0 @@ -/*! - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import type { InternalAxiosRequestConfig } from "axios"; - -export const TOKEN_STORAGE_KEY = "token"; -const getTokenFromCookies = (): string | undefined => { - const cookies = document.cookie.split(";"); - - for (const cookie of cookies) { - const [name, token] = cookie.split("="); - - if (name?.trim() === "_token" && token !== undefined) { - localStorage.setItem(TOKEN_STORAGE_KEY, token); - document.cookie = "_token=; expires=Sat, 01 Jan 2000 00:00:00 UTC; path=/;"; - - return token; - } - } - - return undefined; -}; - -export const tokenHandler = (config: InternalAxiosRequestConfig) => { - const token = localStorage.getItem(TOKEN_STORAGE_KEY) ?? getTokenFromCookies(); - - if (token !== undefined) { - config.headers.Authorization = `Bearer ${token}`; - } - - return config; -}; - -export const clearToken = () => { - localStorage.removeItem(TOKEN_STORAGE_KEY); -}; diff --git a/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts b/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts new file mode 100644 index 0000000000000..d3543228d94eb --- /dev/null +++ b/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts @@ -0,0 +1,92 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { useCallback, useMemo } from "react"; +import { useSearchParams } from "react-router-dom"; + +import { useTableURLState } from "src/components/DataTable/useTableUrlState"; +import type { FilterValue } from "src/components/FilterBar"; +import { useFilterConfigs } from "src/constants/filterConfigs"; +import { SearchParamsKeys } from "src/constants/searchParams"; + +export type FilterableSearchParamsKeys = + | SearchParamsKeys.AFTER + | SearchParamsKeys.BEFORE + | SearchParamsKeys.DAG_DISPLAY_NAME_PATTERN + | SearchParamsKeys.DAG_ID + | SearchParamsKeys.END_DATE + | SearchParamsKeys.EVENT_TYPE + | SearchParamsKeys.KEY_PATTERN + | SearchParamsKeys.LOGICAL_DATE_GTE + | SearchParamsKeys.LOGICAL_DATE_LTE + | SearchParamsKeys.MAP_INDEX + | SearchParamsKeys.RESPONSE_RECEIVED + | SearchParamsKeys.RUN_AFTER_GTE + | SearchParamsKeys.RUN_AFTER_LTE + | SearchParamsKeys.RUN_ID + | SearchParamsKeys.RUN_ID_PATTERN + | SearchParamsKeys.START_DATE + | SearchParamsKeys.TASK_ID + | SearchParamsKeys.TASK_ID_PATTERN + | SearchParamsKeys.TRY_NUMBER + | SearchParamsKeys.USER; + +export const useFiltersHandler = (searchParamKeys: Array) => { + const { getFilterConfig } = useFilterConfigs(); + + const filterConfigs = useMemo( + () => searchParamKeys.map((key) => getFilterConfig(key)), + [searchParamKeys, getFilterConfig], + ); + const [searchParams, setSearchParams] = useSearchParams(); + const { setTableURLState, tableURLState } = useTableURLState(); + const { pagination, sorting } = tableURLState; + const handleFiltersChange = useCallback( + (filters: Record) => { + setTableURLState({ + pagination: { ...pagination, pageIndex: 0 }, + sorting, + }); + + setSearchParams((prevParams) => { + const newParams = new URLSearchParams(prevParams); + + filterConfigs.forEach((config) => { + const value = filters[config.key]; + + if (value === null || value === undefined || value === "") { + newParams.delete(config.key); + } else { + newParams.set(config.key, String(value)); + } + }); + + newParams.delete(SearchParamsKeys.OFFSET); + + return newParams; + }); + }, + [filterConfigs, pagination, setSearchParams, setTableURLState, sorting], + ); + + return { + filterConfigs, + handleFiltersChange, + searchParams, + }; +}; diff --git a/airflow-core/src/airflow/ui/src/utils/usePersistentResizableState.ts b/airflow-core/src/airflow/ui/src/utils/usePersistentResizableState.ts new file mode 100644 index 0000000000000..6ce879700870e --- /dev/null +++ b/airflow-core/src/airflow/ui/src/utils/usePersistentResizableState.ts @@ -0,0 +1,41 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { useCallback, useState } from "react"; +import { useLocalStorage } from "usehooks-ts"; + +type Size = { height: number; width: number }; + +export const usePersistentResizableState = (storageKey: string, defaultSize: Size) => { + const [storedSize, setStoredSize] = useLocalStorage(storageKey, defaultSize); + const [size, setSize] = useState(storedSize); + + const handleResize = useCallback((_event: React.SyntheticEvent, { size: newSize }: { size: Size }) => { + setSize(newSize); + }, []); + + const handleResizeStop = useCallback( + (_event: React.SyntheticEvent, { size: finalSize }: { size: Size }) => { + setSize(finalSize); + setStoredSize(finalSize); + }, + [setStoredSize], + ); + + return { handleResize, handleResizeStop, size }; +}; diff --git a/airflow-core/src/airflow/ui/testsSetup.ts b/airflow-core/src/airflow/ui/testsSetup.ts index 09dbe7bce31e3..91d3533b0aa2c 100644 --- a/airflow-core/src/airflow/ui/testsSetup.ts +++ b/airflow-core/src/airflow/ui/testsSetup.ts @@ -17,12 +17,48 @@ * under the License. */ import "@testing-library/jest-dom/vitest"; +import { cleanup } from "@testing-library/react"; import type { HttpHandler } from "msw"; import { setupServer, type SetupServerApi } from "msw/node"; -import { beforeEach, beforeAll, afterAll } from "vitest"; +import { beforeEach, beforeAll, afterAll, afterEach, vi } from "vitest"; import { handlers } from "src/mocks/handlers"; +// Mock Chart.js to prevent DOM access errors during test cleanup +vi.mock("react-chartjs-2", () => ({ + Bar: vi.fn(() => { + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment + const React = require("react"); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + return React.createElement("div", { "data-testid": "mock-chart" }); + }), + Line: vi.fn(() => { + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment + const React = require("react"); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + return React.createElement("div", { "data-testid": "mock-chart" }); + }), +})); + +// Mock Chart.js core to prevent initialization errors +vi.mock("chart.js", () => ({ + BarElement: vi.fn(), + CategoryScale: vi.fn(), + Chart: { + register: vi.fn(), + }, + Filler: vi.fn(), + Legend: vi.fn(), + LinearScale: vi.fn(), + LineElement: vi.fn(), + PointElement: vi.fn(), + TimeScale: vi.fn(), + Title: vi.fn(), + Tooltip: vi.fn(), +})); + let server: SetupServerApi; beforeAll(() => { @@ -31,4 +67,7 @@ beforeAll(() => { }); beforeEach(() => server.resetHandlers()); +afterEach(() => { + cleanup(); +}); afterAll(() => server.close()); diff --git a/airflow-core/src/airflow/utils/cli.py b/airflow-core/src/airflow/utils/cli.py index 981bbe2c5cc04..b6423c5af3a34 100644 --- a/airflow-core/src/airflow/utils/cli.py +++ b/airflow-core/src/airflow/utils/cli.py @@ -300,7 +300,7 @@ def get_bagged_dag(bundle_names: list | None, dag_id: str, dagfile_path: str | N ) -def _get_db_dag(bundle_names: list | None, dag_id: str, dagfile_path: str | None = None) -> SerializedDAG: +def get_db_dag(bundle_names: list | None, dag_id: str, dagfile_path: str | None = None) -> SerializedDAG: """ Return DAG of a given dag_id. @@ -321,7 +321,7 @@ def get_dags(bundle_names: list | None, dag_id: str, use_regex: bool = False, fr if not use_regex: if from_db: - return [_get_db_dag(bundle_names=bundle_names, dag_id=dag_id)] + return [get_db_dag(bundle_names=bundle_names, dag_id=dag_id)] return [get_bagged_dag(bundle_names=bundle_names, dag_id=dag_id)] def _find_dag(bundle): @@ -433,15 +433,26 @@ def _wrapper(*args, **kwargs): if args[0].verbose: f(*args, **kwargs) else: + from airflow._shared.logging.structlog import respect_stdlib_disable + with warnings.catch_warnings(): warnings.simplefilter("ignore") logging.disable(logging.CRITICAL) + + def drop(*_, **__): + from structlog import DropEvent + + raise DropEvent() + + old_fn = respect_stdlib_disable.__code__ + respect_stdlib_disable.__code__ = drop.__code__ try: f(*args, **kwargs) finally: # logging output again depends on the effective # levels of individual loggers logging.disable(logging.NOTSET) + respect_stdlib_disable.__code__ = old_fn return cast("T", _wrapper) diff --git a/airflow-core/src/airflow/utils/dag_edges.py b/airflow-core/src/airflow/utils/dag_edges.py index f8ed846f25532..94c6069f91b02 100644 --- a/airflow-core/src/airflow/utils/dag_edges.py +++ b/airflow-core/src/airflow/utils/dag_edges.py @@ -20,7 +20,7 @@ from airflow.models.mappedoperator import MappedOperator from airflow.sdk.definitions._internal.abstractoperator import AbstractOperator -from airflow.serialization.serialized_objects import SerializedBaseOperator +from airflow.serialization.serialized_objects import SerializedBaseOperator, SerializedDAG if TYPE_CHECKING: from collections.abc import Iterable @@ -30,7 +30,7 @@ Operator: TypeAlias = MappedOperator | SerializedBaseOperator -def dag_edges(dag: DAG): +def dag_edges(dag: DAG | SerializedDAG): """ Create the list of edges needed to construct the Graph view. diff --git a/airflow-core/src/airflow/utils/db.py b/airflow-core/src/airflow/utils/db.py index 4a6d96dbffca4..11bafc01c2595 100644 --- a/airflow-core/src/airflow/utils/db.py +++ b/airflow-core/src/airflow/utils/db.py @@ -110,7 +110,7 @@ class MappedClassProtocol(Protocol): "2.10.3": "5f2621c13b39", "3.0.0": "29ce7909c52b", "3.0.3": "fe199e1abd77", - "3.1.0": "eaf332f43c7c", + "3.1.0": "cc92b33c6709", } @@ -1255,6 +1255,14 @@ def _handle_fab_downgrade(*, session: Session) -> None: fab_version, ) return + connection = settings.engine.connect() + insp = inspect(connection) + if not fab_version and insp.has_table("ab_user"): + log.info( + "FAB migration version not found, but FAB tables exist. " + "FAB provider is not required for downgrade.", + ) + return # FAB db version is different or not found - require the FAB provider try: diff --git a/airflow-core/src/airflow/utils/db_manager.py b/airflow-core/src/airflow/utils/db_manager.py index 59f4921ce9286..995cb81c803b7 100644 --- a/airflow-core/src/airflow/utils/db_manager.py +++ b/airflow-core/src/airflow/utils/db_manager.py @@ -131,7 +131,7 @@ def upgradedb(self, to_revision=None, from_revision=None, show_sql_only=False): command.upgrade(config, revision=to_revision or "heads", sql=show_sql_only) self.log.info("Migrated the %s database", self.__class__.__name__) - def downgrade(self, to_version, from_version=None, show_sql_only=False): + def downgrade(self, to_revision, from_revision=None, show_sql_only=False): """Downgrade the database.""" raise NotImplementedError diff --git a/airflow-core/src/airflow/utils/deprecation_tools.py b/airflow-core/src/airflow/utils/deprecation_tools.py index f5562adfa6c70..dcb2d6f72d6de 100644 --- a/airflow-core/src/airflow/utils/deprecation_tools.py +++ b/airflow-core/src/airflow/utils/deprecation_tools.py @@ -23,6 +23,17 @@ from types import ModuleType +class DeprecatedImportWarning(FutureWarning): + """ + Warning class for deprecated imports in Airflow. + + This warning is raised when users import deprecated classes or functions + from Airflow modules that have been moved to better locations. + """ + + ... + + def getattr_with_deprecation( imports: dict[str, str], module: str, @@ -59,7 +70,7 @@ def getattr_with_deprecation( message = f"The `{module}.{name}` attribute is deprecated. Please use `{warning_class_name!r}`." if extra_message: message += f" {extra_message}." - warnings.warn(message, DeprecationWarning, stacklevel=2) + warnings.warn(message, DeprecatedImportWarning, stacklevel=2) # Import and return the target attribute new_module, new_class_name = target_class_full_name.rsplit(".", 1) diff --git a/airflow-core/src/airflow/utils/dot_renderer.py b/airflow-core/src/airflow/utils/dot_renderer.py index 259b4ced25204..caa5e27a2ffc1 100644 --- a/airflow-core/src/airflow/utils/dot_renderer.py +++ b/airflow-core/src/airflow/utils/dot_renderer.py @@ -28,7 +28,7 @@ from airflow.sdk import DAG, BaseOperator, TaskGroup from airflow.sdk.definitions.mappedoperator import MappedOperator from airflow.serialization.definitions.taskgroup import SerializedTaskGroup -from airflow.serialization.serialized_objects import SerializedBaseOperator +from airflow.serialization.serialized_objects import SerializedBaseOperator, SerializedDAG from airflow.utils.dag_edges import dag_edges from airflow.utils.state import State @@ -194,7 +194,7 @@ def render_dag_dependencies(deps: dict[str, list[DagDependency]]) -> graphviz.Di return dot -def render_dag(dag: DAG, tis: list[TaskInstance] | None = None) -> graphviz.Digraph: +def render_dag(dag: DAG | SerializedDAG, tis: list[TaskInstance] | None = None) -> graphviz.Digraph: """ Render the DAG object to the DOT object. diff --git a/airflow-core/src/airflow/utils/file.py b/airflow-core/src/airflow/utils/file.py index 21bd5c0511a7c..d546c0ac352d1 100644 --- a/airflow-core/src/airflow/utils/file.py +++ b/airflow-core/src/airflow/utils/file.py @@ -102,24 +102,21 @@ def compile(pattern: str, base_dir: Path, definition_file: Path) -> _IgnoreRule relative_to = definition_file.parent ignore_pattern = GitWildMatchPattern(pattern) - return _GlobIgnoreRule(ignore_pattern, relative_to) + return _GlobIgnoreRule(wild_match_pattern=ignore_pattern, relative_to=relative_to) @staticmethod def match(path: Path, rules: list[_IgnoreRule]) -> bool: - """Match a list of ignore rules against the supplied path.""" + """Match a list of ignore rules against the supplied path, accounting for exclusion rules and ordering.""" matched = False - for r in rules: - if not isinstance(r, _GlobIgnoreRule): - raise ValueError(f"_GlobIgnoreRule cannot match rules of type: {type(r)}") - rule: _GlobIgnoreRule = r # explicit typing to make mypy play nicely + for rule in rules: + if not isinstance(rule, _GlobIgnoreRule): + raise ValueError(f"_GlobIgnoreRule cannot match rules of type: {type(rule)}") rel_path = str(path.relative_to(rule.relative_to) if rule.relative_to else path.name) - matched = rule.wild_match_pattern.match_file(rel_path) is not None - - if matched: - if not rule.wild_match_pattern.include: - return False - - return matched + if ( + rule.wild_match_pattern.include is not None + and rule.wild_match_pattern.match_file(rel_path) is not None + ): + matched = rule.wild_match_pattern.include return matched diff --git a/airflow-core/src/airflow/utils/log/file_processor_handler.py b/airflow-core/src/airflow/utils/log/file_processor_handler.py index ea3151be1db92..2ef63d55c9c97 100644 --- a/airflow-core/src/airflow/utils/log/file_processor_handler.py +++ b/airflow-core/src/airflow/utils/log/file_processor_handler.py @@ -25,7 +25,7 @@ from airflow import settings from airflow._shared.timezones import timezone from airflow.utils.helpers import parse_template_string -from airflow.utils.log.logging_mixin import DISABLE_PROPOGATE +from airflow.utils.log.logging_mixin import SetContextPropagate from airflow.utils.log.non_caching_file_handler import NonCachingFileHandler logger = logging.getLogger(__name__) @@ -69,7 +69,7 @@ def set_context(self, filename): self._symlink_latest_log_directory() self._cur_date = datetime.today() - return DISABLE_PROPOGATE + return SetContextPropagate.DISABLE_PROPAGATE def emit(self, record): if self.handler is not None: diff --git a/airflow-core/src/airflow/utils/log/file_task_handler.py b/airflow-core/src/airflow/utils/log/file_task_handler.py index 3669aae122b3d..9954688a41f2b 100644 --- a/airflow-core/src/airflow/utils/log/file_task_handler.py +++ b/airflow-core/src/airflow/utils/log/file_task_handler.py @@ -741,7 +741,10 @@ def read( if try_number is None: try_number = task_instance.try_number - if try_number == 0 and task_instance.state == TaskInstanceState.SKIPPED: + if try_number == 0 and task_instance.state in ( + TaskInstanceState.SKIPPED, + TaskInstanceState.UPSTREAM_FAILED, + ): logs = [StructuredLogMessage(event="Task was skipped, no logs available.")] return chain(logs), {"end_of_log": True} diff --git a/airflow-core/src/airflow/utils/log/log_reader.py b/airflow-core/src/airflow/utils/log/log_reader.py index c1014d418620f..c238c7d4d4d09 100644 --- a/airflow-core/src/airflow/utils/log/log_reader.py +++ b/airflow-core/src/airflow/utils/log/log_reader.py @@ -17,6 +17,7 @@ from __future__ import annotations import logging +import os import time from collections.abc import Generator, Iterator from datetime import datetime, timezone @@ -25,7 +26,7 @@ from airflow.configuration import conf from airflow.utils.helpers import render_log_filename -from airflow.utils.log.file_task_handler import StructuredLogMessage +from airflow.utils.log.file_task_handler import FileTaskHandler, StructuredLogMessage from airflow.utils.log.logging_mixin import ExternalLoggingMixin from airflow.utils.session import NEW_SESSION, provide_session from airflow.utils.state import TaskInstanceState @@ -146,7 +147,8 @@ def read_log_stream( empty_iterations += 1 if empty_iterations >= self.STREAM_LOOP_STOP_AFTER_EMPTY_ITERATIONS: # we have not received any logs for a while, so we stop the stream - yield "(Log stream stopped - End of log marker not found; logs may be incomplete.)\n" + # this is emitted as json to avoid breaking the ndjson stream format + yield '{"event": "Log stream stopped - End of log marker not found; logs may be incomplete."}\n' return else: # https://mypy.readthedocs.io/en/stable/typed_dict.html#supported-operations @@ -168,6 +170,10 @@ def handlers(): yield from logging.getLogger("airflow.task").handlers yield from logging.getLogger().handlers + fallback = FileTaskHandler(os.devnull) + fallback.name = task_log_reader + yield fallback + return next((h for h in handlers() if h.name == task_log_reader), None) @property diff --git a/airflow-core/src/airflow/utils/log/logging_mixin.py b/airflow-core/src/airflow/utils/log/logging_mixin.py index 55f34d58fb7ac..2325f60449a5b 100644 --- a/airflow-core/src/airflow/utils/log/logging_mixin.py +++ b/airflow-core/src/airflow/utils/log/logging_mixin.py @@ -26,8 +26,10 @@ from logging import Handler, StreamHandler from typing import IO, TYPE_CHECKING, Any, TypeVar, cast +import structlog + if TYPE_CHECKING: - from logging import Logger + from airflow._shared.logging.types import Logger # 7-bit C1 ANSI escape sequences ANSI_ESCAPE = re.compile(r"\x1B[@-_][0-?]*[ -/]*[@-~]") @@ -67,7 +69,7 @@ def remove_escape_codes(text: str) -> str: class LoggingMixin: """Convenience super-class to have a logger configured with the class name.""" - _log: logging.Logger | None = None + _log: Logger | None = None # Parent logger used by this class. It should match one of the loggers defined in the # `logging_config_class`. By default, this attribute is used to create the final name of the logger, and @@ -111,7 +113,7 @@ def _get_log(cls, obj: Any, clazz: type[_T]) -> Logger: log_config_logger_name=obj._log_config_logger_name, class_logger_name=obj._logger_name, ) - obj._log = logging.getLogger(logger_name) + obj._log = structlog.get_logger(logger_name) return obj._log @classmethod @@ -124,9 +126,7 @@ def log(self) -> Logger: """Return a logger.""" return LoggingMixin._get_log(self, self.__class__) - def _set_context(self, context): - if context is not None: - set_context(self.log, context) + def _set_context(self, context): ... class ExternalLoggingMixin(metaclass=abc.ABCMeta): @@ -286,6 +286,10 @@ def set_context(logger, value): :param logger: logger :param value: value to set """ + if not isinstance(logger, logging.Logger): + # This fn doesn't make sense for structlog based handlers + return + while logger: orig_propagate = logger.propagate for handler in logger.handlers: diff --git a/airflow-core/src/airflow/utils/retries.py b/airflow-core/src/airflow/utils/retries.py index 4428db2a49382..a30d676685321 100644 --- a/airflow-core/src/airflow/utils/retries.py +++ b/airflow-core/src/airflow/utils/retries.py @@ -20,18 +20,21 @@ import logging from collections.abc import Callable from inspect import signature -from typing import TypeVar, overload +from typing import TYPE_CHECKING, TypeVar, overload from sqlalchemy.exc import DBAPIError from airflow.configuration import conf +if TYPE_CHECKING: + from airflow._shared.logging.types import Logger + F = TypeVar("F", bound=Callable) MAX_DB_RETRIES = conf.getint("database", "max_db_retries", fallback=3) -def run_with_db_retries(max_retries: int = MAX_DB_RETRIES, logger: logging.Logger | None = None, **kwargs): +def run_with_db_retries(max_retries: int = MAX_DB_RETRIES, logger: Logger | None = None, **kwargs): """Return Tenacity Retrying object with project specific default.""" import tenacity @@ -43,8 +46,8 @@ def run_with_db_retries(max_retries: int = MAX_DB_RETRIES, logger: logging.Logge reraise=True, **kwargs, ) - if logger and isinstance(logger, logging.Logger): - retry_kwargs["before_sleep"] = tenacity.before_sleep_log(logger, logging.DEBUG, True) + if logger is not None: + retry_kwargs["before_sleep"] = tenacity.before_sleep_log(logger, logging.DEBUG, True) # type: ignore[arg-type] return tenacity.Retrying(**retry_kwargs) diff --git a/airflow-core/src/airflow/utils/serve_logs/core.py b/airflow-core/src/airflow/utils/serve_logs/core.py index c7d15f0d24009..f7dcade8d5f1c 100644 --- a/airflow-core/src/airflow/utils/serve_logs/core.py +++ b/airflow-core/src/airflow/utils/serve_logs/core.py @@ -42,23 +42,16 @@ def serve_logs(port=None): port = port or conf.getint("logging", "WORKER_LOG_SERVER_PORT") - # If dual stack is available and IPV6_V6ONLY is not enabled on the socket - # then when IPV6 is bound to it will also bind to IPV4 automatically - if getattr(socket, "has_dualstack_ipv6", lambda: False)(): - host = "::" # ASGI uses `::` syntax for IPv6 binding instead of the `[::]` notation used in WSGI, while preserving the `[::]` format in logs + if socket.has_dualstack_ipv6(): serve_log_uri = f"http://[::]:{port}" else: - host = "0.0.0.0" - serve_log_uri = f"http://{host}:{port}" + serve_log_uri = f"http://0.0.0.0:{port}" logger.info("Starting log server on %s", serve_log_uri) # Use uvicorn directly for ASGI applications - uvicorn.run("airflow.utils.serve_logs.log_server:app", host=host, port=port, workers=2, log_level="info") - # Note: if we want to use more than 1 workers, we **can't** use the instance of FastAPI directly - # This is way we split the instantiation of log server to a separate module - # - # https://github.com/encode/uvicorn/blob/374bb6764e8d7f34abab0746857db5e3d68ecfdd/docs/deployment/index.md?plain=1#L50-L63 + uvicorn.run("airflow.utils.serve_logs.log_server:get_app", host="", port=port, log_level="info") + # Log serving is I/O bound and has low concurrency, so single process is sufficient if __name__ == "__main__": diff --git a/airflow-core/src/airflow/utils/serve_logs/log_server.py b/airflow-core/src/airflow/utils/serve_logs/log_server.py index fa0338e5c9f6e..16acd64c538fa 100644 --- a/airflow-core/src/airflow/utils/serve_logs/log_server.py +++ b/airflow-core/src/airflow/utils/serve_logs/log_server.py @@ -157,4 +157,12 @@ def create_app(): return fastapi_app -app = create_app() +app = None + + +def get_app(): + """Get or create the FastAPI app instance.""" + global app + if app is None: + app = create_app() + return app diff --git a/airflow-core/tests/integration/otel/dags/otel_test_dag.py b/airflow-core/tests/integration/otel/dags/otel_test_dag.py index bd7db5d12894e..d742de938bafd 100644 --- a/airflow-core/tests/integration/otel/dags/otel_test_dag.py +++ b/airflow-core/tests/integration/otel/dags/otel_test_dag.py @@ -45,7 +45,7 @@ def task1(ti): tracer_provider = otel_task_tracer.get_otel_tracer_provider() if context_carrier is not None: - logger.info("Found ti.context_carrier: %s.", context_carrier) + logger.info("Found ti.context_carrier: %s.", str(context_carrier)) logger.info("Extracting the span context from the context_carrier.") parent_context = otel_task_tracer.extract(context_carrier) with otel_task_tracer.start_child_span( diff --git a/airflow-core/tests/integration/otel/test_otel.py b/airflow-core/tests/integration/otel/test_otel.py index d7e124740670c..e218820b292c0 100644 --- a/airflow-core/tests/integration/otel/test_otel.py +++ b/airflow-core/tests/integration/otel/test_otel.py @@ -547,14 +547,14 @@ def print_ti_output_for_dag_run(dag_id: str, run_id: str): for filename in files: if filename.endswith(".log"): full_path = os.path.join(root, filename) - log.info("\n===== LOG FILE: %s - START =====\n", full_path) + print("\n===== LOG FILE: %s - START =====\n", full_path) try: with open(full_path) as f: - log.info(f.read()) + print(f.read()) except Exception as e: log.error("Could not read %s: %s", full_path, e) - log.info("\n===== END =====\n") + print("\n===== END =====\n") @pytest.mark.integration("redis") diff --git a/airflow-core/tests/unit/always/test_connection.py b/airflow-core/tests/unit/always/test_connection.py index 2ace72179e3ad..499da66fd0b1d 100644 --- a/airflow-core/tests/unit/always/test_connection.py +++ b/airflow-core/tests/unit/always/test_connection.py @@ -640,18 +640,8 @@ def test_param_setup(self): assert conn.port is None @pytest.mark.db_test - def test_env_var_priority(self, mock_supervisor_comms): + def test_env_var_priority(self): from airflow.providers.sqlite.hooks.sqlite import SqliteHook - from airflow.sdk.execution_time.comms import ConnectionResult - - conn = ConnectionResult( - conn_id="airflow_db", - conn_type="mysql", - host="mysql", - login="root", - ) - - mock_supervisor_comms.send.return_value = conn conn = SqliteHook.get_connection(conn_id="airflow_db") assert conn.host != "ec2.compute.com" diff --git a/airflow-core/tests/unit/always/test_providers_manager.py b/airflow-core/tests/unit/always/test_providers_manager.py index 5076fd920efe5..70f6070bd21eb 100644 --- a/airflow-core/tests/unit/always/test_providers_manager.py +++ b/airflow-core/tests/unit/always/test_providers_manager.py @@ -60,6 +60,7 @@ def inject_fixtures(self, caplog, cleanup_providers_manager): def test_providers_are_loaded(self): with self._caplog.at_level(logging.WARNING): + self._caplog.clear() provider_manager = ProvidersManager() provider_list = list(provider_manager.providers.keys()) # No need to sort the list - it should be sorted alphabetically ! @@ -119,8 +120,8 @@ def test_warning_logs_generated(self): ) providers_manager._discover_hooks() _ = providers_manager._hooks_lazy_dict["wrong-connection-type"] - assert len(self._caplog.records) == 1 - assert "Inconsistency!" in self._caplog.records[0].message + assert len(self._caplog.entries) == 1 + assert "Inconsistency!" in self._caplog[0]["event"] assert "sftp" not in providers_manager.hooks def test_warning_logs_not_generated(self): @@ -164,11 +165,12 @@ def test_already_registered_conn_type_in_provide(self): providers_manager._discover_hooks() _ = providers_manager._hooks_lazy_dict["dummy"] assert len(self._caplog.records) == 1 - assert "The connection type 'dummy' is already registered" in self._caplog.records[0].message + msg = self._caplog.messages[0] + assert msg.startswith("The connection type 'dummy' is already registered") assert ( "different class names: 'airflow.providers.dummy.hooks.dummy.DummyHook'" " and 'airflow.providers.dummy.hooks.dummy.DummyHook2'." - ) in self._caplog.records[0].message + ) in msg def test_providers_manager_register_plugins(self): providers_manager = ProvidersManager() @@ -248,12 +250,12 @@ def test_hook_values(self): assert len(connections_list) > 60 if len(self._caplog.records) != 0: real_warning_count = 0 - for record in self._caplog.records: + for record in self._caplog.entries: # When there is error importing provider that is excluded the provider name is in the message - if any(excluded_provider in record.message for excluded_provider in excluded_providers): + if any(excluded_provider in record["event"] for excluded_provider in excluded_providers): continue - print(record.message, file=sys.stderr) - print(record.exc_info, file=sys.stderr) + print(record["event"], file=sys.stderr) + print(record.get("exc_info"), file=sys.stderr) real_warning_count += 1 if real_warning_count: if PY313: diff --git a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_middleware.py b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_middleware.py deleted file mode 100644 index fa4bd5566b7ed..0000000000000 --- a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_middleware.py +++ /dev/null @@ -1,62 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -from __future__ import annotations - -import pytest -from fastapi.testclient import TestClient - -from airflow.api_fastapi.app import create_app - -from tests_common.test_utils.config import conf_vars - -pytestmark = pytest.mark.db_test - - -@pytest.fixture -def all_access_test_client(): - with conf_vars( - { - ("core", "simple_auth_manager_all_admins"): "true", - ("api", "expose_config"): "true", - } - ): - app = create_app() - yield TestClient(app) - - -@pytest.mark.parametrize( - "method, path", - [ - ("GET", "/api/v2/assets"), - ("POST", "/api/v2/backfills"), - ("GET", "/api/v2/config"), - ("GET", "/api/v2/dags"), - ("POST", "/api/v2/dags/{dag_id}/clearTaskInstances"), - ("GET", "/api/v2/dags/{dag_id}/dagRuns"), - ("GET", "/api/v2/eventLogs"), - ("GET", "/api/v2/jobs"), - ("GET", "/api/v2/variables"), - ("GET", "/api/v2/version"), - ], -) -def test_all_endpoints_without_auth_header(all_access_test_client, method, path): - response = all_access_test_client.request(method, path) - assert response.status_code not in { - 401, - 403, - }, f"Unexpected status code {response.status_code} for {method} {path}" diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_report.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_report.py deleted file mode 100644 index 3938894001de9..0000000000000 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_report.py +++ /dev/null @@ -1,135 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -from __future__ import annotations - -import os -from unittest.mock import patch - -import pytest - -from airflow.utils.file import list_py_file_paths - -from tests_common.test_utils.config import conf_vars -from tests_common.test_utils.db import clear_db_dags, parse_and_sync_to_db - -pytestmark = pytest.mark.db_test - -TEST_DAG_FOLDER = os.environ["AIRFLOW__CORE__DAGS_FOLDER"] -TEST_DAG_FOLDER_WITH_SUBDIR = f"{TEST_DAG_FOLDER}/subdir2" -TEST_DAG_FOLDER_INVALID = "/invalid/path" -TEST_DAG_FOLDER_INVALID_2 = "/root/airflow/tests/dags/" - - -def get_corresponding_dag_file_count(dir: str, include_examples: bool = True) -> int: - from airflow import example_dags - - return len(list_py_file_paths(directory=dir)) + ( - len(list_py_file_paths(next(iter(example_dags.__path__)))) if include_examples else 0 - ) - - -class TestDagReportEndpoint: - @pytest.fixture(autouse=True) - def setup(self) -> None: - self.clear_db() - - def teardown_method(self) -> None: - self.clear_db() - - def clear_db(self): - clear_db_dags() - - @pytest.mark.parametrize( - "subdir,include_example,expected_total_entries", - [ - pytest.param( - TEST_DAG_FOLDER, - True, - get_corresponding_dag_file_count(TEST_DAG_FOLDER), - id="dag_path_with_example", - ), - pytest.param( - TEST_DAG_FOLDER, - False, - get_corresponding_dag_file_count(TEST_DAG_FOLDER, False), - id="dag_path_without_example", - ), - pytest.param( - TEST_DAG_FOLDER_WITH_SUBDIR, - True, - get_corresponding_dag_file_count(TEST_DAG_FOLDER_WITH_SUBDIR), - id="dag_path_subdir_with_example", - ), - pytest.param( - TEST_DAG_FOLDER_WITH_SUBDIR, - False, - get_corresponding_dag_file_count(TEST_DAG_FOLDER_WITH_SUBDIR, False), - id="dag_path_subdir_without_example", - ), - ], - ) - def test_should_response_200(self, test_client, subdir, include_example, expected_total_entries): - with conf_vars({("core", "load_examples"): str(include_example)}): - parse_and_sync_to_db(subdir, include_examples=include_example) - response = test_client.get("/dagReports", params={"subdir": subdir}) - assert response.status_code == 200 - response_json = response.json() - assert response_json["total_entries"] == expected_total_entries - - def test_should_response_200_with_empty_dagbag(self, test_client): - # the constructor of DagBag will call `collect_dags` method and store the result in `dagbag_stats` - def _mock_collect_dags(self, *args, **kwargs): - self.dagbag_stats = [] - - with patch("airflow.models.dagbag.DagBag.collect_dags", _mock_collect_dags): - response = test_client.get("/dagReports", params={"subdir": TEST_DAG_FOLDER}) - assert response.status_code == 200 - assert response.json() == {"dag_reports": [], "total_entries": 0} - - @pytest.mark.parametrize( - "subdir", - [ - pytest.param(TEST_DAG_FOLDER_INVALID, id="invalid_dag_path"), - pytest.param(TEST_DAG_FOLDER_INVALID_2, id="invalid_dag_path_2"), - ], - ) - def test_should_response_400(self, test_client, subdir): - response = test_client.get("/dagReports", params={"subdir": subdir}) - assert response.status_code == 400 - assert response.json() == {"detail": "subdir should be subpath of DAGS_FOLDER settings"} - - def test_should_response_422(self, test_client): - response = test_client.get("/dagReports") - assert response.status_code == 422 - assert response.json() == { - "detail": [ - { - "input": None, - "loc": ["query", "subdir"], - "msg": "Field required", - "type": "missing", - } - ] - } - - def test_should_respond_401(self, unauthenticated_test_client): - response = unauthenticated_test_client.get("/dagReports") - assert response.status_code == 401 - - def test_should_respond_403(self, unauthorized_test_client): - response = unauthorized_test_client.get("/dagReports") - assert response.status_code == 403 diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_run.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_run.py index c606942693719..262efdccf6c4f 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_run.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_run.py @@ -33,6 +33,7 @@ from airflow.providers.standard.operators.empty import EmptyOperator from airflow.sdk.definitions.asset import Asset from airflow.sdk.definitions.param import Param +from airflow.timetables.interval import CronDataIntervalTimetable from airflow.utils.session import provide_session from airflow.utils.state import DagRunState, State from airflow.utils.types import DagRunTriggeredByType, DagRunType @@ -50,9 +51,44 @@ if TYPE_CHECKING: from airflow.models.dag_version import DagVersion + from airflow.timetables.base import DataInterval pytestmark = pytest.mark.db_test + +class CustomTimetable(CronDataIntervalTimetable): + """Custom timetable that generates custom run IDs.""" + + def generate_run_id( + self, + *, + run_type: DagRunType, + run_after, + data_interval: DataInterval | None, + **kwargs, + ) -> str: + if data_interval: + return f"custom_{data_interval.start.strftime('%Y%m%d%H%M%S')}" + return f"custom_manual_{run_after.strftime('%Y%m%d%H%M%S')}" + + +@pytest.fixture +def custom_timetable_plugin(monkeypatch): + """Fixture to register CustomTimetable for serialization.""" + from airflow import plugins_manager + from airflow.utils.module_loading import qualname + + timetable_class_name = qualname(CustomTimetable) + existing_timetables = getattr(plugins_manager, "timetable_classes", None) or {} + + monkeypatch.setattr(plugins_manager, "initialize_timetables_plugins", lambda: None) + monkeypatch.setattr( + plugins_manager, + "timetable_classes", + {**existing_timetables, timetable_class_name: CustomTimetable}, + ) + + DAG1_ID = "test_dag1" DAG1_DISPLAY_NAME = "test_dag1" DAG2_ID = "test_dag2" @@ -1772,6 +1808,44 @@ def test_should_respond_200_with_null_logical_date(self, test_client): "note": None, } + @time_machine.travel("2025-10-02 12:00:00", tick=False) + @pytest.mark.usefixtures("custom_timetable_plugin") + def test_custom_timetable_generate_run_id_for_manual_trigger(self, dag_maker, test_client, session): + """Test that custom timetable's generate_run_id is used for manual triggers (issue #55908).""" + custom_dag_id = "test_custom_timetable_dag" + with dag_maker( + dag_id=custom_dag_id, + schedule=CustomTimetable("0 0 * * *", timezone="UTC"), + session=session, + serialized=True, + ): + EmptyOperator(task_id="test_task") + + session.commit() + + logical_date = datetime(2025, 10, 1, 0, 0, 0, tzinfo=timezone.utc) + response = test_client.post( + f"/dags/{custom_dag_id}/dagRuns", + json={"logical_date": logical_date.isoformat()}, + ) + assert response.status_code == 200 + run_id_with_logical_date = response.json()["dag_run_id"] + assert run_id_with_logical_date.startswith("custom_") + + run = session.query(DagRun).filter(DagRun.run_id == run_id_with_logical_date).one() + assert run.dag_id == custom_dag_id + + response = test_client.post( + f"/dags/{custom_dag_id}/dagRuns", + json={"logical_date": None}, + ) + assert response.status_code == 200 + run_id_without_logical_date = response.json()["dag_run_id"] + assert run_id_without_logical_date.startswith("custom_manual_") + + run = session.query(DagRun).filter(DagRun.run_id == run_id_without_logical_date).one() + assert run.dag_id == custom_dag_id + class TestWaitDagRun: # The way we init async engine does not work well with FastAPI app init. diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py index 9dfd355992093..161e81607d414 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py @@ -18,7 +18,7 @@ import json from collections.abc import Callable -from datetime import datetime +from datetime import datetime, timedelta from operator import itemgetter from typing import TYPE_CHECKING, Any from unittest import mock @@ -28,11 +28,14 @@ from sqlalchemy import select from sqlalchemy.orm import Session -from airflow._shared.timezones.timezone import utcnow +from airflow._shared.timezones.timezone import utc, utcnow from airflow.models.hitl import HITLDetail from airflow.models.log import Log +from airflow.sdk.execution_time.hitl import HITLUser from airflow.utils.state import TaskInstanceState +from tests_common.test_utils.format_datetime import from_datetime_to_zulu_without_ms + if TYPE_CHECKING: from fastapi.testclient import TestClient @@ -48,6 +51,10 @@ TASK_ID = "sample_task_hitl" +DEFAULT_CREATED_AT = datetime(2025, 9, 15, 13, 0, 0, tzinfo=utc) +ANOTHER_CREATED_AT = datetime(2025, 9, 16, 12, 0, 0, tzinfo=utc) + + @pytest.fixture def sample_ti( create_task_instance: CreateTaskInstance, @@ -64,7 +71,7 @@ def sample_ti( @pytest.fixture def sample_ti_url_identifier() -> str: - return f"{DAG_ID}/test/{TASK_ID}" + return f"/dags/{DAG_ID}/dagRuns/test/taskInstances/{TASK_ID}/-1" @pytest.fixture @@ -77,7 +84,7 @@ def sample_hitl_detail(sample_ti: TaskInstance, session: Session) -> HITLDetail: defaults=["Approve"], multiple=False, params={"input_1": 1}, - respondents=None, + assignees=None, ) session.add(hitl_detail_model) session.commit() @@ -95,7 +102,7 @@ def sample_hitl_detail_non_respondent(sample_ti: TaskInstance, session: Session) defaults=["Approve"], multiple=False, params={"input_1": 1}, - respondents=["non_test"], + assignees=[HITLUser(id="non_test", name="non_test")], ) session.add(hitl_detail_model) session.commit() @@ -113,7 +120,7 @@ def sample_hitl_detail_respondent(sample_ti: TaskInstance, session: Session) -> defaults=["Approve"], multiple=False, params={"input_1": 1}, - respondents=["test"], + assignees=[HITLUser(id="test", name="test")], ) session.add(hitl_detail_model) session.commit() @@ -128,7 +135,7 @@ def sample_tis(create_task_instance: CreateTaskInstance) -> list[TaskInstance]: dag_id=f"hitl_dag_{i}", run_id=f"hitl_run_{i}", task_id=f"hitl_task_{i}", - state=TaskInstanceState.RUNNING, + state=TaskInstanceState.DEFERRED, ) for i in range(5) ] @@ -157,6 +164,7 @@ def sample_hitl_details(sample_tis: list[TaskInstance], session: Session) -> lis defaults=["Approve"], multiple=False, params={"input_1": 1}, + created_at=DEFAULT_CREATED_AT, ) for i, ti in enumerate(sample_tis[:5]) ] @@ -170,11 +178,11 @@ def sample_hitl_details(sample_tis: list[TaskInstance], session: Session) -> lis defaults=["1"], multiple=False, params={"input": 1}, - response_at=utcnow(), + responded_at=utcnow(), chosen_options=[str(i)], params_input={"input": i}, - responded_user_id="test", - responded_user_name="test", + responded_by={"id": "test", "name": "test"}, + created_at=ANOTHER_CREATED_AT, ) for i, ti in enumerate(sample_tis[5:]) ] @@ -208,14 +216,14 @@ def expected_sample_hitl_detail_dict(sample_ti: TaskInstance) -> dict[str, Any]: "multiple": False, "options": ["Approve", "Reject"], "params": {"input_1": 1}, - "respondents": None, + "assigned_users": [], + "created_at": mock.ANY, "params_input": {}, - "response_at": None, + "responded_at": None, "chosen_options": None, "response_received": False, "subject": "This is subject", - "responded_user_id": None, - "responded_user_name": None, + "responded_by_user": None, "task_instance": { "dag_display_name": DAG_ID, "dag_id": DAG_ID, @@ -270,11 +278,10 @@ def cleanup_audit_log(session: Session) -> None: session.commit() -def _assert_sample_audit_log(audit_log: Log, map_index: int | None) -> None: +def _assert_sample_audit_log(audit_log: Log) -> None: assert audit_log.dag_id == DAG_ID assert audit_log.task_id == TASK_ID assert audit_log.run_id == "test" - assert audit_log.map_index is None assert audit_log.try_number is None assert audit_log.owner == "test" assert audit_log.owner_display_name == "test" @@ -287,9 +294,8 @@ def _assert_sample_audit_log(audit_log: Log, map_index: int | None) -> None: "chosen_options": ["Approve"], "params_input": {"input_1": 2}, "method": "PATCH", + "map_index": "-1", } - if map_index is not None: - expected_extra["map_index"] = str(map_index) assert json.loads(audit_log.extra) == expected_extra @@ -302,48 +308,40 @@ def sample_update_payload() -> dict[str, Any]: class TestUpdateHITLDetailEndpoint: @time_machine.travel(datetime(2025, 7, 3, 0, 0, 0), tick=False) @pytest.mark.usefixtures("sample_hitl_detail") - @pytest.mark.parametrize("map_index", [None, -1]) def test_should_respond_200_with_existing_response( self, test_client: TestClient, sample_ti_url_identifier: str, - map_index: int | None, sample_update_payload: dict[str, Any], session: Session, ) -> None: - query_param = "" if map_index is None else f"?map_index={map_index}" response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) - assert response.status_code == 200 assert response.json() == { "params_input": {"input_1": 2}, "chosen_options": ["Approve"], - "responded_user_id": "test", - "responded_user_name": "test", - "response_at": "2025-07-03T00:00:00Z", + "responded_by": {"id": "test", "name": "test"}, + "responded_at": "2025-07-03T00:00:00Z", } audit_log = session.scalar(select(Log)) - _assert_sample_audit_log(audit_log, map_index=map_index) + _assert_sample_audit_log(audit_log) @time_machine.travel(datetime(2025, 7, 3, 0, 0, 0), tick=False) @pytest.mark.usefixtures("sample_hitl_detail_respondent") - @pytest.mark.parametrize("map_index", [None, -1]) - def test_should_respond_200_to_respondent_user( + def test_should_respond_200_to_assigned_users( self, test_client: TestClient, sample_ti_url_identifier: str, - map_index: int | None, sample_update_payload: dict[str, Any], session: Session, ): """Test with an authorized user and the user is a respondent to the task.""" - query_param = "" if map_index is None else f"?map_index={map_index}" response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) @@ -351,43 +349,37 @@ def test_should_respond_200_to_respondent_user( assert response.json() == { "params_input": {"input_1": 2}, "chosen_options": ["Approve"], - "responded_user_id": "test", - "responded_user_name": "test", - "response_at": "2025-07-03T00:00:00Z", + "responded_by": {"id": "test", "name": "test"}, + "responded_at": "2025-07-03T00:00:00Z", } audit_log = session.scalar(select(Log)) - _assert_sample_audit_log(audit_log, map_index=map_index) + _assert_sample_audit_log(audit_log) - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_401( self, unauthenticated_test_client: TestClient, sample_ti_url_identifier: str, sample_update_payload: dict[str, Any], - query_param: str, ) -> None: response = unauthenticated_test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) assert response.status_code == 401 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_403( self, unauthorized_test_client: TestClient, sample_ti_url_identifier: str, sample_update_payload: dict[str, Any], - query_param: str, ) -> None: response = unauthorized_test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) assert response.status_code == 403 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) @time_machine.travel(datetime(2025, 7, 3, 0, 0, 0), tick=False) @pytest.mark.usefixtures("sample_hitl_detail_non_respondent") def test_should_respond_403_to_non_respondent_user( @@ -395,73 +387,65 @@ def test_should_respond_403_to_non_respondent_user( test_client: TestClient, sample_ti_url_identifier: str, sample_update_payload: dict[str, Any], - query_param: str, ): """Test with an authorized user but the user is not a respondent to the task.""" response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) assert response.status_code == 403 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_404_without_ti( self, test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) assert response.status_code == 404 assert response.json() == {"detail": expected_ti_not_found_error_msg} - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_404_without_hitl_detail( self, test_client: TestClient, sample_ti_url_identifier: str, sample_update_payload: dict[str, Any], - query_param: str, expected_hitl_detail_not_found_error_msg: str, ) -> None: response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) assert response.status_code == 404 assert response.json() == {"detail": expected_hitl_detail_not_found_error_msg} - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) @time_machine.travel(datetime(2025, 7, 3, 0, 0, 0), tick=False) @pytest.mark.usefixtures("sample_hitl_detail") def test_should_respond_409( self, test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, sample_ti: TaskInstance, ) -> None: response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) expected_response = { "params_input": {"input_1": 2}, "chosen_options": ["Approve"], - "responded_user_id": "test", - "responded_user_name": "test", - "response_at": "2025-07-03T00:00:00Z", + "responded_by": {"id": "test", "name": "test"}, + "responded_at": "2025-07-03T00:00:00Z", } assert response.status_code == 200 assert response.json() == expected_response response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json={"chosen_options": ["Approve"], "params_input": {"input_1": 3}}, ) assert response.status_code == 409 @@ -473,16 +457,14 @@ def test_should_respond_409( ) } - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) @pytest.mark.usefixtures("sample_hitl_detail") def test_should_respond_422_with_empty_option( self, test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json={"chosen_options": [], "params_input": {"input_1": 2}}, ) @@ -490,59 +472,49 @@ def test_should_respond_422_with_empty_option( class TestGetHITLDetailEndpoint: - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) @pytest.mark.usefixtures("sample_hitl_detail") def test_should_respond_200_with_existing_response( self, test_client: TestClient, sample_ti_url_identifier: str, expected_sample_hitl_detail_dict: dict[str, Any], - query_param: str, ) -> None: - response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 200 assert response.json() == expected_sample_hitl_detail_dict - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_401( self, unauthenticated_test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: - response = unauthenticated_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = unauthenticated_test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 401 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_403( self, unauthorized_test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: - response = unauthorized_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = unauthorized_test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 403 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_404_without_ti( self, test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: - response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 404 assert response.json() == {"detail": expected_ti_not_found_error_msg} - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_404_without_hitl_detail( self, test_client: TestClient, sample_ti_url_identifier: str, expected_hitl_detail_not_found_error_msg: str, - query_param: str, ) -> None: - response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 404 assert response.json() == {"detail": expected_hitl_detail_not_found_error_msg} @@ -554,7 +526,7 @@ def test_should_respond_200_with_existing_response( test_client: TestClient, expected_sample_hitl_detail_dict: dict[str, Any], ) -> None: - response = test_client.get("/hitlDetails/") + response = test_client.get("/dags/~/dagRuns/~/hitlDetails") assert response.status_code == 200 assert response.json() == { "hitl_details": [expected_sample_hitl_detail_dict], @@ -568,35 +540,53 @@ def test_should_respond_200_with_existing_response( # ti related filter ({"dag_id_pattern": "hitl_dag"}, 5), ({"dag_id_pattern": "other_Dag_"}, 3), - ({"dag_id": "hitl_dag_0"}, 1), - ({"dag_run_id": "hitl_run_0"}, 1), ({"task_id": "hitl_task_0"}, 1), ({"task_id_pattern": "another_hitl"}, 3), - ({"state": "running"}, 5), + ({"map_index": -1}, 8), + ({"map_index": 1}, 0), + ({"state": "deferred"}, 5), ({"state": "success"}, 3), # hitl detail related filter ({"subject_search": "This is subject"}, 5), ({"body_search": "this is"}, 8), ({"response_received": False}, 5), ({"response_received": True}, 3), - ({"responded_user_id": ["test"]}, 3), - ({"responded_user_name": ["test"]}, 3), + ({"responded_by_user_id": ["test"]}, 3), + ({"responded_by_user_name": ["test"]}, 3), + ( + {"created_at_gte": from_datetime_to_zulu_without_ms(DEFAULT_CREATED_AT + timedelta(days=1))}, + 0, + ), + ( + {"created_at_lte": from_datetime_to_zulu_without_ms(DEFAULT_CREATED_AT - timedelta(days=1))}, + 0, + ), + ( + { + "created_at_gte": from_datetime_to_zulu_without_ms(DEFAULT_CREATED_AT), + "created_at_lte": from_datetime_to_zulu_without_ms(DEFAULT_CREATED_AT), + }, + 5, + ), ], ids=[ "dag_id_pattern_hitl_dag", "dag_id_pattern_other_dag", - "dag_id", - "dag_run_id", - "task_id_pattern", "task_id", - "ti_state_running", + "task_id_pattern", + "map_index_none", + "map_index_1", + "ti_state_deferred", "ti_state_success", "subject", "body", "response_not_received", "response_received", - "responded_user_id", - "responded_user_name", + "responded_by_user_id", + "responded_by_user_name", + "created_at_gte", + "created_at_lte", + "created_at", ], ) def test_should_respond_200_with_existing_response_and_query( @@ -605,11 +595,40 @@ def test_should_respond_200_with_existing_response_and_query( params: dict[str, Any], expected_ti_count: int, ) -> None: - response = test_client.get("/hitlDetails/", params=params) + response = test_client.get("/dags/~/dagRuns/~/hitlDetails", params=params) assert response.status_code == 200 assert response.json()["total_entries"] == expected_ti_count assert len(response.json()["hitl_details"]) == expected_ti_count + @pytest.mark.usefixtures("sample_hitl_details") + def test_should_respond_200_with_existing_response_and_concrete_query( + self, + test_client: TestClient, + ) -> None: + response = test_client.get("/dags/hitl_dag_0/dagRuns/hitl_run_0/hitlDetails") + assert response.status_code == 200 + assert response.json() == { + "hitl_details": [ + { + "task_instance": mock.ANY, + "options": ["Approve", "Reject"], + "subject": "This is subject 0", + "body": "this is body 0", + "defaults": ["Approve"], + "multiple": False, + "params": {"input_1": 1}, + "assigned_users": [], + "created_at": DEFAULT_CREATED_AT.isoformat().replace("+00:00", "Z"), + "responded_by_user": None, + "responded_at": None, + "chosen_options": None, + "params_input": {}, + "response_received": False, + } + ], + "total_entries": 1, + } + @pytest.mark.usefixtures("sample_hitl_details") @pytest.mark.parametrize("asc_desc_mark", ["", "-"], ids=["asc", "desc"]) @pytest.mark.parametrize( @@ -622,19 +641,25 @@ def test_should_respond_200_with_existing_response_and_query( ("run_after", lambda x: x["task_instance"]["run_after"]), ("rendered_map_index", lambda x: x["task_instance"]["rendered_map_index"]), ("task_instance_operator", lambda x: x["task_instance"]["operator_name"]), + ("task_instance_state", lambda x: x["task_instance"]["state"]), # htil key ("subject", itemgetter("subject")), - ("response_at", itemgetter("response_at")), + ("responded_at", itemgetter("responded_at")), + ("created_at", itemgetter("created_at")), ], ids=[ + # ti key "ti_id", "dag_id", "run_id", "run_after", "rendered_map_index", "task_instance_operator", + "task_instance_state", + # htil key "subject", - "response_at", + "responded_at", + "created_at", ], ) def test_should_respond_200_with_existing_response_and_order_by( @@ -646,7 +671,9 @@ def test_should_respond_200_with_existing_response_and_order_by( ) -> None: reverse = asc_desc_mark == "-" - response = test_client.get("/hitlDetails/", params={"order_by": f"{asc_desc_mark}{key}"}) + response = test_client.get( + "/dags/~/dagRuns/~/hitlDetails", params={"order_by": f"{asc_desc_mark}{key}"} + ) data = response.json() hitl_details = data["hitl_details"] @@ -668,7 +695,7 @@ def test_should_respond_200_with_existing_response_and_order_by( assert hitl_details == sorted_hitl_details def test_should_respond_200_without_response(self, test_client: TestClient) -> None: - response = test_client.get("/hitlDetails/") + response = test_client.get("/dags/~/dagRuns/~/hitlDetails") assert response.status_code == 200 assert response.json() == { "hitl_details": [], @@ -676,9 +703,9 @@ def test_should_respond_200_without_response(self, test_client: TestClient) -> N } def test_should_respond_401(self, unauthenticated_test_client: TestClient) -> None: - response = unauthenticated_test_client.get("/hitlDetails/") + response = unauthenticated_test_client.get("/dags/~/dagRuns/~/hitlDetails") assert response.status_code == 401 def test_should_respond_403(self, unauthorized_test_client: TestClient) -> None: - response = unauthorized_test_client.get("/hitlDetails/") + response = unauthorized_test_client.get("/dags/~/dagRuns/~/hitlDetails") assert response.status_code == 403 diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_log.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_log.py index 3989aae2aa545..64fe8155a1687 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_log.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_log.py @@ -17,9 +17,7 @@ from __future__ import annotations -import copy import json -import logging.config import sys from unittest import mock from unittest.mock import PropertyMock @@ -30,7 +28,6 @@ from airflow._shared.timezones import timezone from airflow.api_fastapi.common.dagbag import create_dag_bag, dag_bag_from_app -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.models.dag import DAG from airflow.providers.standard.operators.empty import EmptyOperator from airflow.sdk import task @@ -151,15 +148,13 @@ def configure_loggers(self, tmp_path, create_log_template): log = dir_path / "attempt=2.log" log.write_text("Log for testing 2.") - # Create a custom logging configuration - logging_config = copy.deepcopy(DEFAULT_LOGGING_CONFIG) - logging_config["handlers"]["task"]["base_log_folder"] = self.log_dir - - logging.config.dictConfig(logging_config) - - yield - - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) + with mock.patch( + "airflow.utils.log.file_task_handler.FileTaskHandler.local_base", + new_callable=mock.PropertyMock, + create=True, + ) as local_base: + local_base.return_value = self.log_dir + yield def teardown_method(self): clear_db_runs() diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_plugins.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_plugins.py index c63a7b19db82f..36312e710abff 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_plugins.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_plugins.py @@ -119,6 +119,35 @@ def test_should_response_403(self, unauthorized_test_client): response = unauthorized_test_client.get("/plugins") assert response.status_code == 403 + def test_invalid_external_view_destination_should_log_warning_and_continue(self, test_client, caplog): + pytest.importorskip("flask_appbuilder") # Remove after upgrading to FAB5 + + caplog.set_level("WARNING", "airflow.api_fastapi.core_api.routes.public.plugins") + + response = test_client.get("/plugins") + assert response.status_code == 200 + + body = response.json() + plugin_names = [plugin["name"] for plugin in body["plugins"]] + + # Ensure our invalid plugin is skipped from the valid list + assert "test_plugin_invalid" not in plugin_names + + # Verify warning was logged + assert any("Skipping invalid plugin due to error" in rec.message for rec in caplog.records) + + response = test_client.get("/plugins", params={"limit": 5, "offset": 9}) + assert response.status_code == 200 + + body = response.json() + plugins_page = body["plugins"] + + # Even though limit=5, only 4 valid plugins should come back + assert len(plugins_page) == 4 + assert "test_plugin_invalid" not in [p["name"] for p in plugins_page] + + assert body["total_entries"] == 13 + @skip_if_force_lowest_dependencies_marker class TestGetPluginImportErrors: diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py index 2c10ef1e341ab..d2303da24a44c 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py @@ -115,12 +115,14 @@ def create_task_instances( dag_version = DagVersion.get_latest_version(dag.dag_id, session=session) tis = [] for i in range(counter): - if task_instances is None: - pass - elif update_extras: - self.ti_extras.update(task_instances[i]) - else: - self.ti_init.update(task_instances[i]) + map_indexes = (-1,) + if task_instances: + map_index = task_instances[i].get("map_index", -1) + map_indexes = task_instances[i].pop("map_indexes", (map_index,)) + if update_extras: + self.ti_extras.update(task_instances[i]) + else: + self.ti_init.update(task_instances[i]) if "logical_date" in self.ti_init: run_id = f"TEST_DAG_RUN_ID_{i}" @@ -139,14 +141,17 @@ def create_task_instances( session.flush() if TYPE_CHECKING: assert dag_version - ti = TaskInstance(task=tasks[i], **self.ti_init, dag_version_id=dag_version.id) - session.add(ti) - ti.dag_run = dr - ti.note = "placeholder-note" - for key, value in self.ti_extras.items(): - setattr(ti, key, value) - tis.append(ti) + for mi in map_indexes: + kwargs = self.ti_init | {"map_index": mi} + ti = TaskInstance(task=tasks[i], **kwargs, dag_version_id=dag_version.id) + session.add(ti) + ti.dag_run = dr + ti.note = "placeholder-note" + + for key, value in self.ti_extras.items(): + setattr(ti, key, value) + tis.append(ti) session.flush() @@ -884,6 +889,8 @@ def test_with_logical_date(self, test_client, one_task_with_mapped_tis): ({"queue": "test_queue"}, 0, 0), ({"executor": "default"}, 3, 3), ({"executor": "no_exec"}, 0, 0), + ({"map_index": [0, 1]}, 2, 2), + ({"map_index": [5]}, 0, 0), ], ) def test_mapped_task_instances_filters( @@ -1225,6 +1232,23 @@ class TestGetTaskInstances(TestTaskInstanceEndpoint): 5, id="test operator type filter filter", ), + pytest.param( + [ + {"map_index": 0}, + {"map_index": 1}, + {"map_index": 2}, + {"map_index": 3}, + {"map_index": 4}, + {"map_index": 5}, + {"map_index": 6}, + {"map_index": 7}, + ], + True, + ("/dags/~/dagRuns/~/taskInstances"), + {"map_index": [0, 1]}, + 2, + id="test map_index filter", + ), ], ) @pytest.mark.usefixtures("make_dag_with_multiple_versions") @@ -2362,10 +2386,116 @@ class TestPostClearTaskInstances(TestTaskInstanceEndpoint): "example_python_operator", { "dry_run": False, - "task_ids": [["print_the_context", 0], "sleep_for_1"], + "task_ids": [["print_the_context", -1], "sleep_for_1"], }, 2, - id="clear mapped task and unmapped tasks together", + id="clear unmapped tasks with and without map index", + ), + pytest.param( + "example_task_mapping_second_order", + [ + { + "logical_date": DEFAULT_DATETIME_1, + "state": State.FAILED, + }, + { + "logical_date": DEFAULT_DATETIME_1 + dt.timedelta(days=1), + "state": State.FAILED, + "map_indexes": (0, 1, 2), + }, + { + "logical_date": DEFAULT_DATETIME_1 + dt.timedelta(days=2), + "state": State.FAILED, + "map_indexes": (0, 1, 2), + }, + ], + "example_task_mapping_second_order", + { + "dry_run": False, + "task_ids": [["times_2", 0], ["add_10", 1]], + }, + 2, + id="clear multiple mapped tasks", + ), + pytest.param( + "example_task_mapping_second_order", + [ + { + "logical_date": DEFAULT_DATETIME_1, + "state": State.FAILED, + }, + { + "logical_date": DEFAULT_DATETIME_1 + dt.timedelta(days=1), + "state": State.FAILED, + "map_indexes": (0, 1, 2), + }, + { + "logical_date": DEFAULT_DATETIME_1 + dt.timedelta(days=2), + "state": State.FAILED, + "map_indexes": (0, 1, 2), + }, + ], + "example_task_mapping_second_order", + { + "dry_run": False, + "task_ids": [["times_2", 0], ["add_10", 1]], + "include_upstream": True, + }, + 5, + id="clear mapped tasks and upstream tasks", + ), + pytest.param( + "example_task_mapping_second_order", + [ + { + "logical_date": DEFAULT_DATETIME_1, + "state": State.FAILED, + }, + { + "logical_date": DEFAULT_DATETIME_1 + dt.timedelta(days=1), + "state": State.FAILED, + "map_indexes": (0, 1, 2), + }, + { + "logical_date": DEFAULT_DATETIME_1 + dt.timedelta(days=2), + "state": State.FAILED, + "map_indexes": (0, 1, 2), + }, + ], + "example_task_mapping_second_order", + { + "dry_run": False, + "task_ids": [["times_2", 0], ["add_10", 1]], + "include_downstream": True, + }, + 4, + id="clear mapped tasks and downstream tasks", + ), + pytest.param( + "example_task_mapping_second_order", + [ + { + "logical_date": DEFAULT_DATETIME_1, + "state": State.FAILED, + }, + { + "logical_date": DEFAULT_DATETIME_1 + dt.timedelta(days=1), + "state": State.FAILED, + "map_indexes": (0, 1, 2), + }, + { + "logical_date": DEFAULT_DATETIME_1 + dt.timedelta(days=2), + "state": State.FAILED, + "map_indexes": (0, 1, 2), + }, + ], + "example_task_mapping_second_order", + { + "dry_run": False, + "task_ids": [["times_2", 0], "add_10"], + }, + 4, + id="clear mapped tasks with and without map index", ), ], ) diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_assets.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_assets.py index a75cadbd6c09e..91b70967891f7 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_assets.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_assets.py @@ -18,8 +18,10 @@ from unittest import mock +import pendulum import pytest +from airflow.models.asset import AssetDagRunQueue, AssetEvent, AssetModel from airflow.providers.standard.operators.empty import EmptyOperator from airflow.sdk.definitions.asset import Asset @@ -74,3 +76,84 @@ def test_should_respond_401(self, unauthenticated_test_client): def test_should_respond_403(self, unauthorized_test_client): response = unauthorized_test_client.get("/next_run_assets/upstream") assert response.status_code == 403 + + def test_should_set_last_update_only_for_queued_and_hide_flag(self, test_client, dag_maker, session): + with dag_maker( + dag_id="two_assets_equal", + schedule=[ + Asset(uri="s3://bucket/A", name="A"), + Asset(uri="s3://bucket/B", name="B"), + ], + serialized=True, + ): + EmptyOperator(task_id="t") + + dr = dag_maker.create_dagrun() + dag_maker.sync_dagbag_to_db() + + assets = { + a.uri: a + for a in session.query(AssetModel).filter(AssetModel.uri.in_(["s3://bucket/A", "s3://bucket/B"])) + } + # Queue and add an event only for A + session.add(AssetDagRunQueue(asset_id=assets["s3://bucket/A"].id, target_dag_id="two_assets_equal")) + session.add( + AssetEvent(asset_id=assets["s3://bucket/A"].id, timestamp=dr.logical_date or pendulum.now()) + ) + session.commit() + + response = test_client.get("/next_run_assets/two_assets_equal") + assert response.status_code == 200 + assert response.json() == { + "asset_expression": { + "all": [ + { + "asset": { + "uri": "s3://bucket/A", + "name": "A", + "group": "asset", + "id": mock.ANY, + } + }, + { + "asset": { + "uri": "s3://bucket/B", + "name": "B", + "group": "asset", + "id": mock.ANY, + } + }, + ] + }, + # events are ordered by uri + "events": [ + {"id": mock.ANY, "uri": "s3://bucket/A", "name": "A", "lastUpdate": mock.ANY}, + {"id": mock.ANY, "uri": "s3://bucket/B", "name": "B", "lastUpdate": None}, + ], + } + + def test_last_update_respects_latest_run_filter(self, test_client, dag_maker, session): + with dag_maker( + dag_id="filter_run", + schedule=[Asset(uri="s3://bucket/F", name="F")], + serialized=True, + ): + EmptyOperator(task_id="t") + + dr = dag_maker.create_dagrun() + dag_maker.sync_dagbag_to_db() + + asset = session.query(AssetModel).filter(AssetModel.uri == "s3://bucket/F").one() + session.add(AssetDagRunQueue(asset_id=asset.id, target_dag_id="filter_run")) + # event before latest_run should be ignored + ts_base = dr.logical_date or pendulum.now() + session.add(AssetEvent(asset_id=asset.id, timestamp=ts_base.subtract(minutes=10))) + # event after latest_run counts + session.add(AssetEvent(asset_id=asset.id, timestamp=ts_base.add(minutes=10))) + session.commit() + + resp = test_client.get("/next_run_assets/filter_run") + assert resp.status_code == 200 + ev = resp.json()["events"][0] + assert ev["lastUpdate"] is not None + assert "queued" not in ev diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py index f85d7bda49b0b..5ebf2221d92d2 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py @@ -29,7 +29,7 @@ from airflow.models.hitl import HITLDetail from airflow.sdk.timezone import utcnow from airflow.utils.session import provide_session -from airflow.utils.state import DagRunState +from airflow.utils.state import DagRunState, TaskInstanceState from airflow.utils.types import DagRunTriggeredByType, DagRunType from unit.api_fastapi.core_api.routes.public.test_dags import ( @@ -136,6 +136,7 @@ def setup_hitl_data(self, create_task_instance: TaskInstance, session: Session): run_id=f"hitl_run_{ti_i}", task_id=f"test_task_{ti_i}", session=session, + state=TaskInstanceState.DEFERRED, ) for ti_i in range(TI_COUNT) ] @@ -158,9 +159,9 @@ def setup_hitl_data(self, create_task_instance: TaskInstance, session: Session): options=["Approve", "Reject"], subject=f"This is subject {i}", defaults=["Approve"], - response_at=utcnow(), + responded_at=utcnow(), chosen_options=["Approve"], - responded_user_id="test", + responded_by={"id": "test", "name": "test"}, ) for i in range(3, 5) ] @@ -186,6 +187,8 @@ def setup_hitl_data(self, create_task_instance: TaskInstance, session: Session): "params": {}, "params_input": {}, "response_received": False, + "assigned_users": [], + "created_at": mock.ANY, } for i in range(3) ], diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dashboard.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dashboard.py index 74aed76ff720c..1c29990fc9c89 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dashboard.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dashboard.py @@ -22,6 +22,7 @@ import pendulum import pytest +from airflow.models.dag import DagModel from airflow.models.dagbag import DBDagBag from airflow.providers.standard.operators.empty import EmptyOperator from airflow.utils.state import DagRunState, TaskInstanceState @@ -204,8 +205,35 @@ def make_multiple_dags(dag_maker, session): start_date=date, ) + with dag_maker( + dag_id="no_dag_runs", + serialized=True, + session=session, + start_date=pendulum.DateTime(2023, 2, 1, 0, 0, 0, tzinfo=pendulum.UTC), + ): + EmptyOperator(task_id="task_1") >> EmptyOperator(task_id="task_2") + + with dag_maker( + dag_id="stale_dag", + serialized=True, + session=session, + start_date=pendulum.DateTime(2023, 2, 1, 0, 0, 0, tzinfo=pendulum.UTC), + ): + EmptyOperator(task_id="task_1") >> EmptyOperator(task_id="task_2") + + date = dag_maker.dag.start_date + dag_maker.create_dagrun( + run_id="run_1", + state=DagRunState.QUEUED, + run_type=DagRunType.SCHEDULED, + logical_date=date, + start_date=date, + ) dag_maker.sync_dagbag_to_db() + session.get(DagModel, "stale_dag").is_stale = True + session.commit() + class TestHistoricalMetricsDataEndpoint: @pytest.mark.parametrize( @@ -304,7 +332,7 @@ def test_should_response_200_multiple_dags(self, test_client): response = test_client.get("/dashboard/dag_stats") assert response.status_code == 200 assert response.json() == { - "active_dag_count": 3, + "active_dag_count": 4, "failed_dag_count": 1, "running_dag_count": 1, "queued_dag_count": 1, diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_grid.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_grid.py index 32f8f2683f0aa..93b5ecfa48794 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_grid.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_grid.py @@ -84,7 +84,7 @@ "is_mapped": True, "label": "mapped_task_group", }, - {"id": "task", "label": "task"}, + {"id": "task", "label": "A Beautiful Task Name 🚀"}, { "children": [ { @@ -92,11 +92,11 @@ { "id": "task_group.inner_task_group.inner_task_group_sub_task", "is_mapped": True, - "label": "inner_task_group_sub_task", + "label": "Inner Task Group Sub Task Label", } ], "id": "task_group.inner_task_group", - "label": "inner_task_group", + "label": "My Inner Task Group", }, {"id": "task_group.mapped_task", "is_mapped": True, "label": "mapped_task"}, ], @@ -121,7 +121,7 @@ def setup(dag_maker, session=None): # DAG 1 with dag_maker(dag_id=DAG_ID, serialized=True, session=session) as dag: - task = EmptyOperator(task_id=TASK_ID) + task = EmptyOperator(task_id=TASK_ID, task_display_name="A Beautiful Task Name 🚀") @task_group def mapped_task_group(arg1): @@ -131,8 +131,10 @@ def mapped_task_group(arg1): with TaskGroup(group_id=TASK_GROUP_ID): MockOperator.partial(task_id=MAPPED_TASK_ID).expand(arg1=["a", "b", "c", "d"]) - with TaskGroup(group_id=INNER_TASK_GROUP): - MockOperator.partial(task_id=INNER_TASK_GROUP_SUB_TASK).expand(arg1=["a", "b"]) + with TaskGroup(group_id=INNER_TASK_GROUP, group_display_name="My Inner Task Group"): + MockOperator.partial( + task_id=INNER_TASK_GROUP_SUB_TASK, task_display_name="Inner Task Group Sub Task Label" + ).expand(arg1=["a", "b"]) # Mapped but never expanded. API should not crash, but count this as one no-status ti. MockOperator.partial(task_id=MAPPED_TASK_ID_2).expand(arg1=task.output) @@ -436,6 +438,39 @@ def test_should_response_200_with_deleted_task_and_taskgroup(self, session, test }, ] + # Also verify that TI summaries include a leaf entry for the removed task + ti_resp = test_client.get(f"/grid/ti_summaries/{DAG_ID_3}/run_3") + assert ti_resp.status_code == 200 + ti_payload = ti_resp.json() + assert ti_payload["dag_id"] == DAG_ID_3 + assert ti_payload["run_id"] == "run_3" + # Find the removed task summary; it should exist even if not in current serialized DAG structure + removed_ti = next( + ( + n + for n in ti_payload["task_instances"] + if n["task_id"] == TASK_ID_4 and n["child_states"] is None + ), + None, + ) + assert removed_ti is not None + # Its state should be the aggregated state of its TIs, which includes 'removed' + assert removed_ti["state"] in ( + "removed", + None, + "skipped", + "success", + "failed", + "running", + "queued", + "scheduled", + "deferred", + "restarting", + "up_for_retry", + "up_for_reschedule", + "upstream_failed", + ) + def test_get_dag_structure(self, session, test_client): session.commit() response = test_client.get(f"/grid/structure/{DAG_ID}?limit=5") @@ -447,7 +482,7 @@ def test_get_dag_structure(self, session, test_client): "is_mapped": True, "label": "mapped_task_group", }, - {"id": "task", "label": "task"}, + {"id": "task", "label": "A Beautiful Task Name 🚀"}, { "children": [ { @@ -455,11 +490,11 @@ def test_get_dag_structure(self, session, test_client): { "id": "task_group.inner_task_group.inner_task_group_sub_task", "is_mapped": True, - "label": "inner_task_group_sub_task", + "label": "Inner Task Group Sub Task Label", } ], "id": "task_group.inner_task_group", - "label": "inner_task_group", + "label": "My Inner Task Group", }, {"id": "task_group.mapped_task", "is_mapped": True, "label": "mapped_task"}, ], @@ -688,3 +723,16 @@ def sort_dict(in_dict): expected = sort_dict(expected) actual = sort_dict(actual) assert actual == expected + + def test_structure_includes_historical_removed_task_with_proper_shape(self, session, test_client): + # Ensure the structure endpoint returns synthetic node for historical/removed task + response = test_client.get(f"/grid/structure/{DAG_ID_3}") + assert response.status_code == 200 + nodes = response.json() + # Find the historical removed task id + t4 = next((n for n in nodes if n["id"] == TASK_ID_4), None) + assert t4 is not None + assert t4["label"] == TASK_ID_4 + # Optional None fields are excluded from response due to response_model_exclude_none=True + assert "is_mapped" not in t4 + assert "children" not in t4 diff --git a/airflow-core/tests/unit/api_fastapi/core_api/test_security.py b/airflow-core/tests/unit/api_fastapi/core_api/test_security.py index 29efa6eae0ece..96d7451c8f26f 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/test_security.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/test_security.py @@ -23,6 +23,7 @@ from jwt import ExpiredSignatureError, InvalidTokenError from airflow.api_fastapi.app import create_app +from airflow.api_fastapi.auth.managers.base_auth_manager import COOKIE_NAME_JWT_TOKEN from airflow.api_fastapi.auth.managers.models.resource_details import ( ConnectionDetails, DagAccessEntity, @@ -35,6 +36,7 @@ from airflow.api_fastapi.core_api.datamodels.pools import PoolBody from airflow.api_fastapi.core_api.datamodels.variables import VariableBody from airflow.api_fastapi.core_api.security import ( + get_user, is_safe_url, requires_access_connection, requires_access_connection_bulk, @@ -104,6 +106,46 @@ async def test_get_user_expired_token(self, mock_get_auth_manager): auth_manager.get_user_from_token.assert_called_once_with(token_str) + @patch("airflow.api_fastapi.core_api.security.resolve_user_from_token") + async def test_get_user_with_request_state(self, mock_resolve_user_from_token): + user = Mock() + request = Mock() + request.state.user = user + + result = await get_user(request, None, None) + + assert result == user + mock_resolve_user_from_token.assert_not_called() + + @pytest.mark.parametrize( + "oauth_token, bearer_credentials_creds, cookies, expected", + [ + ("oauth_token", None, {}, "oauth_token"), + (None, "bearer_credentials_creds", {}, "bearer_credentials_creds"), + (None, None, {COOKIE_NAME_JWT_TOKEN: "cookie_token"}, "cookie_token"), + ], + ) + @patch("airflow.api_fastapi.core_api.security.resolve_user_from_token") + async def test_get_user_with_token( + self, mock_resolve_user_from_token, oauth_token, bearer_credentials_creds, cookies, expected + ): + user = Mock() + mock_resolve_user_from_token.return_value = user + + request = Mock() + request.state.user = None + request.cookies = cookies + bearer_credentials = None + if bearer_credentials_creds: + bearer_credentials = Mock() + bearer_credentials.scheme = "bearer" + bearer_credentials.credentials = bearer_credentials_creds + + result = await get_user(request, oauth_token, bearer_credentials) + + assert result == user + mock_resolve_user_from_token.assert_called_once_with(expected) + @pytest.mark.db_test @patch("airflow.api_fastapi.core_api.security.get_auth_manager") async def test_requires_access_dag_authorized(self, mock_get_auth_manager): @@ -154,6 +196,12 @@ async def test_requires_access_dag_unauthorized(self, mock_get_auth_manager): ("/some_other_page/", False), # traversal, escaping the `prefix` folder ("/../../../../some_page?with_param=3", False), + # encoded url + ("https%3A%2F%2Frequesting_server_base_url.com%2Fprefix2", True), + ("https%3A%2F%2Fserver_base_url.com%2Fprefix", True), + ("https%3A%2F%2Fsome_netlock.com%2Fprefix%2Fsome_page%3Fwith_param%3D3", False), + ("https%3A%2F%2Frequesting_server_base_url.com%2Fprefix2%2Fsub_path", True), + ("%2F..%2F..%2F..%2F..%2Fsome_page%3Fwith_param%3D3", False), ], ) @conf_vars({("api", "base_url"): "https://server_base_url.com/prefix"}) @@ -162,6 +210,23 @@ def test_is_safe_url(self, url, expected_is_safe): request.base_url = "https://requesting_server_base_url.com/prefix2" assert is_safe_url(url, request=request) == expected_is_safe + @pytest.mark.parametrize( + "url, expected_is_safe", + [ + ("https://server_base_url.com/prefix", False), + ("https://requesting_server_base_url.com/prefix2", True), + ("prefix/some_other", False), + ("https%3A%2F%2Fserver_base_url.com%2Fprefix", False), + ("https%3A%2F%2Frequesting_server_base_url.com%2Fprefix2", True), + ("https%3A%2F%2Frequesting_server_base_url.com%2Fprefix2%2Fsub_path", True), + ("%2F..%2F..%2F..%2F..%2Fsome_page%3Fwith_param%3D3", False), + ], + ) + def test_is_safe_url_with_base_url_unset(self, url, expected_is_safe): + request = Mock() + request.base_url = "https://requesting_server_base_url.com/prefix2" + assert is_safe_url(url, request=request) == expected_is_safe + @pytest.mark.db_test @pytest.mark.parametrize( "team_name", @@ -206,6 +271,13 @@ async def test_requires_access_connection_bulk(self, mock_get_auth_manager): "action": "delete", "entities": ["test3"], }, + { + "action": "create", + "entities": [ + {"connection_id": "test4", "conn_type": "test4"}, + ], + "action_on_existence": "overwrite", + }, ] } ) @@ -226,6 +298,14 @@ async def test_requires_access_connection_bulk(self, mock_get_auth_manager): "method": "DELETE", "details": ConnectionDetails(conn_id="test3"), }, + { + "method": "POST", + "details": ConnectionDetails(conn_id="test4"), + }, + { + "method": "PUT", + "details": ConnectionDetails(conn_id="test4"), + }, ], user=user, ) @@ -274,6 +354,13 @@ async def test_requires_access_variable_bulk(self, mock_get_auth_manager): "action": "delete", "entities": ["var3"], }, + { + "action": "create", + "entities": [ + {"key": "var4", "value": "value4"}, + ], + "action_on_existence": "overwrite", + }, ] } ) @@ -294,6 +381,14 @@ async def test_requires_access_variable_bulk(self, mock_get_auth_manager): "method": "DELETE", "details": VariableDetails(key="var3"), }, + { + "method": "POST", + "details": VariableDetails(key="var4"), + }, + { + "method": "PUT", + "details": VariableDetails(key="var4"), + }, ], user=user, ) @@ -342,6 +437,13 @@ async def test_requires_access_pool_bulk(self, mock_get_auth_manager): "action": "delete", "entities": ["pool3"], }, + { + "action": "create", + "entities": [ + {"pool": "pool4", "slots": 1}, + ], + "action_on_existence": "overwrite", + }, ] } ) @@ -362,6 +464,14 @@ async def test_requires_access_pool_bulk(self, mock_get_auth_manager): "method": "DELETE", "details": PoolDetails(name="pool3"), }, + { + "method": "POST", + "details": PoolDetails(name="pool4"), + }, + { + "method": "PUT", + "details": PoolDetails(name="pool4"), + }, ], user=user, ) diff --git a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_hitl.py b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_hitl.py index 085fc7ae6a8b3..b587b35ee2803 100644 --- a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_hitl.py +++ b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_hitl.py @@ -45,13 +45,12 @@ "defaults": ["Approve"], "multiple": False, "params": {"input_1": 1}, - "respondents": None, + "assignees": None, } expected_empty_hitl_detail_response_part: dict[str, Any] = { - "response_at": None, + "responded_at": None, "chosen_options": None, - "responded_user_id": None, - "responded_user_name": None, + "responded_by_user": None, "params_input": {}, "response_received": False, } @@ -92,10 +91,9 @@ def expected_sample_hitl_detail_dict(sample_ti: TaskInstance) -> dict[str, Any]: **default_hitl_detail_request_kwargs, **{ "params_input": {"input_1": 2}, - "response_at": convert_to_utc(datetime(2025, 7, 3, 0, 0, 0)), + "responded_at": convert_to_utc(datetime(2025, 7, 3, 0, 0, 0)), "chosen_options": ["Reject"], - "responded_user_id": "Fallback to defaults", - "responded_user_name": "Fallback to defaults", + "responded_by": None, }, }, ], @@ -125,11 +123,15 @@ def test_upsert_hitl_detail( **default_hitl_detail_request_kwargs, }, ) - assert response.status_code == 201 - assert response.json() == { + + expected_json = { "ti_id": ti.id, **default_hitl_detail_request_kwargs, } + expected_json["assigned_users"] = expected_json.pop("assignees") or [] + + assert response.status_code == 201 + assert response.json() == expected_json def test_upsert_hitl_detail_with_empty_option( @@ -169,11 +171,10 @@ def test_update_hitl_detail(client: Client, sample_ti: TaskInstance) -> None: assert response.status_code == 200 assert response.json() == { "params_input": {"input_1": 2}, - "response_at": "2025-07-03T00:00:00Z", + "responded_at": "2025-07-03T00:00:00Z", "chosen_options": ["Reject"], "response_received": True, - "responded_user_id": "Fallback to defaults", - "responded_user_name": "Fallback to defaults", + "responded_by_user": None, } diff --git a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_task_instances.py b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_task_instances.py index 4efaaa75eee8b..899bf3ba82d5c 100644 --- a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_task_instances.py +++ b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_task_instances.py @@ -782,40 +782,6 @@ def test_ti_update_state_to_success_with_asset_events( assert event[0].asset == AssetModel(name="my-task", uri="s3://bucket/my-task", extra={}) assert event[0].extra == expected_extra - def test_ti_update_state_to_failed_with_inactive_asset(self, client, session, create_task_instance): - # inactive - asset = AssetModel( - id=1, - name="my-task-2", - uri="s3://bucket/my-task", - group="asset", - extra={}, - ) - session.add(asset) - - ti = create_task_instance( - task_id="test_ti_update_state_to_success_with_asset_events", - start_date=DEFAULT_START_DATE, - state=State.RUNNING, - ) - session.commit() - - response = client.patch( - f"/execution/task-instances/{ti.id}/state", - json={ - "state": "success", - "end_date": DEFAULT_END_DATE.isoformat(), - "task_outlets": [{"name": "my-task-2", "uri": "s3://bucket/my-task", "type": "Asset"}], - "outlet_events": [], - }, - ) - - assert response.status_code == 204 - session.expire_all() - - ti = session.get(TaskInstance, ti.id) - assert ti.state == State.FAILED - @pytest.mark.parametrize( "outlet_events, expected_extra", [ @@ -1129,6 +1095,50 @@ def test_ti_update_state_handle_retry(self, client, session, create_task_instanc assert tih.task_instance_id assert tih.task_instance_id != ti.id + @pytest.mark.parametrize( + "target_state", + [ + State.UP_FOR_RETRY, + TerminalTIState.FAILED, + TerminalTIState.SUCCESS, + ], + ) + def test_ti_update_state_clears_deferred_fields( + self, client, session, create_task_instance, target_state + ): + """Test that next_method and next_kwargs are cleared when transitioning to terminal/retry states.""" + ti = create_task_instance( + task_id="test_ti_update_state_clears_deferred_fields", + state=State.RUNNING, + ) + # Simulate a task that resumed from deferred state with next_method/next_kwargs set + ti.next_method = "execute_complete" + ti.next_kwargs = {"event": "test_event", "data": "test_data"} + session.commit() + + response = client.patch( + f"/execution/task-instances/{ti.id}/state", + json={ + "state": target_state, + "end_date": DEFAULT_END_DATE.isoformat(), + }, + ) + + assert response.status_code == 204 + + if target_state == State.UP_FOR_RETRY: + # Retry creates a new TI ID, so we need to fetch by unique key + ti = session.scalar( + select(TaskInstance).filter_by(task_id=ti.task_id, run_id=ti.run_id, dag_id=ti.dag_id) + ) + else: + session.expire_all() + ti = session.get(TaskInstance, ti.id) + + assert ti.state == target_state + assert ti.next_method is None + assert ti.next_kwargs is None + def test_ti_update_state_to_failed_table_check(self, client, session, create_task_instance): # we just want to fail in this test, no need to retry ti = create_task_instance( diff --git a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_variables.py b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_variables.py index 0ada165ed5b9c..0e112ad330aa6 100644 --- a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_variables.py +++ b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_variables.py @@ -65,17 +65,24 @@ async def _(request: Request, variable_key: str, token=JWTBearerDep): class TestGetVariable: - def test_variable_get_from_db(self, client, session): - Variable.set(key="var1", value="value", session=session) + @pytest.mark.parametrize( + "key, value", + [ + ("var1", "value"), + ("var2/with_slash", "slash_value"), + ], + ) + def test_variable_get_from_db(self, client, session, key, value): + Variable.set(key=key, value=value, session=session) session.commit() - response = client.get("/execution/variables/var1") + response = client.get(f"/execution/variables/{key}") assert response.status_code == 200 - assert response.json() == {"key": "var1", "value": "value"} + assert response.json() == {"key": key, "value": value} # Remove connection - Variable.delete(key="var1", session=session) + Variable.delete(key=key, session=session) session.commit() @mock.patch.dict( @@ -88,13 +95,20 @@ def test_variable_get_from_env_var(self, client, session): assert response.status_code == 200 assert response.json() == {"key": "key1", "value": "VALUE"} - def test_variable_get_not_found(self, client): - response = client.get("/execution/variables/non_existent_var") + @pytest.mark.parametrize( + "key", + [ + "non_existent_var", + "non/existent/slash/var", + ], + ) + def test_variable_get_not_found(self, client, key): + response = client.get(f"/execution/variables/{key}") assert response.status_code == 404 assert response.json() == { "detail": { - "message": "Variable with key 'non_existent_var' not found", + "message": f"Variable with key '{key}' not found", "reason": "not_found", } } @@ -117,14 +131,18 @@ def test_variable_get_access_denied(self, client, caplog): class TestPutVariable: @pytest.mark.parametrize( - "payload", + "key, payload", [ - pytest.param({"value": "{}", "description": "description"}, id="valid-payload"), - pytest.param({"value": "{}"}, id="missing-description"), + pytest.param("var_create", {"value": "{}", "description": "description"}, id="valid-payload"), + pytest.param("var_create", {"value": "{}"}, id="missing-description"), + pytest.param( + "var_create/with_slash", + {"value": "slash_value", "description": "Variable with slash"}, + id="slash-key", + ), ], ) - def test_should_create_variable(self, client, payload, session): - key = "var_create" + def test_should_create_variable(self, client, key, payload, session): response = client.put( f"/execution/variables/{key}", json=payload, @@ -132,7 +150,7 @@ def test_should_create_variable(self, client, payload, session): assert response.status_code == 201, response.json() assert response.json()["message"] == "Variable successfully set" - var_from_db = session.query(Variable).where(Variable.key == "var_create").first() + var_from_db = session.query(Variable).where(Variable.key == key).first() assert var_from_db is not None assert var_from_db.key == key assert var_from_db.val == payload["value"] @@ -179,8 +197,14 @@ def test_variable_adding_extra_fields(self, client, key, payload, session): assert response.json()["detail"][0]["type"] == "extra_forbidden" assert response.json()["detail"][0]["msg"] == "Extra inputs are not permitted" - def test_overwriting_existing_variable(self, client, session): - key = "var_create" + @pytest.mark.parametrize( + "key", + [ + "var_create", + "var_create/with_slash", + ], + ) + def test_overwriting_existing_variable(self, client, session, key): Variable.set(key=key, value="value", session=session) session.commit() @@ -218,19 +242,26 @@ def test_post_variable_access_denied(self, client, caplog): class TestDeleteVariable: - def test_should_delete_variable(self, client, session): - for i in range(1, 3): - Variable.set(key=f"key{i}", value=i) + @pytest.mark.parametrize( + "keys_to_create, key_to_delete", + [ + (["key1", "key2"], "key1"), + (["key3/with_slash", "key4"], "key3/with_slash"), + ], + ) + def test_should_delete_variable(self, client, session, keys_to_create, key_to_delete): + for i, key in enumerate(keys_to_create, 1): + Variable.set(key=key, value=str(i)) vars = session.query(Variable).all() - assert len(vars) == 2 + assert len(vars) == len(keys_to_create) - response = client.delete("/execution/variables/key1") + response = client.delete(f"/execution/variables/{key_to_delete}") assert response.status_code == 204 vars = session.query(Variable).all() - assert len(vars) == 1 + assert len(vars) == len(keys_to_create) - 1 def test_should_not_delete_variable(self, client, session): Variable.set(key="key", value="value") diff --git a/airflow-core/tests/unit/api_fastapi/test_app.py b/airflow-core/tests/unit/api_fastapi/test_app.py index d708aae2edf82..448d527ab6b6b 100644 --- a/airflow-core/tests/unit/api_fastapi/test_app.py +++ b/airflow-core/tests/unit/api_fastapi/test_app.py @@ -19,6 +19,10 @@ from unittest import mock import pytest +from fastapi import FastAPI + +import airflow.api_fastapi.app as app_module +import airflow.plugins_manager as plugins_manager pytestmark = pytest.mark.db_test @@ -90,3 +94,27 @@ def test_catch_all_route_last(client): """ test_app = client(apps="all").app assert test_app.routes[-1].path == "/{rest_of_path:path}" + + +@pytest.mark.parametrize( + "fastapi_apps, expected_message, invalid_path", + [ + ( + [{"name": "test", "app": FastAPI(), "url_prefix": ""}], + "'url_prefix' key is empty string for the fastapi app: test", + "", + ), + ( + [{"name": "test", "app": FastAPI(), "url_prefix": next(iter(app_module.RESERVED_URL_PREFIXES))}], + "attempted to use reserved url_prefix", + next(iter(app_module.RESERVED_URL_PREFIXES)), + ), + ], +) +def test_plugin_with_invalid_url_prefix(caplog, fastapi_apps, expected_message, invalid_path): + app = FastAPI() + with mock.patch.object(plugins_manager, "fastapi_apps", fastapi_apps): + app_module.init_plugins(app) + + assert any(expected_message in rec.message for rec in caplog.records) + assert not any(r.path == invalid_path for r in app.routes) diff --git a/airflow-core/tests/unit/callbacks/test_callback_requests.py b/airflow-core/tests/unit/callbacks/test_callback_requests.py index 428ee34d166e0..8f1d959e27ec3 100644 --- a/airflow-core/tests/unit/callbacks/test_callback_requests.py +++ b/airflow-core/tests/unit/callbacks/test_callback_requests.py @@ -32,7 +32,7 @@ CallbackRequest, DagCallbackRequest, DagRunContext, - EmailNotificationRequest, + EmailRequest, TaskCallbackRequest, ) from airflow.models.dag import DAG @@ -314,9 +314,9 @@ def test_dag_callback_request_serialization_with_context(self): assert result.context_from_server.last_ti.task_id == "test_task" -class TestEmailNotificationRequest: +class TestEmailRequest: def test_email_notification_request_serialization(self): - """Test EmailNotificationRequest can be serialized and used in CallbackRequest union.""" + """Test EmailRequest can be serialized and used in CallbackRequest union.""" ti_data = TIDataModel( id=str(uuid.uuid4()), task_id="test_task", @@ -331,8 +331,8 @@ def test_email_notification_request_serialization(self): current_time = timezone.utcnow() - # Create EmailNotificationRequest - email_request = EmailNotificationRequest( + # Create EmailRequest + email_request = EmailRequest( filepath="/path/to/dag.py", bundle_name="test_bundle", bundle_version="1.0.0", @@ -359,17 +359,17 @@ def test_email_notification_request_serialization(self): # Test serialization json_str = email_request.to_json() - assert "EmailNotificationRequest" in json_str + assert "EmailRequest" in json_str assert "failure" in json_str # Test deserialization - result = EmailNotificationRequest.from_json(json_str) + result = EmailRequest.from_json(json_str) assert result == email_request assert result.email_type == "failure" assert result.ti.task_id == "test_task" def test_callback_request_union_with_email_notification(self): - """Test EmailNotificationRequest works in CallbackRequest union type.""" + """Test EmailRequest works in CallbackRequest union type.""" ti_data = TIDataModel( id=str(uuid.uuid4()), task_id="test_task", @@ -402,7 +402,7 @@ def test_callback_request_union_with_email_notification(self): ) email_data = { - "type": "EmailNotificationRequest", + "type": "EmailRequest", "filepath": "/path/to/dag.py", "bundle_name": "test_bundle", "bundle_version": "1.0.0", @@ -416,7 +416,7 @@ def test_callback_request_union_with_email_notification(self): adapter = TypeAdapter(CallbackRequest) callback_request = adapter.validate_python(email_data) - # Verify it's correctly identified as EmailNotificationRequest - assert isinstance(callback_request, EmailNotificationRequest) + # Verify it's correctly identified as EmailRequest + assert isinstance(callback_request, EmailRequest) assert callback_request.email_type == "retry" assert callback_request.ti.task_id == "test_task" diff --git a/airflow-core/tests/unit/cli/commands/test_backfill_command.py b/airflow-core/tests/unit/cli/commands/test_backfill_command.py index 13da9fe66ac9b..ad682ecc442bf 100644 --- a/airflow-core/tests/unit/cli/commands/test_backfill_command.py +++ b/airflow-core/tests/unit/cli/commands/test_backfill_command.py @@ -162,3 +162,78 @@ def test_backfill_dry_run(self, mock_dry_run, reverse): reprocess_behavior="none", session=mock.ANY, ) + + @mock.patch("airflow.cli.commands.backfill_command._create_backfill") + def test_backfill_with_dag_run_conf(self, mock_create): + """Test that dag_run_conf is properly parsed from JSON string.""" + args = [ + "backfill", + "create", + "--dag-id", + "example_bash_operator", + "--from-date", + DEFAULT_DATE.isoformat(), + "--to-date", + DEFAULT_DATE.isoformat(), + "--dag-run-conf", + '{"example_key": "example_value"}', + ] + airflow.cli.commands.backfill_command.create_backfill(self.parser.parse_args(args)) + + mock_create.assert_called_once_with( + dag_id="example_bash_operator", + from_date=DEFAULT_DATE, + to_date=DEFAULT_DATE, + max_active_runs=None, + reverse=False, + dag_run_conf={"example_key": "example_value"}, + reprocess_behavior=None, + triggering_user_name="root", + run_on_latest_version=False, + ) + + def test_backfill_with_invalid_dag_run_conf(self): + """Test that invalid JSON in dag_run_conf raises ValueError.""" + args = [ + "backfill", + "create", + "--dag-id", + "example_bash_operator", + "--from-date", + DEFAULT_DATE.isoformat(), + "--to-date", + DEFAULT_DATE.isoformat(), + "--dag-run-conf", + '{"invalid": json}', # Invalid JSON + ] + with pytest.raises(ValueError, match="Invalid JSON in --dag-run-conf"): + airflow.cli.commands.backfill_command.create_backfill(self.parser.parse_args(args)) + + @mock.patch("airflow.cli.commands.backfill_command._create_backfill") + def test_backfill_with_empty_dag_run_conf(self, mock_create): + """Test that empty dag_run_conf is properly parsed.""" + args = [ + "backfill", + "create", + "--dag-id", + "example_bash_operator", + "--from-date", + DEFAULT_DATE.isoformat(), + "--to-date", + DEFAULT_DATE.isoformat(), + "--dag-run-conf", + "{}", + ] + airflow.cli.commands.backfill_command.create_backfill(self.parser.parse_args(args)) + + mock_create.assert_called_once_with( + dag_id="example_bash_operator", + from_date=DEFAULT_DATE, + to_date=DEFAULT_DATE, + max_active_runs=None, + reverse=False, + dag_run_conf={}, + reprocess_behavior=None, + triggering_user_name="root", + run_on_latest_version=False, + ) diff --git a/airflow-core/tests/unit/cli/commands/test_db_command.py b/airflow-core/tests/unit/cli/commands/test_db_command.py index 8a6ff6dd4ca35..cd7d61f5f2467 100644 --- a/airflow-core/tests/unit/cli/commands/test_db_command.py +++ b/airflow-core/tests/unit/cli/commands/test_db_command.py @@ -47,6 +47,118 @@ def test_cli_resetdb_skip_init(self, mock_resetdb): db_command.resetdb(self.parser.parse_args(["db", "reset", "--yes", "--skip-init"])) mock_resetdb.assert_called_once_with(skip_init=True) + def test_run_db_migrate_command_success_and_messages(self, capsys): + class Args: + to_revision = None + to_version = None + from_revision = None + from_version = None + show_sql_only = False + + called = {} + + def fake_command(**kwargs): + called.update(kwargs) + + heads = {"2.10.0": "22ed7efa9da2"} + + db_command.run_db_migrate_command(Args(), fake_command, heads) + out = capsys.readouterr().out + assert "Performing upgrade" in out + assert "Database migrating done!" in out + assert called == {"to_revision": None, "from_revision": None, "show_sql_only": False} + + def test_run_db_migrate_command_offline_generation(self, capsys): + class Args: + to_revision = None + to_version = None + from_revision = None + from_version = None + show_sql_only = True + + called = {} + + def fake_command(**kwargs): + called.update(kwargs) + + heads = {"2.10.0": "22ed7efa9da2"} + + db_command.run_db_migrate_command(Args(), fake_command, heads) + out = capsys.readouterr().out + assert "Generating sql for upgrade" in out + assert called == {"to_revision": None, "from_revision": None, "show_sql_only": True} + + @pytest.mark.parametrize( + "args, match", + [ + ( + { + "to_revision": "abc", + "to_version": "2.10.0", + "from_revision": None, + "from_version": None, + "show_sql_only": False, + }, + "Cannot supply both", + ), + ( + { + "to_revision": None, + "to_version": None, + "from_revision": "abc", + "from_version": "2.10.0", + "show_sql_only": True, + }, + "Cannot supply both", + ), + ( + { + "to_revision": None, + "to_version": None, + "from_revision": "abc", + "from_version": None, + "show_sql_only": False, + }, + "only .* with `--show-sql-only`", + ), + ( + { + "to_revision": None, + "to_version": "abc", + "from_revision": None, + "from_version": None, + "show_sql_only": False, + }, + "Invalid version", + ), + ( + { + "to_revision": None, + "to_version": "2.1.25", + "from_revision": None, + "from_version": None, + "show_sql_only": False, + }, + "Unknown version", + ), + ], + ) + def test_run_db_migrate_command_validation_errors(self, args, match): + class Args: + to_revision = args["to_revision"] + to_version = args["to_version"] + from_revision = args["from_revision"] + from_version = args["from_version"] + show_sql_only = args["show_sql_only"] + + def fake_command(**kwargs): + pass + + heads = {"2.10.0": "22ed7efa9da2"} + + with pytest.raises(SystemExit, match=match): + db_command.run_db_migrate_command(Args(), fake_command, heads) + @mock.patch("airflow.cli.commands.db_command.db.check_migrations") def test_cli_check_migrations(self, mock_wait_for_migrations): db_command.check_migrations(self.parser.parse_args(["db", "check-migrations"])) @@ -317,6 +429,170 @@ def test_cli_shell_invalid_ppg3(self): with pytest.raises(AirflowException, match=r"Unknown driver: invalid\+psycopg"): db_command.shell(self.parser.parse_args(["db", "shell"])) + def test_run_db_downgrade_command_success_and_messages(self, capsys): + class Args: + to_revision = "abc" + to_version = None + from_revision = None + from_version = None + show_sql_only = False + yes = True + + called = {} + + def fake_command(**kwargs): + called.update(kwargs) + + heads = {"2.10.0": "22ed7efa9da2"} + + db_command.run_db_downgrade_command(Args(), fake_command, heads) + out = capsys.readouterr().out + assert "Performing downgrade" in out + assert "Downgrade complete" in out + assert called == {"to_revision": "abc", "from_revision": None, "show_sql_only": False} + + def test_run_db_downgrade_command_offline_generation(self, capsys): + class Args: + to_revision = None + to_version = "2.10.0" + from_revision = None + from_version = None + show_sql_only = True + yes = False + + called = {} + + def fake_command(**kwargs): + called.update(kwargs) + + heads = {"2.10.0": "22ed7efa9da2"} + + db_command.run_db_downgrade_command(Args(), fake_command, heads) + out = capsys.readouterr().out + assert "Generating sql for downgrade" in out + assert called == {"to_revision": "22ed7efa9da2", "from_revision": None, "show_sql_only": True} + + @pytest.mark.parametrize( + "args, match", + [ + ( + { + "to_revision": None, + "to_version": None, + "from_revision": None, + "from_version": None, + "show_sql_only": False, + "yes": False, + }, + "Must provide either", + ), + ( + { + "to_revision": "abc", + "to_version": "2.10.0", + "from_revision": None, + "from_version": None, + "show_sql_only": False, + "yes": True, + }, + "Cannot supply both", + ), + ( + { + "to_revision": "abc", + "to_version": None, + "from_revision": "abc1", + "from_version": "2.10.0", + "show_sql_only": True, + "yes": True, + }, + "may not be combined", + ), + ( + { + "to_revision": None, + "to_version": "2.1.25", + "from_revision": None, + "from_version": None, + "show_sql_only": False, + "yes": True, + }, + "not supported", + ), + ( + { + "to_revision": None, + "to_version": None, + "from_revision": "abc", + "from_version": None, + "show_sql_only": False, + "yes": True, + }, + "only .* with `--show-sql-only`", + ), + ], + ) + def test_run_db_downgrade_command_validation_errors(self, args, match): + class Args: + to_revision = args["to_revision"] + to_version = args["to_version"] + from_revision = args["from_revision"] + from_version = args["from_version"] + show_sql_only = args["show_sql_only"] + yes = args["yes"] + + def fake_command(**kwargs): + pass + + heads = {"2.10.0": "22ed7efa9da2"} + + with pytest.raises(SystemExit, match=match): + db_command.run_db_downgrade_command(Args(), fake_command, heads) + + @mock.patch("airflow.cli.commands.db_command.input") + def test_run_db_downgrade_command_confirmation_yes_calls_command(self, mock_input, capsys): + mock_input.return_value = "Y" + + class Args: + to_revision = "abc" + to_version = None + from_revision = None + from_version = None + show_sql_only = False + yes = False + + called = {} + + def fake_command(**kwargs): + called.update(kwargs) + + heads = {"2.10.0": "22ed7efa9da2"} + + db_command.run_db_downgrade_command(Args(), fake_command, heads) + out = capsys.readouterr().out + assert "Performing downgrade" in out + assert called == {"to_revision": "abc", "from_revision": None, "show_sql_only": False} + + @mock.patch("airflow.cli.commands.db_command.input") + def test_run_db_downgrade_command_confirmation_no_cancels(self, mock_input): + mock_input.return_value = "n" + + class Args: + to_revision = "abc" + to_version = None + from_revision = None + from_version = None + show_sql_only = False + yes = False + + def fake_command(**kwargs): + raise AssertionError("Command should not be called when cancelled") + + heads = {"2.10.0": "22ed7efa9da2"} + + with pytest.raises(SystemExit, match="Cancelled"): + db_command.run_db_downgrade_command(Args(), fake_command, heads) + @pytest.mark.parametrize( "args, match", [ diff --git a/airflow-core/tests/unit/cli/commands/test_db_manager_command.py b/airflow-core/tests/unit/cli/commands/test_db_manager_command.py index a5e2ae58d102e..df202594205e4 100644 --- a/airflow-core/tests/unit/cli/commands/test_db_manager_command.py +++ b/airflow-core/tests/unit/cli/commands/test_db_manager_command.py @@ -22,48 +22,201 @@ from airflow.cli import cli_parser from airflow.cli.commands import db_manager_command +from airflow.utils.db_manager import BaseDBManager from tests_common.test_utils.config import conf_vars pytestmark = pytest.mark.db_test +class FakeDBManager(BaseDBManager): + metadata = mock.MagicMock() + migration_dir = "migrations" + alembic_file = "alembic.ini" + version_table_name = "alembic_version_ext" + revision_heads_map = {} + + # Test controls + raise_on_init = False + instances: list[FakeDBManager] = [] + last_instance: FakeDBManager | None = None + + def __init__(self, session): + if self.raise_on_init: + raise AssertionError("Should not instantiate manager when cancelled") + super().__init__(session) + self._resetdb_mock = mock.MagicMock(name="resetdb") + self._upgradedb_mock = mock.MagicMock(name="upgradedb") + self._downgrade_mock = mock.MagicMock(name="downgrade") + FakeDBManager.instances.append(self) + FakeDBManager.last_instance = self + + def resetdb(self, skip_init=False): + return self._resetdb_mock(skip_init=skip_init) + + def upgradedb(self, to_revision=None, from_revision=None, show_sql_only=False): + return self._upgradedb_mock( + to_revision=to_revision, from_revision=from_revision, show_sql_only=show_sql_only + ) + + def downgrade(self, to_revision, from_revision=None, show_sql_only=False): + return self._downgrade_mock( + to_revision=to_revision, from_revision=from_revision, show_sql_only=show_sql_only + ) + + +@pytest.fixture(autouse=True) +def _reset_fake_db_manager(): + FakeDBManager.revision_heads_map = {} + FakeDBManager.raise_on_init = False + FakeDBManager.instances = [] + FakeDBManager.last_instance = None + return None + + class TestCliDbManager: @classmethod def setup_class(cls): cls.parser = cli_parser.get_parser() + @mock.patch("airflow.cli.commands.db_manager_command.settings.Session", autospec=True) @mock.patch("airflow.cli.commands.db_manager_command._get_db_manager") - def test_cli_resetdb(self, mock_get_db_manager): - manager_name = "path.to.TestDBManager" - db_manager_command.resetdb(self.parser.parse_args(["db-manager", "reset", manager_name, "--yes"])) - mock_get_db_manager.assert_called_once_with("path.to.TestDBManager") - mock_get_db_manager.return_value.resetdb.asset_called_once() + def test_cli_resetdb_yes_calls_reset(self, mock_get_db_manager, mock_session): + manager_name = "path.to.FakeDBManager" + mock_get_db_manager.return_value = FakeDBManager + + args = self.parser.parse_args(["db-manager", "reset", manager_name, "--yes"]) + db_manager_command.resetdb(args) + + mock_get_db_manager.assert_called_once_with(manager_name) + assert len(FakeDBManager.instances) == 1 + FakeDBManager.last_instance._resetdb_mock.assert_called_once_with(skip_init=False) + @mock.patch("airflow.cli.commands.db_manager_command.settings.Session", autospec=True) @mock.patch("airflow.cli.commands.db_manager_command._get_db_manager") - def test_cli_resetdb_skip_init(self, mock_get_db_manager): - manager_name = "path.to.TestDBManager" - db_manager_command.resetdb( - self.parser.parse_args(["db-manager", "reset", manager_name, "--yes", "--skip-init"]) - ) + def test_cli_resetdb_skip_init(self, mock_get_db_manager, mock_session): + manager_name = "path.to.FakeDBManager" + mock_get_db_manager.return_value = FakeDBManager + + args = self.parser.parse_args(["db-manager", "reset", manager_name, "--yes", "--skip-init"]) + db_manager_command.resetdb(args) mock_get_db_manager.assert_called_once_with(manager_name) - mock_get_db_manager.return_value.resetdb.asset_called_once_with(skip_init=True) + assert len(FakeDBManager.instances) == 1 + FakeDBManager.last_instance._resetdb_mock.assert_called_once_with(skip_init=True) + + @mock.patch("airflow.cli.commands.db_manager_command.input") + @mock.patch("airflow.cli.commands.db_manager_command._get_db_manager") + def test_cli_resetdb_prompt_yes(self, mock_get_db_manager, mock_input): + mock_input.return_value = "Y" + manager_name = "path.to.FakeDBManager" + mock_get_db_manager.return_value = FakeDBManager + args = self.parser.parse_args(["db-manager", "reset", manager_name]) + db_manager_command.resetdb(args) + assert len(FakeDBManager.instances) == 1 + FakeDBManager.last_instance._resetdb_mock.assert_called_once_with(skip_init=False) + @mock.patch("airflow.cli.commands.db_manager_command.input") + @mock.patch("airflow.cli.commands.db_manager_command._get_db_manager") + def test_cli_resetdb_prompt_cancel(self, mock_get_db_manager, mock_input): + mock_input.return_value = "n" + manager_name = "path.to.FakeDBManager" + FakeDBManager.raise_on_init = True + mock_get_db_manager.return_value = FakeDBManager + args = self.parser.parse_args(["db-manager", "reset", manager_name]) + with pytest.raises(SystemExit, match="Cancelled"): + db_manager_command.resetdb(args) + assert FakeDBManager.instances == [] + + @mock.patch("airflow.cli.commands.db_manager_command.settings.Session", autospec=True) @mock.patch("airflow.cli.commands.db_manager_command._get_db_manager") @mock.patch("airflow.cli.commands.db_manager_command.run_db_migrate_command") - def test_cli_migrate_db(self, mock_run_db_migrate_cmd, mock_get_db_manager): - manager_name = "path.to.TestDBManager" - db_manager_command.migratedb(self.parser.parse_args(["db-manager", "migrate", manager_name])) + def test_cli_migrate_db(self, mock_run_db_migrate_cmd, mock_get_db_manager, mock_session): + manager_name = "path.to.FakeDBManager" + FakeDBManager.revision_heads_map = {"2.10.0": "22ed7efa9da2"} + mock_get_db_manager.return_value = FakeDBManager + + args = self.parser.parse_args(["db-manager", "migrate", manager_name]) + db_manager_command.migratedb(args) + mock_get_db_manager.assert_called_once_with(manager_name) - mock_run_db_migrate_cmd.assert_called_once() + assert len(FakeDBManager.instances) == 1 + # Validate run_db_migrate_command was called with the instance's upgradedb and correct heads map + called_args, called_kwargs = mock_run_db_migrate_cmd.call_args + assert called_args[0] is args + # Verify the bound method refers to the instance's upgradedb implementation + assert called_args[1].__self__ is FakeDBManager.last_instance + assert called_args[1].__func__ is FakeDBManager.upgradedb + assert called_kwargs["revision_heads_map"] == {"2.10.0": "22ed7efa9da2"} + + @mock.patch("airflow.cli.commands.db_manager_command.settings.Session", autospec=True) + @mock.patch("airflow.cli.commands.db_manager_command._get_db_manager") + def test_cli_migrate_db_calls_upgradedb_with_args(self, mock_get_db_manager, mock_session): + manager_name = "path.to.FakeDBManager" + mock_get_db_manager.return_value = FakeDBManager + + args = self.parser.parse_args( + [ + "db-manager", + "migrate", + manager_name, + "--to-revision", + "abc", + "--from-revision", + "def", + "--show-sql-only", + ] + ) + db_manager_command.migratedb(args) + + assert FakeDBManager.last_instance is not None + FakeDBManager.last_instance._upgradedb_mock.assert_called_once_with( + to_revision="abc", from_revision="def", show_sql_only=True + ) + @mock.patch("airflow.cli.commands.db_manager_command.settings.Session", autospec=True) + @mock.patch("airflow.cli.commands.db_manager_command._get_db_manager") + def test_cli_downgrade_db_calls_downgrade_with_args(self, mock_get_db_manager, mock_session): + manager_name = "path.to.FakeDBManager" + mock_get_db_manager.return_value = FakeDBManager + + args = self.parser.parse_args( + [ + "db-manager", + "downgrade", + manager_name, + "--to-revision", + "abc", + "--from-revision", + "def", + "--show-sql-only", + ] + ) + db_manager_command.downgrade(args) + + assert FakeDBManager.last_instance is not None + FakeDBManager.last_instance._downgrade_mock.assert_called_once_with( + to_revision="abc", from_revision="def", show_sql_only=True + ) + + @mock.patch("airflow.cli.commands.db_manager_command.settings.Session", autospec=True) @mock.patch("airflow.cli.commands.db_manager_command._get_db_manager") @mock.patch("airflow.cli.commands.db_manager_command.run_db_downgrade_command") - def test_cli_downgrade_db(self, mock_run_db_downgrade_cmd, mock_get_db_manager): - manager_name = "path.to.TestDBManager" - db_manager_command.downgrade(self.parser.parse_args(["db-manager", "downgrade", manager_name])) + def test_cli_downgrade_db(self, mock_run_db_downgrade_cmd, mock_get_db_manager, mock_session): + manager_name = "path.to.FakeDBManager" + FakeDBManager.revision_heads_map = {"2.10.0": "22ed7efa9da2"} + mock_get_db_manager.return_value = FakeDBManager + + args = self.parser.parse_args(["db-manager", "downgrade", manager_name]) + db_manager_command.downgrade(args) + mock_get_db_manager.assert_called_once_with(manager_name) - mock_run_db_downgrade_cmd.assert_called_once() + assert len(FakeDBManager.instances) == 1 + called_args, called_kwargs = mock_run_db_downgrade_cmd.call_args + assert called_args[0] is args + # Verify the bound method refers to the instance's downgrade implementation + assert called_args[1].__self__ is FakeDBManager.last_instance + assert called_args[1].__func__ is FakeDBManager.downgrade + assert called_kwargs["revision_heads_map"] == {"2.10.0": "22ed7efa9da2"} @conf_vars({("database", "external_db_managers"): "path.to.manager.TestDBManager"}) @mock.patch("airflow.cli.commands.db_manager_command.import_string") diff --git a/airflow-core/tests/unit/cli/commands/test_scheduler_command.py b/airflow-core/tests/unit/cli/commands/test_scheduler_command.py index 8c6958159d0b0..63630cb7fd62c 100644 --- a/airflow-core/tests/unit/cli/commands/test_scheduler_command.py +++ b/airflow-core/tests/unit/cli/commands/test_scheduler_command.py @@ -70,8 +70,7 @@ def test_skip_serve_logs(self, mock_process, mock_scheduler_job, executor): with conf_vars({("core", "executor"): executor}): reload(executor_loader) scheduler_command.scheduler(args) - with pytest.raises(AssertionError): - mock_process.assert_has_calls([mock.call(target=serve_logs)]) + assert mock_process.call_count == 0 @mock.patch("airflow.utils.db.check_and_run_migrations") @mock.patch("airflow.utils.db.synchronize_log_template") diff --git a/airflow-core/tests/unit/cli/commands/test_task_command.py b/airflow-core/tests/unit/cli/commands/test_task_command.py index bbe597d0b01c9..532324d06c6c7 100644 --- a/airflow-core/tests/unit/cli/commands/test_task_command.py +++ b/airflow-core/tests/unit/cli/commands/test_task_command.py @@ -21,7 +21,6 @@ import io import json import logging -import logging.config import os import shutil from argparse import ArgumentParser @@ -35,7 +34,6 @@ from airflow._shared.timezones import timezone from airflow.cli import cli_parser from airflow.cli.commands import task_command -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.configuration import conf from airflow.exceptions import DagRunNotFound from airflow.models import DagBag, DagModel, DagRun, TaskInstance @@ -89,7 +87,6 @@ class TestCliTasks: @classmethod def setup_class(cls): - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) parse_and_sync_to_db(os.devnull, include_examples=True) cls.parser = cli_parser.get_parser() clear_db_runs() diff --git a/airflow-core/tests/unit/cli/conftest.py b/airflow-core/tests/unit/cli/conftest.py index c7230d00e534c..d65ea767013bf 100644 --- a/airflow-core/tests/unit/cli/conftest.py +++ b/airflow-core/tests/unit/cli/conftest.py @@ -66,29 +66,37 @@ def parser(): return cli_parser.get_parser() +# The "*_capture" fixtures all ensure that the `caplog` fixture is loaded so that they dont get polluted with +# log messages + + @pytest.fixture -def stdout_capture(): +def stdout_capture(request): """Fixture that captures stdout only.""" + request.getfixturevalue("caplog") return StdoutCaptureManager() @pytest.fixture -def stderr_capture(): +def stderr_capture(request): """Fixture that captures stderr only.""" + request.getfixturevalue("caplog") return StderrCaptureManager() @pytest.fixture -def stream_capture(): +def stream_capture(request): """Fixture that returns a configurable stream capture manager.""" def _capture(stdout=True, stderr=False): + request.getfixturevalue("caplog") return StreamCaptureManager(capture_stdout=stdout, capture_stderr=stderr) return _capture @pytest.fixture -def combined_capture(): +def combined_capture(request): """Fixture that captures both stdout and stderr.""" + request.getfixturevalue("caplog") return CombinedCaptureManager() diff --git a/airflow-core/tests/unit/core/test_configuration.py b/airflow-core/tests/unit/core/test_configuration.py index 757804428a468..0735245f5098d 100644 --- a/airflow-core/tests/unit/core/test_configuration.py +++ b/airflow-core/tests/unit/core/test_configuration.py @@ -43,7 +43,7 @@ write_default_airflow_configuration_if_needed, ) from airflow.providers_manager import ProvidersManager -from airflow.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS +from airflow.sdk.execution_time.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS from tests_common.test_utils.config import conf_vars from tests_common.test_utils.markers import skip_if_force_lowest_dependencies_marker @@ -923,8 +923,10 @@ def test_initialize_secrets_backends_on_workers(self): backends = initialize_secrets_backends(DEFAULT_SECRETS_SEARCH_PATH_WORKERS) backend_classes = [backend.__class__.__name__ for backend in backends] - assert len(backends) == 2 + assert len(backends) == 3 assert "SystemsManagerParameterStoreBackend" in backend_classes + assert "EnvironmentVariablesBackend" in backend_classes + assert "ExecutionAPISecretsBackend" in backend_classes @skip_if_force_lowest_dependencies_marker @conf_vars( @@ -1631,21 +1633,21 @@ def test_future_warning_only_for_code_ref(self, key): def test_as_dict_raw(self): test_conf = AirflowConfigParser() raw_dict = test_conf.as_dict(raw=True) - assert "%%" in raw_dict["logging"]["log_format"] + assert "%%" in raw_dict["logging"]["simple_log_format"] def test_as_dict_not_raw(self): test_conf = AirflowConfigParser() raw_dict = test_conf.as_dict(raw=False) - assert "%%" not in raw_dict["logging"]["log_format"] + assert "%%" not in raw_dict["logging"]["simple_log_format"] def test_default_value_raw(self): test_conf = AirflowConfigParser() - log_format = test_conf.get_default_value("logging", "log_format", raw=True) + log_format = test_conf.get_default_value("logging", "simple_log_format", raw=True) assert "%%" in log_format def test_default_value_not_raw(self): test_conf = AirflowConfigParser() - log_format = test_conf.get_default_value("logging", "log_format", raw=False) + log_format = test_conf.get_default_value("logging", "simple_log_format", raw=False) assert "%%" not in log_format def test_default_value_raw_with_fallback(self): diff --git a/airflow-core/tests/unit/core/test_logging_config.py b/airflow-core/tests/unit/core/test_logging_config.py deleted file mode 100644 index b92a7f0bcfb0c..0000000000000 --- a/airflow-core/tests/unit/core/test_logging_config.py +++ /dev/null @@ -1,422 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -from __future__ import annotations - -import contextlib -import importlib -import logging -import os -import pathlib -import sys -import tempfile -from unittest.mock import call, patch - -import pytest - -from airflow.configuration import conf - -from tests_common.test_utils.config import conf_vars -from tests_common.test_utils.markers import skip_if_force_lowest_dependencies_marker - -pytestmark = skip_if_force_lowest_dependencies_marker - -SETTINGS_FILE_VALID = """ -LOGGING_CONFIG = { - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'airflow.task': { - 'format': '[%%(asctime)s] {{%%(filename)s:%%(lineno)d}} %%(levelname)s - %%(message)s' - }, - }, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'airflow.task', - 'stream': 'ext://sys.stdout' - }, - 'task': { - 'class': 'logging.StreamHandler', - 'formatter': 'airflow.task', - 'stream': 'ext://sys.stdout' - }, - }, - 'loggers': { - 'airflow.task': { - 'handlers': ['task'], - 'level': 'INFO', - 'propagate': False, - }, - } -} -""" - -SETTINGS_FILE_INVALID = """ -LOGGING_CONFIG = { - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'airflow.task': { - 'format': '[%%(asctime)s] {{%%(filename)s:%%(lineno)d}} %%(levelname)s - %%(message)s' - }, - }, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'airflow.task', - 'stream': 'ext://sys.stdout' - } - }, - 'loggers': { - 'airflow': { - 'handlers': ['file.handler'], # this handler does not exists - 'level': 'INFO', - 'propagate': False - } - } -} -""" - -SETTINGS_FILE_EMPTY = """ -# Other settings here -""" - -SETTINGS_FILE_WITH_REMOTE_VARS = f"""{SETTINGS_FILE_VALID} -REMOTE_TASK_LOG = None -DEFAULT_REMOTE_CONN_ID = "test_conn_id" -""" - -SETTINGS_DEFAULT_NAME = "custom_airflow_local_settings" - - -def reset_logging(): - """Reset Logging""" - manager = logging.root.manager - manager.disabled = logging.NOTSET - airflow_loggers = [ - logger for logger_name, logger in manager.loggerDict.items() if logger_name.startswith("airflow") - ] - for logger in airflow_loggers: - if isinstance(logger, logging.Logger): - logger.setLevel(logging.NOTSET) - logger.propagate = True - logger.disabled = False - logger.filters.clear() - handlers = logger.handlers.copy() - for handler in handlers: - # Copied from `logging.shutdown`. - try: - handler.acquire() - handler.flush() - handler.close() - except (OSError, ValueError): - pass - finally: - handler.release() - logger.removeHandler(handler) - - -@contextlib.contextmanager -def settings_context(content, directory=None, name="LOGGING_CONFIG"): - """ - Sets a settings file and puts it in the Python classpath - - :param content: - The content of the settings file - :param directory: the directory - :param name: str - """ - initial_logging_config = os.environ.get("AIRFLOW__LOGGING__LOGGING_CONFIG_CLASS", "") - try: - settings_root = tempfile.mkdtemp() - filename = f"{SETTINGS_DEFAULT_NAME}.py" - if directory: - # Create the directory structure with __init__.py - dir_path = os.path.join(settings_root, directory) - pathlib.Path(dir_path).mkdir(parents=True, exist_ok=True) - - basedir = settings_root - for part in directory.split("/"): - open(os.path.join(basedir, "__init__.py"), "w").close() - basedir = os.path.join(basedir, part) - open(os.path.join(basedir, "__init__.py"), "w").close() - - # Replace slashes by dots - module = directory.replace("/", ".") + "." + SETTINGS_DEFAULT_NAME + "." + name - settings_file = os.path.join(dir_path, filename) - else: - module = SETTINGS_DEFAULT_NAME + "." + name - settings_file = os.path.join(settings_root, filename) - - with open(settings_file, "w") as handle: - handle.writelines(content) - sys.path.append(settings_root) - - # Using environment vars instead of conf_vars so value is accessible - # to parent and child processes when using 'spawn' for multiprocessing. - os.environ["AIRFLOW__LOGGING__LOGGING_CONFIG_CLASS"] = module - yield settings_file - - finally: - os.environ["AIRFLOW__LOGGING__LOGGING_CONFIG_CLASS"] = initial_logging_config - sys.path.remove(settings_root) - - -class TestLoggingSettings: - # Make sure that the configure_logging is not cached - def setup_method(self): - self.old_modules = dict(sys.modules) - - def teardown_method(self): - # Remove any new modules imported during the test run. This lets us - # import the same source files for more than one test. - from airflow.config_templates import airflow_local_settings - from airflow.logging_config import configure_logging - - for mod in list(sys.modules): - if mod not in self.old_modules: - del sys.modules[mod] - - reset_logging() - importlib.reload(airflow_local_settings) - configure_logging() - - def _verify_basic_logging_config( - self, logging_config: dict, logging_class_path: str, expected_path: str - ) -> None: - """Helper method to verify basic logging config structure""" - assert isinstance(logging_config, dict) - assert logging_config["version"] == 1 - assert "airflow.task" in logging_config["loggers"] - assert logging_class_path == expected_path - - # When we try to load an invalid config file, we expect an error - def test_loading_invalid_local_settings(self): - from airflow.logging_config import configure_logging, log - - with settings_context(SETTINGS_FILE_INVALID): - with patch.object(log, "error") as mock_info: - # Load config - with pytest.raises(ValueError): - configure_logging() - - mock_info.assert_called_once_with( - "Unable to load the config, contains a configuration error." - ) - - def test_loading_valid_complex_local_settings(self): - # Test what happens when the config is somewhere in a subfolder - module_structure = "etc.airflow.config" - dir_structure = module_structure.replace(".", "/") - with settings_context(SETTINGS_FILE_VALID, dir_structure): - from airflow.logging_config import configure_logging, log - - with patch.object(log, "info") as mock_info: - configure_logging() - mock_info.assert_any_call( - "Successfully imported user-defined logging config from %s", - f"etc.airflow.config.{SETTINGS_DEFAULT_NAME}.LOGGING_CONFIG", - ) - - # When we load an empty file, it should go to default - def test_loading_no_local_settings(self): - with settings_context(SETTINGS_FILE_EMPTY): - from airflow.logging_config import configure_logging - - with pytest.raises(ImportError): - configure_logging() - - def test_1_9_config(self): - from airflow.logging_config import configure_logging - - with conf_vars({("logging", "task_log_reader"): "file.task"}): - with pytest.warns(DeprecationWarning, match=r"file.task"): - configure_logging() - assert conf.get("logging", "task_log_reader") == "task" - - def test_loading_remote_logging_with_wasb_handler(self): - """Test if logging can be configured successfully for Azure Blob Storage""" - pytest.importorskip( - "airflow.providers.microsoft.azure", reason="'microsoft.azure' provider not installed" - ) - import airflow.logging_config - from airflow.config_templates import airflow_local_settings - from airflow.providers.microsoft.azure.log.wasb_task_handler import WasbRemoteLogIO - - with conf_vars( - { - ("logging", "remote_logging"): "True", - ("logging", "remote_log_conn_id"): "some_wasb", - ("logging", "remote_base_log_folder"): "wasb://some-folder", - } - ): - importlib.reload(airflow_local_settings) - airflow.logging_config.configure_logging() - - assert isinstance(airflow.logging_config.REMOTE_TASK_LOG, WasbRemoteLogIO) - - @pytest.mark.parametrize( - "remote_base_log_folder, log_group_arn", - [ - ( - "cloudwatch://arn:aws:logs:aaaa:bbbbb:log-group:ccccc", - "arn:aws:logs:aaaa:bbbbb:log-group:ccccc", - ), - ( - "cloudwatch://arn:aws:logs:aaaa:bbbbb:log-group:aws/ccccc", - "arn:aws:logs:aaaa:bbbbb:log-group:aws/ccccc", - ), - ( - "cloudwatch://arn:aws:logs:aaaa:bbbbb:log-group:/aws/ecs/ccccc", - "arn:aws:logs:aaaa:bbbbb:log-group:/aws/ecs/ccccc", - ), - ], - ) - def test_log_group_arns_remote_logging_with_cloudwatch_handler( - self, remote_base_log_folder, log_group_arn - ): - """Test if the correct ARNs are configured for Cloudwatch""" - import airflow.logging_config - from airflow.config_templates import airflow_local_settings - from airflow.providers.amazon.aws.log.cloudwatch_task_handler import CloudWatchRemoteLogIO - - with conf_vars( - { - ("logging", "remote_logging"): "True", - ("logging", "remote_log_conn_id"): "some_cloudwatch", - ("logging", "remote_base_log_folder"): remote_base_log_folder, - } - ): - importlib.reload(airflow_local_settings) - airflow.logging_config.configure_logging() - - remote_io = airflow.logging_config.REMOTE_TASK_LOG - assert isinstance(remote_io, CloudWatchRemoteLogIO) - assert remote_io.log_group_arn == log_group_arn - - def test_loading_remote_logging_with_gcs_handler(self): - """Test if logging can be configured successfully for GCS""" - import airflow.logging_config - from airflow.config_templates import airflow_local_settings - from airflow.providers.google.cloud.log.gcs_task_handler import GCSRemoteLogIO - - with conf_vars( - { - ("logging", "remote_logging"): "True", - ("logging", "remote_log_conn_id"): "some_gcs", - ("logging", "remote_base_log_folder"): "gs://some-folder", - ("logging", "google_key_path"): "/gcs-key.json", - ( - "logging", - "remote_task_handler_kwargs", - ): '{"delete_local_copy": true, "project_id": "test-project", "gcp_keyfile_dict": {},"scopes": ["https://www.googleapis.com/auth/devstorage.read_write"]}', - } - ): - importlib.reload(airflow_local_settings) - airflow.logging_config.configure_logging() - - assert isinstance(airflow.logging_config.REMOTE_TASK_LOG, GCSRemoteLogIO) - assert getattr(airflow.logging_config.REMOTE_TASK_LOG, "delete_local_copy") is True - assert getattr(airflow.logging_config.REMOTE_TASK_LOG, "project_id") == "test-project" - assert getattr(airflow.logging_config.REMOTE_TASK_LOG, "gcp_keyfile_dict") == {} - assert getattr(airflow.logging_config.REMOTE_TASK_LOG, "scopes") == [ - "https://www.googleapis.com/auth/devstorage.read_write" - ] - assert getattr(airflow.logging_config.REMOTE_TASK_LOG, "gcp_key_path") == "/gcs-key.json" - - def test_loading_remote_logging_with_kwargs(self): - """Test if logging can be configured successfully with kwargs""" - pytest.importorskip("airflow.providers.amazon", reason="'amazon' provider not installed") - import airflow.logging_config - from airflow.config_templates import airflow_local_settings - from airflow.providers.amazon.aws.log.s3_task_handler import S3RemoteLogIO - - with conf_vars( - { - ("logging", "remote_logging"): "True", - ("logging", "remote_log_conn_id"): "some_s3", - ("logging", "remote_base_log_folder"): "s3://some-folder", - ("logging", "remote_task_handler_kwargs"): '{"delete_local_copy": true}', - } - ): - importlib.reload(airflow_local_settings) - airflow.logging_config.configure_logging() - - task_log = airflow.logging_config.REMOTE_TASK_LOG - assert isinstance(task_log, S3RemoteLogIO) - assert getattr(task_log, "delete_local_copy") is True - - def test_loading_remote_logging_with_hdfs_handler(self): - """Test if logging can be configured successfully for HDFS""" - pytest.importorskip("airflow.providers.apache.hdfs", reason="'apache.hdfs' provider not installed") - import airflow.logging_config - from airflow.config_templates import airflow_local_settings - from airflow.providers.apache.hdfs.log.hdfs_task_handler import HdfsRemoteLogIO - - with conf_vars( - { - ("logging", "remote_logging"): "True", - ("logging", "remote_log_conn_id"): "some_hdfs", - ("logging", "remote_base_log_folder"): "hdfs://some-folder", - } - ): - importlib.reload(airflow_local_settings) - airflow.logging_config.configure_logging() - - assert isinstance(airflow.logging_config.REMOTE_TASK_LOG, HdfsRemoteLogIO) - - @pytest.mark.parametrize( - "settings_content,module_structure,expected_path", - [ - (SETTINGS_FILE_WITH_REMOTE_VARS, None, f"{SETTINGS_DEFAULT_NAME}.LOGGING_CONFIG"), - ( - SETTINGS_FILE_WITH_REMOTE_VARS, - "nested.config.module", - f"nested.config.module.{SETTINGS_DEFAULT_NAME}.LOGGING_CONFIG", - ), - ], - ) - def test_load_logging_config_module_paths( - self, settings_content: str, module_structure: str, expected_path: str - ): - """Test that load_logging_config works with different module path structures""" - dir_structure = module_structure.replace(".", "/") if module_structure else None - - with settings_context(settings_content, dir_structure): - from airflow.logging_config import load_logging_config - - logging_config, logging_class_path = load_logging_config() - self._verify_basic_logging_config(logging_config, logging_class_path, expected_path) - - def test_load_logging_config_fallback_behavior(self): - """Test that load_logging_config falls back gracefully when remote logging vars are missing""" - with settings_context(SETTINGS_FILE_VALID): - from airflow.logging_config import load_logging_config - - with patch("airflow.logging_config.log") as mock_log: - logging_config, logging_class_path = load_logging_config() - - self._verify_basic_logging_config( - logging_config, logging_class_path, f"{SETTINGS_DEFAULT_NAME}.LOGGING_CONFIG" - ) - - mock_log.info.mock_calls = [ - call( - "Remote task logs will not be available due to an error: %s", - ) - ] diff --git a/airflow-core/tests/unit/core/test_stats.py b/airflow-core/tests/unit/core/test_stats.py index 1dad2fcedd7fc..12ed4207d42c4 100644 --- a/airflow-core/tests/unit/core/test_stats.py +++ b/airflow-core/tests/unit/core/test_stats.py @@ -376,11 +376,11 @@ def test_pattern_picker(self, config, expected): @conf_vars({**stats_on, **block_list, ("metrics", "metrics_allow_list"): "baz,qux"}) def test_setting_allow_and_block_logs_warning(self, caplog): - importlib.reload(airflow.stats) - - assert isinstance(airflow.stats.Stats.statsd, statsd.StatsClient) - assert type(airflow.stats.Stats.instance.metrics_validator) is PatternAllowListValidator with caplog.at_level(logging.WARNING): + importlib.reload(airflow.stats) + + assert isinstance(airflow.stats.Stats.statsd, statsd.StatsClient) + assert type(airflow.stats.Stats.instance.metrics_validator) is PatternAllowListValidator assert "Ignoring metrics_block_list" in caplog.text diff --git a/airflow-core/tests/unit/dag_processing/test_manager.py b/airflow-core/tests/unit/dag_processing/test_manager.py index 982cfb27fd0c5..85bb362785d8d 100644 --- a/airflow-core/tests/unit/dag_processing/test_manager.py +++ b/airflow-core/tests/unit/dag_processing/test_manager.py @@ -28,7 +28,6 @@ import time from collections import deque from datetime import datetime, timedelta -from logging.config import dictConfig from pathlib import Path from socket import socket, socketpair from unittest import mock @@ -42,7 +41,6 @@ from airflow._shared.timezones import timezone from airflow.callbacks.callback_requests import DagCallbackRequest -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.dag_processing.bundles.manager import DagBundlesManager from airflow.dag_processing.manager import ( DagFileInfo, @@ -116,7 +114,6 @@ def _disable_examples(self): yield def setup_method(self): - dictConfig(DEFAULT_LOGGING_CONFIG) clear_db_assets() clear_db_runs() clear_db_serialized_dags() @@ -743,6 +740,8 @@ def test_deactivate_deleted_dags(self, dag_maker, session): @conf_vars({("core", "load_examples"): "False"}) def test_fetch_callbacks_from_database(self, configure_testing_dag_bundle): + """Test _fetch_callbacks returns callbacks ordered by priority_weight desc.""" + dag_filepath = TEST_DAG_FOLDER / "test_on_failure_callback_dag.py" callback1 = DagCallbackRequest( @@ -770,7 +769,12 @@ def test_fetch_callbacks_from_database(self, configure_testing_dag_bundle): manager = DagFileProcessorManager(max_runs=1) with create_session() as session: - manager.run() + callbacks = manager._fetch_callbacks(session=session) + + # Should return callbacks ordered by priority_weight desc (highest first) + assert callbacks[0].run_id == "123" + assert callbacks[1].run_id == "456" + assert session.query(DbCallbackRequest).count() == 0 @conf_vars( diff --git a/airflow-core/tests/unit/dag_processing/test_processor.py b/airflow-core/tests/unit/dag_processing/test_processor.py index 14427a6dee5b2..2269d4a2d61d9 100644 --- a/airflow-core/tests/unit/dag_processing/test_processor.py +++ b/airflow-core/tests/unit/dag_processing/test_processor.py @@ -44,9 +44,10 @@ CallbackRequest, DagCallbackRequest, DagRunContext, - EmailNotificationRequest, + EmailRequest, TaskCallbackRequest, ) +from airflow.dag_processing.manager import process_parse_results from airflow.dag_processing.processor import ( DagFileParseRequest, DagFileParsingResult, @@ -62,6 +63,16 @@ from airflow.sdk.api.client import Client from airflow.sdk.api.datamodels._generated import DagRunState from airflow.sdk.execution_time import comms +from airflow.sdk.execution_time.comms import ( + GetTaskStates, + GetTICount, + GetXCom, + GetXComSequenceSlice, + TaskStatesResult, + TICount, + XComResult, + XComSequenceSliceResult, +) from airflow.utils.session import create_session from airflow.utils.state import TaskInstanceState @@ -389,23 +400,28 @@ def test__pre_import_airflow_modules_when_enabled(self): mock_import.assert_called_once_with("airflow.models") logger.warning.assert_not_called() - def test__pre_import_airflow_modules_warns_on_missing_module(self): + @pytest.mark.parametrize( + "exception", + [ + ModuleNotFoundError("module not found"), + RuntimeError("import failed"), + ImportError("import error"), + ], + ) + def test__pre_import_airflow_modules_warns_on_import_errors(self, exception): + """Test that pre-import logs warnings for any import exception type.""" logger = MagicMock(spec=FilteringBoundLogger) with ( env_vars({"AIRFLOW__DAG_PROCESSOR__PARSING_PRE_IMPORT_MODULES": "true"}), - patch( - "airflow.dag_processing.processor.iter_airflow_imports", return_value=["non_existent_module"] - ), - patch( - "airflow.dag_processing.processor.importlib.import_module", side_effect=ModuleNotFoundError() - ), + patch("airflow.dag_processing.processor.iter_airflow_imports", return_value=["some_module"]), + patch("airflow.dag_processing.processor.importlib.import_module", side_effect=exception), ): _pre_import_airflow_modules("test.py", logger) logger.warning.assert_called_once() warning_args = logger.warning.call_args[0] assert "Error when trying to pre-import module" in warning_args[0] - assert "non_existent_module" in warning_args[1] + assert "some_module" in warning_args[1] assert "test.py" in warning_args[2] def test__pre_import_airflow_modules_partial_success_and_warning(self): @@ -575,6 +591,63 @@ def fake_collect_dags(self, *args, **kwargs): assert called is True +def test_callback_processing_does_not_update_timestamps(session): + """Callback processing should not update last_finish_time to prevent stale DAG detection.""" + stat = process_parse_results( + run_duration=1.0, + finish_time=timezone.utcnow(), + run_count=5, + bundle_name="test", + bundle_version=None, + parsing_result=None, + session=session, + is_callback_only=True, + ) + + assert stat.last_finish_time is None + assert stat.run_count == 5 + + +def test_normal_parsing_updates_timestamps(session): + """last_finish_time should be updated when parsing a dag file.""" + finish_time = timezone.utcnow() + + stat = process_parse_results( + run_duration=2.0, + finish_time=finish_time, + run_count=3, + bundle_name="test-bundle", + bundle_version="v1", + parsing_result=DagFileParsingResult(fileloc="test.py", serialized_dags=[]), + session=session, + is_callback_only=False, + ) + + assert stat.last_finish_time == finish_time + assert stat.run_count == 4 + assert stat.import_errors == 0 + + +def test_import_error_updates_timestamps(session): + """last_finish_time should be updated when parsing a dag file results in import errors.""" + finish_time = timezone.utcnow() + + stat = process_parse_results( + run_duration=1.5, + finish_time=finish_time, + run_count=2, + bundle_name="test-bundle", + bundle_version="v1", + parsing_result=None, + session=session, + is_callback_only=False, + ) + + assert stat.last_finish_time == finish_time + assert stat.run_count == 3 + assert stat.import_errors == 1 + + class TestExecuteDagCallbacks: """Test the _execute_dag_callbacks function with context_from_server""" @@ -831,6 +904,219 @@ def fake_collect_dags(self, *args, **kwargs): # Should log warning about no callback found log.warning.assert_called_once_with("Callback requested, but dag didn't have any", dag_id="test_dag") + @pytest.mark.parametrize( + "xcom_operation,expected_message_type,expected_message,mock_response", + [ + ( + lambda ti, task_ids: ti.xcom_pull(key="report_df", task_ids=task_ids), + "GetXComSequenceSlice", + GetXComSequenceSlice( + key="report_df", + dag_id="test_dag", + run_id="test_run", + task_id="test_task", + start=None, + stop=None, + step=None, + include_prior_dates=False, + ), + XComSequenceSliceResult(root=["test data"]), + ), + ( + lambda ti, task_ids: ti.xcom_pull(key="single_value", task_ids=["test_task"]), + "GetXComSequenceSlice", + GetXComSequenceSlice( + key="single_value", + dag_id="test_dag", + run_id="test_run", + task_id="test_task", + start=None, + stop=None, + step=None, + include_prior_dates=False, + ), + XComSequenceSliceResult(root=["test data"]), + ), + ( + lambda ti, task_ids: ti.xcom_pull(key="direct_value", task_ids="test_task", map_indexes=None), + "GetXCom", + GetXCom( + key="direct_value", + dag_id="test_dag", + run_id="test_run", + task_id="test_task", + map_index=None, + include_prior_dates=False, + ), + XComResult( + key="direct_value", + value="test", + ), + ), + ], + ) + def test_notifier_xcom_operations_send_correct_messages( + self, + spy_agency, + mock_supervisor_comms, + xcom_operation, + expected_message_type, + expected_message, + mock_response, + ): + """Test that different XCom operations send correct message types""" + + mock_supervisor_comms.send.return_value = mock_response + + class TestNotifier: + def __call__(self, context): + ti = context["ti"] + dag = context["dag"] + task_ids = list(dag.task_dict) + xcom_operation(ti, task_ids) + + with DAG(dag_id="test_dag", on_success_callback=TestNotifier()) as dag: + BaseOperator(task_id="test_task") + + def fake_collect_dags(self, *args, **kwargs): + self.dags[dag.dag_id] = dag + + spy_agency.spy_on(DagBag.collect_dags, call_fake=fake_collect_dags, owner=DagBag) + + dagbag = DagBag() + dagbag.collect_dags() + + current_time = timezone.utcnow() + request = DagCallbackRequest( + filepath="test.py", + dag_id="test_dag", + run_id="test_run", + bundle_name="testing", + bundle_version=None, + context_from_server=DagRunContext( + dag_run=DRDataModel( + dag_id="test_dag", + run_id="test_run", + logical_date=current_time, + data_interval_start=current_time, + data_interval_end=current_time, + run_after=current_time, + start_date=current_time, + end_date=None, + run_type="manual", + state="success", + consumed_asset_events=[], + ), + last_ti=TIDataModel( + id=uuid.uuid4(), + dag_id="test_dag", + task_id="test_task", + run_id="test_run", + map_index=-1, + try_number=1, + dag_version_id=uuid.uuid4(), + ), + ), + is_failure_callback=False, + msg="Test success message", + ) + + _execute_dag_callbacks(dagbag, request, structlog.get_logger()) + + mock_supervisor_comms.send.assert_called_once_with(msg=expected_message) + + @pytest.mark.parametrize( + "request_operation,operation_type,mock_response,operation_response", + [ + ( + lambda context: context["task_instance"].get_ti_count(dag_id="test_dag"), + GetTICount(dag_id="test_dag"), + TICount(count=2), + "Got response 2", + ), + ( + lambda context: context["task_instance"].get_task_states( + dag_id="test_dag", task_ids=["test_task"] + ), + GetTaskStates( + dag_id="test_dag", + task_ids=["test_task"], + ), + TaskStatesResult(task_states={"test_run": {"task1": "running"}}), + "Got response {'test_run': {'task1': 'running'}}", + ), + ], + ) + def test_dagfileprocessorprocess_request_handler_operations( + self, + spy_agency, + mock_supervisor_comms, + request_operation, + operation_type, + mock_response, + operation_response, + caplog, + ): + """Test that DagFileProcessorProcess Request Handler Operations""" + + mock_supervisor_comms.send.return_value = mock_response + + def callback_fn(context): + log = structlog.get_logger() + log.info("Callback started..") + log.info("Got response %s", request_operation(context)) + + with DAG(dag_id="test_dag", on_success_callback=callback_fn) as dag: + BaseOperator(task_id="test_task") + + def fake_collect_dags(self, *args, **kwargs): + self.dags[dag.dag_id] = dag + + spy_agency.spy_on(DagBag.collect_dags, call_fake=fake_collect_dags, owner=DagBag) + + dagbag = DagBag() + dagbag.collect_dags() + + current_time = timezone.utcnow() + request = DagCallbackRequest( + filepath="test.py", + dag_id="test_dag", + run_id="test_run", + bundle_name="testing", + bundle_version=None, + context_from_server=DagRunContext( + dag_run=DRDataModel( + dag_id="test_dag", + run_id="test_run", + logical_date=current_time, + data_interval_start=current_time, + data_interval_end=current_time, + run_after=current_time, + start_date=current_time, + end_date=None, + run_type="manual", + state="success", + consumed_asset_events=[], + ), + last_ti=TIDataModel( + id=uuid.uuid4(), + dag_id="test_dag", + task_id="test_task", + run_id="test_run", + map_index=-1, + try_number=1, + dag_version_id=uuid.uuid4(), + ), + ), + is_failure_callback=False, + msg="Test success message", + ) + + _execute_dag_callbacks(dagbag, request, structlog.get_logger()) + + mock_supervisor_comms.send.assert_called_once_with(msg=operation_type) + assert operation_response in caplog.text + class TestExecuteTaskCallbacks: """Test the _execute_task_callbacks function""" @@ -1112,7 +1398,7 @@ def test_execute_email_callbacks_failure(self, mock_send_email): ) current_time = timezone.utcnow() - request = EmailNotificationRequest( + request = EmailRequest( filepath="/path/to/dag.py", bundle_name="test_bundle", bundle_version="1.0.0", @@ -1172,7 +1458,7 @@ def test_execute_email_callbacks_retry(self, mock_send_email): current_time = timezone.utcnow() - request = EmailNotificationRequest( + request = EmailRequest( filepath="/path/to/dag.py", bundle_name="test_bundle", bundle_version="1.0.0", @@ -1231,7 +1517,7 @@ def test_execute_email_callbacks_no_email_configured(self, mock_send_email): ) current_time = timezone.utcnow() - request = EmailNotificationRequest( + request = EmailRequest( filepath="/path/to/dag.py", bundle_name="test_bundle", bundle_version="1.0.0", @@ -1289,7 +1575,7 @@ def test_execute_email_callbacks_email_disabled_for_type(self, mock_send_email): current_time = timezone.utcnow() # Create request for failure (but email_on_failure is False) - request = EmailNotificationRequest( + request = EmailRequest( filepath="/path/to/dag.py", bundle_name="test_bundle", bundle_version="1.0.0", diff --git a/airflow-core/tests/unit/dags/.airflowignore_glob b/airflow-core/tests/unit/dags/.airflowignore_glob index b773879d2f05e..ee7ee40eebf29 100644 --- a/airflow-core/tests/unit/dags/.airflowignore_glob +++ b/airflow-core/tests/unit/dags/.airflowignore_glob @@ -5,12 +5,15 @@ *_invalid_* # skip invalid files # test ignoring files at all levels -**/*_dont_* # ignore all python files at all levels with "dont" in their name -!**/*_negate_ignore.py +**/*should_ignore_* # ignore all python files at all levels with "should_ignore" in their name +subdir2/subdir3/test_explicit_ignore.py # ignore this explicit path subdir2/**/test_nested*.py # ignore files in subdir2/subdir3 +!subdir2/**/*_negate_ignore.py # do not ignore files ending with '_negate_ignore.py' # test matching and ignoring of path separators subdir1/* # ignore all of subdir1 +!subdir1/test_explicit_dont_ignore.py # do not ignore this explicit path +!subdir1/*_negate_ignore.py # Do not ignore this one file in subdir1 subdir2*test* # this should not match anything in the subdir2 directory subdir2?test* # this should not match anything in the subdir2 directory diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dag_report.py b/airflow-core/tests/unit/dags/subdir1/test_explicit_dont_ignore.py similarity index 64% rename from airflow-core/src/airflow/api_fastapi/core_api/datamodels/dag_report.py rename to airflow-core/tests/unit/dags/subdir1/test_explicit_dont_ignore.py index aeab3f91af91b..cbacd930ca011 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dag_report.py +++ b/airflow-core/tests/unit/dags/subdir1/test_explicit_dont_ignore.py @@ -1,3 +1,4 @@ +# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -17,24 +18,12 @@ from __future__ import annotations -from datetime import timedelta - -from airflow.api_fastapi.core_api.base import BaseModel - - -class DagReportResponse(BaseModel): - """DAG Report serializer for responses.""" - - file: str - duration: timedelta - dag_num: int - task_num: int - dags: str - warning_num: int +from datetime import datetime +from airflow.models.dag import DAG +from airflow.providers.standard.operators.bash import BashOperator -class DagReportCollectionResponse(BaseModel): - """DAG Report Collection serializer for responses.""" +DEFAULT_DATE = datetime(2019, 12, 1) - dag_reports: list[DagReportResponse] - total_entries: int +dag = DAG(dag_id="test_dag_explicit_dont_ignore", start_date=DEFAULT_DATE, schedule=None) +task = BashOperator(task_id="task1", bash_command='echo "test dag explicitly dont ignore"', dag=dag) diff --git a/airflow-core/tests/unit/dags/subdir2/subdir3/should_ignore_this.py b/airflow-core/tests/unit/dags/subdir2/subdir3/should_ignore_this.py new file mode 100644 index 0000000000000..217e5db960782 --- /dev/null +++ b/airflow-core/tests/unit/dags/subdir2/subdir3/should_ignore_this.py @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/airflow-core/tests/unit/dags/subdir2/subdir3/test_explicit_ignore.py b/airflow-core/tests/unit/dags/subdir2/subdir3/test_explicit_ignore.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/airflow-core/tests/unit/dags/subdir2/subdir3/test_explicit_ignore.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/airflow-core/tests/unit/executors/test_local_executor.py b/airflow-core/tests/unit/executors/test_local_executor.py index ec7102e2e70c2..6489746f22002 100644 --- a/airflow-core/tests/unit/executors/test_local_executor.py +++ b/airflow-core/tests/unit/executors/test_local_executor.py @@ -28,6 +28,7 @@ from airflow._shared.timezones import timezone from airflow.executors import workloads from airflow.executors.local_executor import LocalExecutor, _execute_work +from airflow.settings import Session from airflow.utils.state import State from tests_common.test_utils.config import conf_vars @@ -97,7 +98,8 @@ def fake_supervise(ti, **kwargs): dag_rel_path="some/path", log_path=None, bundle_info=dict(name="hi", version="hi"), - ) + ), + session=mock.MagicMock(spec=Session), ) executor.queue_workload( @@ -107,9 +109,13 @@ def fake_supervise(ti, **kwargs): dag_rel_path="some/path", log_path=None, bundle_info=dict(name="hi", version="hi"), - ) + ), + session=mock.MagicMock(spec=Session), ) + # Process queued workloads to trigger worker spawning + executor._process_workloads(list(executor.queued_tasks.values())) + executor.end() expected = self.TEST_SUCCESS_COMMANDS + 1 if parallelism == 0 else parallelism diff --git a/airflow-core/tests/unit/jobs/test_scheduler_job.py b/airflow-core/tests/unit/jobs/test_scheduler_job.py index d52d3eaed1547..cfebf7b733f9b 100644 --- a/airflow-core/tests/unit/jobs/test_scheduler_job.py +++ b/airflow-core/tests/unit/jobs/test_scheduler_job.py @@ -502,6 +502,7 @@ def test_process_executor_events_with_callback( "finished with state failed, but the task instance's state attribute is queued. " "Learn more: https://airflow.apache.org/docs/apache-airflow/stable/troubleshooting.html#task-state-changed-externally", context_from_server=mock.ANY, + task_callback_type=TaskInstanceState.FAILED, ) scheduler_job.executor.callback_sink.send.assert_called_once_with(task_callback) scheduler_job.executor.callback_sink.reset_mock() @@ -2082,6 +2083,94 @@ def test_adopt_or_reset_orphaned_tasks_multiple_executors(self, dag_maker, mock_ # Second executor called for ti3 mock_executors[1].try_adopt_task_instances.assert_called_once_with([ti3]) + def test_adopt_sets_last_heartbeat_on_adopt(self, dag_maker, session, mock_executor): + with dag_maker("test_adopt_sets_last_heartbeat_on_adopt", session=session): + op1 = EmptyOperator(task_id="op1") + + old_scheduler_job = Job() + session.add(old_scheduler_job) + session.flush() + + dr = dag_maker.create_dagrun(run_type=DagRunType.SCHEDULED) + ti = dr.get_task_instance(task_id=op1.task_id, session=session) + ti.state = State.QUEUED + ti.queued_by_job_id = old_scheduler_job.id + ti.last_heartbeat_at = None + session.commit() + + # Executor adopts all TIs (returns empty list to reset), so TI is adopted + mock_executor.try_adopt_task_instances.return_value = [] + + new_scheduler_job = Job() + self.job_runner = SchedulerJobRunner(job=new_scheduler_job, num_runs=0) + self.job_runner.adopt_or_reset_orphaned_tasks(session=session) + + ti.refresh_from_db(session=session) + assert ti.state == State.QUEUED + assert ti.queued_by_job_id == new_scheduler_job.id + assert ti.last_heartbeat_at is not None + + def test_adopt_sets_dagrun_conf_when_none(self, dag_maker, session, mock_executor): + with dag_maker("test_adopt_sets_dagrun_conf_when_none", session=session): + op1 = EmptyOperator(task_id="op1") + + old_scheduler_job = Job() + session.add(old_scheduler_job) + session.flush() + + dr = dag_maker.create_dagrun(run_type=DagRunType.SCHEDULED) + # Ensure conf starts as None + dr.conf = None + session.merge(dr) + session.flush() + dr = session.scalar(select(DagRun).where(DagRun.id == dr.id)) + assert dr.conf is None + + ti = dr.get_task_instance(task_id=op1.task_id, session=session) + ti.state = State.QUEUED + ti.queued_by_job_id = old_scheduler_job.id + session.commit() + + # Executor adopts all TIs (returns empty list to reset), so TI is adopted + mock_executor.try_adopt_task_instances.return_value = [] + + new_scheduler_job = Job() + self.job_runner = SchedulerJobRunner(job=new_scheduler_job, num_runs=0) + self.job_runner.adopt_or_reset_orphaned_tasks(session=session) + + # DagRun.conf should be set to {} on adoption when it was None + session.refresh(dr) + assert dr.conf == {} + + def test_purge_without_heartbeat_skips_when_missing_dag_version(self, dag_maker, session, caplog): + with dag_maker("test_purge_without_heartbeat_skips_when_missing_dag_version", session=session): + EmptyOperator(task_id="task") + + dag_run = dag_maker.create_dagrun(run_id="test_run", state=DagRunState.RUNNING) + + mock_executor = MagicMock() + scheduler_job = Job(executor=mock_executor) + self.job_runner = SchedulerJobRunner(scheduler_job) + + ti = dag_run.get_task_instance(task_id="task", session=session) + ti.state = TaskInstanceState.RUNNING + ti.queued_by_job_id = scheduler_job.id + ti.last_heartbeat_at = timezone.utcnow() - timedelta(hours=1) + # Simulate missing dag_version + ti.dag_version_id = None + session.merge(ti) + session.commit() + + with caplog.at_level("WARNING", logger="airflow.jobs.scheduler_job_runner"): + self.job_runner._purge_task_instances_without_heartbeats([ti], session=session) + + # Should log a warning and skip processing + assert any("DAG Version not found for TaskInstance" in rec.message for rec in caplog.records) + mock_executor.send_callback.assert_not_called() + # State should be unchanged (not failed) + ti.refresh_from_db(session=session) + assert ti.state == TaskInstanceState.RUNNING + @staticmethod def mock_failure_callback(context): pass @@ -6687,6 +6776,43 @@ def test_scheduler_passes_context_from_server_on_heartbeat_timeout(self, dag_mak assert callback_request.context_from_server.dag_run.logical_date == dag_run.logical_date assert callback_request.context_from_server.max_tries == ti.max_tries + @pytest.mark.parametrize( + "retries,callback_kind,expected", + [ + (1, "retry", TaskInstanceState.UP_FOR_RETRY), + (0, "failure", TaskInstanceState.FAILED), + ], + ) + def test_external_kill_sets_callback_type_param( + self, dag_maker, session, retries, callback_kind, expected + ): + """External kill should mark callback type based on retry eligibility.""" + with dag_maker(dag_id=f"ext_kill_{callback_kind}", fileloc="/test_path1/"): + if callback_kind == "retry": + EmptyOperator(task_id="t1", retries=retries, on_retry_callback=lambda ctx: None) + else: + EmptyOperator(task_id="t1", retries=retries, on_failure_callback=lambda ctx: None) + dr = dag_maker.create_dagrun(state=DagRunState.RUNNING) + ti = dr.get_task_instance(task_id="t1") + + executor = MockExecutor(do_update=False) + scheduler_job = Job(executor=executor) + self.job_runner = SchedulerJobRunner(scheduler_job) + + ti.state = State.QUEUED + session.merge(ti) + session.commit() + + # Executor reports task finished (FAILED) while TI still QUEUED -> external kill path + executor.event_buffer[ti.key] = State.FAILED, None + + self.job_runner._process_executor_events(executor=executor, session=session) + + scheduler_job.executor.callback_sink.send.assert_called() + request = scheduler_job.executor.callback_sink.send.call_args[0][0] + assert isinstance(request, TaskCallbackRequest) + assert request.task_callback_type == expected + def test_scheduler_passes_context_from_server_on_task_failure(self, dag_maker, session): """Test that scheduler passes context_from_server when handling task failures.""" with dag_maker(dag_id="test_dag", session=session): diff --git a/airflow-core/tests/unit/jobs/test_triggerer_job.py b/airflow-core/tests/unit/jobs/test_triggerer_job.py index 121088c645eb7..a12969ce79e2c 100644 --- a/airflow-core/tests/unit/jobs/test_triggerer_job.py +++ b/airflow-core/tests/unit/jobs/test_triggerer_job.py @@ -19,6 +19,7 @@ import asyncio import datetime +import itertools import os import selectors import time @@ -52,6 +53,7 @@ from airflow.models.xcom import XComModel from airflow.providers.standard.operators.empty import EmptyOperator from airflow.providers.standard.operators.python import PythonOperator +from airflow.providers.standard.triggers.file import FileDeleteTrigger from airflow.providers.standard.triggers.temporal import DateTimeTrigger, TimeDeltaTrigger from airflow.sdk import BaseHook, BaseOperator from airflow.serialization.serialized_objects import LazyDeserializedDAG @@ -64,7 +66,9 @@ clear_db_connections, clear_db_dag_bundles, clear_db_dags, + clear_db_jobs, clear_db_runs, + clear_db_triggers, clear_db_variables, clear_db_xcom, ) @@ -84,6 +88,8 @@ def clean_database(): clear_db_dag_bundles() clear_db_xcom() clear_db_variables() + clear_db_triggers() + clear_db_jobs() yield # Test runs here clear_db_connections() clear_db_runs() @@ -91,6 +97,8 @@ def clean_database(): clear_db_dag_bundles() clear_db_xcom() clear_db_variables() + clear_db_triggers() + clear_db_jobs() def create_trigger_in_db(session, trigger, operator=None): @@ -266,9 +274,35 @@ def send_msg_spy(self, msg, *args, **kwargs): trigger_runner_supervisor.kill(force=False) +@pytest.mark.parametrize( + "trigger, watcher_count, trigger_count", + [ + (TimeDeltaTrigger(datetime.timedelta(days=7)), 0, 1), + (FileDeleteTrigger("/tmp/foo.txt", poke_interval=1), 1, 0), + ], +) +@patch("time.monotonic", side_effect=itertools.count(start=1, step=60)) +def test_trigger_log(mock_monotonic, trigger, watcher_count, trigger_count, session, capsys): + """ + Checks that the triggerer will log watcher and trigger in separate lines. + """ + create_trigger_in_db(session, trigger) + + trigger_runner_supervisor = TriggerRunnerSupervisor.start(job=Job(id=123456), capacity=10) + trigger_runner_supervisor.load_triggers() + + for _ in range(30): + trigger_runner_supervisor._service_subprocess(0.1) + + stdout = capsys.readouterr().out + assert f"{trigger_count} triggers currently running" in stdout + assert f"{watcher_count} watchers currently running" in stdout + + trigger_runner_supervisor.kill(force=False) + + class TestTriggerRunner: - @pytest.mark.asyncio - async def test_run_inline_trigger_canceled(self, session) -> None: + def test_run_inline_trigger_canceled(self, session) -> None: trigger_runner = TriggerRunner() trigger_runner.triggers = { 1: {"task": MagicMock(spec=asyncio.Task), "name": "mock_name", "events": 0} @@ -278,10 +312,10 @@ async def test_run_inline_trigger_canceled(self, session) -> None: mock_trigger.run.side_effect = asyncio.CancelledError() with pytest.raises(asyncio.CancelledError): - await trigger_runner.run_trigger(1, mock_trigger) + asyncio.run(trigger_runner.run_trigger(1, mock_trigger)) - @pytest.mark.asyncio - async def test_run_inline_trigger_timeout(self, session, cap_structlog) -> None: + # @pytest.mark.asyncio + def test_run_inline_trigger_timeout(self, session, cap_structlog) -> None: trigger_runner = TriggerRunner() trigger_runner.triggers = { 1: {"task": MagicMock(spec=asyncio.Task), "name": "mock_name", "events": 0} @@ -291,7 +325,7 @@ async def test_run_inline_trigger_timeout(self, session, cap_structlog) -> None: mock_trigger.run.side_effect = asyncio.CancelledError() with pytest.raises(asyncio.CancelledError): - await trigger_runner.run_trigger(1, mock_trigger) + asyncio.run(trigger_runner.run_trigger(1, mock_trigger)) assert {"event": "Trigger cancelled due to timeout", "log_level": "error"} in cap_structlog @patch("airflow.jobs.triggerer_job_runner.Trigger._decrypt_kwargs") diff --git a/airflow-core/tests/unit/models/test_cleartasks.py b/airflow-core/tests/unit/models/test_cleartasks.py index c44cdf5635ee7..9a1f37c89ca21 100644 --- a/airflow-core/tests/unit/models/test_cleartasks.py +++ b/airflow-core/tests/unit/models/test_cleartasks.py @@ -633,11 +633,11 @@ def _get_ti(old_ti): assert ti.max_tries == 1 # test dry_run - for i in range(num_of_dags): + for i, dag in enumerate(dags): ti = _get_ti(tis[i]) ti.try_number += 1 session.commit() - ti.refresh_from_task(tis[i].task) + ti.refresh_from_task(dag.get_task(ti.task_id)) ti.run(session=session) assert ti.state == State.SUCCESS assert ti.try_number == 2 diff --git a/airflow-core/tests/unit/models/test_dag.py b/airflow-core/tests/unit/models/test_dag.py index 796ed807df8e2..febed30fbd251 100644 --- a/airflow-core/tests/unit/models/test_dag.py +++ b/airflow-core/tests/unit/models/test_dag.py @@ -53,6 +53,7 @@ get_asset_triggered_next_run_info, get_next_data_interval, ) +from airflow.models.dagbag import DBDagBag from airflow.models.dagbundle import DagBundleModel from airflow.models.dagrun import DagRun from airflow.models.serialized_dag import SerializedDagModel @@ -80,6 +81,7 @@ from airflow.utils.types import DagRunTriggeredByType, DagRunType from tests_common.test_utils.asserts import assert_queries_count +from tests_common.test_utils.config import conf_vars from tests_common.test_utils.dag import create_scheduler_dag, sync_dag_to_db from tests_common.test_utils.db import ( clear_db_assets, @@ -179,6 +181,29 @@ def setup_method(self) -> None: clear_db_dags() clear_db_assets() + @conf_vars({("core", "load_examples"): "false"}) + def test_dag_test_auto_parses_when_not_serialized(self, test_dags_bundle, session): + """ + DAG.test() should auto-parse and sync the DAG if it's not serialized yet. + """ + + dag_id = "test_example_bash_operator" + + dagbag = DagBag(dag_folder=os.fspath(TEST_DAGS_FOLDER), include_examples=False) + dag = dagbag.dags.get(dag_id) + + # Ensure not serialized yet + assert DBDagBag().get_latest_version_of_dag(dag_id, session=session) is None + assert session.scalar(select(DagRun).where(DagRun.dag_id == dag_id)) is None + + dr = dag.test() + assert dr is not None + + # Serialized DAG should now exist and DagRun would be created + ser = DBDagBag().get_latest_version_of_dag(dag_id, session=session) + assert ser is not None + assert session.scalar(select(DagRun).where(DagRun.dag_id == dag_id)) is not None + def teardown_method(self) -> None: clear_db_runs() clear_db_dags() @@ -925,8 +950,8 @@ def test_dag_handle_callback_with_removed_task(self, dag_maker, session, testing assert dag_run.get_task_instance(task_removed.task_id).state == TaskInstanceState.REMOVED # should not raise any exception - dag_run.handle_dag_callback(dag=scheduler_dag, success=False) - dag_run.handle_dag_callback(dag=scheduler_dag, success=True) + dag_run.handle_dag_callback(dag=dag, success=False) + dag_run.handle_dag_callback(dag=dag, success=True) @pytest.mark.parametrize("catchup,expected_next_dagrun", [(True, DEFAULT_DATE), (False, None)]) def test_next_dagrun_after_fake_scheduled_previous( @@ -1567,7 +1592,6 @@ def test_next_dagrun_info_timedelta_schedule_and_catchup_true(self): assert next_info assert next_info.logical_date == timezone.datetime(2020, 5, 4) - @pytest.mark.usefixtures("clear_all_logger_handlers") def test_next_dagrun_info_timetable_exception(self, caplog): """Test the DAG does not crash the scheduler if the timetable raises an exception.""" @@ -1596,7 +1620,7 @@ def _check_logs(records: list[logging.LogRecord], data_interval: DataInterval) - assert len(records) == 1 record = records[0] assert record.exc_info is not None, "Should contain exception" - assert record.getMessage() == ( + assert record.message == ( f"Failed to fetch run info after data interval {data_interval} " f"for DAG 'test_next_dagrun_info_timetable_exception'" ) @@ -1812,6 +1836,61 @@ def test_dagrun_deadline(self, reference_type, reference_column, dag_maker, sess assert len(dr.deadlines) == 1 assert dr.deadlines[0].deadline_time == getattr(dr, reference_column, DEFAULT_DATE) + interval + def test_dag_with_multiple_deadlines(self, dag_maker, session): + """Test that a DAG with multiple deadlines stores all deadlines in the database.""" + deadlines = [ + DeadlineAlert( + reference=DeadlineReference.DAGRUN_QUEUED_AT, + interval=datetime.timedelta(minutes=5), + callback=AsyncCallback(empty_callback_for_deadline), + ), + DeadlineAlert( + reference=DeadlineReference.DAGRUN_QUEUED_AT, + interval=datetime.timedelta(minutes=10), + callback=AsyncCallback(empty_callback_for_deadline), + ), + DeadlineAlert( + reference=DeadlineReference.DAGRUN_LOGICAL_DATE, + interval=datetime.timedelta(hours=1), + callback=AsyncCallback(empty_callback_for_deadline), + ), + ] + + with dag_maker( + dag_id="test_multiple_deadlines", + schedule=datetime.timedelta(days=1), + deadline=deadlines, + ) as dag: + ... + + scheduler_dag = sync_dag_to_db(dag) + dr = scheduler_dag.create_dagrun( + run_id="test_multiple_deadlines", + run_type=DagRunType.SCHEDULED, + state=State.QUEUED, + logical_date=TEST_DATE, + run_after=TEST_DATE, + triggered_by=DagRunTriggeredByType.TEST, + ) + session.flush() + dr = session.merge(dr) + + # Check that all 3 deadlines were created + assert len(dr.deadlines) == 3 + + # Verify each deadline has correct properties + deadline_times = [d.deadline_time for d in dr.deadlines] + expected_times = [ + dr.queued_at + datetime.timedelta(minutes=5), + dr.queued_at + datetime.timedelta(minutes=10), + dr.logical_date + datetime.timedelta(hours=1), + ] + + # Sort both lists to compare regardless of order + deadline_times.sort() + expected_times.sort() + assert deadline_times == expected_times + class TestDagModel: def _clean(self): @@ -2188,12 +2267,7 @@ def test_asset_expression(self, session: Session, testing_dag_bundle) -> None: ), start_date=datetime.datetime.min, ) - SerializedDAG.bulk_write_to_db( - "testing", - None, - [SerializedDAG.deserialize_dag(SerializedDAG.serialize_dag(dag))], - session=session, - ) + SerializedDAG.bulk_write_to_db("testing", None, [dag], session=session) expression = session.scalars(select(DagModel.asset_expression).filter_by(dag_id=dag.dag_id)).one() assert expression == { @@ -2537,7 +2611,6 @@ def test_iter_dagrun_infos_between(start_date, expected_infos): assert expected_infos == list(iterator) -@pytest.mark.usefixtures("clear_all_logger_handlers") def test_iter_dagrun_infos_between_error(caplog): start = pendulum.instance(DEFAULT_DATE - datetime.timedelta(hours=1)) end = pendulum.instance(DEFAULT_DATE) @@ -2578,7 +2651,7 @@ def _get_registered_timetable(s): f"Failed to fetch run info after data interval {DataInterval(start, end)} for DAG {dag.dag_id!r}", ), ] - assert caplog.records[0].exc_info is not None, "should contain exception context" + assert caplog.entries[0].get("exc_info") is not None, "should contain exception context" @pytest.mark.parametrize( diff --git a/airflow-core/tests/unit/models/test_dagrun.py b/airflow-core/tests/unit/models/test_dagrun.py index 369f530077b4a..74cf038dcec4d 100644 --- a/airflow-core/tests/unit/models/test_dagrun.py +++ b/airflow-core/tests/unit/models/test_dagrun.py @@ -43,7 +43,7 @@ from airflow.providers.standard.operators.bash import BashOperator from airflow.providers.standard.operators.empty import EmptyOperator from airflow.providers.standard.operators.python import PythonOperator, ShortCircuitOperator -from airflow.sdk import DAG, BaseOperator, setup, task, task_group, teardown +from airflow.sdk import DAG, BaseOperator, get_current_context, setup, task, task_group, teardown from airflow.sdk.definitions.deadline import AsyncCallback, DeadlineAlert, DeadlineReference from airflow.serialization.serialized_objects import LazyDeserializedDAG, SerializedDAG from airflow.stats import Stats @@ -401,7 +401,9 @@ def on_success_callable(context): } dag_run = self.create_dag_run(dag=dag, task_states=initial_task_states, session=session) - _, callback = dag_run.update_state() + with mock.patch.object(dag_run, "handle_dag_callback") as handle_dag_callback: + _, callback = dag_run.update_state() + assert handle_dag_callback.mock_calls == [mock.call(dag=dag, success=True, reason="success")] assert dag_run.state == DagRunState.SUCCESS # Callbacks are not added until handle_callback = False is passed to dag_run.update_state() assert callback is None @@ -426,7 +428,9 @@ def on_failure_callable(context): dag_task1.set_downstream(dag_task2) dag_run = self.create_dag_run(dag=dag, task_states=initial_task_states, session=session) - _, callback = dag_run.update_state() + with mock.patch.object(dag_run, "handle_dag_callback") as handle_dag_callback: + _, callback = dag_run.update_state() + assert handle_dag_callback.mock_calls == [mock.call(dag=dag, success=False, reason="task_failure")] assert dag_run.state == DagRunState.FAILED # Callbacks are not added until handle_callback = False is passed to dag_run.update_state() assert callback is None @@ -790,8 +794,7 @@ def test_get_task_instance_on_empty_dagrun(self, dag_maker, session): schedule=datetime.timedelta(days=1), start_date=timezone.datetime(2017, 1, 1), ) as dag: - ... - ShortCircuitOperator(task_id="test_short_circuit_false", dag=dag, python_callable=lambda: False) + ShortCircuitOperator(task_id="test_short_circuit_false", python_callable=lambda: False) now = timezone.utcnow() @@ -1282,7 +1285,9 @@ def on_success_callable(context): dag_run = session.merge(dag_run) dag_run.dag = dag - _, callback = dag_run.update_state() + with mock.patch.object(dag_run, "handle_dag_callback") as handle_dag_callback: + _, callback = dag_run.update_state() + assert handle_dag_callback.mock_calls == [mock.call(dag=dag, success=True, reason="success")] assert dag_run.state == DagRunState.SUCCESS # Callbacks are not added until handle_callback = False is passed to dag_run.update_state() assert callback is None @@ -2164,14 +2169,20 @@ def do_something_else(i): dr = dag_maker.create_dagrun() - ti = dr.get_task_instance("do_something_else", session=session) - ti.map_index = 0 - task = ti.task - for map_index in range(1, 5): - ti = TI(task, run_id=dr.run_id, map_index=map_index, dag_version_id=ti.dag_version_id) - session.add(ti) - ti.dag_run = dr + tis = dr.get_task_instances() + for ti in tis: + if ti.task_id == "do_something_else": + ti.map_index = 0 + task = ti.task + for map_index in range(1, 5): + ti = TI(task, run_id=dr.run_id, map_index=map_index, dag_version_id=ti.dag_version_id) + session.add(ti) + ti.dag_run = dr + else: + # run tasks "do_something" to get XCOMs for correct downstream length + ti.run() session.flush() + tis = dr.get_task_instances() for ti in tis: if ti.task_id == "do_something": @@ -2183,7 +2194,7 @@ def do_something_else(i): session.commit() # The Upstream is done with 2 removed tis and 3 success tis (tis, _) = dr.update_state() - assert len(tis) + assert len(tis) == 3 assert dr.state != DagRunState.FAILED @@ -2242,6 +2253,59 @@ def tg(x, y): } +@pytest.mark.parametrize("rerun_length", [0, 1, 2, 3]) +def test_mapped_task_rerun_with_different_length_of_args(session, dag_maker, rerun_length): + @task + def generate_mapping_args(): + context = get_current_context() + if context["ti"].try_number == 0: + args = [i for i in range(2)] + else: + args = [i for i in range(rerun_length)] + return args + + @task + def mapped_print_value(arg): + return arg + + with dag_maker(session=session): + args = generate_mapping_args() + mapped_print_value.expand(arg=args) + + # First Run + dr = dag_maker.create_dagrun() + dag_maker.run_ti("generate_mapping_args", dr) + + decision = dr.task_instance_scheduling_decisions(session=session) + for ti in decision.schedulable_tis: + dag_maker.run_ti(ti.task_id, dr, map_index=ti.map_index) + + clear_task_instances(dr.get_task_instances(), session=session) + + # Second Run + ti = dr.get_task_instance(task_id="generate_mapping_args", session=session) + ti.try_number += 1 + session.merge(ti) + dag_maker.run_ti("generate_mapping_args", dr) + + # Check if the new mapped task instances are correctly scheduled + decision = dr.task_instance_scheduling_decisions(session=session) + assert len(decision.schedulable_tis) == rerun_length + assert all([ti.task_id == "mapped_print_value" for ti in decision.schedulable_tis]) + + # Check if mapped task rerun successfully + for ti in decision.schedulable_tis: + dag_maker.run_ti(ti.task_id, dr, map_index=ti.map_index) + query = select(TI).where( + TI.dag_id == dr.dag_id, + TI.run_id == dr.run_id, + TI.task_id == "mapped_print_value", + TI.state == TaskInstanceState.SUCCESS, + ) + success_tis = session.execute(query).all() + assert len(success_tis) == rerun_length + + def test_operator_mapped_task_group_receives_value(dag_maker, session): with dag_maker(session=session): diff --git a/airflow-core/tests/unit/models/test_mappedoperator.py b/airflow-core/tests/unit/models/test_mappedoperator.py index 84d05b3b932e6..bd20b5e1f4f38 100644 --- a/airflow-core/tests/unit/models/test_mappedoperator.py +++ b/airflow-core/tests/unit/models/test_mappedoperator.py @@ -17,7 +17,9 @@ # under the License. from __future__ import annotations +import datetime from collections import defaultdict +from datetime import timedelta from typing import TYPE_CHECKING from unittest import mock from unittest.mock import patch @@ -31,6 +33,8 @@ from airflow.models.taskmap import TaskMap from airflow.providers.standard.operators.python import PythonOperator from airflow.sdk import DAG, BaseOperator, TaskGroup, setup, task, task_group, teardown +from airflow.serialization.serialized_objects import SerializedBaseOperator +from airflow.task.priority_strategy import PriorityWeightStrategy from airflow.task.trigger_rule import TriggerRule from airflow.utils.state import TaskInstanceState @@ -1371,6 +1375,181 @@ def group(n: int) -> None: } assert states == expected + @pytest.mark.parametrize( + ( + "email," + "execution_timeout," + "retry_delay," + "max_retry_delay," + "retry_exponential_backoff," + "max_active_tis_per_dag," + "max_active_tis_per_dagrun," + "run_as_user," + "resources," + "has_on_execute_callback," + "has_on_failure_callback," + "has_on_retry_callback," + "has_on_success_callback," + "has_on_skipped_callback," + "executor_config," + "inlets," + "outlets," + "doc," + "doc_md," + "doc_json," + "doc_yaml," + "doc_rst" + ), + [ + pytest.param( + # Default case + "email", + timedelta(seconds=10), + timedelta(seconds=5), + timedelta(seconds=60), + True, + 1, + 2, + "user", + None, + False, + False, + False, + False, + False, + None, + None, + None, + None, + None, + None, + None, + None, + id="default", + ), + pytest.param( + # With all optional values and callbacks set + None, + timedelta(seconds=20), + timedelta(seconds=10), + timedelta(seconds=120), + False, + 3, + 5, + None, + {"CPU": 1}, + True, + True, + True, + True, + True, + {"key": "value"}, + ["input_table"], + ["output_table"], + "Some docs", + "MD docs", + {"json": True}, + "yaml: true", + "RST docs", + id="with-values-and-callbacks", + ), + ], + ) + def test_properties( + self, + email, + execution_timeout, + retry_delay, + max_retry_delay, + retry_exponential_backoff, + max_active_tis_per_dag, + max_active_tis_per_dagrun, + run_as_user, + resources, + has_on_execute_callback, + has_on_failure_callback, + has_on_retry_callback, + has_on_success_callback, + has_on_skipped_callback, + executor_config, + inlets, + outlets, + doc, + doc_md, + doc_json, + doc_yaml, + doc_rst, + ): + op = PythonOperator.partial( + task_id="mapped", + python_callable=print, + email=email, + execution_timeout=execution_timeout, + retry_delay=retry_delay, + max_retry_delay=max_retry_delay, + retry_exponential_backoff=retry_exponential_backoff, + max_active_tis_per_dag=max_active_tis_per_dag, + max_active_tis_per_dagrun=max_active_tis_per_dagrun, + run_as_user=run_as_user, + resources=resources, + on_execute_callback=(lambda: None) if has_on_execute_callback else None, + on_failure_callback=(lambda: None) if has_on_failure_callback else None, + on_retry_callback=(lambda: None) if has_on_retry_callback else None, + on_success_callback=(lambda: None) if has_on_success_callback else None, + on_skipped_callback=(lambda: None) if has_on_skipped_callback else None, + executor_config=executor_config, + inlets=inlets, + outlets=outlets, + doc=doc, + doc_md=doc_md, + doc_json=doc_json, + doc_yaml=doc_yaml, + doc_rst=doc_rst, + ).expand(op_args=["Hello", "world"]) + + assert op.operator_name == PythonOperator.__name__ + assert op.roots == [op] + assert op.leaves == [op] + assert op.task_display_name == "mapped" + assert op.owner == SerializedBaseOperator.owner + assert op.trigger_rule == SerializedBaseOperator.trigger_rule + assert not op.map_index_template + assert not op.is_setup + assert not op.is_teardown + assert not op.depends_on_past + assert op.ignore_first_depends_on_past == bool(SerializedBaseOperator.ignore_first_depends_on_past) + assert not op.wait_for_downstream + assert op.retries == SerializedBaseOperator.retries + assert op.queue == SerializedBaseOperator.queue + assert op.pool == SerializedBaseOperator.pool + assert op.pool_slots == SerializedBaseOperator.pool_slots + assert op.priority_weight == SerializedBaseOperator.priority_weight + assert isinstance(op.weight_rule, PriorityWeightStrategy) + assert op.email == email + assert op.execution_timeout == execution_timeout + assert op.retry_delay == retry_delay + assert op.max_retry_delay == max_retry_delay + assert op.retry_exponential_backoff == retry_exponential_backoff + assert op.max_active_tis_per_dag == max_active_tis_per_dag + assert op.max_active_tis_per_dagrun == max_active_tis_per_dagrun + assert op.run_as_user == run_as_user + assert op.email_on_failure + assert op.email_on_retry + assert (op.resources is not None) == bool(resources) + assert op.has_on_execute_callback == has_on_execute_callback + assert op.has_on_failure_callback == has_on_failure_callback + assert op.has_on_retry_callback == has_on_retry_callback + assert op.has_on_success_callback == has_on_success_callback + assert op.has_on_skipped_callback == has_on_skipped_callback + assert (op.executor_config is not None) == bool(executor_config) + assert (op.inlets is not None) == bool(inlets) + assert (op.outlets is not None) == bool(outlets) + assert (op.doc is not None) == bool(doc) + assert (op.doc_md is not None) == bool(doc_md) + assert (op.doc_json is not None) == bool(doc_json) + assert (op.doc_yaml is not None) == bool(doc_yaml) + assert (op.doc_rst is not None) == bool(doc_rst) + def test_mapped_tasks_in_mapped_task_group_waits_for_upstreams_to_complete(dag_maker, session): """Test that one failed trigger rule works well in mapped task group""" @@ -1401,3 +1580,45 @@ def t3(a): dr.task_instance_scheduling_decisions() ti3 = dr.get_task_instance(task_id="tg1.t3") assert not ti3.state + + +def test_mapped_operator_retry_delay_default(dag_maker): + """ + Test that MappedOperator.retry_delay returns default value when not explicitly set. + + This test verifies the fix for a KeyError that occurred when accessing retry_delay + on a MappedOperator without an explicit retry_delay value in partial_kwargs. + The property should fall back to SerializedBaseOperator.retry_delay (300 seconds). + """ + with dag_maker(dag_id="test_retry_delay", serialized=True) as dag: + # Create a mapped operator without explicitly setting retry_delay + MockOperator.partial(task_id="mapped_task").expand(arg2=[1, 2, 3]) + + # Get the deserialized mapped task + mapped_deser = dag.task_dict["mapped_task"] + + # Accessing retry_delay should not raise KeyError + # and should return the default value (300 seconds) + assert mapped_deser.retry_delay == datetime.timedelta(seconds=300) + + +def test_mapped_operator_retry_delay_explicit(dag_maker): + """ + Test that MappedOperator.retry_delay returns explicit value when set. + + This test verifies that when retry_delay is explicitly set in partial(), + the MappedOperator returns that value instead of the default. + """ + custom_retry_delay = datetime.timedelta(seconds=600) + + with dag_maker(dag_id="test_retry_delay_explicit", serialized=True) as dag: + # Create a mapped operator with explicit retry_delay + MockOperator.partial(task_id="mapped_task_with_retry", retry_delay=custom_retry_delay).expand( + arg2=[1, 2, 3] + ) + + # Get the deserialized mapped task + mapped_deser = dag.task_dict["mapped_task_with_retry"] + + # Should return the explicitly set value + assert mapped_deser.retry_delay == custom_retry_delay diff --git a/airflow-core/tests/unit/models/test_taskinstance.py b/airflow-core/tests/unit/models/test_taskinstance.py index 0df775ca41e17..74260a05a11ce 100644 --- a/airflow-core/tests/unit/models/test_taskinstance.py +++ b/airflow-core/tests/unit/models/test_taskinstance.py @@ -38,7 +38,6 @@ from airflow.exceptions import ( AirflowException, AirflowFailException, - AirflowInactiveAssetInInletOrOutletException, AirflowSkipException, ) from airflow.models.asset import AssetActive, AssetAliasModel, AssetEvent, AssetModel @@ -488,12 +487,12 @@ def test_retry_delay(self, dag_maker, time_machine): ) def run_with_error(ti): + orig_task, ti.task = ti.task, task with contextlib.suppress(AirflowException): ti.run() + ti.task = orig_task ti = dag_maker.create_dagrun(logical_date=timezone.utcnow()).task_instances[0] - ti.task = task - with create_session() as session: session.get(TaskInstance, ti.id).try_number += 1 @@ -539,13 +538,13 @@ def test_retry_handling(self, dag_maker, session): ) def run_with_error(ti): + orig_task, ti.task = ti.task, task with contextlib.suppress(AirflowException): ti.run() + ti.task = orig_task ti = dag_maker.create_dagrun(logical_date=timezone.utcnow()).task_instances[0] - ti.task = task assert ti.try_number == 0 - session.get(TaskInstance, ti.id).try_number += 1 session.commit() @@ -2688,41 +2687,6 @@ def test_task_instance_history_is_created_when_ti_goes_for_retry(self, dag_maker # the new try_id should be different from what's recorded in tih assert str(tih[0].task_instance_id) == try_id - @pytest.mark.skip( - reason="This test has some issues that were surfaced when dag_maker started allowing multiple serdag versions. Issue #48539 will track fixing this." - ) - def test_run_with_inactive_assets(self, dag_maker, session): - from airflow.sdk.definitions.asset import Asset - - with dag_maker(schedule=None, serialized=True, session=session): - - @task(outlets=Asset("asset_first")) - def first_asset_task(*, outlet_events): - outlet_events[Asset("asset_first")].extra = {"foo": "bar"} - - first_asset_task() - - with dag_maker(schedule=None, serialized=True, session=session): - - @task(inlets=Asset("asset_second")) - def asset_task_in_inlet(): - pass - - @task(outlets=Asset(name="asset_first", uri="test://asset"), inlets=Asset("asset_second")) - def duplicate_asset_task_in_outlet(*, outlet_events): - outlet_events[Asset(name="asset_first", uri="test://asset")].extra = {"foo": "bar"} - - duplicate_asset_task_in_outlet() >> asset_task_in_inlet() - - tis = {ti.task_id: ti for ti in dag_maker.create_dagrun().task_instances} - - tis["asset_task_in_inlet"].run(session=session) - with pytest.raises(AirflowInactiveAssetInInletOrOutletException) as exc: - tis["duplicate_asset_task_in_outlet"].run(session=session) - - assert "Asset(name='asset_second', uri='asset_second')" in str(exc.value) - assert "Asset(name='asset_first', uri='test://asset/')" in str(exc.value) - @pytest.mark.parametrize("pool_override", [None, "test_pool2"]) @pytest.mark.parametrize("queue_by_policy", [None, "forced_queue"]) diff --git a/airflow-core/tests/unit/plugins/test_plugin.py b/airflow-core/tests/unit/plugins/test_plugin.py index def446620e94b..62e642955ef6e 100644 --- a/airflow-core/tests/unit/plugins/test_plugin.py +++ b/airflow-core/tests/unit/plugins/test_plugin.py @@ -183,3 +183,18 @@ class AirflowTestOnLoadPlugin(AirflowPlugin): def on_load(self, *args, **kwargs): self.name = "postload" + + +# Example external view with invalid destination +external_view_with_invalid_destination = { + "name": "Invalid External View", + "href": "https://example.com/invalid", + "url_route": "invalid_external_view", + "destination": "Assets", # <-- invalid destination + "icon": "book", +} + + +class AirflowTestPluginInvalid(AirflowPlugin): + name = "test_plugin_invalid" + external_views = [external_view_with_invalid_destination] diff --git a/airflow-core/tests/unit/plugins/test_plugins_manager.py b/airflow-core/tests/unit/plugins/test_plugins_manager.py index 0df2e0d05053d..eaf799ff12c13 100644 --- a/airflow-core/tests/unit/plugins/test_plugins_manager.py +++ b/airflow-core/tests/unit/plugins/test_plugins_manager.py @@ -94,7 +94,7 @@ def test_loads_filesystem_plugins(self, caplog): with mock.patch("airflow.plugins_manager.plugins", []): plugins_manager.load_plugins_from_plugin_directory() - assert len(plugins_manager.plugins) == 9 + assert len(plugins_manager.plugins) == 10 for plugin in plugins_manager.plugins: if "AirflowTestOnLoadPlugin" in str(plugin): assert plugin.name == "postload" diff --git a/airflow-core/tests/unit/serialization/test_dag_serialization.py b/airflow-core/tests/unit/serialization/test_dag_serialization.py index 74865b655a7b1..80c08b23ee001 100644 --- a/airflow-core/tests/unit/serialization/test_dag_serialization.py +++ b/airflow-core/tests/unit/serialization/test_dag_serialization.py @@ -19,13 +19,12 @@ from __future__ import annotations +import contextlib import copy import dataclasses import importlib import importlib.util import json -import logging -import logging.config import multiprocessing import os import pickle @@ -48,7 +47,6 @@ import airflow from airflow._shared.timezones import timezone -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.exceptions import ( AirflowException, ParamValidationError, @@ -61,7 +59,7 @@ from airflow.models.xcom import XCOM_RETURN_KEY, XComModel from airflow.providers.cncf.kubernetes.pod_generator import PodGenerator from airflow.providers.standard.operators.bash import BashOperator -from airflow.sdk import DAG, AssetAlias, BaseHook, teardown +from airflow.sdk import DAG, AssetAlias, BaseHook, WeightRule, teardown from airflow.sdk.bases.decorator import DecoratedOperator from airflow.sdk.bases.operator import OPERATOR_DEFAULTS, BaseOperator from airflow.sdk.definitions._internal.expandinput import EXPAND_INPUT_EMPTY @@ -78,7 +76,7 @@ SerializedDAG, XComOperatorLink, ) -from airflow.task.priority_strategy import _DownstreamPriorityWeightStrategy +from airflow.task.priority_strategy import _AbsolutePriorityWeightStrategy, _DownstreamPriorityWeightStrategy from airflow.ti_deps.deps.ready_to_reschedule import ReadyToRescheduleDep from airflow.timetables.simple import NullTimetable, OnceTimetable from airflow.triggers.base import StartTriggerArgs @@ -102,6 +100,43 @@ if TYPE_CHECKING: from airflow.sdk.definitions.context import Context + +@contextlib.contextmanager +def operator_defaults(overrides): + """ + Temporarily patches OPERATOR_DEFAULTS, restoring original values after context exit. + + Example: + with operator_defaults({"retries": 2, "retry_delay": 200.0}): + # Test code with modified operator defaults + """ + from airflow.sdk.bases.operator import OPERATOR_DEFAULTS + + original_values = {} + try: + # Store original values and apply overrides + for key, value in overrides.items(): + original_values[key] = OPERATOR_DEFAULTS.get(key) + OPERATOR_DEFAULTS[key] = value + + # Clear the cache to ensure fresh generation + SerializedBaseOperator.generate_client_defaults.cache_clear() + + yield + finally: + # Cleanup: restore original values + for key, original_value in original_values.items(): + if original_value is None and key in OPERATOR_DEFAULTS: + # Key didn't exist originally, remove it + del OPERATOR_DEFAULTS[key] + else: + # Restore original value + OPERATOR_DEFAULTS[key] = original_value + + # Clear cache again to restore normal behavior + SerializedBaseOperator.generate_client_defaults.cache_clear() + + AIRFLOW_REPO_ROOT_PATH = Path(airflow.__file__).parents[3] @@ -119,15 +154,14 @@ TYPE = Encoding.TYPE VAR = Encoding.VAR serialized_simple_dag_ground_truth = { - "__version": 2, - "client_defaults": {"tasks": {"retry_delay": 300.0}}, + "__version": 3, "dag": { "default_args": { "__type": "dict", "__var": { "depends_on_past": False, "retries": 1, - "retry_delay": {"__type": "timedelta", "__var": 300.0}, + "retry_delay": {"__type": "timedelta", "__var": 240.0}, "max_retry_delay": {"__type": "timedelta", "__var": 600.0}, }, }, @@ -155,13 +189,8 @@ "downstream_task_ids": [], }, "is_paused_upon_creation": False, - "max_active_runs": 16, - "max_active_tasks": 16, - "max_consecutive_failed_dag_runs": 0, "dag_id": "simple_dag", "deadline": None, - "catchup": False, - "disable_bundle_versioning": False, "doc_md": "### DAG Tutorial Documentation", "fileloc": None, "_processor_dags_folder": ( @@ -173,7 +202,7 @@ "__var": { "task_id": "bash_task", "retries": 1, - "retry_delay": 300.0, + "retry_delay": 240.0, "max_retry_delay": 600.0, "ui_color": "#f0ede4", "template_ext": [".sh", ".bash"], @@ -232,7 +261,7 @@ "__var": { "task_id": "custom_task", "retries": 1, - "retry_delay": 300.0, + "retry_delay": 240.0, "max_retry_delay": 600.0, "_operator_extra_links": {"Google Custom": "_link_CustomOpLink"}, "template_fields": ["bash_command"], @@ -272,7 +301,6 @@ }, ], "params": [], - "tags": [], }, } @@ -303,7 +331,7 @@ def make_simple_dag(): schedule=timedelta(days=1), default_args={ "retries": 1, - "retry_delay": timedelta(minutes=5), + "retry_delay": timedelta(minutes=4), "max_retry_delay": timedelta(minutes=10), "depends_on_past": False, }, @@ -447,9 +475,6 @@ def timetable_plugin(monkeypatch): class TestStringifiedDAGs: """Unit tests for stringified DAGs.""" - def setup_method(self): - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) - @pytest.fixture(autouse=True) def setup_test_cases(self): with mock.patch.object(BaseHook, "get_connection") as m: @@ -629,7 +654,7 @@ def test_deserialization_across_process(self): if v is None: break dag = SerializedDAG.from_json(v) - assert isinstance(dag, DAG) + assert isinstance(dag, SerializedDAG) stringified_dags[dag.dag_id] = dag dags, _ = collect_dags("airflow/example_dags") @@ -963,7 +988,7 @@ def test_deserialization_timetable( expected_timetable, ): serialized = { - "__version": 2, + "__version": 3, "dag": { "default_args": {"__type": "dict", "__var": {}}, "dag_id": "simple_dag", @@ -977,9 +1002,58 @@ def test_deserialization_timetable( dag = SerializedDAG.from_dict(serialized) assert dag.timetable == expected_timetable + @pytest.mark.parametrize( + "serialized_timetable, expected_timetable_summary", + [ + ( + {"__type": "airflow.timetables.simple.NullTimetable", "__var": {}}, + "None", + ), + ( + { + "__type": "airflow.timetables.interval.CronDataIntervalTimetable", + "__var": {"expression": "@weekly", "timezone": "UTC"}, + }, + "0 0 * * 0", + ), + ( + {"__type": "airflow.timetables.simple.OnceTimetable", "__var": {}}, + "@once", + ), + ( + { + "__type": "airflow.timetables.interval.DeltaDataIntervalTimetable", + "__var": {"delta": 86400.0}, + }, + "1 day, 0:00:00", + ), + (CUSTOM_TIMETABLE_SERIALIZED, "CustomSerializationTimetable('foo')"), + ], + ) + @pytest.mark.usefixtures("timetable_plugin") + def test_deserialization_timetable_summary( + self, + serialized_timetable, + expected_timetable_summary, + ): + serialized = { + "__version": 3, + "dag": { + "default_args": {"__type": "dict", "__var": {}}, + "dag_id": "simple_dag", + "fileloc": __file__, + "tasks": [], + "timezone": "UTC", + "timetable": serialized_timetable, + }, + } + SerializedDAG.validate_schema(serialized) + dag = SerializedDAG.from_dict(serialized) + assert dag.timetable_summary == expected_timetable_summary + def test_deserialization_timetable_unregistered(self): serialized = { - "__version": 2, + "__version": 3, "dag": { "default_args": {"__type": "dict", "__var": {}}, "dag_id": "simple_dag", @@ -1103,8 +1177,8 @@ def test_full_param_roundtrip(self, param: Param): """ Test to make sure that only native Param objects are being passed as dag or task params """ - dag = DAG(dag_id="simple_dag", schedule=None, params={"my_param": param}) - serialized_json = SerializedDAG.to_json(dag) + sdk_dag = DAG(dag_id="simple_dag", schedule=None, params={"my_param": param}) + serialized_json = SerializedDAG.to_json(sdk_dag) serialized = json.loads(serialized_json) SerializedDAG.validate_schema(serialized) dag = SerializedDAG.from_dict(serialized) @@ -2183,7 +2257,8 @@ def test_dag_disable_bundle_versioning_roundtrip(self, dag_arg, conf_arg, expect """ with conf_vars({("dag_processor", "disable_bundle_versioning"): conf_arg}): kwargs = {} - kwargs["disable_bundle_versioning"] = dag_arg + if dag_arg is not None: + kwargs["disable_bundle_versioning"] = dag_arg dag = DAG( dag_id="test_dag_disable_bundle_versioning_roundtrip", schedule=None, @@ -2248,7 +2323,7 @@ def test_serialized_objects_are_sorted(self, object_to_serialized, expected_outp def test_params_upgrade(self): """When pre-2.2.0 param (i.e. primitive) is deserialized we convert to Param""" serialized = { - "__version": 2, + "__version": 3, "dag": { "dag_id": "simple_dag", "fileloc": "/path/to/file.py", @@ -2269,7 +2344,7 @@ def test_params_serialization_from_dict_upgrade(self): This test asserts that the params are still deserialized properly. """ serialized = { - "__version": 2, + "__version": 3, "dag": { "dag_id": "simple_dag", "fileloc": "/path/to/file.py", @@ -2296,7 +2371,7 @@ def test_params_serialize_default_2_2_0(self): test only to ensure that params stored in 2.2.0 can still be parsed correctly. """ serialized = { - "__version": 2, + "__version": 3, "dag": { "dag_id": "simple_dag", "fileloc": "/path/to/file.py", @@ -2313,7 +2388,7 @@ def test_params_serialize_default_2_2_0(self): def test_params_serialize_default(self): serialized = { - "__version": 2, + "__version": 3, "dag": { "dag_id": "simple_dag", "fileloc": "/path/to/file.py", @@ -2453,7 +2528,7 @@ def execute_complete(self): def test_kubernetes_optional(): - """Serialisation / deserialisation continues to work without kubernetes installed""" + """Test that serialization module loads without kubernetes, but deserialization of PODs requires it""" def mock__import__(name, globals_=None, locals_=None, fromlist=(), level=0): if level == 0 and name.partition(".")[0] == "kubernetes": @@ -2480,7 +2555,8 @@ def mock__import__(name, globals_=None, locals_=None, fromlist=(), level=0): "__var": PodGenerator.serialize_pod(executor_config_pod), } - with pytest.raises(RuntimeError): + # we should error if attempting to deserialize POD without kubernetes installed + with pytest.raises(RuntimeError, match="Cannot deserialize POD objects without kubernetes"): module.BaseSerialization.from_dict(pod_override) # basic serialization should succeed @@ -3034,7 +3110,7 @@ def test_handle_v1_serdag(): "__var": { "depends_on_past": False, "retries": 1, - "retry_delay": {"__type": "timedelta", "__var": 300.0}, + "retry_delay": {"__type": "timedelta", "__var": 240.0}, "max_retry_delay": {"__type": "timedelta", "__var": 600.0}, "sla": {"__type": "timedelta", "__var": 100.0}, }, @@ -3072,7 +3148,7 @@ def test_handle_v1_serdag(): "__var": { "task_id": "bash_task", "retries": 1, - "retry_delay": 300.0, + "retry_delay": 240.0, "max_retry_delay": 600.0, "sla": 100.0, "downstream_task_ids": [], @@ -3135,7 +3211,7 @@ def test_handle_v1_serdag(): "__var": { "task_id": "custom_task", "retries": 1, - "retry_delay": 300.0, + "retry_delay": 240.0, "max_retry_delay": 600.0, "sla": 100.0, "downstream_task_ids": [], @@ -3303,18 +3379,304 @@ def test_handle_v1_serdag(): ] SerializedDAG.conversion_v1_to_v2(v1) + SerializedDAG.conversion_v2_to_v3(v1) + + dag = SerializedDAG.from_dict(v1) + + expected_sdag = copy.deepcopy(serialized_simple_dag_ground_truth) + expected = SerializedDAG.from_dict(expected_sdag) + + fields_to_verify = set(vars(expected).keys()) - { + "task_group", # Tested separately + "dag_dependencies", # Tested separately + "last_loaded", # Dynamically set to utcnow + } + + for f in fields_to_verify: + dag_value = getattr(dag, f) + expected_value = getattr(expected, f) + + assert dag_value == expected_value, ( + f"V2 DAG field '{f}' differs from V3: V2={dag_value!r} != V3={expected_value!r}" + ) + + for f in set(vars(expected.task_group).keys()) - {"dag"}: + dag_tg_value = getattr(dag.task_group, f) + expected_tg_value = getattr(expected.task_group, f) + + assert dag_tg_value == expected_tg_value, ( + f"V2 task_group field '{f}' differs: V2={dag_tg_value!r} != V3={expected_tg_value!r}" + ) + + assert getattr(dag, "dag_dependencies") == expected_dag_dependencies + + +def test_handle_v2_serdag(): + """Test that v2 serialized DAGs can be deserialized properly.""" + v2 = { + "__version": 2, + "dag": { + "default_args": { + "__type": "dict", + "__var": { + "depends_on_past": False, + "retries": 1, + "retry_delay": {"__type": "timedelta", "__var": 240.0}, + "max_retry_delay": {"__type": "timedelta", "__var": 600.0}, + }, + }, + "start_date": 1564617600.0, + "timetable": { + "__type": "airflow.timetables.interval.DeltaDataIntervalTimetable", + "__var": { + "delta": 86400.0, + }, + }, + "task_group": { + "_group_id": None, + "group_display_name": "", + "prefix_group_id": True, + "children": { + "bash_task": ("operator", "bash_task"), + "custom_task": ("operator", "custom_task"), + }, + "tooltip": "", + "ui_color": "CornflowerBlue", + "ui_fgcolor": "#000", + "upstream_group_ids": [], + "downstream_group_ids": [], + "upstream_task_ids": [], + "downstream_task_ids": [], + }, + "is_paused_upon_creation": False, + "dag_id": "simple_dag", + "catchup": False, + "disable_bundle_versioning": False, + "doc_md": "### DAG Tutorial Documentation", + "fileloc": None, + "_processor_dags_folder": ( + AIRFLOW_REPO_ROOT_PATH / "airflow-core" / "tests" / "unit" / "dags" + ).as_posix(), + "tasks": [ + { + "__type": "operator", + "__var": { + "task_id": "bash_task", + "retries": 1, + "retry_delay": 240.0, + "max_retry_delay": 600.0, + "downstream_task_ids": [], + "ui_color": "#f0ede4", + "ui_fgcolor": "#000", + "template_ext": [".sh", ".bash"], + "template_fields": ["bash_command", "env", "cwd"], + "template_fields_renderers": { + "bash_command": "bash", + "env": "json", + }, + "bash_command": "echo {{ task.task_id }}", + "task_type": "BashOperator", + "_task_module": "airflow.providers.standard.operators.bash", + "owner": "airflow1", + "pool": "pool1", + "is_setup": False, + "is_teardown": False, + "on_failure_fail_dagrun": False, + "executor_config": { + "__type": "dict", + "__var": { + "pod_override": { + "__type": "k8s.V1Pod", + "__var": PodGenerator.serialize_pod(executor_config_pod), + } + }, + }, + "doc_md": "### Task Tutorial Documentation", + "_needs_expansion": False, + "weight_rule": "downstream", + "start_trigger_args": None, + "start_from_trigger": False, + "inlets": [ + { + "__type": "asset", + "__var": { + "extra": {}, + "group": "asset", + "name": "asset-1", + "uri": "asset-1", + }, + }, + { + "__type": "asset_alias", + "__var": {"group": "asset", "name": "alias-name"}, + }, + ], + "outlets": [ + { + "__type": "asset", + "__var": { + "extra": {}, + "group": "asset", + "name": "asset-2", + "uri": "asset-2", + }, + }, + ], + }, + }, + { + "__type": "operator", + "__var": { + "task_id": "custom_task", + "retries": 1, + "retry_delay": 240.0, + "max_retry_delay": 600.0, + "downstream_task_ids": [], + "_operator_extra_links": {"Google Custom": "_link_CustomOpLink"}, + "ui_color": "#fff", + "ui_fgcolor": "#000", + "template_ext": [], + "template_fields": ["bash_command"], + "template_fields_renderers": {}, + "task_type": "CustomOperator", + "_operator_name": "@custom", + "_task_module": "tests_common.test_utils.mock_operators", + "pool": "default_pool", + "is_setup": False, + "is_teardown": False, + "on_failure_fail_dagrun": False, + "_needs_expansion": False, + "weight_rule": "downstream", + "start_trigger_args": None, + "start_from_trigger": False, + }, + }, + ], + "timezone": "UTC", + "access_control": { + "__type": "dict", + "__var": { + "test_role": { + "__type": "dict", + "__var": { + "DAGs": { + "__type": "set", + "__var": [ + permissions.ACTION_CAN_READ, + permissions.ACTION_CAN_EDIT, + ], + } + }, + } + }, + }, + "edge_info": {}, + "dag_dependencies": [ + { + "dependency_id": '{"name": "asset-2", "uri": "asset-2"}', + "dependency_type": "asset", + "label": "asset-2", + "source": "simple_dag", + "target": "asset", + }, + ], + "params": [], + "tags": [], + }, + } + + # Test that v2 DAGs can be deserialized without conversion + dag = SerializedDAG.from_dict(v2) + + expected_sdag = copy.deepcopy(serialized_simple_dag_ground_truth) + expected = SerializedDAG.from_dict(expected_sdag) + + fields_to_verify = set(vars(expected).keys()) - { + "task_group", # Tested separately + "last_loaded", # Dynamically set to utcnow + } + + for f in fields_to_verify: + dag_value = getattr(dag, f) + expected_value = getattr(expected, f) + + assert dag_value == expected_value, ( + f"V2 DAG field '{f}' differs from V3: V2={dag_value!r} != V3={expected_value!r}" + ) + + for f in set(vars(expected.task_group).keys()) - {"dag"}: + dag_tg_value = getattr(dag.task_group, f) + expected_tg_value = getattr(expected.task_group, f) + + assert dag_tg_value == expected_tg_value, ( + f"V2 task_group field '{f}' differs: V2={dag_tg_value!r} != V3={expected_tg_value!r}" + ) + + +def test_dag_schema_defaults_optimization(): + """Test that DAG fields matching schema defaults are excluded from serialization.""" + + # Create DAG with all schema default values + dag_with_defaults = DAG( + dag_id="test_defaults_dag", + start_date=datetime(2023, 1, 1), + # These should match schema defaults and be excluded + catchup=False, + fail_fast=False, + max_active_runs=16, + max_active_tasks=16, + max_consecutive_failed_dag_runs=0, + render_template_as_native_obj=False, + disable_bundle_versioning=False, + # These should be excluded as None + description=None, + doc_md=None, + ) - # Update a few subtle differences - v1["dag"]["tags"] = [] - v1["dag"]["catchup"] = False - v1["dag"]["disable_bundle_versioning"] = False + # Serialize and check exclusions + serialized = SerializedDAG.to_dict(dag_with_defaults) + dag_data = serialized["dag"] + + # Schema default fields should be excluded + for field in SerializedDAG.get_schema_defaults("dag").keys(): + assert field not in dag_data, f"Schema default field '{field}' should be excluded" + + # None fields should also be excluded + none_fields = ["description", "doc_md"] + for field in none_fields: + assert field not in dag_data, f"None field '{field}' should be excluded" + + # Test deserialization restores defaults correctly + deserialized_dag = SerializedDAG.from_dict(serialized) + + # Verify schema defaults are restored + assert deserialized_dag.catchup is False + assert deserialized_dag.fail_fast is False + assert deserialized_dag.max_active_runs == 16 + assert deserialized_dag.max_active_tasks == 16 + assert deserialized_dag.max_consecutive_failed_dag_runs == 0 + assert deserialized_dag.render_template_as_native_obj is False + assert deserialized_dag.disable_bundle_versioning is False + + # Test with non-default values (should be included) + dag_non_defaults = DAG( + dag_id="test_non_defaults_dag", + start_date=datetime(2023, 1, 1), + catchup=True, # Non-default + max_active_runs=32, # Non-default + description="Test description", # Non-None + ) - expected = copy.deepcopy(serialized_simple_dag_ground_truth) - expected["dag"]["dag_dependencies"] = expected_dag_dependencies - del expected["dag"]["tasks"][1]["__var"]["_operator_extra_links"] + serialized_non_defaults = SerializedDAG.to_dict(dag_non_defaults) + dag_non_defaults_data = serialized_non_defaults["dag"] - del expected["client_defaults"] - assert v1 == expected + # Non-default values should be included + assert "catchup" in dag_non_defaults_data + assert dag_non_defaults_data["catchup"] is True + assert "max_active_runs" in dag_non_defaults_data + assert dag_non_defaults_data["max_active_runs"] == 32 + assert "description" in dag_non_defaults_data + assert dag_non_defaults_data["description"] == "Test description" def test_email_optimization_removes_email_attrs_when_email_empty(): @@ -3527,6 +3889,27 @@ def test_task_callback_backward_compatibility(old_callback_name, new_callback_na assert getattr(deserialized_task_empty, new_callback_name) is False +def test_weight_rule_absolute_serialization_deserialization(): + """Test that weight_rule can be serialized and deserialized correctly.""" + from airflow.sdk import task + + with DAG("test_weight_rule_dag") as dag: + + @task(weight_rule=WeightRule.ABSOLUTE) + def test_task(): + return "test" + + test_task() + + serialized_dag = SerializedDAG.to_dict(dag) + assert serialized_dag["dag"]["tasks"][0]["__var"]["weight_rule"] == "absolute" + + deserialized_dag = SerializedDAG.from_dict(serialized_dag) + + deserialized_task = deserialized_dag.task_dict["test_task"] + assert isinstance(deserialized_task.weight_rule, _AbsolutePriorityWeightStrategy) + + class TestClientDefaultsGeneration: """Test client defaults generation functionality.""" @@ -3659,8 +4042,9 @@ def test_apply_defaults_to_encoded_op_none_inputs(self): result = SerializedBaseOperator._apply_defaults_to_encoded_op(encoded_op, None) assert result == encoded_op + @operator_defaults({"retries": 2}) def test_multiple_tasks_share_client_defaults(self): - """Test that multiple tasks can share the same client_defaults.""" + """Test that multiple tasks can share the same client_defaults when there are actually non-default values.""" with DAG(dag_id="test_dag") as dag: BashOperator(task_id="task1", bash_command="echo 1") BashOperator(task_id="task2", bash_command="echo 2") @@ -3679,6 +4063,10 @@ def test_multiple_tasks_share_client_defaults(self): deserialized_task1 = deserialized_dag.get_task("task1") deserialized_task2 = deserialized_dag.get_task("task2") + # Both tasks should have retries=2 from client_defaults + assert deserialized_task1.retries == 2 + assert deserialized_task2.retries == 2 + # Both tasks should have the same default values from client_defaults for field in client_defaults: if hasattr(deserialized_task1, field) and hasattr(deserialized_task2, field): @@ -3690,6 +4078,7 @@ def test_multiple_tasks_share_client_defaults(self): class TestMappedOperatorSerializationAndClientDefaults: """Test MappedOperator serialization with client defaults and callback properties.""" + @operator_defaults({"retry_delay": 200.0}) def test_mapped_operator_client_defaults_application(self): """Test that client_defaults are correctly applied to MappedOperator during deserialization.""" with DAG(dag_id="test_mapped_dag") as dag: @@ -3754,6 +4143,7 @@ def test_mapped_operator_client_defaults_application(self): ), ], ) + @operator_defaults({"retry_delay": 200.0}) def test_mapped_operator_client_defaults_optimization( self, task_config, dag_id, task_id, non_default_fields ): diff --git a/airflow-core/tests/unit/serialization/test_serialized_objects.py b/airflow-core/tests/unit/serialization/test_serialized_objects.py index a5cc17dc3ed16..6dc503ff099ab 100644 --- a/airflow-core/tests/unit/serialization/test_serialized_objects.py +++ b/airflow-core/tests/unit/serialization/test_serialized_objects.py @@ -19,6 +19,7 @@ import json import math +import sys from collections.abc import Iterator from datetime import datetime, timedelta @@ -74,6 +75,7 @@ BaseSerialization, LazyDeserializedDAG, SerializedDAG, + _has_kubernetes, create_scheduler_operator, ) from airflow.triggers.base import BaseTrigger @@ -718,3 +720,29 @@ def test_resume_execution(self): next_kwargs={"error": TriggerFailureReason.TRIGGER_TIMEOUT}, context={}, ) + + +class TestKubernetesImportAvoidance: + """Test that serialization doesn't import kubernetes unnecessarily.""" + + def test_has_kubernetes_no_import_when_not_needed(self): + """Ensure _has_kubernetes() doesn't import k8s when not already loaded.""" + # Remove kubernetes from sys.modules if present + k8s_modules = [m for m in list(sys.modules.keys()) if m.startswith("kubernetes")] + if k8s_modules: + pytest.skip("Kubernetes already imported, cannot test import avoidance") + + # Call _has_kubernetes() - should check sys.modules and return False without importing + result = _has_kubernetes() + + assert result is False + assert "kubernetes.client" not in sys.modules + + def test_has_kubernetes_uses_existing_import(self): + """Ensure _has_kubernetes() uses k8s when it's already imported.""" + pytest.importorskip("kubernetes") + + # Now k8s is imported, should return True + result = _has_kubernetes() + + assert result is True diff --git a/airflow-core/tests/unit/task/conftest.py b/airflow-core/tests/unit/task/conftest.py index 2d66ad640e3e8..0dce9f9e1d6bd 100644 --- a/airflow-core/tests/unit/task/conftest.py +++ b/airflow-core/tests/unit/task/conftest.py @@ -17,9 +17,6 @@ from __future__ import annotations -import logging -from logging.config import dictConfig - import pytest @@ -31,10 +28,6 @@ def reset_to_default_logging(): """ yield - from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.listeners.listener import get_listener_manager - airflow_logger = logging.getLogger("airflow") - airflow_logger.handlers = [] - dictConfig(DEFAULT_LOGGING_CONFIG) get_listener_manager().clear() diff --git a/airflow-core/tests/unit/timetables/test_cron_mixin.py b/airflow-core/tests/unit/timetables/test_cron_mixin.py new file mode 100644 index 0000000000000..d8d5ff44df30b --- /dev/null +++ b/airflow-core/tests/unit/timetables/test_cron_mixin.py @@ -0,0 +1,41 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from airflow.timetables._cron import CronMixin + +SAMPLE_TZ = "UTC" + + +def test_valid_cron_expression(): + cm = CronMixin("* * 1 * *", SAMPLE_TZ) # every day at midnight + assert isinstance(cm.description, str) + assert "Every minute" in cm.description or "month" in cm.description + + +def test_invalid_cron_expression(): + cm = CronMixin("invalid cron", SAMPLE_TZ) + assert cm.description == "" + + +def test_dom_and_dow_conflict(): + cm = CronMixin("* * 1 * 1", SAMPLE_TZ) # 1st of month or Monday + desc = cm.description + + assert "(or)" in desc + assert "Every minute, on day 1 of the month" in desc + assert "Every minute, only on Monday" in desc diff --git a/airflow-core/tests/unit/utils/log/test_colored_log.py b/airflow-core/tests/unit/utils/log/test_colored_log.py deleted file mode 100644 index 1eb86868caaa4..0000000000000 --- a/airflow-core/tests/unit/utils/log/test_colored_log.py +++ /dev/null @@ -1,46 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -from __future__ import annotations - -import logging -from unittest.mock import patch - -import pytest - -from airflow.configuration import conf -from airflow.utils.log.colored_log import CustomTTYColoredFormatter - -pytestmark = pytest.mark.db_test - - -@patch("airflow.utils.log.timezone_aware.TimezoneAware.formatTime") -def test_format_time_uses_tz_aware(mock_fmt): - # get a logger that uses CustomTTYColoredFormatter - logger = logging.getLogger("test_format_time") - h = logging.StreamHandler() - - # Explicitly pass fmt to CustomTTYColoredFormatter to avoid side effects - # from the default value being changed by other tests. - # Previously, it was being affected by tests/models/test_trigger.py::test_assign_unassigned - log_fmt = conf.get("logging", "log_format") - h.setFormatter(CustomTTYColoredFormatter(fmt=log_fmt)) - logger.addHandler(h) - - # verify that it uses TimezoneAware.formatTime - logger.info("hi") - mock_fmt.assert_called() diff --git a/airflow-core/tests/unit/utils/log/test_log_reader.py b/airflow-core/tests/unit/utils/log/test_log_reader.py index ba158a53869e2..c32635d59df6a 100644 --- a/airflow-core/tests/unit/utils/log/test_log_reader.py +++ b/airflow-core/tests/unit/utils/log/test_log_reader.py @@ -18,10 +18,10 @@ import copy import datetime -import logging import os import sys import tempfile +import types from typing import TYPE_CHECKING from unittest import mock @@ -79,16 +79,26 @@ def settings_folder(self): @pytest.fixture(autouse=True) def configure_loggers(self, log_dir, settings_folder): - logging_config = copy.deepcopy(DEFAULT_LOGGING_CONFIG) - logging_config["handlers"]["task"]["base_log_folder"] = log_dir - settings_file = os.path.join(settings_folder, "airflow_local_settings_test.py") - with open(settings_file, "w") as handle: - new_logging_file = f"LOGGING_CONFIG = {logging_config}" - handle.writelines(new_logging_file) + logging_config = {**DEFAULT_LOGGING_CONFIG} + logging_config["handlers"] = {**logging_config["handlers"]} + logging_config["handlers"]["task"] = { + **logging_config["handlers"]["task"], + "base_log_folder": log_dir, + } + + mod = types.SimpleNamespace() + mod.LOGGING_CONFIG = logging_config + + # "Inject" a fake module into sys so it loads it without needing to write valid python code + sys.modules["airflow_local_settings_test"] = mod + with conf_vars({("logging", "logging_config_class"): "airflow_local_settings_test.LOGGING_CONFIG"}): settings.configure_logging() - yield - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) + try: + yield + finally: + del sys.modules["airflow_local_settings_test"] + settings.configure_logging() @pytest.fixture(autouse=True) def prepare_log_files(self, log_dir): @@ -258,7 +268,7 @@ def test_read_log_stream_no_end_of_log_marker(self, mock_read): log_stream = task_log_reader.read_log_stream(ti=self.ti, try_number=1, metadata={}) assert list(log_stream) == [ '{"timestamp":null,"event":"hello"}\n', - "(Log stream stopped - End of log marker not found; logs may be incomplete.)\n", + '{"event": "Log stream stopped - End of log marker not found; logs may be incomplete."}\n', ] assert mock_read.call_count == 11 diff --git a/airflow-core/tests/unit/utils/test_db_manager.py b/airflow-core/tests/unit/utils/test_db_manager.py index e46ac4d4265e1..529dacf58beab 100644 --- a/airflow-core/tests/unit/utils/test_db_manager.py +++ b/airflow-core/tests/unit/utils/test_db_manager.py @@ -34,6 +34,19 @@ class MockDBManager(BaseDBManager): supports_table_dropping = True +class CustomDBManager(BaseDBManager): + metadata = Base.metadata + version_table_name = "custom_alembic_version" + migration_dir = "custom_migration_dir" + alembic_file = "custom_alembic.ini" + + def downgrade(self, to_revision, from_revision=None, show_sql_only=False): + from alembic import command as alembic_command + + config = self.get_alembic_config() + alembic_command.downgrade(config, revision=to_revision, sql=show_sql_only) + + class TestBaseDBManager: @mock.patch.object(BaseDBManager, "get_alembic_config") @mock.patch.object(BaseDBManager, "get_current_revision") @@ -60,3 +73,20 @@ def test_upgrade(self, mock_alembic_cmd, mock_alembic_config, session, caplog): def test_check_migration(self, mock_script_obj, mock_current_revision, session): manager = MockDBManager(session) manager.check_migration() # just ensure this can be called + + def test_custom_db_manager_downgrade_uses_revision_kwarg(self, session): + manager = CustomDBManager(session) + with ( + mock.patch.object(BaseDBManager, "get_alembic_config") as mock_config, + mock.patch("alembic.command.downgrade") as mock_alembic_downgrade, + ): + cfg = object() + mock_config.return_value = cfg + manager.downgrade(to_revision="abc123", show_sql_only=True) + mock_alembic_downgrade.assert_called_once_with(cfg, revision="abc123", sql=True) + + def test_custom_db_manager_downgrade_rejects_to_version_kwarg(self, session): + manager = CustomDBManager(session) + with pytest.raises(TypeError): + # Ensure the old kwarg name is not accepted anymore + manager.downgrade(to_version="1.2.3") # type: ignore[call-arg] diff --git a/airflow-core/tests/unit/utils/test_deprecation_tools.py b/airflow-core/tests/unit/utils/test_deprecation_tools.py index fafcde2364c71..268bc4d3a7be9 100644 --- a/airflow-core/tests/unit/utils/test_deprecation_tools.py +++ b/airflow-core/tests/unit/utils/test_deprecation_tools.py @@ -27,7 +27,11 @@ import pytest -from airflow.utils.deprecation_tools import add_deprecated_classes, getattr_with_deprecation +from airflow.utils.deprecation_tools import ( + DeprecatedImportWarning, + add_deprecated_classes, + getattr_with_deprecation, +) @contextmanager @@ -73,7 +77,7 @@ def test_getattr_with_deprecation_specific_class(self): assert result == mock_new_class assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) + assert issubclass(w[0].category, DeprecatedImportWarning) assert "old.module.OldClass" in str(w[0].message) assert "new.module.NewClass" in str(w[0].message) @@ -99,7 +103,7 @@ def test_getattr_with_deprecation_wildcard(self): assert result == mock_attribute assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) + assert issubclass(w[0].category, DeprecatedImportWarning) assert "old.module.SomeAttribute" in str(w[0].message) assert "new.module.SomeAttribute" in str(w[0].message) @@ -126,7 +130,7 @@ def test_getattr_with_deprecation_wildcard_with_override(self): assert result == mock_attribute assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) + assert issubclass(w[0].category, DeprecatedImportWarning) assert "old.module.SomeAttribute" in str(w[0].message) assert "override.module.OverrideClass" in str(w[0].message) @@ -152,7 +156,7 @@ def test_getattr_with_deprecation_specific_class_priority(self): assert result == mock_specific_class assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) + assert issubclass(w[0].category, DeprecatedImportWarning) assert "old.module.SpecificClass" in str(w[0].message) assert "specific.module.SpecificClass" in str(w[0].message) @@ -383,7 +387,7 @@ def test_current_module_deprecation( assert result == mock_attribute assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) + assert issubclass(w[0].category, DeprecatedImportWarning) assert f"{full_module_name}.{attr_name}" in str(w[0].message) assert expected_target_msg in str(w[0].message) @@ -437,7 +441,7 @@ def mock_import_module(module_name): assert result == mock_current_attr assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) + assert issubclass(w[0].category, DeprecatedImportWarning) assert f"{full_module_name}.current_attr" in str(w[0].message) # Test virtual module access @@ -448,7 +452,7 @@ def mock_import_module(module_name): assert result == mock_virtual_attr assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) + assert issubclass(w[0].category, DeprecatedImportWarning) assert f"{full_virtual_module_name}.VirtualClass" in str(w[0].message) def test_add_deprecated_classes_current_module_not_in_sys_modules(self): diff --git a/airflow-core/tests/unit/utils/test_file.py b/airflow-core/tests/unit/utils/test_file.py index 47c89b2466b24..ca6c7e534b954 100644 --- a/airflow-core/tests/unit/utils/test_file.py +++ b/airflow-core/tests/unit/utils/test_file.py @@ -20,6 +20,7 @@ import os import zipfile from pathlib import Path +from pprint import pformat from unittest import mock import pytest @@ -125,22 +126,32 @@ def test_find_path_from_directory_regex_ignore(self): assert all(os.path.basename(file) not in should_ignore for file in files) def test_find_path_from_directory_glob_ignore(self): - should_ignore = [ + should_ignore = { + "should_ignore_this.py", + "test_explicit_ignore.py", "test_invalid_cron.py", "test_invalid_param.py", "test_ignore_this.py", "test_prev_dagrun_dep.py", "test_nested_dag.py", - "test_dont_ignore.py", ".airflowignore", - ] - should_not_ignore = ["test_on_kill.py", "test_negate_ignore.py", "test_nested_negate_ignore.py"] - files = list(find_path_from_directory(TEST_DAGS_FOLDER, ".airflowignore_glob", "glob")) + } + should_not_ignore = { + "test_on_kill.py", + "test_negate_ignore.py", + "test_dont_ignore_this.py", + "test_nested_negate_ignore.py", + "test_explicit_dont_ignore.py", + } + actual_files = list(find_path_from_directory(TEST_DAGS_FOLDER, ".airflowignore_glob", "glob")) - assert files - assert all(os.path.basename(file) not in should_ignore for file in files) - assert sum(1 for file in files if os.path.basename(file) in should_not_ignore) == len( - should_not_ignore + assert actual_files + assert all(os.path.basename(file) not in should_ignore for file in actual_files) + actual_included_filenames = set( + [os.path.basename(f) for f in actual_files if os.path.basename(f) in should_not_ignore] + ) + assert actual_included_filenames == should_not_ignore, ( + f"actual_included_filenames: {pformat(actual_included_filenames)}\nexpected_included_filenames: {pformat(should_not_ignore)}" ) def test_find_path_from_directory_respects_symlinks_regexp_ignore(self, test_dir): @@ -223,6 +234,8 @@ def test_list_py_file_paths(self, test_zip_path): # No_dags is empty, _invalid_ is ignored by .airflowignore ignored_files = { "no_dags.py", + "should_ignore_this.py", + "test_explicit_ignore.py", "test_invalid_cron.py", "test_invalid_dup_task.py", "test_ignore_this.py", @@ -243,7 +256,9 @@ def test_list_py_file_paths(self, test_zip_path): if file_name not in ignored_files: expected_files.add(f"{root}/{file_name}") detected_files = set(list_py_file_paths(TEST_DAG_FOLDER)) - assert detected_files == expected_files + assert detected_files == expected_files, ( + f"Detected files mismatched expected files:\ndetected_files: {pformat(detected_files)}\nexpected_files: {pformat(expected_files)}" + ) @pytest.mark.parametrize( diff --git a/airflow-core/tests/unit/utils/test_log_handlers.py b/airflow-core/tests/unit/utils/test_log_handlers.py index ba9d09718cd66..6d2caaa8a43a0 100644 --- a/airflow-core/tests/unit/utils/test_log_handlers.py +++ b/airflow-core/tests/unit/utils/test_log_handlers.py @@ -38,6 +38,7 @@ from pydantic.v1.utils import deep_update from requests.adapters import Response +from airflow import settings from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.executors import executor_constants, executor_loader from airflow.jobs.job import Job @@ -78,7 +79,7 @@ ) from tests_common.test_utils.markers import skip_if_force_lowest_dependencies_marker -pytestmark = pytest.mark.db_test +pytestmark = [pytest.mark.db_test] DEFAULT_DATE = pendulum.datetime(2016, 1, 1) TASK_LOGGER = "airflow.task" @@ -92,8 +93,7 @@ def clean_up(self): session.query(TaskInstance).delete() def setup_method(self): - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) - logging.root.disabled = False + settings.configure_logging() self.clean_up() # We use file task handler by default. @@ -156,7 +156,8 @@ def task_callable(ti): # Remove the generated tmp log file. os.remove(log_filename) - def test_file_task_handler_when_ti_is_skipped(self, dag_maker): + @pytest.mark.parametrize("ti_state", [TaskInstanceState.SKIPPED, TaskInstanceState.UPSTREAM_FAILED]) + def test_file_task_handler_when_ti_is_not_run(self, dag_maker, ti_state): def task_callable(ti): ti.log.info("test") @@ -170,10 +171,10 @@ def task_callable(ti): ti = TaskInstance(task=task, run_id=dagrun.run_id, dag_version_id=dag_version.id) ti.try_number = 0 - ti.state = State.SKIPPED + ti.state = ti_state - logger = ti.log - ti.log.disabled = False + logger = logging.getLogger(TASK_LOGGER) + logger.disabled = False file_handler = next( (handler for handler in logger.handlers if handler.name == FILE_TASK_HANDLER), None @@ -295,8 +296,8 @@ def test_file_task_handler_with_multiple_executors( ti.executor = executor_name ti.try_number = 1 ti.state = TaskInstanceState.RUNNING - logger = ti.log - ti.log.disabled = False + logger = logging.getLogger(TASK_LOGGER) + logger.disabled = False file_handler = next( (handler for handler in logger.handlers if handler.name == FILE_TASK_HANDLER), None @@ -344,8 +345,8 @@ def task_callable(ti): ti.try_number = 2 ti.state = State.RUNNING - logger = ti.log - ti.log.disabled = False + logger = logging.getLogger(TASK_LOGGER) + logger.disabled = False file_handler = next( (handler for handler in logger.handlers if handler.name == FILE_TASK_HANDLER), None @@ -396,8 +397,8 @@ def task_callable(ti): ti.try_number = 1 ti.state = State.RUNNING - logger = ti.log - ti.log.disabled = False + logger = logging.getLogger(TASK_LOGGER) + logger.disabled = False file_handler = next( (handler for handler in logger.handlers if handler.name == FILE_TASK_HANDLER), None @@ -413,7 +414,7 @@ def task_callable(ti): assert log_filename.endswith("1.log"), log_filename # mock to generate 2000 lines of log, the total size is larger than max_bytes_size - for i in range(1, 2000): + for i in range(1, 3000): logger.info("this is a Test. %s", i) # this is the rotate log file diff --git a/airflow-core/tests/unit/utils/test_logging_mixin.py b/airflow-core/tests/unit/utils/test_logging_mixin.py index 14e3532074b41..4ad65db7fb1eb 100644 --- a/airflow-core/tests/unit/utils/test_logging_mixin.py +++ b/airflow-core/tests/unit/utils/test_logging_mixin.py @@ -93,18 +93,6 @@ class DummyClass(LoggingMixin): assert DummyClass().log.name == "unit.utils.test_logging_mixin.DummyClass" - def test_logger_name_is_root_when_logger_name_is_empty_string(self): - """ - Ensure that when `_logger_name` is set as an empty string, the resulting logger name is an empty - string too, which result in a logger with 'root' as name. - Note: Passing an empty string to `logging.getLogger` will create a logger with name 'root'. - """ - - class EmptyStringLogger(LoggingMixin): - _logger_name: str | None = "" - - assert EmptyStringLogger().log.name == "root" - def test_log_config_logger_name_correctly_prefix_logger_name(self): """ Ensure that when a class has `_log_config_logger_name`, it is used as prefix in the final logger diff --git a/airflow-core/tests/unit/utils/test_process_utils.py b/airflow-core/tests/unit/utils/test_process_utils.py index 7edc5f28b73b2..47ffc9245f3e8 100644 --- a/airflow-core/tests/unit/utils/test_process_utils.py +++ b/airflow-core/tests/unit/utils/test_process_utils.py @@ -103,19 +103,22 @@ def test_reap_process_group(self): class TestExecuteInSubProcess: def test_should_print_all_messages1(self, caplog): execute_in_subprocess(["bash", "-c", "echo CAT; echo KITTY;"]) - msgs = [record.getMessage() for record in caplog.records] - assert msgs == ["Executing cmd: bash -c 'echo CAT; echo KITTY;'", "Output:", "CAT", "KITTY"] + assert caplog.messages == [ + "Executing cmd: bash -c 'echo CAT; echo KITTY;'", + "Output:", + "CAT", + "KITTY", + ] def test_should_print_all_messages_from_cwd(self, caplog, tmp_path): execute_in_subprocess(["bash", "-c", "echo CAT; pwd; echo KITTY;"], cwd=str(tmp_path)) - msgs = [record.getMessage() for record in caplog.records] assert [ "Executing cmd: bash -c 'echo CAT; pwd; echo KITTY;'", "Output:", "CAT", str(tmp_path), "KITTY", - ] == msgs + ] == caplog.messages def test_using_env_works(self, caplog): execute_in_subprocess(["bash", "-c", 'echo "My value is ${VALUE}"'], env=dict(VALUE="1")) diff --git a/airflow-core/tests/unit/utils/test_retries.py b/airflow-core/tests/unit/utils/test_retries.py index 4c923560e0031..1f44ee9ebf8be 100644 --- a/airflow-core/tests/unit/utils/test_retries.py +++ b/airflow-core/tests/unit/utils/test_retries.py @@ -64,7 +64,7 @@ def test_function(session): mock_obj(2) raise db_error - caplog.set_level(logging.DEBUG, logger=self.__module__) + caplog.set_level(logging.DEBUG) caplog.clear() with pytest.raises(excection_type): test_function(session=mock_session) diff --git a/airflow-core/tests/unit/utils/test_task_group.py b/airflow-core/tests/unit/utils/test_task_group.py index 52524ecda2fd8..67ba538b6cbc8 100644 --- a/airflow-core/tests/unit/utils/test_task_group.py +++ b/airflow-core/tests/unit/utils/test_task_group.py @@ -158,7 +158,6 @@ EXPECTED_JSON = { "children": [ {"id": "task1", "label": "task1", "operator": "EmptyOperator", "type": "task"}, - {"id": "task5", "label": "task5", "operator": "EmptyOperator", "type": "task"}, { "children": [ { @@ -197,6 +196,7 @@ "tooltip": "", "type": "task", }, + {"id": "task5", "label": "task5", "operator": "EmptyOperator", "type": "task"}, ], "id": None, "is_mapped": False, @@ -277,7 +277,6 @@ def test_task_group_to_dict_with_prefix(dag_maker): expected_node_id = { "children": [ {"id": "task1", "label": "task1"}, - {"id": "task5", "label": "task5"}, { "id": "group234", "label": "group234", @@ -299,6 +298,7 @@ def test_task_group_to_dict_with_prefix(dag_maker): {"id": "group234.upstream_join_id", "label": ""}, ], }, + {"id": "task5", "label": "task5"}, ], "id": None, "label": "", @@ -347,7 +347,6 @@ def task_5(): "id": None, "children": [ {"id": "task_1"}, - {"id": "task_5"}, { "id": "group234", "children": [ @@ -358,6 +357,7 @@ def task_5(): {"id": "group234.downstream_join_id"}, ], }, + {"id": "task_5"}, ], } @@ -403,7 +403,6 @@ def test_task_group_to_dict_sub_dag(dag_maker): "id": None, "children": [ {"id": "task1"}, - {"id": "task5"}, { "id": "group234", "children": [ @@ -418,6 +417,7 @@ def test_task_group_to_dict_sub_dag(dag_maker): {"id": "group234.upstream_join_id"}, ], }, + {"id": "task5"}, ], } @@ -478,16 +478,6 @@ def test_task_group_to_dict_and_dag_edges(dag_maker): expected_node_id = { "id": None, "children": [ - { - "id": "group_c", - "children": [ - {"id": "group_c.task6"}, - {"id": "group_c.task7"}, - {"id": "group_c.task8"}, - {"id": "group_c.upstream_join_id"}, - {"id": "group_c.downstream_join_id"}, - ], - }, { "id": "group_d", "children": [ @@ -497,8 +487,6 @@ def test_task_group_to_dict_and_dag_edges(dag_maker): ], }, {"id": "task1"}, - {"id": "task10"}, - {"id": "task9"}, { "id": "group_a", "children": [ @@ -516,6 +504,18 @@ def test_task_group_to_dict_and_dag_edges(dag_maker): {"id": "group_a.downstream_join_id"}, ], }, + { + "id": "group_c", + "children": [ + {"id": "group_c.task6"}, + {"id": "group_c.task7"}, + {"id": "group_c.task8"}, + {"id": "group_c.upstream_join_id"}, + {"id": "group_c.downstream_join_id"}, + ], + }, + {"id": "task10"}, + {"id": "task9"}, ], } @@ -784,7 +784,6 @@ def section_2(value): node_ids = { "id": None, "children": [ - {"id": "task_end"}, {"id": "task_start"}, { "id": "section_1", @@ -804,6 +803,7 @@ def section_2(value): {"id": "section_1.downstream_join_id"}, ], }, + {"id": "task_end"}, ], } diff --git a/airflow-core/tests/unit/utils/test_task_handler_with_custom_formatter.py b/airflow-core/tests/unit/utils/test_task_handler_with_custom_formatter.py deleted file mode 100644 index 856116b15e6f7..0000000000000 --- a/airflow-core/tests/unit/utils/test_task_handler_with_custom_formatter.py +++ /dev/null @@ -1,113 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -from __future__ import annotations - -import logging - -import pytest - -from airflow._shared.timezones.timezone import datetime -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG -from airflow.models.dag_version import DagVersion -from airflow.models.taskinstance import TaskInstance -from airflow.providers.standard.operators.empty import EmptyOperator -from airflow.utils.log.logging_mixin import set_context -from airflow.utils.state import DagRunState -from airflow.utils.types import DagRunTriggeredByType, DagRunType - -from tests_common.test_utils.config import conf_vars -from tests_common.test_utils.db import clear_db_runs - -pytestmark = pytest.mark.db_test - - -DEFAULT_DATE = datetime(2019, 1, 1) -TASK_HANDLER = "task" -TASK_HANDLER_CLASS = "airflow.utils.log.task_handler_with_custom_formatter.TaskHandlerWithCustomFormatter" -PREV_TASK_HANDLER = DEFAULT_LOGGING_CONFIG["handlers"]["task"] - -DAG_ID = "task_handler_with_custom_formatter_dag" -TASK_ID = "task_handler_with_custom_formatter_task" - - -@pytest.fixture(scope="module", autouse=True) -def custom_task_log_handler_config(): - DEFAULT_LOGGING_CONFIG["handlers"]["task"] = { - "class": TASK_HANDLER_CLASS, - "formatter": "airflow", - "stream": "sys.stdout", - } - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) - logging.root.disabled = False - yield - DEFAULT_LOGGING_CONFIG["handlers"]["task"] = PREV_TASK_HANDLER - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) - - -@pytest.fixture -def task_instance(dag_maker): - with dag_maker(DAG_ID, start_date=DEFAULT_DATE, serialized=True) as dag: - task = EmptyOperator(task_id=TASK_ID) - triggered_by_kwargs = {"triggered_by": DagRunTriggeredByType.TEST} - dagrun = dag_maker.create_dagrun( - state=DagRunState.RUNNING, - logical_date=DEFAULT_DATE, - run_type=DagRunType.MANUAL, - data_interval=dag.timetable.infer_manual_data_interval(run_after=DEFAULT_DATE), - **triggered_by_kwargs, - ) - dag_version = DagVersion.get_latest_version(dag.dag_id) - ti = TaskInstance(task=task, run_id=dagrun.run_id, dag_version_id=dag_version.id) - ti.log.disabled = False - yield ti - clear_db_runs() - - -def assert_prefix_once(task_instance: TaskInstance, prefix: str) -> None: - handler = next((h for h in task_instance.log.handlers if h.name == TASK_HANDLER), None) - assert handler is not None, "custom task log handler not set up correctly" - assert handler.formatter is not None, "custom task log formatter not set up correctly" - previous_formatter = handler.formatter - expected_format = f"{prefix}:{handler.formatter._fmt}" - set_context(task_instance.log, task_instance) - assert expected_format == handler.formatter._fmt - handler.setFormatter(previous_formatter) - - -def assert_prefix_multiple(task_instance: TaskInstance, prefix: str) -> None: - handler = next((h for h in task_instance.log.handlers if h.name == TASK_HANDLER), None) - assert handler is not None, "custom task log handler not set up correctly" - assert handler.formatter is not None, "custom task log formatter not set up correctly" - previous_formatter = handler.formatter - expected_format = f"{prefix}:{handler.formatter._fmt}" - set_context(task_instance.log, task_instance) - set_context(task_instance.log, task_instance) - set_context(task_instance.log, task_instance) - assert expected_format == handler.formatter._fmt - handler.setFormatter(previous_formatter) - - -def test_custom_formatter_default_format(task_instance): - """The default format provides no prefix.""" - assert_prefix_once(task_instance, "") - - -@conf_vars({("logging", "task_log_prefix_template"): "{{ ti.dag_id }}-{{ ti.task_id }}"}) -def test_custom_formatter_custom_format_not_affected_by_config(task_instance): - """Certifies that the prefix is only added once, even after repeated calls""" - assert_prefix_multiple(task_instance, f"{DAG_ID}-{TASK_ID}") diff --git a/airflow-ctl/pyproject.toml b/airflow-ctl/pyproject.toml index 611ca1cf09bfb..c67967aeb096a 100644 --- a/airflow-ctl/pyproject.toml +++ b/airflow-ctl/pyproject.toml @@ -33,7 +33,7 @@ dependencies = [ "lazy-object-proxy>=1.2.0", "methodtools>=0.4.7", "platformdirs>=4.3.6", - "pydantic>=2.11.0", + "pydantic>=2.11.0", # https://github.com/apache/airflow/issues/56482 "rich-argparse>=1.0.0", "structlog>=25.2.0", "uuid6>=2024.7.10", @@ -121,7 +121,7 @@ dev = [ "apache-airflow-devel-common", ] codegen = [ - "datamodel-code-generator[http]==0.32.0", + "datamodel-code-generator[http]==0.33.0", "apache-airflow-devel-common" ] diff --git a/airflow-ctl/src/airflowctl/api/datamodels/auth_generated.py b/airflow-ctl/src/airflowctl/api/datamodels/auth_generated.py index 5eb02b4253353..0a100364599cd 100644 --- a/airflow-ctl/src/airflowctl/api/datamodels/auth_generated.py +++ b/airflow-ctl/src/airflowctl/api/datamodels/auth_generated.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: v2-simple-auth-manager-generated.yaml -# version: 0.32.0 +# version: 0.33.0 from __future__ import annotations diff --git a/airflow-ctl/src/airflowctl/api/datamodels/generated.py b/airflow-ctl/src/airflowctl/api/datamodels/generated.py index 37ecd597a5c88..3a624c0633a90 100644 --- a/airflow-ctl/src/airflowctl/api/datamodels/generated.py +++ b/airflow-ctl/src/airflowctl/api/datamodels/generated.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: v2-rest-api-generated.yaml -# version: 0.32.0 +# version: 0.33.0 from __future__ import annotations @@ -143,7 +143,13 @@ class ClearTaskInstancesBody(BaseModel): only_failed: Annotated[bool | None, Field(title="Only Failed")] = True only_running: Annotated[bool | None, Field(title="Only Running")] = False reset_dag_runs: Annotated[bool | None, Field(title="Reset Dag Runs")] = True - task_ids: Annotated[list[str | TaskIds] | None, Field(title="Task Ids")] = None + task_ids: Annotated[ + list[str | TaskIds] | None, + Field( + description="A list of `task_id` or [`task_id`, `map_index`]. If only the `task_id` is provided for a mapped task, all of its map indices will be targeted.", + title="Task Ids", + ), + ] = None dag_run_id: Annotated[str | None, Field(title="Dag Run Id")] = None include_upstream: Annotated[bool | None, Field(title="Include Upstream")] = False include_downstream: Annotated[bool | None, Field(title="Include Downstream")] = False @@ -525,16 +531,13 @@ class FastAPIRootMiddlewareResponse(BaseModel): name: Annotated[str, Field(title="Name")] -class HITLDetailResponse(BaseModel): +class HITLUser(BaseModel): """ - Response of updating a Human-in-the-loop detail. + Schema for a Human-in-the-loop users. """ - responded_user_id: Annotated[str, Field(title="Responded User Id")] - responded_user_name: Annotated[str, Field(title="Responded User Name")] - response_at: Annotated[datetime, Field(title="Response At")] - chosen_options: Annotated[list[str], Field(min_length=1, title="Chosen Options")] - params_input: Annotated[dict[str, Any] | None, Field(title="Params Input")] = None + id: Annotated[str, Field(title="Id")] + name: Annotated[str, Field(title="Name")] class HTTPExceptionResponse(BaseModel): @@ -1434,6 +1437,17 @@ class EventLogCollectionResponse(BaseModel): total_entries: Annotated[int, Field(title="Total Entries")] +class HITLDetailResponse(BaseModel): + """ + Response of updating a Human-in-the-loop detail. + """ + + responded_by: HITLUser + responded_at: Annotated[datetime, Field(title="Responded At")] + chosen_options: Annotated[list[str], Field(min_length=1, title="Chosen Options")] + params_input: Annotated[dict[str, Any] | None, Field(title="Params Input")] = None + + class HTTPValidationError(BaseModel): detail: Annotated[list[ValidationError] | None, Field(title="Detail")] = None @@ -1828,10 +1842,10 @@ class HITLDetail(BaseModel): defaults: Annotated[list[str] | None, Field(title="Defaults")] = None multiple: Annotated[bool | None, Field(title="Multiple")] = False params: Annotated[dict[str, Any] | None, Field(title="Params")] = None - respondents: Annotated[list[str] | None, Field(title="Respondents")] = None - responded_user_id: Annotated[str | None, Field(title="Responded User Id")] = None - responded_user_name: Annotated[str | None, Field(title="Responded User Name")] = None - response_at: Annotated[datetime | None, Field(title="Response At")] = None + assigned_users: Annotated[list[HITLUser] | None, Field(title="Assigned Users")] = None + created_at: Annotated[datetime, Field(title="Created At")] + responded_by_user: HITLUser | None = None + responded_at: Annotated[datetime | None, Field(title="Responded At")] = None chosen_options: Annotated[list[str] | None, Field(title="Chosen Options")] = None params_input: Annotated[dict[str, Any] | None, Field(title="Params Input")] = None response_received: Annotated[bool | None, Field(title="Response Received")] = False diff --git a/chart/docs/conf.py b/chart/docs/conf.py index 59e448d936c7e..c0d022eab980a 100644 --- a/chart/docs/conf.py +++ b/chart/docs/conf.py @@ -38,9 +38,6 @@ from typing import Any import yaml -from packaging.version import parse as parse_version - -import airflow from docs.utils.conf_constants import ( AIRFLOW_FAVICON_PATH, AIRFLOW_REPO_ROOT_PATH, @@ -59,6 +56,9 @@ get_intersphinx_mapping, get_rst_epilogue, ) +from packaging.version import parse as parse_version + +import airflow PACKAGE_NAME = "helm-chart" CHART_ROOT_PATH = AIRFLOW_REPO_ROOT_PATH / "chart" diff --git a/chart/values.yaml b/chart/values.yaml index 9b1d713d58cdc..bdca77834f299 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -2851,9 +2851,13 @@ cleanup: successfulJobsHistoryLimit: ~ # Configuration for postgresql subchart -# Not recommended for production +# Uses bitnamilegacy images to avoid Bitnami licensing restrictions +# Not recommended for production - use external database instead postgresql: enabled: true + image: + repository: postgres + tag: "13" auth: enablePostgresUser: true postgresPassword: postgres diff --git a/clients/python/README.md b/clients/python/README.md index f071d077354a2..e164f4b5ca88c 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -394,6 +394,7 @@ Class | Method | HTTP request | Description *DagRunApi* | [**get_dag_runs**](docs/DagRunApi.md#get_dag_runs) | **GET** /api/v2/dags/{dag_id}/dagRuns | Get Dag Runs *DagRunApi* | [**get_list_dag_runs_batch**](docs/DagRunApi.md#get_list_dag_runs_batch) | **POST** /api/v2/dags/{dag_id}/dagRuns/list | Get List Dag Runs Batch *DagRunApi* | [**get_upstream_asset_events**](docs/DagRunApi.md#get_upstream_asset_events) | **GET** /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/upstreamAssetEvents | Get Upstream Asset Events +*DagRunApi* | [**wait_dag_run_until_finished**](docs/DagRunApi.md#wait_dag_run_until_finished) | **GET** /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/wait | Experimental: Wait for a dag run to complete, and return task results if requested. *DagRunApi* | [**patch_dag_run**](docs/DagRunApi.md#patch_dag_run) | **PATCH** /api/v2/dags/{dag_id}/dagRuns/{dag_run_id} | Patch Dag Run *DagRunApi* | [**trigger_dag_run**](docs/DagRunApi.md#trigger_dag_run) | **POST** /api/v2/dags/{dag_id}/dagRuns | Trigger Dag Run *DagSourceApi* | [**get_dag_source**](docs/DagSourceApi.md#get_dag_source) | **GET** /api/v2/dagSources/{dag_id} | Get Dag Source diff --git a/contributing-docs/08_static_code_checks.rst b/contributing-docs/08_static_code_checks.rst index 5e910a31a6bfe..3760a864a8d68 100644 --- a/contributing-docs/08_static_code_checks.rst +++ b/contributing-docs/08_static_code_checks.rst @@ -22,7 +22,7 @@ The static code checks in Airflow are used to verify that the code meets certain All the static code checks can be run through prek hooks. The prek hooks perform all the necessary installation when you run them -for the first time. See the table below to identify which prek checks require the Breeze Docker images. +for the first time. You can also run the checks via `Breeze <../dev/breeze/doc/README.rst>`_ environment. @@ -116,7 +116,7 @@ To install the checks also for ``pre-push`` operations, enter: .. code-block:: bash - prek install -t pre-push + prek install --hook-type pre-push For details on advanced usage of the install method, use: @@ -157,7 +157,12 @@ Using prek ---------- After installation, prek hooks are run automatically when you commit the -code. But you can run prek hooks manually as needed. +code or push it to the repository (depending on stages configured for the hooks). Some of the +hooks are configured to run on "manual" stage only and are not run automatically. + +By default when you run ``prek``, the ``pre-commit`` stage hooks are run. + +But you can run prek hooks manually as needed. - Run all checks on your staged files by using: @@ -170,33 +175,36 @@ code. But you can run prek hooks manually as needed. .. code-block:: bash - prek mypy-airflow-core mypy-dev + prek mypy-airflow-core mypy-dev --hook-stage pre-push - Run only mypy airflow checks on all "airflow-core" files by using: .. code-block:: bash - prek mypy-airflow-core --all-files + prek mypy-airflow-core --all-files --hook-stage pre-push -- Run all checks on all files by using: +- Run all pre-commit stage hooks on all files by using: .. code-block:: bash prek --all-files -- Run all checks only on files modified in the last locally available commit in your checked out branch: +- Run all pre-commit stage hooks only on files modified in the last locally available + commit in your checked out branch: .. code-block:: bash prek --last-commit -- Run all checks only on files modified in your last branch that is targeted to be merged into the main branch: +- Run all pre-commit stage hooks only on files modified in your last branch that is targeted + to be merged into the main branch: .. code-block:: bash prek --from-ref main -- Show files modified automatically by prek when prek automatically fix errors +- Show files modified automatically by prek when prek automatically fixes errors (after running all + ``pre-commit`` stage hooks on locally modified files): .. code-block:: bash @@ -207,7 +215,7 @@ code. But you can run prek hooks manually as needed. .. code-block:: bash - SKIP=mypy-airflow-core,ruff prek --all-files + SKIP=ruff,rst-backticks prek --all-files You can always skip running the tests by providing ``--no-verify`` flag to the @@ -262,9 +270,8 @@ enter the terminal. Manual prek hooks ----------------- -Most of the checks we run are configured to run automatically when you commit the code. However, -there are some checks that are not run automatically and you need to run them manually. Those -checks are marked with ``manual`` in the ``Description`` column in the table below. You can run +Most of the checks we run are configured to run automatically when you commit the code or push PR. However, +there are some checks that are not run automatically and you need to run them manually. You can run them manually by running ``prek --hook-stage manual ``. Special pin-versions prek @@ -275,24 +282,26 @@ GitHub Actions in the CI workflows. This action requires ``GITHUB_TOKEN`` to be set, otherwise you might hit the rate limits with GitHub API, it is also configured in a separate ``.prek-config.yaml`` file in the -``.github`` directory as it requires Python 3.11 to run. It is not run automatically +``dev`` directory as it requires Python 3.11 to run. It is not run automatically when you commit the code but in runs as a separate job in the CI. However, you can run it manually by running: .. code-block:: bash export GITHUB_TOKEN=YOUR_GITHUB_TOKEN - prek -c .github/.pre-commit-config.yaml --all-files --hook-stage manual --verbose + prek -c dev/.pre-commit-config.yaml --all-files --hook-stage manual --verbose Mypy checks ----------- -When we run mypy checks locally when committing a change, one of the ``mypy-*`` checks is run, ``mypy-airflow``, +When we run mypy checks locally when pushing a change to PR, the ``mypy-*`` checks is run, ``mypy-airflow``, ``mypy-dev``, ``mypy-providers``, ``mypy-airflow-ctl``, depending on the files you are changing. The mypy checks are run by passing those changed files to mypy. This is way faster than running checks for all files (even if mypy cache is used - especially when you change a file in Airflow core that is imported and used by many -files). However, in some cases, it produces different results than when running checks for the whole set +files). You also need to have ``breeze ci-image build --python 3.10`` built locally to run the mypy checks. + +However, in some cases, it produces different results than when running checks for the whole set of files, because ``mypy`` does not even know that some types are defined in other files and it might not be able to follow imports properly if they are dynamic. Therefore in CI we run ``mypy`` check for whole directories (``airflow`` - excluding providers, ``providers``, ``dev`` and ``docs``) to make sure diff --git a/.github/.pre-commit-config.yaml b/dev/.pre-commit-config.yaml similarity index 100% rename from .github/.pre-commit-config.yaml rename to dev/.pre-commit-config.yaml diff --git a/dev/breeze/README.md b/dev/breeze/README.md index fd255fd89f14c..9951c90b60590 100644 --- a/dev/breeze/README.md +++ b/dev/breeze/README.md @@ -129,12 +129,3 @@ uv lock Note that when you update dependencies/lock them you should commit the changes in `pyproject.toml` and `uv.lock`. See [uv documentation](https://docs.astral.sh/uv/getting-started/) for more details on using `uv`. - - -PLEASE DO NOT MODIFY THE HASH BELOW! IT IS AUTOMATICALLY UPDATED BY PREK. - ---------------------------------------------------------------------------------------------------------- - -Package config hash: 85824868b3ba0b7a43509b65f87150d872d2e2f50fea09872d37c9d1e0207ae3084072fb126ba5ebc314c83d86fa17e026630ee3253ddd44a0e139d3f9f1e281 - ---------------------------------------------------------------------------------------------------------- diff --git a/dev/breeze/doc/ci/02_images.md b/dev/breeze/doc/ci/02_images.md index 302caf883b876..4a5ce78466e0d 100644 --- a/dev/breeze/doc/ci/02_images.md +++ b/dev/breeze/doc/ci/02_images.md @@ -443,8 +443,8 @@ can be used for CI images: | `ADDITIONAL_DEV_APT_DEPS` | | Additional apt dev dependencies installed in the first part of the image | | `ADDITIONAL_DEV_APT_ENV` | | Additional env variables defined when installing dev deps | | `AIRFLOW_PIP_VERSION` | `25.2` | `pip` version used. | -| `AIRFLOW_UV_VERSION` | `0.8.15` | `uv` version used. | -| `AIRFLOW_PREK_VERSION` | `0.1.6` | `prek` version used. | +| `AIRFLOW_UV_VERSION` | `0.9.4` | `uv` version used. | +| `AIRFLOW_PREK_VERSION` | `0.2.10` | `prek` version used. | | `AIRFLOW_USE_UV` | `true` | Whether to use UV for installation. | | `PIP_PROGRESS_BAR` | `on` | Progress bar for PIP installation | diff --git a/dev/breeze/doc/images/output_ci-image_build.txt b/dev/breeze/doc/images/output_ci-image_build.txt index fa6a3ac990ebb..33c6066d29562 100644 --- a/dev/breeze/doc/images/output_ci-image_build.txt +++ b/dev/breeze/doc/images/output_ci-image_build.txt @@ -1 +1 @@ -7dee09c877f9b36af3952837456dfff7 +65a5d79676dc76a7488e713d2c4d5337 diff --git a/dev/breeze/doc/images/output_ci_selective-check.svg b/dev/breeze/doc/images/output_ci_selective-check.svg index 4a425297bf18b..fb323e3959888 100644 --- a/dev/breeze/doc/images/output_ci_selective-check.svg +++ b/dev/breeze/doc/images/output_ci_selective-check.svg @@ -140,9 +140,9 @@ ╭─ Selective check flags ──────────────────────────────────────────────────────────────────────────────────────────────╮ --commit-refCommit-ish reference to the commit that should be checked(TEXT) --pr-labelsPython array formatted PR labels assigned to the PR(TEXT) ---default-branchBranch against which the PR should be run(TEXT)[default: main] +--default-branchBranch against which the PR should be run(TEXT)[default: v3-1-test] --default-constraints-branchConstraints Branch against which the PR should be run(TEXT) -[default: constraints-main]                           +[default: constraints-3-1]                            ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ GitHub parameters ──────────────────────────────────────────────────────────────────────────────────────────────────╮ --github-event-nameName of the GitHub event that triggered the check                                           diff --git a/dev/breeze/doc/images/output_ci_selective-check.txt b/dev/breeze/doc/images/output_ci_selective-check.txt index 37fc2e54d5cfe..4cf45dcb9884f 100644 --- a/dev/breeze/doc/images/output_ci_selective-check.txt +++ b/dev/breeze/doc/images/output_ci_selective-check.txt @@ -1 +1 @@ -c6cb6c6a2c70bd5b6a57a82c983af823 +3d881bc1e14fbdf68b1cdfef9f62f91b diff --git a/dev/breeze/doc/images/output_prod-image_build.txt b/dev/breeze/doc/images/output_prod-image_build.txt index 2fd3840285bf4..679c700812088 100644 --- a/dev/breeze/doc/images/output_prod-image_build.txt +++ b/dev/breeze/doc/images/output_prod-image_build.txt @@ -1 +1 @@ -0a491d82c3fa865682261b5cc0c2be56 +31614af6f841392d4b6b14a2a31ad502 diff --git a/dev/breeze/doc/images/output_release-management_add-back-references.svg b/dev/breeze/doc/images/output_release-management_add-back-references.svg index 75b58045516ea..14890da1a0573 100644 --- a/dev/breeze/doc/images/output_release-management_add-back-references.svg +++ b/dev/breeze/doc/images/output_release-management_add-back-references.svg @@ -165,7 +165,7 @@ --include-not-ready-providersWhether to include providers that are not yet ready to be released. --include-removed-providersWhether to include providers that are removed. --head-repoThe repository of redirect files to use.(TEXT)[default: apache/airflow] ---head-refThe branch of redirect files to use.(TEXT)[default: main] +--head-refThe branch of redirect files to use.(TEXT)[default: v3-1-test] ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ --dry-run-DIf dry-run is set, commands are only printed, not executed. diff --git a/dev/breeze/doc/images/output_release-management_add-back-references.txt b/dev/breeze/doc/images/output_release-management_add-back-references.txt index c6ccb5bf552f9..58ef2baf6b432 100644 --- a/dev/breeze/doc/images/output_release-management_add-back-references.txt +++ b/dev/breeze/doc/images/output_release-management_add-back-references.txt @@ -1 +1 @@ -bd8777a62f456af2ad5f29bf51b4f57f +b0b2962b63bd4a42efcd60b06f80e02e diff --git a/dev/breeze/doc/images/output_release-management_install-provider-distributions.svg b/dev/breeze/doc/images/output_release-management_install-provider-distributions.svg index 6c728099b2204..6055d2f2bf481 100644 --- a/dev/breeze/doc/images/output_release-management_install-provider-distributions.svg +++ b/dev/breeze/doc/images/output_release-management_install-provider-distributions.svg @@ -296,9 +296,9 @@ - + - + Usage:breeze release-management install-provider-distributions[OPTIONS] diff --git a/dev/breeze/doc/images/output_release-management_install-provider-distributions.txt b/dev/breeze/doc/images/output_release-management_install-provider-distributions.txt index 8b9730d8ecfcb..bf517fd018dc5 100644 --- a/dev/breeze/doc/images/output_release-management_install-provider-distributions.txt +++ b/dev/breeze/doc/images/output_release-management_install-provider-distributions.txt @@ -1 +1 @@ -1793315cc72534c04a469367c7890117 +93483a78f7d962f62c879522122c52bc diff --git a/dev/breeze/doc/images/output_release-management_verify-provider-distributions.svg b/dev/breeze/doc/images/output_release-management_verify-provider-distributions.svg index 93d72dfd4b2e9..2ae4f9d84cf11 100644 --- a/dev/breeze/doc/images/output_release-management_verify-provider-distributions.svg +++ b/dev/breeze/doc/images/output_release-management_verify-provider-distributions.svg @@ -269,9 +269,9 @@ - + - + Usage:breeze release-management verify-provider-distributions[OPTIONS] diff --git a/dev/breeze/doc/images/output_release-management_verify-provider-distributions.txt b/dev/breeze/doc/images/output_release-management_verify-provider-distributions.txt index 375c19ef19cb9..0ed91f068b6d3 100644 --- a/dev/breeze/doc/images/output_release-management_verify-provider-distributions.txt +++ b/dev/breeze/doc/images/output_release-management_verify-provider-distributions.txt @@ -1 +1 @@ -4466091260d2f0928d5bb0ad00ddfac0 +d8715b5c4f41d15a05b55be5113dffe7 diff --git a/dev/breeze/doc/images/output_shell.svg b/dev/breeze/doc/images/output_shell.svg index 467bb459ab4e5..6dbf70093a2bf 100644 --- a/dev/breeze/doc/images/output_shell.svg +++ b/dev/breeze/doc/images/output_shell.svg @@ -587,9 +587,9 @@ - + - + Usage:breeze shell[OPTIONS] [EXTRA_ARGS]... diff --git a/dev/breeze/doc/images/output_shell.txt b/dev/breeze/doc/images/output_shell.txt index a52f06728d2f5..a2bca2d863a95 100644 --- a/dev/breeze/doc/images/output_shell.txt +++ b/dev/breeze/doc/images/output_shell.txt @@ -1 +1 @@ -5bdfe1d4afe64fb8bd3e07d5c6e9c2d5 +c23fcef0bfb6f2bbb46937d673e4cddb diff --git a/dev/breeze/doc/images/output_start-airflow.svg b/dev/breeze/doc/images/output_start-airflow.svg index 78a56974ffdcb..e4f8058584b2b 100644 --- a/dev/breeze/doc/images/output_start-airflow.svg +++ b/dev/breeze/doc/images/output_start-airflow.svg @@ -497,9 +497,9 @@ - + - + Usage:breeze start-airflow[OPTIONS] [EXTRA_ARGS]... diff --git a/dev/breeze/doc/images/output_start-airflow.txt b/dev/breeze/doc/images/output_start-airflow.txt index fe487fdf0937a..70645b7317e13 100644 --- a/dev/breeze/doc/images/output_start-airflow.txt +++ b/dev/breeze/doc/images/output_start-airflow.txt @@ -1 +1 @@ -da22448455ba68de7ee5d2b1bd206265 +b2b6b3d14961062524f862a86299ccce diff --git a/dev/breeze/doc/images/output_testing_core-tests.svg b/dev/breeze/doc/images/output_testing_core-tests.svg index 8f6b981afe0af..1de8ae1a5d1f2 100644 --- a/dev/breeze/doc/images/output_testing_core-tests.svg +++ b/dev/breeze/doc/images/output_testing_core-tests.svg @@ -386,9 +386,9 @@ - + - + Usage:breeze testing core-tests[OPTIONS] [EXTRA_PYTEST_ARGS]... diff --git a/dev/breeze/doc/images/output_testing_core-tests.txt b/dev/breeze/doc/images/output_testing_core-tests.txt index 673554276e40d..c0196db9e544f 100644 --- a/dev/breeze/doc/images/output_testing_core-tests.txt +++ b/dev/breeze/doc/images/output_testing_core-tests.txt @@ -1 +1 @@ -15ea9d56c6b8cb558221d60eaeac7797 +9e24844ad422493dfe1fb0bad4853205 diff --git a/dev/breeze/doc/images/output_testing_providers-tests.svg b/dev/breeze/doc/images/output_testing_providers-tests.svg index 75c12a68af25b..dad18ac7874c7 100644 --- a/dev/breeze/doc/images/output_testing_providers-tests.svg +++ b/dev/breeze/doc/images/output_testing_providers-tests.svg @@ -416,9 +416,9 @@ - + - + Usage:breeze testing providers-tests[OPTIONS] [EXTRA_PYTEST_ARGS]... diff --git a/dev/breeze/doc/images/output_testing_providers-tests.txt b/dev/breeze/doc/images/output_testing_providers-tests.txt index 06edab1cd6689..3158324c2e7be 100644 --- a/dev/breeze/doc/images/output_testing_providers-tests.txt +++ b/dev/breeze/doc/images/output_testing_providers-tests.txt @@ -1 +1 @@ -ce8bc35c0d74786e2c3635ecab6baa7c +f4b1019647ed481a57a8f49a60546c09 diff --git a/dev/breeze/doc/images/output_testing_system-tests.svg b/dev/breeze/doc/images/output_testing_system-tests.svg index e30f9fd7204db..a20c867331b1c 100644 --- a/dev/breeze/doc/images/output_testing_system-tests.svg +++ b/dev/breeze/doc/images/output_testing_system-tests.svg @@ -275,9 +275,9 @@ - + - + Usage:breeze testing system-tests[OPTIONS] [EXTRA_PYTEST_ARGS]... diff --git a/dev/breeze/doc/images/output_testing_system-tests.txt b/dev/breeze/doc/images/output_testing_system-tests.txt index 4de1a645b72d3..1d2d64d1cf617 100644 --- a/dev/breeze/doc/images/output_testing_system-tests.txt +++ b/dev/breeze/doc/images/output_testing_system-tests.txt @@ -1 +1 @@ -ad627c4fe1628142731a41c346b003f0 +dbc5bfc8af3efdd5ecf85c20018aede4 diff --git a/dev/breeze/pyproject.toml b/dev/breeze/pyproject.toml index abf0159ec859c..e0f9c7fa7decc 100644 --- a/dev/breeze/pyproject.toml +++ b/dev/breeze/pyproject.toml @@ -55,12 +55,12 @@ dependencies = [ "google-auth-httplib2>=0.2.0", "google-auth-oauthlib>=1.2.0", "gitpython>=3.1.40", - "hatch>=1.14.1", + "hatch>=1.15.1", "inputimeout>=1.0.4", "jinja2>=3.1.5", "jsonschema>=4.19.1", "packaging>=25.0", - "prek>=0.1.6", + "prek>=0.2.10", "psutil>=5.9.6", "pygithub>=2.1.1", "pytest-xdist>=3.3.1", @@ -68,7 +68,9 @@ dependencies = [ "pyyaml>=6.0.2", "requests>=2.32.0", "restructuredtext-lint>=1.4.0", - "rich-click>=1.7.1", + # Temporarily pinned to fix for changes in https://github.com/ewels/rich-click/releases/tag/v1.9.0 + # Example failure without it: https://github.com/apache/airflow/actions/runs/17770084165/job/50505281673?pr=55725 + "rich-click>=1.7.1,<1.9.0", "rich>=13.6.0", "tabulate>=0.9.0", "tomli>=2.0.1; python_version < '3.11'", diff --git a/dev/breeze/src/airflow_breeze/branch_defaults.py b/dev/breeze/src/airflow_breeze/branch_defaults.py index e8639d348cd8f..49dc1a24b76f2 100644 --- a/dev/breeze/src/airflow_breeze/branch_defaults.py +++ b/dev/breeze/src/airflow_breeze/branch_defaults.py @@ -38,6 +38,6 @@ from __future__ import annotations -AIRFLOW_BRANCH = "main" -DEFAULT_AIRFLOW_CONSTRAINTS_BRANCH = "constraints-main" +AIRFLOW_BRANCH = "v3-1-test" +DEFAULT_AIRFLOW_CONSTRAINTS_BRANCH = "constraints-3-1" DEBIAN_VERSION = "bookworm" diff --git a/dev/breeze/src/airflow_breeze/commands/developer_commands.py b/dev/breeze/src/airflow_breeze/commands/developer_commands.py index 763f9c528814b..476f9249146da 100644 --- a/dev/breeze/src/airflow_breeze/commands/developer_commands.py +++ b/dev/breeze/src/airflow_breeze/commands/developer_commands.py @@ -1153,6 +1153,8 @@ def run( shell_params=shell_params, project_name=unique_project_name, command=full_command, + # Always preserve the backend specified by user (or resolved from default) + preserve_backend=True, ) # Clean up ownership diff --git a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py index 23fe43ff124f6..bcc050a743718 100644 --- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py +++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py @@ -253,13 +253,13 @@ class VersionedFile(NamedTuple): AIRFLOW_PIP_VERSION = "25.2" -AIRFLOW_UV_VERSION = "0.8.15" +AIRFLOW_UV_VERSION = "0.9.4" AIRFLOW_USE_UV = False GITPYTHON_VERSION = "3.1.45" -RICH_VERSION = "14.1.0" -PREK_VERSION = "0.1.6" -HATCH_VERSION = "1.14.1" -PYYAML_VERSION = "6.0.2" +RICH_VERSION = "14.2.0" +PREK_VERSION = "0.2.10" +HATCH_VERSION = "1.15.1" +PYYAML_VERSION = "6.0.3" # prek environment and this is done with node, no python installation is needed. AIRFLOW_BUILD_DOCKERFILE = f""" diff --git a/dev/breeze/src/airflow_breeze/commands/setup_commands.py b/dev/breeze/src/airflow_breeze/commands/setup_commands.py index 717f50843f72a..e7d39780241e5 100644 --- a/dev/breeze/src/airflow_breeze/commands/setup_commands.py +++ b/dev/breeze/src/airflow_breeze/commands/setup_commands.py @@ -57,7 +57,6 @@ SCRIPTS_CI_DOCKER_COMPOSE_LOCAL_YAML_PATH, get_installation_airflow_sources, get_installation_sources_config_metadata_hash, - get_package_setup_metadata_hash, get_used_airflow_sources, get_used_sources_setup_metadata_hash, ) @@ -181,9 +180,6 @@ def version(): get_console().print( f"[info]Used sources config hash : {get_used_sources_setup_metadata_hash()}[/]" ) - get_console().print( - f"[info]Package config hash : {(get_package_setup_metadata_hash())}[/]\n" - ) @setup.command(name="config") diff --git a/dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json b/dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json index 363e0c55c2ea1..8f297bdae3d71 100644 --- a/dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json +++ b/dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json @@ -1 +1 @@ -{"admin": "admin", "viewer": "viewer"} +{"admin": "admin", "viewer": "viewer"} diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py index 43d74aa2376f6..523412ed4d8c2 100644 --- a/dev/breeze/src/airflow_breeze/global_constants.py +++ b/dev/breeze/src/airflow_breeze/global_constants.py @@ -201,7 +201,7 @@ ALLOWED_INSTALL_MYSQL_CLIENT_TYPES = ["mariadb", "mysql"] PIP_VERSION = "25.2" -UV_VERSION = "0.8.15" +UV_VERSION = "0.9.4" DEFAULT_UV_HTTP_TIMEOUT = 300 DEFAULT_WSL2_HTTP_TIMEOUT = 900 @@ -794,11 +794,11 @@ def generate_provider_dependencies_if_needed(): ] ALL_PYTHON_VERSION_TO_PATCHLEVEL_VERSION: dict[str, str] = { - "3.9": "3.9.23", - "3.10": "3.10.18", - "3.11": "3.11.13", - "3.12": "3.12.11", - "3.13": "3.13.7", + "3.9": "3.9.24", + "3.10": "3.10.19", + "3.11": "3.11.14", + "3.12": "3.12.12", + "3.13": "3.13.9", } # Number of slices for low dep tests diff --git a/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py b/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py index b959d53fc0469..0ec66aa9abf61 100644 --- a/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py +++ b/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py @@ -642,9 +642,10 @@ def remove_docker_volumes(volumes: list[str] | None = None) -> None: # When you are using Docker Desktop (specifically on MacOS). the preferred context is "desktop-linux" # because the docker socket to use is created in the .docker/ directory in the user's home directory # and it does not require the user to belong to the "docker" group. +# The "rancher-desktop" context is the preferred context for the Rancher dockerd (moby) Container Engine. # The "default" context is the traditional one that requires "/var/run/docker.sock" to be writeable by the # user running the docker command. -PREFERRED_CONTEXTS = ["orbstack", "desktop-linux", "default"] +PREFERRED_CONTEXTS = ["orbstack", "desktop-linux", "rancher-desktop", "default"] def autodetect_docker_context(): @@ -730,13 +731,14 @@ def execute_command_in_shell( command: str | None = None, output: Output | None = None, signal_error: bool = True, + preserve_backend: bool = False, ) -> RunCommandResult: """Executes command in shell. When you want to execute a script/bash command inside the CI container and want to use `enter_shell` for this purpose, the helper methods sets the following parameters of shell_params: - * backend - to force sqlite backend + * backend - to force sqlite backend (unless preserve_backend=True) * clean_sql_db=True - to clean the sqlite DB * forward_ports=False - to avoid forwarding ports from the container to the host - again that will allow to avoid clashes with other commands and opened breeze shell @@ -751,16 +753,23 @@ def execute_command_in_shell( :param project_name: Name of the project to use. This avoids name clashes with default 'breeze" project name used - this way you will be able to run the command in parallel to regular "breeze" shell opened in parallel - :param command: + :param command: command to execute in the shell + :param output: output configuration + :param signal_error: whether to signal error + :param preserve_backend: if True, preserve the backend specified in shell_params instead of forcing sqlite """ - shell_params.backend = "sqlite" + if not preserve_backend: + shell_params.backend = "sqlite" shell_params.forward_ports = False shell_params.project_name = project_name shell_params.quiet = True shell_params.skip_environment_initialization = True shell_params.skip_image_upgrade_check = True if get_verbose(): - get_console().print("[warning]Sqlite DB is cleaned[/]") + if not preserve_backend: + get_console().print("[warning]Sqlite DB is cleaned[/]") + else: + get_console().print(f"[info]Using backend: {shell_params.backend}[/]") get_console().print("[warning]Disabled port forwarding[/]") get_console().print(f"[warning]Project name set to: {project_name}[/]") get_console().print("[warning]Forced quiet mode[/]") diff --git a/dev/breeze/src/airflow_breeze/utils/path_utils.py b/dev/breeze/src/airflow_breeze/utils/path_utils.py index 6ad7467989267..ed72286c27b45 100644 --- a/dev/breeze/src/airflow_breeze/utils/path_utils.py +++ b/dev/breeze/src/airflow_breeze/utils/path_utils.py @@ -32,7 +32,7 @@ from airflow_breeze import NAME from airflow_breeze.utils.console import get_console from airflow_breeze.utils.functools_cache import clearable_cache -from airflow_breeze.utils.reinstall import reinstall_breeze, warn_dependencies_changed, warn_non_editable +from airflow_breeze.utils.reinstall import inform_about_self_upgrade, reinstall_breeze, warn_non_editable from airflow_breeze.utils.shared_options import get_verbose, set_forced_answer PYPROJECT_TOML_FILE = "pyproject.toml" @@ -82,37 +82,6 @@ def skip_group_output(): return in_autocomplete() or in_help() or os.environ.get("SKIP_GROUP_OUTPUT") is not None -def get_package_setup_metadata_hash() -> str: - """ - Retrieves hash of setup files from the source of installation of Breeze. - - This is used in order to determine if we need to upgrade Breeze, because some - setup files changed. Blake2b algorithm will not be flagged by security checkers - as insecure algorithm (in Python 3.9 and above we can use `usedforsecurity=False` - to disable it, but for now it's better to use more secure algorithms. - """ - # local imported to make sure that autocomplete works - try: - from importlib.metadata import distribution - except ImportError: - from importlib_metadata import distribution # type: ignore[assignment] - - prefix = "Package config hash: " - metadata = distribution("apache-airflow-breeze").metadata - try: - description = metadata.json["description"] - except (AttributeError, KeyError): - description = str(metadata["Description"]) if "Description" in metadata else "" - - if isinstance(description, list): - description = "\n".join(description) - - for line in description.splitlines(keepends=False): - if line.startswith(prefix): - return line[len(prefix) :] - return "NOT FOUND" - - def get_pyproject_toml_hash(sources: Path) -> str: try: the_hash = hashlib.new("blake2b") @@ -154,15 +123,7 @@ def set_forced_answer_for_upgrade_check(): set_forced_answer("quit") -def process_breeze_readme(breeze_sources: Path, sources_hash: str): - breeze_readme = breeze_sources / "README.md" - lines = breeze_readme.read_text().splitlines(keepends=True) - result_lines = [] - for line in lines: - if line.startswith("Package config hash:"): - line = f"Package config hash: {sources_hash}\n" - result_lines.append(line) - breeze_readme.write_text("".join(result_lines)) +MY_BREEZE_ROOT_PATH = Path(__file__).resolve().parents[1] def reinstall_if_setup_changed() -> bool: @@ -170,28 +131,16 @@ def reinstall_if_setup_changed() -> bool: Prints warning if detected airflow sources are not the ones that Breeze was installed with. :return: True if warning was printed. """ - try: - package_hash = get_package_setup_metadata_hash() - except ModuleNotFoundError as e: - if "importlib_metadata" in e.msg: - return False - if "apache-airflow-breeze" in e.msg: - print( - """Missing Package `apache-airflow-breeze`. Please install it.\n - Use `uv tool install -e ./dev/breeze or `pipx install -e ./dev/breeze` - to install the package.""" - ) - return False - sources_hash = get_installation_sources_config_metadata_hash() - if sources_hash != package_hash: - installation_sources = get_installation_airflow_sources() - if installation_sources is not None: - breeze_sources = installation_sources / "dev" / "breeze" - warn_dependencies_changed() - process_breeze_readme(breeze_sources, sources_hash) - set_forced_answer_for_upgrade_check() - reinstall_breeze(breeze_sources) - set_forced_answer(None) + + res = subprocess.run( + ["uv", "tool", "upgrade", "apache-airflow-breeze"], + cwd=MY_BREEZE_ROOT_PATH, + check=True, + text=True, + capture_output=True, + ) + if "Modified" in res.stderr: + inform_about_self_upgrade() return True return False diff --git a/dev/breeze/src/airflow_breeze/utils/reinstall.py b/dev/breeze/src/airflow_breeze/utils/reinstall.py index 2c2c3298b8c78..22b48b39ef02a 100644 --- a/dev/breeze/src/airflow_breeze/utils/reinstall.py +++ b/dev/breeze/src/airflow_breeze/utils/reinstall.py @@ -99,11 +99,8 @@ def warn_non_editable(): ) -def warn_dependencies_changed(): +def inform_about_self_upgrade(): get_console().print( - f"\n[warning]Breeze dependencies changed since the installation![/]\n\n" - f"[warning]This might cause various problems!![/]\n\n" - f"If you experience problems - reinstall Breeze with:\n\n" - f" {NAME} setup self-upgrade\n" - "\nThis should usually take couple of seconds.\n" + "\n[info]Breeze dependencies changed since the installation. Reinstalling them!\n\n[/]" + "You might need to rerun the command in case it fails\n\n" ) diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py b/dev/breeze/src/airflow_breeze/utils/selective_checks.py index 0fcc1c2b3a8dd..04824055dc8f2 100644 --- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py +++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py @@ -81,7 +81,6 @@ FULL_TESTS_NEEDED_LABEL = "full tests needed" INCLUDE_SUCCESS_OUTPUTS_LABEL = "include success outputs" LATEST_VERSIONS_ONLY_LABEL = "latest versions only" -LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL = "log exception" NON_COMMITTER_BUILD_LABEL = "non committer build" UPGRADE_TO_NEWER_DEPENDENCIES_LABEL = "upgrade to newer dependencies" USE_PUBLIC_RUNNERS_LABEL = "use public runners" @@ -1216,23 +1215,6 @@ def docs_list_as_string(self) -> str | None: def skip_prek_hooks(self) -> str: prek_hooks_to_skip = set() prek_hooks_to_skip.add("identity") - # Skip all mypy "individual" file checks if we are running mypy checks in CI - # In the CI we always run mypy for the whole "package" rather than for `--all-files` because - # The prek will semi-randomly skip such list of files into several groups and we want - # to make sure that such checks are always run in CI for whole "group" of files - i.e. - # whole package rather than for individual files. That's why we skip those checks in CI - # and run them via `mypy-all` command instead and dedicated CI job in matrix - # This will also speed up static-checks job usually as the jobs will be running in parallel - prek_hooks_to_skip.update( - { - "mypy-providers", - "mypy-airflow-core", - "mypy-dev", - "mypy-task-sdk", - "mypy-airflow-ctl", - "mypy-devel-common", - } - ) if self._default_branch != "main": # Skip those tests on all "release" branches prek_hooks_to_skip.update( @@ -1444,80 +1426,6 @@ def _is_canary_run(self): and self._github_repository == APACHE_AIRFLOW_GITHUB_REPOSITORY ) or CANARY_LABEL in self._pr_labels - @classmethod - def _find_caplog_in_def(cls, added_lines): - """ - Find caplog in def - - :param added_lines: lines added in the file - :return: True if caplog is found in def else False - """ - line_counter = 0 - while line_counter < len(added_lines): - if all(keyword in added_lines[line_counter] for keyword in ["def", "caplog", "(", ")"]): - return True - if "def" in added_lines[line_counter] and ")" not in added_lines[line_counter]: - while line_counter < len(added_lines) and ")" not in added_lines[line_counter]: - if "caplog" in added_lines[line_counter]: - return True - line_counter += 1 - line_counter += 1 - return None - - def _caplog_exists_in_added_lines(self) -> bool: - """ - Check if caplog is used in added lines - - :return: True if caplog is used in added lines else False - """ - lines = run_command( - ["git", "diff", f"{self._commit_ref}^"], - capture_output=True, - text=True, - cwd=AIRFLOW_ROOT_PATH, - check=False, - ) - - if "caplog" not in lines.stdout or lines.stdout == "": - return False - - added_caplog_lines = [ - line.lstrip().lstrip("+") for line in lines.stdout.split("\n") if line.lstrip().startswith("+") - ] - return self._find_caplog_in_def(added_lines=added_caplog_lines) - - @cached_property - def is_log_mocked_in_the_tests(self) -> bool: - """ - Check if log is used without mock in the tests - """ - if self._is_canary_run() or self._github_event not in ( - GithubEvents.PULL_REQUEST, - GithubEvents.PULL_REQUEST_TARGET, - ): - return False - # Check if changed files are unit tests - if ( - self._matching_files(FileGroupForCi.UNIT_TEST_FILES, CI_FILE_GROUP_MATCHES) - and LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL not in self._pr_labels - ): - if self._caplog_exists_in_added_lines(): - get_console().print( - f"[error]Caplog is used in the test. " - f"Please be sure you are mocking the log. " - "For example, use `patch.object` to mock `log`." - "Using `caplog` directly in your test files can cause side effects " - "and not recommended. If you think, `caplog` is the only way to test " - "the functionality or there is and exceptional case, " - "please ask maintainer to include as an exception using " - f"'{LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL}' label. " - "It is up to maintainer decision to allow this exception.", - ) - sys.exit(1) - else: - return True - return True - @cached_property def force_pip(self): return FORCE_PIP_LABEL in self._pr_labels diff --git a/dev/breeze/src/airflow_breeze/utils/visuals.py b/dev/breeze/src/airflow_breeze/utils/visuals.py index 8c06657e4a89c..86176895c06b4 100644 --- a/dev/breeze/src/airflow_breeze/utils/visuals.py +++ b/dev/breeze/src/airflow_breeze/utils/visuals.py @@ -90,7 +90,7 @@ Direct links to those services that you can use from the host: * ssh connection for remote debugging: ssh -p {SSH_PORT} airflow@localhost (password: airflow) - * API server or webserver: http://localhost:{WEB_HOST_PORT} + * API server or webserver: http://localhost:{WEB_HOST_PORT} (username: admin, password: admin) * Flower: http://localhost:{FLOWER_HOST_PORT} * Postgres: jdbc:postgresql://localhost:{POSTGRES_HOST_PORT}/airflow?user=postgres&password=airflow * Mysql: jdbc:mysql://localhost:{MYSQL_HOST_PORT}/airflow?user=root diff --git a/dev/breeze/tests/test_selective_checks.py b/dev/breeze/tests/test_selective_checks.py index cd35cff2c9bc1..98d2dbdc68a6a 100644 --- a/dev/breeze/tests/test_selective_checks.py +++ b/dev/breeze/tests/test_selective_checks.py @@ -19,7 +19,6 @@ import json import re from typing import Any -from unittest.mock import MagicMock, patch import pytest from rich.console import Console @@ -105,56 +104,40 @@ ) ALL_SKIPPED_COMMITS_ON_NO_CI_IMAGE = ( - "check-provider-yaml-valid,flynt,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl," - "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk," + "check-provider-yaml-valid,flynt,identity,lint-helm-chart," "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" ) -ALL_SKIPPED_COMMITS_BY_DEFAULT_ON_ALL_TESTS_NEEDED = ( - "identity,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk" -) +ALL_SKIPPED_COMMITS_BY_DEFAULT_ON_ALL_TESTS_NEEDED = "identity" -ALL_SKIPPED_COMMITS_IF_NO_UI = ( - "identity,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common," - "mypy-providers,mypy-task-sdk,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" -) -ALL_SKIPPED_COMMITS_IF_NO_HELM_TESTS = ( - "identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common," - "mypy-providers,mypy-task-sdk" -) +ALL_SKIPPED_COMMITS_IF_NO_UI = "identity,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" +ALL_SKIPPED_COMMITS_IF_NO_HELM_TESTS = "identity,lint-helm-chart" ALL_SKIPPED_COMMITS_IF_NO_UI_AND_HELM_TESTS = ( - "identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common," - "mypy-providers,mypy-task-sdk,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" + "identity,lint-helm-chart,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" ) ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS_AND_UI = ( - "check-provider-yaml-valid,identity,mypy-airflow-core,mypy-airflow-ctl," - "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk," - "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" + "check-provider-yaml-valid,identity,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" ) ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS = ( - "check-provider-yaml-valid,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl," - "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk," + "check-provider-yaml-valid,identity,lint-helm-chart," "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" ) ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS_UI_AND_HELM_TESTS = ( - "check-provider-yaml-valid,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl," - "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk," + "check-provider-yaml-valid,identity,lint-helm-chart," "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" ) ALL_SKIPPED_COMMITS_IF_NO_CODE_PROVIDERS_AND_HELM_TESTS = ( - "check-provider-yaml-valid,flynt,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl," - "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk" + "check-provider-yaml-valid,flynt,identity,lint-helm-chart" ) ALL_SKIPPED_COMMITS_IF_NOT_IMPORTANT_FILES_CHANGED = ( - "check-provider-yaml-valid,flynt,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl," - "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk," + "check-provider-yaml-valid,flynt,identity,lint-helm-chart," "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui" ) @@ -163,17 +146,13 @@ "check-airflow-provider-compatibility,check-airflow-providers-bug-report-template," "check-extra-packages-references,check-provider-yaml-valid," "compile-fab-assets,generate-openapi-spec-fab,identity," - "lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,mypy-dev," - "mypy-devel-common,mypy-providers,mypy-task-sdk,validate-operators-init" + "lint-helm-chart,validate-operators-init" ) # commit that is neutral - allows to keep pyproject.toml-changing PRS neutral for unit tests NEUTRAL_COMMIT = "938f0c1f3cc4cbe867123ee8aa9f290f9f18100a" -# Use me if you are adding test for the changed files that includes caplog -LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL = "log exception" - def escape_ansi_colors(line): return ANSI_COLORS_MATCHER.sub("", line) @@ -1112,7 +1091,7 @@ def assert_outputs_are_printed(expected_outputs: dict[str, str], stderr: str): "run-unit-tests": "true", "run-amazon-tests": "false", "docs-build": "true", - "skip-prek-hooks": "check-provider-yaml-valid,flynt,identity,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui", + "skip-prek-hooks": "check-provider-yaml-valid,flynt,identity,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui", "upgrade-to-newer-dependencies": "false", "core-test-types-list-as-strings-in-json": None, "providers-test-types-list-as-strings-in-json": None, @@ -1170,7 +1149,7 @@ def test_expected_output_pull_request_main( files=files, commit_ref=NEUTRAL_COMMIT, github_event=GithubEvents.PULL_REQUEST, - pr_labels=(LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL,), + pr_labels=tuple(), default_branch="main", ) assert_outputs_are_printed(expected_outputs, str(stderr)) @@ -1548,10 +1527,7 @@ def test_full_test_needed_when_scripts_changes(files: tuple[str, ...], expected_ ( pytest.param( ("INTHEWILD.md", "providers/asana/tests/asana.py"), - ( - "full tests needed", - LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL, - ), + ("full tests needed",), "v2-7-stable", { "all-python-versions": f"['{DEFAULT_PYTHON_MAJOR_MINOR_VERSION}']", @@ -1706,7 +1682,7 @@ def test_expected_output_pull_request_v2_7( files=files, commit_ref=NEUTRAL_COMMIT, github_event=GithubEvents.PULL_REQUEST, - pr_labels=(LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL,), + pr_labels=(), default_branch="v2-7-stable", ) assert_outputs_are_printed(expected_outputs, str(stderr)) @@ -1984,7 +1960,7 @@ def test_expected_output_pull_request_target( files=files, commit_ref=NEUTRAL_COMMIT, github_event=GithubEvents.PULL_REQUEST_TARGET, - pr_labels=(LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL,), + pr_labels=(), default_branch="main", ) assert_outputs_are_printed(expected_outputs, str(stderr)) @@ -2447,231 +2423,6 @@ def test_mypy_matches( assert_outputs_are_printed(expected_outputs, str(stderr)) -@pytest.mark.parametrize( - "files, pr_labels, github_event", - [ - pytest.param( - ("airflow-core/tests/unit/test.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the the git diff Tests", - ), - pytest.param( - ("providers/common/sql/tests/unit/common/sql/operators/test_sql.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the git diff Providers", - ), - pytest.param( - ("task-sdk/tests/definitions/test_dag.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the git diff TaskSDK", - ), - ], -) -# Patch run_command -@patch("airflow_breeze.utils.selective_checks.run_command") -def test_is_log_mocked_in_the_tests_fail( - mock_run_command, - files: tuple[str, ...], - pr_labels: tuple[str, ...], - github_event: GithubEvents, -): - mock_run_command_result = MagicMock() - mock_run_command_result.stdout = """ - + #Test Change - + def test_selective_checks_caplop(self, caplog) - + caplog.set_level(logging.INFO) - + "test log" in caplog.text - """ - mock_run_command.return_value = mock_run_command_result - with pytest.raises(SystemExit): - assert ( - "[error]please ask maintainer to include as an exception using " - f"'{LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL}' label." - in escape_ansi_colors( - str( - SelectiveChecks( - files=files, - commit_ref=NEUTRAL_COMMIT, - pr_labels=pr_labels, - github_event=GithubEvents.PULL_REQUEST, - default_branch="main", - ) - ) - ) - ) - - -@pytest.mark.parametrize( - "files, pr_labels, github_event", - [ - pytest.param( - ("airflow-core/tests/unit/test.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the the git diff Tests", - ), - pytest.param( - ("providers/common/sql/tests/unit/common/sql/operators/test_sql.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the git diff Providers", - ), - pytest.param( - ("task-sdk/tests/definitions/test_dag.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the git diff TaskSDK", - ), - ], -) -# Patch run_command -@patch("airflow_breeze.utils.selective_checks.run_command") -def test_is_log_mocked_in_the_tests_fail_formatted( - mock_run_command, - files: tuple[str, ...], - pr_labels: tuple[str, ...], - github_event: GithubEvents, -): - mock_run_command_result = MagicMock() - mock_run_command_result.stdout = """ - + #Test Change - + def test_selective_checks( - + self, - + caplog - + ) - + caplog.set_level(logging.INFO) - + "test log" in caplog.text - """ - mock_run_command.return_value = mock_run_command_result - with pytest.raises(SystemExit): - assert ( - "[error]please ask maintainer to include as an exception using " - f"'{LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL}' label." - in escape_ansi_colors( - str( - SelectiveChecks( - files=files, - commit_ref=NEUTRAL_COMMIT, - pr_labels=pr_labels, - github_event=GithubEvents.PULL_REQUEST, - default_branch="main", - ) - ) - ) - ) - - -@pytest.mark.parametrize( - "files, pr_labels, github_event", - [ - pytest.param( - ("airflow-core/tests/unit/test.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the the git diff Tests", - ), - pytest.param( - ("providers/common/sql/tests/unit/common/sql/operators/test_sql.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the git diff Providers", - ), - pytest.param( - ("task-sdk/tests/definitions/test_dag.py",), - (), - GithubEvents.PULL_REQUEST, - id="Caplog is in the git diff TaskSDK", - ), - ], -) -# Patch run_command -@patch("airflow_breeze.utils.selective_checks.run_command") -def test_is_log_mocked_in_the_tests_not_fail( - mock_run_command, - files: tuple[str, ...], - pr_labels: tuple[str, ...], - github_event: GithubEvents, -): - mock_run_command_result = MagicMock() - mock_run_command_result.stdout = """ - + #Test Change - + def test_selective_checks(self) - + assert "I am just a test" == "I am just a test" - """ - mock_run_command.return_value = mock_run_command_result - selective_checks = SelectiveChecks( - files=files, - commit_ref=NEUTRAL_COMMIT, - pr_labels=pr_labels, - github_event=GithubEvents.PULL_REQUEST, - default_branch="main", - ) - assert selective_checks.is_log_mocked_in_the_tests - - -@pytest.mark.parametrize( - "files, pr_labels, github_event", - [ - pytest.param( - ("airflow-core/tests/unit/test.py",), - (LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL,), - GithubEvents.PULL_REQUEST, - id="Caplog is in the the git diff Tests", - ), - pytest.param( - ("providers/common/sql/tests/unit/common/sql/operators/test_sql.py",), - (LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL,), - GithubEvents.PULL_REQUEST, - id="Caplog is in the git diff Providers", - ), - pytest.param( - ("task-sdk/tests/definitions/test_dag.py",), - (LOG_WITHOUT_MOCK_IN_TESTS_EXCEPTION_LABEL,), - GithubEvents.PULL_REQUEST, - id="Caplog is in the git diff TaskSDK", - ), - ], -) -# Patch run_command -@patch("airflow_breeze.utils.selective_checks.run_command") -def test_is_log_mocked_in_the_tests_not_fail_with_label( - mock_run_command, - files: tuple[str, ...], - pr_labels: tuple[str, ...], - github_event: GithubEvents, -): - mock_run_command_result = MagicMock() - mock_run_command_result.stdout = """ - + #Test Change - + def test_selective_checks_caplop(self, caplog) - + caplog.set_level(logging.INFO) - + "test log" in caplog.text - """ - mock_run_command.return_value = mock_run_command_result - selective_checks = SelectiveChecks( - files=files, - commit_ref=NEUTRAL_COMMIT, - pr_labels=pr_labels, - github_event=GithubEvents.PULL_REQUEST, - default_branch="main", - ) - assert selective_checks.is_log_mocked_in_the_tests - - -def test_ui_english_translation_changed_false(): - selective_checks = SelectiveChecks( - files=("README.md",), - commit_ref=NEUTRAL_COMMIT, - pr_labels=(), - github_event=GithubEvents.PULL_REQUEST, - default_branch="main", - ) - assert selective_checks.ui_english_translation_changed is False - - def test_ui_english_translation_changed_fail_on_change(): translation_file = "airflow-core/src/airflow/ui/public/i18n/locales/en/some_file.json" with pytest.raises(SystemExit): diff --git a/dev/breeze/uv.lock b/dev/breeze/uv.lock index 7301c56db81c4..cd18712c2cc24 100644 --- a/dev/breeze/uv.lock +++ b/dev/breeze/uv.lock @@ -1,14 +1,16 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.10, !=3.13" resolution-markers = [ - "python_full_version >= '3.13'", + "python_full_version >= '3.14' and platform_python_implementation != 'PyPy'", + "python_full_version == '3.13.*' and platform_python_implementation != 'PyPy'", + "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", "python_full_version < '3.13'", ] [[package]] name = "anyio" -version = "4.10.0" +version = "4.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, @@ -16,9 +18,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload-time = "2025-08-04T08:54:26.451Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, ] [[package]] @@ -70,12 +72,12 @@ requires-dist = [ { name = "google-api-python-client", specifier = ">=2.142.0" }, { name = "google-auth-httplib2", specifier = ">=0.2.0" }, { name = "google-auth-oauthlib", specifier = ">=1.2.0" }, - { name = "hatch", specifier = ">=1.14.1" }, + { name = "hatch", specifier = ">=1.15.1" }, { name = "inputimeout", specifier = ">=1.0.4" }, { name = "jinja2", specifier = ">=3.1.5" }, { name = "jsonschema", specifier = ">=4.19.1" }, { name = "packaging", specifier = ">=25.0" }, - { name = "prek", specifier = ">=0.1.6" }, + { name = "prek", specifier = ">=0.2.10" }, { name = "psutil", specifier = ">=5.9.6" }, { name = "pygithub", specifier = ">=2.1.1" }, { name = "pytest", specifier = ">=8.3.3" }, @@ -84,7 +86,7 @@ requires-dist = [ { name = "requests", specifier = ">=2.32.0" }, { name = "restructuredtext-lint", specifier = ">=1.4.0" }, { name = "rich", specifier = ">=13.6.0" }, - { name = "rich-click", specifier = ">=1.7.1" }, + { name = "rich-click", specifier = ">=1.7.1,<1.9.0" }, { name = "semver", specifier = ">=3.0.4" }, { name = "tabulate", specifier = ">=0.9.0" }, { name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2.0.1" }, @@ -94,11 +96,11 @@ requires-dist = [ [[package]] name = "attrs" -version = "25.3.0" +version = "25.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] [[package]] @@ -112,7 +114,7 @@ wheels = [ [[package]] name = "black" -version = "25.1.0" +version = "25.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -120,195 +122,246 @@ dependencies = [ { name = "packaging" }, { name = "pathspec" }, { name = "platformdirs" }, + { name = "pytokens" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619", size = 648393, upload-time = "2025-09-19T00:27:37.758Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/3b/4ba3f93ac8d90410423fdd31d7541ada9bcee1df32fb90d26de41ed40e1d/black-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32", size = 1629419, upload-time = "2025-01-29T05:37:06.642Z" }, - { url = "https://files.pythonhosted.org/packages/b4/02/0bde0485146a8a5e694daed47561785e8b77a0466ccc1f3e485d5ef2925e/black-25.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da", size = 1461080, upload-time = "2025-01-29T05:37:09.321Z" }, - { url = "https://files.pythonhosted.org/packages/52/0e/abdf75183c830eaca7589144ff96d49bce73d7ec6ad12ef62185cc0f79a2/black-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7", size = 1766886, upload-time = "2025-01-29T04:18:24.432Z" }, - { url = "https://files.pythonhosted.org/packages/dc/a6/97d8bb65b1d8a41f8a6736222ba0a334db7b7b77b8023ab4568288f23973/black-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9", size = 1419404, upload-time = "2025-01-29T04:19:04.296Z" }, - { url = "https://files.pythonhosted.org/packages/7e/4f/87f596aca05c3ce5b94b8663dbfe242a12843caaa82dd3f85f1ffdc3f177/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0", size = 1614372, upload-time = "2025-01-29T05:37:11.71Z" }, - { url = "https://files.pythonhosted.org/packages/e7/d0/2c34c36190b741c59c901e56ab7f6e54dad8df05a6272a9747ecef7c6036/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299", size = 1442865, upload-time = "2025-01-29T05:37:14.309Z" }, - { url = "https://files.pythonhosted.org/packages/21/d4/7518c72262468430ead45cf22bd86c883a6448b9eb43672765d69a8f1248/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096", size = 1749699, upload-time = "2025-01-29T04:18:17.688Z" }, - { url = "https://files.pythonhosted.org/packages/58/db/4f5beb989b547f79096e035c4981ceb36ac2b552d0ac5f2620e941501c99/black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2", size = 1428028, upload-time = "2025-01-29T04:18:51.711Z" }, - { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988, upload-time = "2025-01-29T05:37:16.707Z" }, - { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985, upload-time = "2025-01-29T05:37:18.273Z" }, - { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816, upload-time = "2025-01-29T04:18:33.823Z" }, - { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860, upload-time = "2025-01-29T04:19:12.944Z" }, - { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload-time = "2025-01-29T05:37:20.574Z" }, - { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload-time = "2025-01-29T05:37:22.106Z" }, - { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload-time = "2025-01-29T04:18:58.564Z" }, - { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload-time = "2025-01-29T04:19:27.63Z" }, - { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" }, + { url = "https://files.pythonhosted.org/packages/25/40/dbe31fc56b218a858c8fc6f5d8d3ba61c1fa7e989d43d4a4574b8b992840/black-25.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ce41ed2614b706fd55fd0b4a6909d06b5bab344ffbfadc6ef34ae50adba3d4f7", size = 1715605, upload-time = "2025-09-19T00:36:13.483Z" }, + { url = "https://files.pythonhosted.org/packages/92/b2/f46800621200eab6479b1f4c0e3ede5b4c06b768e79ee228bc80270bcc74/black-25.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ab0ce111ef026790e9b13bd216fa7bc48edd934ffc4cbf78808b235793cbc92", size = 1571829, upload-time = "2025-09-19T00:32:42.13Z" }, + { url = "https://files.pythonhosted.org/packages/4e/64/5c7f66bd65af5c19b4ea86062bb585adc28d51d37babf70969e804dbd5c2/black-25.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f96b6726d690c96c60ba682955199f8c39abc1ae0c3a494a9c62c0184049a713", size = 1631888, upload-time = "2025-09-19T00:30:54.212Z" }, + { url = "https://files.pythonhosted.org/packages/3b/64/0b9e5bfcf67db25a6eef6d9be6726499a8a72ebab3888c2de135190853d3/black-25.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:d119957b37cc641596063cd7db2656c5be3752ac17877017b2ffcdb9dfc4d2b1", size = 1327056, upload-time = "2025-09-19T00:31:08.877Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f4/7531d4a336d2d4ac6cc101662184c8e7d068b548d35d874415ed9f4116ef/black-25.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:456386fe87bad41b806d53c062e2974615825c7a52159cde7ccaeb0695fa28fa", size = 1698727, upload-time = "2025-09-19T00:31:14.264Z" }, + { url = "https://files.pythonhosted.org/packages/28/f9/66f26bfbbf84b949cc77a41a43e138d83b109502cd9c52dfc94070ca51f2/black-25.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a16b14a44c1af60a210d8da28e108e13e75a284bf21a9afa6b4571f96ab8bb9d", size = 1555679, upload-time = "2025-09-19T00:31:29.265Z" }, + { url = "https://files.pythonhosted.org/packages/bf/59/61475115906052f415f518a648a9ac679d7afbc8da1c16f8fdf68a8cebed/black-25.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaf319612536d502fdd0e88ce52d8f1352b2c0a955cc2798f79eeca9d3af0608", size = 1617453, upload-time = "2025-09-19T00:30:42.24Z" }, + { url = "https://files.pythonhosted.org/packages/7f/5b/20fd5c884d14550c911e4fb1b0dae00d4abb60a4f3876b449c4d3a9141d5/black-25.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:c0372a93e16b3954208417bfe448e09b0de5cc721d521866cd9e0acac3c04a1f", size = 1333655, upload-time = "2025-09-19T00:30:56.715Z" }, + { url = "https://files.pythonhosted.org/packages/fb/8e/319cfe6c82f7e2d5bfb4d3353c6cc85b523d677ff59edc61fdb9ee275234/black-25.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1b9dc70c21ef8b43248f1d86aedd2aaf75ae110b958a7909ad8463c4aa0880b0", size = 1742012, upload-time = "2025-09-19T00:33:08.678Z" }, + { url = "https://files.pythonhosted.org/packages/94/cc/f562fe5d0a40cd2a4e6ae3f685e4c36e365b1f7e494af99c26ff7f28117f/black-25.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8e46eecf65a095fa62e53245ae2795c90bdecabd53b50c448d0a8bcd0d2e74c4", size = 1581421, upload-time = "2025-09-19T00:35:25.937Z" }, + { url = "https://files.pythonhosted.org/packages/84/67/6db6dff1ebc8965fd7661498aea0da5d7301074b85bba8606a28f47ede4d/black-25.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9101ee58ddc2442199a25cb648d46ba22cd580b00ca4b44234a324e3ec7a0f7e", size = 1655619, upload-time = "2025-09-19T00:30:49.241Z" }, + { url = "https://files.pythonhosted.org/packages/10/10/3faef9aa2a730306cf469d76f7f155a8cc1f66e74781298df0ba31f8b4c8/black-25.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:77e7060a00c5ec4b3367c55f39cf9b06e68965a4f2e61cecacd6d0d9b7ec945a", size = 1342481, upload-time = "2025-09-19T00:31:29.625Z" }, + { url = "https://files.pythonhosted.org/packages/48/99/3acfea65f5e79f45472c45f87ec13037b506522719cd9d4ac86484ff51ac/black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175", size = 1742165, upload-time = "2025-09-19T00:34:10.402Z" }, + { url = "https://files.pythonhosted.org/packages/3a/18/799285282c8236a79f25d590f0222dbd6850e14b060dfaa3e720241fd772/black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f", size = 1581259, upload-time = "2025-09-19T00:32:49.685Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ce/883ec4b6303acdeca93ee06b7622f1fa383c6b3765294824165d49b1a86b/black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831", size = 1655583, upload-time = "2025-09-19T00:30:44.505Z" }, + { url = "https://files.pythonhosted.org/packages/21/17/5c253aa80a0639ccc427a5c7144534b661505ae2b5a10b77ebe13fa25334/black-25.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357", size = 1343428, upload-time = "2025-09-19T00:32:13.839Z" }, + { url = "https://files.pythonhosted.org/packages/1b/46/863c90dcd3f9d41b109b7f19032ae0db021f0b2a81482ba0a1e28c84de86/black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae", size = 203363, upload-time = "2025-09-19T00:27:35.724Z" }, ] [[package]] name = "boto3" -version = "1.40.11" +version = "1.40.55" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/92/3ffa75ed0594ef289dde3dde9e1d62a496515313f11caee499a5dfd2241d/boto3-1.40.11.tar.gz", hash = "sha256:0c03da130467d51c6b940d19be295c56314e14ce0f0464cc86145e98d3c9e983", size = 112060, upload-time = "2025-08-15T19:26:03.724Z" } +sdist = { url = "https://files.pythonhosted.org/packages/50/d8/a279c054e0c9731172f05b3d118f3ffc9d74806657f84fc0c93c42d1bb5d/boto3-1.40.55.tar.gz", hash = "sha256:27e35b4fa9edd414ce06c1a748bf57cacd8203271847d93fc1053e4a4ec6e1a9", size = 111590, upload-time = "2025-10-17T19:34:56.753Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/4a/5d33b6046d425c9b39d36a1171ea87a9c3b297ba116952b81033eae61260/boto3-1.40.11-py3-none-any.whl", hash = "sha256:9d2d211d9cb3efc9a2b2ceec3c510b4e62e389618fd5c871e74d2cbca4561ff5", size = 140072, upload-time = "2025-08-15T19:26:02.09Z" }, + { url = "https://files.pythonhosted.org/packages/42/8c/559c6145d857ed953536a83f3a94915bbd5d3d2d406db1abf8bf40be7645/boto3-1.40.55-py3-none-any.whl", hash = "sha256:2e30f5a0d49e107b8a5c0c487891afd300bfa410e1d918bf187ae45ac3839332", size = 139322, upload-time = "2025-10-17T19:34:55.028Z" }, ] [[package]] name = "botocore" -version = "1.40.11" +version = "1.40.55" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/34/b2/23e4dc97d941dad612959664029f2eb843fd65ce58cc7b3c02f996b6357c/botocore-1.40.11.tar.gz", hash = "sha256:95af22e1b2230bdd5faa9d1c87e8b147028b14b531770a1148bf495967ccba5e", size = 14339310, upload-time = "2025-08-15T19:25:54.286Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/92/dce4842b2e215d213d34b064fcdd13c6a782c43344e77336bcde586e9229/botocore-1.40.55.tar.gz", hash = "sha256:79b6472e2de92b3519d44fc1eec8c5feced7f99a0d10fdea6dc93133426057c1", size = 14446917, upload-time = "2025-10-17T19:34:47.44Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/f9/400e0da61cbbcea7868458f3a447d1191a62ae5e2852d2acdfd4d51b2843/botocore-1.40.11-py3-none-any.whl", hash = "sha256:4beca0c5f92201da1bf1bc0a55038538ad2defded32ab0638cb68f5631dcc665", size = 14005730, upload-time = "2025-08-15T19:25:49.793Z" }, + { url = "https://files.pythonhosted.org/packages/21/30/f13bbc36e83b78777ff1abf50a084efcc3336b808e76560d8c5a0c9219e0/botocore-1.40.55-py3-none-any.whl", hash = "sha256:cdc38f7a4ddb30a2cd1cdd4fabde2a5a16e41b5a642292e1c30de5c4e46f5d44", size = 14116107, upload-time = "2025-10-17T19:34:44.398Z" }, ] [[package]] name = "cachetools" -version = "5.5.2" +version = "6.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380, upload-time = "2025-02-20T21:01:19.524Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/7e/b975b5814bd36faf009faebe22c1072a1fa1168db34d285ef0ba071ad78c/cachetools-6.2.1.tar.gz", hash = "sha256:3f391e4bd8f8bf0931169baf7456cc822705f4e2a31f840d218f445b9a854201", size = 31325, upload-time = "2025-10-12T14:55:30.139Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080, upload-time = "2025-02-20T21:01:16.647Z" }, + { url = "https://files.pythonhosted.org/packages/96/c5/1e741d26306c42e2bf6ab740b2202872727e0f606033c9dd713f8b93f5a8/cachetools-6.2.1-py3-none-any.whl", hash = "sha256:09868944b6dde876dfd44e1d47e18484541eaf12f26f29b7af91b26cc892d701", size = 11280, upload-time = "2025-10-12T14:55:28.382Z" }, ] [[package]] name = "certifi" -version = "2025.8.3" +version = "2025.10.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, ] [[package]] name = "cffi" -version = "1.17.1" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pycparser" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191, upload-time = "2024-09-04T20:43:30.027Z" }, - { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592, upload-time = "2024-09-04T20:43:32.108Z" }, - { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024, upload-time = "2024-09-04T20:43:34.186Z" }, - { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188, upload-time = "2024-09-04T20:43:36.286Z" }, - { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571, upload-time = "2024-09-04T20:43:38.586Z" }, - { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687, upload-time = "2024-09-04T20:43:40.084Z" }, - { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211, upload-time = "2024-09-04T20:43:41.526Z" }, - { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325, upload-time = "2024-09-04T20:43:43.117Z" }, - { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784, upload-time = "2024-09-04T20:43:45.256Z" }, - { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564, upload-time = "2024-09-04T20:43:46.779Z" }, - { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804, upload-time = "2024-09-04T20:43:48.186Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299, upload-time = "2024-09-04T20:43:49.812Z" }, - { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" }, - { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, - { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, - { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, - { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, - { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, - { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, - { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, - { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, - { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" }, - { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" }, - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, + { name = "pycparser", marker = "(python_full_version < '3.13' and implementation_name != 'PyPy') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283, upload-time = "2025-09-08T23:22:08.01Z" }, + { url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504, upload-time = "2025-09-08T23:22:10.637Z" }, + { url = "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811, upload-time = "2025-09-08T23:22:12.267Z" }, + { url = "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402, upload-time = "2025-09-08T23:22:13.455Z" }, + { url = "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217, upload-time = "2025-09-08T23:22:14.596Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079, upload-time = "2025-09-08T23:22:15.769Z" }, + { url = "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475, upload-time = "2025-09-08T23:22:17.427Z" }, + { url = "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829, upload-time = "2025-09-08T23:22:19.069Z" }, + { url = "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211, upload-time = "2025-09-08T23:22:20.588Z" }, + { url = "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036, upload-time = "2025-09-08T23:22:22.143Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184, upload-time = "2025-09-08T23:22:23.328Z" }, + { url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790, upload-time = "2025-09-08T23:22:24.752Z" }, + { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, ] [[package]] name = "charset-normalizer" -version = "3.4.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/98/f3b8013223728a99b908c9344da3aa04ee6e3fa235f19409033eda92fb78/charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", size = 207695, upload-time = "2025-08-09T07:55:36.452Z" }, - { url = "https://files.pythonhosted.org/packages/21/40/5188be1e3118c82dcb7c2a5ba101b783822cfb413a0268ed3be0468532de/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", size = 147153, upload-time = "2025-08-09T07:55:38.467Z" }, - { url = "https://files.pythonhosted.org/packages/37/60/5d0d74bc1e1380f0b72c327948d9c2aca14b46a9efd87604e724260f384c/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", size = 160428, upload-time = "2025-08-09T07:55:40.072Z" }, - { url = "https://files.pythonhosted.org/packages/85/9a/d891f63722d9158688de58d050c59dc3da560ea7f04f4c53e769de5140f5/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", size = 157627, upload-time = "2025-08-09T07:55:41.706Z" }, - { url = "https://files.pythonhosted.org/packages/65/1a/7425c952944a6521a9cfa7e675343f83fd82085b8af2b1373a2409c683dc/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", size = 152388, upload-time = "2025-08-09T07:55:43.262Z" }, - { url = "https://files.pythonhosted.org/packages/f0/c9/a2c9c2a355a8594ce2446085e2ec97fd44d323c684ff32042e2a6b718e1d/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", size = 150077, upload-time = "2025-08-09T07:55:44.903Z" }, - { url = "https://files.pythonhosted.org/packages/3b/38/20a1f44e4851aa1c9105d6e7110c9d020e093dfa5836d712a5f074a12bf7/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", size = 161631, upload-time = "2025-08-09T07:55:46.346Z" }, - { url = "https://files.pythonhosted.org/packages/a4/fa/384d2c0f57edad03d7bec3ebefb462090d8905b4ff5a2d2525f3bb711fac/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", size = 159210, upload-time = "2025-08-09T07:55:47.539Z" }, - { url = "https://files.pythonhosted.org/packages/33/9e/eca49d35867ca2db336b6ca27617deed4653b97ebf45dfc21311ce473c37/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", size = 153739, upload-time = "2025-08-09T07:55:48.744Z" }, - { url = "https://files.pythonhosted.org/packages/2a/91/26c3036e62dfe8de8061182d33be5025e2424002125c9500faff74a6735e/charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", size = 99825, upload-time = "2025-08-09T07:55:50.305Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c6/f05db471f81af1fa01839d44ae2a8bfeec8d2a8b4590f16c4e7393afd323/charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", size = 107452, upload-time = "2025-08-09T07:55:51.461Z" }, - { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, - { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, - { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, - { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, - { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, - { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, - { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, - { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, - { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, - { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, - { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, - { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, - { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, - { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, - { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, - { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, - { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, - { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, - { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, - { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, - { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, - { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, - { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, - { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, - { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, - { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, - { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, - { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, - { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, - { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, - { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, - { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, - { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, - { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, - { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, - { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, - { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, - { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, - { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d", size = 209709, upload-time = "2025-10-14T04:40:11.385Z" }, + { url = "https://files.pythonhosted.org/packages/5c/af/1f9d7f7faafe2ddfb6f72a2e07a548a629c61ad510fe60f9630309908fef/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8", size = 148814, upload-time = "2025-10-14T04:40:13.135Z" }, + { url = "https://files.pythonhosted.org/packages/79/3d/f2e3ac2bbc056ca0c204298ea4e3d9db9b4afe437812638759db2c976b5f/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad", size = 144467, upload-time = "2025-10-14T04:40:14.728Z" }, + { url = "https://files.pythonhosted.org/packages/ec/85/1bf997003815e60d57de7bd972c57dc6950446a3e4ccac43bc3070721856/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8", size = 162280, upload-time = "2025-10-14T04:40:16.14Z" }, + { url = "https://files.pythonhosted.org/packages/3e/8e/6aa1952f56b192f54921c436b87f2aaf7c7a7c3d0d1a765547d64fd83c13/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d", size = 159454, upload-time = "2025-10-14T04:40:17.567Z" }, + { url = "https://files.pythonhosted.org/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313", size = 153609, upload-time = "2025-10-14T04:40:19.08Z" }, + { url = "https://files.pythonhosted.org/packages/64/91/6a13396948b8fd3c4b4fd5bc74d045f5637d78c9675585e8e9fbe5636554/charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e", size = 151849, upload-time = "2025-10-14T04:40:20.607Z" }, + { url = "https://files.pythonhosted.org/packages/b7/7a/59482e28b9981d105691e968c544cc0df3b7d6133152fb3dcdc8f135da7a/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93", size = 151586, upload-time = "2025-10-14T04:40:21.719Z" }, + { url = "https://files.pythonhosted.org/packages/92/59/f64ef6a1c4bdd2baf892b04cd78792ed8684fbc48d4c2afe467d96b4df57/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0", size = 145290, upload-time = "2025-10-14T04:40:23.069Z" }, + { url = "https://files.pythonhosted.org/packages/6b/63/3bf9f279ddfa641ffa1962b0db6a57a9c294361cc2f5fcac997049a00e9c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84", size = 163663, upload-time = "2025-10-14T04:40:24.17Z" }, + { url = "https://files.pythonhosted.org/packages/ed/09/c9e38fc8fa9e0849b172b581fd9803bdf6e694041127933934184e19f8c3/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e", size = 151964, upload-time = "2025-10-14T04:40:25.368Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d1/d28b747e512d0da79d8b6a1ac18b7ab2ecfd81b2944c4c710e166d8dd09c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db", size = 161064, upload-time = "2025-10-14T04:40:26.806Z" }, + { url = "https://files.pythonhosted.org/packages/bb/9a/31d62b611d901c3b9e5500c36aab0ff5eb442043fb3a1c254200d3d397d9/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6", size = 155015, upload-time = "2025-10-14T04:40:28.284Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/107e008fa2bff0c8b9319584174418e5e5285fef32f79d8ee6a430d0039c/charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f", size = 99792, upload-time = "2025-10-14T04:40:29.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/66/e396e8a408843337d7315bab30dbf106c38966f1819f123257f5520f8a96/charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d", size = 107198, upload-time = "2025-10-14T04:40:30.644Z" }, + { url = "https://files.pythonhosted.org/packages/b5/58/01b4f815bf0312704c267f2ccb6e5d42bcc7752340cd487bc9f8c3710597/charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69", size = 100262, upload-time = "2025-10-14T04:40:32.108Z" }, + { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, + { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, + { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, + { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, + { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, + { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, + { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, + { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, + { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] [[package]] @@ -334,49 +387,67 @@ wheels = [ [[package]] name = "cryptography" -version = "45.0.6" +version = "46.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d6/0d/d13399c94234ee8f3df384819dc67e0c5ce215fb751d567a55a1f4b028c7/cryptography-45.0.6.tar.gz", hash = "sha256:5c966c732cf6e4a276ce83b6e4c729edda2df6929083a952cc7da973c539c719", size = 744949, upload-time = "2025-08-05T23:59:27.93Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/29/2793d178d0eda1ca4a09a7c4e09a5185e75738cc6d526433e8663b460ea6/cryptography-45.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:048e7ad9e08cf4c0ab07ff7f36cc3115924e22e2266e034450a890d9e312dd74", size = 7042702, upload-time = "2025-08-05T23:58:23.464Z" }, - { url = "https://files.pythonhosted.org/packages/b3/b6/cabd07410f222f32c8d55486c464f432808abaa1f12af9afcbe8f2f19030/cryptography-45.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:44647c5d796f5fc042bbc6d61307d04bf29bccb74d188f18051b635f20a9c75f", size = 4206483, upload-time = "2025-08-05T23:58:27.132Z" }, - { url = "https://files.pythonhosted.org/packages/8b/9e/f9c7d36a38b1cfeb1cc74849aabe9bf817990f7603ff6eb485e0d70e0b27/cryptography-45.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e40b80ecf35ec265c452eea0ba94c9587ca763e739b8e559c128d23bff7ebbbf", size = 4429679, upload-time = "2025-08-05T23:58:29.152Z" }, - { url = "https://files.pythonhosted.org/packages/9c/2a/4434c17eb32ef30b254b9e8b9830cee4e516f08b47fdd291c5b1255b8101/cryptography-45.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:00e8724bdad672d75e6f069b27970883179bd472cd24a63f6e620ca7e41cc0c5", size = 4210553, upload-time = "2025-08-05T23:58:30.596Z" }, - { url = "https://files.pythonhosted.org/packages/ef/1d/09a5df8e0c4b7970f5d1f3aff1b640df6d4be28a64cae970d56c6cf1c772/cryptography-45.0.6-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a3085d1b319d35296176af31c90338eeb2ddac8104661df79f80e1d9787b8b2", size = 3894499, upload-time = "2025-08-05T23:58:32.03Z" }, - { url = "https://files.pythonhosted.org/packages/79/62/120842ab20d9150a9d3a6bdc07fe2870384e82f5266d41c53b08a3a96b34/cryptography-45.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1b7fa6a1c1188c7ee32e47590d16a5a0646270921f8020efc9a511648e1b2e08", size = 4458484, upload-time = "2025-08-05T23:58:33.526Z" }, - { url = "https://files.pythonhosted.org/packages/fd/80/1bc3634d45ddfed0871bfba52cf8f1ad724761662a0c792b97a951fb1b30/cryptography-45.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:275ba5cc0d9e320cd70f8e7b96d9e59903c815ca579ab96c1e37278d231fc402", size = 4210281, upload-time = "2025-08-05T23:58:35.445Z" }, - { url = "https://files.pythonhosted.org/packages/7d/fe/ffb12c2d83d0ee625f124880a1f023b5878f79da92e64c37962bbbe35f3f/cryptography-45.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f4028f29a9f38a2025abedb2e409973709c660d44319c61762202206ed577c42", size = 4456890, upload-time = "2025-08-05T23:58:36.923Z" }, - { url = "https://files.pythonhosted.org/packages/8c/8e/b3f3fe0dc82c77a0deb5f493b23311e09193f2268b77196ec0f7a36e3f3e/cryptography-45.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ee411a1b977f40bd075392c80c10b58025ee5c6b47a822a33c1198598a7a5f05", size = 4333247, upload-time = "2025-08-05T23:58:38.781Z" }, - { url = "https://files.pythonhosted.org/packages/b3/a6/c3ef2ab9e334da27a1d7b56af4a2417d77e7806b2e0f90d6267ce120d2e4/cryptography-45.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e2a21a8eda2d86bb604934b6b37691585bd095c1f788530c1fcefc53a82b3453", size = 4565045, upload-time = "2025-08-05T23:58:40.415Z" }, - { url = "https://files.pythonhosted.org/packages/31/c3/77722446b13fa71dddd820a5faab4ce6db49e7e0bf8312ef4192a3f78e2f/cryptography-45.0.6-cp311-abi3-win32.whl", hash = "sha256:d063341378d7ee9c91f9d23b431a3502fc8bfacd54ef0a27baa72a0843b29159", size = 2928923, upload-time = "2025-08-05T23:58:41.919Z" }, - { url = "https://files.pythonhosted.org/packages/38/63/a025c3225188a811b82932a4dcc8457a26c3729d81578ccecbcce2cb784e/cryptography-45.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:833dc32dfc1e39b7376a87b9a6a4288a10aae234631268486558920029b086ec", size = 3403805, upload-time = "2025-08-05T23:58:43.792Z" }, - { url = "https://files.pythonhosted.org/packages/5b/af/bcfbea93a30809f126d51c074ee0fac5bd9d57d068edf56c2a73abedbea4/cryptography-45.0.6-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:3436128a60a5e5490603ab2adbabc8763613f638513ffa7d311c900a8349a2a0", size = 7020111, upload-time = "2025-08-05T23:58:45.316Z" }, - { url = "https://files.pythonhosted.org/packages/98/c6/ea5173689e014f1a8470899cd5beeb358e22bb3cf5a876060f9d1ca78af4/cryptography-45.0.6-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0d9ef57b6768d9fa58e92f4947cea96ade1233c0e236db22ba44748ffedca394", size = 4198169, upload-time = "2025-08-05T23:58:47.121Z" }, - { url = "https://files.pythonhosted.org/packages/ba/73/b12995edc0c7e2311ffb57ebd3b351f6b268fed37d93bfc6f9856e01c473/cryptography-45.0.6-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea3c42f2016a5bbf71825537c2ad753f2870191134933196bee408aac397b3d9", size = 4421273, upload-time = "2025-08-05T23:58:48.557Z" }, - { url = "https://files.pythonhosted.org/packages/f7/6e/286894f6f71926bc0da67408c853dd9ba953f662dcb70993a59fd499f111/cryptography-45.0.6-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:20ae4906a13716139d6d762ceb3e0e7e110f7955f3bc3876e3a07f5daadec5f3", size = 4199211, upload-time = "2025-08-05T23:58:50.139Z" }, - { url = "https://files.pythonhosted.org/packages/de/34/a7f55e39b9623c5cb571d77a6a90387fe557908ffc44f6872f26ca8ae270/cryptography-45.0.6-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dac5ec199038b8e131365e2324c03d20e97fe214af051d20c49db129844e8b3", size = 3883732, upload-time = "2025-08-05T23:58:52.253Z" }, - { url = "https://files.pythonhosted.org/packages/f9/b9/c6d32edbcba0cd9f5df90f29ed46a65c4631c4fbe11187feb9169c6ff506/cryptography-45.0.6-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:18f878a34b90d688982e43f4b700408b478102dd58b3e39de21b5ebf6509c301", size = 4450655, upload-time = "2025-08-05T23:58:53.848Z" }, - { url = "https://files.pythonhosted.org/packages/77/2d/09b097adfdee0227cfd4c699b3375a842080f065bab9014248933497c3f9/cryptography-45.0.6-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5bd6020c80c5b2b2242d6c48487d7b85700f5e0038e67b29d706f98440d66eb5", size = 4198956, upload-time = "2025-08-05T23:58:55.209Z" }, - { url = "https://files.pythonhosted.org/packages/55/66/061ec6689207d54effdff535bbdf85cc380d32dd5377173085812565cf38/cryptography-45.0.6-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:eccddbd986e43014263eda489abbddfbc287af5cddfd690477993dbb31e31016", size = 4449859, upload-time = "2025-08-05T23:58:56.639Z" }, - { url = "https://files.pythonhosted.org/packages/41/ff/e7d5a2ad2d035e5a2af116e1a3adb4d8fcd0be92a18032917a089c6e5028/cryptography-45.0.6-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:550ae02148206beb722cfe4ef0933f9352bab26b087af00e48fdfb9ade35c5b3", size = 4320254, upload-time = "2025-08-05T23:58:58.833Z" }, - { url = "https://files.pythonhosted.org/packages/82/27/092d311af22095d288f4db89fcaebadfb2f28944f3d790a4cf51fe5ddaeb/cryptography-45.0.6-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5b64e668fc3528e77efa51ca70fadcd6610e8ab231e3e06ae2bab3b31c2b8ed9", size = 4554815, upload-time = "2025-08-05T23:59:00.283Z" }, - { url = "https://files.pythonhosted.org/packages/7e/01/aa2f4940262d588a8fdf4edabe4cda45854d00ebc6eaac12568b3a491a16/cryptography-45.0.6-cp37-abi3-win32.whl", hash = "sha256:780c40fb751c7d2b0c6786ceee6b6f871e86e8718a8ff4bc35073ac353c7cd02", size = 2912147, upload-time = "2025-08-05T23:59:01.716Z" }, - { url = "https://files.pythonhosted.org/packages/0a/bc/16e0276078c2de3ceef6b5a34b965f4436215efac45313df90d55f0ba2d2/cryptography-45.0.6-cp37-abi3-win_amd64.whl", hash = "sha256:20d15aed3ee522faac1a39fbfdfee25d17b1284bafd808e1640a74846d7c4d1b", size = 3390459, upload-time = "2025-08-05T23:59:03.358Z" }, - { url = "https://files.pythonhosted.org/packages/56/d2/4482d97c948c029be08cb29854a91bd2ae8da7eb9c4152461f1244dcea70/cryptography-45.0.6-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:705bb7c7ecc3d79a50f236adda12ca331c8e7ecfbea51edd931ce5a7a7c4f012", size = 3576812, upload-time = "2025-08-05T23:59:04.833Z" }, - { url = "https://files.pythonhosted.org/packages/ec/24/55fc238fcaa122855442604b8badb2d442367dfbd5a7ca4bb0bd346e263a/cryptography-45.0.6-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:826b46dae41a1155a0c0e66fafba43d0ede1dc16570b95e40c4d83bfcf0a451d", size = 4141694, upload-time = "2025-08-05T23:59:06.66Z" }, - { url = "https://files.pythonhosted.org/packages/f9/7e/3ea4fa6fbe51baf3903806a0241c666b04c73d2358a3ecce09ebee8b9622/cryptography-45.0.6-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cc4d66f5dc4dc37b89cfef1bd5044387f7a1f6f0abb490815628501909332d5d", size = 4375010, upload-time = "2025-08-05T23:59:08.14Z" }, - { url = "https://files.pythonhosted.org/packages/50/42/ec5a892d82d2a2c29f80fc19ced4ba669bca29f032faf6989609cff1f8dc/cryptography-45.0.6-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f68f833a9d445cc49f01097d95c83a850795921b3f7cc6488731e69bde3288da", size = 4141377, upload-time = "2025-08-05T23:59:09.584Z" }, - { url = "https://files.pythonhosted.org/packages/e7/d7/246c4c973a22b9c2931999da953a2c19cae7c66b9154c2d62ffed811225e/cryptography-45.0.6-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:3b5bf5267e98661b9b888a9250d05b063220dfa917a8203744454573c7eb79db", size = 4374609, upload-time = "2025-08-05T23:59:11.923Z" }, - { url = "https://files.pythonhosted.org/packages/78/6d/c49ccf243f0a1b0781c2a8de8123ee552f0c8a417c6367a24d2ecb7c11b3/cryptography-45.0.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2384f2ab18d9be88a6e4f8972923405e2dbb8d3e16c6b43f15ca491d7831bd18", size = 3322156, upload-time = "2025-08-05T23:59:13.597Z" }, - { url = "https://files.pythonhosted.org/packages/61/69/c252de4ec047ba2f567ecb53149410219577d408c2aea9c989acae7eafce/cryptography-45.0.6-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fc022c1fa5acff6def2fc6d7819bbbd31ccddfe67d075331a65d9cfb28a20983", size = 3584669, upload-time = "2025-08-05T23:59:15.431Z" }, - { url = "https://files.pythonhosted.org/packages/e3/fe/deea71e9f310a31fe0a6bfee670955152128d309ea2d1c79e2a5ae0f0401/cryptography-45.0.6-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3de77e4df42ac8d4e4d6cdb342d989803ad37707cf8f3fbf7b088c9cbdd46427", size = 4153022, upload-time = "2025-08-05T23:59:16.954Z" }, - { url = "https://files.pythonhosted.org/packages/60/45/a77452f5e49cb580feedba6606d66ae7b82c128947aa754533b3d1bd44b0/cryptography-45.0.6-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:599c8d7df950aa68baa7e98f7b73f4f414c9f02d0e8104a30c0182a07732638b", size = 4386802, upload-time = "2025-08-05T23:59:18.55Z" }, - { url = "https://files.pythonhosted.org/packages/a3/b9/a2f747d2acd5e3075fdf5c145c7c3568895daaa38b3b0c960ef830db6cdc/cryptography-45.0.6-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:31a2b9a10530a1cb04ffd6aa1cd4d3be9ed49f7d77a4dafe198f3b382f41545c", size = 4152706, upload-time = "2025-08-05T23:59:20.044Z" }, - { url = "https://files.pythonhosted.org/packages/81/ec/381b3e8d0685a3f3f304a382aa3dfce36af2d76467da0fd4bb21ddccc7b2/cryptography-45.0.6-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:e5b3dda1b00fb41da3af4c5ef3f922a200e33ee5ba0f0bc9ecf0b0c173958385", size = 4386740, upload-time = "2025-08-05T23:59:21.525Z" }, - { url = "https://files.pythonhosted.org/packages/0a/76/cf8d69da8d0b5ecb0db406f24a63a3f69ba5e791a11b782aeeefef27ccbb/cryptography-45.0.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:629127cfdcdc6806dfe234734d7cb8ac54edaf572148274fa377a7d3405b0043", size = 3331874, upload-time = "2025-08-05T23:59:23.017Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload-time = "2025-10-15T23:18:31.74Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004, upload-time = "2025-10-15T23:16:52.239Z" }, + { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667, upload-time = "2025-10-15T23:16:54.369Z" }, + { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807, upload-time = "2025-10-15T23:16:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615, upload-time = "2025-10-15T23:16:58.442Z" }, + { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800, upload-time = "2025-10-15T23:17:00.378Z" }, + { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707, upload-time = "2025-10-15T23:17:01.98Z" }, + { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541, upload-time = "2025-10-15T23:17:04.078Z" }, + { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464, upload-time = "2025-10-15T23:17:05.483Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838, upload-time = "2025-10-15T23:17:07.425Z" }, + { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596, upload-time = "2025-10-15T23:17:09.343Z" }, + { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782, upload-time = "2025-10-15T23:17:11.22Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381, upload-time = "2025-10-15T23:17:12.829Z" }, + { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988, upload-time = "2025-10-15T23:17:14.65Z" }, + { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451, upload-time = "2025-10-15T23:17:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007, upload-time = "2025-10-15T23:17:18.04Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012, upload-time = "2025-10-15T23:17:19.982Z" }, + { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728, upload-time = "2025-10-15T23:17:21.527Z" }, + { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078, upload-time = "2025-10-15T23:17:23.042Z" }, + { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460, upload-time = "2025-10-15T23:17:24.885Z" }, + { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237, upload-time = "2025-10-15T23:17:26.449Z" }, + { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344, upload-time = "2025-10-15T23:17:28.06Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564, upload-time = "2025-10-15T23:17:29.665Z" }, + { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415, upload-time = "2025-10-15T23:17:31.686Z" }, + { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457, upload-time = "2025-10-15T23:17:33.478Z" }, + { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074, upload-time = "2025-10-15T23:17:35.158Z" }, + { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569, upload-time = "2025-10-15T23:17:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941, upload-time = "2025-10-15T23:17:39.236Z" }, + { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339, upload-time = "2025-10-15T23:17:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315, upload-time = "2025-10-15T23:17:42.769Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331, upload-time = "2025-10-15T23:17:44.468Z" }, + { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248, upload-time = "2025-10-15T23:17:46.294Z" }, + { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089, upload-time = "2025-10-15T23:17:48.269Z" }, + { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029, upload-time = "2025-10-15T23:17:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222, upload-time = "2025-10-15T23:17:51.357Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280, upload-time = "2025-10-15T23:17:52.964Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958, upload-time = "2025-10-15T23:17:54.965Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714, upload-time = "2025-10-15T23:17:56.754Z" }, + { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970, upload-time = "2025-10-15T23:17:58.588Z" }, + { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236, upload-time = "2025-10-15T23:18:00.897Z" }, + { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642, upload-time = "2025-10-15T23:18:02.749Z" }, + { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126, upload-time = "2025-10-15T23:18:04.85Z" }, + { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload-time = "2025-10-15T23:18:06.908Z" }, + { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695, upload-time = "2025-10-15T23:18:08.672Z" }, + { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720, upload-time = "2025-10-15T23:18:10.632Z" }, + { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740, upload-time = "2025-10-15T23:18:12.277Z" }, + { url = "https://files.pythonhosted.org/packages/d9/cd/1a8633802d766a0fa46f382a77e096d7e209e0817892929655fe0586ae32/cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32", size = 3689163, upload-time = "2025-10-15T23:18:13.821Z" }, + { url = "https://files.pythonhosted.org/packages/4c/59/6b26512964ace6480c3e54681a9859c974172fb141c38df11eadd8416947/cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c", size = 3429474, upload-time = "2025-10-15T23:18:15.477Z" }, + { url = "https://files.pythonhosted.org/packages/06/8a/e60e46adab4362a682cf142c7dcb5bf79b782ab2199b0dcb81f55970807f/cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea", size = 3698132, upload-time = "2025-10-15T23:18:17.056Z" }, + { url = "https://files.pythonhosted.org/packages/da/38/f59940ec4ee91e93d3311f7532671a5cef5570eb04a144bf203b58552d11/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b", size = 4243992, upload-time = "2025-10-15T23:18:18.695Z" }, + { url = "https://files.pythonhosted.org/packages/b0/0c/35b3d92ddebfdfda76bb485738306545817253d0a3ded0bfe80ef8e67aa5/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb", size = 4409944, upload-time = "2025-10-15T23:18:20.597Z" }, + { url = "https://files.pythonhosted.org/packages/99/55/181022996c4063fc0e7666a47049a1ca705abb9c8a13830f074edb347495/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717", size = 4242957, upload-time = "2025-10-15T23:18:22.18Z" }, + { url = "https://files.pythonhosted.org/packages/ba/af/72cd6ef29f9c5f731251acadaeb821559fe25f10852f44a63374c9ca08c1/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9", size = 4409447, upload-time = "2025-10-15T23:18:24.209Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c3/e90f4a4feae6410f914f8ebac129b9ae7a8c92eb60a638012dde42030a9d/cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c", size = 3438528, upload-time = "2025-10-15T23:18:26.227Z" }, ] [[package]] @@ -390,11 +461,11 @@ wheels = [ [[package]] name = "docutils" -version = "0.22" +version = "0.22.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e9/86/5b41c32ecedcfdb4c77b28b6cb14234f252075f8cdb254531727a35547dd/docutils-0.22.tar.gz", hash = "sha256:ba9d57750e92331ebe7c08a1bbf7a7f8143b86c476acd51528b042216a6aad0f", size = 2277984, upload-time = "2025-07-29T15:20:31.06Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/c0/89fe6215b443b919cb98a5002e107cb5026854ed1ccb6b5833e0768419d1/docutils-0.22.2.tar.gz", hash = "sha256:9fdb771707c8784c8f2728b67cb2c691305933d68137ef95a75db5f4dfbc213d", size = 2289092, upload-time = "2025-09-20T17:55:47.994Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/57/8db39bc5f98f042e0153b1de9fb88e1a409a33cda4dd7f723c2ed71e01f6/docutils-0.22-py3-none-any.whl", hash = "sha256:4ed966a0e96a0477d852f7af31bdcb3adc049fbb35ccba358c2ea8a03287615e", size = 630709, upload-time = "2025-07-29T15:20:28.335Z" }, + { url = "https://files.pythonhosted.org/packages/66/dd/f95350e853a4468ec37478414fc04ae2d61dad7a947b3015c3dcc51a09b9/docutils-0.22.2-py3-none-any.whl", hash = "sha256:b0e98d679283fc3bb0ead8a5da7f501baa632654e7056e9c5846842213d674d8", size = 632667, upload-time = "2025-09-20T17:55:43.052Z" }, ] [[package]] @@ -420,11 +491,11 @@ wheels = [ [[package]] name = "filelock" -version = "3.19.1" +version = "3.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, ] [[package]] @@ -478,7 +549,7 @@ wheels = [ [[package]] name = "google-api-core" -version = "2.25.1" +version = "2.26.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-auth" }, @@ -487,14 +558,14 @@ dependencies = [ { name = "protobuf" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/dc/21/e9d043e88222317afdbdb567165fdbc3b0aad90064c7e0c9eb0ad9955ad8/google_api_core-2.25.1.tar.gz", hash = "sha256:d2aaa0b13c78c61cb3f4282c464c046e45fbd75755683c9c525e6e8f7ed0a5e8", size = 165443, upload-time = "2025-06-12T20:52:20.439Z" } +sdist = { url = "https://files.pythonhosted.org/packages/32/ea/e7b6ac3c7b557b728c2d0181010548cbbdd338e9002513420c5a354fa8df/google_api_core-2.26.0.tar.gz", hash = "sha256:e6e6d78bd6cf757f4aee41dcc85b07f485fbb069d5daa3afb126defba1e91a62", size = 166369, upload-time = "2025-10-08T21:37:38.39Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/4b/ead00905132820b623732b175d66354e9d3e69fcf2a5dcdab780664e7896/google_api_core-2.25.1-py3-none-any.whl", hash = "sha256:8a2a56c1fef82987a524371f99f3bd0143702fecc670c72e600c1cda6bf8dbb7", size = 160807, upload-time = "2025-06-12T20:52:19.334Z" }, + { url = "https://files.pythonhosted.org/packages/77/ad/f73cf9fe9bd95918502b270e3ddb8764e4c900b3bbd7782b90c56fac14bb/google_api_core-2.26.0-py3-none-any.whl", hash = "sha256:2b204bd0da2c81f918e3582c48458e24c11771f987f6258e6e227212af78f3ed", size = 162505, upload-time = "2025-10-08T21:37:36.651Z" }, ] [[package]] name = "google-api-python-client" -version = "2.179.0" +version = "2.185.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core" }, @@ -503,23 +574,23 @@ dependencies = [ { name = "httplib2" }, { name = "uritemplate" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/73/ed/6e7865324252ea0a9f7c8171a3a00439a1e8447a5dc08e6d6c483777bb38/google_api_python_client-2.179.0.tar.gz", hash = "sha256:76a774a49dd58af52e74ce7114db387e58f0aaf6760c9cf9201ab6d731d8bd8d", size = 13397672, upload-time = "2025-08-13T18:45:28.838Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5a/6f9b49d67ea91376305fdb8bbf2877c746d756e45fd8fb7d2e32d6dad19b/google_api_python_client-2.185.0.tar.gz", hash = "sha256:aa1b338e4bb0f141c2df26743f6b46b11f38705aacd775b61971cbc51da089c3", size = 13885609, upload-time = "2025-10-17T15:00:35.623Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d4/2568d5d907582cc145f3ffede43879746fd4b331308088a0fc57f7ecdbca/google_api_python_client-2.179.0-py3-none-any.whl", hash = "sha256:79ab5039d70c59dab874fd18333fca90fb469be51c96113cb133e5fc1f0b2a79", size = 13955142, upload-time = "2025-08-13T18:45:25.944Z" }, + { url = "https://files.pythonhosted.org/packages/fa/28/be3b17bd6a190c8c2ec9e4fb65d43e6ecd7b7a1bb19ccc1d9ab4f687a58c/google_api_python_client-2.185.0-py3-none-any.whl", hash = "sha256:00fe173a4b346d2397fbe0d37ac15368170dfbed91a0395a66ef2558e22b93fc", size = 14453595, upload-time = "2025-10-17T15:00:33.176Z" }, ] [[package]] name = "google-auth" -version = "2.40.3" +version = "2.41.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cachetools" }, { name = "pyasn1-modules" }, { name = "rsa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/9b/e92ef23b84fa10a64ce4831390b7a4c2e53c0132568d99d4ae61d04c8855/google_auth-2.40.3.tar.gz", hash = "sha256:500c3a29adedeb36ea9cf24b8d10858e152f2412e3ca37829b3fa18e33d63b77", size = 281029, upload-time = "2025-06-04T18:04:57.577Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a8/af/5129ce5b2f9688d2fa49b463e544972a7c82b0fdb50980dafee92e121d9f/google_auth-2.41.1.tar.gz", hash = "sha256:b76b7b1f9e61f0cb7e88870d14f6a94aeef248959ef6992670efee37709cbfd2", size = 292284, upload-time = "2025-09-30T22:51:26.363Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/63/b19553b658a1692443c62bd07e5868adaa0ad746a0751ba62c59568cd45b/google_auth-2.40.3-py2.py3-none-any.whl", hash = "sha256:1370d4593e86213563547f97a92752fc658456fe4514c809544f330fed45a7ca", size = 216137, upload-time = "2025-06-04T18:04:55.573Z" }, + { url = "https://files.pythonhosted.org/packages/be/a4/7319a2a8add4cc352be9e3efeff5e2aacee917c85ca2fa1647e29089983c/google_auth-2.41.1-py2.py3-none-any.whl", hash = "sha256:754843be95575b9a19c604a848a41be03f7f2afd8c019f716dc1f51ee41c639d", size = 221302, upload-time = "2025-09-30T22:51:24.212Z" }, ] [[package]] @@ -571,7 +642,7 @@ wheels = [ [[package]] name = "hatch" -version = "1.14.1" +version = "1.15.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -591,9 +662,9 @@ dependencies = [ { name = "virtualenv" }, { name = "zstandard" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1f/43/c0b37db0e857a44ce5ffdb7e8a9b8fa6425d0b74dea698fafcd9bddb50d1/hatch-1.14.1.tar.gz", hash = "sha256:ca1aff788f8596b0dd1f8f8dfe776443d2724a86b1976fabaf087406ba3d0713", size = 5188180, upload-time = "2025-04-07T04:16:04.522Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/30/a7f19d337df93fb15dec6892e9ae678acd4ae10ce03d02722f17c7fe513b/hatch-1.15.1.tar.gz", hash = "sha256:444a78123c9837e8c9f5adfbf2b8b0a72139587eb49d6b368038b0521136fc43", size = 5189156, upload-time = "2025-10-16T20:35:54.616Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/40/19c0935bf9f25808541a0e3144ac459de696c5b6b6d4511a98d456c69604/hatch-1.14.1-py3-none-any.whl", hash = "sha256:39cdaa59e47ce0c5505d88a951f4324a9c5aafa17e4a877e2fde79b36ab66c21", size = 125770, upload-time = "2025-04-07T04:16:02.525Z" }, + { url = "https://files.pythonhosted.org/packages/69/01/316ef533114e0de0649e2e925ae2f97dfe26fbe5358f678e84b2a5fa1407/hatch-1.15.1-py3-none-any.whl", hash = "sha256:99dccb26b00226056142f89d6e286be61e2d7b5b5b4e6178ebbe9298c1bc45d9", size = 126295, upload-time = "2025-10-16T20:35:52.354Z" }, ] [[package]] @@ -627,14 +698,14 @@ wheels = [ [[package]] name = "httplib2" -version = "0.22.0" +version = "0.31.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyparsing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3d/ad/2371116b22d616c194aa25ec410c9c6c37f23599dcd590502b74db197584/httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81", size = 351116, upload-time = "2023-03-21T22:29:37.214Z" } +sdist = { url = "https://files.pythonhosted.org/packages/52/77/6653db69c1f7ecfe5e3f9726fdadc981794656fcd7d98c4209fecfea9993/httplib2-0.31.0.tar.gz", hash = "sha256:ac7ab497c50975147d4f7b1ade44becc7df2f8954d42b38b3d69c515f531135c", size = 250759, upload-time = "2025-09-11T12:16:03.403Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/6c/d2fbdaaa5959339d53ba38e94c123e4e84b8fbc4b84beb0e70d7c1608486/httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc", size = 96854, upload-time = "2023-03-21T22:29:35.683Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a2/0d269db0f6163be503775dc8b6a6fa15820cc9fdc866f6ba608d86b721f2/httplib2-0.31.0-py3-none-any.whl", hash = "sha256:b9cd78abea9b4e43a7714c6e0f8b6b8561a6fc1e95d5dbd367f5bf0ef35f5d24", size = 91148, upload-time = "2025-09-11T12:16:01.803Z" }, ] [[package]] @@ -678,11 +749,11 @@ wheels = [ [[package]] name = "idna" -version = "3.10" +version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] [[package]] @@ -699,11 +770,11 @@ wheels = [ [[package]] name = "iniconfig" -version = "2.1.0" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] @@ -740,14 +811,14 @@ wheels = [ [[package]] name = "jaraco-functools" -version = "4.2.1" +version = "4.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "more-itertools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/49/1c/831faaaa0f090b711c355c6d8b2abf277c72133aab472b6932b03322294c/jaraco_functools-4.2.1.tar.gz", hash = "sha256:be634abfccabce56fa3053f8c7ebe37b682683a4ee7793670ced17bab0087353", size = 19661, upload-time = "2025-06-21T19:22:03.201Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/ed/1aa2d585304ec07262e1a83a9889880701079dde796ac7b1d1826f40c63d/jaraco_functools-4.3.0.tar.gz", hash = "sha256:cfd13ad0dd2c47a3600b439ef72d8615d482cedcff1632930d6f28924d92f294", size = 19755, upload-time = "2025-08-18T20:05:09.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/fd/179a20f832824514df39a90bb0e5372b314fea99f217f5ab942b10a8a4e8/jaraco_functools-4.2.1-py3-none-any.whl", hash = "sha256:590486285803805f4b1f99c60ca9e94ed348d4added84b74c7a12885561e524e", size = 10349, upload-time = "2025-06-21T19:22:02.039Z" }, + { url = "https://files.pythonhosted.org/packages/b4/09/726f168acad366b11e420df31bf1c702a54d373a83f968d94141a8c3fde0/jaraco_functools-4.3.0-py3-none-any.whl", hash = "sha256:227ff8ed6f7b8f62c56deff101545fa7543cf2c8e7b82a7c2116e672f29c26e8", size = 10408, upload-time = "2025-08-18T20:05:08.69Z" }, ] [[package]] @@ -782,7 +853,7 @@ wheels = [ [[package]] name = "jsonschema" -version = "4.25.0" +version = "4.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, @@ -790,21 +861,21 @@ dependencies = [ { name = "referencing" }, { name = "rpds-py" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d5/00/a297a868e9d0784450faa7365c2172a7d6110c763e30ba861867c32ae6a9/jsonschema-4.25.0.tar.gz", hash = "sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f", size = 356830, upload-time = "2025-07-18T15:39:45.11Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/69/f7185de793a29082a9f3c7728268ffb31cb5095131a9c139a74078e27336/jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85", size = 357342, upload-time = "2025-08-18T17:03:50.038Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/54/c86cd8e011fe98803d7e382fd67c0df5ceab8d2b7ad8c5a81524f791551c/jsonschema-4.25.0-py3-none-any.whl", hash = "sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716", size = 89184, upload-time = "2025-07-18T15:39:42.956Z" }, + { url = "https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63", size = 90040, upload-time = "2025-08-18T17:03:48.373Z" }, ] [[package]] name = "jsonschema-specifications" -version = "2025.4.1" +version = "2025.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" }, + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] [[package]] @@ -839,60 +910,87 @@ wheels = [ [[package]] name = "markupsafe" -version = "3.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357, upload-time = "2024-10-18T15:20:51.44Z" }, - { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393, upload-time = "2024-10-18T15:20:52.426Z" }, - { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732, upload-time = "2024-10-18T15:20:53.578Z" }, - { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866, upload-time = "2024-10-18T15:20:55.06Z" }, - { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964, upload-time = "2024-10-18T15:20:55.906Z" }, - { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977, upload-time = "2024-10-18T15:20:57.189Z" }, - { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366, upload-time = "2024-10-18T15:20:58.235Z" }, - { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091, upload-time = "2024-10-18T15:20:59.235Z" }, - { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065, upload-time = "2024-10-18T15:21:00.307Z" }, - { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514, upload-time = "2024-10-18T15:21:01.122Z" }, - { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, - { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, - { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, - { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, - { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, - { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, - { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, - { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559", size = 11631, upload-time = "2025-09-27T18:36:05.558Z" }, + { url = "https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419", size = 12057, upload-time = "2025-09-27T18:36:07.165Z" }, + { url = "https://files.pythonhosted.org/packages/40/01/e560d658dc0bb8ab762670ece35281dec7b6c1b33f5fbc09ebb57a185519/markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695", size = 22050, upload-time = "2025-09-27T18:36:08.005Z" }, + { url = "https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591", size = 20681, upload-time = "2025-09-27T18:36:08.881Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2a/b5c12c809f1c3045c4d580b035a743d12fcde53cf685dbc44660826308da/markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c", size = 20705, upload-time = "2025-09-27T18:36:10.131Z" }, + { url = "https://files.pythonhosted.org/packages/cf/e3/9427a68c82728d0a88c50f890d0fc072a1484de2f3ac1ad0bfc1a7214fd5/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f", size = 21524, upload-time = "2025-09-27T18:36:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/bc/36/23578f29e9e582a4d0278e009b38081dbe363c5e7165113fad546918a232/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6", size = 20282, upload-time = "2025-09-27T18:36:12.573Z" }, + { url = "https://files.pythonhosted.org/packages/56/21/dca11354e756ebd03e036bd8ad58d6d7168c80ce1fe5e75218e4945cbab7/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1", size = 20745, upload-time = "2025-09-27T18:36:13.504Z" }, + { url = "https://files.pythonhosted.org/packages/87/99/faba9369a7ad6e4d10b6a5fbf71fa2a188fe4a593b15f0963b73859a1bbd/markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa", size = 14571, upload-time = "2025-09-27T18:36:14.779Z" }, + { url = "https://files.pythonhosted.org/packages/d6/25/55dc3ab959917602c96985cb1253efaa4ff42f71194bddeb61eb7278b8be/markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8", size = 15056, upload-time = "2025-09-27T18:36:16.125Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9e/0a02226640c255d1da0b8d12e24ac2aa6734da68bff14c05dd53b94a0fc3/markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1", size = 13932, upload-time = "2025-09-27T18:36:17.311Z" }, + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] @@ -906,11 +1004,11 @@ wheels = [ [[package]] name = "more-itertools" -version = "10.7.0" +version = "10.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ce/a0/834b0cebabbfc7e311f30b46c8188790a37f89fc8d756660346fe5abfd09/more_itertools-10.7.0.tar.gz", hash = "sha256:9fddd5403be01a94b204faadcff459ec3568cf110265d3c54323e1e866ad29d3", size = 127671, upload-time = "2025-04-22T14:17:41.838Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ea/5d/38b681d3fce7a266dd9ab73c66959406d565b3e85f21d5e66e1181d93721/more_itertools-10.8.0.tar.gz", hash = "sha256:f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd", size = 137431, upload-time = "2025-09-02T15:23:11.018Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/9f/7ba6f94fc1e9ac3d2b853fdff3035fb2fa5afbed898c4a72b8a020610594/more_itertools-10.7.0-py3-none-any.whl", hash = "sha256:d43980384673cb07d2f7d2d918c616b30c659c089ee23953f601d6609c67510e", size = 65278, upload-time = "2025-04-22T14:17:40.49Z" }, + { url = "https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl", hash = "sha256:52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b", size = 69667, upload-time = "2025-09-02T15:23:09.635Z" }, ] [[package]] @@ -924,35 +1022,35 @@ wheels = [ [[package]] name = "nh3" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/a4/96cff0977357f60f06ec4368c4c7a7a26cccfe7c9fcd54f5378bf0428fd3/nh3-0.3.0.tar.gz", hash = "sha256:d8ba24cb31525492ea71b6aac11a4adac91d828aadeff7c4586541bf5dc34d2f", size = 19655, upload-time = "2025-07-17T14:43:37.05Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/11/340b7a551916a4b2b68c54799d710f86cf3838a4abaad8e74d35360343bb/nh3-0.3.0-cp313-cp313t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a537ece1bf513e5a88d8cff8a872e12fe8d0f42ef71dd15a5e7520fecd191bbb", size = 1427992, upload-time = "2025-07-17T14:43:06.848Z" }, - { url = "https://files.pythonhosted.org/packages/ad/7f/7c6b8358cf1222921747844ab0eef81129e9970b952fcb814df417159fb9/nh3-0.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c915060a2c8131bef6a29f78debc29ba40859b6dbe2362ef9e5fd44f11487c2", size = 798194, upload-time = "2025-07-17T14:43:08.263Z" }, - { url = "https://files.pythonhosted.org/packages/63/da/c5fd472b700ba37d2df630a9e0d8cc156033551ceb8b4c49cc8a5f606b68/nh3-0.3.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba0caa8aa184196daa6e574d997a33867d6d10234018012d35f86d46024a2a95", size = 837884, upload-time = "2025-07-17T14:43:09.233Z" }, - { url = "https://files.pythonhosted.org/packages/4c/3c/cba7b26ccc0ef150c81646478aa32f9c9535234f54845603c838a1dc955c/nh3-0.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:80fe20171c6da69c7978ecba33b638e951b85fb92059259edd285ff108b82a6d", size = 996365, upload-time = "2025-07-17T14:43:10.243Z" }, - { url = "https://files.pythonhosted.org/packages/f3/ba/59e204d90727c25b253856e456ea61265ca810cda8ee802c35f3fadaab00/nh3-0.3.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e90883f9f85288f423c77b3f5a6f4486375636f25f793165112679a7b6363b35", size = 1071042, upload-time = "2025-07-17T14:43:11.57Z" }, - { url = "https://files.pythonhosted.org/packages/10/71/2fb1834c10fab6d9291d62c95192ea2f4c7518bd32ad6c46aab5d095cb87/nh3-0.3.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0649464ac8eee018644aacbc103874ccbfac80e3035643c3acaab4287e36e7f5", size = 995737, upload-time = "2025-07-17T14:43:12.659Z" }, - { url = "https://files.pythonhosted.org/packages/33/c1/8f8ccc2492a000b6156dce68a43253fcff8b4ce70ab4216d08f90a2ac998/nh3-0.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1adeb1062a1c2974bc75b8d1ecb014c5fd4daf2df646bbe2831f7c23659793f9", size = 980552, upload-time = "2025-07-17T14:43:13.763Z" }, - { url = "https://files.pythonhosted.org/packages/2f/d6/f1c6e091cbe8700401c736c2bc3980c46dca770a2cf6a3b48a175114058e/nh3-0.3.0-cp313-cp313t-win32.whl", hash = "sha256:7275fdffaab10cc5801bf026e3c089d8de40a997afc9e41b981f7ac48c5aa7d5", size = 593618, upload-time = "2025-07-17T14:43:15.098Z" }, - { url = "https://files.pythonhosted.org/packages/23/1e/80a8c517655dd40bb13363fc4d9e66b2f13245763faab1a20f1df67165a7/nh3-0.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:423201bbdf3164a9e09aa01e540adbb94c9962cc177d5b1cbb385f5e1e79216e", size = 598948, upload-time = "2025-07-17T14:43:16.064Z" }, - { url = "https://files.pythonhosted.org/packages/9a/e0/af86d2a974c87a4ba7f19bc3b44a8eaa3da480de264138fec82fe17b340b/nh3-0.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:16f8670201f7e8e0e05ed1a590eb84bfa51b01a69dd5caf1d3ea57733de6a52f", size = 580479, upload-time = "2025-07-17T14:43:17.038Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e0/cf1543e798ba86d838952e8be4cb8d18e22999be2a24b112a671f1c04fd6/nh3-0.3.0-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:ec6cfdd2e0399cb79ba4dcffb2332b94d9696c52272ff9d48a630c5dca5e325a", size = 1442218, upload-time = "2025-07-17T14:43:18.087Z" }, - { url = "https://files.pythonhosted.org/packages/5c/86/a96b1453c107b815f9ab8fac5412407c33cc5c7580a4daf57aabeb41b774/nh3-0.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5e7185599f89b0e391e2f29cc12dc2e206167380cea49b33beda4891be2fe1", size = 823791, upload-time = "2025-07-17T14:43:19.721Z" }, - { url = "https://files.pythonhosted.org/packages/97/33/11e7273b663839626f714cb68f6eb49899da5a0d9b6bc47b41fe870259c2/nh3-0.3.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:389d93d59b8214d51c400fb5b07866c2a4f79e4e14b071ad66c92184fec3a392", size = 811143, upload-time = "2025-07-17T14:43:20.779Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1b/b15bd1ce201a1a610aeb44afd478d55ac018b4475920a3118ffd806e2483/nh3-0.3.0-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e9e6a7e4d38f7e8dda9edd1433af5170c597336c1a74b4693c5cb75ab2b30f2a", size = 1064661, upload-time = "2025-07-17T14:43:21.839Z" }, - { url = "https://files.pythonhosted.org/packages/8f/14/079670fb2e848c4ba2476c5a7a2d1319826053f4f0368f61fca9bb4227ae/nh3-0.3.0-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7852f038a054e0096dac12b8141191e02e93e0b4608c4b993ec7d4ffafea4e49", size = 997061, upload-time = "2025-07-17T14:43:23.179Z" }, - { url = "https://files.pythonhosted.org/packages/a3/e5/ac7fc565f5d8bce7f979d1afd68e8cb415020d62fa6507133281c7d49f91/nh3-0.3.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af5aa8127f62bbf03d68f67a956627b1bd0469703a35b3dad28d0c1195e6c7fb", size = 924761, upload-time = "2025-07-17T14:43:24.23Z" }, - { url = "https://files.pythonhosted.org/packages/39/2c/6394301428b2017a9d5644af25f487fa557d06bc8a491769accec7524d9a/nh3-0.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f416c35efee3e6a6c9ab7716d9e57aa0a49981be915963a82697952cba1353e1", size = 803959, upload-time = "2025-07-17T14:43:26.377Z" }, - { url = "https://files.pythonhosted.org/packages/4e/9a/344b9f9c4bd1c2413a397f38ee6a3d5db30f1a507d4976e046226f12b297/nh3-0.3.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:37d3003d98dedca6cd762bf88f2e70b67f05100f6b949ffe540e189cc06887f9", size = 844073, upload-time = "2025-07-17T14:43:27.375Z" }, - { url = "https://files.pythonhosted.org/packages/66/3f/cd37f76c8ca277b02a84aa20d7bd60fbac85b4e2cbdae77cb759b22de58b/nh3-0.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:634e34e6162e0408e14fb61d5e69dbaea32f59e847cfcfa41b66100a6b796f62", size = 1000680, upload-time = "2025-07-17T14:43:28.452Z" }, - { url = "https://files.pythonhosted.org/packages/ee/db/7aa11b44bae4e7474feb1201d8dee04fabe5651c7cb51409ebda94a4ed67/nh3-0.3.0-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:b0612ccf5de8a480cf08f047b08f9d3fecc12e63d2ee91769cb19d7290614c23", size = 1076613, upload-time = "2025-07-17T14:43:30.031Z" }, - { url = "https://files.pythonhosted.org/packages/97/03/03f79f7e5178eb1ad5083af84faff471e866801beb980cc72943a4397368/nh3-0.3.0-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c7a32a7f0d89f7d30cb8f4a84bdbd56d1eb88b78a2434534f62c71dac538c450", size = 1001418, upload-time = "2025-07-17T14:43:31.429Z" }, - { url = "https://files.pythonhosted.org/packages/ce/55/1974bcc16884a397ee699cebd3914e1f59be64ab305533347ca2d983756f/nh3-0.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3f1b4f8a264a0c86ea01da0d0c390fe295ea0bcacc52c2103aca286f6884f518", size = 986499, upload-time = "2025-07-17T14:43:32.459Z" }, - { url = "https://files.pythonhosted.org/packages/c9/50/76936ec021fe1f3270c03278b8af5f2079038116b5d0bfe8538ffe699d69/nh3-0.3.0-cp38-abi3-win32.whl", hash = "sha256:6d68fa277b4a3cf04e5c4b84dd0c6149ff7d56c12b3e3fab304c525b850f613d", size = 599000, upload-time = "2025-07-17T14:43:33.852Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ae/324b165d904dc1672eee5f5661c0a68d4bab5b59fbb07afb6d8d19a30b45/nh3-0.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:bae63772408fd63ad836ec569a7c8f444dd32863d0c67f6e0b25ebbd606afa95", size = 604530, upload-time = "2025-07-17T14:43:34.95Z" }, - { url = "https://files.pythonhosted.org/packages/5b/76/3165e84e5266d146d967a6cc784ff2fbf6ddd00985a55ec006b72bc39d5d/nh3-0.3.0-cp38-abi3-win_arm64.whl", hash = "sha256:d97d3efd61404af7e5721a0e74d81cdbfc6e5f97e11e731bb6d090e30a7b62b2", size = 585971, upload-time = "2025-07-17T14:43:35.936Z" }, +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/a6/c6e942fc8dcadab08645f57a6d01d63e97114a30ded5f269dc58e05d4741/nh3-0.3.1.tar.gz", hash = "sha256:6a854480058683d60bdc7f0456105092dae17bef1f300642856d74bd4201da93", size = 18590, upload-time = "2025-10-07T03:27:58.217Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/24/4becaa61e066ff694c37627f5ef7528901115ffa17f7a6693c40da52accd/nh3-0.3.1-cp313-cp313t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:80dc7563a2a3b980e44b221f69848e3645bbf163ab53e3d1add4f47b26120355", size = 1420887, upload-time = "2025-10-07T03:27:25.654Z" }, + { url = "https://files.pythonhosted.org/packages/94/49/16a6ec9098bb9bdf0fb9f09d6464865a3a48858d8d96e779a998ec3bdce0/nh3-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f600ad86114df21efc4a3592faa6b1d099c0eebc7e018efebb1c133376097da", size = 791700, upload-time = "2025-10-07T03:27:27.041Z" }, + { url = "https://files.pythonhosted.org/packages/1d/cc/1c024d7c23ad031dfe82ad59581736abcc403b006abb0d2785bffa768b54/nh3-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:669a908706cd28203d9cfce2f567575686e364a1bc6074d413d88d456066f743", size = 830225, upload-time = "2025-10-07T03:27:28.315Z" }, + { url = "https://files.pythonhosted.org/packages/89/08/4a87f9212373bd77bba01c1fd515220e0d263316f448d9c8e4b09732a645/nh3-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a5721f59afa0ab3dcaa0d47e58af33a5fcd254882e1900ee4a8968692a40f79d", size = 999112, upload-time = "2025-10-07T03:27:29.782Z" }, + { url = "https://files.pythonhosted.org/packages/19/cf/94783911eb966881a440ba9641944c27152662a253c917a794a368b92a3c/nh3-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2cb6d9e192fbe0d451c7cb1350dadedbeae286207dbf101a28210193d019752e", size = 1070424, upload-time = "2025-10-07T03:27:31.2Z" }, + { url = "https://files.pythonhosted.org/packages/71/44/efb57b44e86a3de528561b49ed53803e5d42cd0441dcfd29b89422160266/nh3-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:474b176124c1b495ccfa1c20f61b7eb83ead5ecccb79ab29f602c148e8378489", size = 996129, upload-time = "2025-10-07T03:27:32.595Z" }, + { url = "https://files.pythonhosted.org/packages/ee/d3/87c39ea076510e57ee99a27fa4c2335e9e5738172b3963ee7c744a32726c/nh3-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4a2434668f4eef4eab17c128e565ce6bea42113ce10c40b928e42c578d401800", size = 980310, upload-time = "2025-10-07T03:27:34.282Z" }, + { url = "https://files.pythonhosted.org/packages/bc/30/00cfbd2a4d268e8d3bda9d1542ba4f7a20fbed37ad1e8e51beeee3f6fdae/nh3-0.3.1-cp313-cp313t-win32.whl", hash = "sha256:0f454ba4c6aabafcaae964ae6f0a96cecef970216a57335fabd229a265fbe007", size = 584439, upload-time = "2025-10-07T03:27:36.103Z" }, + { url = "https://files.pythonhosted.org/packages/80/fa/39d27a62a2f39eb88c2bd50d9fee365a3645e456f3ec483c945a49c74f47/nh3-0.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:22b9e9c9eda497b02b7273b79f7d29e1f1170d2b741624c1b8c566aef28b1f48", size = 592388, upload-time = "2025-10-07T03:27:37.075Z" }, + { url = "https://files.pythonhosted.org/packages/7c/39/7df1c4ee13ef65ee06255df8101141793e97b4326e8509afbce5deada2b5/nh3-0.3.1-cp313-cp313t-win_arm64.whl", hash = "sha256:42e426f36e167ed29669b77ae3c4b9e185e4a1b130a86d7c3249194738a1d7b2", size = 579337, upload-time = "2025-10-07T03:27:38.055Z" }, + { url = "https://files.pythonhosted.org/packages/e1/28/a387fed70438d2810c8ac866e7b24bf1a5b6f30ae65316dfe4de191afa52/nh3-0.3.1-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:1de5c1a35bed19a1b1286bab3c3abfe42e990a8a6c4ce9bb9ab4bde49107ea3b", size = 1433666, upload-time = "2025-10-07T03:27:39.118Z" }, + { url = "https://files.pythonhosted.org/packages/c7/f9/500310c1f19cc80770a81aac3c94a0c6b4acdd46489e34019173b2b15a50/nh3-0.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaba26591867f697cffdbc539faddeb1d75a36273f5bfe957eb421d3f87d7da1", size = 819897, upload-time = "2025-10-07T03:27:40.488Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d4/ebb0965d767cba943793fa8f7b59d7f141bd322c86387a5e9485ad49754a/nh3-0.3.1-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:489ca5ecd58555c2865701e65f614b17555179e71ecc76d483b6f3886b813a9b", size = 803562, upload-time = "2025-10-07T03:27:41.86Z" }, + { url = "https://files.pythonhosted.org/packages/0a/9c/df037a13f0513283ecee1cf99f723b18e5f87f20e480582466b1f8e3a7db/nh3-0.3.1-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5a25662b392b06f251da6004a1f8a828dca7f429cd94ac07d8a98ba94d644438", size = 1050854, upload-time = "2025-10-07T03:27:43.29Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9d/488fce56029de430e30380ec21f29cfaddaf0774f63b6aa2bf094c8b4c27/nh3-0.3.1-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38b4872499ab15b17c5c6e9f091143d070d75ddad4a4d1ce388d043ca556629c", size = 1002152, upload-time = "2025-10-07T03:27:44.358Z" }, + { url = "https://files.pythonhosted.org/packages/da/4a/24b0118de34d34093bf03acdeca3a9556f8631d4028814a72b9cc5216382/nh3-0.3.1-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48425995d37880281b467f7cf2b3218c1f4750c55bcb1ff4f47f2320a2bb159c", size = 912333, upload-time = "2025-10-07T03:27:45.757Z" }, + { url = "https://files.pythonhosted.org/packages/11/0e/16b3886858b3953ef836dea25b951f3ab0c5b5a431da03f675c0e999afb8/nh3-0.3.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94292dd1bd2a2e142fa5bb94c0ee1d84433a5d9034640710132da7e0376fca3a", size = 796945, upload-time = "2025-10-07T03:27:47.169Z" }, + { url = "https://files.pythonhosted.org/packages/87/bb/aac139cf6796f2e0fec026b07843cea36099864ec104f865e2d802a25a30/nh3-0.3.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dd6d1be301123a9af3263739726eeeb208197e5e78fc4f522408c50de77a5354", size = 837257, upload-time = "2025-10-07T03:27:48.243Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d7/1d770876a288a3f5369fd6c816363a5f9d3a071dba24889458fdeb4f7a49/nh3-0.3.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b74bbd047b361c0f21d827250c865ff0895684d9fcf85ea86131a78cfa0b835b", size = 1004142, upload-time = "2025-10-07T03:27:49.278Z" }, + { url = "https://files.pythonhosted.org/packages/31/2a/c4259e8b94c2f4ba10a7560e0889a6b7d2f70dce7f3e93f6153716aaae47/nh3-0.3.1-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:b222c05ae5139320da6caa1c5aed36dd0ee36e39831541d9b56e048a63b4d701", size = 1075896, upload-time = "2025-10-07T03:27:50.527Z" }, + { url = "https://files.pythonhosted.org/packages/59/06/b15ba9fea4773741acb3382dcf982f81e55f6053e8a6e72a97ac91928b1d/nh3-0.3.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:b0d6c834d3c07366ecbdcecc1f4804c5ce0a77fa52ee4653a2a26d2d909980ea", size = 1003235, upload-time = "2025-10-07T03:27:51.673Z" }, + { url = "https://files.pythonhosted.org/packages/1d/13/74707f99221bbe0392d18611b51125d45f8bd5c6be077ef85575eb7a38b1/nh3-0.3.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:670f18b09f75c86c3865f79543bf5acd4bbe2a5a4475672eef2399dd8cdb69d2", size = 987308, upload-time = "2025-10-07T03:27:53.003Z" }, + { url = "https://files.pythonhosted.org/packages/ee/81/24bf41a5ce7648d7e954de40391bb1bcc4b7731214238c7138c2420f962c/nh3-0.3.1-cp38-abi3-win32.whl", hash = "sha256:d7431b2a39431017f19cd03144005b6c014201b3e73927c05eab6ca37bb1d98c", size = 591695, upload-time = "2025-10-07T03:27:54.43Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ca/263eb96b6d32c61a92c1e5480b7f599b60db7d7fbbc0d944be7532d0ac42/nh3-0.3.1-cp38-abi3-win_amd64.whl", hash = "sha256:c0acef923a1c3a2df3ee5825ea79c149b6748c6449781c53ab6923dc75e87d26", size = 600564, upload-time = "2025-10-07T03:27:55.966Z" }, + { url = "https://files.pythonhosted.org/packages/34/67/d5e07efd38194f52b59b8af25a029b46c0643e9af68204ee263022924c27/nh3-0.3.1-cp38-abi3-win_arm64.whl", hash = "sha256:a3e810a92fb192373204456cac2834694440af73d749565b4348e30235da7f0b", size = 586369, upload-time = "2025-10-07T03:27:57.234Z" }, ] [[package]] @@ -1005,11 +1103,11 @@ wheels = [ [[package]] name = "platformdirs" -version = "4.3.8" +version = "4.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } +sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, + { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, ] [[package]] @@ -1023,28 +1121,28 @@ wheels = [ [[package]] name = "prek" -version = "0.1.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/77/29/99625bf6570b64b0d63f4ee6c3be939bbdaa64a842bab8e4e702a83f9946/prek-0.1.6.tar.gz", hash = "sha256:ceb193fa12235c448514e91c0d5ee94e47c48941cd20d7242c7a2031f9cc3b2e", size = 195662, upload-time = "2025-09-03T12:09:01.501Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/cb/46a7d29b5e250231afcf399c799cda9ead421712f9f343d26f2d43cf4d53/prek-0.1.6-py3-none-linux_armv6l.whl", hash = "sha256:cb06b7c1cb876382344995b19ce4df05d18bd9cc21b84905fae9953765f7fdfe", size = 5479888, upload-time = "2025-09-03T12:08:33.342Z" }, - { url = "https://files.pythonhosted.org/packages/5e/85/fcaa6fbb1a28e8df1b184f0a5a7d2fa529258f1ced83b5cea041f0ecb055/prek-0.1.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:88ea43afd30f13c99ca6d493f0a277b0234a3411be1dacdf7a1e96d6e41bbfca", size = 5463396, upload-time = "2025-09-03T12:08:35.056Z" }, - { url = "https://files.pythonhosted.org/packages/52/1d/ce17324f500fdc78e5462a982806da253f641b07ffdf5ec7da2d8b316d94/prek-0.1.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e446c91ce04126467753ff21dffc13c263689f2626251993feb32176f829cfdc", size = 5268164, upload-time = "2025-09-03T12:08:36.683Z" }, - { url = "https://files.pythonhosted.org/packages/ce/22/a9a063587d1b8b1f5298771f29da38e4b3138a8eb33801b58958c0c934ff/prek-0.1.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:49b7307f6795ba3a3b4b7f7d4821e168148854541786dfeaf481074f941858e0", size = 5647952, upload-time = "2025-09-03T12:08:38.124Z" }, - { url = "https://files.pythonhosted.org/packages/5d/10/0b00b92974ae5e03115382f1e20803baf2f5b799ae89768e8c3a406daa2e/prek-0.1.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5880499d304eda6d9f099cba976b922fe3441040112fc868171e885c4e14f4c5", size = 5389501, upload-time = "2025-09-03T12:08:39.496Z" }, - { url = "https://files.pythonhosted.org/packages/04/ea/0a89b20b5d0d20841dcf52ff4d65a8be512013137830dd691ed0b27edb39/prek-0.1.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fb15e00613492073ce64c016768d30580839d62812623a70d9e870402603361", size = 6050426, upload-time = "2025-09-03T12:08:41.066Z" }, - { url = "https://files.pythonhosted.org/packages/5b/29/bd3c45199d7a5ab653990229c30a5e2b266c9a6732b7b6c8f057603bd2bd/prek-0.1.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:376c5c6fb5e9d7faa2ccea55e9791e8af8ceb96679aedb52363f48e879dc38fa", size = 6615182, upload-time = "2025-09-03T12:08:43.676Z" }, - { url = "https://files.pythonhosted.org/packages/12/ad/d49d061c8d829fe0bc47db0e1d483ed42430ec88ea71d3acfd3ea83690e8/prek-0.1.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7d3b9ebbf8d3d275d30513e4477f19845434f519d2f0ef230bebbf9f4c0cb156", size = 6380740, upload-time = "2025-09-03T12:08:45.051Z" }, - { url = "https://files.pythonhosted.org/packages/11/c2/ed4feba7cd5f7426a1f68a997c487dea38eb6fabed86e18b5b007a1f695b/prek-0.1.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:38f318458673578cd4ca28079881d5d3b7e5630a4b6fa24ef97da2398d9eac95", size = 5842265, upload-time = "2025-09-03T12:08:46.416Z" }, - { url = "https://files.pythonhosted.org/packages/36/06/1925768b33e5e7b9fa039164dc44e43de47c0ecd548457a3d83453c7c201/prek-0.1.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59d22a6f8a7908223bc9c5e1dda004ec9f7f24adef0f8747b9d09d63b206647d", size = 5822255, upload-time = "2025-09-03T12:08:47.987Z" }, - { url = "https://files.pythonhosted.org/packages/8b/41/c8d2682ccb5015eea10943802c341ffd808c1890c4030b7ef36f22120912/prek-0.1.6-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3df1705d07c951da47105d9d13e985792094cd068841bc0b4a88001c65181a43", size = 5675825, upload-time = "2025-09-03T12:08:49.235Z" }, - { url = "https://files.pythonhosted.org/packages/53/02/7ace9dcf2b74f4423733a3c60dbc8b32b1205372bb39d141eb11cfe842ab/prek-0.1.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:09071cc2a4b5d30dbe369e9259378439d1fa1c03534e50afae9f94cbee4c567c", size = 5739031, upload-time = "2025-09-03T12:08:50.581Z" }, - { url = "https://files.pythonhosted.org/packages/09/85/dad0ef6fd9c3186a928ecbfc858e48fa11b6b7c1bb6b55c9cf29e406ddea/prek-0.1.6-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:26a184108ebe5e3db36bedac9d50d61c690207754aaf58205cd2afea93983509", size = 5408159, upload-time = "2025-09-03T12:08:52.137Z" }, - { url = "https://files.pythonhosted.org/packages/6c/70/6c66edc0b27780927bd5e8729f382c5a1ba87d68c30ffc1b7058c81c2730/prek-0.1.6-py3-none-musllinux_1_1_i686.whl", hash = "sha256:59f3f9606d7a065b520fc06d54cf09f27d627afcfd1222206947119d2c3337bf", size = 5758070, upload-time = "2025-09-03T12:08:53.66Z" }, - { url = "https://files.pythonhosted.org/packages/6f/f4/166071db1e3eb5a18c3b2c41a73b664c7e16bf0ef6d8d819d15756046359/prek-0.1.6-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:0a31c0fe23d5bc0eabd2222cdd2efb085cf306422d594433e20fd13606919c1a", size = 5905007, upload-time = "2025-09-03T12:08:55.415Z" }, - { url = "https://files.pythonhosted.org/packages/8f/c3/cdeb71b0e3bb4788482548bd1b3f2c080e2a3f8fbe043f1da68e8f92951e/prek-0.1.6-py3-none-win32.whl", hash = "sha256:61ec7db7dadd70ea5ac4a06145598cd88d4518278e0addfed49f5fec92fd3c3d", size = 4233887, upload-time = "2025-09-03T12:08:56.634Z" }, - { url = "https://files.pythonhosted.org/packages/e7/f5/31e515cc9c7cbfbc4af122b77fa7457efaacf2d6c6fc17ca9bcb47155b98/prek-0.1.6-py3-none-win_amd64.whl", hash = "sha256:ab80c81dac48ec53fe8670273248b7044e18bc2012b07241dbcada14b8a057fd", size = 4741942, upload-time = "2025-09-03T12:08:58.717Z" }, - { url = "https://files.pythonhosted.org/packages/e3/18/c52d5ae8235710688a561140884166265787670801ae30e1a691cbec163f/prek-0.1.6-py3-none-win_arm64.whl", hash = "sha256:424fdb239204e48724cc3c9690493bebac0e8c071d79fa6e0204573c36f42425", size = 4500561, upload-time = "2025-09-03T12:09:00.333Z" }, +version = "0.2.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/d7/a99876b9327533494a142f5e064ee80b83f8f190e143d77df0e58b102a39/prek-0.2.10.tar.gz", hash = "sha256:b1e39e164e6e50b90370aefdaa8ea3b0d294c2dca32213a0e434338c071a084f", size = 306656, upload-time = "2025-10-18T12:59:39.016Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/a1/b0b1b2617da42180bb268ef7d602bd1d44cce513996580d8972cf0062f03/prek-0.2.10-py3-none-linux_armv6l.whl", hash = "sha256:14f92676c21cb8f6939e97573dd44afe374ae80d80ffb3b014d7fa1f5cd4f90e", size = 4423728, upload-time = "2025-10-18T12:59:13.311Z" }, + { url = "https://files.pythonhosted.org/packages/83/57/d3446e1349a37c6a8d67cb5d0bade6845eb8eecd5f1edf7e4d238d86e168/prek-0.2.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9d8c2fd564743a9fa75b3ef50e1e7d949ae9cdad81e7ad7190d33816f73eab24", size = 4526478, upload-time = "2025-10-18T12:59:15.131Z" }, + { url = "https://files.pythonhosted.org/packages/4f/3a/0c243787712a5651bb4dfadea447fae204b9bc6a9e125746e39e5cd50b7c/prek-0.2.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:884cd224ec585c31cc55d108c50ba806b56c76c5db3f00b8ee785fc23cc2650d", size = 4217789, upload-time = "2025-10-18T12:59:16.687Z" }, + { url = "https://files.pythonhosted.org/packages/80/a5/91fb3b639659160d4324c57bbc1da4e86f51246bd6a16df44ab56ab2b0c0/prek-0.2.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:c8198e9bc23999e25bf2b7f48539b828a5c4ce573f53c8666801b65bd9413856", size = 4401213, upload-time = "2025-10-18T12:59:18.111Z" }, + { url = "https://files.pythonhosted.org/packages/2e/26/ce28b3181add1f5f9d16a6ca5533ea54210a0148ff57d7889491390666bb/prek-0.2.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:86bce4c3078ffbf24b025b6f3072fccbffbe26b89e89f7824b9eebc79efd9117", size = 4358034, upload-time = "2025-10-18T12:59:19.48Z" }, + { url = "https://files.pythonhosted.org/packages/58/95/6d5faf64827db7ac7536cb9647758dd55657d0064f78050fe17d6bc8d75e/prek-0.2.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebf2874650b169a50b78a212372021c11243125dd476fd4f4d5a54cefb19f905", size = 4639510, upload-time = "2025-10-18T12:59:21.098Z" }, + { url = "https://files.pythonhosted.org/packages/50/55/8b81042d7063f3fcd3c339d57cce7aa7d48d4881c4f3370a2d271208c248/prek-0.2.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ba498c642c30ae9b874723bb6994adecea98e0558d5a1ed392c2b128f533be0e", size = 5080393, upload-time = "2025-10-18T12:59:22.855Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4a/ccd4cbeec66e26c0883d74345ddb5e7a162267081fff5d0ceb30da8ed099/prek-0.2.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:42f7a82f5a7f00f6cdf6a0a7894be43efdd43265edc2d3852b088e84f6647943", size = 5008842, upload-time = "2025-10-18T12:59:24.066Z" }, + { url = "https://files.pythonhosted.org/packages/10/4e/106072bde84f10f704c9829a59698e5727eb54389abda999732f1612793c/prek-0.2.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d245a596db86c1e73410465aaa02e71190c271bbfe72c9479260874ac28d248", size = 5126863, upload-time = "2025-10-18T12:59:25.459Z" }, + { url = "https://files.pythonhosted.org/packages/53/5b/34e823be911835ad1c78c2e69845275ee13b57eecbfdf19172f4d2a561dc/prek-0.2.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb09ad5956ec80bd9a9823d836ed73965df6ad79a1524ba41474ba2b207fbcd3", size = 4705646, upload-time = "2025-10-18T12:59:27.06Z" }, + { url = "https://files.pythonhosted.org/packages/43/49/96526b72bb840b5b0f5fd59c4d3547db5a67a80df22ad5c979312a13f774/prek-0.2.10-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:50eaa0be4f44fa988f06ead6fbd31924ccd717233d4a48dd63d7aeee0da35d3f", size = 4416120, upload-time = "2025-10-18T12:59:28.679Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/267d601521c72ccf19635f98f42fa31b643cc68073cecdaa0fda1dc27bee/prek-0.2.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:740112b6f4516b8ca3ac8d1c2ad8a97ebae6e9849eda30eab36789cb50237dce", size = 4515004, upload-time = "2025-10-18T12:59:29.905Z" }, + { url = "https://files.pythonhosted.org/packages/b4/1c/dd34cefe57cdfd636d2c9d120c4254a3cee2698249f27ccbb8319f936b36/prek-0.2.10-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:7fb02642afa58aadbffb5899aa8d846cc3bc2fb1703ce2244601e29eaba02223", size = 4334781, upload-time = "2025-10-18T12:59:31.168Z" }, + { url = "https://files.pythonhosted.org/packages/69/20/98cd5e2e1da4eebed1e1280a82f18870efed3e669d8eb939d410b4c571ad/prek-0.2.10-py3-none-musllinux_1_1_i686.whl", hash = "sha256:56e3c4883f4bbc0a39c82c4c3b7e326ece49e7357fe29937a708ed0fd7a31999", size = 4533087, upload-time = "2025-10-18T12:59:32.374Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ed/e7dea5f2e456e7f16d5be08c30be8fbf665c8391196c3870de39d5c0fb1d/prek-0.2.10-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:56df3f2022f4e8fd359c35acde550e1dec76187183524c8e1e3236b121401173", size = 4811474, upload-time = "2025-10-18T12:59:33.933Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2d/8118069a15280a5d3f2f9eae5a897b876a38ee470f0a1654e2740aa52c7a/prek-0.2.10-py3-none-win32.whl", hash = "sha256:f6a4801188749951732e662c3ac2f1494abd7e846ba8bb90cf82bd2f6afcffea", size = 4244014, upload-time = "2025-10-18T12:59:35.173Z" }, + { url = "https://files.pythonhosted.org/packages/93/a0/20a780d3de14cdddd74f25512c6b313b8b922c00437bf89854665a6fc7de/prek-0.2.10-py3-none-win_amd64.whl", hash = "sha256:3f35e5630bafa3d7654798f354e6e8fc9717c9687088b9f842d7e6dcc6450743", size = 4817435, upload-time = "2025-10-18T12:59:36.592Z" }, + { url = "https://files.pythonhosted.org/packages/4a/a4/7c50e6992a5c6664e30c65b3e4884e93e19525eb66afbcda6c545c6cfbea/prek-0.2.10-py3-none-win_arm64.whl", hash = "sha256:62d77b3dce2eaf7f69f175a3bf6c95e351d4b55fdd8f5b31f9a739713c472c26", size = 4498683, upload-time = "2025-10-18T12:59:37.946Z" }, ] [[package]] @@ -1061,31 +1159,33 @@ wheels = [ [[package]] name = "protobuf" -version = "6.32.0" +version = "6.33.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/df/fb4a8eeea482eca989b51cffd274aac2ee24e825f0bf3cbce5281fa1567b/protobuf-6.32.0.tar.gz", hash = "sha256:a81439049127067fc49ec1d36e25c6ee1d1a2b7be930675f919258d03c04e7d2", size = 440614, upload-time = "2025-08-14T21:21:25.015Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/33/18/df8c87da2e47f4f1dcc5153a81cd6bca4e429803f4069a299e236e4dd510/protobuf-6.32.0-cp310-abi3-win32.whl", hash = "sha256:84f9e3c1ff6fb0308dbacb0950d8aa90694b0d0ee68e75719cb044b7078fe741", size = 424409, upload-time = "2025-08-14T21:21:12.366Z" }, - { url = "https://files.pythonhosted.org/packages/e1/59/0a820b7310f8139bd8d5a9388e6a38e1786d179d6f33998448609296c229/protobuf-6.32.0-cp310-abi3-win_amd64.whl", hash = "sha256:a8bdbb2f009cfc22a36d031f22a625a38b615b5e19e558a7b756b3279723e68e", size = 435735, upload-time = "2025-08-14T21:21:15.046Z" }, - { url = "https://files.pythonhosted.org/packages/cc/5b/0d421533c59c789e9c9894683efac582c06246bf24bb26b753b149bd88e4/protobuf-6.32.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d52691e5bee6c860fff9a1c86ad26a13afbeb4b168cd4445c922b7e2cf85aaf0", size = 426449, upload-time = "2025-08-14T21:21:16.687Z" }, - { url = "https://files.pythonhosted.org/packages/ec/7b/607764ebe6c7a23dcee06e054fd1de3d5841b7648a90fd6def9a3bb58c5e/protobuf-6.32.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:501fe6372fd1c8ea2a30b4d9be8f87955a64d6be9c88a973996cef5ef6f0abf1", size = 322869, upload-time = "2025-08-14T21:21:18.282Z" }, - { url = "https://files.pythonhosted.org/packages/40/01/2e730bd1c25392fc32e3268e02446f0d77cb51a2c3a8486b1798e34d5805/protobuf-6.32.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:75a2aab2bd1aeb1f5dc7c5f33bcb11d82ea8c055c9becbb41c26a8c43fd7092c", size = 322009, upload-time = "2025-08-14T21:21:19.893Z" }, - { url = "https://files.pythonhosted.org/packages/9c/f2/80ffc4677aac1bc3519b26bc7f7f5de7fce0ee2f7e36e59e27d8beb32dd1/protobuf-6.32.0-py3-none-any.whl", hash = "sha256:ba377e5b67b908c8f3072a57b63e2c6a4cbd18aea4ed98d2584350dbf46f2783", size = 169287, upload-time = "2025-08-14T21:21:23.515Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, + { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, + { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, + { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, + { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, ] [[package]] name = "psutil" -version = "7.0.0" +version = "7.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload-time = "2025-02-13T21:54:07.946Z" } +sdist = { url = "https://files.pythonhosted.org/packages/89/fc/889242351a932d6183eec5df1fc6539b6f36b6a88444f1e63f18668253aa/psutil-7.1.1.tar.gz", hash = "sha256:092b6350145007389c1cfe5716050f02030a05219d90057ea867d18fe8d372fc", size = 487067, upload-time = "2025-10-19T15:43:59.373Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload-time = "2025-02-13T21:54:12.36Z" }, - { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload-time = "2025-02-13T21:54:16.07Z" }, - { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload-time = "2025-02-13T21:54:18.662Z" }, - { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload-time = "2025-02-13T21:54:21.811Z" }, - { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload-time = "2025-02-13T21:54:24.68Z" }, - { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload-time = "2025-02-13T21:54:34.31Z" }, - { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload-time = "2025-02-13T21:54:37.486Z" }, + { url = "https://files.pythonhosted.org/packages/51/30/f97f8fb1f9ecfbeae4b5ca738dcae66ab28323b5cfbc96cb5565f3754056/psutil-7.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8fa59d7b1f01f0337f12cd10dbd76e4312a4d3c730a4fedcbdd4e5447a8b8460", size = 244221, upload-time = "2025-10-19T15:44:03.145Z" }, + { url = "https://files.pythonhosted.org/packages/7b/98/b8d1f61ebf35f4dbdbaabadf9208282d8adc820562f0257e5e6e79e67bf2/psutil-7.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:2a95104eae85d088891716db676f780c1404fc15d47fde48a46a5d61e8f5ad2c", size = 245660, upload-time = "2025-10-19T15:44:05.657Z" }, + { url = "https://files.pythonhosted.org/packages/f0/4a/b8015d7357fefdfe34bc4a3db48a107bae4bad0b94fb6eb0613f09a08ada/psutil-7.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:98629cd8567acefcc45afe2f4ba1e9290f579eacf490a917967decce4b74ee9b", size = 286963, upload-time = "2025-10-19T15:44:08.877Z" }, + { url = "https://files.pythonhosted.org/packages/3d/3c/b56076bb35303d0733fc47b110a1c9cce081a05ae2e886575a3587c1ee76/psutil-7.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92ebc58030fb054fa0f26c3206ef01c31c29d67aee1367e3483c16665c25c8d2", size = 290118, upload-time = "2025-10-19T15:44:11.897Z" }, + { url = "https://files.pythonhosted.org/packages/dc/af/c13d360c0adc6f6218bf9e2873480393d0f729c8dd0507d171f53061c0d3/psutil-7.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:146a704f224fb2ded2be3da5ac67fc32b9ea90c45b51676f9114a6ac45616967", size = 292587, upload-time = "2025-10-19T15:44:14.67Z" }, + { url = "https://files.pythonhosted.org/packages/90/2d/c933e7071ba60c7862813f2c7108ec4cf8304f1c79660efeefd0de982258/psutil-7.1.1-cp37-abi3-win32.whl", hash = "sha256:295c4025b5cd880f7445e4379e6826f7307e3d488947bf9834e865e7847dc5f7", size = 243772, upload-time = "2025-10-19T15:44:16.938Z" }, + { url = "https://files.pythonhosted.org/packages/be/f3/11fd213fff15427bc2853552138760c720fd65032d99edfb161910d04127/psutil-7.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:9b4f17c5f65e44f69bd3a3406071a47b79df45cf2236d1f717970afcb526bcd3", size = 246936, upload-time = "2025-10-19T15:44:18.663Z" }, + { url = "https://files.pythonhosted.org/packages/0a/8d/8a9a45c8b655851f216c1d44f68e3533dc8d2c752ccd0f61f1aa73be4893/psutil-7.1.1-cp37-abi3-win_arm64.whl", hash = "sha256:5457cf741ca13da54624126cd5d333871b454ab133999a9a103fb097a7d7d21a", size = 243944, upload-time = "2025-10-19T15:44:20.666Z" }, ] [[package]] @@ -1120,16 +1220,16 @@ wheels = [ [[package]] name = "pycparser" -version = "2.22" +version = "2.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, ] [[package]] name = "pygithub" -version = "2.7.0" +version = "2.8.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyjwt", extra = ["crypto"] }, @@ -1138,9 +1238,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/a7/403e04aa96e2d94e1518d518d69718c2ba978c8d3ffa4ab3b101b94dbafa/pygithub-2.7.0.tar.gz", hash = "sha256:7cd6eafabb09b5369afba3586d86b1f1ad6f1326d2ff01bc47bb26615dce4cbb", size = 3707928, upload-time = "2025-07-31T11:52:53.714Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/74/e560bdeffea72ecb26cff27f0fad548bbff5ecc51d6a155311ea7f9e4c4c/pygithub-2.8.1.tar.gz", hash = "sha256:341b7c78521cb07324ff670afd1baa2bf5c286f8d9fd302c1798ba594a5400c9", size = 2246994, upload-time = "2025-09-02T17:41:54.674Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/57/76/d768dd31322173b3956692b75471ac37bf3759c7abb603152f6a9b6594a8/pygithub-2.7.0-py3-none-any.whl", hash = "sha256:40ecbfe26dc55cc34ab4b0ffa1d455e6f816ef9a2bc8d6f5ad18ce572f163700", size = 416514, upload-time = "2025-07-31T11:52:51.909Z" }, + { url = "https://files.pythonhosted.org/packages/07/ba/7049ce39f653f6140aac4beb53a5aaf08b4407b6a3019aae394c1c5244ff/pygithub-2.8.1-py3-none-any.whl", hash = "sha256:23a0a5bca93baef082e03411bf0ce27204c32be8bfa7abc92fe4a3e132936df0", size = 432709, upload-time = "2025-09-02T17:41:52.947Z" }, ] [[package]] @@ -1168,36 +1268,53 @@ crypto = [ [[package]] name = "pynacl" -version = "1.5.0" +version = "1.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cffi" }, + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a7/22/27582568be639dfe22ddb3902225f91f2f17ceff88ce80e4db396c8986da/PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", size = 3392854, upload-time = "2022-01-07T22:05:41.134Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/75/0b8ede18506041c0bf23ac4d8e2971b4161cd6ce630b177d0a08eb0d8857/PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", size = 349920, upload-time = "2022-01-07T22:05:49.156Z" }, - { url = "https://files.pythonhosted.org/packages/59/bb/fddf10acd09637327a97ef89d2a9d621328850a72f1fdc8c08bdf72e385f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", size = 601722, upload-time = "2022-01-07T22:05:50.989Z" }, - { url = "https://files.pythonhosted.org/packages/5d/70/87a065c37cca41a75f2ce113a5a2c2aa7533be648b184ade58971b5f7ccc/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", size = 680087, upload-time = "2022-01-07T22:05:52.539Z" }, - { url = "https://files.pythonhosted.org/packages/ee/87/f1bb6a595f14a327e8285b9eb54d41fef76c585a0edef0a45f6fc95de125/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", size = 856678, upload-time = "2022-01-07T22:05:54.251Z" }, - { url = "https://files.pythonhosted.org/packages/66/28/ca86676b69bf9f90e710571b67450508484388bfce09acf8a46f0b8c785f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", size = 1133660, upload-time = "2022-01-07T22:05:56.056Z" }, - { url = "https://files.pythonhosted.org/packages/3d/85/c262db650e86812585e2bc59e497a8f59948a005325a11bbbc9ecd3fe26b/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", size = 663824, upload-time = "2022-01-07T22:05:57.434Z" }, - { url = "https://files.pythonhosted.org/packages/fd/1a/cc308a884bd299b651f1633acb978e8596c71c33ca85e9dc9fa33a5399b9/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", size = 1117912, upload-time = "2022-01-07T22:05:58.665Z" }, - { url = "https://files.pythonhosted.org/packages/25/2d/b7df6ddb0c2a33afdb358f8af6ea3b8c4d1196ca45497dd37a56f0c122be/PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543", size = 204624, upload-time = "2022-01-07T22:06:00.085Z" }, - { url = "https://files.pythonhosted.org/packages/5e/22/d3db169895faaf3e2eda892f005f433a62db2decbcfbc2f61e6517adfa87/PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", size = 212141, upload-time = "2022-01-07T22:06:01.861Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/06/c6/a3124dee667a423f2c637cfd262a54d67d8ccf3e160f3c50f622a85b7723/pynacl-1.6.0.tar.gz", hash = "sha256:cb36deafe6e2bce3b286e5d1f3e1c246e0ccdb8808ddb4550bb2792f2df298f2", size = 3505641, upload-time = "2025-09-10T23:39:22.308Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/24/1b639176401255605ba7c2b93a7b1eb1e379e0710eca62613633eb204201/pynacl-1.6.0-cp314-cp314t-macosx_10_10_universal2.whl", hash = "sha256:f46386c24a65383a9081d68e9c2de909b1834ec74ff3013271f1bca9c2d233eb", size = 384141, upload-time = "2025-09-10T23:38:28.675Z" }, + { url = "https://files.pythonhosted.org/packages/5e/7b/874efdf57d6bf172db0df111b479a553c3d9e8bb4f1f69eb3ffff772d6e8/pynacl-1.6.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:dea103a1afcbc333bc0e992e64233d360d393d1e63d0bc88554f572365664348", size = 808132, upload-time = "2025-09-10T23:38:38.995Z" }, + { url = "https://files.pythonhosted.org/packages/f3/61/9b53f5913f3b75ac3d53170cdb897101b2b98afc76f4d9d3c8de5aa3ac05/pynacl-1.6.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:04f20784083014e265ad58c1b2dd562c3e35864b5394a14ab54f5d150ee9e53e", size = 1407253, upload-time = "2025-09-10T23:38:40.492Z" }, + { url = "https://files.pythonhosted.org/packages/7c/0a/b138916b22bbf03a1bdbafecec37d714e7489dd7bcaf80cd17852f8b67be/pynacl-1.6.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbcc4452a1eb10cd5217318c822fde4be279c9de8567f78bad24c773c21254f8", size = 843719, upload-time = "2025-09-10T23:38:30.87Z" }, + { url = "https://files.pythonhosted.org/packages/01/3b/17c368197dfb2c817ce033f94605a47d0cc27901542109e640cef263f0af/pynacl-1.6.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51fed9fe1bec9e7ff9af31cd0abba179d0e984a2960c77e8e5292c7e9b7f7b5d", size = 1445441, upload-time = "2025-09-10T23:38:33.078Z" }, + { url = "https://files.pythonhosted.org/packages/35/3c/f79b185365ab9be80cd3cd01dacf30bf5895f9b7b001e683b369e0bb6d3d/pynacl-1.6.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:10d755cf2a455d8c0f8c767a43d68f24d163b8fe93ccfaabfa7bafd26be58d73", size = 825691, upload-time = "2025-09-10T23:38:34.832Z" }, + { url = "https://files.pythonhosted.org/packages/f7/1f/8b37d25e95b8f2a434a19499a601d4d272b9839ab8c32f6b0fc1e40c383f/pynacl-1.6.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:536703b8f90e911294831a7fbcd0c062b837f3ccaa923d92a6254e11178aaf42", size = 1410726, upload-time = "2025-09-10T23:38:36.893Z" }, + { url = "https://files.pythonhosted.org/packages/bd/93/5a4a4cf9913014f83d615ad6a2df9187330f764f606246b3a744c0788c03/pynacl-1.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6b08eab48c9669d515a344fb0ef27e2cbde847721e34bba94a343baa0f33f1f4", size = 801035, upload-time = "2025-09-10T23:38:42.109Z" }, + { url = "https://files.pythonhosted.org/packages/bf/60/40da6b0fe6a4d5fd88f608389eb1df06492ba2edca93fca0b3bebff9b948/pynacl-1.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5789f016e08e5606803161ba24de01b5a345d24590a80323379fc4408832d290", size = 1371854, upload-time = "2025-09-10T23:38:44.16Z" }, + { url = "https://files.pythonhosted.org/packages/44/b2/37ac1d65008f824cba6b5bf68d18b76d97d0f62d7a032367ea69d4a187c8/pynacl-1.6.0-cp314-cp314t-win32.whl", hash = "sha256:4853c154dc16ea12f8f3ee4b7e763331876316cc3a9f06aeedf39bcdca8f9995", size = 230345, upload-time = "2025-09-10T23:38:48.276Z" }, + { url = "https://files.pythonhosted.org/packages/f4/5a/9234b7b45af890d02ebee9aae41859b9b5f15fb4a5a56d88e3b4d1659834/pynacl-1.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:347dcddce0b4d83ed3f32fd00379c83c425abee5a9d2cd0a2c84871334eaff64", size = 243103, upload-time = "2025-09-10T23:38:45.503Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2c/c1a0f19d720ab0af3bc4241af2bdf4d813c3ecdcb96392b5e1ddf2d8f24f/pynacl-1.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2d6cd56ce4998cb66a6c112fda7b1fdce5266c9f05044fa72972613bef376d15", size = 187778, upload-time = "2025-09-10T23:38:46.731Z" }, + { url = "https://files.pythonhosted.org/packages/63/37/87c72df19857c5b3b47ace6f211a26eb862ada495cc96daa372d96048fca/pynacl-1.6.0-cp38-abi3-macosx_10_10_universal2.whl", hash = "sha256:f4b3824920e206b4f52abd7de621ea7a44fd3cb5c8daceb7c3612345dfc54f2e", size = 382610, upload-time = "2025-09-10T23:38:49.459Z" }, + { url = "https://files.pythonhosted.org/packages/0c/64/3ce958a5817fd3cc6df4ec14441c43fd9854405668d73babccf77f9597a3/pynacl-1.6.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:16dd347cdc8ae0b0f6187a2608c0af1c8b7ecbbe6b4a06bff8253c192f696990", size = 798744, upload-time = "2025-09-10T23:38:58.531Z" }, + { url = "https://files.pythonhosted.org/packages/e4/8a/3f0dd297a0a33fa3739c255feebd0206bb1df0b44c52fbe2caf8e8bc4425/pynacl-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:16c60daceee88d04f8d41d0a4004a7ed8d9a5126b997efd2933e08e93a3bd850", size = 1397879, upload-time = "2025-09-10T23:39:00.44Z" }, + { url = "https://files.pythonhosted.org/packages/41/94/028ff0434a69448f61348d50d2c147dda51aabdd4fbc93ec61343332174d/pynacl-1.6.0-cp38-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25720bad35dfac34a2bcdd61d9e08d6bfc6041bebc7751d9c9f2446cf1e77d64", size = 833907, upload-time = "2025-09-10T23:38:50.936Z" }, + { url = "https://files.pythonhosted.org/packages/52/bc/a5cff7f8c30d5f4c26a07dfb0bcda1176ab8b2de86dda3106c00a02ad787/pynacl-1.6.0-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8bfaa0a28a1ab718bad6239979a5a57a8d1506d0caf2fba17e524dbb409441cf", size = 1436649, upload-time = "2025-09-10T23:38:52.783Z" }, + { url = "https://files.pythonhosted.org/packages/7a/20/c397be374fd5d84295046e398de4ba5f0722dc14450f65db76a43c121471/pynacl-1.6.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ef214b90556bb46a485b7da8258e59204c244b1b5b576fb71848819b468c44a7", size = 817142, upload-time = "2025-09-10T23:38:54.4Z" }, + { url = "https://files.pythonhosted.org/packages/12/30/5efcef3406940cda75296c6d884090b8a9aad2dcc0c304daebb5ae99fb4a/pynacl-1.6.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:49c336dd80ea54780bcff6a03ee1a476be1612423010472e60af83452aa0f442", size = 1401794, upload-time = "2025-09-10T23:38:56.614Z" }, + { url = "https://files.pythonhosted.org/packages/be/e1/a8fe1248cc17ccb03b676d80fa90763760a6d1247da434844ea388d0816c/pynacl-1.6.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f3482abf0f9815e7246d461fab597aa179b7524628a4bc36f86a7dc418d2608d", size = 772161, upload-time = "2025-09-10T23:39:01.93Z" }, + { url = "https://files.pythonhosted.org/packages/a3/76/8a62702fb657d6d9104ce13449db221a345665d05e6a3fdefb5a7cafd2ad/pynacl-1.6.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:140373378e34a1f6977e573033d1dd1de88d2a5d90ec6958c9485b2fd9f3eb90", size = 1370720, upload-time = "2025-09-10T23:39:03.531Z" }, + { url = "https://files.pythonhosted.org/packages/6d/38/9e9e9b777a1c4c8204053733e1a0269672c0bd40852908c9ad6b6eaba82c/pynacl-1.6.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6b393bc5e5a0eb86bb85b533deb2d2c815666665f840a09e0aa3362bb6088736", size = 791252, upload-time = "2025-09-10T23:39:05.058Z" }, + { url = "https://files.pythonhosted.org/packages/63/ef/d972ce3d92ae05c9091363cf185e8646933f91c376e97b8be79ea6e96c22/pynacl-1.6.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a25cfede801f01e54179b8ff9514bd7b5944da560b7040939732d1804d25419", size = 1362910, upload-time = "2025-09-10T23:39:06.924Z" }, + { url = "https://files.pythonhosted.org/packages/35/2c/ee0b373a1861f66a7ca8bdb999331525615061320dd628527a50ba8e8a60/pynacl-1.6.0-cp38-abi3-win32.whl", hash = "sha256:dcdeb41c22ff3c66eef5e63049abf7639e0db4edee57ba70531fc1b6b133185d", size = 226461, upload-time = "2025-09-10T23:39:11.894Z" }, + { url = "https://files.pythonhosted.org/packages/75/f7/41b6c0b9dd9970173b6acc026bab7b4c187e4e5beef2756d419ad65482da/pynacl-1.6.0-cp38-abi3-win_amd64.whl", hash = "sha256:cf831615cc16ba324240de79d925eacae8265b7691412ac6b24221db157f6bd1", size = 238802, upload-time = "2025-09-10T23:39:08.966Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0f/462326910c6172fa2c6ed07922b22ffc8e77432b3affffd9e18f444dbfbb/pynacl-1.6.0-cp38-abi3-win_arm64.whl", hash = "sha256:84709cea8f888e618c21ed9a0efdb1a59cc63141c403db8bf56c469b71ad56f2", size = 183846, upload-time = "2025-09-10T23:39:10.552Z" }, ] [[package]] name = "pyparsing" -version = "3.2.3" +version = "3.2.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, ] [[package]] name = "pytest" -version = "8.4.1" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1208,9 +1325,9 @@ dependencies = [ { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] [[package]] @@ -1238,6 +1355,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "pytokens" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/c2/dbadcdddb412a267585459142bfd7cc241e6276db69339353ae6e241ab2b/pytokens-0.2.0.tar.gz", hash = "sha256:532d6421364e5869ea57a9523bf385f02586d4662acbcc0342afd69511b4dd43", size = 15368, upload-time = "2025-10-15T08:02:42.738Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/5a/c269ea6b348b6f2c32686635df89f32dbe05df1088dd4579302a6f8f99af/pytokens-0.2.0-py3-none-any.whl", hash = "sha256:74d4b318c67f4295c13782ddd9abcb7e297ec5630ad060eb90abf7ebbefe59f8", size = 12038, upload-time = "2025-10-15T08:02:41.694Z" }, +] + [[package]] name = "pywin32-ctypes" version = "0.2.3" @@ -1307,21 +1433,21 @@ wheels = [ [[package]] name = "referencing" -version = "0.36.2" +version = "0.37.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "rpds-py" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" }, + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, ] [[package]] name = "requests" -version = "2.32.4" +version = "2.32.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1329,9 +1455,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] @@ -1379,15 +1505,15 @@ wheels = [ [[package]] name = "rich" -version = "14.1.0" +version = "14.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441, upload-time = "2025-07-25T07:32:58.125Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, ] [[package]] @@ -1406,137 +1532,137 @@ wheels = [ [[package]] name = "rpds-py" -version = "0.27.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/d9/991a0dee12d9fc53ed027e26a26a64b151d77252ac477e22666b9688bc16/rpds_py-0.27.0.tar.gz", hash = "sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f", size = 27420, upload-time = "2025-08-07T08:26:39.624Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/75/2d/ad2e37dee3f45580f7fa0066c412a521f9bee53d2718b0e9436d308a1ecd/rpds_py-0.27.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:130c1ffa5039a333f5926b09e346ab335f0d4ec393b030a18549a7c7e7c2cea4", size = 371511, upload-time = "2025-08-07T08:23:06.205Z" }, - { url = "https://files.pythonhosted.org/packages/f5/67/57b4b2479193fde9dd6983a13c2550b5f9c3bcdf8912dffac2068945eb14/rpds_py-0.27.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a4cf32a26fa744101b67bfd28c55d992cd19438aff611a46cac7f066afca8fd4", size = 354718, upload-time = "2025-08-07T08:23:08.222Z" }, - { url = "https://files.pythonhosted.org/packages/a3/be/c2b95ec4b813eb11f3a3c3d22f22bda8d3a48a074a0519cde968c4d102cf/rpds_py-0.27.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64a0fe3f334a40b989812de70160de6b0ec7e3c9e4a04c0bbc48d97c5d3600ae", size = 381518, upload-time = "2025-08-07T08:23:09.696Z" }, - { url = "https://files.pythonhosted.org/packages/a5/d2/5a7279bc2b93b20bd50865a2269016238cee45f7dc3cc33402a7f41bd447/rpds_py-0.27.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a0ff7ee28583ab30a52f371b40f54e7138c52ca67f8ca17ccb7ccf0b383cb5f", size = 396694, upload-time = "2025-08-07T08:23:11.105Z" }, - { url = "https://files.pythonhosted.org/packages/65/e9/bac8b3714bd853c5bcb466e04acfb9a5da030d77e0ddf1dfad9afb791c31/rpds_py-0.27.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15ea4d2e182345dd1b4286593601d766411b43f868924afe297570658c31a62b", size = 514813, upload-time = "2025-08-07T08:23:12.215Z" }, - { url = "https://files.pythonhosted.org/packages/1d/aa/293115e956d7d13b7d2a9e9a4121f74989a427aa125f00ce4426ca8b7b28/rpds_py-0.27.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36184b44bf60a480863e51021c26aca3dfe8dd2f5eeabb33622b132b9d8b8b54", size = 402246, upload-time = "2025-08-07T08:23:13.699Z" }, - { url = "https://files.pythonhosted.org/packages/88/59/2d6789bb898fb3e2f0f7b82b7bcf27f579ebcb6cc36c24f4e208f7f58a5b/rpds_py-0.27.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b78430703cfcf5f5e86eb74027a1ed03a93509273d7c705babb547f03e60016", size = 383661, upload-time = "2025-08-07T08:23:15.231Z" }, - { url = "https://files.pythonhosted.org/packages/0c/55/add13a593a7a81243a9eed56d618d3d427be5dc1214931676e3f695dfdc1/rpds_py-0.27.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:dbd749cff1defbde270ca346b69b3baf5f1297213ef322254bf2a28537f0b046", size = 401691, upload-time = "2025-08-07T08:23:16.681Z" }, - { url = "https://files.pythonhosted.org/packages/04/09/3e8b2aad494ffaca571e4e19611a12cc18fcfd756d9274f3871a2d822445/rpds_py-0.27.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bde37765564cd22a676dd8101b657839a1854cfaa9c382c5abf6ff7accfd4ae", size = 416529, upload-time = "2025-08-07T08:23:17.863Z" }, - { url = "https://files.pythonhosted.org/packages/a4/6d/bd899234728f1d8f72c9610f50fdf1c140ecd0a141320e1f1d0f6b20595d/rpds_py-0.27.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1d66f45b9399036e890fb9c04e9f70c33857fd8f58ac8db9f3278cfa835440c3", size = 558673, upload-time = "2025-08-07T08:23:18.99Z" }, - { url = "https://files.pythonhosted.org/packages/79/f4/f3e02def5193fb899d797c232f90d6f8f0f2b9eca2faef6f0d34cbc89b2e/rpds_py-0.27.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d85d784c619370d9329bbd670f41ff5f2ae62ea4519761b679d0f57f0f0ee267", size = 588426, upload-time = "2025-08-07T08:23:20.541Z" }, - { url = "https://files.pythonhosted.org/packages/e3/0c/88e716cd8fd760e5308835fe298255830de4a1c905fd51760b9bb40aa965/rpds_py-0.27.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5df559e9e7644d9042f626f2c3997b555f347d7a855a15f170b253f6c5bfe358", size = 554552, upload-time = "2025-08-07T08:23:21.714Z" }, - { url = "https://files.pythonhosted.org/packages/2b/a9/0a8243c182e7ac59b901083dff7e671feba6676a131bfff3f8d301cd2b36/rpds_py-0.27.0-cp310-cp310-win32.whl", hash = "sha256:b8a4131698b6992b2a56015f51646711ec5d893a0b314a4b985477868e240c87", size = 218081, upload-time = "2025-08-07T08:23:23.273Z" }, - { url = "https://files.pythonhosted.org/packages/0f/e7/202ff35852312760148be9e08fe2ba6900aa28e7a46940a313eae473c10c/rpds_py-0.27.0-cp310-cp310-win_amd64.whl", hash = "sha256:cbc619e84a5e3ab2d452de831c88bdcad824414e9c2d28cd101f94dbdf26329c", size = 230077, upload-time = "2025-08-07T08:23:24.308Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c1/49d515434c1752e40f5e35b985260cf27af052593378580a2f139a5be6b8/rpds_py-0.27.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dbc2ab5d10544eb485baa76c63c501303b716a5c405ff2469a1d8ceffaabf622", size = 371577, upload-time = "2025-08-07T08:23:25.379Z" }, - { url = "https://files.pythonhosted.org/packages/e1/6d/bf2715b2fee5087fa13b752b5fd573f1a93e4134c74d275f709e38e54fe7/rpds_py-0.27.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7ec85994f96a58cf7ed288caa344b7fe31fd1d503bdf13d7331ead5f70ab60d5", size = 354959, upload-time = "2025-08-07T08:23:26.767Z" }, - { url = "https://files.pythonhosted.org/packages/a3/5c/e7762808c746dd19733a81373c10da43926f6a6adcf4920a21119697a60a/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:190d7285cd3bb6d31d37a0534d7359c1ee191eb194c511c301f32a4afa5a1dd4", size = 381485, upload-time = "2025-08-07T08:23:27.869Z" }, - { url = "https://files.pythonhosted.org/packages/40/51/0d308eb0b558309ca0598bcba4243f52c4cd20e15fe991b5bd75824f2e61/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c10d92fb6d7fd827e44055fcd932ad93dac6a11e832d51534d77b97d1d85400f", size = 396816, upload-time = "2025-08-07T08:23:29.424Z" }, - { url = "https://files.pythonhosted.org/packages/5c/aa/2d585ec911d78f66458b2c91252134ca0c7c70f687a72c87283173dc0c96/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd2c1d27ebfe6a015cfa2005b7fe8c52d5019f7bbdd801bc6f7499aab9ae739e", size = 514950, upload-time = "2025-08-07T08:23:30.576Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ef/aced551cc1148179557aed84343073adadf252c91265263ee6203458a186/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4790c9d5dd565ddb3e9f656092f57268951398cef52e364c405ed3112dc7c7c1", size = 402132, upload-time = "2025-08-07T08:23:32.428Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ac/cf644803d8d417653fe2b3604186861d62ea6afaef1b2284045741baef17/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4300e15e7d03660f04be84a125d1bdd0e6b2f674bc0723bc0fd0122f1a4585dc", size = 383660, upload-time = "2025-08-07T08:23:33.829Z" }, - { url = "https://files.pythonhosted.org/packages/c9/ec/caf47c55ce02b76cbaeeb2d3b36a73da9ca2e14324e3d75cf72b59dcdac5/rpds_py-0.27.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:59195dc244fc183209cf8a93406889cadde47dfd2f0a6b137783aa9c56d67c85", size = 401730, upload-time = "2025-08-07T08:23:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/0b/71/c1f355afdcd5b99ffc253422aa4bdcb04ccf1491dcd1bda3688a0c07fd61/rpds_py-0.27.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fae4a01ef8c4cb2bbe92ef2063149596907dc4a881a8d26743b3f6b304713171", size = 416122, upload-time = "2025-08-07T08:23:36.062Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/f4b5b1eda724ed0e04d2b26d8911cdc131451a7ee4c4c020a1387e5c6ded/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e3dc8d4ede2dbae6c0fc2b6c958bf51ce9fd7e9b40c0f5b8835c3fde44f5807d", size = 558771, upload-time = "2025-08-07T08:23:37.478Z" }, - { url = "https://files.pythonhosted.org/packages/93/c0/5f8b834db2289ab48d5cffbecbb75e35410103a77ac0b8da36bf9544ec1c/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c3782fb753aa825b4ccabc04292e07897e2fd941448eabf666856c5530277626", size = 587876, upload-time = "2025-08-07T08:23:38.662Z" }, - { url = "https://files.pythonhosted.org/packages/d2/dd/1a1df02ab8eb970115cff2ae31a6f73916609b900dc86961dc382b8c2e5e/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:887ab1f12b0d227e9260558a4a2320024b20102207ada65c43e1ffc4546df72e", size = 554359, upload-time = "2025-08-07T08:23:39.897Z" }, - { url = "https://files.pythonhosted.org/packages/a1/e4/95a014ab0d51ab6e3bebbdb476a42d992d2bbf9c489d24cff9fda998e925/rpds_py-0.27.0-cp311-cp311-win32.whl", hash = "sha256:5d6790ff400254137b81b8053b34417e2c46921e302d655181d55ea46df58cf7", size = 218084, upload-time = "2025-08-07T08:23:41.086Z" }, - { url = "https://files.pythonhosted.org/packages/49/78/f8d5b71ec65a0376b0de31efcbb5528ce17a9b7fdd19c3763303ccfdedec/rpds_py-0.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:e24d8031a2c62f34853756d9208eeafa6b940a1efcbfe36e8f57d99d52bb7261", size = 230085, upload-time = "2025-08-07T08:23:42.143Z" }, - { url = "https://files.pythonhosted.org/packages/e7/d3/84429745184091e06b4cc70f8597408e314c2d2f7f5e13249af9ffab9e3d/rpds_py-0.27.0-cp311-cp311-win_arm64.whl", hash = "sha256:08680820d23df1df0a0260f714d12966bc6c42d02e8055a91d61e03f0c47dda0", size = 222112, upload-time = "2025-08-07T08:23:43.233Z" }, - { url = "https://files.pythonhosted.org/packages/cd/17/e67309ca1ac993fa1888a0d9b2f5ccc1f67196ace32e76c9f8e1dbbbd50c/rpds_py-0.27.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4", size = 362611, upload-time = "2025-08-07T08:23:44.773Z" }, - { url = "https://files.pythonhosted.org/packages/93/2e/28c2fb84aa7aa5d75933d1862d0f7de6198ea22dfd9a0cca06e8a4e7509e/rpds_py-0.27.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b", size = 347680, upload-time = "2025-08-07T08:23:46.014Z" }, - { url = "https://files.pythonhosted.org/packages/44/3e/9834b4c8f4f5fe936b479e623832468aa4bd6beb8d014fecaee9eac6cdb1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e", size = 384600, upload-time = "2025-08-07T08:23:48Z" }, - { url = "https://files.pythonhosted.org/packages/19/78/744123c7b38865a965cd9e6f691fde7ef989a00a256fa8bf15b75240d12f/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34", size = 400697, upload-time = "2025-08-07T08:23:49.407Z" }, - { url = "https://files.pythonhosted.org/packages/32/97/3c3d32fe7daee0a1f1a678b6d4dfb8c4dcf88197fa2441f9da7cb54a8466/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8", size = 517781, upload-time = "2025-08-07T08:23:50.557Z" }, - { url = "https://files.pythonhosted.org/packages/b2/be/28f0e3e733680aa13ecec1212fc0f585928a206292f14f89c0b8a684cad1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726", size = 406449, upload-time = "2025-08-07T08:23:51.732Z" }, - { url = "https://files.pythonhosted.org/packages/95/ae/5d15c83e337c082d0367053baeb40bfba683f42459f6ebff63a2fd7e5518/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e", size = 386150, upload-time = "2025-08-07T08:23:52.822Z" }, - { url = "https://files.pythonhosted.org/packages/bf/65/944e95f95d5931112829e040912b25a77b2e7ed913ea5fe5746aa5c1ce75/rpds_py-0.27.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3", size = 406100, upload-time = "2025-08-07T08:23:54.339Z" }, - { url = "https://files.pythonhosted.org/packages/21/a4/1664b83fae02894533cd11dc0b9f91d673797c2185b7be0f7496107ed6c5/rpds_py-0.27.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e", size = 421345, upload-time = "2025-08-07T08:23:55.832Z" }, - { url = "https://files.pythonhosted.org/packages/7c/26/b7303941c2b0823bfb34c71378249f8beedce57301f400acb04bb345d025/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f", size = 561891, upload-time = "2025-08-07T08:23:56.951Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c8/48623d64d4a5a028fa99576c768a6159db49ab907230edddc0b8468b998b/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03", size = 591756, upload-time = "2025-08-07T08:23:58.146Z" }, - { url = "https://files.pythonhosted.org/packages/b3/51/18f62617e8e61cc66334c9fb44b1ad7baae3438662098efbc55fb3fda453/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374", size = 557088, upload-time = "2025-08-07T08:23:59.6Z" }, - { url = "https://files.pythonhosted.org/packages/bd/4c/e84c3a276e2496a93d245516be6b49e20499aa8ca1c94d59fada0d79addc/rpds_py-0.27.0-cp312-cp312-win32.whl", hash = "sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97", size = 221926, upload-time = "2025-08-07T08:24:00.695Z" }, - { url = "https://files.pythonhosted.org/packages/83/89/9d0fbcef64340db0605eb0a0044f258076f3ae0a3b108983b2c614d96212/rpds_py-0.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5", size = 233235, upload-time = "2025-08-07T08:24:01.846Z" }, - { url = "https://files.pythonhosted.org/packages/c9/b0/e177aa9f39cbab060f96de4a09df77d494f0279604dc2f509263e21b05f9/rpds_py-0.27.0-cp312-cp312-win_arm64.whl", hash = "sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9", size = 223315, upload-time = "2025-08-07T08:24:03.337Z" }, - { url = "https://files.pythonhosted.org/packages/81/d2/dfdfd42565a923b9e5a29f93501664f5b984a802967d48d49200ad71be36/rpds_py-0.27.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff", size = 362133, upload-time = "2025-08-07T08:24:04.508Z" }, - { url = "https://files.pythonhosted.org/packages/ac/4a/0a2e2460c4b66021d349ce9f6331df1d6c75d7eea90df9785d333a49df04/rpds_py-0.27.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367", size = 347128, upload-time = "2025-08-07T08:24:05.695Z" }, - { url = "https://files.pythonhosted.org/packages/35/8d/7d1e4390dfe09d4213b3175a3f5a817514355cb3524593380733204f20b9/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185", size = 384027, upload-time = "2025-08-07T08:24:06.841Z" }, - { url = "https://files.pythonhosted.org/packages/c1/65/78499d1a62172891c8cd45de737b2a4b84a414b6ad8315ab3ac4945a5b61/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc", size = 399973, upload-time = "2025-08-07T08:24:08.143Z" }, - { url = "https://files.pythonhosted.org/packages/10/a1/1c67c1d8cc889107b19570bb01f75cf49852068e95e6aee80d22915406fc/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe", size = 515295, upload-time = "2025-08-07T08:24:09.711Z" }, - { url = "https://files.pythonhosted.org/packages/df/27/700ec88e748436b6c7c4a2262d66e80f8c21ab585d5e98c45e02f13f21c0/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9", size = 406737, upload-time = "2025-08-07T08:24:11.182Z" }, - { url = "https://files.pythonhosted.org/packages/33/cc/6b0ee8f0ba3f2df2daac1beda17fde5cf10897a7d466f252bd184ef20162/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c", size = 385898, upload-time = "2025-08-07T08:24:12.798Z" }, - { url = "https://files.pythonhosted.org/packages/e8/7e/c927b37d7d33c0a0ebf249cc268dc2fcec52864c1b6309ecb960497f2285/rpds_py-0.27.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295", size = 405785, upload-time = "2025-08-07T08:24:14.906Z" }, - { url = "https://files.pythonhosted.org/packages/5b/d2/8ed50746d909dcf402af3fa58b83d5a590ed43e07251d6b08fad1a535ba6/rpds_py-0.27.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43", size = 419760, upload-time = "2025-08-07T08:24:16.129Z" }, - { url = "https://files.pythonhosted.org/packages/d3/60/2b2071aee781cb3bd49f94d5d35686990b925e9b9f3e3d149235a6f5d5c1/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432", size = 561201, upload-time = "2025-08-07T08:24:17.645Z" }, - { url = "https://files.pythonhosted.org/packages/98/1f/27b67304272521aaea02be293fecedce13fa351a4e41cdb9290576fc6d81/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b", size = 591021, upload-time = "2025-08-07T08:24:18.999Z" }, - { url = "https://files.pythonhosted.org/packages/db/9b/a2fadf823164dd085b1f894be6443b0762a54a7af6f36e98e8fcda69ee50/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d", size = 556368, upload-time = "2025-08-07T08:24:20.54Z" }, - { url = "https://files.pythonhosted.org/packages/24/f3/6d135d46a129cda2e3e6d4c5e91e2cc26ea0428c6cf152763f3f10b6dd05/rpds_py-0.27.0-cp313-cp313-win32.whl", hash = "sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd", size = 221236, upload-time = "2025-08-07T08:24:22.144Z" }, - { url = "https://files.pythonhosted.org/packages/c5/44/65d7494f5448ecc755b545d78b188440f81da98b50ea0447ab5ebfdf9bd6/rpds_py-0.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2", size = 232634, upload-time = "2025-08-07T08:24:23.642Z" }, - { url = "https://files.pythonhosted.org/packages/70/d9/23852410fadab2abb611733933401de42a1964ce6600a3badae35fbd573e/rpds_py-0.27.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac", size = 222783, upload-time = "2025-08-07T08:24:25.098Z" }, - { url = "https://files.pythonhosted.org/packages/15/75/03447917f78512b34463f4ef11066516067099a0c466545655503bed0c77/rpds_py-0.27.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774", size = 359154, upload-time = "2025-08-07T08:24:26.249Z" }, - { url = "https://files.pythonhosted.org/packages/6b/fc/4dac4fa756451f2122ddaf136e2c6aeb758dc6fdbe9ccc4bc95c98451d50/rpds_py-0.27.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b", size = 343909, upload-time = "2025-08-07T08:24:27.405Z" }, - { url = "https://files.pythonhosted.org/packages/7b/81/723c1ed8e6f57ed9d8c0c07578747a2d3d554aaefc1ab89f4e42cfeefa07/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd", size = 379340, upload-time = "2025-08-07T08:24:28.714Z" }, - { url = "https://files.pythonhosted.org/packages/98/16/7e3740413de71818ce1997df82ba5f94bae9fff90c0a578c0e24658e6201/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb", size = 391655, upload-time = "2025-08-07T08:24:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/e0/63/2a9f510e124d80660f60ecce07953f3f2d5f0b96192c1365443859b9c87f/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433", size = 513017, upload-time = "2025-08-07T08:24:31.446Z" }, - { url = "https://files.pythonhosted.org/packages/2c/4e/cf6ff311d09776c53ea1b4f2e6700b9d43bb4e99551006817ade4bbd6f78/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615", size = 402058, upload-time = "2025-08-07T08:24:32.613Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/5e36096d474cb10f2a2d68b22af60a3bc4164fd8db15078769a568d9d3ac/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8", size = 383474, upload-time = "2025-08-07T08:24:33.767Z" }, - { url = "https://files.pythonhosted.org/packages/db/a2/3dff02805b06058760b5eaa6d8cb8db3eb3e46c9e452453ad5fc5b5ad9fe/rpds_py-0.27.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858", size = 400067, upload-time = "2025-08-07T08:24:35.021Z" }, - { url = "https://files.pythonhosted.org/packages/67/87/eed7369b0b265518e21ea836456a4ed4a6744c8c12422ce05bce760bb3cf/rpds_py-0.27.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5", size = 412085, upload-time = "2025-08-07T08:24:36.267Z" }, - { url = "https://files.pythonhosted.org/packages/8b/48/f50b2ab2fbb422fbb389fe296e70b7a6b5ea31b263ada5c61377e710a924/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9", size = 555928, upload-time = "2025-08-07T08:24:37.573Z" }, - { url = "https://files.pythonhosted.org/packages/98/41/b18eb51045d06887666c3560cd4bbb6819127b43d758f5adb82b5f56f7d1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79", size = 585527, upload-time = "2025-08-07T08:24:39.391Z" }, - { url = "https://files.pythonhosted.org/packages/be/03/a3dd6470fc76499959b00ae56295b76b4bdf7c6ffc60d62006b1217567e1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c", size = 554211, upload-time = "2025-08-07T08:24:40.6Z" }, - { url = "https://files.pythonhosted.org/packages/bf/d1/ee5fd1be395a07423ac4ca0bcc05280bf95db2b155d03adefeb47d5ebf7e/rpds_py-0.27.0-cp313-cp313t-win32.whl", hash = "sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23", size = 216624, upload-time = "2025-08-07T08:24:42.204Z" }, - { url = "https://files.pythonhosted.org/packages/1c/94/4814c4c858833bf46706f87349c37ca45e154da7dbbec9ff09f1abeb08cc/rpds_py-0.27.0-cp313-cp313t-win_amd64.whl", hash = "sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1", size = 230007, upload-time = "2025-08-07T08:24:43.329Z" }, - { url = "https://files.pythonhosted.org/packages/0e/a5/8fffe1c7dc7c055aa02df310f9fb71cfc693a4d5ccc5de2d3456ea5fb022/rpds_py-0.27.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb", size = 362595, upload-time = "2025-08-07T08:24:44.478Z" }, - { url = "https://files.pythonhosted.org/packages/bc/c7/4e4253fd2d4bb0edbc0b0b10d9f280612ca4f0f990e3c04c599000fe7d71/rpds_py-0.27.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f", size = 347252, upload-time = "2025-08-07T08:24:45.678Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c8/3d1a954d30f0174dd6baf18b57c215da03cf7846a9d6e0143304e784cddc/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64", size = 384886, upload-time = "2025-08-07T08:24:46.86Z" }, - { url = "https://files.pythonhosted.org/packages/e0/52/3c5835f2df389832b28f9276dd5395b5a965cea34226e7c88c8fbec2093c/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015", size = 399716, upload-time = "2025-08-07T08:24:48.174Z" }, - { url = "https://files.pythonhosted.org/packages/40/73/176e46992461a1749686a2a441e24df51ff86b99c2d34bf39f2a5273b987/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0", size = 517030, upload-time = "2025-08-07T08:24:49.52Z" }, - { url = "https://files.pythonhosted.org/packages/79/2a/7266c75840e8c6e70effeb0d38922a45720904f2cd695e68a0150e5407e2/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89", size = 408448, upload-time = "2025-08-07T08:24:50.727Z" }, - { url = "https://files.pythonhosted.org/packages/e6/5f/a7efc572b8e235093dc6cf39f4dbc8a7f08e65fdbcec7ff4daeb3585eef1/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d", size = 387320, upload-time = "2025-08-07T08:24:52.004Z" }, - { url = "https://files.pythonhosted.org/packages/a2/eb/9ff6bc92efe57cf5a2cb74dee20453ba444b6fdc85275d8c99e0d27239d1/rpds_py-0.27.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51", size = 407414, upload-time = "2025-08-07T08:24:53.664Z" }, - { url = "https://files.pythonhosted.org/packages/fb/bd/3b9b19b00d5c6e1bd0f418c229ab0f8d3b110ddf7ec5d9d689ef783d0268/rpds_py-0.27.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c", size = 420766, upload-time = "2025-08-07T08:24:55.917Z" }, - { url = "https://files.pythonhosted.org/packages/17/6b/521a7b1079ce16258c70805166e3ac6ec4ee2139d023fe07954dc9b2d568/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4", size = 562409, upload-time = "2025-08-07T08:24:57.17Z" }, - { url = "https://files.pythonhosted.org/packages/8b/bf/65db5bfb14ccc55e39de8419a659d05a2a9cd232f0a699a516bb0991da7b/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e", size = 590793, upload-time = "2025-08-07T08:24:58.388Z" }, - { url = "https://files.pythonhosted.org/packages/db/b8/82d368b378325191ba7aae8f40f009b78057b598d4394d1f2cdabaf67b3f/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e", size = 558178, upload-time = "2025-08-07T08:24:59.756Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ff/f270bddbfbc3812500f8131b1ebbd97afd014cd554b604a3f73f03133a36/rpds_py-0.27.0-cp314-cp314-win32.whl", hash = "sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6", size = 222355, upload-time = "2025-08-07T08:25:01.027Z" }, - { url = "https://files.pythonhosted.org/packages/bf/20/fdab055b1460c02ed356a0e0b0a78c1dd32dc64e82a544f7b31c9ac643dc/rpds_py-0.27.0-cp314-cp314-win_amd64.whl", hash = "sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a", size = 234007, upload-time = "2025-08-07T08:25:02.268Z" }, - { url = "https://files.pythonhosted.org/packages/4d/a8/694c060005421797a3be4943dab8347c76c2b429a9bef68fb2c87c9e70c7/rpds_py-0.27.0-cp314-cp314-win_arm64.whl", hash = "sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d", size = 223527, upload-time = "2025-08-07T08:25:03.45Z" }, - { url = "https://files.pythonhosted.org/packages/1e/f9/77f4c90f79d2c5ca8ce6ec6a76cb4734ee247de6b3a4f337e289e1f00372/rpds_py-0.27.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828", size = 359469, upload-time = "2025-08-07T08:25:04.648Z" }, - { url = "https://files.pythonhosted.org/packages/c0/22/b97878d2f1284286fef4172069e84b0b42b546ea7d053e5fb7adb9ac6494/rpds_py-0.27.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669", size = 343960, upload-time = "2025-08-07T08:25:05.863Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b0/dfd55b5bb480eda0578ae94ef256d3061d20b19a0f5e18c482f03e65464f/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd", size = 380201, upload-time = "2025-08-07T08:25:07.513Z" }, - { url = "https://files.pythonhosted.org/packages/28/22/e1fa64e50d58ad2b2053077e3ec81a979147c43428de9e6de68ddf6aff4e/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec", size = 392111, upload-time = "2025-08-07T08:25:09.149Z" }, - { url = "https://files.pythonhosted.org/packages/49/f9/43ab7a43e97aedf6cea6af70fdcbe18abbbc41d4ae6cdec1bfc23bbad403/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303", size = 515863, upload-time = "2025-08-07T08:25:10.431Z" }, - { url = "https://files.pythonhosted.org/packages/38/9b/9bd59dcc636cd04d86a2d20ad967770bf348f5eb5922a8f29b547c074243/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b", size = 402398, upload-time = "2025-08-07T08:25:11.819Z" }, - { url = "https://files.pythonhosted.org/packages/71/bf/f099328c6c85667aba6b66fa5c35a8882db06dcd462ea214be72813a0dd2/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410", size = 384665, upload-time = "2025-08-07T08:25:13.194Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c5/9c1f03121ece6634818490bd3c8be2c82a70928a19de03467fb25a3ae2a8/rpds_py-0.27.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156", size = 400405, upload-time = "2025-08-07T08:25:14.417Z" }, - { url = "https://files.pythonhosted.org/packages/b5/b8/e25d54af3e63ac94f0c16d8fe143779fe71ff209445a0c00d0f6984b6b2c/rpds_py-0.27.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2", size = 413179, upload-time = "2025-08-07T08:25:15.664Z" }, - { url = "https://files.pythonhosted.org/packages/f9/d1/406b3316433fe49c3021546293a04bc33f1478e3ec7950215a7fce1a1208/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1", size = 556895, upload-time = "2025-08-07T08:25:17.061Z" }, - { url = "https://files.pythonhosted.org/packages/5f/bc/3697c0c21fcb9a54d46ae3b735eb2365eea0c2be076b8f770f98e07998de/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42", size = 585464, upload-time = "2025-08-07T08:25:18.406Z" }, - { url = "https://files.pythonhosted.org/packages/63/09/ee1bb5536f99f42c839b177d552f6114aa3142d82f49cef49261ed28dbe0/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae", size = 555090, upload-time = "2025-08-07T08:25:20.461Z" }, - { url = "https://files.pythonhosted.org/packages/7d/2c/363eada9e89f7059199d3724135a86c47082cbf72790d6ba2f336d146ddb/rpds_py-0.27.0-cp314-cp314t-win32.whl", hash = "sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5", size = 218001, upload-time = "2025-08-07T08:25:21.761Z" }, - { url = "https://files.pythonhosted.org/packages/e2/3f/d6c216ed5199c9ef79e2a33955601f454ed1e7420a93b89670133bca5ace/rpds_py-0.27.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391", size = 230993, upload-time = "2025-08-07T08:25:23.34Z" }, - { url = "https://files.pythonhosted.org/packages/47/55/287068956f9ba1cb40896d291213f09fdd4527630709058b45a592bc09dc/rpds_py-0.27.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:46f48482c1a4748ab2773f75fffbdd1951eb59794e32788834b945da857c47a8", size = 371566, upload-time = "2025-08-07T08:25:43.95Z" }, - { url = "https://files.pythonhosted.org/packages/a2/fb/443af59cbe552e89680bb0f1d1ba47f6387b92083e28a45b8c8863b86c5a/rpds_py-0.27.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:419dd9c98bcc9fb0242be89e0c6e922df333b975d4268faa90d58499fd9c9ebe", size = 355781, upload-time = "2025-08-07T08:25:45.256Z" }, - { url = "https://files.pythonhosted.org/packages/ad/f0/35f48bb073b5ca42b1dcc55cb148f4a3bd4411a3e584f6a18d26f0ea8832/rpds_py-0.27.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d42a0ef2bdf6bc81e1cc2d49d12460f63c6ae1423c4f4851b828e454ccf6f1", size = 382575, upload-time = "2025-08-07T08:25:46.524Z" }, - { url = "https://files.pythonhosted.org/packages/51/e1/5f5296a21d1189f0f116a938af2e346d83172bf814d373695e54004a936f/rpds_py-0.27.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2e39169ac6aae06dd79c07c8a69d9da867cef6a6d7883a0186b46bb46ccfb0c3", size = 397435, upload-time = "2025-08-07T08:25:48.204Z" }, - { url = "https://files.pythonhosted.org/packages/97/79/3af99b7852b2b55cad8a08863725cbe9dc14781bcf7dc6ecead0c3e1dc54/rpds_py-0.27.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:935afcdea4751b0ac918047a2df3f720212892347767aea28f5b3bf7be4f27c0", size = 514861, upload-time = "2025-08-07T08:25:49.814Z" }, - { url = "https://files.pythonhosted.org/packages/df/3e/11fd6033708ed3ae0e6947bb94f762f56bb46bf59a1b16eef6944e8a62ee/rpds_py-0.27.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8de567dec6d451649a781633d36f5c7501711adee329d76c095be2178855b042", size = 402776, upload-time = "2025-08-07T08:25:51.135Z" }, - { url = "https://files.pythonhosted.org/packages/b7/89/f9375ceaa996116de9cbc949874804c7874d42fb258c384c037a46d730b8/rpds_py-0.27.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:555ed147cbe8c8f76e72a4c6cd3b7b761cbf9987891b9448808148204aed74a5", size = 384665, upload-time = "2025-08-07T08:25:52.82Z" }, - { url = "https://files.pythonhosted.org/packages/48/bf/0061e55c6f1f573a63c0f82306b8984ed3b394adafc66854a936d5db3522/rpds_py-0.27.0-pp310-pypy310_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:d2cc2b34f9e1d31ce255174da82902ad75bd7c0d88a33df54a77a22f2ef421ee", size = 402518, upload-time = "2025-08-07T08:25:54.073Z" }, - { url = "https://files.pythonhosted.org/packages/ae/dc/8d506676bfe87b3b683332ec8e6ab2b0be118a3d3595ed021e3274a63191/rpds_py-0.27.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cb0702c12983be3b2fab98ead349ac63a98216d28dda6f518f52da5498a27a1b", size = 416247, upload-time = "2025-08-07T08:25:55.433Z" }, - { url = "https://files.pythonhosted.org/packages/2e/02/9a89eea1b75c69e81632de7963076e455b1e00e1cfb46dfdabb055fa03e3/rpds_py-0.27.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ba783541be46f27c8faea5a6645e193943c17ea2f0ffe593639d906a327a9bcc", size = 559456, upload-time = "2025-08-07T08:25:56.866Z" }, - { url = "https://files.pythonhosted.org/packages/38/4a/0f3ac4351957847c0d322be6ec72f916e43804a2c1d04e9672ea4a67c315/rpds_py-0.27.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:2406d034635d1497c596c40c85f86ecf2bf9611c1df73d14078af8444fe48031", size = 587778, upload-time = "2025-08-07T08:25:58.202Z" }, - { url = "https://files.pythonhosted.org/packages/c2/8e/39d0d7401095bed5a5ad5ef304fae96383f9bef40ca3f3a0807ff5b68d9d/rpds_py-0.27.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dea0808153f1fbbad772669d906cddd92100277533a03845de6893cadeffc8be", size = 555247, upload-time = "2025-08-07T08:25:59.707Z" }, - { url = "https://files.pythonhosted.org/packages/e0/04/6b8311e811e620b9eaca67cd80a118ff9159558a719201052a7b2abb88bf/rpds_py-0.27.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d2a81bdcfde4245468f7030a75a37d50400ac2455c3a4819d9d550c937f90ab5", size = 230256, upload-time = "2025-08-07T08:26:01.07Z" }, - { url = "https://files.pythonhosted.org/packages/59/64/72ab5b911fdcc48058359b0e786e5363e3fde885156116026f1a2ba9a5b5/rpds_py-0.27.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e6491658dd2569f05860bad645569145c8626ac231877b0fb2d5f9bcb7054089", size = 371658, upload-time = "2025-08-07T08:26:02.369Z" }, - { url = "https://files.pythonhosted.org/packages/6c/4b/90ff04b4da055db53d8fea57640d8d5d55456343a1ec9a866c0ecfe10fd1/rpds_py-0.27.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec77545d188f8bdd29d42bccb9191682a46fb2e655e3d1fb446d47c55ac3b8d", size = 355529, upload-time = "2025-08-07T08:26:03.83Z" }, - { url = "https://files.pythonhosted.org/packages/a4/be/527491fb1afcd86fc5ce5812eb37bc70428ee017d77fee20de18155c3937/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a4aebf8ca02bbb90a9b3e7a463bbf3bee02ab1c446840ca07b1695a68ce424", size = 382822, upload-time = "2025-08-07T08:26:05.52Z" }, - { url = "https://files.pythonhosted.org/packages/e0/a5/dcdb8725ce11e6d0913e6fcf782a13f4b8a517e8acc70946031830b98441/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44524b96481a4c9b8e6c46d6afe43fa1fb485c261e359fbe32b63ff60e3884d8", size = 397233, upload-time = "2025-08-07T08:26:07.179Z" }, - { url = "https://files.pythonhosted.org/packages/33/f9/0947920d1927e9f144660590cc38cadb0795d78fe0d9aae0ef71c1513b7c/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45d04a73c54b6a5fd2bab91a4b5bc8b426949586e61340e212a8484919183859", size = 514892, upload-time = "2025-08-07T08:26:08.622Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ed/d1343398c1417c68f8daa1afce56ef6ce5cc587daaf98e29347b00a80ff2/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:343cf24de9ed6c728abefc5d5c851d5de06497caa7ac37e5e65dd572921ed1b5", size = 402733, upload-time = "2025-08-07T08:26:10.433Z" }, - { url = "https://files.pythonhosted.org/packages/1d/0b/646f55442cd14014fb64d143428f25667a100f82092c90087b9ea7101c74/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aed8118ae20515974650d08eb724150dc2e20c2814bcc307089569995e88a14", size = 384447, upload-time = "2025-08-07T08:26:11.847Z" }, - { url = "https://files.pythonhosted.org/packages/4b/15/0596ef7529828e33a6c81ecf5013d1dd33a511a3e0be0561f83079cda227/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:af9d4fd79ee1cc8e7caf693ee02737daabfc0fcf2773ca0a4735b356c8ad6f7c", size = 402502, upload-time = "2025-08-07T08:26:13.537Z" }, - { url = "https://files.pythonhosted.org/packages/c3/8d/986af3c42f8454a6cafff8729d99fb178ae9b08a9816325ac7a8fa57c0c0/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f0396e894bd1e66c74ecbc08b4f6a03dc331140942c4b1d345dd131b68574a60", size = 416651, upload-time = "2025-08-07T08:26:14.923Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/b4ec3629b7b447e896eec574469159b5b60b7781d3711c914748bf32de05/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:59714ab0a5af25d723d8e9816638faf7f4254234decb7d212715c1aa71eee7be", size = 559460, upload-time = "2025-08-07T08:26:16.295Z" }, - { url = "https://files.pythonhosted.org/packages/61/63/d1e127b40c3e4733b3a6f26ae7a063cdf2bc1caa5272c89075425c7d397a/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:88051c3b7d5325409f433c5a40328fcb0685fc04e5db49ff936e910901d10114", size = 588072, upload-time = "2025-08-07T08:26:17.776Z" }, - { url = "https://files.pythonhosted.org/packages/04/7e/8ffc71a8f6833d9c9fb999f5b0ee736b8b159fd66968e05c7afc2dbcd57e/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:181bc29e59e5e5e6e9d63b143ff4d5191224d355e246b5a48c88ce6b35c4e466", size = 555083, upload-time = "2025-08-07T08:26:19.301Z" }, +version = "0.27.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/ed/3aef893e2dd30e77e35d20d4ddb45ca459db59cead748cad9796ad479411/rpds_py-0.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:68afeec26d42ab3b47e541b272166a0b4400313946871cba3ed3a4fc0cab1cef", size = 371606, upload-time = "2025-08-27T12:12:25.189Z" }, + { url = "https://files.pythonhosted.org/packages/6d/82/9818b443e5d3eb4c83c3994561387f116aae9833b35c484474769c4a8faf/rpds_py-0.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74e5b2f7bb6fa38b1b10546d27acbacf2a022a8b5543efb06cfebc72a59c85be", size = 353452, upload-time = "2025-08-27T12:12:27.433Z" }, + { url = "https://files.pythonhosted.org/packages/99/c7/d2a110ffaaa397fc6793a83c7bd3545d9ab22658b7cdff05a24a4535cc45/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9024de74731df54546fab0bfbcdb49fae19159ecaecfc8f37c18d2c7e2c0bd61", size = 381519, upload-time = "2025-08-27T12:12:28.719Z" }, + { url = "https://files.pythonhosted.org/packages/5a/bc/e89581d1f9d1be7d0247eaef602566869fdc0d084008ba139e27e775366c/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:31d3ebadefcd73b73928ed0b2fd696f7fefda8629229f81929ac9c1854d0cffb", size = 394424, upload-time = "2025-08-27T12:12:30.207Z" }, + { url = "https://files.pythonhosted.org/packages/ac/2e/36a6861f797530e74bb6ed53495f8741f1ef95939eed01d761e73d559067/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2e7f8f169d775dd9092a1743768d771f1d1300453ddfe6325ae3ab5332b4657", size = 523467, upload-time = "2025-08-27T12:12:31.808Z" }, + { url = "https://files.pythonhosted.org/packages/c4/59/c1bc2be32564fa499f988f0a5c6505c2f4746ef96e58e4d7de5cf923d77e/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d905d16f77eb6ab2e324e09bfa277b4c8e5e6b8a78a3e7ff8f3cdf773b4c013", size = 402660, upload-time = "2025-08-27T12:12:33.444Z" }, + { url = "https://files.pythonhosted.org/packages/0a/ec/ef8bf895f0628dd0a59e54d81caed6891663cb9c54a0f4bb7da918cb88cf/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50c946f048209e6362e22576baea09193809f87687a95a8db24e5fbdb307b93a", size = 384062, upload-time = "2025-08-27T12:12:34.857Z" }, + { url = "https://files.pythonhosted.org/packages/69/f7/f47ff154be8d9a5e691c083a920bba89cef88d5247c241c10b9898f595a1/rpds_py-0.27.1-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:3deab27804d65cd8289eb814c2c0e807c4b9d9916c9225e363cb0cf875eb67c1", size = 401289, upload-time = "2025-08-27T12:12:36.085Z" }, + { url = "https://files.pythonhosted.org/packages/3b/d9/ca410363efd0615814ae579f6829cafb39225cd63e5ea5ed1404cb345293/rpds_py-0.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b61097f7488de4be8244c89915da8ed212832ccf1e7c7753a25a394bf9b1f10", size = 417718, upload-time = "2025-08-27T12:12:37.401Z" }, + { url = "https://files.pythonhosted.org/packages/e3/a0/8cb5c2ff38340f221cc067cc093d1270e10658ba4e8d263df923daa18e86/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a3f29aba6e2d7d90528d3c792555a93497fe6538aa65eb675b44505be747808", size = 558333, upload-time = "2025-08-27T12:12:38.672Z" }, + { url = "https://files.pythonhosted.org/packages/6f/8c/1b0de79177c5d5103843774ce12b84caa7164dfc6cd66378768d37db11bf/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd6cd0485b7d347304067153a6dc1d73f7d4fd995a396ef32a24d24b8ac63ac8", size = 589127, upload-time = "2025-08-27T12:12:41.48Z" }, + { url = "https://files.pythonhosted.org/packages/c8/5e/26abb098d5e01266b0f3a2488d299d19ccc26849735d9d2b95c39397e945/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6f4461bf931108c9fa226ffb0e257c1b18dc2d44cd72b125bec50ee0ab1248a9", size = 554899, upload-time = "2025-08-27T12:12:42.925Z" }, + { url = "https://files.pythonhosted.org/packages/de/41/905cc90ced13550db017f8f20c6d8e8470066c5738ba480d7ba63e3d136b/rpds_py-0.27.1-cp310-cp310-win32.whl", hash = "sha256:ee5422d7fb21f6a00c1901bf6559c49fee13a5159d0288320737bbf6585bd3e4", size = 217450, upload-time = "2025-08-27T12:12:44.813Z" }, + { url = "https://files.pythonhosted.org/packages/75/3d/6bef47b0e253616ccdf67c283e25f2d16e18ccddd38f92af81d5a3420206/rpds_py-0.27.1-cp310-cp310-win_amd64.whl", hash = "sha256:3e039aabf6d5f83c745d5f9a0a381d031e9ed871967c0a5c38d201aca41f3ba1", size = 228447, upload-time = "2025-08-27T12:12:46.204Z" }, + { url = "https://files.pythonhosted.org/packages/b5/c1/7907329fbef97cbd49db6f7303893bd1dd5a4a3eae415839ffdfb0762cae/rpds_py-0.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:be898f271f851f68b318872ce6ebebbc62f303b654e43bf72683dbdc25b7c881", size = 371063, upload-time = "2025-08-27T12:12:47.856Z" }, + { url = "https://files.pythonhosted.org/packages/11/94/2aab4bc86228bcf7c48760990273653a4900de89c7537ffe1b0d6097ed39/rpds_py-0.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62ac3d4e3e07b58ee0ddecd71d6ce3b1637de2d373501412df395a0ec5f9beb5", size = 353210, upload-time = "2025-08-27T12:12:49.187Z" }, + { url = "https://files.pythonhosted.org/packages/3a/57/f5eb3ecf434342f4f1a46009530e93fd201a0b5b83379034ebdb1d7c1a58/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4708c5c0ceb2d034f9991623631d3d23cb16e65c83736ea020cdbe28d57c0a0e", size = 381636, upload-time = "2025-08-27T12:12:50.492Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f4/ef95c5945e2ceb5119571b184dd5a1cc4b8541bbdf67461998cfeac9cb1e/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abfa1171a9952d2e0002aba2ad3780820b00cc3d9c98c6630f2e93271501f66c", size = 394341, upload-time = "2025-08-27T12:12:52.024Z" }, + { url = "https://files.pythonhosted.org/packages/5a/7e/4bd610754bf492d398b61725eb9598ddd5eb86b07d7d9483dbcd810e20bc/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b507d19f817ebaca79574b16eb2ae412e5c0835542c93fe9983f1e432aca195", size = 523428, upload-time = "2025-08-27T12:12:53.779Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e5/059b9f65a8c9149361a8b75094864ab83b94718344db511fd6117936ed2a/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168b025f8fd8d8d10957405f3fdcef3dc20f5982d398f90851f4abc58c566c52", size = 402923, upload-time = "2025-08-27T12:12:55.15Z" }, + { url = "https://files.pythonhosted.org/packages/f5/48/64cabb7daced2968dd08e8a1b7988bf358d7bd5bcd5dc89a652f4668543c/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c6210ef77caa58e16e8c17d35c63fe3f5b60fd9ba9d424470c3400bcf9ed", size = 384094, upload-time = "2025-08-27T12:12:57.194Z" }, + { url = "https://files.pythonhosted.org/packages/ae/e1/dc9094d6ff566bff87add8a510c89b9e158ad2ecd97ee26e677da29a9e1b/rpds_py-0.27.1-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:d252f2d8ca0195faa707f8eb9368955760880b2b42a8ee16d382bf5dd807f89a", size = 401093, upload-time = "2025-08-27T12:12:58.985Z" }, + { url = "https://files.pythonhosted.org/packages/37/8e/ac8577e3ecdd5593e283d46907d7011618994e1d7ab992711ae0f78b9937/rpds_py-0.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6e5e54da1e74b91dbc7996b56640f79b195d5925c2b78efaa8c5d53e1d88edde", size = 417969, upload-time = "2025-08-27T12:13:00.367Z" }, + { url = "https://files.pythonhosted.org/packages/66/6d/87507430a8f74a93556fe55c6485ba9c259949a853ce407b1e23fea5ba31/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ffce0481cc6e95e5b3f0a47ee17ffbd234399e6d532f394c8dce320c3b089c21", size = 558302, upload-time = "2025-08-27T12:13:01.737Z" }, + { url = "https://files.pythonhosted.org/packages/3a/bb/1db4781ce1dda3eecc735e3152659a27b90a02ca62bfeea17aee45cc0fbc/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a205fdfe55c90c2cd8e540ca9ceba65cbe6629b443bc05db1f590a3db8189ff9", size = 589259, upload-time = "2025-08-27T12:13:03.127Z" }, + { url = "https://files.pythonhosted.org/packages/7b/0e/ae1c8943d11a814d01b482e1f8da903f88047a962dff9bbdadf3bd6e6fd1/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:689fb5200a749db0415b092972e8eba85847c23885c8543a8b0f5c009b1a5948", size = 554983, upload-time = "2025-08-27T12:13:04.516Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/0b2a55415931db4f112bdab072443ff76131b5ac4f4dc98d10d2d357eb03/rpds_py-0.27.1-cp311-cp311-win32.whl", hash = "sha256:3182af66048c00a075010bc7f4860f33913528a4b6fc09094a6e7598e462fe39", size = 217154, upload-time = "2025-08-27T12:13:06.278Z" }, + { url = "https://files.pythonhosted.org/packages/24/75/3b7ffe0d50dc86a6a964af0d1cc3a4a2cdf437cb7b099a4747bbb96d1819/rpds_py-0.27.1-cp311-cp311-win_amd64.whl", hash = "sha256:b4938466c6b257b2f5c4ff98acd8128ec36b5059e5c8f8372d79316b1c36bb15", size = 228627, upload-time = "2025-08-27T12:13:07.625Z" }, + { url = "https://files.pythonhosted.org/packages/8d/3f/4fd04c32abc02c710f09a72a30c9a55ea3cc154ef8099078fd50a0596f8e/rpds_py-0.27.1-cp311-cp311-win_arm64.whl", hash = "sha256:2f57af9b4d0793e53266ee4325535a31ba48e2f875da81a9177c9926dfa60746", size = 220998, upload-time = "2025-08-27T12:13:08.972Z" }, + { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" }, + { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" }, + { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" }, + { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" }, + { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" }, + { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" }, + { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" }, + { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" }, + { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" }, + { url = "https://files.pythonhosted.org/packages/cc/77/610aeee8d41e39080c7e14afa5387138e3c9fa9756ab893d09d99e7d8e98/rpds_py-0.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b", size = 361741, upload-time = "2025-08-27T12:13:31.039Z" }, + { url = "https://files.pythonhosted.org/packages/3a/fc/c43765f201c6a1c60be2043cbdb664013def52460a4c7adace89d6682bf4/rpds_py-0.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf", size = 345574, upload-time = "2025-08-27T12:13:32.902Z" }, + { url = "https://files.pythonhosted.org/packages/20/42/ee2b2ca114294cd9847d0ef9c26d2b0851b2e7e00bf14cc4c0b581df0fc3/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83", size = 385051, upload-time = "2025-08-27T12:13:34.228Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e8/1e430fe311e4799e02e2d1af7c765f024e95e17d651612425b226705f910/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78827d7ac08627ea2c8e02c9e5b41180ea5ea1f747e9db0915e3adf36b62dcf", size = 398395, upload-time = "2025-08-27T12:13:36.132Z" }, + { url = "https://files.pythonhosted.org/packages/82/95/9dc227d441ff2670651c27a739acb2535ccaf8b351a88d78c088965e5996/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae92443798a40a92dc5f0b01d8a7c93adde0c4dc965310a29ae7c64d72b9fad2", size = 524334, upload-time = "2025-08-27T12:13:37.562Z" }, + { url = "https://files.pythonhosted.org/packages/87/01/a670c232f401d9ad461d9a332aa4080cd3cb1d1df18213dbd0d2a6a7ab51/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c46c9dd2403b66a2a3b9720ec4b74d4ab49d4fabf9f03dfdce2d42af913fe8d0", size = 407691, upload-time = "2025-08-27T12:13:38.94Z" }, + { url = "https://files.pythonhosted.org/packages/03/36/0a14aebbaa26fe7fab4780c76f2239e76cc95a0090bdb25e31d95c492fcd/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2efe4eb1d01b7f5f1939f4ef30ecea6c6b3521eec451fb93191bf84b2a522418", size = 386868, upload-time = "2025-08-27T12:13:40.192Z" }, + { url = "https://files.pythonhosted.org/packages/3b/03/8c897fb8b5347ff6c1cc31239b9611c5bf79d78c984430887a353e1409a1/rpds_py-0.27.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:15d3b4d83582d10c601f481eca29c3f138d44c92187d197aff663a269197c02d", size = 405469, upload-time = "2025-08-27T12:13:41.496Z" }, + { url = "https://files.pythonhosted.org/packages/da/07/88c60edc2df74850d496d78a1fdcdc7b54360a7f610a4d50008309d41b94/rpds_py-0.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4ed2e16abbc982a169d30d1a420274a709949e2cbdef119fe2ec9d870b42f274", size = 422125, upload-time = "2025-08-27T12:13:42.802Z" }, + { url = "https://files.pythonhosted.org/packages/6b/86/5f4c707603e41b05f191a749984f390dabcbc467cf833769b47bf14ba04f/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a75f305c9b013289121ec0f1181931975df78738cdf650093e6b86d74aa7d8dd", size = 562341, upload-time = "2025-08-27T12:13:44.472Z" }, + { url = "https://files.pythonhosted.org/packages/b2/92/3c0cb2492094e3cd9baf9e49bbb7befeceb584ea0c1a8b5939dca4da12e5/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:67ce7620704745881a3d4b0ada80ab4d99df390838839921f99e63c474f82cf2", size = 592511, upload-time = "2025-08-27T12:13:45.898Z" }, + { url = "https://files.pythonhosted.org/packages/10/bb/82e64fbb0047c46a168faa28d0d45a7851cd0582f850b966811d30f67ad8/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d992ac10eb86d9b6f369647b6a3f412fc0075cfd5d799530e84d335e440a002", size = 557736, upload-time = "2025-08-27T12:13:47.408Z" }, + { url = "https://files.pythonhosted.org/packages/00/95/3c863973d409210da7fb41958172c6b7dbe7fc34e04d3cc1f10bb85e979f/rpds_py-0.27.1-cp313-cp313-win32.whl", hash = "sha256:4f75e4bd8ab8db624e02c8e2fc4063021b58becdbe6df793a8111d9343aec1e3", size = 221462, upload-time = "2025-08-27T12:13:48.742Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2c/5867b14a81dc217b56d95a9f2a40fdbc56a1ab0181b80132beeecbd4b2d6/rpds_py-0.27.1-cp313-cp313-win_amd64.whl", hash = "sha256:f9025faafc62ed0b75a53e541895ca272815bec18abe2249ff6501c8f2e12b83", size = 232034, upload-time = "2025-08-27T12:13:50.11Z" }, + { url = "https://files.pythonhosted.org/packages/c7/78/3958f3f018c01923823f1e47f1cc338e398814b92d83cd278364446fac66/rpds_py-0.27.1-cp313-cp313-win_arm64.whl", hash = "sha256:ed10dc32829e7d222b7d3b93136d25a406ba9788f6a7ebf6809092da1f4d279d", size = 222392, upload-time = "2025-08-27T12:13:52.587Z" }, + { url = "https://files.pythonhosted.org/packages/01/76/1cdf1f91aed5c3a7bf2eba1f1c4e4d6f57832d73003919a20118870ea659/rpds_py-0.27.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:92022bbbad0d4426e616815b16bc4127f83c9a74940e1ccf3cfe0b387aba0228", size = 358355, upload-time = "2025-08-27T12:13:54.012Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6f/bf142541229374287604caf3bb2a4ae17f0a580798fd72d3b009b532db4e/rpds_py-0.27.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47162fdab9407ec3f160805ac3e154df042e577dd53341745fc7fb3f625e6d92", size = 342138, upload-time = "2025-08-27T12:13:55.791Z" }, + { url = "https://files.pythonhosted.org/packages/1a/77/355b1c041d6be40886c44ff5e798b4e2769e497b790f0f7fd1e78d17e9a8/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb89bec23fddc489e5d78b550a7b773557c9ab58b7946154a10a6f7a214a48b2", size = 380247, upload-time = "2025-08-27T12:13:57.683Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a4/d9cef5c3946ea271ce2243c51481971cd6e34f21925af2783dd17b26e815/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e48af21883ded2b3e9eb48cb7880ad8598b31ab752ff3be6457001d78f416723", size = 390699, upload-time = "2025-08-27T12:13:59.137Z" }, + { url = "https://files.pythonhosted.org/packages/3a/06/005106a7b8c6c1a7e91b73169e49870f4af5256119d34a361ae5240a0c1d/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f5b7bd8e219ed50299e58551a410b64daafb5017d54bbe822e003856f06a802", size = 521852, upload-time = "2025-08-27T12:14:00.583Z" }, + { url = "https://files.pythonhosted.org/packages/e5/3e/50fb1dac0948e17a02eb05c24510a8fe12d5ce8561c6b7b7d1339ab7ab9c/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08f1e20bccf73b08d12d804d6e1c22ca5530e71659e6673bce31a6bb71c1e73f", size = 402582, upload-time = "2025-08-27T12:14:02.034Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b0/f4e224090dc5b0ec15f31a02d746ab24101dd430847c4d99123798661bfc/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dc5dceeaefcc96dc192e3a80bbe1d6c410c469e97bdd47494a7d930987f18b2", size = 384126, upload-time = "2025-08-27T12:14:03.437Z" }, + { url = "https://files.pythonhosted.org/packages/54/77/ac339d5f82b6afff1df8f0fe0d2145cc827992cb5f8eeb90fc9f31ef7a63/rpds_py-0.27.1-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d76f9cc8665acdc0c9177043746775aa7babbf479b5520b78ae4002d889f5c21", size = 399486, upload-time = "2025-08-27T12:14:05.443Z" }, + { url = "https://files.pythonhosted.org/packages/d6/29/3e1c255eee6ac358c056a57d6d6869baa00a62fa32eea5ee0632039c50a3/rpds_py-0.27.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:134fae0e36022edad8290a6661edf40c023562964efea0cc0ec7f5d392d2aaef", size = 414832, upload-time = "2025-08-27T12:14:06.902Z" }, + { url = "https://files.pythonhosted.org/packages/3f/db/6d498b844342deb3fa1d030598db93937a9964fcf5cb4da4feb5f17be34b/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb11a4f1b2b63337cfd3b4d110af778a59aae51c81d195768e353d8b52f88081", size = 557249, upload-time = "2025-08-27T12:14:08.37Z" }, + { url = "https://files.pythonhosted.org/packages/60/f3/690dd38e2310b6f68858a331399b4d6dbb9132c3e8ef8b4333b96caf403d/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:13e608ac9f50a0ed4faec0e90ece76ae33b34c0e8656e3dceb9a7db994c692cd", size = 587356, upload-time = "2025-08-27T12:14:10.034Z" }, + { url = "https://files.pythonhosted.org/packages/86/e3/84507781cccd0145f35b1dc32c72675200c5ce8d5b30f813e49424ef68fc/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dd2135527aa40f061350c3f8f89da2644de26cd73e4de458e79606384f4f68e7", size = 555300, upload-time = "2025-08-27T12:14:11.783Z" }, + { url = "https://files.pythonhosted.org/packages/e5/ee/375469849e6b429b3516206b4580a79e9ef3eb12920ddbd4492b56eaacbe/rpds_py-0.27.1-cp313-cp313t-win32.whl", hash = "sha256:3020724ade63fe320a972e2ffd93b5623227e684315adce194941167fee02688", size = 216714, upload-time = "2025-08-27T12:14:13.629Z" }, + { url = "https://files.pythonhosted.org/packages/21/87/3fc94e47c9bd0742660e84706c311a860dcae4374cf4a03c477e23ce605a/rpds_py-0.27.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8ee50c3e41739886606388ba3ab3ee2aae9f35fb23f833091833255a31740797", size = 228943, upload-time = "2025-08-27T12:14:14.937Z" }, + { url = "https://files.pythonhosted.org/packages/70/36/b6e6066520a07cf029d385de869729a895917b411e777ab1cde878100a1d/rpds_py-0.27.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:acb9aafccaae278f449d9c713b64a9e68662e7799dbd5859e2c6b3c67b56d334", size = 362472, upload-time = "2025-08-27T12:14:16.333Z" }, + { url = "https://files.pythonhosted.org/packages/af/07/b4646032e0dcec0df9c73a3bd52f63bc6c5f9cda992f06bd0e73fe3fbebd/rpds_py-0.27.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b7fb801aa7f845ddf601c49630deeeccde7ce10065561d92729bfe81bd21fb33", size = 345676, upload-time = "2025-08-27T12:14:17.764Z" }, + { url = "https://files.pythonhosted.org/packages/b0/16/2f1003ee5d0af4bcb13c0cf894957984c32a6751ed7206db2aee7379a55e/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0dd05afb46597b9a2e11c351e5e4283c741237e7f617ffb3252780cca9336a", size = 385313, upload-time = "2025-08-27T12:14:19.829Z" }, + { url = "https://files.pythonhosted.org/packages/05/cd/7eb6dd7b232e7f2654d03fa07f1414d7dfc980e82ba71e40a7c46fd95484/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b6dfb0e058adb12d8b1d1b25f686e94ffa65d9995a5157afe99743bf7369d62b", size = 399080, upload-time = "2025-08-27T12:14:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/20/51/5829afd5000ec1cb60f304711f02572d619040aa3ec033d8226817d1e571/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed090ccd235f6fa8bb5861684567f0a83e04f52dfc2e5c05f2e4b1309fcf85e7", size = 523868, upload-time = "2025-08-27T12:14:23.485Z" }, + { url = "https://files.pythonhosted.org/packages/05/2c/30eebca20d5db95720ab4d2faec1b5e4c1025c473f703738c371241476a2/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf876e79763eecf3e7356f157540d6a093cef395b65514f17a356f62af6cc136", size = 408750, upload-time = "2025-08-27T12:14:24.924Z" }, + { url = "https://files.pythonhosted.org/packages/90/1a/cdb5083f043597c4d4276eae4e4c70c55ab5accec078da8611f24575a367/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12ed005216a51b1d6e2b02a7bd31885fe317e45897de81d86dcce7d74618ffff", size = 387688, upload-time = "2025-08-27T12:14:27.537Z" }, + { url = "https://files.pythonhosted.org/packages/7c/92/cf786a15320e173f945d205ab31585cc43969743bb1a48b6888f7a2b0a2d/rpds_py-0.27.1-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:ee4308f409a40e50593c7e3bb8cbe0b4d4c66d1674a316324f0c2f5383b486f9", size = 407225, upload-time = "2025-08-27T12:14:28.981Z" }, + { url = "https://files.pythonhosted.org/packages/33/5c/85ee16df5b65063ef26017bef33096557a4c83fbe56218ac7cd8c235f16d/rpds_py-0.27.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b08d152555acf1f455154d498ca855618c1378ec810646fcd7c76416ac6dc60", size = 423361, upload-time = "2025-08-27T12:14:30.469Z" }, + { url = "https://files.pythonhosted.org/packages/4b/8e/1c2741307fcabd1a334ecf008e92c4f47bb6f848712cf15c923becfe82bb/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dce51c828941973a5684d458214d3a36fcd28da3e1875d659388f4f9f12cc33e", size = 562493, upload-time = "2025-08-27T12:14:31.987Z" }, + { url = "https://files.pythonhosted.org/packages/04/03/5159321baae9b2222442a70c1f988cbbd66b9be0675dd3936461269be360/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c1476d6f29eb81aa4151c9a31219b03f1f798dc43d8af1250a870735516a1212", size = 592623, upload-time = "2025-08-27T12:14:33.543Z" }, + { url = "https://files.pythonhosted.org/packages/ff/39/c09fd1ad28b85bc1d4554a8710233c9f4cefd03d7717a1b8fbfd171d1167/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ce0cac322b0d69b63c9cdb895ee1b65805ec9ffad37639f291dd79467bee675", size = 558800, upload-time = "2025-08-27T12:14:35.436Z" }, + { url = "https://files.pythonhosted.org/packages/c5/d6/99228e6bbcf4baa764b18258f519a9035131d91b538d4e0e294313462a98/rpds_py-0.27.1-cp314-cp314-win32.whl", hash = "sha256:dfbfac137d2a3d0725758cd141f878bf4329ba25e34979797c89474a89a8a3a3", size = 221943, upload-time = "2025-08-27T12:14:36.898Z" }, + { url = "https://files.pythonhosted.org/packages/be/07/c802bc6b8e95be83b79bdf23d1aa61d68324cb1006e245d6c58e959e314d/rpds_py-0.27.1-cp314-cp314-win_amd64.whl", hash = "sha256:a6e57b0abfe7cc513450fcf529eb486b6e4d3f8aee83e92eb5f1ef848218d456", size = 233739, upload-time = "2025-08-27T12:14:38.386Z" }, + { url = "https://files.pythonhosted.org/packages/c8/89/3e1b1c16d4c2d547c5717377a8df99aee8099ff050f87c45cb4d5fa70891/rpds_py-0.27.1-cp314-cp314-win_arm64.whl", hash = "sha256:faf8d146f3d476abfee026c4ae3bdd9ca14236ae4e4c310cbd1cf75ba33d24a3", size = 223120, upload-time = "2025-08-27T12:14:39.82Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/dc7931dc2fa4a6e46b2a4fa744a9fe5c548efd70e0ba74f40b39fa4a8c10/rpds_py-0.27.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:ba81d2b56b6d4911ce735aad0a1d4495e808b8ee4dc58715998741a26874e7c2", size = 358944, upload-time = "2025-08-27T12:14:41.199Z" }, + { url = "https://files.pythonhosted.org/packages/e6/22/4af76ac4e9f336bfb1a5f240d18a33c6b2fcaadb7472ac7680576512b49a/rpds_py-0.27.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:84f7d509870098de0e864cad0102711c1e24e9b1a50ee713b65928adb22269e4", size = 342283, upload-time = "2025-08-27T12:14:42.699Z" }, + { url = "https://files.pythonhosted.org/packages/1c/15/2a7c619b3c2272ea9feb9ade67a45c40b3eeb500d503ad4c28c395dc51b4/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e960fc78fecd1100539f14132425e1d5fe44ecb9239f8f27f079962021523e", size = 380320, upload-time = "2025-08-27T12:14:44.157Z" }, + { url = "https://files.pythonhosted.org/packages/a2/7d/4c6d243ba4a3057e994bb5bedd01b5c963c12fe38dde707a52acdb3849e7/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:62f85b665cedab1a503747617393573995dac4600ff51869d69ad2f39eb5e817", size = 391760, upload-time = "2025-08-27T12:14:45.845Z" }, + { url = "https://files.pythonhosted.org/packages/b4/71/b19401a909b83bcd67f90221330bc1ef11bc486fe4e04c24388d28a618ae/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fed467af29776f6556250c9ed85ea5a4dd121ab56a5f8b206e3e7a4c551e48ec", size = 522476, upload-time = "2025-08-27T12:14:47.364Z" }, + { url = "https://files.pythonhosted.org/packages/e4/44/1a3b9715c0455d2e2f0f6df5ee6d6f5afdc423d0773a8a682ed2b43c566c/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2729615f9d430af0ae6b36cf042cb55c0936408d543fb691e1a9e36648fd35a", size = 403418, upload-time = "2025-08-27T12:14:49.991Z" }, + { url = "https://files.pythonhosted.org/packages/1c/4b/fb6c4f14984eb56673bc868a66536f53417ddb13ed44b391998100a06a96/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b207d881a9aef7ba753d69c123a35d96ca7cb808056998f6b9e8747321f03b8", size = 384771, upload-time = "2025-08-27T12:14:52.159Z" }, + { url = "https://files.pythonhosted.org/packages/c0/56/d5265d2d28b7420d7b4d4d85cad8ef891760f5135102e60d5c970b976e41/rpds_py-0.27.1-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:639fd5efec029f99b79ae47e5d7e00ad8a773da899b6309f6786ecaf22948c48", size = 400022, upload-time = "2025-08-27T12:14:53.859Z" }, + { url = "https://files.pythonhosted.org/packages/8f/e9/9f5fc70164a569bdd6ed9046486c3568d6926e3a49bdefeeccfb18655875/rpds_py-0.27.1-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fecc80cb2a90e28af8a9b366edacf33d7a91cbfe4c2c4544ea1246e949cfebeb", size = 416787, upload-time = "2025-08-27T12:14:55.673Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/56dd03430ba491db943a81dcdef115a985aac5f44f565cd39a00c766d45c/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42a89282d711711d0a62d6f57d81aa43a1368686c45bc1c46b7f079d55692734", size = 557538, upload-time = "2025-08-27T12:14:57.245Z" }, + { url = "https://files.pythonhosted.org/packages/3f/36/92cc885a3129993b1d963a2a42ecf64e6a8e129d2c7cc980dbeba84e55fb/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:cf9931f14223de59551ab9d38ed18d92f14f055a5f78c1d8ad6493f735021bbb", size = 588512, upload-time = "2025-08-27T12:14:58.728Z" }, + { url = "https://files.pythonhosted.org/packages/dd/10/6b283707780a81919f71625351182b4f98932ac89a09023cb61865136244/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f39f58a27cc6e59f432b568ed8429c7e1641324fbe38131de852cd77b2d534b0", size = 555813, upload-time = "2025-08-27T12:15:00.334Z" }, + { url = "https://files.pythonhosted.org/packages/04/2e/30b5ea18c01379da6272a92825dd7e53dc9d15c88a19e97932d35d430ef7/rpds_py-0.27.1-cp314-cp314t-win32.whl", hash = "sha256:d5fa0ee122dc09e23607a28e6d7b150da16c662e66409bbe85230e4c85bb528a", size = 217385, upload-time = "2025-08-27T12:15:01.937Z" }, + { url = "https://files.pythonhosted.org/packages/32/7d/97119da51cb1dd3f2f3c0805f155a3aa4a95fa44fe7d78ae15e69edf4f34/rpds_py-0.27.1-cp314-cp314t-win_amd64.whl", hash = "sha256:6567d2bb951e21232c2f660c24cf3470bb96de56cdcb3f071a83feeaff8a2772", size = 230097, upload-time = "2025-08-27T12:15:03.961Z" }, + { url = "https://files.pythonhosted.org/packages/d5/63/b7cc415c345625d5e62f694ea356c58fb964861409008118f1245f8c3347/rpds_py-0.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7ba22cb9693df986033b91ae1d7a979bc399237d45fccf875b76f62bb9e52ddf", size = 371360, upload-time = "2025-08-27T12:15:29.218Z" }, + { url = "https://files.pythonhosted.org/packages/e5/8c/12e1b24b560cf378b8ffbdb9dc73abd529e1adcfcf82727dfd29c4a7b88d/rpds_py-0.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b640501be9288c77738b5492b3fd3abc4ba95c50c2e41273c8a1459f08298d3", size = 353933, upload-time = "2025-08-27T12:15:30.837Z" }, + { url = "https://files.pythonhosted.org/packages/9b/85/1bb2210c1f7a1b99e91fea486b9f0f894aa5da3a5ec7097cbad7dec6d40f/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb08b65b93e0c6dd70aac7f7890a9c0938d5ec71d5cb32d45cf844fb8ae47636", size = 382962, upload-time = "2025-08-27T12:15:32.348Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c9/a839b9f219cf80ed65f27a7f5ddbb2809c1b85c966020ae2dff490e0b18e/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d7ff07d696a7a38152ebdb8212ca9e5baab56656749f3d6004b34ab726b550b8", size = 394412, upload-time = "2025-08-27T12:15:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/02/2d/b1d7f928b0b1f4fc2e0133e8051d199b01d7384875adc63b6ddadf3de7e5/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb7c72262deae25366e3b6c0c0ba46007967aea15d1eea746e44ddba8ec58dcc", size = 523972, upload-time = "2025-08-27T12:15:35.377Z" }, + { url = "https://files.pythonhosted.org/packages/a9/af/2cbf56edd2d07716df1aec8a726b3159deb47cb5c27e1e42b71d705a7c2f/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b002cab05d6339716b03a4a3a2ce26737f6231d7b523f339fa061d53368c9d8", size = 403273, upload-time = "2025-08-27T12:15:37.051Z" }, + { url = "https://files.pythonhosted.org/packages/c0/93/425e32200158d44ff01da5d9612c3b6711fe69f606f06e3895511f17473b/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23f6b69d1c26c4704fec01311963a41d7de3ee0570a84ebde4d544e5a1859ffc", size = 385278, upload-time = "2025-08-27T12:15:38.571Z" }, + { url = "https://files.pythonhosted.org/packages/eb/1a/1a04a915ecd0551bfa9e77b7672d1937b4b72a0fc204a17deef76001cfb2/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:530064db9146b247351f2a0250b8f00b289accea4596a033e94be2389977de71", size = 402084, upload-time = "2025-08-27T12:15:40.529Z" }, + { url = "https://files.pythonhosted.org/packages/51/f7/66585c0fe5714368b62951d2513b684e5215beaceab2c6629549ddb15036/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b90b0496570bd6b0321724a330d8b545827c4df2034b6ddfc5f5275f55da2ad", size = 419041, upload-time = "2025-08-27T12:15:42.191Z" }, + { url = "https://files.pythonhosted.org/packages/8e/7e/83a508f6b8e219bba2d4af077c35ba0e0cdd35a751a3be6a7cba5a55ad71/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:879b0e14a2da6a1102a3fc8af580fc1ead37e6d6692a781bd8c83da37429b5ab", size = 560084, upload-time = "2025-08-27T12:15:43.839Z" }, + { url = "https://files.pythonhosted.org/packages/66/66/bb945683b958a1b19eb0fe715594630d0f36396ebdef4d9b89c2fa09aa56/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:0d807710df3b5faa66c731afa162ea29717ab3be17bdc15f90f2d9f183da4059", size = 590115, upload-time = "2025-08-27T12:15:46.647Z" }, + { url = "https://files.pythonhosted.org/packages/12/00/ccfaafaf7db7e7adace915e5c2f2c2410e16402561801e9c7f96683002d3/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:3adc388fc3afb6540aec081fa59e6e0d3908722771aa1e37ffe22b220a436f0b", size = 556561, upload-time = "2025-08-27T12:15:48.219Z" }, + { url = "https://files.pythonhosted.org/packages/e1/b7/92b6ed9aad103bfe1c45df98453dfae40969eef2cb6c6239c58d7e96f1b3/rpds_py-0.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c796c0c1cc68cb08b0284db4229f5af76168172670c74908fdbd4b7d7f515819", size = 229125, upload-time = "2025-08-27T12:15:49.956Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ed/e1fba02de17f4f76318b834425257c8ea297e415e12c68b4361f63e8ae92/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdfe4bb2f9fe7458b7453ad3c33e726d6d1c7c0a72960bcc23800d77384e42df", size = 371402, upload-time = "2025-08-27T12:15:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/af/7c/e16b959b316048b55585a697e94add55a4ae0d984434d279ea83442e460d/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8fabb8fd848a5f75a2324e4a84501ee3a5e3c78d8603f83475441866e60b94a3", size = 354084, upload-time = "2025-08-27T12:15:53.219Z" }, + { url = "https://files.pythonhosted.org/packages/de/c1/ade645f55de76799fdd08682d51ae6724cb46f318573f18be49b1e040428/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda8719d598f2f7f3e0f885cba8646644b55a187762bec091fa14a2b819746a9", size = 383090, upload-time = "2025-08-27T12:15:55.158Z" }, + { url = "https://files.pythonhosted.org/packages/1f/27/89070ca9b856e52960da1472efcb6c20ba27cfe902f4f23ed095b9cfc61d/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c64d07e95606ec402a0a1c511fe003873fa6af630bda59bac77fac8b4318ebc", size = 394519, upload-time = "2025-08-27T12:15:57.238Z" }, + { url = "https://files.pythonhosted.org/packages/b3/28/be120586874ef906aa5aeeae95ae8df4184bc757e5b6bd1c729ccff45ed5/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93a2ed40de81bcff59aabebb626562d48332f3d028ca2036f1d23cbb52750be4", size = 523817, upload-time = "2025-08-27T12:15:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/70cc197bc11cfcde02a86f36ac1eed15c56667c2ebddbdb76a47e90306da/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:387ce8c44ae94e0ec50532d9cb0edce17311024c9794eb196b90e1058aadeb66", size = 403240, upload-time = "2025-08-27T12:16:00.923Z" }, + { url = "https://files.pythonhosted.org/packages/cf/35/46936cca449f7f518f2f4996e0e8344db4b57e2081e752441154089d2a5f/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf94f812c95b5e60ebaf8bfb1898a7d7cb9c1af5744d4a67fa47796e0465d4e", size = 385194, upload-time = "2025-08-27T12:16:02.802Z" }, + { url = "https://files.pythonhosted.org/packages/e1/62/29c0d3e5125c3270b51415af7cbff1ec587379c84f55a5761cc9efa8cd06/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4848ca84d6ded9b58e474dfdbad4b8bfb450344c0551ddc8d958bf4b36aa837c", size = 402086, upload-time = "2025-08-27T12:16:04.806Z" }, + { url = "https://files.pythonhosted.org/packages/8f/66/03e1087679227785474466fdd04157fb793b3b76e3fcf01cbf4c693c1949/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bde09cbcf2248b73c7c323be49b280180ff39fadcfe04e7b6f54a678d02a7cf", size = 419272, upload-time = "2025-08-27T12:16:06.471Z" }, + { url = "https://files.pythonhosted.org/packages/6a/24/e3e72d265121e00b063aef3e3501e5b2473cf1b23511d56e529531acf01e/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:94c44ee01fd21c9058f124d2d4f0c9dc7634bec93cd4b38eefc385dabe71acbf", size = 560003, upload-time = "2025-08-27T12:16:08.06Z" }, + { url = "https://files.pythonhosted.org/packages/26/ca/f5a344c534214cc2d41118c0699fffbdc2c1bc7046f2a2b9609765ab9c92/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:df8b74962e35c9249425d90144e721eed198e6555a0e22a563d29fe4486b51f6", size = 590482, upload-time = "2025-08-27T12:16:10.137Z" }, + { url = "https://files.pythonhosted.org/packages/ce/08/4349bdd5c64d9d193c360aa9db89adeee6f6682ab8825dca0a3f535f434f/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dc23e6820e3b40847e2f4a7726462ba0cf53089512abe9ee16318c366494c17a", size = 556523, upload-time = "2025-08-27T12:16:12.188Z" }, ] [[package]] @@ -1553,27 +1679,27 @@ wheels = [ [[package]] name = "s3transfer" -version = "0.13.1" +version = "0.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6d/05/d52bf1e65044b4e5e27d4e63e8d1579dbdec54fce685908ae09bc3720030/s3transfer-0.13.1.tar.gz", hash = "sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf", size = 150589, upload-time = "2025-07-18T19:22:42.31Z" } +sdist = { url = "https://files.pythonhosted.org/packages/62/74/8d69dcb7a9efe8baa2046891735e5dfe433ad558ae23d9e3c14c633d1d58/s3transfer-0.14.0.tar.gz", hash = "sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125", size = 151547, upload-time = "2025-09-09T19:23:31.089Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/4f/d073e09df851cfa251ef7840007d04db3293a0482ce607d2b993926089be/s3transfer-0.13.1-py3-none-any.whl", hash = "sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724", size = 85308, upload-time = "2025-07-18T19:22:40.947Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712, upload-time = "2025-09-09T19:23:30.041Z" }, ] [[package]] name = "secretstorage" -version = "3.3.3" +version = "3.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "jeepney" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/53/a4/f48c9d79cb507ed1373477dbceaba7401fd8a23af63b837fa61f1dcd3691/SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", size = 19739, upload-time = "2022-08-13T16:22:46.976Z" } +sdist = { url = "https://files.pythonhosted.org/packages/31/9f/11ef35cf1027c1339552ea7bfe6aaa74a8516d8b5caf6e7d338daf54fd80/secretstorage-3.4.0.tar.gz", hash = "sha256:c46e216d6815aff8a8a18706a2fbfd8d53fcbb0dce99301881687a1b0289ef7c", size = 19748, upload-time = "2025-09-09T16:42:13.859Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99", size = 15221, upload-time = "2022-08-13T16:22:44.457Z" }, + { url = "https://files.pythonhosted.org/packages/91/ff/2e2eed29e02c14a5cb6c57f09b2d5b40e65d6cc71f45b52e0be295ccbc2f/secretstorage-3.4.0-py3-none-any.whl", hash = "sha256:0e3b6265c2c63509fb7415717607e4b2c9ab767b7f344a57473b779ca13bd02e", size = 15272, upload-time = "2025-09-09T16:42:12.744Z" }, ] [[package]] @@ -1632,41 +1758,51 @@ wheels = [ [[package]] name = "tomli" -version = "2.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, - { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, - { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, - { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, - { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, - { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, - { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, - { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, - { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, - { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, - { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, - { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, - { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, - { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, - { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, - { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, - { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, - { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, - { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, - { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, - { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, - { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, - { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, - { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, - { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, - { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, - { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, - { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, - { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" }, + { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" }, + { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" }, + { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" }, + { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" }, + { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" }, + { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" }, + { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" }, + { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" }, + { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" }, + { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" }, + { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" }, + { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" }, + { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" }, + { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" }, + { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" }, + { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" }, + { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" }, + { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" }, + { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" }, + { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" }, + { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" }, + { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" }, + { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" }, + { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" }, + { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" }, + { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, ] [[package]] @@ -1701,16 +1837,16 @@ wheels = [ [[package]] name = "trove-classifiers" -version = "2025.8.6.13" +version = "2025.9.11.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/21/707af14daa638b0df15b5d5700349e0abdd3e5140069f9ab6e0ccb922806/trove_classifiers-2025.8.6.13.tar.gz", hash = "sha256:5a0abad839d2ed810f213ab133d555d267124ddea29f1d8a50d6eca12a50ae6e", size = 16932, upload-time = "2025-08-06T13:26:26.479Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/9a/778622bc06632529817c3c524c82749a112603ae2bbcf72ee3eb33a2c4f1/trove_classifiers-2025.9.11.17.tar.gz", hash = "sha256:931ca9841a5e9c9408bc2ae67b50d28acf85bef56219b56860876dd1f2d024dd", size = 16975, upload-time = "2025-09-11T17:07:50.97Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/44/323a87d78f04d5329092aada803af3612dd004a64b69ba8b13046601a8c9/trove_classifiers-2025.8.6.13-py3-none-any.whl", hash = "sha256:c4e7fc83012770d80b3ae95816111c32b085716374dccee0d3fbf5c235495f9f", size = 14121, upload-time = "2025-08-06T13:26:25.063Z" }, + { url = "https://files.pythonhosted.org/packages/e1/85/a4ff8758c66f1fc32aa5e9a145908394bf9cf1c79ffd1113cfdeb77e74e4/trove_classifiers-2025.9.11.17-py3-none-any.whl", hash = "sha256:5d392f2d244deb1866556457d6f3516792124a23d1c3a463a2e8668a5d1c15dd", size = 14158, upload-time = "2025-09-11T17:07:49.886Z" }, ] [[package]] name = "twine" -version = "6.1.0" +version = "6.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "id" }, @@ -1723,18 +1859,18 @@ dependencies = [ { name = "rich" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c8/a2/6df94fc5c8e2170d21d7134a565c3a8fb84f9797c1dd65a5976aaf714418/twine-6.1.0.tar.gz", hash = "sha256:be324f6272eff91d07ee93f251edf232fc647935dd585ac003539b42404a8dbd", size = 168404, upload-time = "2025-01-21T18:45:26.758Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/a8/949edebe3a82774c1ec34f637f5dd82d1cf22c25e963b7d63771083bbee5/twine-6.2.0.tar.gz", hash = "sha256:e5ed0d2fd70c9959770dce51c8f39c8945c574e18173a7b81802dab51b4b75cf", size = 172262, upload-time = "2025-09-04T15:43:17.255Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/b6/74e927715a285743351233f33ea3c684528a0d374d2e43ff9ce9585b73fe/twine-6.1.0-py3-none-any.whl", hash = "sha256:a47f973caf122930bf0fbbf17f80b83bc1602c9ce393c7845f289a3001dc5384", size = 40791, upload-time = "2025-01-21T18:45:24.584Z" }, + { url = "https://files.pythonhosted.org/packages/3a/7a/882d99539b19b1490cac5d77c67338d126e4122c8276bf640e411650c830/twine-6.2.0-py3-none-any.whl", hash = "sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8", size = 42727, upload-time = "2025-09-04T15:43:15.994Z" }, ] [[package]] name = "typing-extensions" -version = "4.14.1" +version = "4.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] @@ -1769,33 +1905,33 @@ wheels = [ [[package]] name = "uv" -version = "0.8.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a8/c1/765112567045a2219979d1a7038e4a2afbddd0637446556b089e77252528/uv-0.8.11.tar.gz", hash = "sha256:d98105244b895c6026e9f3d86f200b70039d39a5f4866022fae664ed935530f3", size = 3504312, upload-time = "2025-08-14T19:48:18.071Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/2f/6703896c45d29b44e5954bb283f00616387cef7ae80188226dac87aff93d/uv-0.8.11-py3-none-linux_armv6l.whl", hash = "sha256:1be7cbc874980dc3e5e0c40fdb3787013a35cce64485f7685fc4b0ee550f7c0c", size = 18497046, upload-time = "2025-08-14T19:47:28.18Z" }, - { url = "https://files.pythonhosted.org/packages/61/fe/3ae518ea5a6c2e4fd3d0174486c841bd85e676b3971d9553445ab57319d9/uv-0.8.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:84c888cc7b3310aada6058ce964d9b48d4f7801add6f1236548adeb262c637bf", size = 18573000, upload-time = "2025-08-14T19:47:32.156Z" }, - { url = "https://files.pythonhosted.org/packages/00/21/6a1cd01103aec916fdf2daa034e3a179a6b835b25db89f4f5e43117ac68c/uv-0.8.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3e46395c7f2c7e52bf63f29f3fc1c6b357b011285d1df37d8af9c6f6f7cad36f", size = 17205164, upload-time = "2025-08-14T19:47:34.561Z" }, - { url = "https://files.pythonhosted.org/packages/d0/b2/8a9e00d6e5c41a231f59f75c15b04626f7d4561364475962894a31b01fee/uv-0.8.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:d9d35783ac8600cd8e95e9afd007aa281edf3125803c570a4b3246138e2a304d", size = 17822163, upload-time = "2025-08-14T19:47:37.111Z" }, - { url = "https://files.pythonhosted.org/packages/d9/e5/230f1ed3cbeae61d10ac8acc3d63b38a81c728161e7671fe3516aec72c76/uv-0.8.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce267b13f498cebb9690c06461b727718bd11624679ddebb0a3998efe6b80ad7", size = 18152038, upload-time = "2025-08-14T19:47:39.951Z" }, - { url = "https://files.pythonhosted.org/packages/95/be/7fd436adedd79c9afad14722135029010a972e17b05312795a976bc08854/uv-0.8.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c03aec1ad898642ae427b763cf5e5f90a678b91254f733ae08d01d15acd3672b", size = 18991855, upload-time = "2025-08-14T19:47:42.664Z" }, - { url = "https://files.pythonhosted.org/packages/80/4e/2cca1be92fc3cdfddb5f2fa8d5650098948f357774cbe51810aaa5968da0/uv-0.8.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:83aa9c8b0085949542674301268e2b7b541f1108dc95664dedf50fffd1578f97", size = 20248085, upload-time = "2025-08-14T19:47:45.489Z" }, - { url = "https://files.pythonhosted.org/packages/a5/9d/c4a5bbccfa45d8573d22da0d753329e572e72cd70796720dc0bc5c74e5c5/uv-0.8.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e9506b3febbce3559290cb10cd1c84dbed32bc4f4b1062bc2fe4f093aa42aea", size = 19961250, upload-time = "2025-08-14T19:47:47.963Z" }, - { url = "https://files.pythonhosted.org/packages/a4/f1/c1f9e59110fce261ee67cff854b4f95cae39a523d2a076c7566a704ebbe6/uv-0.8.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ba7bb038f0a263accefde1db68ecba7a756c85e6bcc25af161acef2711d6da19", size = 19314178, upload-time = "2025-08-14T19:47:50.469Z" }, - { url = "https://files.pythonhosted.org/packages/fc/47/c398c3a9657a6f8c3a7b1938ae0b7061c4087e1fbb00f83a7a4f79005752/uv-0.8.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36eb184758f18347547045a3aa7cc87c98a75c773e437c8a85878eb004a31c2e", size = 19314121, upload-time = "2025-08-14T19:47:54.17Z" }, - { url = "https://files.pythonhosted.org/packages/69/04/7ff94b68c33b93e89ec9920724b2a6d3992051584afd3410bf2604d2b93c/uv-0.8.11-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:0a7fcbe71cc5402b7c3d4c381f9b970a455d8ccc2a43ee2ce5ac2b617ec0534c", size = 18105431, upload-time = "2025-08-14T19:47:56.844Z" }, - { url = "https://files.pythonhosted.org/packages/09/5a/aee6041cd0c9ab1c56da61ba1e9ac30b4ea7c1c85471e19cb0cc1e415c0a/uv-0.8.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0da2c794dead209e660cb7df143ea9756c118ffa5874859e8a28a79101b5c760", size = 18984052, upload-time = "2025-08-14T19:47:59.927Z" }, - { url = "https://files.pythonhosted.org/packages/05/cd/7b9926b676a3807312bfb91662813305b305c5218a05a9b651763b28267e/uv-0.8.11-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:0a95dc944d62db4ca282f7415c2d3c0fa3ead9e245a47d845515f5ddbd5a80ef", size = 18109344, upload-time = "2025-08-14T19:48:02.607Z" }, - { url = "https://files.pythonhosted.org/packages/82/19/1e90e45fd84c4f5512dc9c8ad0ac3a4792677725047d3e7299f9dae41406/uv-0.8.11-py3-none-musllinux_1_1_i686.whl", hash = "sha256:0cd14f319e18a7b278238f0d87b18180282ec4d44d023f8b3ed2c8c091a14277", size = 18493945, upload-time = "2025-08-14T19:48:05.112Z" }, - { url = "https://files.pythonhosted.org/packages/68/b8/e6b784ede573d3f1ba6fafe70dd317b4543146a6c2ca88a5f56923518552/uv-0.8.11-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:261d19395a211f980d1ebc861356cf73ba23ceece2392c0b36ade38f89fd16a6", size = 19398023, upload-time = "2025-08-14T19:48:07.993Z" }, - { url = "https://files.pythonhosted.org/packages/65/5f/fd61ebec95bb5854c860d5268bc8ecbbca881465340f1e86302cacdd8234/uv-0.8.11-py3-none-win32.whl", hash = "sha256:0b922061f7b5915f224df23a849b6e1bfcace2e6b9fc0ee128868447873edb22", size = 18308608, upload-time = "2025-08-14T19:48:10.847Z" }, - { url = "https://files.pythonhosted.org/packages/bb/57/84358ea67cee7ec029ed0d51e801a64c5929b7d647ae31cd5e5aea0c6f61/uv-0.8.11-py3-none-win_amd64.whl", hash = "sha256:fe01737f3ddd533903f31236219c29e09063541f17a060403acc51906ce0cfe8", size = 20214609, upload-time = "2025-08-14T19:48:13.368Z" }, - { url = "https://files.pythonhosted.org/packages/e8/72/069a75703693d3297d95657957ea00d2f035896066f00a5692fbdce76d36/uv-0.8.11-py3-none-win_arm64.whl", hash = "sha256:cf3454d3407a5cac0d661b6033e3197643d0a6b5bb0e00869f6877ff7af907c9", size = 18878482, upload-time = "2025-08-14T19:48:15.743Z" }, +version = "0.9.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/e4/71780e9afade36354a76a1e4dc5659605c66446b9d0a0e97c990d2c374a3/uv-0.9.4.tar.gz", hash = "sha256:57582a149de7788a83f998ddad2dfc50a328aae7a474fbb1617c73a9e2b42ebf", size = 3701040, upload-time = "2025-10-18T21:34:59.108Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/bd/c64d332586ede567827687e77088ee41e56e00d2f822a7769c2a27da276a/uv-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:787cf63c2f5c97cc6b30915632351eac655fcd4ec19620bc67cbd6855975817b", size = 20680251, upload-time = "2025-10-18T21:33:54.277Z" }, + { url = "https://files.pythonhosted.org/packages/11/15/a4e13592544651fb6b676ae88b065a7a8661429cbd6041b4ff05c3b44bbe/uv-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:42012fcfdbaec08e1c009bbdbf96296b05e0e86feb83e1182d9335ae86a288d2", size = 19619663, upload-time = "2025-10-18T21:33:59.405Z" }, + { url = "https://files.pythonhosted.org/packages/da/59/7ee66db3caed7cc7332e5ca414733d1df761919c8cb38c4d6f09055c4af8/uv-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:610a219a6d92cc56c1a24888118a5ae1b07233b93dde0565d64fe198a2c7c376", size = 18231469, upload-time = "2025-10-18T21:34:03.123Z" }, + { url = "https://files.pythonhosted.org/packages/ae/37/0eab636ac6ffaf8b6d60fb0bd202331060f187e933d43766fa0b3964fe0d/uv-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:aa0e144df0276945cbe49e30b577cf51e19b808e5ca55e23b8a1a354857e1629", size = 20051606, upload-time = "2025-10-18T21:34:06.627Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b4/24ae03f66eadc6d8fb46962387162f1fef3430c4dfda0542fd5a0ebaa0ce/uv-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ee7695b6632b74ea62d67fcef732e519d1fdb3f9ecf81c99bfd5a354ff925fb", size = 20302565, upload-time = "2025-10-18T21:34:10.004Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e6/ee0de4ed1770d70915c0dd4329cc7e3d146bf726a8ebbc6e527325c6aefd/uv-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa33399d5e3e31b753910cfaa6f87022736339cadb140c8896dccb7c6a855e32", size = 21175677, upload-time = "2025-10-18T21:34:13.366Z" }, + { url = "https://files.pythonhosted.org/packages/7b/01/a236caffb2430e27346afd07ebaf485406ff56f1f2f915c018bd69525210/uv-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:df3288f85bd6bfb4b8722bb7223d6723de7c32d213596573d92803f89af9007c", size = 22630798, upload-time = "2025-10-18T21:34:17.27Z" }, + { url = "https://files.pythonhosted.org/packages/8c/bf/2880311bd73951de52ef62ecf65f2a5a16761edeb50f3c6892035f09db04/uv-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7f7d3fd51627fbcca06cf75d327e060db924d4ca054e1e934b71682d58f1f51", size = 22264831, upload-time = "2025-10-18T21:34:21.383Z" }, + { url = "https://files.pythonhosted.org/packages/4d/5d/17eaf451254ce011ca163bbcb4435eeaa76e5188381d0b4ec60d40a26cf2/uv-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:03a85b02e6ccf1b705ce78bd98da78c90d5a0d0f941756ee842825d850cada2f", size = 21342146, upload-time = "2025-10-18T21:34:25.231Z" }, + { url = "https://files.pythonhosted.org/packages/fa/8a/235e90024d54aa62a5a4f0afe05ae2be3d039ecb90e3cc0048e50bb14b8d/uv-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89f88df09d571f6d06228b32a6a71100905eb64343247317d363bcd774ee870", size = 21308444, upload-time = "2025-10-18T21:34:28.611Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/f03d83a67855c7227ce8a452dcd29ef9d3bc233a28693bdae16e61e25aee/uv-0.9.4-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:39f6b459fdabc80c0afc080ba8bce86e048afa799bc6c5c372f78b14195cf49c", size = 20187789, upload-time = "2025-10-18T21:34:32.145Z" }, + { url = "https://files.pythonhosted.org/packages/6c/14/b9291a0e41054f598cc21aa3c0319cf9f9ad0ce5a0a26cf8d14e24d53866/uv-0.9.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:3e1b5df83e96a8128b81a9f2bd72a4db752f691515914471b76df994339d2c35", size = 21272041, upload-time = "2025-10-18T21:34:35.765Z" }, + { url = "https://files.pythonhosted.org/packages/3c/48/aa9994d2b00c08d5976a0a8942f1491acccb325691ba3f945c82417c9dc2/uv-0.9.4-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:2feb2adc0a2eb41a757b9cef3226f649452423badf20d68d177b6649342d021d", size = 20250918, upload-time = "2025-10-18T21:34:38.997Z" }, + { url = "https://files.pythonhosted.org/packages/96/9f/239b922ce00ca98d3a2df8bcd6d62ed1771043c1e7fb4a99d514263809c4/uv-0.9.4-py3-none-musllinux_1_1_i686.whl", hash = "sha256:dcbcc963232e13e279002844e983cd6d0f53560e75d8a3f7a68e7d68a6021235", size = 20641334, upload-time = "2025-10-18T21:34:42.85Z" }, + { url = "https://files.pythonhosted.org/packages/c3/1c/4406fb13052409a26a6372e8d70747281143f87d9c488e552390796742dc/uv-0.9.4-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:c353be83686f769bf50e6c6bc8591ad59752b492c6bb51296e378e55521482f5", size = 21525445, upload-time = "2025-10-18T21:34:46.197Z" }, + { url = "https://files.pythonhosted.org/packages/e8/c2/8f9318e42cbeb9335ab657c9648ce45bb353482dbf86ddeced52116cd9a3/uv-0.9.4-py3-none-win32.whl", hash = "sha256:79efd533016d9bf077056cac72e68fa501e9d0e09576a2c375f7c286d19be9d6", size = 19446923, upload-time = "2025-10-18T21:34:49.58Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ed/1d036a7d2ce5c3382c8c21481b0fd10f8de577b401b549c5992b8c00114a/uv-0.9.4-py3-none-win_amd64.whl", hash = "sha256:0840346084d28aa5345eeabcb7f9e727448b56b3b399300447a9155066909925", size = 21431844, upload-time = "2025-10-18T21:34:53.437Z" }, + { url = "https://files.pythonhosted.org/packages/ad/30/2fbaeed4efdda407fa9b3a4c0d7f3b9b53498d13f06498b15decc52ee253/uv-0.9.4-py3-none-win_arm64.whl", hash = "sha256:253133f7f2eac8fed10ad601c56ddcd13d8d81d9343ed9e95873d19b149199f2", size = 19905878, upload-time = "2025-10-18T21:34:56.696Z" }, ] [[package]] name = "virtualenv" -version = "20.34.0" +version = "20.35.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, @@ -1803,9 +1939,9 @@ dependencies = [ { name = "platformdirs" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/14/37fcdba2808a6c615681cd216fecae00413c9dab44fb2e57805ecf3eaee3/virtualenv-20.34.0.tar.gz", hash = "sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a", size = 6003808, upload-time = "2025-08-13T14:24:07.464Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/d5/b0ccd381d55c8f45d46f77df6ae59fbc23d19e901e2d523395598e5f4c93/virtualenv-20.35.3.tar.gz", hash = "sha256:4f1a845d131133bdff10590489610c98c168ff99dc75d6c96853801f7f67af44", size = 6002907, upload-time = "2025-10-10T21:23:33.178Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/06/04c8e804f813cf972e3262f3f8584c232de64f0cde9f703b46cf53a45090/virtualenv-20.34.0-py3-none-any.whl", hash = "sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026", size = 5983279, upload-time = "2025-08-13T14:24:05.111Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/d9a94da0e9d470a543c1b9d3ccbceb0f59455983088e727b8a1824ed90fb/virtualenv-20.35.3-py3-none-any.whl", hash = "sha256:63d106565078d8c8d0b206d48080f938a8b25361e19432d2c9db40d2899c810a", size = 5981061, upload-time = "2025-10-10T21:23:30.433Z" }, ] [[package]] @@ -1819,75 +1955,90 @@ wheels = [ [[package]] name = "zstandard" -version = "0.23.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cffi", marker = "platform_python_implementation == 'PyPy'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ed/f6/2ac0287b442160a89d726b17a9184a4c615bb5237db763791a7fd16d9df1/zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09", size = 681701, upload-time = "2024-07-15T00:18:06.141Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/55/bd0487e86679db1823fc9ee0d8c9c78ae2413d34c0b461193b5f4c31d22f/zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9", size = 788701, upload-time = "2024-07-15T00:13:27.351Z" }, - { url = "https://files.pythonhosted.org/packages/e1/8a/ccb516b684f3ad987dfee27570d635822e3038645b1a950c5e8022df1145/zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880", size = 633678, upload-time = "2024-07-15T00:13:30.24Z" }, - { url = "https://files.pythonhosted.org/packages/12/89/75e633d0611c028e0d9af6df199423bf43f54bea5007e6718ab7132e234c/zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc", size = 4941098, upload-time = "2024-07-15T00:13:32.526Z" }, - { url = "https://files.pythonhosted.org/packages/4a/7a/bd7f6a21802de358b63f1ee636ab823711c25ce043a3e9f043b4fcb5ba32/zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573", size = 5308798, upload-time = "2024-07-15T00:13:34.925Z" }, - { url = "https://files.pythonhosted.org/packages/79/3b/775f851a4a65013e88ca559c8ae42ac1352db6fcd96b028d0df4d7d1d7b4/zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391", size = 5341840, upload-time = "2024-07-15T00:13:37.376Z" }, - { url = "https://files.pythonhosted.org/packages/09/4f/0cc49570141dd72d4d95dd6fcf09328d1b702c47a6ec12fbed3b8aed18a5/zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e", size = 5440337, upload-time = "2024-07-15T00:13:39.772Z" }, - { url = "https://files.pythonhosted.org/packages/e7/7c/aaa7cd27148bae2dc095191529c0570d16058c54c4597a7d118de4b21676/zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd", size = 4861182, upload-time = "2024-07-15T00:13:42.495Z" }, - { url = "https://files.pythonhosted.org/packages/ac/eb/4b58b5c071d177f7dc027129d20bd2a44161faca6592a67f8fcb0b88b3ae/zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4", size = 4932936, upload-time = "2024-07-15T00:13:44.234Z" }, - { url = "https://files.pythonhosted.org/packages/44/f9/21a5fb9bb7c9a274b05ad700a82ad22ce82f7ef0f485980a1e98ed6e8c5f/zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea", size = 5464705, upload-time = "2024-07-15T00:13:46.822Z" }, - { url = "https://files.pythonhosted.org/packages/49/74/b7b3e61db3f88632776b78b1db597af3f44c91ce17d533e14a25ce6a2816/zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2", size = 4857882, upload-time = "2024-07-15T00:13:49.297Z" }, - { url = "https://files.pythonhosted.org/packages/4a/7f/d8eb1cb123d8e4c541d4465167080bec88481ab54cd0b31eb4013ba04b95/zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9", size = 4697672, upload-time = "2024-07-15T00:13:51.447Z" }, - { url = "https://files.pythonhosted.org/packages/5e/05/f7dccdf3d121309b60342da454d3e706453a31073e2c4dac8e1581861e44/zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a", size = 5206043, upload-time = "2024-07-15T00:13:53.587Z" }, - { url = "https://files.pythonhosted.org/packages/86/9d/3677a02e172dccd8dd3a941307621c0cbd7691d77cb435ac3c75ab6a3105/zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0", size = 5667390, upload-time = "2024-07-15T00:13:56.137Z" }, - { url = "https://files.pythonhosted.org/packages/41/7e/0012a02458e74a7ba122cd9cafe491facc602c9a17f590367da369929498/zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c", size = 5198901, upload-time = "2024-07-15T00:13:58.584Z" }, - { url = "https://files.pythonhosted.org/packages/65/3a/8f715b97bd7bcfc7342d8adcd99a026cb2fb550e44866a3b6c348e1b0f02/zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813", size = 430596, upload-time = "2024-07-15T00:14:00.693Z" }, - { url = "https://files.pythonhosted.org/packages/19/b7/b2b9eca5e5a01111e4fe8a8ffb56bdcdf56b12448a24effe6cfe4a252034/zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4", size = 495498, upload-time = "2024-07-15T00:14:02.741Z" }, - { url = "https://files.pythonhosted.org/packages/9e/40/f67e7d2c25a0e2dc1744dd781110b0b60306657f8696cafb7ad7579469bd/zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e", size = 788699, upload-time = "2024-07-15T00:14:04.909Z" }, - { url = "https://files.pythonhosted.org/packages/e8/46/66d5b55f4d737dd6ab75851b224abf0afe5774976fe511a54d2eb9063a41/zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23", size = 633681, upload-time = "2024-07-15T00:14:13.99Z" }, - { url = "https://files.pythonhosted.org/packages/63/b6/677e65c095d8e12b66b8f862b069bcf1f1d781b9c9c6f12eb55000d57583/zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a", size = 4944328, upload-time = "2024-07-15T00:14:16.588Z" }, - { url = "https://files.pythonhosted.org/packages/59/cc/e76acb4c42afa05a9d20827116d1f9287e9c32b7ad58cc3af0721ce2b481/zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db", size = 5311955, upload-time = "2024-07-15T00:14:19.389Z" }, - { url = "https://files.pythonhosted.org/packages/78/e4/644b8075f18fc7f632130c32e8f36f6dc1b93065bf2dd87f03223b187f26/zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2", size = 5344944, upload-time = "2024-07-15T00:14:22.173Z" }, - { url = "https://files.pythonhosted.org/packages/76/3f/dbafccf19cfeca25bbabf6f2dd81796b7218f768ec400f043edc767015a6/zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca", size = 5442927, upload-time = "2024-07-15T00:14:24.825Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c3/d24a01a19b6733b9f218e94d1a87c477d523237e07f94899e1c10f6fd06c/zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c", size = 4864910, upload-time = "2024-07-15T00:14:26.982Z" }, - { url = "https://files.pythonhosted.org/packages/1c/a9/cf8f78ead4597264f7618d0875be01f9bc23c9d1d11afb6d225b867cb423/zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e", size = 4935544, upload-time = "2024-07-15T00:14:29.582Z" }, - { url = "https://files.pythonhosted.org/packages/2c/96/8af1e3731b67965fb995a940c04a2c20997a7b3b14826b9d1301cf160879/zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5", size = 5467094, upload-time = "2024-07-15T00:14:40.126Z" }, - { url = "https://files.pythonhosted.org/packages/ff/57/43ea9df642c636cb79f88a13ab07d92d88d3bfe3e550b55a25a07a26d878/zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48", size = 4860440, upload-time = "2024-07-15T00:14:42.786Z" }, - { url = "https://files.pythonhosted.org/packages/46/37/edb78f33c7f44f806525f27baa300341918fd4c4af9472fbc2c3094be2e8/zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c", size = 4700091, upload-time = "2024-07-15T00:14:45.184Z" }, - { url = "https://files.pythonhosted.org/packages/c1/f1/454ac3962671a754f3cb49242472df5c2cced4eb959ae203a377b45b1a3c/zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003", size = 5208682, upload-time = "2024-07-15T00:14:47.407Z" }, - { url = "https://files.pythonhosted.org/packages/85/b2/1734b0fff1634390b1b887202d557d2dd542de84a4c155c258cf75da4773/zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78", size = 5669707, upload-time = "2024-07-15T00:15:03.529Z" }, - { url = "https://files.pythonhosted.org/packages/52/5a/87d6971f0997c4b9b09c495bf92189fb63de86a83cadc4977dc19735f652/zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473", size = 5201792, upload-time = "2024-07-15T00:15:28.372Z" }, - { url = "https://files.pythonhosted.org/packages/79/02/6f6a42cc84459d399bd1a4e1adfc78d4dfe45e56d05b072008d10040e13b/zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160", size = 430586, upload-time = "2024-07-15T00:15:32.26Z" }, - { url = "https://files.pythonhosted.org/packages/be/a2/4272175d47c623ff78196f3c10e9dc7045c1b9caf3735bf041e65271eca4/zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0", size = 495420, upload-time = "2024-07-15T00:15:34.004Z" }, - { url = "https://files.pythonhosted.org/packages/7b/83/f23338c963bd9de687d47bf32efe9fd30164e722ba27fb59df33e6b1719b/zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094", size = 788713, upload-time = "2024-07-15T00:15:35.815Z" }, - { url = "https://files.pythonhosted.org/packages/5b/b3/1a028f6750fd9227ee0b937a278a434ab7f7fdc3066c3173f64366fe2466/zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8", size = 633459, upload-time = "2024-07-15T00:15:37.995Z" }, - { url = "https://files.pythonhosted.org/packages/26/af/36d89aae0c1f95a0a98e50711bc5d92c144939efc1f81a2fcd3e78d7f4c1/zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1", size = 4945707, upload-time = "2024-07-15T00:15:39.872Z" }, - { url = "https://files.pythonhosted.org/packages/cd/2e/2051f5c772f4dfc0aae3741d5fc72c3dcfe3aaeb461cc231668a4db1ce14/zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072", size = 5306545, upload-time = "2024-07-15T00:15:41.75Z" }, - { url = "https://files.pythonhosted.org/packages/0a/9e/a11c97b087f89cab030fa71206963090d2fecd8eb83e67bb8f3ffb84c024/zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20", size = 5337533, upload-time = "2024-07-15T00:15:44.114Z" }, - { url = "https://files.pythonhosted.org/packages/fc/79/edeb217c57fe1bf16d890aa91a1c2c96b28c07b46afed54a5dcf310c3f6f/zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373", size = 5436510, upload-time = "2024-07-15T00:15:46.509Z" }, - { url = "https://files.pythonhosted.org/packages/81/4f/c21383d97cb7a422ddf1ae824b53ce4b51063d0eeb2afa757eb40804a8ef/zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db", size = 4859973, upload-time = "2024-07-15T00:15:49.939Z" }, - { url = "https://files.pythonhosted.org/packages/ab/15/08d22e87753304405ccac8be2493a495f529edd81d39a0870621462276ef/zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772", size = 4936968, upload-time = "2024-07-15T00:15:52.025Z" }, - { url = "https://files.pythonhosted.org/packages/eb/fa/f3670a597949fe7dcf38119a39f7da49a8a84a6f0b1a2e46b2f71a0ab83f/zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105", size = 5467179, upload-time = "2024-07-15T00:15:54.971Z" }, - { url = "https://files.pythonhosted.org/packages/4e/a9/dad2ab22020211e380adc477a1dbf9f109b1f8d94c614944843e20dc2a99/zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba", size = 4848577, upload-time = "2024-07-15T00:15:57.634Z" }, - { url = "https://files.pythonhosted.org/packages/08/03/dd28b4484b0770f1e23478413e01bee476ae8227bbc81561f9c329e12564/zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd", size = 4693899, upload-time = "2024-07-15T00:16:00.811Z" }, - { url = "https://files.pythonhosted.org/packages/2b/64/3da7497eb635d025841e958bcd66a86117ae320c3b14b0ae86e9e8627518/zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a", size = 5199964, upload-time = "2024-07-15T00:16:03.669Z" }, - { url = "https://files.pythonhosted.org/packages/43/a4/d82decbab158a0e8a6ebb7fc98bc4d903266bce85b6e9aaedea1d288338c/zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90", size = 5655398, upload-time = "2024-07-15T00:16:06.694Z" }, - { url = "https://files.pythonhosted.org/packages/f2/61/ac78a1263bc83a5cf29e7458b77a568eda5a8f81980691bbc6eb6a0d45cc/zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35", size = 5191313, upload-time = "2024-07-15T00:16:09.758Z" }, - { url = "https://files.pythonhosted.org/packages/e7/54/967c478314e16af5baf849b6ee9d6ea724ae5b100eb506011f045d3d4e16/zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d", size = 430877, upload-time = "2024-07-15T00:16:11.758Z" }, - { url = "https://files.pythonhosted.org/packages/75/37/872d74bd7739639c4553bf94c84af7d54d8211b626b352bc57f0fd8d1e3f/zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b", size = 495595, upload-time = "2024-07-15T00:16:13.731Z" }, - { url = "https://files.pythonhosted.org/packages/80/f1/8386f3f7c10261fe85fbc2c012fdb3d4db793b921c9abcc995d8da1b7a80/zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9", size = 788975, upload-time = "2024-07-15T00:16:16.005Z" }, - { url = "https://files.pythonhosted.org/packages/16/e8/cbf01077550b3e5dc86089035ff8f6fbbb312bc0983757c2d1117ebba242/zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a", size = 633448, upload-time = "2024-07-15T00:16:17.897Z" }, - { url = "https://files.pythonhosted.org/packages/06/27/4a1b4c267c29a464a161aeb2589aff212b4db653a1d96bffe3598f3f0d22/zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2", size = 4945269, upload-time = "2024-07-15T00:16:20.136Z" }, - { url = "https://files.pythonhosted.org/packages/7c/64/d99261cc57afd9ae65b707e38045ed8269fbdae73544fd2e4a4d50d0ed83/zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5", size = 5306228, upload-time = "2024-07-15T00:16:23.398Z" }, - { url = "https://files.pythonhosted.org/packages/7a/cf/27b74c6f22541f0263016a0fd6369b1b7818941de639215c84e4e94b2a1c/zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f", size = 5336891, upload-time = "2024-07-15T00:16:26.391Z" }, - { url = "https://files.pythonhosted.org/packages/fa/18/89ac62eac46b69948bf35fcd90d37103f38722968e2981f752d69081ec4d/zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed", size = 5436310, upload-time = "2024-07-15T00:16:29.018Z" }, - { url = "https://files.pythonhosted.org/packages/a8/a8/5ca5328ee568a873f5118d5b5f70d1f36c6387716efe2e369010289a5738/zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea", size = 4859912, upload-time = "2024-07-15T00:16:31.871Z" }, - { url = "https://files.pythonhosted.org/packages/ea/ca/3781059c95fd0868658b1cf0440edd832b942f84ae60685d0cfdb808bca1/zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847", size = 4936946, upload-time = "2024-07-15T00:16:34.593Z" }, - { url = "https://files.pythonhosted.org/packages/ce/11/41a58986f809532742c2b832c53b74ba0e0a5dae7e8ab4642bf5876f35de/zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171", size = 5466994, upload-time = "2024-07-15T00:16:36.887Z" }, - { url = "https://files.pythonhosted.org/packages/83/e3/97d84fe95edd38d7053af05159465d298c8b20cebe9ccb3d26783faa9094/zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840", size = 4848681, upload-time = "2024-07-15T00:16:39.709Z" }, - { url = "https://files.pythonhosted.org/packages/6e/99/cb1e63e931de15c88af26085e3f2d9af9ce53ccafac73b6e48418fd5a6e6/zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690", size = 4694239, upload-time = "2024-07-15T00:16:41.83Z" }, - { url = "https://files.pythonhosted.org/packages/ab/50/b1e703016eebbc6501fc92f34db7b1c68e54e567ef39e6e59cf5fb6f2ec0/zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b", size = 5200149, upload-time = "2024-07-15T00:16:44.287Z" }, - { url = "https://files.pythonhosted.org/packages/aa/e0/932388630aaba70197c78bdb10cce2c91fae01a7e553b76ce85471aec690/zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057", size = 5655392, upload-time = "2024-07-15T00:16:46.423Z" }, - { url = "https://files.pythonhosted.org/packages/02/90/2633473864f67a15526324b007a9f96c96f56d5f32ef2a56cc12f9548723/zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33", size = 5191299, upload-time = "2024-07-15T00:16:49.053Z" }, - { url = "https://files.pythonhosted.org/packages/b0/4c/315ca5c32da7e2dc3455f3b2caee5c8c2246074a61aac6ec3378a97b7136/zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd", size = 430862, upload-time = "2024-07-15T00:16:51.003Z" }, - { url = "https://files.pythonhosted.org/packages/a2/bf/c6aaba098e2d04781e8f4f7c0ba3c7aa73d00e4c436bcc0cf059a66691d1/zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b", size = 495578, upload-time = "2024-07-15T00:16:53.135Z" }, +version = "0.25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513, upload-time = "2025-09-14T22:15:54.002Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/7a/28efd1d371f1acd037ac64ed1c5e2b41514a6cc937dd6ab6a13ab9f0702f/zstandard-0.25.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e59fdc271772f6686e01e1b3b74537259800f57e24280be3f29c8a0deb1904dd", size = 795256, upload-time = "2025-09-14T22:15:56.415Z" }, + { url = "https://files.pythonhosted.org/packages/96/34/ef34ef77f1ee38fc8e4f9775217a613b452916e633c4f1d98f31db52c4a5/zstandard-0.25.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4d441506e9b372386a5271c64125f72d5df6d2a8e8a2a45a0ae09b03cb781ef7", size = 640565, upload-time = "2025-09-14T22:15:58.177Z" }, + { url = "https://files.pythonhosted.org/packages/9d/1b/4fdb2c12eb58f31f28c4d28e8dc36611dd7205df8452e63f52fb6261d13e/zstandard-0.25.0-cp310-cp310-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:ab85470ab54c2cb96e176f40342d9ed41e58ca5733be6a893b730e7af9c40550", size = 5345306, upload-time = "2025-09-14T22:16:00.165Z" }, + { url = "https://files.pythonhosted.org/packages/73/28/a44bdece01bca027b079f0e00be3b6bd89a4df180071da59a3dd7381665b/zstandard-0.25.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e05ab82ea7753354bb054b92e2f288afb750e6b439ff6ca78af52939ebbc476d", size = 5055561, upload-time = "2025-09-14T22:16:02.22Z" }, + { url = "https://files.pythonhosted.org/packages/e9/74/68341185a4f32b274e0fc3410d5ad0750497e1acc20bd0f5b5f64ce17785/zstandard-0.25.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:78228d8a6a1c177a96b94f7e2e8d012c55f9c760761980da16ae7546a15a8e9b", size = 5402214, upload-time = "2025-09-14T22:16:04.109Z" }, + { url = "https://files.pythonhosted.org/packages/8b/67/f92e64e748fd6aaffe01e2b75a083c0c4fd27abe1c8747fee4555fcee7dd/zstandard-0.25.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:2b6bd67528ee8b5c5f10255735abc21aa106931f0dbaf297c7be0c886353c3d0", size = 5449703, upload-time = "2025-09-14T22:16:06.312Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e5/6d36f92a197c3c17729a2125e29c169f460538a7d939a27eaaa6dcfcba8e/zstandard-0.25.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4b6d83057e713ff235a12e73916b6d356e3084fd3d14ced499d84240f3eecee0", size = 5556583, upload-time = "2025-09-14T22:16:08.457Z" }, + { url = "https://files.pythonhosted.org/packages/d7/83/41939e60d8d7ebfe2b747be022d0806953799140a702b90ffe214d557638/zstandard-0.25.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9174f4ed06f790a6869b41cba05b43eeb9a35f8993c4422ab853b705e8112bbd", size = 5045332, upload-time = "2025-09-14T22:16:10.444Z" }, + { url = "https://files.pythonhosted.org/packages/b3/87/d3ee185e3d1aa0133399893697ae91f221fda79deb61adbe998a7235c43f/zstandard-0.25.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:25f8f3cd45087d089aef5ba3848cd9efe3ad41163d3400862fb42f81a3a46701", size = 5572283, upload-time = "2025-09-14T22:16:12.128Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1d/58635ae6104df96671076ac7d4ae7816838ce7debd94aecf83e30b7121b0/zstandard-0.25.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3756b3e9da9b83da1796f8809dd57cb024f838b9eeafde28f3cb472012797ac1", size = 4959754, upload-time = "2025-09-14T22:16:14.225Z" }, + { url = "https://files.pythonhosted.org/packages/75/d6/57e9cb0a9983e9a229dd8fd2e6e96593ef2aa82a3907188436f22b111ccd/zstandard-0.25.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:81dad8d145d8fd981b2962b686b2241d3a1ea07733e76a2f15435dfb7fb60150", size = 5266477, upload-time = "2025-09-14T22:16:16.343Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a9/ee891e5edf33a6ebce0a028726f0bbd8567effe20fe3d5808c42323e8542/zstandard-0.25.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a5a419712cf88862a45a23def0ae063686db3d324cec7edbe40509d1a79a0aab", size = 5440914, upload-time = "2025-09-14T22:16:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/58/08/a8522c28c08031a9521f27abc6f78dbdee7312a7463dd2cfc658b813323b/zstandard-0.25.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e7360eae90809efd19b886e59a09dad07da4ca9ba096752e61a2e03c8aca188e", size = 5819847, upload-time = "2025-09-14T22:16:20.559Z" }, + { url = "https://files.pythonhosted.org/packages/6f/11/4c91411805c3f7b6f31c60e78ce347ca48f6f16d552fc659af6ec3b73202/zstandard-0.25.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:75ffc32a569fb049499e63ce68c743155477610532da1eb38e7f24bf7cd29e74", size = 5363131, upload-time = "2025-09-14T22:16:22.206Z" }, + { url = "https://files.pythonhosted.org/packages/ef/d6/8c4bd38a3b24c4c7676a7a3d8de85d6ee7a983602a734b9f9cdefb04a5d6/zstandard-0.25.0-cp310-cp310-win32.whl", hash = "sha256:106281ae350e494f4ac8a80470e66d1fe27e497052c8d9c3b95dc4cf1ade81aa", size = 436469, upload-time = "2025-09-14T22:16:25.002Z" }, + { url = "https://files.pythonhosted.org/packages/93/90/96d50ad417a8ace5f841b3228e93d1bb13e6ad356737f42e2dde30d8bd68/zstandard-0.25.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea9d54cc3d8064260114a0bbf3479fc4a98b21dffc89b3459edd506b69262f6e", size = 506100, upload-time = "2025-09-14T22:16:23.569Z" }, + { url = "https://files.pythonhosted.org/packages/2a/83/c3ca27c363d104980f1c9cee1101cc8ba724ac8c28a033ede6aab89585b1/zstandard-0.25.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c", size = 795254, upload-time = "2025-09-14T22:16:26.137Z" }, + { url = "https://files.pythonhosted.org/packages/ac/4d/e66465c5411a7cf4866aeadc7d108081d8ceba9bc7abe6b14aa21c671ec3/zstandard-0.25.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f", size = 640559, upload-time = "2025-09-14T22:16:27.973Z" }, + { url = "https://files.pythonhosted.org/packages/12/56/354fe655905f290d3b147b33fe946b0f27e791e4b50a5f004c802cb3eb7b/zstandard-0.25.0-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431", size = 5348020, upload-time = "2025-09-14T22:16:29.523Z" }, + { url = "https://files.pythonhosted.org/packages/3b/13/2b7ed68bd85e69a2069bcc72141d378f22cae5a0f3b353a2c8f50ef30c1b/zstandard-0.25.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a", size = 5058126, upload-time = "2025-09-14T22:16:31.811Z" }, + { url = "https://files.pythonhosted.org/packages/c9/dd/fdaf0674f4b10d92cb120ccff58bbb6626bf8368f00ebfd2a41ba4a0dc99/zstandard-0.25.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc", size = 5405390, upload-time = "2025-09-14T22:16:33.486Z" }, + { url = "https://files.pythonhosted.org/packages/0f/67/354d1555575bc2490435f90d67ca4dd65238ff2f119f30f72d5cde09c2ad/zstandard-0.25.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6", size = 5452914, upload-time = "2025-09-14T22:16:35.277Z" }, + { url = "https://files.pythonhosted.org/packages/bb/1f/e9cfd801a3f9190bf3e759c422bbfd2247db9d7f3d54a56ecde70137791a/zstandard-0.25.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072", size = 5559635, upload-time = "2025-09-14T22:16:37.141Z" }, + { url = "https://files.pythonhosted.org/packages/21/88/5ba550f797ca953a52d708c8e4f380959e7e3280af029e38fbf47b55916e/zstandard-0.25.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277", size = 5048277, upload-time = "2025-09-14T22:16:38.807Z" }, + { url = "https://files.pythonhosted.org/packages/46/c0/ca3e533b4fa03112facbe7fbe7779cb1ebec215688e5df576fe5429172e0/zstandard-0.25.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313", size = 5574377, upload-time = "2025-09-14T22:16:40.523Z" }, + { url = "https://files.pythonhosted.org/packages/12/9b/3fb626390113f272abd0799fd677ea33d5fc3ec185e62e6be534493c4b60/zstandard-0.25.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097", size = 4961493, upload-time = "2025-09-14T22:16:43.3Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d3/23094a6b6a4b1343b27ae68249daa17ae0651fcfec9ed4de09d14b940285/zstandard-0.25.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778", size = 5269018, upload-time = "2025-09-14T22:16:45.292Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a7/bb5a0c1c0f3f4b5e9d5b55198e39de91e04ba7c205cc46fcb0f95f0383c1/zstandard-0.25.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065", size = 5443672, upload-time = "2025-09-14T22:16:47.076Z" }, + { url = "https://files.pythonhosted.org/packages/27/22/503347aa08d073993f25109c36c8d9f029c7d5949198050962cb568dfa5e/zstandard-0.25.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa", size = 5822753, upload-time = "2025-09-14T22:16:49.316Z" }, + { url = "https://files.pythonhosted.org/packages/e2/be/94267dc6ee64f0f8ba2b2ae7c7a2df934a816baaa7291db9e1aa77394c3c/zstandard-0.25.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7", size = 5366047, upload-time = "2025-09-14T22:16:51.328Z" }, + { url = "https://files.pythonhosted.org/packages/7b/a3/732893eab0a3a7aecff8b99052fecf9f605cf0fb5fb6d0290e36beee47a4/zstandard-0.25.0-cp311-cp311-win32.whl", hash = "sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4", size = 436484, upload-time = "2025-09-14T22:16:55.005Z" }, + { url = "https://files.pythonhosted.org/packages/43/a3/c6155f5c1cce691cb80dfd38627046e50af3ee9ddc5d0b45b9b063bfb8c9/zstandard-0.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2", size = 506183, upload-time = "2025-09-14T22:16:52.753Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3e/8945ab86a0820cc0e0cdbf38086a92868a9172020fdab8a03ac19662b0e5/zstandard-0.25.0-cp311-cp311-win_arm64.whl", hash = "sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137", size = 462533, upload-time = "2025-09-14T22:16:53.878Z" }, + { url = "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738, upload-time = "2025-09-14T22:16:56.237Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436, upload-time = "2025-09-14T22:16:57.774Z" }, + { url = "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019, upload-time = "2025-09-14T22:16:59.302Z" }, + { url = "https://files.pythonhosted.org/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", size = 5063012, upload-time = "2025-09-14T22:17:01.156Z" }, + { url = "https://files.pythonhosted.org/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", size = 5394148, upload-time = "2025-09-14T22:17:03.091Z" }, + { url = "https://files.pythonhosted.org/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", size = 5451652, upload-time = "2025-09-14T22:17:04.979Z" }, + { url = "https://files.pythonhosted.org/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", size = 5546993, upload-time = "2025-09-14T22:17:06.781Z" }, + { url = "https://files.pythonhosted.org/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", size = 5046806, upload-time = "2025-09-14T22:17:08.415Z" }, + { url = "https://files.pythonhosted.org/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", size = 5576659, upload-time = "2025-09-14T22:17:10.164Z" }, + { url = "https://files.pythonhosted.org/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", size = 4953933, upload-time = "2025-09-14T22:17:11.857Z" }, + { url = "https://files.pythonhosted.org/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", size = 5268008, upload-time = "2025-09-14T22:17:13.627Z" }, + { url = "https://files.pythonhosted.org/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", size = 5433517, upload-time = "2025-09-14T22:17:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", size = 5814292, upload-time = "2025-09-14T22:17:17.827Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", size = 5360237, upload-time = "2025-09-14T22:17:19.954Z" }, + { url = "https://files.pythonhosted.org/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl", hash = "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", size = 436922, upload-time = "2025-09-14T22:17:24.398Z" }, + { url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload-time = "2025-09-14T22:17:21.429Z" }, + { url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload-time = "2025-09-14T22:17:23.147Z" }, + { url = "https://files.pythonhosted.org/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", size = 795735, upload-time = "2025-09-14T22:17:26.042Z" }, + { url = "https://files.pythonhosted.org/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", size = 640440, upload-time = "2025-09-14T22:17:27.366Z" }, + { url = "https://files.pythonhosted.org/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", size = 5343070, upload-time = "2025-09-14T22:17:28.896Z" }, + { url = "https://files.pythonhosted.org/packages/6d/db/ddb11011826ed7db9d0e485d13df79b58586bfdec56e5c84a928a9a78c1c/zstandard-0.25.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", size = 5063001, upload-time = "2025-09-14T22:17:31.044Z" }, + { url = "https://files.pythonhosted.org/packages/db/00/87466ea3f99599d02a5238498b87bf84a6348290c19571051839ca943777/zstandard-0.25.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", size = 5394120, upload-time = "2025-09-14T22:17:32.711Z" }, + { url = "https://files.pythonhosted.org/packages/2b/95/fc5531d9c618a679a20ff6c29e2b3ef1d1f4ad66c5e161ae6ff847d102a9/zstandard-0.25.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", size = 5451230, upload-time = "2025-09-14T22:17:34.41Z" }, + { url = "https://files.pythonhosted.org/packages/63/4b/e3678b4e776db00f9f7b2fe58e547e8928ef32727d7a1ff01dea010f3f13/zstandard-0.25.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", size = 5547173, upload-time = "2025-09-14T22:17:36.084Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d5/ba05ed95c6b8ec30bd468dfeab20589f2cf709b5c940483e31d991f2ca58/zstandard-0.25.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", size = 5046736, upload-time = "2025-09-14T22:17:37.891Z" }, + { url = "https://files.pythonhosted.org/packages/50/d5/870aa06b3a76c73eced65c044b92286a3c4e00554005ff51962deef28e28/zstandard-0.25.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", size = 5576368, upload-time = "2025-09-14T22:17:40.206Z" }, + { url = "https://files.pythonhosted.org/packages/5d/35/398dc2ffc89d304d59bc12f0fdd931b4ce455bddf7038a0a67733a25f550/zstandard-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", size = 4954022, upload-time = "2025-09-14T22:17:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/9a/5c/36ba1e5507d56d2213202ec2b05e8541734af5f2ce378c5d1ceaf4d88dc4/zstandard-0.25.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", size = 5267889, upload-time = "2025-09-14T22:17:43.577Z" }, + { url = "https://files.pythonhosted.org/packages/70/e8/2ec6b6fb7358b2ec0113ae202647ca7c0e9d15b61c005ae5225ad0995df5/zstandard-0.25.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", size = 5433952, upload-time = "2025-09-14T22:17:45.271Z" }, + { url = "https://files.pythonhosted.org/packages/7b/01/b5f4d4dbc59ef193e870495c6f1275f5b2928e01ff5a81fecb22a06e22fb/zstandard-0.25.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", size = 5814054, upload-time = "2025-09-14T22:17:47.08Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/fbd822d5c6f427cf158316d012c5a12f233473c2f9c5fe5ab1ae5d21f3d8/zstandard-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", size = 5360113, upload-time = "2025-09-14T22:17:48.893Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl", hash = "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", size = 436936, upload-time = "2025-09-14T22:17:52.658Z" }, + { url = "https://files.pythonhosted.org/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", size = 506232, upload-time = "2025-09-14T22:17:50.402Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl", hash = "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", size = 462671, upload-time = "2025-09-14T22:17:51.533Z" }, + { url = "https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", size = 795887, upload-time = "2025-09-14T22:17:54.198Z" }, + { url = "https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", size = 640658, upload-time = "2025-09-14T22:17:55.423Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", size = 5379849, upload-time = "2025-09-14T22:17:57.372Z" }, + { url = "https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", size = 5058095, upload-time = "2025-09-14T22:17:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", size = 5551751, upload-time = "2025-09-14T22:18:01.618Z" }, + { url = "https://files.pythonhosted.org/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", size = 6364818, upload-time = "2025-09-14T22:18:03.769Z" }, + { url = "https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", size = 5560402, upload-time = "2025-09-14T22:18:05.954Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", size = 4955108, upload-time = "2025-09-14T22:18:07.68Z" }, + { url = "https://files.pythonhosted.org/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", size = 5269248, upload-time = "2025-09-14T22:18:09.753Z" }, + { url = "https://files.pythonhosted.org/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", size = 5430330, upload-time = "2025-09-14T22:18:11.966Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", size = 5811123, upload-time = "2025-09-14T22:18:13.907Z" }, + { url = "https://files.pythonhosted.org/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", size = 5359591, upload-time = "2025-09-14T22:18:16.465Z" }, + { url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" }, + { url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" }, ] diff --git a/dev/i18n/check_translations_completeness.py b/dev/i18n/check_translations_completeness.py index ff99e5141969c..e3c2e0d841863 100755 --- a/dev/i18n/check_translations_completeness.py +++ b/dev/i18n/check_translations_completeness.py @@ -53,16 +53,21 @@ "ar": ["_zero", "_one", "_two", "_few", "_many", "_other"], "ca": MOST_COMMON_PLURAL_SUFFIXES, "de": MOST_COMMON_PLURAL_SUFFIXES, + "el": MOST_COMMON_PLURAL_SUFFIXES, "en": MOST_COMMON_PLURAL_SUFFIXES, "es": ["_one", "_many", "_other"], "fr": ["_one", "_many", "_other"], "he": ["_one", "_two", "_other"], "hi": MOST_COMMON_PLURAL_SUFFIXES, "hu": MOST_COMMON_PLURAL_SUFFIXES, + "it": ["_zero", "_one", "_many", "_other"], "ko": ["_other"], "nl": MOST_COMMON_PLURAL_SUFFIXES, "pl": ["_one", "_few", "_many", "_other"], + "pt": ["_zero", "_one", "_many", "_other"], + "th": ["_other"], "tr": MOST_COMMON_PLURAL_SUFFIXES, + "zh-CN": ["_other"], "zh-TW": ["_other"], } @@ -451,20 +456,31 @@ def print_translation_progress(console, locale_files, missing_counts, summary): "--add-missing", is_flag=True, default=False, - help="Add missing translations for the selected language, prefixed with 'TODO: translate:'.", + help="Add missing translations for all languages except English, prefixed with 'TODO: translate:'.", ) def cli(language: str | None = None, add_missing: bool = False): - if add_missing: - if not language: - raise ValueError("--language is required when passing --add_missing") - locale_path = LOCALES_DIR / language - locale_path.mkdir(exist_ok=True) locale_files = get_locale_files() console = Console(force_terminal=True, color_system="auto") print_locale_file_table(locale_files, console, language) found_difference = print_file_set_differences(locale_files, console, language) summary, missing_counts = compare_keys(locale_files, console) console.print("\n[bold underline]Summary of differences by language:[/bold underline]", style="cyan") + if add_missing and language != "en": + # Loop through all languages except 'en' and add missing translations + if language: + language_files = [lf for lf in locale_files if lf.locale == language] + else: + language_files = [lf for lf in locale_files if lf.locale != "en"] + for lf in language_files: + filtered_summary = {} + for filename, diff in summary.items(): + filtered_summary[filename] = LocaleSummary( + missing_keys={lf.locale: diff.missing_keys.get(lf.locale, [])}, + extra_keys={lf.locale: diff.extra_keys.get(lf.locale, [])}, + ) + add_missing_translations(lf.locale, filtered_summary, console) + # After adding, re-run the summary for all languages + summary, missing_counts = compare_keys(get_locale_files(), console) if language: locales = [lf.locale for lf in locale_files] if language not in locales: @@ -484,8 +500,6 @@ def cli(language: str | None = None, add_missing: bool = False): [lf for lf in locale_files if lf.locale == language], filtered_summary, console ) found_difference = found_difference or lang_diff - if add_missing: - add_missing_translations(language, filtered_summary, console) else: lang_diff = print_language_summary(locale_files, summary, console) found_difference = found_difference or lang_diff @@ -547,16 +561,11 @@ def add_keys(src, dst, prefix=""): full_key = f"{prefix}.{k}" if prefix else k base = get_plural_base(full_key, suffixes) if base and any(full_key == base + s for s in suffixes): - # Add all plural forms at the current level (not nested) for suffix in suffixes: plural_key = base + suffix key_name = plural_key.split(".")[-1] if plural_key in missing_keys: - if isinstance(v, dict): - dst[key_name] = {} - add_keys(v, dst[key_name], plural_key) - else: - dst[key_name] = f"TODO: translate: {v}" + dst[key_name] = f"TODO: translate: {v}" continue if full_key in missing_keys: if isinstance(v, dict): diff --git a/dev/react-plugin-tools/react_plugin_template/package.json b/dev/react-plugin-tools/react_plugin_template/package.json index 5f5ed1ffe82fa..b93711f5e2539 100644 --- a/dev/react-plugin-tools/react_plugin_template/package.json +++ b/dev/react-plugin-tools/react_plugin_template/package.json @@ -31,9 +31,9 @@ "@chakra-ui/anatomy": "^2.3.4", "@chakra-ui/react": "^3.20.0", "@emotion/react": "^11.14.0", - "next-themes": "^0.3.0", - "react": "^18.3.1", - "react-dom": "^18.3.1" + "next-themes": "^0.4.6", + "react": "^19.1.1", + "react-dom": "^19.1.1" }, "devDependencies": { "@eslint/compat": "^1.2.9", @@ -52,8 +52,7 @@ "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-prettier": "^5.2.6", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-perfectionist": "^4.12.3", + "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-unicorn": "^55.0.0", "globals": "^15.15.0", @@ -61,7 +60,7 @@ "prettier": "^3.5.3", "typescript": "~5.8.3", "typescript-eslint": "^8.31.1", - "vite": "^5.4.19", + "vite": "^5.4.20", "vite-plugin-css-injected-by-js": "^3.5.2", "vite-plugin-dts": "^4.3.0", "vitest": "^2.1.9" diff --git a/dev/react-plugin-tools/react_plugin_template/src/context/colorMode/ColorModeProvider.tsx b/dev/react-plugin-tools/react_plugin_template/src/context/colorMode/ColorModeProvider.tsx index 2b0c93cd403ac..96c29fc60314f 100644 --- a/dev/react-plugin-tools/react_plugin_template/src/context/colorMode/ColorModeProvider.tsx +++ b/dev/react-plugin-tools/react_plugin_template/src/context/colorMode/ColorModeProvider.tsx @@ -17,8 +17,7 @@ * under the License. */ -import { ThemeProvider } from "next-themes"; -import type { ThemeProviderProps } from "next-themes/dist/types"; +import { ThemeProvider, type ThemeProviderProps } from "next-themes"; export const ColorModeProvider = (props: ThemeProviderProps) => ( diff --git a/dev/react-plugin-tools/react_plugin_template/src/pages/HomePage.tsx b/dev/react-plugin-tools/react_plugin_template/src/pages/HomePage.tsx index 2d587c152d731..7fa7b038d7fef 100644 --- a/dev/react-plugin-tools/react_plugin_template/src/pages/HomePage.tsx +++ b/dev/react-plugin-tools/react_plugin_template/src/pages/HomePage.tsx @@ -22,7 +22,7 @@ import { Box, Button, Heading, Text, VStack } from "@chakra-ui/react"; import { useColorMode } from "src/context/colorMode"; export const HomePage = () => { - const { setColorMode, colorMode } = useColorMode(); + const { colorMode, setColorMode } = useColorMode(); return ( @@ -33,7 +33,7 @@ export const HomePage = () => { This project was bootstrapped with the Airflow React Plugin tool. - diff --git a/dev/react-plugin-tools/react_plugin_template/src/theme.ts b/dev/react-plugin-tools/react_plugin_template/src/theme.ts index 88bac3fd19299..464fbc8f86b50 100644 --- a/dev/react-plugin-tools/react_plugin_template/src/theme.ts +++ b/dev/react-plugin-tools/react_plugin_template/src/theme.ts @@ -18,7 +18,10 @@ */ /* eslint-disable perfectionist/sort-objects */ + +/* eslint-disable max-lines */ import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"; +import type { CSSProperties } from "react"; const generateSemanticTokens = (color: string, darkContrast: string = "white") => ({ solid: { value: `{colors.${color}.600}` }, @@ -30,147 +33,394 @@ const generateSemanticTokens = (color: string, darkContrast: string = "white") = focusRing: { value: { _light: `{colors.${color}.800}`, _dark: `{colors.${color}.200}` } }, }); -const customConfig = defineConfig({ +export const customConfig = defineConfig({ + // See https://chakra-ui.com/docs/theming/colors for more information on the colors used here. theme: { tokens: { colors: { - // Default green was too light - success: { - "50": { value: "#E0FFE0" }, - "100": { value: "#C2FFC2" }, - "200": { value: "#80FF80" }, - "300": { value: "#42FF42" }, - "400": { value: "#22C55E" }, - "500": { value: "#16A34A" }, - "600": { value: "#008000" }, - "700": { value: "#006100" }, - "800": { value: "#004200" }, - "900": { value: "#001F00" }, - "950": { value: "#000F00" }, - }, - failed: defaultConfig.theme?.tokens?.colors?.red ?? {}, - // Default gray was too dark - queued: { - "50": { value: "#F5F5F5" }, - "100": { value: "#EBEBEB" }, - "200": { value: "#D4D4D4" }, - "300": { value: "#BFBFBF" }, - "400": { value: "#ABABAB" }, - "500": { value: "#969696" }, - "600": { value: "#808080" }, - "700": { value: "#616161" }, - "800": { value: "#404040" }, - "900": { value: "#212121" }, - "950": { value: "#0F0F0F" }, - }, - skipped: defaultConfig.theme?.tokens?.colors?.pink ?? {}, - up_for_reschedule: defaultConfig.theme?.tokens?.colors?.cyan ?? {}, - up_for_retry: defaultConfig.theme?.tokens?.colors?.yellow ?? {}, - upstream_failed: defaultConfig.theme?.tokens?.colors?.orange ?? {}, - // lime - running: { - "50": { value: "#EFFBEF" }, - "100": { value: "#DEF7DE" }, - "200": { value: "#B9EEB9" }, - "300": { value: "#98E698" }, - "400": { value: "#78DE78" }, - "500": { value: "#53D553" }, - "600": { value: "#32CD32" }, - "700": { value: "#269C26" }, - "800": { value: "#196719" }, - "900": { value: "#0D350D" }, - "950": { value: "#061906" }, - }, - // violet - restarting: { - "50": { value: "#F6EBFF" }, - "100": { value: "#EDD6FF" }, - "200": { value: "#D9A8FF" }, - "300": { value: "#C880FF" }, - "400": { value: "#B657FF" }, - "500": { value: "#A229FF" }, - "600": { value: "#8F00FF" }, - "700": { value: "#6E00C2" }, - "800": { value: "#480080" }, - "900": { value: "#260042" }, - "950": { value: "#11001F" }, - }, - // mediumpurple - deferred: { - "50": { value: "#F6F3FC" }, - "100": { value: "#EDE7F9" }, - "200": { value: "#DACEF3" }, - "300": { value: "#C8B6ED" }, - "400": { value: "#B9A1E7" }, - "500": { value: "#A689E1" }, - "600": { value: "#9370DB" }, - "700": { value: "#6432C8" }, - "800": { value: "#412182" }, - "900": { value: "#211041" }, - "950": { value: "#100821" }, - }, - // tan - scheduled: { - "50": { value: "#FBF8F4" }, - "100": { value: "#F8F3ED" }, - "200": { value: "#F1E7DA" }, - "300": { value: "#E8D9C4" }, - "400": { value: "#E1CDB2" }, - "500": { value: "#DAC1A0" }, - "600": { value: "#D2B48C" }, - "700": { value: "#B9894B" }, - "800": { value: "#7D5C31" }, - "900": { value: "#3E2E18" }, - "950": { value: "#21180D" }, - }, - // lightblue - none: { - "50": { value: "#F7FBFD" }, - "100": { value: "#F3F9FB" }, - "200": { value: "#E4F2F7" }, - "300": { value: "#D8ECF3" }, - "400": { value: "#C8E5EE" }, - "500": { value: "#BDDFEB" }, - "600": { value: "#ADD8E6" }, - "700": { value: "#5FB2CE" }, - "800": { value: "#30819C" }, - "900": { value: "#18414E" }, - "950": { value: "#0C2027" }, - }, - // lightgrey - removed: { - "50": { value: "#FCFCFC" }, - "100": { value: "#F7F7F7" }, - "200": { value: "#F0F0F0" }, - "300": { value: "#E8E8E8" }, - "400": { value: "#E0E0E0" }, - "500": { value: "#DBDBDB" }, - "600": { value: "#D3D3D3" }, - "700": { value: "#9E9E9E" }, - "800": { value: "#696969" }, - "900": { value: "#363636" }, - "950": { value: "#1A1A1A" }, + black: { value: "oklch(0.23185 0.0323 266.44)" }, // Custom value for dark mode + brand: { + "50": { value: "oklch(0.98 0.006 248.717)" }, + "100": { value: "oklch(0.962 0.012 249.460)" }, + "200": { value: "oklch(0.923 0.023 255.082)" }, + "300": { value: "oklch(0.865 0.039 252.420)" }, + "400": { value: "oklch(0.705 0.066 256.378)" }, + "500": { value: "oklch(0.575 0.08 257.759)" }, + "600": { value: "oklch(0.469 0.084 257.657)" }, + "700": { value: "oklch(0.399 0.084 257.850)" }, + "800": { value: "oklch(0.324 0.072 260.329)" }, + "900": { value: "oklch(0.259 0.062 265.566)" }, + "950": { value: "oklch(0.179 0.05 265.487)" }, + }, + gray: { + // Values modified from original Tailwind to improve contrast in Chakra UI + "50": { value: "oklch(0.985 0.004 253)" }, // Original: oklch(0.985 0.002 247.839) + "100": { value: "oklch(0.955 0.006 253)" }, // Original: oklch(0.967 0.003 264.542) + "200": { value: "oklch(0.915 0.01 253)" }, // Original: oklch(0.928 0.006 264.531) + "300": { value: "oklch(0.85 0.016 253)" }, // Original: oklch(0.872 0.01 258.338) + "400": { value: "oklch(0.75 0.025 252)" }, // Original: oklch(0.707 0.022 261.325) + "500": { value: "oklch(0.63, 0.04, 252)" }, // Original: oklch(0.551 0.027 264.364) + "600": { value: "oklch(0.45 0.055 251)" }, // Original: oklch(0.446 0.03 256.802) + "700": { value: "oklch(0.35 0.045 251)" }, // Original: oklch(0.373 0.034 259.733) + "800": { value: "oklch(0.28 0.035 251)" }, // Original: oklch(0.278 0.033 256.848) + "900": { value: "oklch(0.18 0.03 251)" }, // Original: oklch(0.21 0.034 264.665) + "950": { value: "oklch(0.11 0.025 251)" }, // Original: oklch(0.13 0.028 261.692) + }, + // TAILWIND 4.0 COLORS + // See https://tailwindcss.com/docs/colors for more information on the colors used here. + red: { + "50": { value: "oklch(0.971 0.013 17.38)" }, + "100": { value: "oklch(0.936 0.032 17.717)" }, + "200": { value: "oklch(0.885 0.062 18.334)" }, + "300": { value: "oklch(0.808 0.114 19.571)" }, + "400": { value: "oklch(0.704 0.191 22.216)" }, + "500": { value: "oklch(0.637 0.237 25.331)" }, + "600": { value: "oklch(0.577 0.245 27.325)" }, + "700": { value: "oklch(0.505 0.213 27.518)" }, + "800": { value: "oklch(0.444 0.177 26.899)" }, + "900": { value: "oklch(0.396 0.141 25.723)" }, + "950": { value: "oklch(0.258 0.092 26.042)" }, + }, + // Values modified from original Tailwind to improve contrast in Chakra UI + orange: { + "50": { value: "oklch(0.982 0.013 83.915)" }, + "100": { value: "oklch(0.961 0.033 82.320)" }, + "200": { value: "oklch(0.918 0.065 79.975)" }, + "300": { value: "oklch(0.857 0.118 76.815)" }, + "400": { value: "oklch(0.7492 0.1439 62.081)" }, // Original: oklch(0.774 0.186 71.555) + "500": { value: "oklch(0.6462 0.1979 43.792)" }, // Original: oklch(0.705 0.213 47.604) + "600": { value: "oklch(0.5902 0.198 35.93)" }, // Original: oklch(0.632 0.214 41.185) + "700": { value: "oklch(0.553 0.184 41.777)" }, + "800": { value: "oklch(0.469 0.144 45.164)" }, + "900": { value: "oklch(0.414 0.110 48.717)" }, + "950": { value: "oklch(0.271 0.069 52.345)" }, + }, + amber: { + "50": { value: "oklch(0.987 0.022 95.277)" }, + "100": { value: "oklch(0.962 0.059 95.617)" }, + "200": { value: "oklch(0.924 0.12 95.746)" }, + "300": { value: "oklch(0.879 0.169 91.605)" }, + "400": { value: "oklch(0.828 0.189 84.429)" }, + "500": { value: "oklch(0.769 0.188 70.08)" }, + "600": { value: "oklch(0.666 0.179 58.318)" }, + "700": { value: "oklch(0.555 0.163 48.998)" }, + "800": { value: "oklch(0.473 0.137 46.201)" }, + "900": { value: "oklch(0.414 0.112 45.904)" }, + "950": { value: "oklch(0.279 0.077 45.635)" }, + }, + yellow: { + "50": { value: "oklch(0.987 0.026 102.212)" }, + "100": { value: "oklch(0.973 0.071 103.193)" }, + "200": { value: "oklch(0.945 0.129 101.54)" }, + "300": { value: "oklch(0.905 0.182 98.111)" }, + "400": { value: "oklch(0.852 0.199 91.936)" }, + "500": { value: "oklch(0.795 0.184 86.047)" }, + "600": { value: "oklch(0.681 0.162 75.834)" }, + "700": { value: "oklch(0.554 0.135 66.442)" }, + "800": { value: "oklch(0.476 0.114 61.907)" }, + "900": { value: "oklch(0.421 0.095 57.708)" }, + "950": { value: "oklch(0.286 0.066 53.813)" }, + }, + lime: { + "50": { value: "oklch(0.986 0.031 120.757)" }, + "100": { value: "oklch(0.967 0.067 122.328)" }, + "200": { value: "oklch(0.938 0.127 124.321)" }, + "300": { value: "oklch(0.897 0.196 126.665)" }, + "400": { value: "oklch(0.841 0.238 128.85)" }, + "500": { value: "oklch(0.768 0.233 130.85)" }, + "600": { value: "oklch(0.648 0.2 131.684)" }, + "700": { value: "oklch(0.532 0.157 131.589)" }, + "800": { value: "oklch(0.453 0.124 130.933)" }, + "900": { value: "oklch(0.405 0.101 131.063)" }, + "950": { value: "oklch(0.274 0.072 132.109)" }, + }, + green: { + // Values modified from original Tailwind to improve contrast in Chakra UI + "50": { value: "oklch(0.982 0.018 155.826)" }, + "100": { value: "oklch(0.962 0.044 156.743)" }, + "200": { value: "oklch(0.925 0.084 155.995)" }, + "300": { value: "oklch(0.75 0.18 153.0)" }, // Original: oklch(0.871 0.15 154.449) + "400": { value: "oklch(0.625 0.209 150.0)" }, // Original: oklch(0.792 0.209 151.711) + "500": { value: "oklch(0.528 0.219 149.579)" }, // Original: oklch(0.723 0.219 149.579) + "600": { value: "oklch(0.47 0.20 149.0)" }, // Original: oklch(0.627 0.194 149.214) + "700": { value: "oklch(0.40 0.16 149.5)" }, // Original: oklch(0.527 0.154 150.069) + "800": { value: "oklch(0.448 0.119 151.328)" }, + "900": { value: "oklch(0.393 0.095 152.535)" }, + "950": { value: "oklch(0.266 0.065 152.934)" }, + }, + emerald: { + "50": { value: "oklch(0.979 0.021 166.113)" }, + "100": { value: "oklch(0.95 0.052 163.051)" }, + "200": { value: "oklch(0.905 0.093 164.15)" }, + "300": { value: "oklch(0.845 0.143 164.978)" }, + "400": { value: "oklch(0.765 0.177 163.223)" }, + "500": { value: "oklch(0.696 0.17 162.48)" }, + "600": { value: "oklch(0.596 0.145 163.225)" }, + "700": { value: "oklch(0.508 0.118 165.612)" }, + "800": { value: "oklch(0.432 0.095 166.913)" }, + "900": { value: "oklch(0.378 0.077 168.94)" }, + "950": { value: "oklch(0.262 0.051 172.552)" }, + }, + teal: { + "50": { value: "oklch(0.984 0.014 180.72)" }, + "100": { value: "oklch(0.953 0.051 180.801)" }, + "200": { value: "oklch(0.91 0.096 180.426)" }, + "300": { value: "oklch(0.855 0.138 181.071)" }, + "400": { value: "oklch(0.777 0.152 181.912)" }, + "500": { value: "oklch(0.704 0.14 182.503)" }, + "600": { value: "oklch(0.6 0.118 184.704)" }, + "700": { value: "oklch(0.511 0.096 186.391)" }, + "800": { value: "oklch(0.437 0.078 188.216)" }, + "900": { value: "oklch(0.386 0.063 188.416)" }, + "950": { value: "oklch(0.277 0.046 192.524)" }, + }, + cyan: { + "50": { value: "oklch(0.984 0.019 200.873)" }, + "100": { value: "oklch(0.956 0.045 203.388)" }, + "200": { value: "oklch(0.917 0.08 205.041)" }, + "300": { value: "oklch(0.865 0.127 207.078)" }, + "400": { value: "oklch(0.789 0.154 211.53)" }, + "500": { value: "oklch(0.715 0.143 215.221)" }, + "600": { value: "oklch(0.609 0.126 221.723)" }, + "700": { value: "oklch(0.52 0.105 223.128)" }, + "800": { value: "oklch(0.45 0.085 224.283)" }, + "900": { value: "oklch(0.398 0.07 227.392)" }, + "950": { value: "oklch(0.302 0.056 229.695)" }, + }, + sky: { + "50": { value: "oklch(0.977 0.013 236.62)" }, + "100": { value: "oklch(0.951 0.026 236.824)" }, + "200": { value: "oklch(0.901 0.058 230.902)" }, + "300": { value: "oklch(0.828 0.111 230.318)" }, + "400": { value: "oklch(0.746 0.16 232.661)" }, + "500": { value: "oklch(0.685 0.169 237.323)" }, + "600": { value: "oklch(0.588 0.158 241.966)" }, + "700": { value: "oklch(0.5 0.134 242.749)" }, + "800": { value: "oklch(0.443 0.11 240.79)" }, + "900": { value: "oklch(0.391 0.09 240.876)" }, + "950": { value: "oklch(0.293 0.066 243.157)" }, + }, + blue: { + "50": { value: "oklch(0.97 0.014 254.604)" }, + "100": { value: "oklch(0.932 0.032 255.585)" }, + "200": { value: "oklch(0.882 0.059 254.128)" }, + "300": { value: "oklch(0.809 0.105 251.813)" }, + "400": { value: "oklch(0.707 0.165 254.624)" }, + "500": { value: "oklch(0.623 0.214 259.815)" }, + "600": { value: "oklch(0.546 0.245 262.881)" }, + "700": { value: "oklch(0.488 0.243 264.376)" }, + "800": { value: "oklch(0.424 0.199 265.638)" }, + "900": { value: "oklch(0.379 0.146 265.522)" }, + "950": { value: "oklch(0.282 0.091 267.935)" }, + }, + indigo: { + "50": { value: "oklch(0.962 0.018 272.314)" }, + "100": { value: "oklch(0.93 0.034 272.788)" }, + "200": { value: "oklch(0.87 0.065 274.039)" }, + "300": { value: "oklch(0.785 0.115 274.713)" }, + "400": { value: "oklch(0.673 0.182 276.935)" }, + "500": { value: "oklch(0.585 0.233 277.117)" }, + "600": { value: "oklch(0.511 0.262 276.966)" }, + "700": { value: "oklch(0.457 0.24 277.023)" }, + "800": { value: "oklch(0.398 0.195 277.366)" }, + "900": { value: "oklch(0.359 0.144 278.697)" }, + "950": { value: "oklch(0.257 0.09 281.288)" }, + }, + violet: { + "50": { value: "oklch(0.969 0.016 293.756)" }, + "100": { value: "oklch(0.943 0.029 294.588)" }, + "200": { value: "oklch(0.894 0.057 293.283)" }, + "300": { value: "oklch(0.811 0.111 293.571)" }, + "400": { value: "oklch(0.702 0.183 293.541)" }, + "500": { value: "oklch(0.606 0.25 292.717)" }, + "600": { value: "oklch(0.541 0.281 293.009)" }, + "700": { value: "oklch(0.491 0.27 292.581)" }, + "800": { value: "oklch(0.432 0.232 292.759)" }, + "900": { value: "oklch(0.38 0.189 293.745)" }, + "950": { value: "oklch(0.283 0.141 291.089)" }, + }, + purple: { + "50": { value: "oklch(0.977 0.014 308.299)" }, + "100": { value: "oklch(0.946 0.033 307.174)" }, + "200": { value: "oklch(0.902 0.063 306.703)" }, + "300": { value: "oklch(0.827 0.119 306.383)" }, + "400": { value: "oklch(0.714 0.203 305.504)" }, + "500": { value: "oklch(0.627 0.265 303.9)" }, + "600": { value: "oklch(0.558 0.288 302.321)" }, + "700": { value: "oklch(0.496 0.265 301.924)" }, + "800": { value: "oklch(0.438 0.218 303.724)" }, + "900": { value: "oklch(0.381 0.176 304.987)" }, + "950": { value: "oklch(0.291 0.149 302.717)" }, + }, + fuchsia: { + "50": { value: "oklch(0.977 0.017 320.058)" }, + "100": { value: "oklch(0.952 0.037 318.852)" }, + "200": { value: "oklch(0.903 0.076 319.62)" }, + "300": { value: "oklch(0.833 0.145 321.434)" }, + "400": { value: "oklch(0.74 0.238 322.16)" }, + "500": { value: "oklch(0.667 0.295 322.15)" }, + "600": { value: "oklch(0.591 0.293 322.896)" }, + "700": { value: "oklch(0.518 0.253 323.949)" }, + "800": { value: "oklch(0.452 0.211 324.591)" }, + "900": { value: "oklch(0.401 0.17 325.612)" }, + "950": { value: "oklch(0.293 0.136 325.661)" }, + }, + pink: { + "50": { value: "oklch(0.971 0.014 343.198)" }, + "100": { value: "oklch(0.948 0.028 342.258)" }, + "200": { value: "oklch(0.899 0.061 343.231)" }, + "300": { value: "oklch(0.823 0.12 346.018)" }, + "400": { value: "oklch(0.718 0.202 349.761)" }, + "500": { value: "oklch(0.656 0.241 354.308)" }, + "600": { value: "oklch(0.592 0.249 0.584)" }, + "700": { value: "oklch(0.525 0.223 3.958)" }, + "800": { value: "oklch(0.459 0.187 3.815)" }, + "900": { value: "oklch(0.408 0.153 2.432)" }, + "950": { value: "oklch(0.284 0.109 3.907)" }, + }, + rose: { + "50": { value: "oklch(0.969 0.015 12.422)" }, + "100": { value: "oklch(0.941 0.03 12.58)" }, + "200": { value: "oklch(0.892 0.058 10.001)" }, + "300": { value: "oklch(0.81 0.117 11.638)" }, + "400": { value: "oklch(0.712 0.194 13.428)" }, + "500": { value: "oklch(0.645 0.246 16.439)" }, + "600": { value: "oklch(0.586 0.253 17.585)" }, + "700": { value: "oklch(0.514 0.222 16.935)" }, + "800": { value: "oklch(0.455 0.188 13.697)" }, + "900": { value: "oklch(0.41 0.159 10.272)" }, + "950": { value: "oklch(0.271 0.105 12.094)" }, + }, + slate: { + "50": { value: "oklch(0.984 0.003 247.858)" }, + "100": { value: "oklch(0.968 0.007 247.896)" }, + "200": { value: "oklch(0.929 0.013 255.508)" }, + "300": { value: "oklch(0.869 0.022 252.894)" }, + "400": { value: "oklch(0.704 0.04 256.788)" }, + "500": { value: "oklch(0.554 0.046 257.417)" }, + "600": { value: "oklch(0.446 0.043 257.281)" }, + "700": { value: "oklch(0.372 0.044 257.287)" }, + "800": { value: "oklch(0.279 0.041 260.031)" }, + "900": { value: "oklch(0.208 0.042 265.755)" }, + "950": { value: "oklch(0.129 0.042 264.695)" }, + }, + zinc: { + "50": { value: "oklch(0.985 0 0)" }, + "100": { value: "oklch(0.967 0.001 286.375)" }, + "200": { value: "oklch(0.92 0.004 286.32)" }, + "300": { value: "oklch(0.871 0.006 286.286)" }, + "400": { value: "oklch(0.705 0.015 286.067)" }, + "500": { value: "oklch(0.552 0.016 285.938)" }, + "600": { value: "oklch(0.442 0.017 285.786)" }, + "700": { value: "oklch(0.37 0.013 285.805)" }, + "800": { value: "oklch(0.274 0.006 286.033)" }, + "900": { value: "oklch(0.21 0.006 285.885)" }, + "950": { value: "oklch(0.141 0.005 285.823)" }, + }, + neutral: { + "50": { value: "oklch(0.985 0 0)" }, + "100": { value: "oklch(0.97 0 0)" }, + "200": { value: "oklch(0.922 0 0)" }, + "300": { value: "oklch(0.87 0 0)" }, + "400": { value: "oklch(0.708 0 0)" }, + "500": { value: "oklch(0.556 0 0)" }, + "600": { value: "oklch(0.439 0 0)" }, + "700": { value: "oklch(0.371 0 0)" }, + "800": { value: "oklch(0.269 0 0)" }, + "900": { value: "oklch(0.205 0 0)" }, + "950": { value: "oklch(0.145 0 0)" }, + }, + stone: { + "50": { value: "oklch(0.985 0.001 106.423)" }, + "100": { value: "oklch(0.97 0.001 106.424)" }, + "200": { value: "oklch(0.923 0.003 48.717)" }, + "300": { value: "oklch(0.869 0.005 56.366)" }, + "400": { value: "oklch(0.709 0.01 56.259)" }, + "500": { value: "oklch(0.553 0.013 58.071)" }, + "600": { value: "oklch(0.444 0.011 73.639)" }, + "700": { value: "oklch(0.374 0.01 67.558)" }, + "800": { value: "oklch(0.268 0.007 34.298)" }, + "900": { value: "oklch(0.216 0.006 56.043)" }, + "950": { value: "oklch(0.147 0.004 49.25)" }, }, }, }, semanticTokens: { colors: { - success: generateSemanticTokens("success"), - failed: defaultConfig.theme?.semanticTokens?.colors?.red ?? {}, - queued: generateSemanticTokens("queued"), - skipped: defaultConfig.theme?.semanticTokens?.colors?.pink ?? {}, - up_for_reschedule: defaultConfig.theme?.semanticTokens?.colors?.cyan ?? {}, - up_for_retry: defaultConfig.theme?.semanticTokens?.colors?.yellow ?? {}, - upstream_failed: defaultConfig.theme?.semanticTokens?.colors?.orange ?? {}, - running: generateSemanticTokens("running"), - restarting: generateSemanticTokens("restarting"), - deferred: generateSemanticTokens("deferred"), - scheduled: generateSemanticTokens("scheduled"), - none: generateSemanticTokens("none", "black"), - removed: generateSemanticTokens("removed", "black"), + // Brand colors for consistent theming + brand: generateSemanticTokens("brand"), + // GENERIC STATE + danger: generateSemanticTokens("red"), + info: generateSemanticTokens("blue"), + warning: generateSemanticTokens("amber"), + error: generateSemanticTokens("red"), + // AIRFLOW TASK STATE + active: generateSemanticTokens("blue"), + success: generateSemanticTokens("green"), + failed: generateSemanticTokens("red"), + queued: generateSemanticTokens("stone"), + skipped: generateSemanticTokens("pink"), + up_for_reschedule: generateSemanticTokens("sky"), + up_for_retry: generateSemanticTokens("yellow"), + upstream_failed: generateSemanticTokens("orange"), + running: generateSemanticTokens("cyan"), + restarting: generateSemanticTokens("violet"), + deferred: generateSemanticTokens("purple"), + scheduled: generateSemanticTokens("zinc"), + none: generateSemanticTokens("gray"), + removed: generateSemanticTokens("slate"), + // TAILWIND 4.0 COLORS + red: generateSemanticTokens("red"), + orange: generateSemanticTokens("orange"), + amber: generateSemanticTokens("amber"), + yellow: generateSemanticTokens("yellow"), + lime: generateSemanticTokens("lime"), + green: generateSemanticTokens("green"), + emerald: generateSemanticTokens("emerald"), + teal: generateSemanticTokens("teal"), + cyan: generateSemanticTokens("cyan"), + sky: generateSemanticTokens("sky"), + blue: generateSemanticTokens("blue"), + indigo: generateSemanticTokens("indigo"), + violet: generateSemanticTokens("violet"), + purple: generateSemanticTokens("purple"), + fuchsia: generateSemanticTokens("fuchsia"), + pink: generateSemanticTokens("pink"), + rose: generateSemanticTokens("rose"), + slate: generateSemanticTokens("slate"), + gray: generateSemanticTokens("gray"), + zinc: generateSemanticTokens("zinc"), + neutral: generateSemanticTokens("neutral"), + stone: generateSemanticTokens("stone"), }, }, }, }); export const system = createSystem(defaultConfig, customConfig); + +// Utility function to resolve CSS variables to their computed values +// See: https://github.com/chakra-ui/panda/discussions/2200 +export const getComputedCSSVariableValue = (variable: string): string => + getComputedStyle(document.documentElement) + .getPropertyValue(variable.slice(4, variable.length - 1)) + .trim(); + +// Returns ReactFlow style props using Chakra UI CSS variables +export const getReactFlowThemeStyle = (colorMode: "dark" | "light"): CSSProperties => + ({ + // Background + "--xy-background-color": + colorMode === "dark" ? "var(--chakra-colors-brand-950)" : "var(--chakra-colors-brand-50)", + "--xy-background-pattern-color": + colorMode === "dark" ? "var(--chakra-colors-gray-200)" : "var(--chakra-colors-gray-800)", + + // Controls + "--xy-controls-button-background-color": + colorMode === "dark" ? "var(--chakra-colors-gray-800)" : "var(--chakra-colors-white)", + "--xy-controls-button-background-color-hover": + colorMode === "dark" ? "var(--chakra-colors-gray-700)" : "var(--chakra-colors-gray-100)", + + // MiniMap + "--xy-minimap-background-color": "var(--chakra-colors-bg)", + }) as CSSProperties; diff --git a/dev/react-plugin-tools/react_plugin_template/vite.config.ts b/dev/react-plugin-tools/react_plugin_template/vite.config.ts index dc9384ff2bc70..d610e0c173c54 100644 --- a/dev/react-plugin-tools/react_plugin_template/vite.config.ts +++ b/dev/react-plugin-tools/react_plugin_template/vite.config.ts @@ -38,10 +38,12 @@ export default defineConfig(({ command }) => { name: 'AirflowPlugin', }, rollupOptions: { - external: ["react", "react-dom"], + external: ["react", "react-dom", "react-router-dom", "react/jsx-runtime"], output: { globals: { react: "React", + "react-dom": "ReactDOM", + "react-router-dom": "ReactRouterDOM", "react/jsx-runtime": "ReactJSXRuntime", }, }, diff --git a/devel-common/pyproject.toml b/devel-common/pyproject.toml index 7cb72bba82ce1..d297bedbbcddf 100644 --- a/devel-common/pyproject.toml +++ b/devel-common/pyproject.toml @@ -35,7 +35,7 @@ dependencies = [ "kgb>=7.2.0", "requests_mock>=1.11.0", "rich>=13.6.0", - "ruff==0.12.12", + "ruff==0.14.1", "semver>=3.0.2", "time-machine>=2.15.0", "wheel>=0.42.0", @@ -67,7 +67,8 @@ dependencies = [ "twine>=4.0.2", ] "docs" = [ - "astroid>=3", + # Astroid 4 released 5 Oct 2025 breaks autoapi https://github.com/apache/airflow/issues/56420 + "astroid>=3,<4", "checksumdir>=1.2.0", "rich-click>=1.7.1", "click>=8.1.8", @@ -99,7 +100,7 @@ dependencies = [ "mypy" = [ # Mypy dependencies # TODO: upgrade to newer versions of MyPy continuously as they are released - "mypy==1.17.1", + "mypy==1.18.2", "types-Deprecated>=1.2.9.20240311", "types-Markdown>=3.6.0.20240316", "types-PyMySQL>=1.1.0.20240425", diff --git a/devel-common/src/tests_common/pytest_plugin.py b/devel-common/src/tests_common/pytest_plugin.py index 9f05f0ec8b0eb..a50dba0892135 100644 --- a/devel-common/src/tests_common/pytest_plugin.py +++ b/devel-common/src/tests_common/pytest_plugin.py @@ -18,8 +18,8 @@ from __future__ import annotations import importlib -import itertools import json +import logging import os import platform import re @@ -1700,13 +1700,9 @@ def _delete_log_template(): @pytest.fixture def reset_logging_config(): - import logging.config + from airflow.logging_config import configure_logging - from airflow import settings - from airflow.utils.module_loading import import_string - - logging_config = import_string(settings.LOGGING_CLASS_PATH) - logging.config.dictConfig(logging_config) + configure_logging() @pytest.fixture(scope="session", autouse=True) @@ -1795,6 +1791,7 @@ def refuse_to_run_test_from_wrongly_named_files(request: pytest.FixtureRequest): @pytest.fixture(autouse=True, scope="session") +@pytest.mark.usefixture("_ensure_configured_logging") def initialize_providers_manager(): if importlib.util.find_spec("airflow") is None: # If airflow is not installed, we should not initialize providers manager @@ -2025,7 +2022,7 @@ def add_expected_folders_to_pythonpath(): @pytest.fixture -def cap_structlog(): +def cap_structlog(monkeypatch, request): """ Test that structlog messages are logged. @@ -2040,62 +2037,96 @@ def cap_structlog(): ... ... assert "not logged" not in cap_structlog # not in works too """ - import structlog.testing - from structlog import configure, get_config + import structlog.stdlib + from structlog import DropEvent, configure, get_config - class LogCapture(structlog.testing.LogCapture): - # Partial comparison -- only check keys passed in, or the "event"/message if a single value is given - def __contains__(self, target): - if not isinstance(target, dict): - target = {"event": target} + from tests_common.test_utils.logs import StructlogCapture - def predicate(e): - def check_one(key, want): - try: - val = e.get(key) - if isinstance(want, re.Pattern): - return want.match(val) - return val == want - except Exception: - return False + cap = StructlogCapture() + # Modify `_Configuration.default_processors` set via `configure` but always + # keep the list instance intact to not break references held by bound + # loggers. + processors = get_config()["processors"] + old_processors = processors.copy() - return all(itertools.starmap(check_one, target.items())) + # And modify the stdlib logging to capture too + handler = logging.root.handlers[0] + if not isinstance(handler.formatter, structlog.stdlib.ProcessorFormatter): + raise AssertionError( + f"{type(handler.formatter)} is not an instance of structlog.stblid.ProcessorFormatter" + ) - return any(predicate(e) for e in self.entries) + std_formatter = structlog.stdlib.ProcessorFormatter( + foreign_pre_chain=handler.formatter.foreign_pre_chain, + pass_foreign_args=True, + use_get_message=False, + processor=cap, + ) - def __getitem__(self, i): - return self.entries[i] + def stdlib_filter(record): + with suppress(DropEvent): + std_formatter.format(record) + return False - def __iter__(self): - return iter(self.entries) + dict_exc_formatter = structlog.tracebacks.ExceptionDictTransformer( + use_rich=False, + show_locals=False, + ) - def __repr__(self): - return repr(self.entries) + dict_tracebacks = structlog.processors.ExceptionRenderer(dict_exc_formatter) + timestamper = structlog.processors.MaybeTimeStamper(fmt="iso") - @property - def text(self): - """All the event text as a single multi-line string.""" - return "\n".join(e["event"] for e in self.entries) + level = logging.INFO + for setting_name in ("log_cli_level", "log_level"): + log_level = request.config.getoption(setting_name) + if log_level is None: + log_level = request.config.getini(setting_name) + if log_level: + level = structlog.processors.NAME_TO_LEVEL[log_level.lower()] + break + + monkeypatch.setattr(logging.root, "level", level) + # Ensure the handler doesn't filter anything itself (in stblib both loggers and handlers have their own + # independent level!) + monkeypatch.setattr(handler, "level", 0) + monkeypatch.setattr(handler, "filters", [stdlib_filter]) - cap = LogCapture() - # Modify `_Configuration.default_processors` set via `configure` but always - # keep the list instance intact to not break references held by bound - # loggers. - processors = get_config()["processors"] - old_processors = processors.copy() try: # clear processors list and use LogCapture for testing processors.clear() + processors.append(timestamper) + processors.append(dict_tracebacks) processors.append(cap) configure(processors=processors) yield cap finally: + cap._finalize() # remove LogCapture and restore original processors processors.clear() processors.extend(old_processors) configure(processors=processors) +@pytest.fixture(scope="session", autouse=True) +def _ensure_configured_logging(request): + try: + from airflow.sdk._shared.logging import configure_logging + except ModuleNotFoundError: + try: + from airflow.sdk._shared.logging import configure_logging + except ModuleNotFoundError: + return + + log_level = logging.INFO + for setting_name in ("log_cli_level", "log_level"): + log_level = request.config.getoption(setting_name) + if log_level is None: + log_level = request.config.getini(setting_name) + if log_level: + break + configure_logging(log_level=log_level) + + @pytest.fixture(name="caplog") def override_caplog(request): """ @@ -2104,15 +2135,28 @@ def override_caplog(request): This is in an effort to reduce flakiness from caplog related tests where one test file can change log behaviour and bleed in to affecting other test files """ - # We need this `_ispytest` so it doesn't warn about using private - fixture = pytest.LogCaptureFixture(request.node, _ispytest=True) - yield fixture - fixture._finalize() - if "airflow.logging_config" in sys.modules: - import airflow.logging_config + try: + import airflow.sdk._shared.logging + except ModuleNotFoundError: + try: + import airflow.sdk._shared.logging + except ModuleNotFoundError: + # No structlog available, fallback to the stock one. Compat for pre-3.1 + + # We need this `_ispytest` so it doesn't warn about using private + fixture = pytest.LogCaptureFixture(request.node, _ispytest=True) + yield fixture + fixture._finalize() + + if "airflow.logging_config" in sys.modules: + import airflow.logging_config - airflow.logging_config.configure_logging() + airflow.logging_config.configure_logging() + return + + yield request.getfixturevalue("cap_structlog") + return @pytest.fixture diff --git a/devel-common/src/tests_common/test_utils/logs.py b/devel-common/src/tests_common/test_utils/logs.py index 475d83054a19f..ef717e19b13b7 100644 --- a/devel-common/src/tests_common/test_utils/logs.py +++ b/devel-common/src/tests_common/test_utils/logs.py @@ -17,7 +17,15 @@ # under the License. from __future__ import annotations +import itertools import json +import logging +import re +import sys +import traceback +from collections.abc import MutableMapping +from contextlib import ExitStack, contextmanager +from typing import TYPE_CHECKING, NoReturn from airflow.models import Log @@ -26,6 +34,9 @@ except ImportError: from airflow.sdk.execution_time.secrets_masker import DEFAULT_SENSITIVE_FIELDS # type:ignore[no-redef] +if TYPE_CHECKING: + from structlog.typing import EventDict, WrappedLogger + def _masked_value_check(data, sensitive_fields): """ @@ -73,3 +84,236 @@ def check_last_log(session, dag_id, event, logical_date, expected_extra=None, ch _masked_value_check(extra_json, DEFAULT_SENSITIVE_FIELDS) session.query(Log).delete() + + +class StructlogCapture: + """ + Test that structlog messages are logged. + + This extends the feature built in to structlog to make it easier to find if a message is logged. + + >>> def test_something(cap_structlog): + ... log.info("some event", field1=False, field2=[1, 2]) + ... log.info("some event", field1=True) + ... assert "some_event" in cap_structlog # a string searches on `event` field + ... assert {"event": "some_event", "field1": True} in cap_structlog # Searches only on passed fields + ... assert {"field2": [1, 2]} in cap_structlog + ... + ... assert "not logged" not in cap_structlog # not in works too + + This fixture class will also manage the log level of stdlib loggers via ``at_level`` and ``set_level``. + """ + + # This class is a manual mixing of pytest's LogCaptureFixture and structlog's LogCapture class, but + # tailored to Airflow's "send all logs via structlog" approach + + _logger: str | None = None + NAME_TO_LEVEL: dict[str, int] + PER_LOGGER_LEVELS: MutableMapping[str, int] + """The logger we specifically want to capture log messages from""" + + def __init__(self): + self.entries = [] + self._initial_logger_levels: dict[str, int] = {} + + try: + from airflow.sdk._shared.logging.structlog import NAME_TO_LEVEL, PER_LOGGER_LEVELS + + self.NAME_TO_LEVEL = NAME_TO_LEVEL + self.PER_LOGGER_LEVELS = PER_LOGGER_LEVELS + + try: + import airflow._shared.logging.structlog + except ModuleNotFoundError: + pass + else: + airflow._shared.logging.structlog.PER_LOGGER_LEVELS = PER_LOGGER_LEVELS + except ModuleNotFoundError: + from airflow._shared.logging.structlog import NAME_TO_LEVEL, PER_LOGGER_LEVELS + + self.NAME_TO_LEVEL = NAME_TO_LEVEL + self.PER_LOGGER_LEVELS = PER_LOGGER_LEVELS + + def _finalize(self) -> None: + """ + Finalize the fixture. + + This restores the log levels and the disabled logging levels changed by :meth:`set_level`. + """ + for logger_name, level in self._initial_logger_levels.items(): + logger = logging.getLogger(logger_name) + logger.setLevel(level) + if level is logging.NOTSET: + del self.PER_LOGGER_LEVELS[logger_name] + else: + self.PER_LOGGER_LEVELS[logger_name] = level + + def __contains__(self, target): + import operator + + if isinstance(target, str): + + def predicate(e): + return e["event"] == target + elif isinstance(target, dict): + # Partial comparison -- only check keys passed in + get = operator.itemgetter(*target.keys()) + want = tuple(target.values()) + + def predicate(e): + try: + got = get(e) + return all( + expected.match(val) if isinstance(expected, re.Pattern) else val == expected + for (val, expected) in zip(got, want) + ) + except Exception: + return False + else: + raise TypeError(f"Can't search logs using {type(target)}") + + return any(predicate(e) for e in self.entries) + + def __getitem__(self, i): + return self.entries[i] + + def __iter__(self): + return iter(self.entries) + + def __repr__(self): + return f"" + + def __call__(self, logger: WrappedLogger, method_name: str, event_dict: EventDict) -> NoReturn: + from structlog import DropEvent + from structlog._log_levels import map_method_name + + event_dict["event"] = str(event_dict["event"]) + event_dict["log_level"] = map_method_name(method_name) + if name := getattr(logger, "name", None): + event_dict["logger_name"] = name + + # Capture the current exception. This mirrors the "ExceptionRenderer", but much more minimal for + # testing + if event_dict.get("exc_info") is True: + event_dict["exc_info"] = sys.exc_info() + self.entries.append(event_dict) + + raise DropEvent + + @property + def text(self): + """All the event text as a single multi-line string.""" + + def exc_dict_to_string(exc): + if isinstance(exc, tuple): + yield from traceback.format_exception(*exc) + return + for i, e in enumerate(exc): + if i != 0: + yield "\n" + yield "During handling of the above exception, another exception occurred:\n" + yield "\n" + + # This doesn't include the stacktrace, but this should be enough for testing + yield f"{e['exc_type']}: {e['exc_value']}\n" + + def format(e): + yield e["event"] + "\n" + if exc_info := e.get("exc_info"): + yield from exc_dict_to_string(exc_info) + elif exc := e.get("exception"): + yield from exc_dict_to_string(exc) + + return "".join(itertools.chain.from_iterable(map(format, self.entries))) + + # These next fns make it duck-type the same as Pytests "caplog" fixture + @property + def messages(self): + """All the event messages as a list.""" + return [e["event"] for e in self.entries] + + @contextmanager + def at_level(self, level: str | int, logger: str | None = None): + if isinstance(level, str): + level = self.NAME_TO_LEVEL[level.lower()] + + # Since we explicitly set the level of the "airflow" logger in our config, we want to set that by + # default if the test auithor didn't ask for this at a specific logger to be set (otherwise we only + # set the root logging level, which doesn't have any affect if sub loggers have explicit levels set) + keys: tuple[str, ...] = (logger or "",) + if not logger: + keys += ("airflow",) + + def _reset(logger, key, level, orig_hdlr_level): + logger.setLevel(level) + if level is logging.NOTSET: + del self.PER_LOGGER_LEVELS[key] + else: + self.PER_LOGGER_LEVELS[key] = level + if logger.handlers: + hdlr = logger.handlers[0] + hdlr.setLevel(orig_hdlr_level) + + cm = ExitStack() + for key in keys: + old = self.PER_LOGGER_LEVELS.get(key, logging.NOTSET) + self.PER_LOGGER_LEVELS[key] = level + stdlogger = logging.getLogger(key) + stdlogger.setLevel(level) + hdlr = orig_hdlr_level = None + if stdlogger.handlers: + hdlr = stdlogger.handlers[0] + orig_hdlr_level = hdlr.level + hdlr.setLevel(level) + cm.callback(_reset, stdlogger, key, old, orig_hdlr_level) + + with cm: + yield self + + def set_level(self, level: str | int, logger: str | None = None): + # Set the global level + if isinstance(level, str): + level = self.NAME_TO_LEVEL[level.lower()] + + key = logger or "" + + stdlogger = logging.getLogger(key) + self._initial_logger_levels[key] = self.PER_LOGGER_LEVELS.get(key, logging.NOTSET) + + self.PER_LOGGER_LEVELS[key] = level + stdlogger.setLevel(level) + + def clear(self): + self.entries = [] + + # pytest caplog support: + # TODO: deprecate and remove all of this in tests + @property + def records(self): + records = [] + for entry in self.entries: + record = logging.LogRecord( + entry.get("logger", "") or entry.get("logger_name"), + self.NAME_TO_LEVEL.get(entry.get("log_level"), 0), + "?", + 0, + entry["event"], + (), + entry.get("exc_info") or entry.get("exception"), + None, + None, + ) + record.message = record.msg + records.append(record) + return records + + @property + def record_tuples(self): + return [ + ( + entry.get("logger", "") or entry.get("logger_name"), + self.NAME_TO_LEVEL.get(entry.get("log_level"), 0), + entry.get("event"), + ) + for entry in self.entries + ] diff --git a/docker-stack-docs/README.md b/docker-stack-docs/README.md index 137072ac309d0..d0f1b71ad4cc7 100644 --- a/docker-stack-docs/README.md +++ b/docker-stack-docs/README.md @@ -31,12 +31,12 @@ Every time a new version of Airflow is released, the images are prepared in the [apache/airflow DockerHub](https://hub.docker.com/r/apache/airflow) for all the supported Python versions. -You can find the following images there (Assuming Airflow version `3.1.0`): +You can find the following images there (Assuming Airflow version `3.1.1`): * `apache/airflow:latest` - the latest released Airflow image with default Python version (3.12 currently) * `apache/airflow:latest-pythonX.Y` - the latest released Airflow image with specific Python version -* `apache/airflow:3.1.0` - the versioned Airflow image with default Python version (3.12 currently) -* `apache/airflow:3.1.0-pythonX.Y` - the versioned Airflow image with specific Python version +* `apache/airflow:3.1.1` - the versioned Airflow image with default Python version (3.12 currently) +* `apache/airflow:3.1.1-pythonX.Y` - the versioned Airflow image with specific Python version Those are "reference" regular images. They contain the most common set of extras, dependencies and providers that are often used by the users and they are good to "try-things-out" when you want to just take Airflow for a spin, @@ -47,8 +47,8 @@ via [Building the image](https://airflow.apache.org/docs/docker-stack/build.html * `apache/airflow:slim-latest` - the latest released Airflow image with default Python version (3.12 currently) * `apache/airflow:slim-latest-pythonX.Y` - the latest released Airflow image with specific Python version -* `apache/airflow:slim-3.1.0` - the versioned Airflow image with default Python version (3.12 currently) -* `apache/airflow:slim-3.1.0-pythonX.Y` - the versioned Airflow image with specific Python version +* `apache/airflow:slim-3.1.1` - the versioned Airflow image with default Python version (3.12 currently) +* `apache/airflow:slim-3.1.1-pythonX.Y` - the versioned Airflow image with specific Python version The Apache Airflow image provided as convenience package is optimized for size, and it provides just a bare minimal set of the extras and dependencies installed and in most cases diff --git a/docker-stack-docs/build-arg-ref.rst b/docker-stack-docs/build-arg-ref.rst index ec65153d42a7f..bad7047a326d7 100644 --- a/docker-stack-docs/build-arg-ref.rst +++ b/docker-stack-docs/build-arg-ref.rst @@ -32,7 +32,7 @@ Those are the most common arguments that you use when you want to build a custom +==========================================+===========================================+=============================================+ | ``AIRFLOW_VERSION`` | :subst-code:`|airflow-version|` | Version of Airflow. | +------------------------------------------+-------------------------------------------+---------------------------------------------+ -| ``AIRFLOW_PYTHON_VERSION`` | ``3.12.11`` | Version of Python. | +| ``AIRFLOW_PYTHON_VERSION`` | ``3.12.12`` | Version of Python. | +------------------------------------------+-------------------------------------------+---------------------------------------------+ | ``AIRFLOW_EXTRAS`` | (see below the table) | Default extras with which Airflow is | | | | installed. | diff --git a/docker-stack-docs/changelog.rst b/docker-stack-docs/changelog.rst index c70b16c3a3ccb..d1073bf578808 100644 --- a/docker-stack-docs/changelog.rst +++ b/docker-stack-docs/changelog.rst @@ -62,6 +62,13 @@ especially dev libraries installed with ``apt`` might not be installed by defaul as a side-effect in the original image, however that should only affect those who want to customise the image. They should be able to install in their custom images following the :doc:`Building the image ` +The Python 3.13 image for Airflow 3.1.0 (both slim and regular) does not contain ``fab`` provider because +at the time of release the ``fab`` provider did not support Python 3.13. It should be possible to install +future versions of ``fab`` provider (when they support Python 3.13) in the image using ``pip install``, +and until it is possible - if you need ``fab`` provider (and particularly FABAuthManager) in the +image, you should use Python 3.12 image. You can use experimental KeycloakAuthManager in Python 3.13 image +or develop your own AuthManager. + Airflow 3.0.2 ~~~~~~~~~~~~~ diff --git a/docker-stack-docs/conf.py b/docker-stack-docs/conf.py index c42e311844cb6..e7919e2ca6863 100644 --- a/docker-stack-docs/conf.py +++ b/docker-stack-docs/conf.py @@ -35,7 +35,6 @@ import os from typing import Any -import airflow from docs.utils.conf_constants import ( AIRFLOW_FAVICON_PATH, AIRFLOW_REPO_ROOT_PATH, @@ -56,6 +55,8 @@ get_rst_epilogue, ) +import airflow + PACKAGE_NAME = "docker-stack" DOCKER_STACK_DOCS_PATH = AIRFLOW_REPO_ROOT_PATH / "docker-stack-docs" os.environ["AIRFLOW_PACKAGE_NAME"] = PACKAGE_NAME diff --git a/docker-stack-docs/docker-examples/customizing/add-build-essential-custom.sh b/docker-stack-docs/docker-examples/customizing/add-build-essential-custom.sh index e2c0e55692ae5..8a0aed47c7d86 100755 --- a/docker-stack-docs/docker-examples/customizing/add-build-essential-custom.sh +++ b/docker-stack-docs/docker-examples/customizing/add-build-essential-custom.sh @@ -33,7 +33,7 @@ docker build . \ --pull \ --build-arg BASE_IMAGE="debian:bookworm-slim" \ --build-arg AIRFLOW_VERSION="${AIRFLOW_VERSION}" \ - --build-arg AIRFLOW_PYTHON_VERSION="3.12.11" \ + --build-arg AIRFLOW_PYTHON_VERSION="3.12.12" \ --build-arg ADDITIONAL_PYTHON_DEPS="mpi4py==4.1.0" \ --build-arg ADDITIONAL_DEV_APT_DEPS="libopenmpi-dev" \ --build-arg ADDITIONAL_RUNTIME_APT_DEPS="openmpi-common" \ diff --git a/docker-stack-docs/docker-examples/customizing/custom-sources.sh b/docker-stack-docs/docker-examples/customizing/custom-sources.sh index 4ea37142e135f..44848e7835863 100755 --- a/docker-stack-docs/docker-examples/customizing/custom-sources.sh +++ b/docker-stack-docs/docker-examples/customizing/custom-sources.sh @@ -33,7 +33,7 @@ docker build . -f Dockerfile \ --pull \ --platform 'linux/amd64' \ --build-arg BASE_IMAGE="debian:bookworm-slim" \ - --build-arg AIRFLOW_PYTHON_VERSION="3.12.11" \ + --build-arg AIRFLOW_PYTHON_VERSION="3.12.12" \ --build-arg AIRFLOW_VERSION="${AIRFLOW_VERSION}" \ --build-arg ADDITIONAL_AIRFLOW_EXTRAS="slack,odbc" \ --build-arg ADDITIONAL_PYTHON_DEPS=" \ diff --git a/docker-stack-docs/docker-examples/customizing/pypi-dev-runtime-deps.sh b/docker-stack-docs/docker-examples/customizing/pypi-dev-runtime-deps.sh index f6faea085a9a2..5846252d7a06b 100755 --- a/docker-stack-docs/docker-examples/customizing/pypi-dev-runtime-deps.sh +++ b/docker-stack-docs/docker-examples/customizing/pypi-dev-runtime-deps.sh @@ -33,7 +33,7 @@ export DOCKER_BUILDKIT=1 docker build . \ --pull \ --build-arg BASE_IMAGE="debian:bookworm-slim" \ - --build-arg AIRFLOW_PYTHON_VERSION="3.12.11" \ + --build-arg AIRFLOW_PYTHON_VERSION="3.12.12" \ --build-arg AIRFLOW_VERSION="${AIRFLOW_VERSION}" \ --build-arg ADDITIONAL_AIRFLOW_EXTRAS="jdbc" \ --build-arg ADDITIONAL_PYTHON_DEPS="pandas==2.1.2" \ diff --git a/docker-stack-docs/docker-examples/customizing/pypi-extras-and-deps.sh b/docker-stack-docs/docker-examples/customizing/pypi-extras-and-deps.sh index 8b90cacc5cb15..542cc29578a1f 100755 --- a/docker-stack-docs/docker-examples/customizing/pypi-extras-and-deps.sh +++ b/docker-stack-docs/docker-examples/customizing/pypi-extras-and-deps.sh @@ -32,7 +32,7 @@ export DOCKER_BUILDKIT=1 docker build . \ --pull \ --build-arg BASE_IMAGE="debian:bookworm-slim" \ - --build-arg AIRFLOW_PYTHON_VERSION="3.12.11" \ + --build-arg AIRFLOW_PYTHON_VERSION="3.12.12" \ --build-arg AIRFLOW_VERSION="${AIRFLOW_VERSION}" \ --build-arg ADDITIONAL_AIRFLOW_EXTRAS="mssql,hdfs" \ --build-arg ADDITIONAL_PYTHON_DEPS="oauth2client" \ diff --git a/docker-stack-docs/docker-examples/customizing/pypi-selected-version.sh b/docker-stack-docs/docker-examples/customizing/pypi-selected-version.sh index d5660170c04bc..7c6d9be927e00 100755 --- a/docker-stack-docs/docker-examples/customizing/pypi-selected-version.sh +++ b/docker-stack-docs/docker-examples/customizing/pypi-selected-version.sh @@ -31,7 +31,7 @@ export DOCKER_BUILDKIT=1 docker build . \ --build-arg BASE_IMAGE="debian:bookworm-slim" \ - --build-arg AIRFLOW_PYTHON_VERSION="3.12.11" \ + --build-arg AIRFLOW_PYTHON_VERSION="3.12.12" \ --build-arg AIRFLOW_VERSION="${AIRFLOW_VERSION}" \ --tag "my-pypi-selected-version:0.0.1" # [END build] diff --git a/docker-stack-docs/docker-examples/extending/add-airflow-configuration/Dockerfile b/docker-stack-docs/docker-examples/extending/add-airflow-configuration/Dockerfile index 3bb2585a64b3f..9c1a10ae8cef9 100644 --- a/docker-stack-docs/docker-examples/extending/add-airflow-configuration/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/add-airflow-configuration/Dockerfile @@ -15,7 +15,7 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 ENV AIRFLOW__CORE__LOAD_EXAMPLES=True ENV AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=my_conn_string # [END Dockerfile] diff --git a/docker-stack-docs/docker-examples/extending/add-apt-packages/Dockerfile b/docker-stack-docs/docker-examples/extending/add-apt-packages/Dockerfile index 4b669eefa0476..623b87ee79581 100644 --- a/docker-stack-docs/docker-examples/extending/add-apt-packages/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/add-apt-packages/Dockerfile @@ -15,7 +15,7 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 USER root RUN apt-get update \ && apt-get install -y --no-install-recommends \ diff --git a/docker-stack-docs/docker-examples/extending/add-build-essential-extend/Dockerfile b/docker-stack-docs/docker-examples/extending/add-build-essential-extend/Dockerfile index c6bb483024211..3f36b1125072f 100644 --- a/docker-stack-docs/docker-examples/extending/add-build-essential-extend/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/add-build-essential-extend/Dockerfile @@ -15,7 +15,7 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 USER root RUN apt-get update \ && apt-get install -y --no-install-recommends \ diff --git a/docker-stack-docs/docker-examples/extending/add-providers/Dockerfile b/docker-stack-docs/docker-examples/extending/add-providers/Dockerfile index 0c119156a8996..84947574c79fa 100644 --- a/docker-stack-docs/docker-examples/extending/add-providers/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/add-providers/Dockerfile @@ -15,7 +15,7 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 USER root RUN apt-get update \ && apt-get install -y --no-install-recommends \ diff --git a/docker-stack-docs/docker-examples/extending/add-pypi-packages-constraints/Dockerfile b/docker-stack-docs/docker-examples/extending/add-pypi-packages-constraints/Dockerfile index 4c0f44f7dbb73..4f6358501721c 100644 --- a/docker-stack-docs/docker-examples/extending/add-pypi-packages-constraints/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/add-pypi-packages-constraints/Dockerfile @@ -15,6 +15,6 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 RUN pip install --no-cache-dir "apache-airflow==${AIRFLOW_VERSION}" lxml --constraint "${HOME}/constraints.txt" # [END Dockerfile] diff --git a/docker-stack-docs/docker-examples/extending/add-pypi-packages-uv/Dockerfile b/docker-stack-docs/docker-examples/extending/add-pypi-packages-uv/Dockerfile index 253b952d83229..aad3e01c02a6d 100644 --- a/docker-stack-docs/docker-examples/extending/add-pypi-packages-uv/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/add-pypi-packages-uv/Dockerfile @@ -15,7 +15,7 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 # The `uv` tools is Rust packaging tool that is much faster than `pip` and other installer # Support for uv as installation tool is experimental diff --git a/docker-stack-docs/docker-examples/extending/add-pypi-packages/Dockerfile b/docker-stack-docs/docker-examples/extending/add-pypi-packages/Dockerfile index d4f913637ebae..f0c330390729e 100644 --- a/docker-stack-docs/docker-examples/extending/add-pypi-packages/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/add-pypi-packages/Dockerfile @@ -15,6 +15,6 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 RUN pip install --no-cache-dir "apache-airflow==${AIRFLOW_VERSION}" lxml # [END Dockerfile] diff --git a/docker-stack-docs/docker-examples/extending/add-requirement-packages/Dockerfile b/docker-stack-docs/docker-examples/extending/add-requirement-packages/Dockerfile index f26ec60854d05..02074035f0941 100644 --- a/docker-stack-docs/docker-examples/extending/add-requirement-packages/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/add-requirement-packages/Dockerfile @@ -15,7 +15,7 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 COPY requirements.txt / RUN pip install --no-cache-dir "apache-airflow==${AIRFLOW_VERSION}" -r /requirements.txt # [END Dockerfile] diff --git a/docker-stack-docs/docker-examples/extending/custom-providers/Dockerfile b/docker-stack-docs/docker-examples/extending/custom-providers/Dockerfile index f5cf359493829..8be9acfc29028 100644 --- a/docker-stack-docs/docker-examples/extending/custom-providers/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/custom-providers/Dockerfile @@ -15,6 +15,6 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 RUN pip install "apache-airflow==${AIRFLOW_VERSION}" --no-cache-dir apache-airflow-providers-docker==2.5.1 # [END Dockerfile] diff --git a/docker-stack-docs/docker-examples/extending/embedding-dags/Dockerfile b/docker-stack-docs/docker-examples/extending/embedding-dags/Dockerfile index bbeb5795ecb70..08aaa6c4702f1 100644 --- a/docker-stack-docs/docker-examples/extending/embedding-dags/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/embedding-dags/Dockerfile @@ -15,7 +15,7 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 COPY --chown=airflow:root test_dag.py /opt/airflow/dags diff --git a/docker-stack-docs/docker-examples/extending/writable-directory/Dockerfile b/docker-stack-docs/docker-examples/extending/writable-directory/Dockerfile index f362d4dfbcfb0..e9021ef087cdd 100644 --- a/docker-stack-docs/docker-examples/extending/writable-directory/Dockerfile +++ b/docker-stack-docs/docker-examples/extending/writable-directory/Dockerfile @@ -15,7 +15,7 @@ # This is an example Dockerfile. It is not intended for PRODUCTION use # [START Dockerfile] -FROM apache/airflow:3.1.0 +FROM apache/airflow:3.1.1 RUN umask 0002; \ mkdir -p ~/writeable-directory # [END Dockerfile] diff --git a/docker-stack-docs/docker-examples/restricted/restricted_environments.sh b/docker-stack-docs/docker-examples/restricted/restricted_environments.sh index d7de8aa86edb8..92ead48fbcc4d 100755 --- a/docker-stack-docs/docker-examples/restricted/restricted_environments.sh +++ b/docker-stack-docs/docker-examples/restricted/restricted_environments.sh @@ -48,7 +48,7 @@ export DOCKER_BUILDKIT=1 docker build . \ --pull \ --build-arg BASE_IMAGE="debian:bookworm-slim" \ - --build-arg AIRFLOW_PYTHON_VERSION="3.12.11" \ + --build-arg AIRFLOW_PYTHON_VERSION="3.12.12" \ --build-arg AIRFLOW_INSTALLATION_METHOD="apache-airflow" \ --build-arg AIRFLOW_VERSION="${AIRFLOW_VERSION}" \ --build-arg INSTALL_MYSQL_CLIENT="false" \ diff --git a/docker-stack-docs/entrypoint.rst b/docker-stack-docs/entrypoint.rst index bcfde3e705382..329a3a350850f 100644 --- a/docker-stack-docs/entrypoint.rst +++ b/docker-stack-docs/entrypoint.rst @@ -132,7 +132,7 @@ if you specify extra arguments. For example: .. code-block:: bash - docker run -it apache/airflow:3.1.0-python3.10 bash -c "ls -la" + docker run -it apache/airflow:3.1.1-python3.10 bash -c "ls -la" total 16 drwxr-xr-x 4 airflow root 4096 Jun 5 18:12 . drwxr-xr-x 1 root root 4096 Jun 5 18:12 .. @@ -144,7 +144,7 @@ you pass extra parameters. For example: .. code-block:: bash - > docker run -it apache/airflow:3.1.0-python3.10 python -c "print('test')" + > docker run -it apache/airflow:3.1.1-python3.10 python -c "print('test')" test If first argument equals to ``airflow`` - the rest of the arguments is treated as an Airflow command @@ -152,13 +152,13 @@ to execute. Example: .. code-block:: bash - docker run -it apache/airflow:3.1.0-python3.10 airflow webserver + docker run -it apache/airflow:3.1.1-python3.10 airflow webserver If there are any other arguments - they are simply passed to the "airflow" command .. code-block:: bash - > docker run -it apache/airflow:3.1.0-python3.10 help + > docker run -it apache/airflow:3.1.1-python3.10 help usage: airflow [-h] GROUP_OR_COMMAND ... Positional Arguments: @@ -318,9 +318,12 @@ Upgrading Airflow DB If you set :envvar:`_AIRFLOW_DB_MIGRATE` variable to a non-empty value, the entrypoint will run the ``airflow db migrate`` command right after verifying the connection. You can also use this when you are running Airflow with internal SQLite database (default) to upgrade the db and create -admin users at entrypoint, so that you can start the webserver immediately. Note - using SQLite is -intended only for testing purpose, never use SQLite in production as it has severe limitations when it -comes to concurrency. +admin users at entrypoint, so that you can start the webserver immediately. If no command is +provided to the container and :envvar:`_AIRFLOW_DB_MIGRATE` is set, the container will exit +cleanly after completing the database migration. This allows one-off init containers +(such as ``airflow-init``) to perform setup without requiring a placeholder command to suppress +CLI errors. Note - using SQLite is intended only for testing purpose, never use SQLite in +production as it has severe limitations when it comes to concurrency. Creating admin user ................... @@ -363,7 +366,7 @@ database and creating an ``admin/admin`` Admin user with the following command: --env "_AIRFLOW_DB_MIGRATE=true" \ --env "_AIRFLOW_WWW_USER_CREATE=true" \ --env "_AIRFLOW_WWW_USER_PASSWORD=admin" \ - apache/airflow:3.1.0-python3.10 webserver + apache/airflow:3.1.1-python3.10 webserver .. code-block:: bash @@ -372,7 +375,7 @@ database and creating an ``admin/admin`` Admin user with the following command: --env "_AIRFLOW_DB_MIGRATE=true" \ --env "_AIRFLOW_WWW_USER_CREATE=true" \ --env "_AIRFLOW_WWW_USER_PASSWORD_CMD=echo admin" \ - apache/airflow:3.1.0-python3.10 webserver + apache/airflow:3.1.1-python3.10 webserver The commands above perform initialization of the SQLite database, create admin user with admin password and Admin role. They also forward local port ``8080`` to the webserver port and finally start the webserver. @@ -412,6 +415,6 @@ Example: --env "_AIRFLOW_DB_MIGRATE=true" \ --env "_AIRFLOW_WWW_USER_CREATE=true" \ --env "_AIRFLOW_WWW_USER_PASSWORD_CMD=echo admin" \ - apache/airflow:3.1.0-python3.10 webserver + apache/airflow:3.1.1-python3.10 webserver This method is only available starting from Docker image of Airflow 2.1.1 and above. diff --git a/docker-tests/tests/docker_tests/test_prod_image.py b/docker-tests/tests/docker_tests/test_prod_image.py index 76b594f8e7ebc..984ab7d0e9037 100644 --- a/docker-tests/tests/docker_tests/test_prod_image.py +++ b/docker-tests/tests/docker_tests/test_prod_image.py @@ -93,6 +93,12 @@ def test_required_providers_are_installed(self, default_docker_image): else: packages_to_install = set(REGULAR_IMAGE_PROVIDERS) assert len(packages_to_install) != 0 + python_version = run_bash_in_docker( + "python --version", + image=default_docker_image, + ) + if python_version.startswith("Python 3.13"): + packages_to_install.discard("apache-airflow-providers-fab") output = run_bash_in_docker( "airflow providers list --output json", image=default_docker_image, @@ -194,7 +200,17 @@ def test_pip_dependencies_conflict(self, default_docker_image): "package_name,import_names", SLIM_PACKAGE_IMPORTS.items() if testing_slim_image else REGULAR_PACKAGE_IMPORTS.items(), ) - def test_check_dependencies_imports(self, package_name, import_names, default_docker_image): + def test_check_dependencies_imports( + self, package_name: str, import_names: list[str], default_docker_image: str + ): + if package_name == "providers": + python_version = run_bash_in_docker( + "python --version", + image=default_docker_image, + ) + if python_version.startswith("Python 3.13"): + if "airflow.providers.fab" in import_names: + import_names.remove("airflow.providers.fab") run_python_in_docker(f"import {','.join(import_names)}", image=default_docker_image) def test_there_is_no_opt_airflow_airflow_folder(self, default_docker_image): diff --git a/docs/images/documentation_architecture.md5sum b/docs/images/documentation_architecture.md5sum index 394ee887a84e3..de72fbd745d8d 100644 --- a/docs/images/documentation_architecture.md5sum +++ b/docs/images/documentation_architecture.md5sum @@ -1 +1 @@ -1f460a38c43a136d03d3891ea7299d09 +8948941e4684025792d1947d3e4aa971 diff --git a/docs/images/documentation_architecture.png b/docs/images/documentation_architecture.png index 20bf207fd40d7..62e7db2d9f256 100644 Binary files a/docs/images/documentation_architecture.png and b/docs/images/documentation_architecture.png differ diff --git a/docs/images/documentation_architecture.py b/docs/images/documentation_architecture.py index fff1d3b911789..5e7df5ab16cef 100644 --- a/docs/images/documentation_architecture.py +++ b/docs/images/documentation_architecture.py @@ -22,7 +22,6 @@ from diagrams.aws.storage import S3 from diagrams.custom import Custom from diagrams.onprem.client import User, Users -from diagrams.onprem.network import Apache from rich.console import Console MY_DIR = Path(__file__).parent @@ -32,6 +31,7 @@ console = Console(width=400, color_system="standard") GITHUB_LOGO = MY_DIR / "logos" / "github.png" +ASF_LOGO = MY_DIR / "logos" / "asf_logo_wide.png" graph_attr = { "concentrate": "false", @@ -85,7 +85,7 @@ def generate_documentation_architecture_diagram(): with Cluster("Live Docs", graph_attr={"margin": "80"}): live_bucket = S3("live-docs-airflow-apache-org") apache_airflow_site_archive_repo = Custom("apache-airflow-site-archive", GITHUB_LOGO.as_posix()) - apache_live_webserver = Apache("https://airflow.apache.org") + apache_live_webserver = Custom("https://airflow.apache.org", ASF_LOGO.as_posix()) release_manager >> Edge(color="black", style="solid", label="Publish package docs") >> live_bucket ( diff --git a/docs/images/logos/asf_logo_wide.png b/docs/images/logos/asf_logo_wide.png new file mode 100644 index 0000000000000..cef985efb0219 Binary files /dev/null and b/docs/images/logos/asf_logo_wide.png differ diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index fd3bbe39f39f2..a4dbbdf3202aa 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -66,6 +66,7 @@ AnExampleDisplayName AnnotateTextResponse AnotherExampleDisplayName ans +anser Ansible anyOf apache @@ -225,6 +226,7 @@ bytestring cacert Cadwyn callables +callsite camelCase Cancelled cancelled @@ -1575,6 +1577,7 @@ sched schedulable schedulername schemas +scrollbar sdk sdks searchpath @@ -1968,6 +1971,7 @@ Utils utils uuid uv +uvicorn V1JobList validator validators diff --git a/generated/provider_metadata.json b/generated/provider_metadata.json index 69a5011f903c4..fe915f9c5600f 100644 --- a/generated/provider_metadata.json +++ b/generated/provider_metadata.json @@ -119,6 +119,10 @@ "5.2.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:38Z" + }, + "5.2.3": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "alibaba": { @@ -555,6 +559,10 @@ "9.11.0": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "9.12.0": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "apache.beam": { @@ -1751,6 +1759,10 @@ "1.10.1": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "1.10.2": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "apache.kylin": { @@ -2423,6 +2435,10 @@ "1.0.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "1.0.3": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "apprise": { @@ -3373,6 +3389,10 @@ "10.6.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "10.7.0": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "cohere": { @@ -3787,6 +3807,10 @@ "1.27.4": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:38Z" + }, + "1.27.5": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "databricks": { @@ -4013,6 +4037,10 @@ "7.7.0": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "7.7.1": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "datadog": { @@ -4729,6 +4757,10 @@ "1.1.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "1.1.3": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "elasticsearch": { @@ -5199,6 +5231,14 @@ "2.3.1": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "2.4.0": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" + }, + "2.4.1": { + "associated_airflow_version": "3.0.6", + "date_released": "2025-08-17T18:26:38Z" } }, "facebook": { @@ -5477,6 +5517,10 @@ "0.0.5": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "0.0.6": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "github": { @@ -5873,6 +5917,10 @@ "17.0.0": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:38Z" + }, + "17.1.0": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "grpc": { @@ -6805,6 +6853,12 @@ "date_released": "2025-08-02T06:58:37Z" } }, + "keycloak": { + "0.0.1": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-17T18:26:38Z" + } + }, "microsoft.azure": { "1.0.0": { "associated_airflow_version": "2.0.0", @@ -7089,6 +7143,10 @@ "12.6.0": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "12.6.1": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "microsoft.mssql": { @@ -7455,6 +7513,10 @@ "3.10.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "3.11.0": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "mongo": { @@ -8353,6 +8415,10 @@ "2.6.0": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "2.6.1": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "opensearch": { @@ -9269,6 +9335,10 @@ "6.2.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:38Z" + }, + "6.2.3": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "presto": { @@ -9489,6 +9559,10 @@ "1.4.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "1.4.3": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "redis": { @@ -9859,6 +9933,10 @@ "4.10.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:38Z" + }, + "4.10.3": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "segment": { @@ -10249,6 +10327,10 @@ "5.3.3": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "5.3.4": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "singularity": { @@ -10529,6 +10611,10 @@ "9.1.3": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:38Z" + }, + "9.1.4": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "smtp": { @@ -10627,6 +10713,10 @@ "2.1.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "2.2.0": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "snowflake": { @@ -10885,6 +10975,10 @@ "6.5.1": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "6.5.2": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "sqlite": { @@ -11197,6 +11291,10 @@ "4.1.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "4.1.3": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "standard": { @@ -11259,6 +11357,10 @@ "1.5.0": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "1.6.0": { + "associated_airflow_version": "3.0.6", + "date_released": "2025-08-17T18:26:38Z" } }, "tableau": { @@ -11763,6 +11865,10 @@ "6.3.2": { "associated_airflow_version": "3.0.4", "date_released": "2025-08-02T06:58:37Z" + }, + "6.3.3": { + "associated_airflow_version": "3.0.5", + "date_released": "2025-08-11T05:36:14Z" } }, "vertica": { diff --git a/go-sdk/.pre-commit-config.yaml b/go-sdk/.pre-commit-config.yaml new file mode 100644 index 0000000000000..4154c0801682d --- /dev/null +++ b/go-sdk/.pre-commit-config.yaml @@ -0,0 +1,73 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +--- +default_stages: [pre-commit, pre-push] +default_language_version: + golang: 1.24.0 +minimum_prek_version: '0.0.28' +repos: + - repo: meta + hooks: + - id: identity + name: Print checked files + description: Print input to the static check hooks for troubleshooting + - id: check-hooks-apply + name: Check if all hooks apply to the repository + - repo: https://github.com/Lucas-C/pre-commit-hooks + # replace hash with version once PR #103 merged comes in a release + rev: abdd8b62891099da34162217ecb3872d22184a51 + hooks: + - id: insert-license + name: Add license for all Go files + types: [go] + exclude: mocks/.*\.go$ + args: + - --comment-style + - "|//|" + - --license-filepath + - ../scripts/ci/license-templates/LICENSE.txt + - --insert-license-after-regex + # We need this 'generated by' line at the top for `golines` to not format it + - '// Code generated by .*' + - repo: local + hooks: + - id: go-mockery + name: Generate mocks for go + entry: vektra/mockery:3 + exclude: mocks/.*\.go$ + types: [go] + pass_filenames: false + language: docker_image + - id: go-mod-tidy + name: Run go mod tidy + entry: go mod tidy + types: [go] + exclude: mocks/.*\.go$ + pass_filenames: false + language: golang + - id: gofmt + name: Format go code + entry: golines --base-formatter=gofumpt --write-output --max-len=100 --chain-split-dots + additional_dependencies: [github.com/segmentio/golines@latest, mvdan.cc/gofumpt@v0.8.0] + types: [go] + language: golang + - id: gci + name: Consistent import ordering for Go files + entry: gci write --skip-generated -s standard -s default -s localmodule + additional_dependencies: [github.com/daixiang0/gci@v0.13.6] + types: [go] + language: golang diff --git a/helm-tests/tests/chart_utils/helm_template_generator.py b/helm-tests/tests/chart_utils/helm_template_generator.py index ed194609c5716..3cd93aea09cfd 100644 --- a/helm-tests/tests/chart_utils/helm_template_generator.py +++ b/helm-tests/tests/chart_utils/helm_template_generator.py @@ -19,18 +19,20 @@ import json import os import subprocess +from datetime import datetime from functools import cache from pathlib import Path from tempfile import NamedTemporaryFile +from time import timezone from typing import Any import jmespath import jsonschema import requests import yaml -from airflow_breeze.utils.console import get_console -from airflow_breeze.utils.github import log_github_rate_limit_error from kubernetes.client.api_client import ApiClient +from requests import Response +from rich.console import Console api_client = ApiClient() @@ -55,6 +57,47 @@ GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "") +console = Console(width=400, color_system="standard") + + +def log_github_rate_limit_error(response: Response) -> None: + """ + Logs info about GitHub rate limit errors (primary or secondary). + """ + if response.status_code not in (403, 429): + return + + remaining = response.headers.get("x-rateLimit-remaining") + reset = response.headers.get("x-rateLimit-reset") + retry_after = response.headers.get("retry-after") + + try: + message = response.json().get("message", "") + except Exception: + message = response.text or "" + + remaining_int = int(remaining) if remaining and remaining.isdigit() else None + + if reset and reset.isdigit(): + reset_dt = datetime.fromtimestamp(int(reset), tz=timezone.utc) + reset_time = reset_dt.strftime("%Y-%m-%d %H:%M:%S UTC") + else: + reset_time = "unknown" + + if remaining_int == 0: + print(f"Primary rate limit exceeded. No requests remaining. Reset at {reset_time}.") + return + + # Message for secondary looks like: "You have exceeded a secondary rate limit" + if "secondary rate limit" in message.lower(): + if retry_after and retry_after.isdigit(): + print(f"Secondary rate limit exceeded. Retry after {retry_after} seconds.") + else: + print(f"Secondary rate limit exceeded. Please wait until {reset_time} or at least 60 seconds.") + return + + print(f"Rate limit error. Status: {response.status_code}, Message: {message}") + @cache def get_schema_k8s(api_version, kind, kubernetes_version): @@ -75,7 +118,7 @@ def get_schema_k8s(api_version, kind, kubernetes_version): headers["Authorization"] = f"Bearer {GITHUB_TOKEN}" headers["X-GitHub-Api-Version"] = "2022-11-28" else: - get_console().print("[info] No GITHUB_TOKEN found. Using unauthenticated requests.") + console.print("[bright_blue] No GITHUB_TOKEN found. Using unauthenticated requests.") response = requests.get(url, headers=headers) log_github_rate_limit_error(response) diff --git a/kubernetes-tests/tests/kubernetes_tests/test_kubernetes_pod_operator.py b/kubernetes-tests/tests/kubernetes_tests/test_kubernetes_pod_operator.py index 3f74aa805bb96..77d44ed5a67ab 100644 --- a/kubernetes-tests/tests/kubernetes_tests/test_kubernetes_pod_operator.py +++ b/kubernetes-tests/tests/kubernetes_tests/test_kubernetes_pod_operator.py @@ -970,20 +970,24 @@ def test_pod_template_file( await_pod_completion_mock.return_value = pod_mock context = create_context(k) - # I'm not really sure what the point is of this assert - with caplog.at_level(logging.DEBUG, logger="airflow.task.operators"): + # TODO: once Airflow 3.1 is the min version, replace this with out structlog-based caplog fixture + with mock.patch.object(k.log, "debug") as debug_logs: k.execute(context) - expected_lines = [ - "Starting pod:", - "api_version: v1", - "kind: Pod", - "metadata:", - " annotations: {}", - " creation_timestamp: null", - " deletion_grace_period_seconds: null", - ] - actual = next(x.getMessage() for x in caplog.records if x.msg == "Starting pod:\n%s").splitlines() - assert actual[: len(expected_lines)] == expected_lines + expected_lines = "\n".join( + [ + "api_version: v1", + "kind: Pod", + "metadata:", + " annotations: {}", + " creation_timestamp: null", + " deletion_grace_period_seconds: null", + ] + ) + # Make a nice assert if it's not there + debug_logs.assert_any_call("Starting pod:\n%s", mock.ANY) + # Now we know it is there, examine the second argument + mock_call = next(call for call in debug_logs.mock_calls if call[1][0] == "Starting pod:\n%s") + assert mock_call[1][1][: len(expected_lines)] == expected_lines actual_pod = self.api_client.sanitize_for_serialization(k.pod) expected_dict = { @@ -1473,8 +1477,7 @@ def test_log_output_configurations(self, log_prefix_enabled, log_formatter, expe ) # Test the _log_message method directly - logger = logging.getLogger("airflow.providers.cncf.kubernetes.utils.pod_manager.PodManager") - with mock.patch.object(logger, "info") as mock_info: + with mock.patch.object(k.pod_manager.log, "info") as mock_info: k.pod_manager._log_message( message=marker, container_name="base", diff --git a/performance/requirements.txt b/performance/requirements.txt index 2e913c9233400..50fef03cc13f1 100644 --- a/performance/requirements.txt +++ b/performance/requirements.txt @@ -1,2 +1,2 @@ -apache-airflow==3.0.6 +apache-airflow==3.1.0 openlineage-airflow==1.37.0 diff --git a/providers-summary-docs/conf.py b/providers-summary-docs/conf.py index 2219f0bcb8ab6..7329988f99818 100644 --- a/providers-summary-docs/conf.py +++ b/providers-summary-docs/conf.py @@ -35,9 +35,6 @@ import os from typing import Any -from sphinx_exts.provider_yaml_utils import load_package_data - -import airflow from docs.utils.conf_constants import ( AIRFLOW_FAVICON_PATH, AIRFLOW_REPO_ROOT_PATH, @@ -56,6 +53,9 @@ get_intersphinx_mapping, get_rst_epilogue, ) +from sphinx_exts.provider_yaml_utils import load_package_data + +import airflow PACKAGE_NAME = "apache-airflow-providers" PROVIDERS_SUMMARY_DOCS_PATH = AIRFLOW_REPO_ROOT_PATH / "providers-summary-docs" diff --git a/providers/amazon/src/airflow/providers/amazon/aws/auth_manager/routes/login.py b/providers/amazon/src/airflow/providers/amazon/aws/auth_manager/routes/login.py index 5dab5de6b40f1..c3ca59a28c140 100644 --- a/providers/amazon/src/airflow/providers/amazon/aws/auth_manager/routes/login.py +++ b/providers/amazon/src/airflow/providers/amazon/aws/auth_manager/routes/login.py @@ -35,6 +35,7 @@ from airflow.providers.amazon.aws.auth_manager.constants import CONF_SAML_METADATA_URL_KEY, CONF_SECTION_NAME from airflow.providers.amazon.aws.auth_manager.datamodels.login import LoginResponse from airflow.providers.amazon.aws.auth_manager.user import AwsAuthManagerUser +from airflow.providers.amazon.version_compat import AIRFLOW_V_3_1_1_PLUS try: from onelogin.saml2.auth import OneLogin_Saml2_Auth @@ -101,7 +102,12 @@ def login_callback(request: Request): if relay_state == "login-redirect": response = RedirectResponse(url=url, status_code=303) secure = bool(conf.get("api", "ssl_cert", fallback="")) - response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure) + # In Airflow 3.1.1 authentication changes, front-end no longer handle the token + # See https://github.com/apache/airflow/pull/55506 + if AIRFLOW_V_3_1_1_PLUS: + response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure, httponly=True) + else: + response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure) return response if relay_state == "login-token": return LoginResponse(access_token=token) diff --git a/providers/amazon/src/airflow/providers/amazon/aws/hooks/glue.py b/providers/amazon/src/airflow/providers/amazon/aws/hooks/glue.py index cdf9347009098..002282d594763 100644 --- a/providers/amazon/src/airflow/providers/amazon/aws/hooks/glue.py +++ b/providers/amazon/src/airflow/providers/amazon/aws/hooks/glue.py @@ -109,7 +109,7 @@ def __init__( "retry": retry_if_exception(self._should_retry_on_error), "wait": wait_exponential(multiplier=1, min=1, max=60), "stop": stop_after_attempt(5), - "before_sleep": before_sleep_log(self.log, log_level=20), + "before_sleep": before_sleep_log(self.log, log_level=20), # type: ignore[arg-type] "reraise": True, } diff --git a/providers/amazon/src/airflow/providers/amazon/aws/utils/task_log_fetcher.py b/providers/amazon/src/airflow/providers/amazon/aws/utils/task_log_fetcher.py index a5fd8af3ba1d7..24b426a536e20 100644 --- a/providers/amazon/src/airflow/providers/amazon/aws/utils/task_log_fetcher.py +++ b/providers/amazon/src/airflow/providers/amazon/aws/utils/task_log_fetcher.py @@ -28,7 +28,7 @@ from airflow.providers.amazon.aws.hooks.logs import AwsLogsHook if TYPE_CHECKING: - from logging import Logger + from airflow.sdk.types import Logger class AwsTaskLogFetcher(Thread): diff --git a/providers/amazon/src/airflow/providers/amazon/version_compat.py b/providers/amazon/src/airflow/providers/amazon/version_compat.py index f2e3fdfc6afc5..f7b680bd10d25 100644 --- a/providers/amazon/src/airflow/providers/amazon/version_compat.py +++ b/providers/amazon/src/airflow/providers/amazon/version_compat.py @@ -34,6 +34,7 @@ def get_base_airflow_version_tuple() -> tuple[int, int, int]: AIRFLOW_V_3_0_PLUS = get_base_airflow_version_tuple() >= (3, 0, 0) AIRFLOW_V_3_1_PLUS: bool = get_base_airflow_version_tuple() >= (3, 1, 0) +AIRFLOW_V_3_1_1_PLUS: bool = get_base_airflow_version_tuple() >= (3, 1, 1) if AIRFLOW_V_3_1_PLUS: from airflow.sdk import BaseHook diff --git a/providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py b/providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py index 2714b036e721a..c5abfa7991251 100644 --- a/providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py +++ b/providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py @@ -97,6 +97,7 @@ def setup_tests(self, create_runtime_ti, tmp_path, monkeypatch): conn.create_log_group(logGroupName=self.remote_log_group) processors = structlog.get_config()["processors"] + logger_factory = structlog.get_config()["logger_factory"] old_processors = processors.copy() try: @@ -106,7 +107,11 @@ def setup_tests(self, create_runtime_ti, tmp_path, monkeypatch): # Set up the right chain of processors so the event looks like we want for our full test monkeypatch.setattr(airflow.logging_config, "REMOTE_TASK_LOG", self.subject) - procs, _ = airflow.sdk.log.logging_processors(enable_pretty_log=False) + try: + procs = airflow.sdk.log.logging_processors(colors=False, json_output=False) + except TypeError: + # Compat issue only comes up in the tests, not in the real code + procs, _ = airflow.sdk.log.logging_processors(enable_pretty_log=False) processors.clear() processors.extend(procs) @@ -127,7 +132,7 @@ def drop(*args): # remove LogCapture and restore original processors processors.clear() processors.extend(old_processors) - structlog.configure(processors=old_processors) + structlog.configure(processors=old_processors, logger_factory=logger_factory) @time_machine.travel(datetime(2025, 3, 27, 21, 58, 1, 2345), tick=False) def test_log_message(self): diff --git a/providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py b/providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py index 47fa354af535a..9b41ac18cc93d 100644 --- a/providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py +++ b/providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py @@ -19,6 +19,7 @@ import contextlib import copy +import logging import os from unittest import mock @@ -138,27 +139,33 @@ def test_log_exists_no_hook(self): with pytest.raises(ConnectionError, match="Fake: Failed to connect"): subject.s3_log_exists(self.remote_log_location) - def test_s3_read_when_log_missing(self): + def test_s3_read_when_log_missing(self, caplog): url = "s3://bucket/foo" - with mock.patch.object(self.subject.log, "error") as mock_error: + with caplog.at_level(logging.ERROR): result = self.subject.s3_read(url, return_error=True) - msg = ( - f"Could not read logs from {url} with error: An error occurred (404) when calling the " - f"HeadObject operation: Not Found" - ) - assert result == msg - mock_error.assert_called_once_with(msg, exc_info=True) + msg = ( + f"Could not read logs from {url} with error: An error occurred (404) when calling the " + f"HeadObject operation: Not Found" + ) + assert result == msg + assert len(caplog.records) == 1 + rec = caplog.records[0] + assert rec.levelno == logging.ERROR + assert rec.exc_info is not None - def test_read_raises_return_error(self): + def test_read_raises_return_error(self, caplog): url = "s3://nonexistentbucket/foo" - with mock.patch.object(self.subject.log, "error") as mock_error: + with caplog.at_level(logging.ERROR): result = self.subject.s3_read(url, return_error=True) msg = ( f"Could not read logs from {url} with error: An error occurred (NoSuchBucket) when " f"calling the HeadObject operation: The specified bucket does not exist" ) - assert result == msg - mock_error.assert_called_once_with(msg, exc_info=True) + assert result == msg + assert len(caplog.records) == 1 + rec = caplog.records[0] + assert rec.levelno == logging.ERROR + assert rec.exc_info is not None def test_write(self): with mock.patch.object(self.subject.log, "error") as mock_error: @@ -176,11 +183,15 @@ def test_write_existing(self): assert body == b"previous \ntext" - def test_write_raises(self): + def test_write_raises(self, caplog): url = "s3://nonexistentbucket/foo" - with mock.patch.object(self.subject.log, "error") as mock_error: + with caplog.at_level(logging.ERROR): self.subject.write("text", url) - mock_error.assert_called_once_with("Could not write logs to %s", url, exc_info=True) + assert len(caplog.records) == 1 + rec = caplog.records[0] + assert rec.levelno == logging.ERROR + assert rec.message == f"Could not write logs to {url}" + assert rec.exc_info is not None @pytest.mark.db_test diff --git a/providers/apache/beam/src/airflow/providers/apache/beam/hooks/beam.py b/providers/apache/beam/src/airflow/providers/apache/beam/hooks/beam.py index e40e7f086e780..8810ff454e04b 100644 --- a/providers/apache/beam/src/airflow/providers/apache/beam/hooks/beam.py +++ b/providers/apache/beam/src/airflow/providers/apache/beam/hooks/beam.py @@ -39,7 +39,7 @@ from airflow.providers.common.compat.standard.utils import prepare_virtualenv if TYPE_CHECKING: - import logging + from airflow.sdk.types import Logger _APACHE_BEAM_VERSION_SCRIPT = "import apache_beam; print(apache_beam.__version__)" @@ -122,7 +122,7 @@ def beam_options_to_args(options: dict) -> list[str]: def process_fd( proc, fd, - log: logging.Logger, + log: Logger, process_line_callback: Callable[[str], None] | None = None, is_dataflow_job_id_exist_callback: Callable[[], bool] | None = None, ): @@ -152,7 +152,7 @@ def process_fd( def run_beam_command( cmd: list[str], - log: logging.Logger, + log: Logger, process_line_callback: Callable[[str], None] | None = None, working_directory: str | None = None, is_dataflow_job_id_exist_callback: Callable[[], bool] | None = None, @@ -614,7 +614,7 @@ async def start_pipeline_async( async def run_beam_command_async( self, cmd: list[str], - log: logging.Logger, + log: Logger, working_directory: str | None = None, process_line_callback: Callable[[str], None] | None = None, ) -> int: diff --git a/providers/apache/flink/tests/unit/apache/flink/sensors/test_flink_kubernetes.py b/providers/apache/flink/tests/unit/apache/flink/sensors/test_flink_kubernetes.py index cbaf52e0aca1a..dea745b9ccf21 100644 --- a/providers/apache/flink/tests/unit/apache/flink/sensors/test_flink_kubernetes.py +++ b/providers/apache/flink/tests/unit/apache/flink/sensors/test_flink_kubernetes.py @@ -20,7 +20,8 @@ from __future__ import annotations import json -from unittest.mock import call, patch +import logging +from unittest.mock import ANY, patch import pytest from kubernetes.client import V1ObjectMeta, V1Pod, V1PodList @@ -1069,7 +1070,6 @@ def test_namespace_from_connection(self, mock_get_namespaced_crd, mock_kubernete "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_ERROR_CLUSTER, ) - @patch("logging.Logger.error") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", return_value=TEST_POD_LOGS, @@ -1079,7 +1079,7 @@ def test_namespace_from_connection(self, mock_get_namespaced_crd, mock_kubernete return_value=TASK_MANAGER_POD_LIST, ) def test_driver_logging_failure( - self, mock_namespaced_pod_list, mock_pod_logs, error_log_call, mock_namespaced_crd, mock_kube_conn + self, mock_namespaced_pod_list, mock_pod_logs, mock_namespaced_crd, mock_kube_conn, caplog ): sensor = FlinkKubernetesSensor( application_name="flink-stream-example", @@ -1093,7 +1093,7 @@ def test_driver_logging_failure( namespace="default", watch=False, label_selector="component=taskmanager,app=flink-stream-example" ) mock_pod_logs.assert_called_once_with("basic-example-taskmanager-1-1", namespace="default") - error_log_call.assert_called_once_with(TEST_POD_LOG_RESULT) + assert TEST_POD_LOG_RESULT in caplog.messages mock_namespaced_crd.assert_called_once_with( group="flink.apache.org", version="v1beta1", @@ -1106,7 +1106,6 @@ def test_driver_logging_failure( "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_READY_CLUSTER, ) - @patch("logging.Logger.info") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", return_value=TEST_POD_LOGS, @@ -1116,7 +1115,7 @@ def test_driver_logging_failure( return_value=TASK_MANAGER_POD_LIST, ) def test_driver_logging_completed( - self, mock_namespaced_pod_list, mock_pod_logs, info_log_call, mock_namespaced_crd, mock_kube_conn + self, mock_namespaced_pod_list, mock_pod_logs, mock_namespaced_crd, mock_kube_conn, caplog ): sensor = FlinkKubernetesSensor( application_name="flink-stream-example", @@ -1130,7 +1129,7 @@ def test_driver_logging_completed( namespace="default", watch=False, label_selector="component=taskmanager,app=flink-stream-example" ) mock_pod_logs.assert_called_once_with("basic-example-taskmanager-1-1", namespace="default") - assert call(TEST_POD_LOG_RESULT) in info_log_call.mock_calls + assert TEST_POD_LOG_RESULT in caplog.messages mock_namespaced_crd.assert_called_once_with( group="flink.apache.org", @@ -1144,7 +1143,6 @@ def test_driver_logging_completed( "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_READY_CLUSTER, ) - @patch("logging.Logger.info") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", return_value=TEST_POD_LOGS, @@ -1154,7 +1152,7 @@ def test_driver_logging_completed( return_value=TASK_MANAGER_POD_LIST, ) def test_logging_taskmanager_from_taskmanager_namespace_when_namespace_is_set( - self, mock_namespaced_pod_list, mock_pod_logs, info_log_call, mock_namespaced_crd, mock_kube_conn + self, mock_namespaced_pod_list, mock_pod_logs, mock_namespaced_crd, mock_kube_conn ): namespace = "different-namespace123456" namespae_name = "test123" @@ -1190,7 +1188,7 @@ def test_logging_taskmanager_from_taskmanager_namespace_when_namespace_is_set( return_value=TASK_MANAGER_POD_LIST, ) def test_logging_taskmanager_from_non_default_namespace( - self, mock_namespaced_pod_list, mock_pod_logs, info_log_call, mock_namespaced_crd, mock_kube_conn + self, mock_namespaced_pod_list, mock_pod_logs, mock_namespaced_crd, mock_kube_conn, caplog ): namespae_name = "test123" @@ -1214,7 +1212,6 @@ def test_logging_taskmanager_from_non_default_namespace( "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_READY_CLUSTER, ) - @patch("logging.Logger.warning") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", side_effect=ApiException("Test api exception"), @@ -1224,7 +1221,7 @@ def test_logging_taskmanager_from_non_default_namespace( return_value=TASK_MANAGER_POD_LIST, ) def test_driver_logging_error( - self, mock_namespaced_pod_list, mock_pod_logs, warn_log_call, mock_namespaced_crd, mock_kube_conn + self, mock_namespaced_pod_list, mock_pod_logs, mock_namespaced_crd, mock_kube_conn, caplog ): sensor = FlinkKubernetesSensor( application_name="flink-stream-example", @@ -1233,13 +1230,12 @@ def test_driver_logging_error( task_id="test_task_id", ) sensor.poke(None) - warn_log_call.assert_called_once() + assert (ANY, logging.WARNING, ANY) in caplog.record_tuples, "Expected something logged at warning" @patch( "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_ERROR_CLUSTER, ) - @patch("logging.Logger.warning") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", side_effect=ApiException("Test api exception"), @@ -1249,7 +1245,7 @@ def test_driver_logging_error( return_value=TASK_MANAGER_POD_LIST, ) def test_driver_logging_error_missing_state( - self, mock_namespaced_pod_list, mock_pod_logs, warn_log_call, mock_namespaced_crd, mock_kube_conn + self, mock_namespaced_pod_list, mock_pod_logs, mock_namespaced_crd, mock_kube_conn, caplog ): sensor = FlinkKubernetesSensor( application_name="flink-stream-example", @@ -1259,4 +1255,4 @@ def test_driver_logging_error_missing_state( ) with pytest.raises(AirflowException): sensor.poke(None) - warn_log_call.assert_called_once() + assert (ANY, logging.WARNING, ANY) in caplog.record_tuples, "Expected something logged at warning" diff --git a/providers/apache/kafka/tests/integration/apache/kafka/operators/test_consume.py b/providers/apache/kafka/tests/integration/apache/kafka/operators/test_consume.py index ddca5fc502e17..aefcee1d753e1 100644 --- a/providers/apache/kafka/tests/integration/apache/kafka/operators/test_consume.py +++ b/providers/apache/kafka/tests/integration/apache/kafka/operators/test_consume.py @@ -25,10 +25,9 @@ from confluent_kafka import Producer # Import Operator +from airflow.models.connection import Connection from airflow.providers.apache.kafka.operators.consume import ConsumeFromTopicOperator -from tests_common.test_utils.config import conf_vars - log = logging.getLogger(__name__) @@ -49,23 +48,29 @@ def _basic_message_tester(message, test=None) -> Any: assert message.value().decode(encoding="utf-8") == test +@pytest.fixture(autouse=True) +def kafka_consumer_connections(create_connection_without_db): + """Create Kafka consumer connections for testing purpose.""" + connections = [ + Connection( + conn_id="operator.consumer.test.integration.test_1", + uri="kafka://broker:29092?socket.timeout.ms=10&bootstrap.servers=broker:29092&group.id=operator.consumer.test.integration.test_1&enable.auto.commit=False&auto.offset.reset=beginning", + ), + Connection( + conn_id="operator.consumer.test.integration.test_2", + uri="kafka://broker:29092?socket.timeout.ms=10&bootstrap.servers=broker:29092&group.id=operator.consumer.test.integration.test_2&enable.auto.commit=False&auto.offset.reset=beginning", + ), + Connection( + conn_id="operator.consumer.test.integration.test_3", + uri="kafka://broker:29092?socket.timeout.ms=10&bootstrap.servers=broker:29092&group.id=operator.consumer.test.integration.test_3&enable.auto.commit=False&auto.offset.reset=beginning", + ), + ] + + for conn in connections: + create_connection_without_db(conn) + + @pytest.mark.integration("kafka") -@conf_vars( - { - ( - "connections", - "operator.consumer.test.integration.test_1", - ): "kafka://broker:29092?socket.timeout.ms=10&bootstrap.servers=broker:29092&group.id=operator.consumer.test.integration.test_1&enable.auto.commit=False&auto.offset.reset=beginning", - ( - "connections", - "operator.consumer.test.integration.test_2", - ): "kafka://broker:29092?socket.timeout.ms=10&bootstrap.servers=broker:29092&group.id=operator.consumer.test.integration.test_2&enable.auto.commit=False&auto.offset.reset=beginning", - ( - "connections", - "operator.consumer.test.integration.test_3", - ): "kafka://broker:29092?socket.timeout.ms=10&bootstrap.servers=broker:29092&group.id=operator.consumer.test.integration.test_3&enable.auto.commit=False&auto.offset.reset=beginning", - } -) class TestConsumeFromTopic: """ test ConsumeFromTopicOperator diff --git a/providers/apache/kafka/tests/integration/apache/kafka/operators/test_produce.py b/providers/apache/kafka/tests/integration/apache/kafka/operators/test_produce.py index ada93900ce67d..d7a5167916dec 100644 --- a/providers/apache/kafka/tests/integration/apache/kafka/operators/test_produce.py +++ b/providers/apache/kafka/tests/integration/apache/kafka/operators/test_produce.py @@ -22,10 +22,9 @@ import pytest from confluent_kafka import Consumer +from airflow.models.connection import Connection from airflow.providers.apache.kafka.operators.produce import ProduceToTopicOperator -from tests_common.test_utils.config import conf_vars - log = logging.getLogger(__name__) @@ -34,19 +33,25 @@ def _producer_function(): yield (json.dumps(i), json.dumps(i + 1)) +@pytest.fixture(autouse=True) +def kafka_connections(create_connection_without_db): + """Create Kafka producer connections for testing purpose.""" + connections = [ + Connection( + conn_id="kafka_default_test_1", + uri="kafka://broker:29092?socket.timeout.ms=10&message.timeout.ms=10&group.id=operator.producer.test.integration.test_1", + ), + Connection( + conn_id="kafka_default_test_2", + uri="kafka://broker:29092?socket.timeout.ms=10&message.timeout.ms=10&group.id=operator.producer.test.integration.test_2", + ), + ] + + for conn in connections: + create_connection_without_db(conn) + + @pytest.mark.integration("kafka") -@conf_vars( - { - ( - "connections", - "kafka_default_test_1", - ): "kafka://broker:29092?socket.timeout.ms=10&message.timeout.ms=10&group.id=operator.producer.test.integration.test_1", - ( - "connections", - "kafka_default_test_2", - ): "kafka://broker:29092?socket.timeout.ms=10&message.timeout.ms=10&group.id=operator.producer.test.integration.test_2", - } -) class TestProduceToTopic: """ test ProduceToTopicOperator diff --git a/providers/celery/tests/unit/celery/cli/test_celery_command.py b/providers/celery/tests/unit/celery/cli/test_celery_command.py index 41f74c9c4a687..94e339804e3cc 100644 --- a/providers/celery/tests/unit/celery/cli/test_celery_command.py +++ b/providers/celery/tests/unit/celery/cli/test_celery_command.py @@ -37,8 +37,14 @@ from tests_common.test_utils.version_compat import AIRFLOW_V_3_0_PLUS +@pytest.fixture(autouse=False) +def conf_stale_bundle_cleanup_disabled(): + with conf_vars({("dag_processor", "stale_bundle_cleanup_interval"): "0"}): + yield + + @pytest.mark.backend("mysql", "postgres") -@conf_vars({("dag_processor", "stale_bundle_cleanup_interval"): 0}) +@pytest.mark.usefixtures("conf_stale_bundle_cleanup_disabled") class TestCeleryStopCommand: @classmethod def setup_class(cls): @@ -120,7 +126,7 @@ def test_custom_pid_file_is_used_in_start_and_stop( @pytest.mark.backend("mysql", "postgres") -@conf_vars({("dag_processor", "stale_bundle_cleanup_interval"): 0}) +@pytest.mark.usefixtures("conf_stale_bundle_cleanup_disabled") class TestWorkerStart: @classmethod def setup_class(cls): @@ -181,7 +187,7 @@ def test_worker_started_with_required_arguments(self, mock_celery_app, mock_pope @pytest.mark.backend("mysql", "postgres") -@conf_vars({("dag_processor", "stale_bundle_cleanup_interval"): 0}) +@pytest.mark.usefixtures("conf_stale_bundle_cleanup_disabled") class TestWorkerFailure: @classmethod def setup_class(cls): @@ -201,7 +207,7 @@ def test_worker_failure_gracefull_shutdown(self, mock_celery_app, mock_popen): @pytest.mark.backend("mysql", "postgres") -@conf_vars({("dag_processor", "stale_bundle_cleanup_interval"): 0}) +@pytest.mark.usefixtures("conf_stale_bundle_cleanup_disabled") class TestFlowerCommand: @classmethod def setup_class(cls): diff --git a/providers/celery/tests/unit/celery/log_handlers/test_log_handlers.py b/providers/celery/tests/unit/celery/log_handlers/test_log_handlers.py index c95ab43236ecf..6a0ef98842ff2 100644 --- a/providers/celery/tests/unit/celery/log_handlers/test_log_handlers.py +++ b/providers/celery/tests/unit/celery/log_handlers/test_log_handlers.py @@ -24,7 +24,6 @@ import pytest -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.executors import executor_loader from airflow.models.dagrun import DagRun from airflow.models.taskinstance import TaskInstance @@ -56,7 +55,6 @@ def clean_up(self): session.query(TaskInstance).delete() def setup_method(self): - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) logging.root.disabled = False self.clean_up() # We use file task handler by default. diff --git a/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/log_handlers/test_log_handlers.py b/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/log_handlers/test_log_handlers.py index 954ec3ed80645..7cddf3d04af97 100644 --- a/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/log_handlers/test_log_handlers.py +++ b/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/log_handlers/test_log_handlers.py @@ -27,13 +27,13 @@ import pytest from kubernetes.client import models as k8s -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.executors import executor_loader from airflow.models.dag import DAG from airflow.models.taskinstance import TaskInstance from airflow.utils.log.file_task_handler import ( FileTaskHandler, ) +from airflow.utils.log.log_reader import TaskLogReader from airflow.utils.log.logging_mixin import set_context from airflow.utils.state import State, TaskInstanceState from airflow.utils.types import DagRunType @@ -66,7 +66,6 @@ def clean_up(self): clear_db_dag_bundles() def setup_method(self): - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) logging.root.disabled = False self.clean_up() # We use file task handler by default. @@ -156,7 +155,7 @@ def task_callable(ti): logger = ti.log ti.task.log.disabled = False - file_handler = next((h for h in logger.handlers if h.name == FILE_TASK_HANDLER), None) + file_handler = TaskLogReader().log_handler set_context(logger, ti) ti.run(ignore_ti_state=True) ti.state = TaskInstanceState.RUNNING diff --git a/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/sensors/test_spark_kubernetes.py b/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/sensors/test_spark_kubernetes.py index 16d89033607f6..00528660228e2 100644 --- a/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/sensors/test_spark_kubernetes.py +++ b/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/sensors/test_spark_kubernetes.py @@ -18,7 +18,8 @@ from __future__ import annotations import json -from unittest.mock import call, patch +import logging +from unittest.mock import ANY, patch import pytest from kubernetes.client.rest import ApiException @@ -794,7 +795,6 @@ def test_namespace_from_connection(self, mock_get_namespaced_crd, mock_kubernete "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_FAILED_APPLICATION, ) - @patch("logging.Logger.error") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", return_value=TEST_POD_LOGS, @@ -802,9 +802,9 @@ def test_namespace_from_connection(self, mock_get_namespaced_crd, mock_kubernete def test_driver_logging_failure( self, mock_log_call, - error_log_call, mock_get_namespaced_crd, mock_kube_conn, + caplog, ): sensor = SparkKubernetesSensor( application_name="spark_pi", @@ -817,20 +817,17 @@ def test_driver_logging_failure( mock_log_call.assert_called_once_with( "spark-pi-driver", namespace="default", container="spark-kubernetes-driver" ) - error_log_call.assert_called_once_with(TEST_POD_LOG_RESULT) + assert (ANY, logging.ERROR, TEST_POD_LOG_RESULT) in caplog.record_tuples @patch( "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_COMPLETED_APPLICATION, ) - @patch("logging.Logger.info") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", return_value=TEST_POD_LOGS, ) - def test_driver_logging_completed( - self, mock_log_call, info_log_call, mock_get_namespaced_crd, mock_kube_conn - ): + def test_driver_logging_completed(self, mock_log_call, mock_get_namespaced_crd, mock_kube_conn, caplog): sensor = SparkKubernetesSensor( application_name="spark_pi", attach_log=True, @@ -841,20 +838,17 @@ def test_driver_logging_completed( mock_log_call.assert_called_once_with( "spark-pi-2020-02-24-1-driver", namespace="default", container="spark-kubernetes-driver" ) - assert call(TEST_POD_LOG_RESULT) in info_log_call.mock_calls + assert (ANY, logging.INFO, TEST_POD_LOG_RESULT) in caplog.record_tuples @patch( "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_COMPLETED_APPLICATION, ) - @patch("logging.Logger.warning") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", side_effect=ApiException("Test api exception"), ) - def test_driver_logging_error( - self, mock_log_call, warn_log_call, mock_get_namespaced_crd, mock_kube_conn - ): + def test_driver_logging_error(self, mock_log_call, mock_get_namespaced_crd, mock_kube_conn, caplog): sensor = SparkKubernetesSensor( application_name="spark_pi", attach_log=True, @@ -862,19 +856,18 @@ def test_driver_logging_error( task_id="test_task_id", ) sensor.poke({}) - warn_log_call.assert_called_once() + assert (ANY, logging.WARNING, ANY) in caplog.record_tuples, "Expected something logged at warning" @patch( "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object", return_value=TEST_DRIVER_WITH_SIDECAR_APPLICATION, ) - @patch("logging.Logger.info") @patch( "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs", return_value=TEST_POD_LOGS, ) def test_sidecar_driver_logging_completed( - self, mock_log_call, info_log_call, mock_get_namespaced_crd, mock_kube_conn + self, mock_log_call, mock_get_namespaced_crd, mock_kube_conn, caplog ): sensor = SparkKubernetesSensor( application_name="spark_pi", @@ -886,4 +879,4 @@ def test_sidecar_driver_logging_completed( mock_log_call.assert_called_once_with( "spark-pi-2020-02-24-1-driver", namespace="default", container="spark-kubernetes-driver" ) - assert call(TEST_POD_LOG_RESULT) in info_log_call.mock_calls + assert (ANY, logging.INFO, TEST_POD_LOG_RESULT) in caplog.record_tuples diff --git a/providers/common/compat/provider.yaml b/providers/common/compat/provider.yaml index d290542b0aade..43899fd8cba93 100644 --- a/providers/common/compat/provider.yaml +++ b/providers/common/compat/provider.yaml @@ -28,6 +28,7 @@ source-date-epoch: 1753690102 # In such case adding >= NEW_VERSION and bumping to NEW_VERSION in a provider have # to be done in the same PR versions: + - 1.7.4 - 1.7.3 - 1.7.2 - 1.7.1 diff --git a/providers/common/compat/pyproject.toml b/providers/common/compat/pyproject.toml index eadf633a8cb16..f5e9b26ee20ec 100644 --- a/providers/common/compat/pyproject.toml +++ b/providers/common/compat/pyproject.toml @@ -25,7 +25,7 @@ build-backend = "flit_core.buildapi" [project] name = "apache-airflow-providers-common-compat" -version = "1.7.3" +version = "1.7.4" description = "Provider package apache-airflow-providers-common-compat for Apache Airflow" readme = "README.rst" authors = [ @@ -106,8 +106,8 @@ apache-airflow-providers-common-sql = {workspace = true} apache-airflow-providers-standard = {workspace = true} [project.urls] -"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-common-compat/1.7.3" -"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-common-compat/1.7.3/changelog.html" +"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-common-compat/1.7.4" +"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-common-compat/1.7.4/changelog.html" "Bug Tracker" = "https://github.com/apache/airflow/issues" "Source Code" = "https://github.com/apache/airflow" "Slack Chat" = "https://s.apache.org/airflow-slack" diff --git a/providers/common/compat/src/airflow/providers/common/compat/__init__.py b/providers/common/compat/src/airflow/providers/common/compat/__init__.py index 2068fff6f2f98..4395c37bb052b 100644 --- a/providers/common/compat/src/airflow/providers/common/compat/__init__.py +++ b/providers/common/compat/src/airflow/providers/common/compat/__init__.py @@ -29,7 +29,7 @@ __all__ = ["__version__"] -__version__ = "1.7.3" +__version__ = "1.7.4" if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse( "2.10.0" diff --git a/providers/common/io/provider.yaml b/providers/common/io/provider.yaml index ef0c9a5ee25be..ac93f241e7926 100644 --- a/providers/common/io/provider.yaml +++ b/providers/common/io/provider.yaml @@ -28,6 +28,7 @@ source-date-epoch: 1753690124 # In such case adding >= NEW_VERSION and bumping to NEW_VERSION in a provider have # to be done in the same PR versions: + - 1.6.3 - 1.6.2 - 1.6.1 - 1.6.0 diff --git a/providers/common/io/pyproject.toml b/providers/common/io/pyproject.toml index eb3d198c655e5..b30e00f1df8a9 100644 --- a/providers/common/io/pyproject.toml +++ b/providers/common/io/pyproject.toml @@ -25,7 +25,7 @@ build-backend = "flit_core.buildapi" [project] name = "apache-airflow-providers-common-io" -version = "1.6.2" +version = "1.6.3" description = "Provider package apache-airflow-providers-common-io for Apache Airflow" readme = "README.rst" authors = [ @@ -106,8 +106,8 @@ apache-airflow-providers-common-sql = {workspace = true} apache-airflow-providers-standard = {workspace = true} [project.urls] -"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-common-io/1.6.2" -"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-common-io/1.6.2/changelog.html" +"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-common-io/1.6.3" +"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-common-io/1.6.3/changelog.html" "Bug Tracker" = "https://github.com/apache/airflow/issues" "Source Code" = "https://github.com/apache/airflow" "Slack Chat" = "https://s.apache.org/airflow-slack" diff --git a/providers/common/io/src/airflow/providers/common/io/__init__.py b/providers/common/io/src/airflow/providers/common/io/__init__.py index 953ca8b415998..915c74120d953 100644 --- a/providers/common/io/src/airflow/providers/common/io/__init__.py +++ b/providers/common/io/src/airflow/providers/common/io/__init__.py @@ -29,7 +29,7 @@ __all__ = ["__version__"] -__version__ = "1.6.2" +__version__ = "1.6.3" if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse( "2.10.0" diff --git a/providers/common/sql/provider.yaml b/providers/common/sql/provider.yaml index 31e82b8d2163b..becc72b27989b 100644 --- a/providers/common/sql/provider.yaml +++ b/providers/common/sql/provider.yaml @@ -28,6 +28,7 @@ source-date-epoch: 1756876759 # In such case adding >= NEW_VERSION and bumping to NEW_VERSION in a provider have # to be done in the same PR versions: + - 1.28.1 - 1.28.0 - 1.27.5 - 1.27.4 diff --git a/providers/common/sql/pyproject.toml b/providers/common/sql/pyproject.toml index cc1aaf226cd60..fc1b640a048a3 100644 --- a/providers/common/sql/pyproject.toml +++ b/providers/common/sql/pyproject.toml @@ -25,7 +25,7 @@ build-backend = "flit_core.buildapi" [project] name = "apache-airflow-providers-common-sql" -version = "1.28.0" +version = "1.28.1" description = "Provider package apache-airflow-providers-common-sql for Apache Airflow" readme = "README.rst" authors = [ @@ -121,8 +121,8 @@ apache-airflow-providers-common-sql = {workspace = true} apache-airflow-providers-standard = {workspace = true} [project.urls] -"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.28.0" -"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.28.0/changelog.html" +"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.28.1" +"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.28.1/changelog.html" "Bug Tracker" = "https://github.com/apache/airflow/issues" "Source Code" = "https://github.com/apache/airflow" "Slack Chat" = "https://s.apache.org/airflow-slack" diff --git a/providers/common/sql/src/airflow/providers/common/sql/__init__.py b/providers/common/sql/src/airflow/providers/common/sql/__init__.py index cd1b26f985a56..610cd54821576 100644 --- a/providers/common/sql/src/airflow/providers/common/sql/__init__.py +++ b/providers/common/sql/src/airflow/providers/common/sql/__init__.py @@ -29,7 +29,7 @@ __all__ = ["__version__"] -__version__ = "1.28.0" +__version__ = "1.28.1" if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse( "2.10.0" diff --git a/providers/common/sql/tests/unit/common/sql/hooks/test_dbapi.py b/providers/common/sql/tests/unit/common/sql/hooks/test_dbapi.py index 69c3147a40e19..b3fb7a476f032 100644 --- a/providers/common/sql/tests/unit/common/sql/hooks/test_dbapi.py +++ b/providers/common/sql/tests/unit/common/sql/hooks/test_dbapi.py @@ -25,7 +25,6 @@ import pytest from pyodbc import Cursor -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.models import Connection from airflow.providers.common.sql.dialects.dialect import Dialect from airflow.providers.common.sql.hooks.handlers import fetch_all_handler, fetch_one_handler @@ -71,14 +70,13 @@ def dialect(self): def get_db_log_messages(self, conn) -> None: return conn.get_messages() - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) logging.root.disabled = True self.db_hook = DbApiHookMock(**kwargs) self.db_hook_no_log_sql = DbApiHookMock(log_sql=False) self.db_hook_schema_override = DbApiHookMock(schema="schema-override") self.db_hook.supports_executemany = False - self.db_hook.log.setLevel(logging.DEBUG) + # self.db_hook.log.setLevel(logging.DEBUG) def test_get_records(self): statement = "SQL" @@ -228,7 +226,7 @@ def test_insert_rows_as_generator(self, caplog): table = "table" rows = [("What's",), ("up",), ("world",)] - with caplog.at_level(logging.DEBUG): + with caplog.at_level(logging.DEBUG, logger="airflow.task"): self.db_hook.insert_rows(table, iter(rows)) assert self.conn.close.call_count == 1 @@ -249,7 +247,7 @@ def test_insert_rows_as_generator_supports_executemany(self, caplog): table = "table" rows = [("What's",), ("up",), ("world",)] - with caplog.at_level(logging.DEBUG): + with caplog.at_level(logging.DEBUG, "airflow.task"): self.db_hook.supports_executemany = True self.db_hook.insert_rows(table, iter(rows)) diff --git a/providers/common/sql/tests/unit/common/sql/hooks/test_sql.py b/providers/common/sql/tests/unit/common/sql/hooks/test_sql.py index e881f52f69c45..b900310324447 100644 --- a/providers/common/sql/tests/unit/common/sql/hooks/test_sql.py +++ b/providers/common/sql/tests/unit/common/sql/hooks/test_sql.py @@ -27,7 +27,6 @@ import polars as pl import pytest -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.exceptions import AirflowProviderDeprecationWarning from airflow.models import Connection from airflow.providers.common.sql.dialects.dialect import Dialect @@ -227,7 +226,6 @@ def mock_execute(*args, **kwargs): class TestDbApiHook: def setup_method(self, **kwargs): - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) logging.root.disabled = True @pytest.mark.db_test diff --git a/providers/databricks/src/airflow/providers/databricks/operators/databricks.py b/providers/databricks/src/airflow/providers/databricks/operators/databricks.py index f1c8a411962a9..2c1607bb53df0 100644 --- a/providers/databricks/src/airflow/providers/databricks/operators/databricks.py +++ b/providers/databricks/src/airflow/providers/databricks/operators/databricks.py @@ -24,7 +24,6 @@ from abc import ABC, abstractmethod from collections.abc import Sequence from functools import cached_property -from logging import Logger from typing import TYPE_CHECKING, Any from airflow.configuration import conf @@ -60,12 +59,8 @@ DatabricksWorkflowTaskGroup, ) from airflow.providers.openlineage.extractors import OperatorLineage - from airflow.utils.context import Context - - try: - from airflow.sdk import TaskGroup - except ImportError: - from airflow.utils.task_group import TaskGroup # type: ignore[no-redef] + from airflow.sdk import TaskGroup + from airflow.sdk.types import Context, Logger if AIRFLOW_V_3_0_PLUS: from airflow.sdk import BaseOperatorLink diff --git a/providers/databricks/src/airflow/providers/databricks/plugins/databricks_workflow.py b/providers/databricks/src/airflow/providers/databricks/plugins/databricks_workflow.py index 9624cb685fd53..3fd7bfb0dafb9 100644 --- a/providers/databricks/src/airflow/providers/databricks/plugins/databricks_workflow.py +++ b/providers/databricks/src/airflow/providers/databricks/plugins/databricks_workflow.py @@ -17,7 +17,6 @@ from __future__ import annotations -import logging import os from typing import TYPE_CHECKING, Any from urllib.parse import unquote @@ -45,6 +44,7 @@ from airflow.models import BaseOperator from airflow.providers.databricks.operators.databricks import DatabricksTaskBaseOperator + from airflow.sdk.types import Logger from airflow.utils.context import Context @@ -62,7 +62,7 @@ def get_auth_decorator(): def get_databricks_task_ids( - group_id: str, task_map: dict[str, DatabricksTaskBaseOperator], log: logging.Logger + group_id: str, task_map: dict[str, DatabricksTaskBaseOperator], log: Logger ) -> list[str]: """ Return a list of all Databricks task IDs for a dictionary of Airflow tasks. @@ -112,7 +112,7 @@ def _get_dagrun(dag, run_id: str, session: Session) -> DagRun: @provide_session def _clear_task_instances( - dag_id: str, run_id: str, task_ids: list[str], log: logging.Logger, session: Session = NEW_SESSION + dag_id: str, run_id: str, task_ids: list[str], log: Logger, session: Session = NEW_SESSION ) -> None: dag = _get_dag(dag_id, session=session) log.debug("task_ids %s to clear", str(task_ids)) @@ -145,7 +145,7 @@ def _repair_task( databricks_conn_id: str, databricks_run_id: int, tasks_to_repair: list[str], - logger: logging.Logger, + logger: Logger, ) -> int: """ Repair a Databricks task using the Databricks API. @@ -294,7 +294,7 @@ def _get_link_legacy( def store_databricks_job_run_link( context: Context, metadata: Any, - logger: logging.Logger, + logger: Logger, ) -> None: """ Store the Databricks job run link in XCom during task execution. @@ -368,7 +368,7 @@ def get_task_group_children(cls, task_group: TaskGroup) -> dict[str, BaseOperato children[child_id] = child return children - def get_tasks_to_run(self, ti_key: TaskInstanceKey, operator: BaseOperator, log: logging.Logger) -> str: + def get_tasks_to_run(self, ti_key: TaskInstanceKey, operator: BaseOperator, log: Logger) -> str: task_group = operator.task_group if not task_group: raise AirflowException("Task group is required for generating repair link.") diff --git a/providers/databricks/tests/unit/databricks/hooks/test_databricks.py b/providers/databricks/tests/unit/databricks/hooks/test_databricks.py index 1564c6dbfbc0f..fb57aacf83596 100644 --- a/providers/databricks/tests/unit/databricks/hooks/test_databricks.py +++ b/providers/databricks/tests/unit/databricks/hooks/test_databricks.py @@ -1449,7 +1449,6 @@ async def test_async_do_api_call_respects_schema(self, mock_get): @pytest.mark.asyncio @mock.patch("airflow.providers.databricks.hooks.databricks_base.aiohttp.ClientSession.get") async def test_async_do_api_call_only_existing_response_properties_are_read(self, mock_get): - self.hook.log.setLevel("DEBUG") response = mock_get.return_value.__aenter__.return_value response.mock_add_spec(aiohttp.ClientResponse, spec_set=True) response.json = AsyncMock(return_value={"bar": "baz"}) diff --git a/providers/docker/src/airflow/providers/docker/operators/docker.py b/providers/docker/src/airflow/providers/docker/operators/docker.py index bf6f7a463fad6..dc8065d79cc6d 100644 --- a/providers/docker/src/airflow/providers/docker/operators/docker.py +++ b/providers/docker/src/airflow/providers/docker/operators/docker.py @@ -42,16 +42,11 @@ from airflow.providers.docker.version_compat import BaseOperator if TYPE_CHECKING: - from logging import Logger - from docker import APIClient from docker.types import DeviceRequest - try: - from airflow.sdk.definitions.context import Context - except ImportError: - # TODO: Remove once provider drops support for Airflow 2 - from airflow.utils.context import Context + from airflow.sdk.definitions.context import Context + from airflow.sdk.types import Logger def stringify(line: str | bytes): diff --git a/providers/docker/tests/unit/docker/decorators/test_docker.py b/providers/docker/tests/unit/docker/decorators/test_docker.py index 56818438cbcde..33b026bd449d6 100644 --- a/providers/docker/tests/unit/docker/decorators/test_docker.py +++ b/providers/docker/tests/unit/docker/decorators/test_docker.py @@ -16,9 +16,7 @@ # under the License. from __future__ import annotations -import logging from importlib.util import find_spec -from io import StringIO as StringBuffer import pytest @@ -339,7 +337,7 @@ def f(): assert ret.operator.docker_url == "unix://var/run/docker.sock" @pytest.mark.db_test - def test_failing_task(self, dag_maker, session): + def test_failing_task(self, dag_maker, session, caplog): """Test regression #39319 Check the log content of the DockerOperator when the task fails. @@ -349,12 +347,6 @@ def test_failing_task(self, dag_maker, session): def f(): raise ValueError("This task is expected to fail") - docker_operator_logger_name = "airflow.task.operators" - - docker_operator_logger = logging.getLogger(docker_operator_logger_name) - log_capture_string = StringBuffer() - ch = logging.StreamHandler(log_capture_string) - docker_operator_logger.addHandler(ch) with dag_maker(session=session): f() @@ -366,10 +358,8 @@ def f(): ti = dr.get_task_instances(session=session)[0] assert ti.state == TaskInstanceState.FAILED - log_content = str(log_capture_string.getvalue()) - assert 'with open(sys.argv[4], "w") as file:' not in log_content - last_line_of_docker_operator_log = log_content.splitlines()[-1] - assert "ValueError: This task is expected to fail" in last_line_of_docker_operator_log + assert 'with open(sys.argv[4], "w") as file:' not in caplog.text + assert "ValueError: This task is expected to fail" in caplog.messages @pytest.mark.db_test def test_invalid_serializer(self, dag_maker): diff --git a/providers/edge3/src/airflow/providers/edge3/openapi/v2-edge-generated.yaml b/providers/edge3/src/airflow/providers/edge3/openapi/v2-edge-generated.yaml index 4619fc222354e..26e646dcb9ba7 100644 --- a/providers/edge3/src/airflow/providers/edge3/openapi/v2-edge-generated.yaml +++ b/providers/edge3/src/airflow/providers/edge3/openapi/v2-edge-generated.yaml @@ -142,9 +142,7 @@ paths: description: Successful Response content: application/json: - schema: - type: 'null' - title: Response State + schema: {} '400': content: application/json: @@ -319,9 +317,7 @@ paths: description: Successful Response content: application/json: - schema: - type: 'null' - title: Response Push Logs + schema: {} '400': content: application/json: @@ -514,9 +510,7 @@ paths: description: Successful Response content: application/json: - schema: - type: 'null' - title: Response Update Queues + schema: {} '400': content: application/json: @@ -614,9 +608,7 @@ paths: description: Successful Response content: application/json: - schema: - type: 'null' - title: Response Request Worker Maintenance + schema: {} '422': description: Validation Error content: @@ -644,9 +636,7 @@ paths: description: Successful Response content: application/json: - schema: - type: 'null' - title: Response Exit Worker Maintenance + schema: {} '422': description: Validation Error content: diff --git a/providers/edge3/src/airflow/providers/edge3/plugins/www/dist/main.umd.cjs b/providers/edge3/src/airflow/providers/edge3/plugins/www/dist/main.umd.cjs index 766376f7f11a8..345b03be6246a 100644 --- a/providers/edge3/src/airflow/providers/edge3/plugins/www/dist/main.umd.cjs +++ b/providers/edge3/src/airflow/providers/edge3/plugins/www/dist/main.umd.cjs @@ -1,4 +1,4 @@ -(function(E,te){typeof exports=="object"&&typeof module<"u"?module.exports=te(require("react"),require("react-dom")):typeof define=="function"&&define.amd?define(["react","react-dom"],te):(E=typeof globalThis<"u"?globalThis:E||self,E.AirflowPlugin=te(E.React,E.ReactDOM))})(this,function(E,te){"use strict";var YA=Object.defineProperty;var hb=E=>{throw TypeError(E)};var QA=(E,te,ve)=>te in E?YA(E,te,{enumerable:!0,configurable:!0,writable:!0,value:ve}):E[te]=ve;var Je=(E,te,ve)=>QA(E,typeof te!="symbol"?te+"":te,ve),pc=(E,te,ve)=>te.has(E)||hb("Cannot "+ve);var b=(E,te,ve)=>(pc(E,te,"read from private field"),ve?ve.call(E):te.get(E)),W=(E,te,ve)=>te.has(E)?hb("Cannot add the same private member more than once"):te instanceof WeakSet?te.add(E):te.set(E,ve),M=(E,te,ve,O)=>(pc(E,te,"write to private field"),O?O.call(E,ve):te.set(E,ve),ve),J=(E,te,ve)=>(pc(E,te,"access private method"),ve);var Bs=(E,te,ve,O)=>({set _(Gs){M(E,te,Gs,ve)},get _(){return b(E,te,O)}});var hm,fm,gm,pm,mm,vm,bm,ym,xm,Cm,Sm,wm,Em,km,Om,Im,Pm,Rm,Tm,Nm,Am,_m,Vm,Fm,Lm,Dm,zm,Mm,$m,Bm,jm,Wm,Hm,Um,Gm,qm,Km,Xm,Ym,Qm,Jm,Zm,ev,tv,nv,rv,iv,ov,sv,av,lv,cv,uv,dv,hv,fv,gv,pv,mv,vv,bv,yv,xv,fn,hc,Cv,Yn,gn,Dr,Sv,zr,pn,Mr,wv,Qn,Ev,Jn,$r,ft,Zn,Ae,zi,er,Ct,Xt,kv,Ye,ee,Mi,Be,tr,Br,Ht,mn,$i,jr,Wr,nr,rr,vn,Hr,oe,Wi,mc,vc,bc,yc,xc,Cc,Sc,pb,Ov,Ft,je,ir,Lt,En,Iv,Ut,St,Bi,Pv,bn,yn,Qe,Gt,qt,Us,wc,Rv,Dt,Tv,me,xn,Cn,Ur,Gr,Sn,qr,Kr,Nv,Av,_v,Vv,Fv,Lv,Dv,zv,Mv,$v,Bv,jv,Wv,Hv,Uv,Gv,qv,Kv,Xv,Yv,Qv,Jv,Zv,eb,tb,nb,rb,ib,ob,sb,ab;function ve(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const O=ve(E);function Gs(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Ec={exports:{}},Hi={};/** +(function(E,te){typeof exports=="object"&&typeof module<"u"?module.exports=te(require("react"),require("react-dom")):typeof define=="function"&&define.amd?define(["react","react-dom"],te):(E=typeof globalThis<"u"?globalThis:E||self,E.AirflowPlugin=te(E.React,E.ReactDOM))})(this,function(E,te){"use strict";var JA=Object.defineProperty;var gb=E=>{throw TypeError(E)};var ZA=(E,te,ve)=>te in E?JA(E,te,{enumerable:!0,configurable:!0,writable:!0,value:ve}):E[te]=ve;var Je=(E,te,ve)=>ZA(E,typeof te!="symbol"?te+"":te,ve),pc=(E,te,ve)=>te.has(E)||gb("Cannot "+ve);var v=(E,te,ve)=>(pc(E,te,"read from private field"),ve?ve.call(E):te.get(E)),H=(E,te,ve)=>te.has(E)?gb("Cannot add the same private member more than once"):te instanceof WeakSet?te.add(E):te.set(E,ve),$=(E,te,ve,O)=>(pc(E,te,"write to private field"),O?O.call(E,ve):te.set(E,ve),ve),J=(E,te,ve)=>(pc(E,te,"access private method"),ve);var js=(E,te,ve,O)=>({set _(qs){$(E,te,qs,ve)},get _(){return v(E,te,O)}});var gm,pm,mm,vm,bm,ym,xm,Cm,Sm,wm,Em,km,Om,Im,Pm,Rm,Tm,Nm,Am,_m,Vm,Fm,Lm,Dm,zm,Mm,$m,Bm,jm,Wm,Hm,Um,Gm,qm,Km,Xm,Ym,Qm,Jm,Zm,ev,tv,nv,rv,iv,ov,sv,av,lv,cv,uv,dv,hv,fv,gv,pv,mv,vv,bv,yv,xv,Cv,Sv,vn,hc,wv,Jn,bn,Br,Ev,jr,yn,Wr,kv,Zn,Ov,er,Hr,ft,tr,Ae,$i,nr,St,Zt,Iv,Ye,ee,Bi,Be,rr,Ur,Gt,xn,ji,Gr,qr,ir,or,Cn,Kr,se,Ui,mc,vc,bc,yc,xc,Cc,Sc,vb,Pv,Wi,Lt,je,sr,Dt,On,Rv,qt,wt,Hi,Tv,Kt,Sn,Qe,Xt,Yt,Gs,wc,Nv,zt,Av,me,wn,En,Xr,Yr,kn,Qr,Jr,_v,Vv,Fv,Lv,Dv,zv,Mv,$v,Bv,jv,Wv,Hv,Uv,Gv,qv,Kv,Xv,Yv,Qv,Jv,Zv,eb,tb,nb,rb,ib,ob,sb,ab,lb,cb;function ve(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const O=ve(E);function qs(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Ec={exports:{}},Gi={};/** * @license React * react-jsx-runtime.production.min.js * @@ -6,27 +6,27 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var vb=E,bb=Symbol.for("react.element"),yb=Symbol.for("react.fragment"),xb=Object.prototype.hasOwnProperty,Cb=vb.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Sb={key:!0,ref:!0,__self:!0,__source:!0};function kc(e,t,n){var r,i={},o=null,s=null;n!==void 0&&(o=""+n),t.key!==void 0&&(o=""+t.key),t.ref!==void 0&&(s=t.ref);for(r in t)xb.call(t,r)&&!Sb.hasOwnProperty(r)&&(i[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps,t)i[r]===void 0&&(i[r]=t[r]);return{$$typeof:bb,type:e,key:o,ref:s,props:i,_owner:Cb.current}}Hi.Fragment=yb,Hi.jsx=kc,Hi.jsxs=kc,Ec.exports=Hi;var y=Ec.exports;function Oc(e){var t=Object.create(null);return function(n){return t[n]===void 0&&(t[n]=e(n)),t[n]}}var wb=/^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|abbr|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|disableRemotePlayback|download|draggable|encType|enterKeyHint|fetchpriority|fetchPriority|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|popover|popoverTarget|popoverTargetAction|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|translate|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|incremental|fallback|inert|itemProp|itemScope|itemType|itemID|itemRef|on|option|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/,Eb=Oc(function(e){return wb.test(e)||e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)<91});function kb(e){if(e.sheet)return e.sheet;for(var t=0;t0?_e(sr,--We):0,or--,ye===10&&(or=1,Ki--),ye}function Ze(){return ye=We2||ei(ye)>3?"":" "}function zb(e,t){for(;--t&&Ze()&&!(ye<48||ye>102||ye>57&&ye<65||ye>70&&ye<97););return Zr(e,Yi()+(t<6&&Et()==32&&Ze()==32))}function Qs(e){for(;Ze();)switch(ye){case e:return We;case 34:case 39:e!==34&&e!==39&&Qs(ye);break;case 40:e===41&&Qs(e);break;case 92:Ze();break}return We}function Mb(e,t){for(;Ze()&&e+ye!==57;)if(e+ye===84&&Et()===47)break;return"/*"+Zr(t,We-1)+"*"+Gi(e===47?e:Ze())}function $b(e){for(;!ei(Et());)Ze();return Zr(e,We)}function Bb(e){return Ac(Ji("",null,null,null,[""],e=Nc(e),0,[0],e))}function Ji(e,t,n,r,i,o,s,a,l){for(var c=0,u=0,d=s,h=0,m=0,f=0,g=1,p=1,v=1,x=0,S="",C=i,w=o,P=r,_=S;p;)switch(f=x,x=Ze()){case 40:if(f!=108&&_e(_,d-1)==58){Xs(_+=ie(Qi(x),"&","&\f"),"&\f")!=-1&&(v=-1);break}case 34:case 39:case 91:_+=Qi(x);break;case 9:case 10:case 13:case 32:_+=Db(f);break;case 92:_+=zb(Yi()-1,7);continue;case 47:switch(Et()){case 42:case 47:qi(jb(Mb(Ze(),Yi()),t,n),l);break;default:_+="/"}break;case 123*g:a[c++]=wt(_)*v;case 125*g:case 59:case 0:switch(x){case 0:case 125:p=0;case 59+u:v==-1&&(_=ie(_,/\f/g,"")),m>0&&wt(_)-d&&qi(m>32?Vc(_+";",r,n,d-1):Vc(ie(_," ","")+";",r,n,d-2),l);break;case 59:_+=";";default:if(qi(P=_c(_,t,n,c,u,i,a,S,C=[],w=[],d),o),x===123)if(u===0)Ji(_,t,P,P,C,o,d,a,w);else switch(h===99&&_e(_,3)===110?100:h){case 100:case 108:case 109:case 115:Ji(e,P,P,r&&qi(_c(e,P,P,0,0,i,a,S,i,C=[],d),w),i,w,d,a,r?C:w);break;default:Ji(_,P,P,P,[""],w,0,a,w)}}c=u=m=0,g=v=1,S=_="",d=s;break;case 58:d=1+wt(_),m=f;default:if(g<1){if(x==123)--g;else if(x==125&&g++==0&&Lb()==125)continue}switch(_+=Gi(x),x*g){case 38:v=u>0?1:(_+="\f",-1);break;case 44:a[c++]=(wt(_)-1)*v,v=1;break;case 64:Et()===45&&(_+=Qi(Ze())),h=Et(),u=d=wt(S=_+=$b(Yi())),x++;break;case 45:f===45&&wt(_)==2&&(g=0)}}return o}function _c(e,t,n,r,i,o,s,a,l,c,u){for(var d=i-1,h=i===0?o:[""],m=Ys(h),f=0,g=0,p=0;f0?h[v]+" "+x:ie(x,/&\f/g,h[v])))&&(l[p++]=S);return Xi(e,t,n,i===0?qs:a,l,c,u)}function jb(e,t,n){return Xi(e,t,n,Ic,Gi(Fb()),Qr(e,2,-2),0)}function Vc(e,t,n,r){return Xi(e,t,n,Ks,Qr(e,0,r),Qr(e,r+1,-1),r)}function ar(e,t){for(var n="",r=Ys(e),i=0;i6)switch(_e(e,t+1)){case 109:if(_e(e,t+4)!==45)break;case 102:return ie(e,/(.+:)(.+)-([^]+)/,"$1"+re+"$2-$3$1"+Ui+(_e(e,t+3)==108?"$3":"$2-$3"))+e;case 115:return~Xs(e,"stretch")?Lc(ie(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(_e(e,t+1)!==115)break;case 6444:switch(_e(e,wt(e)-3-(~Xs(e,"!important")&&10))){case 107:return ie(e,":",":"+re)+e;case 101:return ie(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+re+(_e(e,14)===45?"inline-":"")+"box$3$1"+re+"$2$3$1"+De+"$2box$3")+e}break;case 5936:switch(_e(e,t+11)){case 114:return re+e+De+ie(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return re+e+De+ie(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return re+e+De+ie(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return re+e+De+e+e}return e}var Qb=function(t,n,r,i){if(t.length>-1&&!t.return)switch(t.type){case Ks:t.return=Lc(t.value,t.length);break;case Pc:return ar([Jr(t,{value:ie(t.value,"@","@"+re)})],i);case qs:if(t.length)return Vb(t.props,function(o){switch(_b(o,/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":return ar([Jr(t,{props:[ie(o,/:(read-\w+)/,":"+Ui+"$1")]})],i);case"::placeholder":return ar([Jr(t,{props:[ie(o,/:(plac\w+)/,":"+re+"input-$1")]}),Jr(t,{props:[ie(o,/:(plac\w+)/,":"+Ui+"$1")]}),Jr(t,{props:[ie(o,/:(plac\w+)/,De+"input-$1")]})],i)}return""})}},Jb=[Qb],Zb=function(t){var n=t.key;if(n==="css"){var r=document.querySelectorAll("style[data-emotion]:not([data-s])");Array.prototype.forEach.call(r,function(g){var p=g.getAttribute("data-emotion");p.indexOf(" ")!==-1&&(document.head.appendChild(g),g.setAttribute("data-s",""))})}var i=t.stylisPlugins||Jb,o={},s,a=[];s=t.container||document.head,Array.prototype.forEach.call(document.querySelectorAll('style[data-emotion^="'+n+' "]'),function(g){for(var p=g.getAttribute("data-emotion").split(" "),v=1;v0?_e(lr,--We):0,ar--,ye===10&&(ar=1,Yi--),ye}function Ze(){return ye=We2||ri(ye)>3?"":" "}function $b(e,t){for(;--t&&Ze()&&!(ye<48||ye>102||ye>57&&ye<65||ye>70&&ye<97););return ni(e,Ji()+(t<6&&kt()==32&&Ze()==32))}function Js(e){for(;Ze();)switch(ye){case e:return We;case 34:case 39:e!==34&&e!==39&&Js(ye);break;case 40:e===41&&Js(e);break;case 92:Ze();break}return We}function Bb(e,t){for(;Ze()&&e+ye!==57;)if(e+ye===84&&kt()===47)break;return"/*"+ni(t,We-1)+"*"+Ki(e===47?e:Ze())}function jb(e){for(;!ri(kt());)Ze();return ni(e,We)}function Wb(e){return Ac(eo("",null,null,null,[""],e=Nc(e),0,[0],e))}function eo(e,t,n,r,i,o,s,a,l){for(var c=0,u=0,d=s,h=0,m=0,f=0,g=1,p=1,b=1,C=0,S="",y=i,k=o,R=r,A=S;p;)switch(f=C,C=Ze()){case 40:if(f!=108&&_e(A,d-1)==58){Ys(A+=oe(Zi(C),"&","&\f"),"&\f")!=-1&&(b=-1);break}case 34:case 39:case 91:A+=Zi(C);break;case 9:case 10:case 13:case 32:A+=Mb(f);break;case 92:A+=$b(Ji()-1,7);continue;case 47:switch(kt()){case 42:case 47:Xi(Hb(Bb(Ze(),Ji()),t,n),l);break;default:A+="/"}break;case 123*g:a[c++]=Et(A)*b;case 125*g:case 59:case 0:switch(C){case 0:case 125:p=0;case 59+u:b==-1&&(A=oe(A,/\f/g,"")),m>0&&Et(A)-d&&Xi(m>32?Vc(A+";",r,n,d-1):Vc(oe(A," ","")+";",r,n,d-2),l);break;case 59:A+=";";default:if(Xi(R=_c(A,t,n,c,u,i,a,S,y=[],k=[],d),o),C===123)if(u===0)eo(A,t,R,R,y,o,d,a,k);else switch(h===99&&_e(A,3)===110?100:h){case 100:case 108:case 109:case 115:eo(e,R,R,r&&Xi(_c(e,R,R,0,0,i,a,S,i,y=[],d),k),i,k,d,a,r?y:k);break;default:eo(A,R,R,R,[""],k,0,a,k)}}c=u=m=0,g=b=1,S=A="",d=s;break;case 58:d=1+Et(A),m=f;default:if(g<1){if(C==123)--g;else if(C==125&&g++==0&&zb()==125)continue}switch(A+=Ki(C),C*g){case 38:b=u>0?1:(A+="\f",-1);break;case 44:a[c++]=(Et(A)-1)*b,b=1;break;case 64:kt()===45&&(A+=Zi(Ze())),h=kt(),u=d=Et(S=A+=jb(Ji())),C++;break;case 45:f===45&&Et(A)==2&&(g=0)}}return o}function _c(e,t,n,r,i,o,s,a,l,c,u){for(var d=i-1,h=i===0?o:[""],m=Qs(h),f=0,g=0,p=0;f0?h[b]+" "+C:oe(C,/&\f/g,h[b])))&&(l[p++]=S);return Qi(e,t,n,i===0?Ks:a,l,c,u)}function Hb(e,t,n){return Qi(e,t,n,Ic,Ki(Db()),ei(e,2,-2),0)}function Vc(e,t,n,r){return Qi(e,t,n,Xs,ei(e,0,r),ei(e,r+1,-1),r)}function cr(e,t){for(var n="",r=Qs(e),i=0;i6)switch(_e(e,t+1)){case 109:if(_e(e,t+4)!==45)break;case 102:return oe(e,/(.+:)(.+)-([^]+)/,"$1"+ie+"$2-$3$1"+qi+(_e(e,t+3)==108?"$3":"$2-$3"))+e;case 115:return~Ys(e,"stretch")?Lc(oe(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(_e(e,t+1)!==115)break;case 6444:switch(_e(e,Et(e)-3-(~Ys(e,"!important")&&10))){case 107:return oe(e,":",":"+ie)+e;case 101:return oe(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+ie+(_e(e,14)===45?"inline-":"")+"box$3$1"+ie+"$2$3$1"+De+"$2box$3")+e}break;case 5936:switch(_e(e,t+11)){case 114:return ie+e+De+oe(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return ie+e+De+oe(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return ie+e+De+oe(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return ie+e+De+e+e}return e}var Zb=function(t,n,r,i){if(t.length>-1&&!t.return)switch(t.type){case Xs:t.return=Lc(t.value,t.length);break;case Pc:return cr([ti(t,{value:oe(t.value,"@","@"+ie)})],i);case Ks:if(t.length)return Lb(t.props,function(o){switch(Fb(o,/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":return cr([ti(t,{props:[oe(o,/:(read-\w+)/,":"+qi+"$1")]})],i);case"::placeholder":return cr([ti(t,{props:[oe(o,/:(plac\w+)/,":"+ie+"input-$1")]}),ti(t,{props:[oe(o,/:(plac\w+)/,":"+qi+"$1")]}),ti(t,{props:[oe(o,/:(plac\w+)/,De+"input-$1")]})],i)}return""})}},ey=[Zb],ty=function(t){var n=t.key;if(n==="css"){var r=document.querySelectorAll("style[data-emotion]:not([data-s])");Array.prototype.forEach.call(r,function(g){var p=g.getAttribute("data-emotion");p.indexOf(" ")!==-1&&(document.head.appendChild(g),g.setAttribute("data-s",""))})}var i=t.stylisPlugins||ey,o={},s,a=[];s=t.container||document.head,Array.prototype.forEach.call(document.querySelectorAll('style[data-emotion^="'+n+' "]'),function(g){for(var p=g.getAttribute("data-emotion").split(" "),b=1;b=4;++r,i-=4)n=e.charCodeAt(r)&255|(e.charCodeAt(++r)&255)<<8|(e.charCodeAt(++r)&255)<<16|(e.charCodeAt(++r)&255)<<24,n=(n&65535)*1540483477+((n>>>16)*59797<<16),n^=n>>>24,t=(n&65535)*1540483477+((n>>>16)*59797<<16)^(t&65535)*1540483477+((t>>>16)*59797<<16);switch(i){case 3:t^=(e.charCodeAt(r+2)&255)<<16;case 2:t^=(e.charCodeAt(r+1)&255)<<8;case 1:t^=e.charCodeAt(r)&255,t=(t&65535)*1540483477+((t>>>16)*59797<<16)}return t^=t>>>13,t=(t&65535)*1540483477+((t>>>16)*59797<<16),((t^t>>>15)>>>0).toString(36)}var uy={animationIterationCount:1,aspectRatio:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,scale:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},dy=/[A-Z]|^ms/g,hy=/_EMO_([^_]+?)_([^]*?)_EMO_/g,jc=function(t){return t.charCodeAt(1)===45},Wc=function(t){return t!=null&&typeof t!="boolean"},ra=Oc(function(e){return jc(e)?e:e.replace(dy,"-$&").toLowerCase()}),Hc=function(t,n){switch(t){case"animation":case"animationName":if(typeof n=="string")return n.replace(hy,function(r,i,o){return kt={name:i,styles:o,next:kt},i})}return uy[t]!==1&&!jc(t)&&typeof n=="number"&&n!==0?n+"px":n};function ti(e,t,n){if(n==null)return"";var r=n;if(r.__emotion_styles!==void 0)return r;switch(typeof n){case"boolean":return"";case"object":{var i=n;if(i.anim===1)return kt={name:i.name,styles:i.styles,next:kt},i.name;var o=n;if(o.styles!==void 0){var s=o.next;if(s!==void 0)for(;s!==void 0;)kt={name:s.name,styles:s.styles,next:kt},s=s.next;var a=o.styles+";";return a}return fy(e,t,n)}case"function":{if(e!==void 0){var l=kt,c=n(e);return kt=l,ti(e,t,c)}break}}var u=n;if(t==null)return u;var d=t[u];return d!==void 0?d:u}function fy(e,t,n){var r="";if(Array.isArray(n))for(var i=0;ir==null?void 0:r(...n))}}const xy=(...e)=>e.map(t=>{var n;return(n=t==null?void 0:t.trim)==null?void 0:n.call(t)}).filter(Boolean).join(" "),Cy=/^on[A-Z]/;function ni(...e){let t={};for(let n of e){for(let r in t){if(Cy.test(r)&&typeof t[r]=="function"&&typeof n[r]=="function"){t[r]=yy(t[r],n[r]);continue}if(r==="className"||r==="class"){t[r]=xy(t[r],n[r]);continue}if(r==="style"){t[r]=Object.assign({},t[r]??{},n[r]??{});continue}t[r]=n[r]!==void 0?n[r]:t[r]}for(let r in n)t[r]===void 0&&(t[r]=n[r])}return t}function Sy(e,t){if(e!=null){if(typeof e=="function"){e(t);return}try{e.current=t}catch{throw new Error(`Cannot assign value '${t}' to ref '${e}'`)}}}function wy(...e){return t=>{e.forEach(n=>{Sy(n,t)})}}function ri(e){const t=Object.assign({},e);for(let n in t)t[n]===void 0&&delete t[n];return t}const st=(...e)=>e.filter(Boolean).map(t=>t.trim()).join(" ");function Ey(e){return e.default||e}const He=e=>e!=null&&typeof e=="object"&&!Array.isArray(e),Ot=e=>typeof e=="string",ca=e=>typeof e=="function";function ky(e){var n;const t=O.version;return!Ot(t)||t.startsWith("18.")?e==null?void 0:e.ref:(n=e==null?void 0:e.props)==null?void 0:n.ref}const Jc=(...e)=>{const t=e.reduce((n,r)=>(r!=null&&r.forEach(i=>n.add(i)),n),new Set([]));return Array.from(t)};function Oy(e,t){return`${e} returned \`undefined\`. Seems you forgot to wrap component within ${t}`}function lr(e={}){const{name:t,strict:n=!0,hookName:r="useContext",providerName:i="Provider",errorMessage:o,defaultValue:s}=e,a=E.createContext(s);a.displayName=t;function l(){var u;const c=E.useContext(a);if(!c&&n){const d=new Error(o??Oy(r,i));throw d.name="ContextError",(u=Error.captureStackTrace)==null||u.call(Error,d,l),d}return c}return[a.Provider,l,a]}const[Iy,co]=lr({name:"ChakraContext",strict:!0,providerName:""});function Py(e){const{value:t,children:n}=e;return y.jsxs(Iy,{value:t,children:[!t._config.disableLayers&&y.jsx(Qc,{styles:t.layers.atRule}),y.jsx(Qc,{styles:t._global}),n]})}const Ry=(e,t)=>{const n={},r={},i=Object.keys(e);for(const o of i)t(o)?r[o]=e[o]:n[o]=e[o];return[r,n]},cr=(e,t)=>{const n=ca(t)?t:r=>t.includes(r);return Ry(e,n)},Ty=new Set(["htmlWidth","htmlHeight","htmlSize","htmlTranslate"]);function Ny(e){return typeof e=="string"&&Ty.has(e)}function Ay(e,t,n){const{css:r,isValidProperty:i}=co(),{children:o,...s}=e,a=E.useMemo(()=>{const[h,m]=cr(s,x=>n(x,t.variantKeys)),[f,g]=cr(m,t.variantKeys),[p,v]=cr(g,i);return{forwardedProps:h,variantProps:f,styleProps:p,elementProps:v}},[t.variantKeys,n,s,i]),{css:l,...c}=a.styleProps,u=E.useMemo(()=>{const h={...a.variantProps};return t.variantKeys.includes("colorPalette")||(h.colorPalette=s.colorPalette),t.variantKeys.includes("orientation")||(h.orientation=s.orientation),t(h)},[t,a.variantProps,s.colorPalette,s.orientation]);return{styles:E.useMemo(()=>r(u,..._y(l),c),[r,u,l,c]),props:{...a.forwardedProps,...a.elementProps,children:o}}}const _y=e=>(Array.isArray(e)?e:[e]).filter(Boolean).flat(),Vy=Ey(Eb),Fy=e=>e!=="theme",Ly=(e,t,n)=>{let r;if(t){const i=t.shouldForwardProp;r=e.__emotion_forwardProp&&i?o=>e.__emotion_forwardProp(o)&&i(o):i}return typeof r!="function"&&n&&(r=e.__emotion_forwardProp),r};let Dy=typeof document<"u";const Zc=({cache:e,serialized:t,isStringTag:n})=>{ta(e,t,n);const r=qc(()=>na(e,t,n));if(!Dy&&r!==void 0){let i=t.name,o=t.next;for(;o!==void 0;)i=st(i,o.name),o=o.next;return y.jsx("style",{"data-emotion":st(e.key,i),dangerouslySetInnerHTML:{__html:r},nonce:e.sheet.nonce})}return null},eu={path:["d"],text:["x","y"],circle:["cx","cy","r"],rect:["width","height","x","y","rx","ry"],ellipse:["cx","cy","rx","ry"],g:["transform"],stop:["offset","stopOpacity"]},zy=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),ua=((e,t={},n={})=>{if(zy(eu,e)){n.forwardProps||(n.forwardProps=[]);const c=eu[e];n.forwardProps=Jc([...n.forwardProps,...c])}const r=e.__emotion_real===e,i=r&&e.__emotion_base||e;let o,s;n!==void 0&&(o=n.label,s=n.target);let a=[];const l=oa((c,u,d)=>{var z;const{cva:h,isValidProperty:m}=co(),f=t.__cva__?t:h(t),g=My(e.__emotion_cva,f),p=V=>(B,K)=>V.includes(B)?!0:!(K!=null&&K.includes(B))&&!m(B);!n.shouldForwardProp&&n.forwardProps&&(n.shouldForwardProp=p(n.forwardProps));const v=(V,B)=>{const K=typeof e=="string"&&e.charCodeAt(0)>96?Vy:Fy,$=!(B!=null&&B.includes(V))&&!m(V);return K(V)&&$},x=Ly(e,n,r)||v,S=O.useMemo(()=>Object.assign({},n.defaultProps,ri(c)),[c]),{props:C,styles:w}=Ay(S,g,x);let P="",_=[w],R=C;if(C.theme==null){R={};for(let V in C)R[V]=C[V];R.theme=O.useContext(sa)}typeof C.className=="string"?P=Bc(u.registered,_,C.className):C.className!=null&&(P=st(P,C.className));const N=ia(a.concat(_),u.registered,R);N.styles&&(P=st(P,`${u.key}-${N.name}`)),s!==void 0&&(P=st(P,s));const T=!x("as");let j=T&&C.as||i,I={};for(let V in C)if(!(T&&V==="as")){if(Ny(V)){const B=V.replace("html","").toLowerCase();I[B]=C[V];continue}x(V)&&(I[V]=C[V])}let F=P.trim();F?I.className=F:Reflect.deleteProperty(I,"className"),I.ref=d;const Y=n.forwardAsChild||((z=n.forwardProps)==null?void 0:z.includes("asChild"));if(C.asChild&&!Y){const V=O.isValidElement(C.children)?O.Children.only(C.children):O.Children.toArray(C.children).find(O.isValidElement);if(!V)throw new Error("[chakra-ui > factory] No valid child found");j=V.type,I.children=null,Reflect.deleteProperty(I,"asChild"),I=ni(I,V.props),I.ref=wy(d,ky(V))}return I.as&&Y?(I.as=void 0,y.jsxs(O.Fragment,{children:[y.jsx(Zc,{cache:u,serialized:N,isStringTag:typeof j=="string"}),y.jsx(j,{asChild:!0,...I,children:y.jsx(C.as,{children:I.children})})]})):y.jsxs(O.Fragment,{children:[y.jsx(Zc,{cache:u,serialized:N,isStringTag:typeof j=="string"}),y.jsx(j,{...I})]})});return l.displayName=o!==void 0?o:`chakra(${typeof i=="string"?i:i.displayName||i.name||"Component"})`,l.__emotion_real=l,l.__emotion_base=i,l.__emotion_forwardProp=n.shouldForwardProp,l.__emotion_cva=t,Object.defineProperty(l,"toString",{value(){return`.${s}`}}),l}).bind(),da=new Map,Oe=new Proxy(ua,{apply(e,t,n){return ua(...n)},get(e,t){return da.has(t)||da.set(t,ua(t)),da.get(t)}}),My=(e,t)=>e&&!t?e:!e&&t?t:e.merge(t),zt=Oe("div");zt.displayName="Box";const $y=Object.freeze({}),By=Object.freeze({});function jy(e){const{key:t,recipe:n}=e,r=co();return E.useMemo(()=>{const i=n||(t!=null?r.getRecipe(t):{});return r.cva(structuredClone(i))},[t,n,r])}const Wy=e=>e.charAt(0).toUpperCase()+e.slice(1);function ii(e){const{key:t,recipe:n}=e,r=Wy(t||n.className||"Component"),[i,o]=lr({strict:!1,name:`${r}PropsContext`,providerName:`${r}PropsContext`});function s(c){const{unstyled:u,...d}=c,h=jy({key:t,recipe:d.recipe||n}),[m,f]=E.useMemo(()=>h.splitVariantProps(d),[h,d]);return{styles:u?$y:h(m),className:h.className,props:f}}const a=(c,u)=>{const d=Oe(c,{},u),h=E.forwardRef((m,f)=>{const g=o(),p=E.useMemo(()=>ni(g,m),[m,g]),{styles:v,className:x,props:S}=s(p);return y.jsx(d,{...S,ref:f,css:[v,p.css],className:st(x,p.className)})});return h.displayName=c.displayName||c.name,h};function l(){return i}return{withContext:a,PropsProvider:i,withPropsProvider:l,usePropsContext:o,useRecipeResult:s}}function uo(e){return e==null?[]:Array.isArray(e)?e:[e]}var oi=e=>e[0],ha=e=>e[e.length-1],Hy=(e,t)=>e.indexOf(t)!==-1,kn=(e,...t)=>e.concat(t),On=(e,...t)=>e.filter(n=>!t.includes(n)),ur=e=>Array.from(new Set(e)),fa=(e,t)=>{const n=new Set(t);return e.filter(r=>!n.has(r))},dr=(e,t)=>Hy(e,t)?On(e,t):kn(e,t);function tu(e,t,n={}){const{step:r=1,loop:i=!0}=n,o=t+r,s=e.length,a=s-1;return t===-1?r>0?0:a:o<0?i?a:0:o>=s?i?0:t>s?s:t:o}function Uy(e,t,n={}){return e[tu(e,t,n)]}function Gy(e,t,n={}){const{step:r=1,loop:i=!0}=n;return tu(e,t,{step:-r,loop:i})}function qy(e,t,n={}){return e[Gy(e,t,n)]}function nu(e,t){return e.reduce(([n,r],i)=>(t(i)?n.push(i):r.push(i),[n,r]),[[],[]])}var ru=e=>(e==null?void 0:e.constructor.name)==="Array",Ky=(e,t)=>{if(e.length!==t.length)return!1;for(let n=0;n{if(Object.is(e,t))return!0;if(e==null&&t!=null||e!=null&&t==null)return!1;if(typeof(e==null?void 0:e.isEqual)=="function"&&typeof(t==null?void 0:t.isEqual)=="function")return e.isEqual(t);if(typeof e=="function"&&typeof t=="function")return e.toString()===t.toString();if(ru(e)&&ru(t))return Ky(Array.from(e),Array.from(t));if(typeof e!="object"||typeof t!="object")return!1;const n=Object.keys(t??Object.create(null)),r=n.length;for(let i=0;iArray.isArray(e),Xy=e=>e===!0||e===!1,iu=e=>e!=null&&typeof e=="object",In=e=>iu(e)&&!si(e),ho=e=>typeof e=="string",Pn=e=>typeof e=="function",Yy=e=>e==null,Yt=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),Qy=e=>Object.prototype.toString.call(e),ou=Function.prototype.toString,Jy=ou.call(Object),Zy=e=>{if(!iu(e)||Qy(e)!="[object Object]"||n0(e))return!1;const t=Object.getPrototypeOf(e);if(t===null)return!0;const n=Yt(t,"constructor")&&t.constructor;return typeof n=="function"&&n instanceof n&&ou.call(n)==Jy},e0=e=>typeof e=="object"&&e!==null&&"$$typeof"in e&&"props"in e,t0=e=>typeof e=="object"&&e!==null&&"__v_isVNode"in e,n0=e=>e0(e)||t0(e),fo=(e,...t)=>(typeof e=="function"?e(...t):e)??void 0,r0=e=>e(),i0=()=>{},go=(...e)=>(...t)=>{e.forEach(function(n){n==null||n(...t)})},o0=(()=>{let e=0;return()=>(e++,e.toString(36))})();function Mt(e,t,...n){var i;if(e in t){const o=t[e];return Pn(o)?o(...n):o}const r=new Error(`No matching key: ${JSON.stringify(e)} in ${JSON.stringify(Object.keys(t))}`);throw(i=Error.captureStackTrace)==null||i.call(Error,r,Mt),r}var su=(e,t)=>{var n;try{return e()}catch(r){return r instanceof Error&&((n=Error.captureStackTrace)==null||n.call(Error,r,su)),t==null?void 0:t()}},{floor:au,abs:lu,round:po,min:s0,max:a0,pow:l0,sign:c0}=Math,ga=e=>Number.isNaN(e),Qt=e=>ga(e)?0:e,cu=(e,t)=>(e%t+t)%t,u0=(e,t)=>(e%t+t)%t,d0=(e,t)=>Qt(e)>=t,h0=(e,t)=>Qt(e)<=t,f0=(e,t,n)=>{const r=Qt(e),i=t==null||r>=t,o=n==null||r<=n;return i&&o},g0=(e,t,n)=>po((Qt(e)-t)/n)*n+t,Ue=(e,t,n)=>s0(a0(Qt(e),t),n),p0=(e,t,n)=>(Qt(e)-t)/(n-t),m0=(e,t,n,r)=>Ue(g0(e*(n-t)+t,t,r),t,n),uu=(e,t)=>{let n=e,r=t.toString(),i=r.indexOf("."),o=i>=0?r.length-i:0;if(o>0){let s=l0(10,o);n=po(n*s)/s}return n},pa=(e,t)=>typeof t=="number"?au(e*t+.5)/t:po(e),du=(e,t,n,r)=>{const i=t!=null?Number(t):0,o=Number(n),s=(e-i)%r;let a=lu(s)*2>=r?e+c0(s)*(r-lu(s)):e-s;if(a=uu(a,r),!ga(i)&&ao){const l=au((o-i)/r),c=i+l*r;a=l<=0||c{const r=Math.pow(n,t);return po(e*r)/r},hu=e=>{if(!Number.isFinite(e))return 0;let t=1,n=0;for(;Math.round(e*t)/t!==e;)t*=10,n+=1;return n},fu=(e,t,n)=>{let r=t==="+"?e+n:e-n;if(e%1!==0||n%1!==0){const i=10**Math.max(hu(e),hu(n));e=Math.round(e*i),n=Math.round(n*i),r=t==="+"?e+n:e-n,r/=i}return r},v0=(e,t)=>fu(Qt(e),"+",t),b0=(e,t)=>fu(Qt(e),"-",t);function mo(e){if(!Zy(e)||e===void 0)return e;const t=Reflect.ownKeys(e).filter(r=>typeof r=="string"),n={};for(const r of t){const i=e[r];i!==void 0&&(n[r]=mo(i))}return n}function y0(e,t=Object.is){let n={...e};const r=new Set,i=u=>(r.add(u),()=>r.delete(u)),o=()=>{r.forEach(u=>u())};return{subscribe:i,get:u=>n[u],set:(u,d)=>{t(n[u],d)||(n[u]=d,o())},update:u=>{let d=!1;for(const h in u){const m=u[h];m!==void 0&&!t(n[h],m)&&(n[h]=m,d=!0)}d&&o()},snapshot:()=>({...n})}}function ai(...e){e.length===1?e[0]:e[1],e.length===2&&e[0]}function gu(e,t){if(e==null)throw new Error(t())}function x0(e,t){return`${e} returned \`undefined\`. Seems you forgot to wrap component within ${t}`}function hr(e={}){const{name:t,strict:n=!0,hookName:r="useContext",providerName:i="Provider",errorMessage:o,defaultValue:s}=e,a=E.createContext(s);a.displayName=t;function l(){var u;const c=E.useContext(a);if(!c&&n){const d=new Error(o??x0(r,i));throw d.name="ContextError",(u=Error.captureStackTrace)==null||u.call(Error,d,l),d}return c}return[a.Provider,l,a]}const[t5,pu]=hr({name:"EnvironmentContext",hookName:"useEnvironmentContext",providerName:"",strict:!1,defaultValue:{getRootNode:()=>document,getDocument:()=>document,getWindow:()=>window}});function C0(e){if(!e)return;const t=e.selectionStart??0,n=e.selectionEnd??0;Math.abs(n-t)===0&&t===0&&e.setSelectionRange(e.value.length,e.value.length)}var mu=e=>Math.max(0,Math.min(1,e)),S0=(e,t)=>e.map((n,r)=>e[(Math.max(t,0)+r)%e.length]),vu=()=>{},vo=e=>typeof e=="object"&&e!==null,w0=2147483647,E0=1,k0=9,O0=11,Me=e=>vo(e)&&e.nodeType===E0&&typeof e.nodeName=="string",ma=e=>vo(e)&&e.nodeType===k0,I0=e=>vo(e)&&e===e.window,bu=e=>Me(e)?e.localName||"":"#document";function P0(e){return["html","body","#document"].includes(bu(e))}var R0=e=>vo(e)&&e.nodeType!==void 0,fr=e=>R0(e)&&e.nodeType===O0&&"host"in e,T0=e=>Me(e)&&e.localName==="input",N0=e=>Me(e)?e.offsetWidth>0||e.offsetHeight>0||e.getClientRects().length>0:!1,A0=/(textarea|select)/;function yu(e){if(e==null||!Me(e))return!1;try{return T0(e)&&e.selectionStart!=null||A0.test(e.localName)||e.isContentEditable||e.getAttribute("contenteditable")==="true"||e.getAttribute("contenteditable")===""}catch{return!1}}function Rn(e,t){var r;if(!e||!t||!Me(e)||!Me(t))return!1;const n=(r=t.getRootNode)==null?void 0:r.call(t);if(e===t||e.contains(t))return!0;if(n&&fr(n)){let i=t;for(;i;){if(e===i)return!0;i=i.parentNode||i.host}}return!1}function Ge(e){return ma(e)?e:I0(e)?e.document:(e==null?void 0:e.ownerDocument)??document}function _0(e){return Ge(e).documentElement}function Ie(e){var t;return fr(e)?Ie(e.host):ma(e)?e.defaultView??window:Me(e)?((t=e.ownerDocument)==null?void 0:t.defaultView)??window:window}function xu(e){let t=e.activeElement;for(;t!=null&&t.shadowRoot;){const n=t.shadowRoot.activeElement;if(n===t)break;t=n}return t}function V0(e){if(bu(e)==="html")return e;const t=e.assignedSlot||e.parentNode||fr(e)&&e.host||_0(e);return fr(t)?t.host:t}var va=new WeakMap;function bo(e){return va.has(e)||va.set(e,Ie(e).getComputedStyle(e)),va.get(e)}var yo=()=>typeof document<"u";function F0(){const e=navigator.userAgentData;return(e==null?void 0:e.platform)??navigator.platform}function L0(){const e=navigator.userAgentData;return e&&Array.isArray(e.brands)?e.brands.map(({brand:t,version:n})=>`${t}/${n}`).join(" "):navigator.userAgent}var ba=e=>yo()&&e.test(F0()),Cu=e=>yo()&&e.test(L0()),D0=e=>yo()&&e.test(navigator.vendor),Su=()=>yo()&&!!navigator.maxTouchPoints,z0=()=>ba(/^iPhone/i),M0=()=>ba(/^iPad/i)||Co()&&navigator.maxTouchPoints>1,xo=()=>z0()||M0(),$0=()=>Co()||xo(),Co=()=>ba(/^Mac/i),wu=()=>$0()&&D0(/apple/i),B0=()=>Cu(/Firefox/i),j0=()=>Cu(/Android/i);function W0(e){var t,n,r;return((t=e.composedPath)==null?void 0:t.call(e))??((r=(n=e.nativeEvent)==null?void 0:n.composedPath)==null?void 0:r.call(n))}function tt(e){const t=W0(e);return(t==null?void 0:t[0])??e.target}function H0(e){return K0(e).isComposing||e.keyCode===229}function U0(e){return e.pointerType===""&&e.isTrusted?!0:j0()&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}var G0=e=>e.button===2||Co()&&e.ctrlKey&&e.button===0,q0=e=>"touches"in e&&e.touches.length>0;function K0(e){return e.nativeEvent??e}function X0(e,t="client"){const n=q0(e)?e.touches[0]||e.changedTouches[0]:e;return{x:n[`${t}X`],y:n[`${t}Y`]}}var he=(e,t,n,r)=>{const i=typeof e=="function"?e():e;return i==null||i.addEventListener(t,n,r),()=>{i==null||i.removeEventListener(t,n,r)}};function Y0(e,t){const{type:n="HTMLInputElement",property:r="value"}=t,i=Ie(e)[n].prototype;return Object.getOwnPropertyDescriptor(i,r)??{}}function Q0(e){if(e.localName==="input")return"HTMLInputElement";if(e.localName==="textarea")return"HTMLTextAreaElement";if(e.localName==="select")return"HTMLSelectElement"}function So(e,t,n="value"){var i;if(!e)return;const r=Q0(e);r&&((i=Y0(e,{type:r,property:n}).set)==null||i.call(e,t)),e.setAttribute(n,t)}function J0(e,t){const{value:n,bubbles:r=!0}=t;if(!e)return;const i=Ie(e);e instanceof i.HTMLInputElement&&(So(e,`${n}`),e.dispatchEvent(new i.Event("input",{bubbles:r})))}function Z0(e){return ex(e)?e.form:e.closest("form")}function ex(e){return e.matches("textarea, input, select, button")}function tx(e,t){if(!e)return;const n=Z0(e),r=i=>{i.defaultPrevented||t()};return n==null||n.addEventListener("reset",r,{passive:!0}),()=>n==null?void 0:n.removeEventListener("reset",r)}function nx(e,t){const n=e==null?void 0:e.closest("fieldset");if(!n)return;t(n.disabled);const r=Ie(n),i=new r.MutationObserver(()=>t(n.disabled));return i.observe(n,{attributes:!0,attributeFilter:["disabled"]}),()=>i.disconnect()}function ya(e,t){if(!e)return;const{onFieldsetDisabledChange:n,onFormReset:r}=t,i=[tx(e,r),nx(e,n)];return()=>i.forEach(o=>o==null?void 0:o())}var Eu=e=>Me(e)&&e.tagName==="IFRAME",rx=e=>!Number.isNaN(parseInt(e.getAttribute("tabindex")||"0",10)),ix=e=>parseInt(e.getAttribute("tabindex")||"0",10)<0,xa="input:not([type='hidden']):not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], button:not([disabled]), [tabindex], iframe, object, embed, area[href], audio[controls], video[controls], [contenteditable]:not([contenteditable='false']), details > summary:first-of-type",ku=(e,t=!1)=>{if(!e)return[];const n=Array.from(e.querySelectorAll(xa));(t==!0||t=="if-empty"&&n.length===0)&&Me(e)&&Jt(e)&&n.unshift(e);const i=n.filter(Jt);return i.forEach((o,s)=>{if(Eu(o)&&o.contentDocument){const a=o.contentDocument.body;i.splice(s,1,...ku(a))}}),i};function Jt(e){return!e||e.closest("[inert]")?!1:e.matches(xa)&&N0(e)}function Ca(e,t){if(!e)return[];const r=Array.from(e.querySelectorAll(xa)).filter(Tn);return r.forEach((i,o)=>{if(Eu(i)&&i.contentDocument){const s=i.contentDocument.body,a=Ca(s);r.splice(o,1,...a)}}),r.length,r}function Tn(e){return e!=null&&e.tabIndex>0?!0:Jt(e)&&!ix(e)}function li(e){return e.tabIndex<0&&(/^(audio|video|details)$/.test(e.localName)||yu(e))&&!rx(e)?0:e.tabIndex}function Sa(e){const{root:t,getInitialEl:n,filter:r,enabled:i=!0}=e;if(!i)return;let o=null;if(o||(o=typeof n=="function"?n():n),o||(o=t==null?void 0:t.querySelector("[data-autofocus],[autofocus]")),!o){const s=Ca(t);o=r?s.filter(r)[0]:s[0]}return o||t||void 0}function wa(e){const t=new Set;function n(r){const i=globalThis.requestAnimationFrame(r);t.add(()=>globalThis.cancelAnimationFrame(i))}return n(()=>n(e)),function(){t.forEach(i=>i())}}function Z(e){let t;const n=globalThis.requestAnimationFrame(()=>{t=e()});return()=>{globalThis.cancelAnimationFrame(n),t==null||t()}}function ox(e,t,n){const r=Z(()=>{e.removeEventListener(t,i,!0),n()}),i=()=>{r(),n()};return e.addEventListener(t,i,{once:!0,capture:!0}),r}function sx(e,t){if(!e)return;const{attributes:n,callback:r}=t,i=e.ownerDocument.defaultView||window,o=new i.MutationObserver(s=>{for(const a of s)a.type==="attributes"&&a.attributeName&&n.includes(a.attributeName)&&r(a)});return o.observe(e,{attributes:!0,attributeFilter:n}),()=>o.disconnect()}function wo(e,t){const{defer:n}=t,r=n?Z:o=>o(),i=[];return i.push(r(()=>{const o=typeof e=="function"?e():e;i.push(sx(o,t))})),()=>{i.forEach(o=>o==null?void 0:o())}}function Ou(e){const t=()=>{const n=Ie(e);e.dispatchEvent(new n.MouseEvent("click"))};B0()?ox(e,"keyup",t):queueMicrotask(t)}function Eo(e){const t=V0(e);return P0(t)?Ge(t).body:Me(t)&&Ea(t)?t:Eo(t)}function Iu(e,t=[]){const n=Eo(e),r=n===e.ownerDocument.body,i=Ie(n);return r?t.concat(i,i.visualViewport||[],Ea(n)?n:[]):t.concat(n,Iu(n,[]))}var ax=/auto|scroll|overlay|hidden|clip/,lx=new Set(["inline","contents"]);function Ea(e){const t=Ie(e),{overflow:n,overflowX:r,overflowY:i,display:o}=t.getComputedStyle(e);return ax.test(n+i+r)&&!lx.has(o)}function cx(e){return e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth}function ko(e,t){const{rootEl:n,...r}=t||{};!e||!n||!Ea(n)||!cx(n)||e.scrollIntoView(r)}function Pu(e,t){const{left:n,top:r,width:i,height:o}=t.getBoundingClientRect(),s={x:e.x-n,y:e.y-r},a={x:mu(s.x/i),y:mu(s.y/o)};function l(c={}){const{dir:u="ltr",orientation:d="horizontal",inverted:h}=c,m=typeof h=="object"?h.x:h,f=typeof h=="object"?h.y:h;return d==="horizontal"?u==="rtl"||m?1-a.x:a.x:f?1-a.y:a.y}return{offset:s,percent:a,getPercentValue:l}}function ux(e,t){const n=e.body,r="pointerLockElement"in e||"mozPointerLockElement"in e,i=()=>!!e.pointerLockElement;function o(){}function s(l){i(),console.error("PointerLock error occurred:",l),e.exitPointerLock()}if(!r)return;try{n.requestPointerLock()}catch{}const a=[he(e,"pointerlockchange",o,!1),he(e,"pointerlockerror",s,!1)];return()=>{a.forEach(l=>l()),e.exitPointerLock()}}var gr="default",ka="",Oo=new WeakMap;function dx(e={}){const{target:t,doc:n}=e,r=n??document,i=r.documentElement;return xo()?(gr==="default"&&(ka=i.style.webkitUserSelect,i.style.webkitUserSelect="none"),gr="disabled"):t&&(Oo.set(t,t.style.userSelect),t.style.userSelect="none"),()=>hx({target:t,doc:r})}function hx(e={}){const{target:t,doc:n}=e,i=(n??document).documentElement;if(xo()){if(gr!=="disabled")return;gr="restoring",setTimeout(()=>{wa(()=>{gr==="restoring"&&(i.style.webkitUserSelect==="none"&&(i.style.webkitUserSelect=ka||""),ka="",gr="default")})},300)}else if(t&&Oo.has(t)){const o=Oo.get(t);t.style.userSelect==="none"&&(t.style.userSelect=o??""),t.getAttribute("style")===""&&t.removeAttribute("style"),Oo.delete(t)}}function Ru(e={}){const{defer:t,target:n,...r}=e,i=t?Z:s=>s(),o=[];return o.push(i(()=>{const s=typeof n=="function"?n():n;o.push(dx({...r,target:s}))})),()=>{o.forEach(s=>s==null?void 0:s())}}function fx(e,t){const{onPointerMove:n,onPointerUp:r}=t,o=[he(e,"pointermove",s=>{const a=X0(s),l=Math.sqrt(a.x**2+a.y**2),c=s.pointerType==="touch"?10:5;if(!(l{o.forEach(s=>s())}}function Io(e,t){return Array.from((e==null?void 0:e.querySelectorAll(t))??[])}function gx(e,t){return(e==null?void 0:e.querySelector(t))??null}var Oa=e=>e.id;function px(e,t,n=Oa){return e.find(r=>n(r)===t)}function Ia(e,t,n=Oa){const r=px(e,t,n);return r?e.indexOf(r):-1}function mx(e,t,n=!0){let r=Ia(e,t);return r=n?(r+1)%e.length:Math.min(r+1,e.length-1),e[r]}function vx(e,t,n=!0){let r=Ia(e,t);return r===-1?n?e[e.length-1]:null:(r=n?(r-1+e.length)%e.length:Math.max(0,r-1),e[r])}var bx=e=>e.split("").map(t=>{const n=t.charCodeAt(0);return n>0&&n<128?t:n>=128&&n<=255?`/x${n.toString(16)}`.replace("/","\\"):""}).join("").trim(),yx=e=>{var t;return bx(((t=e.dataset)==null?void 0:t.valuetext)??e.textContent??"")},xx=(e,t)=>e.trim().toLowerCase().startsWith(t.toLowerCase());function Cx(e,t,n,r=Oa){const i=n?Ia(e,n,r):-1;let o=n?S0(e,i):e;return t.length===1&&(o=o.filter(a=>r(a)!==n)),o.find(a=>xx(yx(a),t))}function Po(e,t){if(!e)return vu;const n=Object.keys(t).reduce((r,i)=>(r[i]=e.style.getPropertyValue(i),r),{});return Object.assign(e.style,t),()=>{Object.assign(e.style,n),e.style.length===0&&e.removeAttribute("style")}}function Sx(e,t,n){if(!e)return vu;const r=e.style.getPropertyValue(t);return e.style.setProperty(t,n),()=>{e.style.setProperty(t,r),e.style.length===0&&e.removeAttribute("style")}}function wx(e,t){const{state:n,activeId:r,key:i,timeout:o=350,itemToId:s}=t,a=n.keysSoFar+i,c=a.length>1&&Array.from(a).every(f=>f===a[0])?a[0]:a;let u=e.slice();const d=Cx(u,c,r,s);function h(){clearTimeout(n.timer),n.timer=-1}function m(f){n.keysSoFar=f,h(),f!==""&&(n.timer=+setTimeout(()=>{m(""),h()},o))}return m(a),d}var ci=Object.assign(wx,{defaultOptions:{keysSoFar:"",timer:-1},isValidEvent:Ex});function Ex(e){return e.key.length===1&&!e.ctrlKey&&!e.metaKey}function kx(e,t,n){const{signal:r}=t;return[new Promise((s,a)=>{const l=setTimeout(()=>{a(new Error(`Timeout of ${n}ms exceeded`))},n);r.addEventListener("abort",()=>{clearTimeout(l),a(new Error("Promise aborted"))}),e.then(c=>{r.aborted||(clearTimeout(l),s(c))}).catch(c=>{r.aborted||(clearTimeout(l),a(c))})}),()=>t.abort()]}function Ox(e,t){const{timeout:n,rootNode:r}=t,i=Ie(r),o=Ge(r),s=new i.AbortController;return kx(new Promise(a=>{const l=e();if(l){a(l);return}const c=new i.MutationObserver(()=>{const u=e();u&&u.isConnected&&(c.disconnect(),a(u))});c.observe(o.body,{childList:!0,subtree:!0})}),s,n)}var Ix=(...e)=>e.map(t=>{var n;return(n=t==null?void 0:t.trim)==null?void 0:n.call(t)}).filter(Boolean).join(" "),Px=/((?:--)?(?:\w+-?)+)\s*:\s*([^;]*)/g,Tu=e=>{const t={};let n;for(;n=Px.exec(e);)t[n[1]]=n[2];return t},Rx=(e,t)=>{if(ho(e)){if(ho(t))return`${e};${t}`;e=Tu(e)}else ho(t)&&(t=Tu(t));return Object.assign({},e??{},t??{})};function pt(...e){let t={};for(let n of e){for(let r in t){if(r.startsWith("on")&&typeof t[r]=="function"&&typeof n[r]=="function"){t[r]=go(n[r],t[r]);continue}if(r==="className"||r==="class"){t[r]=Ix(t[r],n[r]);continue}if(r==="style"){t[r]=Rx(t[r],n[r]);continue}t[r]=n[r]!==void 0?n[r]:t[r]}for(let r in n)t[r]===void 0&&(t[r]=n[r])}return t}function Nu(e,t,n){let r=[],i;return o=>{const s=e(o);return(s.length!==r.length||s.some((l,c)=>!gt(r[c],l)))&&(r=s,i=t(...s)),i}}function Zt(){return{and:(...e)=>function(n){return e.every(r=>n.guard(r))},or:(...e)=>function(n){return e.some(r=>n.guard(r))},not:e=>function(n){return!n.guard(e)}}}function n5(e){return e}function Au(){return{guards:Zt(),createMachine:e=>e,choose:e=>function({choose:n}){var r;return(r=n(e))==null?void 0:r.actions}}}var pr=(e=>(e.NotStarted="Not Started",e.Started="Started",e.Stopped="Stopped",e))(pr||{}),Pa="__init__";function Tx(e){const t=()=>{var a;return((a=e.getRootNode)==null?void 0:a.call(e))??document},n=()=>Ge(t()),r=()=>n().defaultView??window,i=()=>xu(t());return{...e,getRootNode:t,getDoc:n,getWin:r,getActiveElement:i,isActiveElement:a=>a===i(),getById:a=>t().getElementById(a)}}function Ro(...e){return t=>{const n=[];for(const r of e)if(typeof r=="function"){const i=r(t);typeof i=="function"&&n.push(i)}else r&&(r.current=t);if(n.length)return()=>{for(const r of n)r()}}}function Nx(e){var r,i;let t=(r=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:r.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=(i=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:i.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}const Ra=e=>{const t=E.memo(E.forwardRef((n,r)=>{const{asChild:i,children:o,...s}=n;if(!i)return E.createElement(e,{...s,ref:r},o);if(!E.isValidElement(o))return null;const a=E.Children.only(o),l=Nx(a);return E.cloneElement(a,{...pt(s,a.props),ref:r?Ro(r,l):l})}));return t.displayName=e.displayName||e.name,t},en=(()=>{const e=new Map;return new Proxy(Ra,{apply(t,n,r){return Ra(r[0])},get(t,n){const r=n;return e.has(r)||e.set(r,Ra(r)),e.get(r)}})})(),[i5,Ax]=hr({name:"LocaleContext",hookName:"useLocaleContext",providerName:"",strict:!1,defaultValue:{dir:"ltr",locale:"en-US"}}),_u=()=>(e,t)=>t.reduce((n,r)=>{const[i,o]=n,s=r;return o[s]!==void 0&&(i[s]=o[s]),delete o[s],[i,o]},[{},{...e}]),Vu=e=>_u()(e,["immediate","lazyMount","onExitComplete","present","skipAnimationOnMount","unmountOnExit"]);function _x(e){return new Proxy({},{get(t,n){return n==="style"?r=>e({style:r}).style:e}})}var U=()=>e=>Array.from(new Set(e));function Vx(e,t){const{state:n,send:r,context:i}=e,o=n.matches("mounted","unmountSuspended");return{skip:!i.get("initial"),present:o,setNode(s){s&&r({type:"NODE.SET",node:s})},unmount(){r({type:"UNMOUNT"})}}}var Fx={props({props:e}){return{...e,present:!!e.present}},initialState({prop:e}){return e("present")?"mounted":"unmounted"},refs(){return{node:null,styles:null}},context({bindable:e}){return{unmountAnimationName:e(()=>({defaultValue:null})),prevAnimationName:e(()=>({defaultValue:null})),present:e(()=>({defaultValue:!1})),initial:e(()=>({sync:!0,defaultValue:!1}))}},exit:["clearInitial","cleanupNode"],watch({track:e,prop:t,send:n}){e([()=>t("present")],()=>{n({type:"PRESENCE.CHANGED"})})},on:{"NODE.SET":{actions:["setupNode"]},"PRESENCE.CHANGED":{actions:["setInitial","syncPresence"]}},states:{mounted:{on:{UNMOUNT:{target:"unmounted",actions:["clearPrevAnimationName","invokeOnExitComplete"]},"UNMOUNT.SUSPEND":{target:"unmountSuspended"}}},unmountSuspended:{effects:["trackAnimationEvents"],on:{MOUNT:{target:"mounted",actions:["setPrevAnimationName"]},UNMOUNT:{target:"unmounted",actions:["clearPrevAnimationName","invokeOnExitComplete"]}}},unmounted:{on:{MOUNT:{target:"mounted",actions:["setPrevAnimationName"]}}}},implementations:{actions:{setInitial:({context:e})=>{e.get("initial")||queueMicrotask(()=>{e.set("initial",!0)})},clearInitial:({context:e})=>{e.set("initial",!1)},invokeOnExitComplete:({prop:e})=>{var t;(t=e("onExitComplete"))==null||t()},setupNode:({refs:e,event:t})=>{e.get("node")!==t.node&&(e.set("node",t.node),e.set("styles",bo(t.node)))},cleanupNode:({refs:e})=>{e.set("node",null),e.set("styles",null)},syncPresence:({context:e,refs:t,send:n,prop:r})=>{const i=r("present");if(i)return n({type:"MOUNT",src:"presence.changed"});const o=t.get("node");if(!i&&(o==null?void 0:o.ownerDocument.visibilityState)==="hidden")return n({type:"UNMOUNT",src:"visibilitychange"});Z(()=>{var a,l;const s=To(t.get("styles"));e.set("unmountAnimationName",s),s==="none"||s===e.get("prevAnimationName")||((a=t.get("styles"))==null?void 0:a.display)==="none"||((l=t.get("styles"))==null?void 0:l.animationDuration)==="0s"?n({type:"UNMOUNT",src:"presence.changed"}):n({type:"UNMOUNT.SUSPEND"})})},setPrevAnimationName:({context:e,refs:t})=>{Z(()=>{e.set("prevAnimationName",To(t.get("styles")))})},clearPrevAnimationName:({context:e})=>{e.set("prevAnimationName",null)}},effects:{trackAnimationEvents:({context:e,refs:t,send:n})=>{const r=t.get("node");if(!r)return;const i=a=>{var c,u;(((u=(c=a.composedPath)==null?void 0:c.call(a))==null?void 0:u[0])??a.target)===r&&e.set("prevAnimationName",To(t.get("styles")))},o=a=>{const l=To(t.get("styles"));tt(a)===r&&l===e.get("unmountAnimationName")&&n({type:"UNMOUNT",src:"animationend"})};r.addEventListener("animationstart",i),r.addEventListener("animationcancel",o),r.addEventListener("animationend",o);const s=Po(r,{animationFillMode:"forwards"});return()=>{r.removeEventListener("animationstart",i),r.removeEventListener("animationcancel",o),r.removeEventListener("animationend",o),wa(()=>s())}}}}};function To(e){return(e==null?void 0:e.animationName)||"none"}U()(["onExitComplete","present","immediate"]);var Fu=typeof globalThis.document<"u"?E.useLayoutEffect:E.useEffect;function No(e){const t=e().value??e().defaultValue,n=e().isEqual??Object.is,[r]=E.useState(t),[i,o]=E.useState(r),s=e().value!==void 0,a=E.useRef(i);a.current=s?e().value:i;const l=E.useRef(a.current);Fu(()=>{l.current=a.current},[i,e().value]);const c=d=>{var f,g;const h=l.current,m=Pn(d)?d(h):d;e().debug&&console.log(`[bindable > ${e().debug}] setValue`,{next:m,prev:h}),s||o(m),n(m,h)||(g=(f=e()).onChange)==null||g.call(f,m,h)};function u(){return s?e().value:i}return{initial:r,ref:a,get:u,set(d){(e().sync?te.flushSync:r0)(()=>c(d))},invoke(d,h){var m,f;(f=(m=e()).onChange)==null||f.call(m,d,h)},hash(d){var h,m;return((m=(h=e()).hash)==null?void 0:m.call(h,d))??String(d)}}}No.cleanup=e=>{E.useEffect(()=>e,[])},No.ref=e=>{const t=E.useRef(e);return{get:()=>t.current,set:n=>{t.current=n}}};function Lx(e){const t=E.useRef(e);return{get(n){return t.current[n]},set(n,r){t.current[n]=r}}}var Dx=(e,t)=>{const n=E.useRef(!1),r=E.useRef(!1);E.useEffect(()=>{if(n.current&&r.current)return t();r.current=!0},[...(e??[]).map(i=>typeof i=="function"?i():i)]),E.useEffect(()=>(n.current=!0,()=>{n.current=!1}),[])};function Lu(e,t={}){var j,I,F,Y;const n=E.useMemo(()=>{const{id:z,ids:V,getRootNode:B}=t;return Tx({id:z,ids:V,getRootNode:B})},[t]),r=(...z)=>{e.debug&&console.log(...z)},i=((j=e.props)==null?void 0:j.call(e,{props:mo(t),scope:n}))??t,o=zx(i),s=(I=e.context)==null?void 0:I.call(e,{prop:o,bindable:No,scope:n,flush:zu,getContext(){return l},getComputed(){return w},getRefs(){return g},getEvent(){return m()}}),a=Du(s),l={get(z){var V;return(V=a.current)==null?void 0:V[z].ref.current},set(z,V){var B;(B=a.current)==null||B[z].set(V)},initial(z){var V;return(V=a.current)==null?void 0:V[z].initial},hash(z){var B,K;const V=(B=a.current)==null?void 0:B[z].get();return(K=a.current)==null?void 0:K[z].hash(V)}},c=E.useRef(new Map),u=E.useRef(null),d=E.useRef(null),h=E.useRef({type:""}),m=()=>({...h.current,current(){return h.current},previous(){return d.current}}),f=()=>({...P,matches(...z){return z.includes(P.ref.current)},hasTag(z){var V,B;return!!((B=(V=e.states[P.ref.current])==null?void 0:V.tags)!=null&&B.includes(z))}}),g=Lx(((F=e.refs)==null?void 0:F.call(e,{prop:o,context:l}))??{}),p=()=>({state:f(),context:l,event:m(),prop:o,send:T,action:v,guard:x,track:Dx,refs:g,computed:w,flush:zu,scope:n,choose:C}),v=z=>{const V=Pn(z)?z(p()):z;if(!V)return;const B=V.map(K=>{var H,X;const $=(X=(H=e.implementations)==null?void 0:H.actions)==null?void 0:X[K];return $||ai(`[zag-js] No implementation found for action "${JSON.stringify(K)}"`),$});for(const K of B)K==null||K(p())},x=z=>{var V,B;return Pn(z)?z(p()):(B=(V=e.implementations)==null?void 0:V.guards)==null?void 0:B[z](p())},S=z=>{const V=Pn(z)?z(p()):z;if(!V)return;const B=V.map($=>{var X,ue;const H=(ue=(X=e.implementations)==null?void 0:X.effects)==null?void 0:ue[$];return H||ai(`[zag-js] No implementation found for effect "${JSON.stringify($)}"`),H}),K=[];for(const $ of B){const H=$==null?void 0:$(p());H&&K.push(H)}return()=>K.forEach($=>$==null?void 0:$())},C=z=>uo(z).find(V=>{let B=!V.guard;return ho(V.guard)?B=!!x(V.guard):Pn(V.guard)&&(B=V.guard(p())),B}),w=z=>{gu(e.computed,()=>"[zag-js] No computed object found on machine");const V=e.computed[z];return V({context:l,event:m(),prop:o,refs:g,scope:n,computed:w})},P=No(()=>({defaultValue:e.initialState({prop:o}),onChange(z,V){var K,$,H,X;if(V){const ue=c.current.get(V);ue==null||ue(),c.current.delete(V)}V&&v((K=e.states[V])==null?void 0:K.exit),v(($=u.current)==null?void 0:$.actions);const B=S((H=e.states[z])==null?void 0:H.effects);if(B&&c.current.set(z,B),V===Pa){v(e.entry);const ue=S(e.effects);ue&&c.current.set(Pa,ue)}v((X=e.states[z])==null?void 0:X.entry)}})),_=E.useRef(void 0),R=E.useRef(pr.NotStarted);Fu(()=>{queueMicrotask(()=>{const B=R.current===pr.Started;R.current=pr.Started,r(B?"rehydrating...":"initializing...");const K=_.current??P.initial;P.invoke(K,B?P.get():Pa)});const z=c.current,V=P.ref.current;return()=>{r("unmounting..."),_.current=V,R.current=pr.Stopped,z.forEach(B=>B==null?void 0:B()),c.current=new Map,u.current=null,queueMicrotask(()=>{v(e.exit)})}},[]);const N=()=>"ref"in P?P.ref.current:P.get(),T=z=>{queueMicrotask(()=>{var X,ue;if(R.current!==pr.Started)return;d.current=h.current,h.current=z;let V=N();const B=((X=e.states[V].on)==null?void 0:X[z.type])??((ue=e.on)==null?void 0:ue[z.type]),K=C(B);if(!K)return;u.current=K;const $=K.target??V;r("transition",z.type,K.target||V,`(${K.actions})`);const H=$!==V;H?te.flushSync(()=>P.set($)):K.reenter&&!H?P.invoke(V,V):v(K.actions??[])})};return(Y=e.watch)==null||Y.call(e,p()),{state:f(),send:T,context:l,prop:o,scope:n,refs:g,computed:w,event:m(),getStatus:()=>R.current}}function Du(e){const t=E.useRef(e);return t.current=e,t}function zx(e){const t=Du(e);return function(r){return t.current[r]}}function zu(e){queueMicrotask(()=>{te.flushSync(()=>e())})}var Mx=_x(e=>e);function $x(e,t={}){const{sync:n=!1}=t,r=Bx(e);return E.useCallback((...i)=>{var o;return n?queueMicrotask(()=>{var s;return(s=r.current)==null?void 0:s.call(r,...i)}):(o=r.current)==null?void 0:o.call(r,...i)},[n,r])}function Bx(e){const t=E.useRef(e);return t.current=e,t}const Ta=(e={})=>{const{lazyMount:t,unmountOnExit:n,present:r,skipAnimationOnMount:i=!1,...o}=e,s=E.useRef(!1),a={...o,present:r,onExitComplete:$x(e.onExitComplete)},l=Lu(Fx,a),c=Vx(l);c.present&&(s.current=!0);const u=!c.present&&!s.current&&t||n&&!c.present&&s.current,d=()=>({"data-state":c.skip&&i?void 0:r?"open":"closed",hidden:!c.present});return{ref:c.setNode,getPresenceProps:d,present:c.present,unmounted:u}},[Mu,Na]=hr({name:"PresenceContext",hookName:"usePresenceContext",providerName:""}),Ao=Oe("span"),{withContext:jx}=ii({key:"text"}),Wx=jx("p");function $u(e,t=[]){const n=E.useRef(()=>{throw new Error("Cannot call an event handler while rendering.")});return E.useInsertionEffect(()=>{n.current=e}),E.useCallback((...r)=>{var i;return(i=n.current)==null?void 0:i.call(n,...r)},t)}function Hx(e={}){const t=$u(e.onOpen),n=$u(e.onClose),[r,i]=E.useState(e.defaultOpen||!1),o=e.open!==void 0?e.open:r,s=e.open!==void 0,a=E.useCallback(()=>{s||i(!1),n==null||n()},[s,n]),l=E.useCallback(()=>{s||i(!0),t==null||t()},[s,t]),c=E.useCallback(()=>{o?a():l()},[o,l,a]);return{open:o,onOpen:l,onClose:a,onToggle:c,setOpen:i}}var G=(e,t=[])=>({parts:(...n)=>{if(Ux(t))return G(e,n);throw new Error("createAnatomy().parts(...) should only be called once. Did you mean to use .extendWith(...) ?")},extendWith:(...n)=>G(e,[...t,...n]),omit:(...n)=>G(e,t.filter(r=>!n.includes(r))),rename:n=>G(n,t),keys:()=>t,build:()=>[...new Set(t)].reduce((n,r)=>Object.assign(n,{[r]:{selector:[`&[data-scope="${mr(e)}"][data-part="${mr(r)}"]`,`& [data-scope="${mr(e)}"][data-part="${mr(r)}"]`].join(", "),attrs:{"data-scope":mr(e),"data-part":mr(r)}}}),{})}),mr=e=>e.replace(/([A-Z])([A-Z])/g,"$1-$2").replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase(),Ux=e=>e.length===0,Bu=G("collapsible").parts("root","trigger","content","indicator");Bu.build(),U()(["dir","disabled","getRootNode","id","ids","onExitComplete","onOpenChange","defaultOpen","open"]);var Gx=Object.defineProperty,qx=(e,t,n)=>t in e?Gx(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Aa=(e,t,n)=>qx(e,t+"",n),Kx=(e,t)=>{if(Object.keys(e).length!==Object.keys(t).length)return!1;for(let n in e)if(e[n]!==t[n])return!1;return!0},_a=class{toHexInt(){return this.toFormat("rgba").toHexInt()}getChannelValue(e){if(e in this)return this[e];throw new Error("Unsupported color channel: "+e)}getChannelValuePercent(e,t){const n=t??this.getChannelValue(e),{minValue:r,maxValue:i}=this.getChannelRange(e);return p0(n,r,i)}getChannelPercentValue(e,t){const{minValue:n,maxValue:r,step:i}=this.getChannelRange(e),o=m0(t,n,r,i);return du(o,n,r,i)}withChannelValue(e,t){const{minValue:n,maxValue:r}=this.getChannelRange(e);if(e in this){let i=this.clone();return i[e]=Ue(t,n,r),i}throw new Error("Unsupported color channel: "+e)}getColorAxes(e){let{xChannel:t,yChannel:n}=e,r=t||this.getChannels().find(s=>s!==n),i=n||this.getChannels().find(s=>s!==r),o=this.getChannels().find(s=>s!==r&&s!==i);return{xChannel:r,yChannel:i,zChannel:o}}incrementChannel(e,t){const{minValue:n,maxValue:r,step:i}=this.getChannelRange(e),o=du(Ue(this.getChannelValue(e)+t,n,r),n,r,i);return this.withChannelValue(e,o)}decrementChannel(e,t){return this.incrementChannel(e,-t)}isEqual(e){return Kx(this.toJSON(),e.toJSON())&&this.getChannelValue("alpha")===e.getChannelValue("alpha")}},Xx=/^#[\da-f]+$/i,Yx=/^rgba?\((.*)\)$/,Qx=/[^#]/gi,ju=class js extends _a{constructor(t,n,r,i){super(),this.red=t,this.green=n,this.blue=r,this.alpha=i}static parse(t){let n=[];if(Xx.test(t)&&[4,5,7,9].includes(t.length)){const i=(t.length<6?t.replace(Qx,"$&$&"):t).slice(1).split("");for(;i.length>0;)n.push(parseInt(i.splice(0,2).join(""),16));n[3]=n[3]!==void 0?n[3]/255:void 0}const r=t.match(Yx);return r!=null&&r[1]&&(n=r[1].split(",").map(i=>Number(i.trim())).map((i,o)=>Ue(i,0,o<3?255:1))),n.length<3?void 0:new js(n[0],n[1],n[2],n[3]??1)}toString(t){switch(t){case"hex":return"#"+(this.red.toString(16).padStart(2,"0")+this.green.toString(16).padStart(2,"0")+this.blue.toString(16).padStart(2,"0")).toUpperCase();case"hexa":return"#"+(this.red.toString(16).padStart(2,"0")+this.green.toString(16).padStart(2,"0")+this.blue.toString(16).padStart(2,"0")+Math.round(this.alpha*255).toString(16).padStart(2,"0")).toUpperCase();case"rgb":return`rgb(${this.red}, ${this.green}, ${this.blue})`;case"css":case"rgba":return`rgba(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`;case"hsl":return this.toHSL().toString("hsl");case"hsb":return this.toHSB().toString("hsb");default:return this.toFormat(t).toString(t)}}toFormat(t){switch(t){case"rgba":return this;case"hsba":return this.toHSB();case"hsla":return this.toHSL();default:throw new Error("Unsupported color conversion: rgb -> "+t)}}toHexInt(){return this.red<<16|this.green<<8|this.blue}toHSB(){const t=this.red/255,n=this.green/255,r=this.blue/255,i=Math.min(t,n,r),o=Math.max(t,n,r),s=o-i,a=o===0?0:s/o;let l=0;if(s!==0){switch(o){case t:l=(n-r)/s+(nNumber(a.trim().replace("%","")));return new Ws(cu(r,360),Ue(i,0,100),Ue(o,0,100),Ue(s??1,0,1))}}toString(t){switch(t){case"hex":return this.toRGB().toString("hex");case"hexa":return this.toRGB().toString("hexa");case"hsl":return`hsl(${this.hue}, ${ce(this.saturation,2)}%, ${ce(this.lightness,2)}%)`;case"css":case"hsla":return`hsla(${this.hue}, ${ce(this.saturation,2)}%, ${ce(this.lightness,2)}%, ${this.alpha})`;case"hsb":return this.toHSB().toString("hsb");case"rgb":return this.toRGB().toString("rgb");default:return this.toFormat(t).toString(t)}}toFormat(t){switch(t){case"hsla":return this;case"hsba":return this.toHSB();case"rgba":return this.toRGB();default:throw new Error("Unsupported color conversion: hsl -> "+t)}}toHSB(){let t=this.saturation/100,n=this.lightness/100,r=n+t*Math.min(n,1-n);return t=r===0?0:2*(1-n/r),new La(ce(this.hue,2),ce(t*100,2),ce(r*100,2),ce(this.alpha,2))}toRGB(){let t=this.hue,n=this.saturation/100,r=this.lightness/100,i=n*Math.min(r,1-r),o=(s,a=(s+t/30)%12)=>r-i*Math.max(Math.min(a-3,9-a,1),-1);return new Va(Math.round(o(0)*255),Math.round(o(8)*255),Math.round(o(4)*255),ce(this.alpha,2))}clone(){return new Ws(this.hue,this.saturation,this.lightness,this.alpha)}getChannelFormatOptions(t){switch(t){case"hue":return{style:"unit",unit:"degree",unitDisplay:"narrow"};case"saturation":case"lightness":case"alpha":return{style:"percent"};default:throw new Error("Unknown color channel: "+t)}}formatChannelValue(t,n){let r=this.getChannelFormatOptions(t),i=this.getChannelValue(t);return(t==="saturation"||t==="lightness")&&(i/=100),new Intl.NumberFormat(n,r).format(i)}getChannelRange(t){switch(t){case"hue":return{minValue:0,maxValue:360,step:1,pageSize:15};case"saturation":case"lightness":return{minValue:0,maxValue:100,step:1,pageSize:10};case"alpha":return{minValue:0,maxValue:1,step:.01,pageSize:.1};default:throw new Error("Unknown color channel: "+t)}}toJSON(){return{h:this.hue,s:this.saturation,l:this.lightness,a:this.alpha}}getFormat(){return"hsla"}getChannels(){return Ws.colorChannels}};Aa(Wu,"colorChannels",["hue","saturation","lightness"]);var Fa=Wu,Zx=/hsb\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%)\)|hsba\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d(.\d+)?)\)/,Hu=class Hs extends _a{constructor(t,n,r,i){super(),this.hue=t,this.saturation=n,this.brightness=r,this.alpha=i}static parse(t){let n;if(n=t.match(Zx)){const[r,i,o,s]=(n[1]??n[2]).split(",").map(a=>Number(a.trim().replace("%","")));return new Hs(cu(r,360),Ue(i,0,100),Ue(o,0,100),Ue(s??1,0,1))}}toString(t){switch(t){case"css":return this.toHSL().toString("css");case"hex":return this.toRGB().toString("hex");case"hexa":return this.toRGB().toString("hexa");case"hsb":return`hsb(${this.hue}, ${ce(this.saturation,2)}%, ${ce(this.brightness,2)}%)`;case"hsba":return`hsba(${this.hue}, ${ce(this.saturation,2)}%, ${ce(this.brightness,2)}%, ${this.alpha})`;case"hsl":return this.toHSL().toString("hsl");case"rgb":return this.toRGB().toString("rgb");default:return this.toFormat(t).toString(t)}}toFormat(t){switch(t){case"hsba":return this;case"hsla":return this.toHSL();case"rgba":return this.toRGB();default:throw new Error("Unsupported color conversion: hsb -> "+t)}}toHSL(){let t=this.saturation/100,n=this.brightness/100,r=n*(1-t/2);return t=r===0||r===1?0:(n-r)/Math.min(r,1-r),new Fa(ce(this.hue,2),ce(t*100,2),ce(r*100,2),ce(this.alpha,2))}toRGB(){let t=this.hue,n=this.saturation/100,r=this.brightness/100,i=(o,s=(o+t/60)%6)=>r-n*r*Math.max(Math.min(s,4-s,1),0);return new Va(Math.round(i(5)*255),Math.round(i(3)*255),Math.round(i(1)*255),ce(this.alpha,2))}clone(){return new Hs(this.hue,this.saturation,this.brightness,this.alpha)}getChannelFormatOptions(t){switch(t){case"hue":return{style:"unit",unit:"degree",unitDisplay:"narrow"};case"saturation":case"brightness":case"alpha":return{style:"percent"};default:throw new Error("Unknown color channel: "+t)}}formatChannelValue(t,n){let r=this.getChannelFormatOptions(t),i=this.getChannelValue(t);return(t==="saturation"||t==="brightness")&&(i/=100),new Intl.NumberFormat(n,r).format(i)}getChannelRange(t){switch(t){case"hue":return{minValue:0,maxValue:360,step:1,pageSize:15};case"saturation":case"brightness":return{minValue:0,maxValue:100,step:1,pageSize:10};case"alpha":return{minValue:0,maxValue:1,step:.01,pageSize:.1};default:throw new Error("Unknown color channel: "+t)}}toJSON(){return{h:this.hue,s:this.saturation,b:this.brightness,a:this.alpha}}getFormat(){return"hsba"}getChannels(){return Hs.colorChannels}};Aa(Hu,"colorChannels",["hue","saturation","brightness"]);var La=Hu,e1="aliceblue:f0f8ff,antiquewhite:faebd7,aqua:00ffff,aquamarine:7fffd4,azure:f0ffff,beige:f5f5dc,bisque:ffe4c4,black:000000,blanchedalmond:ffebcd,blue:0000ff,blueviolet:8a2be2,brown:a52a2a,burlywood:deb887,cadetblue:5f9ea0,chartreuse:7fff00,chocolate:d2691e,coral:ff7f50,cornflowerblue:6495ed,cornsilk:fff8dc,crimson:dc143c,cyan:00ffff,darkblue:00008b,darkcyan:008b8b,darkgoldenrod:b8860b,darkgray:a9a9a9,darkgreen:006400,darkkhaki:bdb76b,darkmagenta:8b008b,darkolivegreen:556b2f,darkorange:ff8c00,darkorchid:9932cc,darkred:8b0000,darksalmon:e9967a,darkseagreen:8fbc8f,darkslateblue:483d8b,darkslategray:2f4f4f,darkturquoise:00ced1,darkviolet:9400d3,deeppink:ff1493,deepskyblue:00bfff,dimgray:696969,dodgerblue:1e90ff,firebrick:b22222,floralwhite:fffaf0,forestgreen:228b22,fuchsia:ff00ff,gainsboro:dcdcdc,ghostwhite:f8f8ff,gold:ffd700,goldenrod:daa520,gray:808080,green:008000,greenyellow:adff2f,honeydew:f0fff0,hotpink:ff69b4,indianred:cd5c5c,indigo:4b0082,ivory:fffff0,khaki:f0e68c,lavender:e6e6fa,lavenderblush:fff0f5,lawngreen:7cfc00,lemonchiffon:fffacd,lightblue:add8e6,lightcoral:f08080,lightcyan:e0ffff,lightgoldenrodyellow:fafad2,lightgrey:d3d3d3,lightgreen:90ee90,lightpink:ffb6c1,lightsalmon:ffa07a,lightseagreen:20b2aa,lightskyblue:87cefa,lightslategray:778899,lightsteelblue:b0c4de,lightyellow:ffffe0,lime:00ff00,limegreen:32cd32,linen:faf0e6,magenta:ff00ff,maroon:800000,mediumaquamarine:66cdaa,mediumblue:0000cd,mediumorchid:ba55d3,mediumpurple:9370d8,mediumseagreen:3cb371,mediumslateblue:7b68ee,mediumspringgreen:00fa9a,mediumturquoise:48d1cc,mediumvioletred:c71585,midnightblue:191970,mintcream:f5fffa,mistyrose:ffe4e1,moccasin:ffe4b5,navajowhite:ffdead,navy:000080,oldlace:fdf5e6,olive:808000,olivedrab:6b8e23,orange:ffa500,orangered:ff4500,orchid:da70d6,palegoldenrod:eee8aa,palegreen:98fb98,paleturquoise:afeeee,palevioletred:d87093,papayawhip:ffefd5,peachpuff:ffdab9,peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple:800080,rebeccapurple:663399,red:ff0000,rosybrown:bc8f8f,royalblue:4169e1,saddlebrown:8b4513,salmon:fa8072,sandybrown:f4a460,seagreen:2e8b57,seashell:fff5ee,sienna:a0522d,silver:c0c0c0,skyblue:87ceeb,slateblue:6a5acd,slategray:708090,snow:fffafa,springgreen:00ff7f,steelblue:4682b4,tan:d2b48c,teal:008080,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32",t1=e=>{const t=new Map,n=e.split(",");for(let r=0;r{var n;if(Uu.has(e))return _o(Uu.get(e));const t=Va.parse(e)||La.parse(e)||Fa.parse(e);if(!t){const r=new Error("Invalid color value: "+e);throw(n=Error.captureStackTrace)==null||n.call(Error,r,_o),r}return t};const n1=["top","right","bottom","left"],tn=Math.min,nt=Math.max,Vo=Math.round,Fo=Math.floor,It=e=>({x:e,y:e}),r1={left:"right",right:"left",bottom:"top",top:"bottom"},i1={start:"end",end:"start"};function Da(e,t,n){return nt(e,tn(t,n))}function $t(e,t){return typeof e=="function"?e(t):e}function Bt(e){return e.split("-")[0]}function vr(e){return e.split("-")[1]}function za(e){return e==="x"?"y":"x"}function Ma(e){return e==="y"?"height":"width"}const o1=new Set(["top","bottom"]);function Pt(e){return o1.has(Bt(e))?"y":"x"}function $a(e){return za(Pt(e))}function s1(e,t,n){n===void 0&&(n=!1);const r=vr(e),i=$a(e),o=Ma(i);let s=i==="x"?r===(n?"end":"start")?"right":"left":r==="start"?"bottom":"top";return t.reference[o]>t.floating[o]&&(s=Lo(s)),[s,Lo(s)]}function a1(e){const t=Lo(e);return[Ba(e),t,Ba(t)]}function Ba(e){return e.replace(/start|end/g,t=>i1[t])}const Gu=["left","right"],qu=["right","left"],l1=["top","bottom"],c1=["bottom","top"];function u1(e,t,n){switch(e){case"top":case"bottom":return n?t?qu:Gu:t?Gu:qu;case"left":case"right":return t?l1:c1;default:return[]}}function d1(e,t,n,r){const i=vr(e);let o=u1(Bt(e),n==="start",r);return i&&(o=o.map(s=>s+"-"+i),t&&(o=o.concat(o.map(Ba)))),o}function Lo(e){return e.replace(/left|right|bottom|top/g,t=>r1[t])}function h1(e){return{top:0,right:0,bottom:0,left:0,...e}}function Ku(e){return typeof e!="number"?h1(e):{top:e,right:e,bottom:e,left:e}}function Do(e){const{x:t,y:n,width:r,height:i}=e;return{width:r,height:i,top:n,left:t,right:t+r,bottom:n+i,x:t,y:n}}function Xu(e,t,n){let{reference:r,floating:i}=e;const o=Pt(t),s=$a(t),a=Ma(s),l=Bt(t),c=o==="y",u=r.x+r.width/2-i.width/2,d=r.y+r.height/2-i.height/2,h=r[a]/2-i[a]/2;let m;switch(l){case"top":m={x:u,y:r.y-i.height};break;case"bottom":m={x:u,y:r.y+r.height};break;case"right":m={x:r.x+r.width,y:d};break;case"left":m={x:r.x-i.width,y:d};break;default:m={x:r.x,y:r.y}}switch(vr(t)){case"start":m[s]-=h*(n&&c?-1:1);break;case"end":m[s]+=h*(n&&c?-1:1);break}return m}const f1=async(e,t,n)=>{const{placement:r="bottom",strategy:i="absolute",middleware:o=[],platform:s}=n,a=o.filter(Boolean),l=await(s.isRTL==null?void 0:s.isRTL(t));let c=await s.getElementRects({reference:e,floating:t,strategy:i}),{x:u,y:d}=Xu(c,r,l),h=r,m={},f=0;for(let g=0;g({name:"arrow",options:e,async fn(t){const{x:n,y:r,placement:i,rects:o,platform:s,elements:a,middlewareData:l}=t,{element:c,padding:u=0}=$t(e,t)||{};if(c==null)return{};const d=Ku(u),h={x:n,y:r},m=$a(i),f=Ma(m),g=await s.getDimensions(c),p=m==="y",v=p?"top":"left",x=p?"bottom":"right",S=p?"clientHeight":"clientWidth",C=o.reference[f]+o.reference[m]-h[m]-o.floating[f],w=h[m]-o.reference[m],P=await(s.getOffsetParent==null?void 0:s.getOffsetParent(c));let _=P?P[S]:0;(!_||!await(s.isElement==null?void 0:s.isElement(P)))&&(_=a.floating[S]||o.floating[f]);const R=C/2-w/2,N=_/2-g[f]/2-1,T=tn(d[v],N),j=tn(d[x],N),I=T,F=_-g[f]-j,Y=_/2-g[f]/2+R,z=Da(I,Y,F),V=!l.arrow&&vr(i)!=null&&Y!==z&&o.reference[f]/2-(YY<=0)){var j,I;const Y=(((j=o.flip)==null?void 0:j.index)||0)+1,z=_[Y];if(z&&(!(d==="alignment"?x!==Pt(z):!1)||T.every(K=>Pt(K.placement)===x?K.overflows[0]>0:!0)))return{data:{index:Y,overflows:T},reset:{placement:z}};let V=(I=T.filter(B=>B.overflows[0]<=0).sort((B,K)=>B.overflows[1]-K.overflows[1])[0])==null?void 0:I.placement;if(!V)switch(m){case"bestFit":{var F;const B=(F=T.filter(K=>{if(P){const $=Pt(K.placement);return $===x||$==="y"}return!0}).map(K=>[K.placement,K.overflows.filter($=>$>0).reduce(($,H)=>$+H,0)]).sort((K,$)=>K[1]-$[1])[0])==null?void 0:F[0];B&&(V=B);break}case"initialPlacement":V=a;break}if(i!==V)return{reset:{placement:V}}}return{}}}};function Yu(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function Qu(e){return n1.some(t=>e[t]>=0)}const m1=function(e){return e===void 0&&(e={}),{name:"hide",options:e,async fn(t){const{rects:n}=t,{strategy:r="referenceHidden",...i}=$t(e,t);switch(r){case"referenceHidden":{const o=await ui(t,{...i,elementContext:"reference"}),s=Yu(o,n.reference);return{data:{referenceHiddenOffsets:s,referenceHidden:Qu(s)}}}case"escaped":{const o=await ui(t,{...i,altBoundary:!0}),s=Yu(o,n.floating);return{data:{escapedOffsets:s,escaped:Qu(s)}}}default:return{}}}}},Ju=new Set(["left","top"]);async function v1(e,t){const{placement:n,platform:r,elements:i}=e,o=await(r.isRTL==null?void 0:r.isRTL(i.floating)),s=Bt(n),a=vr(n),l=Pt(n)==="y",c=Ju.has(s)?-1:1,u=o&&l?-1:1,d=$t(t,e);let{mainAxis:h,crossAxis:m,alignmentAxis:f}=typeof d=="number"?{mainAxis:d,crossAxis:0,alignmentAxis:null}:{mainAxis:d.mainAxis||0,crossAxis:d.crossAxis||0,alignmentAxis:d.alignmentAxis};return a&&typeof f=="number"&&(m=a==="end"?f*-1:f),l?{x:m*u,y:h*c}:{x:h*c,y:m*u}}const b1=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var n,r;const{x:i,y:o,placement:s,middlewareData:a}=t,l=await v1(t,e);return s===((n=a.offset)==null?void 0:n.placement)&&(r=a.arrow)!=null&&r.alignmentOffset?{}:{x:i+l.x,y:o+l.y,data:{...l,placement:s}}}}},y1=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){const{x:n,y:r,placement:i}=t,{mainAxis:o=!0,crossAxis:s=!1,limiter:a={fn:p=>{let{x:v,y:x}=p;return{x:v,y:x}}},...l}=$t(e,t),c={x:n,y:r},u=await ui(t,l),d=Pt(Bt(i)),h=za(d);let m=c[h],f=c[d];if(o){const p=h==="y"?"top":"left",v=h==="y"?"bottom":"right",x=m+u[p],S=m-u[v];m=Da(x,m,S)}if(s){const p=d==="y"?"top":"left",v=d==="y"?"bottom":"right",x=f+u[p],S=f-u[v];f=Da(x,f,S)}const g=a.fn({...t,[h]:m,[d]:f});return{...g,data:{x:g.x-n,y:g.y-r,enabled:{[h]:o,[d]:s}}}}}},x1=function(e){return e===void 0&&(e={}),{options:e,fn(t){const{x:n,y:r,placement:i,rects:o,middlewareData:s}=t,{offset:a=0,mainAxis:l=!0,crossAxis:c=!0}=$t(e,t),u={x:n,y:r},d=Pt(i),h=za(d);let m=u[h],f=u[d];const g=$t(a,t),p=typeof g=="number"?{mainAxis:g,crossAxis:0}:{mainAxis:0,crossAxis:0,...g};if(l){const S=h==="y"?"height":"width",C=o.reference[h]-o.floating[S]+p.mainAxis,w=o.reference[h]+o.reference[S]-p.mainAxis;mw&&(m=w)}if(c){var v,x;const S=h==="y"?"width":"height",C=Ju.has(Bt(i)),w=o.reference[d]-o.floating[S]+(C&&((v=s.offset)==null?void 0:v[d])||0)+(C?0:p.crossAxis),P=o.reference[d]+o.reference[S]+(C?0:((x=s.offset)==null?void 0:x[d])||0)-(C?p.crossAxis:0);fP&&(f=P)}return{[h]:m,[d]:f}}}},C1=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){var n,r;const{placement:i,rects:o,platform:s,elements:a}=t,{apply:l=()=>{},...c}=$t(e,t),u=await ui(t,c),d=Bt(i),h=vr(i),m=Pt(i)==="y",{width:f,height:g}=o.floating;let p,v;d==="top"||d==="bottom"?(p=d,v=h===(await(s.isRTL==null?void 0:s.isRTL(a.floating))?"start":"end")?"left":"right"):(v=d,p=h==="end"?"top":"bottom");const x=g-u.top-u.bottom,S=f-u.left-u.right,C=tn(g-u[p],x),w=tn(f-u[v],S),P=!t.middlewareData.shift;let _=C,R=w;if((n=t.middlewareData.shift)!=null&&n.enabled.x&&(R=S),(r=t.middlewareData.shift)!=null&&r.enabled.y&&(_=x),P&&!h){const T=nt(u.left,0),j=nt(u.right,0),I=nt(u.top,0),F=nt(u.bottom,0);m?R=f-2*(T!==0||j!==0?T+j:nt(u.left,u.right)):_=g-2*(I!==0||F!==0?I+F:nt(u.top,u.bottom))}await l({...t,availableWidth:R,availableHeight:_});const N=await s.getDimensions(a.floating);return f!==N.width||g!==N.height?{reset:{rects:!0}}:{}}}};function zo(){return typeof window<"u"}function br(e){return Zu(e)?(e.nodeName||"").toLowerCase():"#document"}function rt(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function Rt(e){var t;return(t=(Zu(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function Zu(e){return zo()?e instanceof Node||e instanceof rt(e).Node:!1}function mt(e){return zo()?e instanceof Element||e instanceof rt(e).Element:!1}function Tt(e){return zo()?e instanceof HTMLElement||e instanceof rt(e).HTMLElement:!1}function ed(e){return!zo()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof rt(e).ShadowRoot}const S1=new Set(["inline","contents"]);function di(e){const{overflow:t,overflowX:n,overflowY:r,display:i}=vt(e);return/auto|scroll|overlay|hidden|clip/.test(t+r+n)&&!S1.has(i)}const w1=new Set(["table","td","th"]);function E1(e){return w1.has(br(e))}const k1=[":popover-open",":modal"];function Mo(e){return k1.some(t=>{try{return e.matches(t)}catch{return!1}})}const O1=["transform","translate","scale","rotate","perspective"],I1=["transform","translate","scale","rotate","perspective","filter"],P1=["paint","layout","strict","content"];function ja(e){const t=Wa(),n=mt(e)?vt(e):e;return O1.some(r=>n[r]?n[r]!=="none":!1)||(n.containerType?n.containerType!=="normal":!1)||!t&&(n.backdropFilter?n.backdropFilter!=="none":!1)||!t&&(n.filter?n.filter!=="none":!1)||I1.some(r=>(n.willChange||"").includes(r))||P1.some(r=>(n.contain||"").includes(r))}function R1(e){let t=nn(e);for(;Tt(t)&&!yr(t);){if(ja(t))return t;if(Mo(t))return null;t=nn(t)}return null}function Wa(){return typeof CSS>"u"||!CSS.supports?!1:CSS.supports("-webkit-backdrop-filter","none")}const T1=new Set(["html","body","#document"]);function yr(e){return T1.has(br(e))}function vt(e){return rt(e).getComputedStyle(e)}function $o(e){return mt(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function nn(e){if(br(e)==="html")return e;const t=e.assignedSlot||e.parentNode||ed(e)&&e.host||Rt(e);return ed(t)?t.host:t}function td(e){const t=nn(e);return yr(t)?e.ownerDocument?e.ownerDocument.body:e.body:Tt(t)&&di(t)?t:td(t)}function hi(e,t,n){var r;t===void 0&&(t=[]),n===void 0&&(n=!0);const i=td(e),o=i===((r=e.ownerDocument)==null?void 0:r.body),s=rt(i);if(o){const a=Ha(s);return t.concat(s,s.visualViewport||[],di(i)?i:[],a&&n?hi(a):[])}return t.concat(i,hi(i,[],n))}function Ha(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function nd(e){const t=vt(e);let n=parseFloat(t.width)||0,r=parseFloat(t.height)||0;const i=Tt(e),o=i?e.offsetWidth:n,s=i?e.offsetHeight:r,a=Vo(n)!==o||Vo(r)!==s;return a&&(n=o,r=s),{width:n,height:r,$:a}}function Ua(e){return mt(e)?e:e.contextElement}function xr(e){const t=Ua(e);if(!Tt(t))return It(1);const n=t.getBoundingClientRect(),{width:r,height:i,$:o}=nd(t);let s=(o?Vo(n.width):n.width)/r,a=(o?Vo(n.height):n.height)/i;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}const N1=It(0);function rd(e){const t=rt(e);return!Wa()||!t.visualViewport?N1:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function A1(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==rt(e)?!1:t}function Nn(e,t,n,r){t===void 0&&(t=!1),n===void 0&&(n=!1);const i=e.getBoundingClientRect(),o=Ua(e);let s=It(1);t&&(r?mt(r)&&(s=xr(r)):s=xr(e));const a=A1(o,n,r)?rd(o):It(0);let l=(i.left+a.x)/s.x,c=(i.top+a.y)/s.y,u=i.width/s.x,d=i.height/s.y;if(o){const h=rt(o),m=r&&mt(r)?rt(r):r;let f=h,g=Ha(f);for(;g&&r&&m!==f;){const p=xr(g),v=g.getBoundingClientRect(),x=vt(g),S=v.left+(g.clientLeft+parseFloat(x.paddingLeft))*p.x,C=v.top+(g.clientTop+parseFloat(x.paddingTop))*p.y;l*=p.x,c*=p.y,u*=p.x,d*=p.y,l+=S,c+=C,f=rt(g),g=Ha(f)}}return Do({width:u,height:d,x:l,y:c})}function Bo(e,t){const n=$o(e).scrollLeft;return t?t.left+n:Nn(Rt(e)).left+n}function id(e,t){const n=e.getBoundingClientRect(),r=n.left+t.scrollLeft-Bo(e,n),i=n.top+t.scrollTop;return{x:r,y:i}}function _1(e){let{elements:t,rect:n,offsetParent:r,strategy:i}=e;const o=i==="fixed",s=Rt(r),a=t?Mo(t.floating):!1;if(r===s||a&&o)return n;let l={scrollLeft:0,scrollTop:0},c=It(1);const u=It(0),d=Tt(r);if((d||!d&&!o)&&((br(r)!=="body"||di(s))&&(l=$o(r)),Tt(r))){const m=Nn(r);c=xr(r),u.x=m.x+r.clientLeft,u.y=m.y+r.clientTop}const h=s&&!d&&!o?id(s,l):It(0);return{width:n.width*c.x,height:n.height*c.y,x:n.x*c.x-l.scrollLeft*c.x+u.x+h.x,y:n.y*c.y-l.scrollTop*c.y+u.y+h.y}}function V1(e){return Array.from(e.getClientRects())}function F1(e){const t=Rt(e),n=$o(e),r=e.ownerDocument.body,i=nt(t.scrollWidth,t.clientWidth,r.scrollWidth,r.clientWidth),o=nt(t.scrollHeight,t.clientHeight,r.scrollHeight,r.clientHeight);let s=-n.scrollLeft+Bo(e);const a=-n.scrollTop;return vt(r).direction==="rtl"&&(s+=nt(t.clientWidth,r.clientWidth)-i),{width:i,height:o,x:s,y:a}}const od=25;function L1(e,t){const n=rt(e),r=Rt(e),i=n.visualViewport;let o=r.clientWidth,s=r.clientHeight,a=0,l=0;if(i){o=i.width,s=i.height;const u=Wa();(!u||u&&t==="fixed")&&(a=i.offsetLeft,l=i.offsetTop)}const c=Bo(r);if(c<=0){const u=r.ownerDocument,d=u.body,h=getComputedStyle(d),m=u.compatMode==="CSS1Compat"&&parseFloat(h.marginLeft)+parseFloat(h.marginRight)||0,f=Math.abs(r.clientWidth-d.clientWidth-m);f<=od&&(o-=f)}else c<=od&&(o+=c);return{width:o,height:s,x:a,y:l}}const D1=new Set(["absolute","fixed"]);function z1(e,t){const n=Nn(e,!0,t==="fixed"),r=n.top+e.clientTop,i=n.left+e.clientLeft,o=Tt(e)?xr(e):It(1),s=e.clientWidth*o.x,a=e.clientHeight*o.y,l=i*o.x,c=r*o.y;return{width:s,height:a,x:l,y:c}}function sd(e,t,n){let r;if(t==="viewport")r=L1(e,n);else if(t==="document")r=F1(Rt(e));else if(mt(t))r=z1(t,n);else{const i=rd(e);r={x:t.x-i.x,y:t.y-i.y,width:t.width,height:t.height}}return Do(r)}function ad(e,t){const n=nn(e);return n===t||!mt(n)||yr(n)?!1:vt(n).position==="fixed"||ad(n,t)}function M1(e,t){const n=t.get(e);if(n)return n;let r=hi(e,[],!1).filter(a=>mt(a)&&br(a)!=="body"),i=null;const o=vt(e).position==="fixed";let s=o?nn(e):e;for(;mt(s)&&!yr(s);){const a=vt(s),l=ja(s);!l&&a.position==="fixed"&&(i=null),(o?!l&&!i:!l&&a.position==="static"&&!!i&&D1.has(i.position)||di(s)&&!l&&ad(e,s))?r=r.filter(u=>u!==s):i=a,s=nn(s)}return t.set(e,r),r}function $1(e){let{element:t,boundary:n,rootBoundary:r,strategy:i}=e;const s=[...n==="clippingAncestors"?Mo(t)?[]:M1(t,this._c):[].concat(n),r],a=s[0],l=s.reduce((c,u)=>{const d=sd(t,u,i);return c.top=nt(d.top,c.top),c.right=tn(d.right,c.right),c.bottom=tn(d.bottom,c.bottom),c.left=nt(d.left,c.left),c},sd(t,a,i));return{width:l.right-l.left,height:l.bottom-l.top,x:l.left,y:l.top}}function B1(e){const{width:t,height:n}=nd(e);return{width:t,height:n}}function j1(e,t,n){const r=Tt(t),i=Rt(t),o=n==="fixed",s=Nn(e,!0,o,t);let a={scrollLeft:0,scrollTop:0};const l=It(0);function c(){l.x=Bo(i)}if(r||!r&&!o)if((br(t)!=="body"||di(i))&&(a=$o(t)),r){const m=Nn(t,!0,o,t);l.x=m.x+t.clientLeft,l.y=m.y+t.clientTop}else i&&c();o&&!r&&i&&c();const u=i&&!r&&!o?id(i,a):It(0),d=s.left+a.scrollLeft-l.x-u.x,h=s.top+a.scrollTop-l.y-u.y;return{x:d,y:h,width:s.width,height:s.height}}function Ga(e){return vt(e).position==="static"}function ld(e,t){if(!Tt(e)||vt(e).position==="fixed")return null;if(t)return t(e);let n=e.offsetParent;return Rt(e)===n&&(n=n.ownerDocument.body),n}function cd(e,t){const n=rt(e);if(Mo(e))return n;if(!Tt(e)){let i=nn(e);for(;i&&!yr(i);){if(mt(i)&&!Ga(i))return i;i=nn(i)}return n}let r=ld(e,t);for(;r&&E1(r)&&Ga(r);)r=ld(r,t);return r&&yr(r)&&Ga(r)&&!ja(r)?n:r||R1(e)||n}const W1=async function(e){const t=this.getOffsetParent||cd,n=this.getDimensions,r=await n(e.floating);return{reference:j1(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:r.width,height:r.height}}};function H1(e){return vt(e).direction==="rtl"}const U1={convertOffsetParentRelativeRectToViewportRelativeRect:_1,getDocumentElement:Rt,getClippingRect:$1,getOffsetParent:cd,getElementRects:W1,getClientRects:V1,getDimensions:B1,getScale:xr,isElement:mt,isRTL:H1};function ud(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function G1(e,t){let n=null,r;const i=Rt(e);function o(){var a;clearTimeout(r),(a=n)==null||a.disconnect(),n=null}function s(a,l){a===void 0&&(a=!1),l===void 0&&(l=1),o();const c=e.getBoundingClientRect(),{left:u,top:d,width:h,height:m}=c;if(a||t(),!h||!m)return;const f=Fo(d),g=Fo(i.clientWidth-(u+h)),p=Fo(i.clientHeight-(d+m)),v=Fo(u),S={rootMargin:-f+"px "+-g+"px "+-p+"px "+-v+"px",threshold:nt(0,tn(1,l))||1};let C=!0;function w(P){const _=P[0].intersectionRatio;if(_!==l){if(!C)return s();_?s(!1,_):r=setTimeout(()=>{s(!1,1e-7)},1e3)}_===1&&!ud(c,e.getBoundingClientRect())&&s(),C=!1}try{n=new IntersectionObserver(w,{...S,root:i.ownerDocument})}catch{n=new IntersectionObserver(w,S)}n.observe(e)}return s(!0),o}function q1(e,t,n,r){r===void 0&&(r={});const{ancestorScroll:i=!0,ancestorResize:o=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:l=!1}=r,c=Ua(e),u=i||o?[...c?hi(c):[],...hi(t)]:[];u.forEach(v=>{i&&v.addEventListener("scroll",n,{passive:!0}),o&&v.addEventListener("resize",n)});const d=c&&a?G1(c,n):null;let h=-1,m=null;s&&(m=new ResizeObserver(v=>{let[x]=v;x&&x.target===c&&m&&(m.unobserve(t),cancelAnimationFrame(h),h=requestAnimationFrame(()=>{var S;(S=m)==null||S.observe(t)})),n()}),c&&!l&&m.observe(c),m.observe(t));let f,g=l?Nn(e):null;l&&p();function p(){const v=Nn(e);g&&!ud(g,v)&&n(),g=v,f=requestAnimationFrame(p)}return n(),()=>{var v;u.forEach(x=>{i&&x.removeEventListener("scroll",n),o&&x.removeEventListener("resize",n)}),d==null||d(),(v=m)==null||v.disconnect(),m=null,l&&cancelAnimationFrame(f)}}const K1=b1,X1=y1,Y1=p1,Q1=C1,J1=m1,Z1=g1,eC=x1,tC=(e,t,n)=>{const r=new Map,i={platform:U1,...n},o={...i.platform,_c:r};return f1(e,t,{...i,platform:o})};function dd(e=0,t=0,n=0,r=0){if(typeof DOMRect=="function")return new DOMRect(e,t,n,r);const i={x:e,y:t,width:n,height:r,top:t,right:e+n,bottom:t+r,left:e};return{...i,toJSON:()=>i}}function nC(e){if(!e)return dd();const{x:t,y:n,width:r,height:i}=e;return dd(t,n,r,i)}function rC(e,t){return{contextElement:Me(e)?e:void 0,getBoundingClientRect:()=>{const n=e,r=t==null?void 0:t(n);return r||!n?nC(r):n.getBoundingClientRect()}}}var hd=e=>({variable:e,reference:`var(${e})`}),fd={transformOrigin:hd("--transform-origin"),arrowOffset:hd("--arrow-offset")},iC=e=>e==="top"||e==="bottom"?"y":"x";function oC(e,t){return{name:"transformOrigin",fn(n){var N,T,j,I;const{elements:r,middlewareData:i,placement:o,rects:s,y:a}=n,l=o.split("-")[0],c=iC(l),u=((N=i.arrow)==null?void 0:N.x)||0,d=((T=i.arrow)==null?void 0:T.y)||0,h=(t==null?void 0:t.clientWidth)||0,m=(t==null?void 0:t.clientHeight)||0,f=u+h/2,g=d+m/2,p=Math.abs(((j=i.shift)==null?void 0:j.y)||0),v=s.reference.height/2,x=m/2,S=((I=e.offset)==null?void 0:I.mainAxis)??e.gutter,C=typeof S=="number"?S+x:S??x,w=p>C,P={top:`${f}px calc(100% + ${C}px)`,bottom:`${f}px ${-C}px`,left:`calc(100% + ${C}px) ${g}px`,right:`${-C}px ${g}px`}[l],_=`${f}px ${s.reference.y+v-a}px`,R=!!e.overlap&&c==="y"&&w;return r.floating.style.setProperty(fd.transformOrigin.variable,R?_:P),{data:{transformOrigin:R?_:P}}}}}var sC={name:"rects",fn({rects:e}){return{data:e}}},aC=e=>{if(e)return{name:"shiftArrow",fn({placement:t,middlewareData:n}){if(!n.arrow)return{};const{x:r,y:i}=n.arrow,o=t.split("-")[0];return Object.assign(e.style,{left:r!=null?`${r}px`:"",top:i!=null?`${i}px`:"",[o]:`calc(100% + ${fd.arrowOffset.reference})`}),{}}}};function lC(e){const[t,n]=e.split("-");return{side:t,align:n,hasAlign:n!=null}}function cC(e){return e.split("-")[0]}var uC={strategy:"absolute",placement:"bottom",listeners:!0,gutter:8,flip:!0,slide:!0,overlap:!1,sameWidth:!1,fitViewport:!1,overflowPadding:8,arrowPadding:4};function gd(e,t){const n=e.devicePixelRatio||1;return Math.round(t*n)/n}function qa(e){return typeof e=="function"?e():e==="clipping-ancestors"?"clippingAncestors":e}function dC(e,t,n){const r=e||t.createElement("div");return Z1({element:r,padding:n.arrowPadding})}function hC(e,t){if(!Yy(t.offset??t.gutter))return K1(({placement:n})=>{var c,u;const r=((e==null?void 0:e.clientHeight)||0)/2,i=((c=t.offset)==null?void 0:c.mainAxis)??t.gutter,o=typeof i=="number"?i+r:i??r,{hasAlign:s}=lC(n),a=s?void 0:t.shift,l=((u=t.offset)==null?void 0:u.crossAxis)??a;return mo({crossAxis:l,mainAxis:o,alignmentAxis:t.shift})})}function fC(e){if(!e.flip)return;const t=qa(e.boundary);return Y1({...t?{boundary:t}:void 0,padding:e.overflowPadding,fallbackPlacements:e.flip===!0?void 0:e.flip})}function gC(e){if(!e.slide&&!e.overlap)return;const t=qa(e.boundary);return X1({...t?{boundary:t}:void 0,mainAxis:e.slide,crossAxis:e.overlap,padding:e.overflowPadding,limiter:eC()})}function pC(e){return Q1({padding:e.overflowPadding,apply({elements:t,rects:n,availableHeight:r,availableWidth:i}){const o=t.floating,s=Math.round(n.reference.width),a=Math.round(n.reference.height);i=Math.floor(i),r=Math.floor(r),o.style.setProperty("--reference-width",`${s}px`),o.style.setProperty("--reference-height",`${a}px`),o.style.setProperty("--available-width",`${i}px`),o.style.setProperty("--available-height",`${r}px`)}})}function mC(e){if(e.hideWhenDetached)return J1({strategy:"referenceHidden",boundary:qa(e.boundary)??"clippingAncestors"})}function vC(e){return e?e===!0?{ancestorResize:!0,ancestorScroll:!0,elementResize:!0,layoutShift:!0}:e:{}}function bC(e,t,n={}){const r=rC(e,n.getAnchorRect);if(!t||!r)return;const i=Object.assign({},uC,n),o=t.querySelector("[data-part=arrow]"),s=[hC(o,i),fC(i),gC(i),dC(o,t.ownerDocument,i),aC(o),oC({gutter:i.gutter,offset:i.offset,overlap:i.overlap},o),pC(i),mC(i),sC],{placement:a,strategy:l,onComplete:c,onPositioned:u}=i,d=async()=>{var C;if(!r||!t)return;const g=await tC(r,t,{placement:a,middleware:s,strategy:l});c==null||c(g),u==null||u({placed:!0});const p=Ie(t),v=gd(p,g.x),x=gd(p,g.y);t.style.setProperty("--x",`${v}px`),t.style.setProperty("--y",`${x}px`),i.hideWhenDetached&&(((C=g.middlewareData.hide)==null?void 0:C.referenceHidden)?(t.style.setProperty("visibility","hidden"),t.style.setProperty("pointer-events","none")):(t.style.removeProperty("visibility"),t.style.removeProperty("pointer-events")));const S=t.firstElementChild;if(S){const w=bo(S);t.style.setProperty("--z-index",w.zIndex)}},h=async()=>{n.updatePosition?(await n.updatePosition({updatePosition:d,floatingElement:t}),u==null||u({placed:!0})):await d()},m=vC(i.listeners),f=i.listeners?q1(r,t,h,m):i0;return h(),()=>{f==null||f(),u==null||u({placed:!1})}}function bt(e,t,n={}){const{defer:r,...i}=n,o=r?Z:a=>a(),s=[];return s.push(o(()=>{const a=typeof e=="function"?e():e,l=typeof t=="function"?t():t;s.push(bC(a,l,i))})),()=>{s.forEach(a=>a==null?void 0:a())}}function yC(e){const t={each(n){var r;for(let i=0;i<((r=e.frames)==null?void 0:r.length);i+=1){const o=e.frames[i];o&&n(o)}},addEventListener(n,r,i){return t.each(o=>{try{o.document.addEventListener(n,r,i)}catch{}}),()=>{try{t.removeEventListener(n,r,i)}catch{}}},removeEventListener(n,r,i){t.each(o=>{try{o.document.removeEventListener(n,r,i)}catch{}})}};return t}function xC(e){const t=e.frameElement!=null?e.parent:null;return{addEventListener:(n,r,i)=>{try{t==null||t.addEventListener(n,r,i)}catch{}return()=>{try{t==null||t.removeEventListener(n,r,i)}catch{}}},removeEventListener:(n,r,i)=>{try{t==null||t.removeEventListener(n,r,i)}catch{}}}}var pd="pointerdown.outside",md="focus.outside";function CC(e){for(const t of e)if(Me(t)&&Jt(t))return!0;return!1}var vd=e=>"clientY"in e;function SC(e,t){if(!vd(t)||!e)return!1;const n=e.getBoundingClientRect();return n.width===0||n.height===0?!1:n.top<=t.clientY&&t.clientY<=n.top+n.height&&n.left<=t.clientX&&t.clientX<=n.left+n.width}function wC(e,t){return e.y<=t.y&&t.y<=e.y+e.height&&e.x<=t.x&&t.x<=e.x+e.width}function bd(e,t){if(!t||!vd(e))return!1;const n=t.scrollHeight>t.clientHeight,r=n&&e.clientX>t.offsetLeft+t.clientWidth,i=t.scrollWidth>t.clientWidth,o=i&&e.clientY>t.offsetTop+t.clientHeight,s={x:t.offsetLeft,y:t.offsetTop,width:t.clientWidth+(n?16:0),height:t.clientHeight+(i?16:0)},a={x:e.clientX,y:e.clientY};return wC(s,a)?r||o:!1}function EC(e,t){const{exclude:n,onFocusOutside:r,onPointerDownOutside:i,onInteractOutside:o,defer:s}=t;if(!e)return;const a=Ge(e),l=Ie(e),c=yC(l),u=xC(l);function d(x,S){if(!Me(S)||!S.isConnected||Rn(e,S)||SC(e,x))return!1;const C=a.querySelector(`[aria-controls="${e.id}"]`);if(C){const P=Eo(C);if(bd(x,P))return!1}const w=Eo(e);return bd(x,w)?!1:!(n!=null&&n(S))}const h=new Set,m=fr(e==null?void 0:e.getRootNode());function f(x){function S(C){var R;const w=s&&!Su()?Z:N=>N(),P=C??x,_=((R=P==null?void 0:P.composedPath)==null?void 0:R.call(P))??[P==null?void 0:P.target];w(()=>{const N=m?_[0]:tt(x);if(!(!e||!d(x,N))){if(i||o){const T=go(i,o);e.addEventListener(pd,T,{once:!0})}yd(e,pd,{bubbles:!1,cancelable:!0,detail:{originalEvent:P,contextmenu:G0(P),focusable:CC(_),target:N}})}})}x.pointerType==="touch"?(h.forEach(C=>C()),h.add(he(a,"click",S,{once:!0})),h.add(u.addEventListener("click",S,{once:!0})),h.add(c.addEventListener("click",S,{once:!0}))):S()}const g=new Set,p=setTimeout(()=>{g.add(he(a,"pointerdown",f,!0)),g.add(u.addEventListener("pointerdown",f,!0)),g.add(c.addEventListener("pointerdown",f,!0))},0);function v(x){(s?Z:C=>C())(()=>{const C=tt(x);if(!(!e||!d(x,C))){if(r||o){const w=go(r,o);e.addEventListener(md,w,{once:!0})}yd(e,md,{bubbles:!1,cancelable:!0,detail:{originalEvent:x,contextmenu:!1,focusable:Jt(C),target:C}})}})}return Su()||(g.add(he(a,"focusin",v,!0)),g.add(u.addEventListener("focusin",v,!0)),g.add(c.addEventListener("focusin",v,!0))),()=>{clearTimeout(p),h.forEach(x=>x()),g.forEach(x=>x())}}function kC(e,t){const{defer:n}=t,r=n?Z:o=>o(),i=[];return i.push(r(()=>{const o=typeof e=="function"?e():e;i.push(EC(o,t))})),()=>{i.forEach(o=>o==null?void 0:o())}}function yd(e,t,n){const r=e.ownerDocument.defaultView||window,i=new r.CustomEvent(t,n);return e.dispatchEvent(i)}function OC(e,t){const n=r=>{r.key==="Escape"&&(r.isComposing||t==null||t(r))};return he(Ge(e),"keydown",n,{capture:!0})}var xd="layer:request-dismiss",at={layers:[],branches:[],count(){return this.layers.length},pointerBlockingLayers(){return this.layers.filter(e=>e.pointerBlocking)},topMostPointerBlockingLayer(){return[...this.pointerBlockingLayers()].slice(-1)[0]},hasPointerBlockingLayer(){return this.pointerBlockingLayers().length>0},isBelowPointerBlockingLayer(e){var r;const t=this.indexOf(e),n=this.topMostPointerBlockingLayer()?this.indexOf((r=this.topMostPointerBlockingLayer())==null?void 0:r.node):-1;return tRn(n.node,t))},isInBranch(e){return Array.from(this.branches).some(t=>Rn(t,e))},add(e){this.layers.push(e),this.syncLayerIndex()},addBranch(e){this.branches.push(e)},remove(e){const t=this.indexOf(e);t<0||(tat.dismiss(r.node,e)),this.layers.splice(t,1),this.syncLayerIndex())},removeBranch(e){const t=this.branches.indexOf(e);t>=0&&this.branches.splice(t,1)},syncLayerIndex(){this.layers.forEach((e,t)=>{e.node.style.setProperty("--layer-index",`${t}`)})},indexOf(e){return this.layers.findIndex(t=>t.node===e)},dismiss(e,t){const n=this.indexOf(e);if(n===-1)return;const r=this.layers[n];PC(e,xd,i=>{var o;(o=r.requestDismiss)==null||o.call(r,i),i.defaultPrevented||r==null||r.dismiss()}),IC(e,xd,{originalLayer:e,targetLayer:t,originalIndex:n,targetIndex:t?this.indexOf(t):-1}),this.syncLayerIndex()},clear(){this.remove(this.layers[0].node)}};function IC(e,t,n){const r=e.ownerDocument.defaultView||window,i=new r.CustomEvent(t,{cancelable:!0,bubbles:!0,detail:n});return e.dispatchEvent(i)}function PC(e,t,n){e.addEventListener(t,n,{once:!0})}var Cd;function Sd(){at.layers.forEach(({node:e})=>{e.style.pointerEvents=at.isBelowPointerBlockingLayer(e)?"none":"auto"})}function RC(e){e.style.pointerEvents=""}function TC(e,t){const n=Ge(e),r=[];return at.hasPointerBlockingLayer()&&!n.body.hasAttribute("data-inert")&&(Cd=document.body.style.pointerEvents,queueMicrotask(()=>{n.body.style.pointerEvents="none",n.body.setAttribute("data-inert","")})),t==null||t.forEach(i=>{const[o,s]=Ox(()=>{const a=i();return Me(a)?a:null},{timeout:1e3});o.then(a=>r.push(Po(a,{pointerEvents:"auto"}))),r.push(s)}),()=>{at.hasPointerBlockingLayer()||(queueMicrotask(()=>{n.body.style.pointerEvents=Cd,n.body.removeAttribute("data-inert"),n.body.style.length===0&&n.body.removeAttribute("style")}),r.forEach(i=>i()))}}function NC(e,t){const{warnOnMissingNode:n=!0}=t;if(n&&!e){ai("[@zag-js/dismissable] node is `null` or `undefined`");return}if(!e)return;const{onDismiss:r,onRequestDismiss:i,pointerBlocking:o,exclude:s,debug:a}=t,l={dismiss:r,node:e,pointerBlocking:o,requestDismiss:i};at.add(l),Sd();function c(f){var p,v;const g=tt(f.detail.originalEvent);at.isBelowPointerBlockingLayer(e)||at.isInBranch(g)||((p=t.onPointerDownOutside)==null||p.call(t,f),(v=t.onInteractOutside)==null||v.call(t,f),!f.defaultPrevented&&(a&&console.log("onPointerDownOutside:",f.detail.originalEvent),r==null||r()))}function u(f){var p,v;const g=tt(f.detail.originalEvent);at.isInBranch(g)||((p=t.onFocusOutside)==null||p.call(t,f),(v=t.onInteractOutside)==null||v.call(t,f),!f.defaultPrevented&&(a&&console.log("onFocusOutside:",f.detail.originalEvent),r==null||r()))}function d(f){var g;at.isTopMost(e)&&((g=t.onEscapeKeyDown)==null||g.call(t,f),!f.defaultPrevented&&r&&(f.preventDefault(),r()))}function h(f){var x;if(!e)return!1;const g=typeof s=="function"?s():s,p=Array.isArray(g)?g:[g],v=(x=t.persistentElements)==null?void 0:x.map(S=>S()).filter(Me);return v&&p.push(...v),p.some(S=>Rn(S,f))||at.isInNestedLayer(e,f)}const m=[o?TC(e,t.persistentElements):void 0,OC(e,d),kC(e,{exclude:h,onFocusOutside:u,onPointerDownOutside:c,defer:t.defer})];return()=>{at.remove(e),Sd(),RC(e),m.forEach(f=>f==null?void 0:f())}}function Cr(e,t){const{defer:n}=t,r=n?Z:o=>o(),i=[];return i.push(r(()=>{const o=Pn(e)?e():e;i.push(NC(o,t))})),()=>{i.forEach(o=>o==null?void 0:o())}}var wd=G("color-picker",["root","label","control","trigger","positioner","content","area","areaThumb","valueText","areaBackground","channelSlider","channelSliderLabel","channelSliderTrack","channelSliderThumb","channelSliderValueText","channelInput","transparencyGrid","swatchGroup","swatchTrigger","swatchIndicator","swatch","eyeDropperTrigger","formatTrigger","formatSelect"]);wd.build();var AC=e=>{var t;return((t=e.ids)==null?void 0:t.hiddenInput)??`color-picker:${e.id}:hidden-input`},_C=e=>{var t;return((t=e.ids)==null?void 0:t.control)??`color-picker:${e.id}:control`},VC=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`color-picker:${e.id}:trigger`},FC=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`color-picker:${e.id}:content`},LC=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`color-picker:${e.id}:positioner`},DC=e=>{var t;return((t=e.ids)==null?void 0:t.formatSelect)??`color-picker:${e.id}:format-select`},zC=e=>{var t;return((t=e.ids)==null?void 0:t.area)??`color-picker:${e.id}:area`},MC=e=>{var t;return((t=e.ids)==null?void 0:t.areaThumb)??`color-picker:${e.id}:area-thumb`},$C=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.channelSliderTrack)==null?void 0:r.call(n,t))??`color-picker:${e.id}:slider-track:${t}`},BC=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.channelSliderThumb)==null?void 0:r.call(n,t))??`color-picker:${e.id}:slider-thumb:${t}`},jo=e=>e.getById(FC(e)),jC=e=>e.getById(MC(e)),WC=(e,t)=>e.getById(BC(e,t)),HC=e=>e.getById(DC(e)),Ed=e=>e.getById(AC(e)),UC=e=>e.getById(zC(e)),GC=(e,t,n)=>{const r=UC(e);if(!r)return;const{getPercentValue:i}=Pu(t,r);return{x:i({dir:n,orientation:"horizontal"}),y:i({orientation:"vertical"})}},qC=e=>e.getById(_C(e)),Ka=e=>e.getById(VC(e)),KC=e=>e.getById(LC(e)),XC=(e,t)=>e.getById($C(e,t)),YC=(e,t,n,r)=>{const i=XC(e,n);if(!i)return;const{getPercentValue:o}=Pu(t,i);return{x:o({dir:r,orientation:"horizontal"}),y:o({orientation:"vertical"})}},QC=e=>[...Io(jo(e),"input[data-channel]"),...Io(qC(e),"input[data-channel]")];function JC(e,t){if(t==null)return"";if(t==="hex")return e.toString("hex");if(t==="css")return e.toString("css");if(t in e)return e.getChannelValue(t).toString();const n=e.getFormat()==="hsla";switch(t){case"hue":return n?e.toFormat("hsla").getChannelValue("hue").toString():e.toFormat("hsba").getChannelValue("hue").toString();case"saturation":return n?e.toFormat("hsla").getChannelValue("saturation").toString():e.toFormat("hsba").getChannelValue("saturation").toString();case"lightness":return e.toFormat("hsla").getChannelValue("lightness").toString();case"brightness":return e.toFormat("hsba").getChannelValue("brightness").toString();case"red":case"green":case"blue":return e.toFormat("rgba").getChannelValue(t).toString();default:return e.getChannelValue(t).toString()}}var kd=e=>_o(e),ZC=/^[0-9a-fA-F]{3,8}$/;function eS(e){return ZC.test(e)}function tS(e){return e.startsWith("#")?e:eS(e)?`#${e}`:e}var{and:nS}=Zt();nS("isOpenControlled","closeOnSelect");function Od(e,t,n){const r=QC(e);Z(()=>{r.forEach(i=>{const o=i.dataset.channel;So(i,JC(n||t,o))})})}function rS(e,t){const n=HC(e);n&&Z(()=>So(n,t))}U()(["closeOnSelect","dir","disabled","format","defaultFormat","getRootNode","id","ids","initialFocusEl","inline","name","positioning","onFocusOutside","onFormatChange","onInteractOutside","onOpenChange","onPointerDownOutside","onValueChange","onValueChangeEnd","defaultOpen","open","positioning","required","readOnly","value","defaultValue","invalid","openAutoFocus"]),U()(["xChannel","yChannel"]),U()(["channel","orientation"]),U()(["value","disabled"]),U()(["value","respectAlpha"]),U()(["size"]);const[Id,iS]=hr({name:"RenderStrategyContext",hookName:"useRenderStrategyContext",providerName:""}),Pd=e=>_u()(e,["lazyMount","unmountOnExit"]);var Rd=G("accordion").parts("root","item","itemTrigger","itemContent","itemIndicator");Rd.build();var Td=e=>{var t;return((t=e.ids)==null?void 0:t.root)??`accordion:${e.id}`},Nd=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.itemTrigger)==null?void 0:r.call(n,t))??`accordion:${e.id}:trigger:${t}`},oS=e=>e.getById(Td(e)),Wo=e=>{const n=`[aria-controls][data-ownedby='${CSS.escape(Td(e))}']:not([disabled])`;return Io(oS(e),n)},sS=e=>oi(Wo(e)),aS=e=>ha(Wo(e)),lS=(e,t)=>mx(Wo(e),Nd(e,t)),cS=(e,t)=>vx(Wo(e),Nd(e,t)),{and:uS,not:dS}=Zt();uS("isExpanded","canToggle"),dS("isExpanded"),U()(["collapsible","dir","disabled","getRootNode","id","ids","multiple","onFocusChange","onValueChange","orientation","value","defaultValue"]),U()(["value","disabled"]);var fi=(e,t)=>({x:e,y:t});function hS(e){const{x:t,y:n,width:r,height:i}=e,o=t+r/2,s=n+i/2;return{x:t,y:n,width:r,height:i,minX:t,minY:n,maxX:t+r,maxY:n+i,midX:o,midY:s,center:fi(o,s)}}function fS(e){const t=fi(e.minX,e.minY),n=fi(e.maxX,e.minY),r=fi(e.maxX,e.maxY),i=fi(e.minX,e.maxY);return{top:t,right:n,bottom:r,left:i}}function gS(e,t){const n=hS(e),{top:r,right:i,left:o,bottom:s}=fS(n),[a]=t.split("-");return{top:[o,r,i,s],right:[r,i,s,o],bottom:[r,o,s,i],left:[i,r,o,s]}[a]}function pS(e,t){const{x:n,y:r}=t;let i=!1;for(let o=0,s=e.length-1;or!=u>r&&n<(c-a)*(r-l)/(u-l)+a&&(i=!i)}return i}var Ad=G("avatar").parts("root","image","fallback");Ad.build(),U()(["dir","id","ids","onStatusChange","getRootNode"]);function mS(e){return!(e.metaKey||!Co()&&e.altKey||e.ctrlKey||e.key==="Control"||e.key==="Shift"||e.key==="Meta")}var vS=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);function bS(e,t,n){const r=n?tt(n):null,i=Ie(r);return e=e||r instanceof i.HTMLInputElement&&!vS.has(r==null?void 0:r.type)||r instanceof i.HTMLTextAreaElement||r instanceof i.HTMLElement&&r.isContentEditable,!(e&&t==="keyboard"&&n instanceof i.KeyboardEvent&&!Reflect.has(yS,n.key))}var An=null,Xa=new Set,gi=new Map,_n=!1,Ya=!1,yS={Tab:!0,Escape:!0};function Ho(e,t){for(let n of Xa)n(e,t)}function Uo(e){_n=!0,mS(e)&&(An="keyboard",Ho("keyboard",e))}function lt(e){An="pointer",(e.type==="mousedown"||e.type==="pointerdown")&&(_n=!0,Ho("pointer",e))}function _d(e){U0(e)&&(_n=!0,An="virtual")}function Vd(e){const t=tt(e);t===Ie(t)||t===Ge(t)||(!_n&&!Ya&&(An="virtual",Ho("virtual",e)),_n=!1,Ya=!1)}function Fd(){_n=!1,Ya=!0}function xS(e){if(typeof window>"u"||gi.get(Ie(e)))return;const t=Ie(e),n=Ge(e);let r=t.HTMLElement.prototype.focus;function i(){An="virtual",Ho("virtual",null),_n=!0,r.apply(this,arguments)}Object.defineProperty(t.HTMLElement.prototype,"focus",{configurable:!0,value:i}),n.addEventListener("keydown",Uo,!0),n.addEventListener("keyup",Uo,!0),n.addEventListener("click",_d,!0),t.addEventListener("focus",Vd,!0),t.addEventListener("blur",Fd,!1),typeof t.PointerEvent<"u"?(n.addEventListener("pointerdown",lt,!0),n.addEventListener("pointermove",lt,!0),n.addEventListener("pointerup",lt,!0)):(n.addEventListener("mousedown",lt,!0),n.addEventListener("mousemove",lt,!0),n.addEventListener("mouseup",lt,!0)),t.addEventListener("beforeunload",()=>{CS(e)},{once:!0}),gi.set(t,{focus:r})}var CS=(e,t)=>{const n=Ie(e),r=Ge(e);gi.has(n)&&(n.HTMLElement.prototype.focus=gi.get(n).focus,r.removeEventListener("keydown",Uo,!0),r.removeEventListener("keyup",Uo,!0),r.removeEventListener("click",_d,!0),n.removeEventListener("focus",Vd,!0),n.removeEventListener("blur",Fd,!1),typeof n.PointerEvent<"u"?(r.removeEventListener("pointerdown",lt,!0),r.removeEventListener("pointermove",lt,!0),r.removeEventListener("pointerup",lt,!0)):(r.removeEventListener("mousedown",lt,!0),r.removeEventListener("mousemove",lt,!0),r.removeEventListener("mouseup",lt,!0)),gi.delete(n))};function Ld(){return An==="keyboard"}function SS(e={}){const{isTextInput:t,autoFocus:n,onChange:r,root:i}=e;xS(i),r==null||r({isFocusVisible:n||Ld(),modality:An});const o=(s,a)=>{bS(!!t,s,a)&&(r==null||r({isFocusVisible:Ld(),modality:s}))};return Xa.add(o),()=>{Xa.delete(o)}}var Dd=G("checkbox").parts("root","label","control","indicator");Dd.build(),U()(["defaultChecked","checked","dir","disabled","form","getRootNode","id","ids","invalid","name","onCheckedChange","readOnly","required","value"]);const wS=Dd.extendWith("group"),[o5,ES]=hr({name:"FieldContext",hookName:"useFieldContext",providerName:"",strict:!1});var zd=G("clipboard").parts("root","control","trigger","indicator","input","label");zd.build(),U()(["getRootNode","id","ids","value","defaultValue","timeout","onStatusChange","onValueChange"]),U()(["copied"]);const kS=wd.extendWith("view");var OS=Object.defineProperty,IS=(e,t,n)=>t in e?OS(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,A=(e,t,n)=>IS(e,typeof t!="symbol"?t+"":t,n),Go={itemToValue(e){return typeof e=="string"?e:In(e)&&Yt(e,"value")?e.value:""},itemToString(e){return typeof e=="string"?e:In(e)&&Yt(e,"label")?e.label:Go.itemToValue(e)},isItemDisabled(e){return In(e)&&Yt(e,"disabled")?!!e.disabled:!1}},qo=class fb{constructor(t){this.options=t,A(this,"items"),A(this,"indexMap",null),A(this,"copy",n=>new fb({...this.options,items:n??[...this.items]})),A(this,"isEqual",n=>gt(this.items,n.items)),A(this,"setItems",n=>this.copy(n)),A(this,"getValues",(n=this.items)=>{const r=[];for(const i of n){const o=this.getItemValue(i);o!=null&&r.push(o)}return r}),A(this,"find",n=>{if(n==null)return null;const r=this.indexOf(n);return r!==-1?this.at(r):null}),A(this,"findMany",n=>{const r=[];for(const i of n){const o=this.find(i);o!=null&&r.push(o)}return r}),A(this,"at",n=>{if(!this.options.groupBy&&!this.options.groupSort)return this.items[n]??null;let r=0;const i=this.group();for(const[,o]of i)for(const s of o){if(r===n)return s;r++}return null}),A(this,"sortFn",(n,r)=>{const i=this.indexOf(n),o=this.indexOf(r);return(i??0)-(o??0)}),A(this,"sort",n=>[...n].sort(this.sortFn.bind(this))),A(this,"getItemValue",n=>{var r,i;return n==null?null:((i=(r=this.options).itemToValue)==null?void 0:i.call(r,n))??Go.itemToValue(n)}),A(this,"getItemDisabled",n=>{var r,i;return n==null?!1:((i=(r=this.options).isItemDisabled)==null?void 0:i.call(r,n))??Go.isItemDisabled(n)}),A(this,"stringifyItem",n=>{var r,i;return n==null?null:((i=(r=this.options).itemToString)==null?void 0:i.call(r,n))??Go.itemToString(n)}),A(this,"stringify",n=>n==null?null:this.stringifyItem(this.find(n))),A(this,"stringifyItems",(n,r=", ")=>{const i=[];for(const o of n){const s=this.stringifyItem(o);s!=null&&i.push(s)}return i.join(r)}),A(this,"stringifyMany",(n,r)=>this.stringifyItems(this.findMany(n),r)),A(this,"has",n=>this.indexOf(n)!==-1),A(this,"hasItem",n=>n==null?!1:this.has(this.getItemValue(n))),A(this,"group",()=>{const{groupBy:n,groupSort:r}=this.options;if(!n)return[["",[...this.items]]];const i=new Map;this.items.forEach((s,a)=>{const l=n(s,a);i.has(l)||i.set(l,[]),i.get(l).push(s)});let o=Array.from(i.entries());return r&&o.sort(([s],[a])=>{if(typeof r=="function")return r(s,a);if(Array.isArray(r)){const l=r.indexOf(s),c=r.indexOf(a);return l===-1?1:c===-1?-1:l-c}return r==="asc"?s.localeCompare(a):r==="desc"?a.localeCompare(s):0}),o}),A(this,"getNextValue",(n,r=1,i=!1)=>{let o=this.indexOf(n);if(o===-1)return null;for(o=i?Math.min(o+r,this.size-1):o+r;o<=this.size&&this.getItemDisabled(this.at(o));)o++;return this.getItemValue(this.at(o))}),A(this,"getPreviousValue",(n,r=1,i=!1)=>{let o=this.indexOf(n);if(o===-1)return null;for(o=i?Math.max(o-r,0):o-r;o>=0&&this.getItemDisabled(this.at(o));)o--;return this.getItemValue(this.at(o))}),A(this,"indexOf",n=>{if(n==null)return-1;if(!this.options.groupBy&&!this.options.groupSort)return this.items.findIndex(r=>this.getItemValue(r)===n);if(!this.indexMap){this.indexMap=new Map;let r=0;const i=this.group();for(const[,o]of i)for(const s of o){const a=this.getItemValue(s);a!=null&&this.indexMap.set(a,r),r++}}return this.indexMap.get(n)??-1}),A(this,"getByText",(n,r)=>{const i=r!=null?this.indexOf(r):-1,o=n.length===1;for(let s=0;s{const{state:i,currentValue:o,timeout:s=350}=r,a=i.keysSoFar+n,c=a.length>1&&Array.from(a).every(f=>f===a[0])?a[0]:a,u=this.getByText(c,o),d=this.getItemValue(u);function h(){clearTimeout(i.timer),i.timer=-1}function m(f){i.keysSoFar=f,h(),f!==""&&(i.timer=+setTimeout(()=>{m(""),h()},s))}return m(a),d}),A(this,"update",(n,r)=>{let i=this.indexOf(n);return i===-1?this:this.copy([...this.items.slice(0,i),r,...this.items.slice(i+1)])}),A(this,"upsert",(n,r,i="append")=>{let o=this.indexOf(n);return o===-1?(i==="append"?this.append:this.prepend)(r):this.copy([...this.items.slice(0,o),r,...this.items.slice(o+1)])}),A(this,"insert",(n,...r)=>this.copy(pi(this.items,n,...r))),A(this,"insertBefore",(n,...r)=>{let i=this.indexOf(n);if(i===-1)if(this.items.length===0)i=0;else return this;return this.copy(pi(this.items,i,...r))}),A(this,"insertAfter",(n,...r)=>{let i=this.indexOf(n);if(i===-1)if(this.items.length===0)i=0;else return this;return this.copy(pi(this.items,i+1,...r))}),A(this,"prepend",(...n)=>this.copy(pi(this.items,0,...n))),A(this,"append",(...n)=>this.copy(pi(this.items,this.items.length,...n))),A(this,"filter",n=>{const r=this.items.filter((i,o)=>n(this.stringifyItem(i),o,i));return this.copy(r)}),A(this,"remove",(...n)=>{const r=n.map(i=>typeof i=="string"?i:this.getItemValue(i));return this.copy(this.items.filter(i=>{const o=this.getItemValue(i);return o==null?!1:!r.includes(o)}))}),A(this,"move",(n,r)=>{const i=this.indexOf(n);return i===-1?this:this.copy(Ko(this.items,[i],r))}),A(this,"moveBefore",(n,...r)=>{let i=this.items.findIndex(s=>this.getItemValue(s)===n);if(i===-1)return this;let o=r.map(s=>this.items.findIndex(a=>this.getItemValue(a)===s)).sort((s,a)=>s-a);return this.copy(Ko(this.items,o,i))}),A(this,"moveAfter",(n,...r)=>{let i=this.items.findIndex(s=>this.getItemValue(s)===n);if(i===-1)return this;let o=r.map(s=>this.items.findIndex(a=>this.getItemValue(a)===s)).sort((s,a)=>s-a);return this.copy(Ko(this.items,o,i+1))}),A(this,"reorder",(n,r)=>this.copy(Ko(this.items,[n],r))),A(this,"compareValue",(n,r)=>{const i=this.indexOf(n),o=this.indexOf(r);return io?1:0}),A(this,"range",(n,r)=>{let i=[],o=n;for(;o!=null;){if(this.find(o)&&i.push(o),o===r)return i;o=this.getNextValue(o)}return[]}),A(this,"getValueRange",(n,r)=>n&&r?this.compareValue(n,r)<=0?this.range(n,r):this.range(r,n):[]),A(this,"toString",()=>{let n="";for(const r of this.items){const i=this.getItemValue(r),o=this.stringifyItem(r),s=this.getItemDisabled(r),a=[i,o,s].filter(Boolean).join(":");n+=a+","}return n}),A(this,"toJSON",()=>({size:this.size,first:this.firstValue,last:this.lastValue})),this.items=[...t.items]}get size(){return this.items.length}get firstValue(){let t=0;for(;this.getItemDisabled(this.at(t));)t++;return this.getItemValue(this.at(t))}get lastValue(){let t=this.size-1;for(;this.getItemDisabled(this.at(t));)t--;return this.getItemValue(this.at(t))}*[Symbol.iterator](){yield*this.items}},PS=(e,t)=>!!(e!=null&&e.toLowerCase().startsWith(t.toLowerCase()));function pi(e,t,...n){return[...e.slice(0,t),...n,...e.slice(t)]}function Ko(e,t,n){t=[...t].sort((i,o)=>i-o);const r=t.map(i=>e[i]);for(let i=t.length-1;i>=0;i--)e=[...e.slice(0,t[i]),...e.slice(t[i]+1)];return n=Math.max(0,n-t.filter(i=>it[n])return 1}return e.length-t.length}function TS(e){return e.sort($d)}function NS(e,t){let n;return it(e,{...t,onEnter:(r,i)=>{if(t.predicate(r,i))return n=r,"stop"}}),n}function AS(e,t){const n=[];return it(e,{onEnter:(r,i)=>{t.predicate(r,i)&&n.push(r)},getChildren:t.getChildren}),n}function Bd(e,t){let n;return it(e,{onEnter:(r,i)=>{if(t.predicate(r,i))return n=[...i],"stop"},getChildren:t.getChildren}),n}function _S(e,t){let n=t.initialResult;return it(e,{...t,onEnter:(r,i)=>{n=t.nextResult(n,r,i)}}),n}function VS(e,t){return _S(e,{...t,initialResult:[],nextResult:(n,r,i)=>(n.push(...t.transform(r,i)),n)})}function FS(e,t){const{predicate:n,create:r,getChildren:i}=t,o=(s,a)=>{const l=i(s,a),c=[];l.forEach((m,f)=>{const g=[...a,f],p=o(m,g);p&&c.push(p)});const u=a.length===0,d=n(s,a),h=c.length>0;return u||d||h?r(s,c,a):null};return o(e,[])||r(e,[],[])}function LS(e,t){const n=[];let r=0;const i=new Map,o=new Map;return it(e,{getChildren:t.getChildren,onEnter:(s,a)=>{i.has(s)||i.set(s,r++);const l=t.getChildren(s,a);l.forEach(m=>{o.has(m)||o.set(m,s),i.has(m)||i.set(m,r++)});const c=l.length>0?l.map(m=>i.get(m)):void 0,u=o.get(s),d=u?i.get(u):void 0,h=i.get(s);n.push({...s,_children:c,_parent:d,_index:h})}}),n}function DS(e,t){return{type:"insert",index:e,nodes:t}}function zS(e){return{type:"remove",indexes:e}}function Qa(){return{type:"replace"}}function jd(e){return[e.slice(0,-1),e[e.length-1]]}function Wd(e,t,n=new Map){var s;const[r,i]=jd(e);for(let a=r.length-1;a>=0;a--){const l=r.slice(0,a).join();switch((s=n.get(l))==null?void 0:s.type){case"remove":continue}n.set(l,Qa())}const o=n.get(r.join());switch(o==null?void 0:o.type){case"remove":n.set(r.join(),{type:"removeThenInsert",removeIndexes:o.indexes,insertIndex:i,insertNodes:t});break;default:n.set(r.join(),DS(i,t))}return n}function Hd(e){const t=new Map,n=new Map;for(const r of e){const i=r.slice(0,-1).join(),o=n.get(i)??[];o.push(r[r.length-1]),n.set(i,o.sort((s,a)=>s-a))}for(const r of e)for(let i=r.length-2;i>=0;i--){const o=r.slice(0,i).join();t.has(o)||t.set(o,Qa())}for(const[r,i]of n)t.set(r,zS(i));return t}function MS(e,t){const n=new Map,[r,i]=jd(e);for(let o=r.length-1;o>=0;o--){const s=r.slice(0,o).join();n.set(s,Qa())}return n.set(r.join(),{type:"removeThenInsert",removeIndexes:[i],insertIndex:i,insertNodes:[t]}),n}function Xo(e,t,n){return $S(e,{...n,getChildren:(r,i)=>{const o=i.join(),s=t.get(o);switch(s==null?void 0:s.type){case"replace":case"remove":case"removeThenInsert":case"insert":return n.getChildren(r,i);default:return[]}},transform:(r,i,o)=>{const s=o.join(),a=t.get(s);switch(a==null?void 0:a.type){case"remove":return n.create(r,i.filter((u,d)=>!a.indexes.includes(d)),o);case"removeThenInsert":const l=i.filter((u,d)=>!a.removeIndexes.includes(d)),c=a.removeIndexes.reduce((u,d)=>d{const o=[0,...i],s=o.join(),a=t.transform(r,n[s]??[],i),l=o.slice(0,-1).join(),c=n[l]??[];c.push(a),n[l]=c}}),n[""][0]}function BS(e,t){const{nodes:n,at:r}=t;if(r.length===0)throw new Error("Can't insert nodes at the root");const i=Wd(r,n);return Xo(e,i,t)}function jS(e,t){if(t.at.length===0)return t.node;const n=MS(t.at,t.node);return Xo(e,n,t)}function WS(e,t){if(t.indexPaths.length===0)return e;for(const r of t.indexPaths)if(r.length===0)throw new Error("Can't remove the root node");const n=Hd(t.indexPaths);return Xo(e,n,t)}function HS(e,t){if(t.indexPaths.length===0)return e;for(const o of t.indexPaths)if(o.length===0)throw new Error("Can't move the root node");if(t.to.length===0)throw new Error("Can't move nodes to the root");const n=RS(t.indexPaths),r=n.map(o=>Md(e,o,t)),i=Wd(t.to,r,Hd(n));return Xo(e,i,t)}function it(e,t){const{onEnter:n,onLeave:r,getChildren:i}=t;let o=[],s=[{node:e}];const a=t.reuseIndexPath?()=>o:()=>o.slice();for(;s.length>0;){let l=s[s.length-1];if(l.state===void 0){const u=n==null?void 0:n(l.node,a());if(u==="stop")return;l.state=u==="skip"?-1:0}const c=l.children||i(l.node,a());if(l.children||(l.children=c),l.state!==-1){if(l.stategt(this.rootNode,n.rootNode)),A(this,"getNodeChildren",n=>{var r,i;return((i=(r=this.options).nodeToChildren)==null?void 0:i.call(r,n))??Sr.nodeToChildren(n)??[]}),A(this,"resolveIndexPath",n=>typeof n=="string"?this.getIndexPath(n):n),A(this,"resolveNode",n=>{const r=this.resolveIndexPath(n);return r?this.at(r):void 0}),A(this,"getNodeChildrenCount",n=>{var r,i;return((i=(r=this.options).nodeToChildrenCount)==null?void 0:i.call(r,n))??Sr.nodeToChildrenCount(n)}),A(this,"getNodeValue",n=>{var r,i;return((i=(r=this.options).nodeToValue)==null?void 0:i.call(r,n))??Sr.nodeToValue(n)}),A(this,"getNodeDisabled",n=>{var r,i;return((i=(r=this.options).isNodeDisabled)==null?void 0:i.call(r,n))??Sr.isNodeDisabled(n)}),A(this,"stringify",n=>{const r=this.findNode(n);return r?this.stringifyNode(r):null}),A(this,"stringifyNode",n=>{var r,i;return((i=(r=this.options).nodeToString)==null?void 0:i.call(r,n))??Sr.nodeToString(n)}),A(this,"getFirstNode",(n=this.rootNode)=>{let r;return it(n,{getChildren:this.getNodeChildren,onEnter:(i,o)=>{if(!r&&o.length>0&&!this.getNodeDisabled(i))return r=i,"stop"}}),r}),A(this,"getLastNode",(n=this.rootNode,r={})=>{let i;return it(n,{getChildren:this.getNodeChildren,onEnter:(o,s)=>{var a;if(!this.isSameNode(o,n)){if((a=r.skip)!=null&&a.call(r,{value:this.getNodeValue(o),node:o,indexPath:s}))return"skip";s.length>0&&!this.getNodeDisabled(o)&&(i=o)}}}),i}),A(this,"at",n=>Md(this.rootNode,n,{getChildren:this.getNodeChildren})),A(this,"findNode",(n,r=this.rootNode)=>NS(r,{getChildren:this.getNodeChildren,predicate:i=>this.getNodeValue(i)===n})),A(this,"findNodes",(n,r=this.rootNode)=>{const i=new Set(n.filter(o=>o!=null));return AS(r,{getChildren:this.getNodeChildren,predicate:o=>i.has(this.getNodeValue(o))})}),A(this,"sort",n=>n.reduce((r,i)=>{const o=this.getIndexPath(i);return o&&r.push({value:i,indexPath:o}),r},[]).sort((r,i)=>$d(r.indexPath,i.indexPath)).map(({value:r})=>r)),A(this,"getIndexPath",n=>Bd(this.rootNode,{getChildren:this.getNodeChildren,predicate:r=>this.getNodeValue(r)===n})),A(this,"getValue",n=>{const r=this.at(n);return r?this.getNodeValue(r):void 0}),A(this,"getValuePath",n=>{if(!n)return[];const r=[];let i=[...n];for(;i.length>0;){const o=this.at(i);o&&r.unshift(this.getNodeValue(o)),i.pop()}return r}),A(this,"getDepth",n=>{const r=Bd(this.rootNode,{getChildren:this.getNodeChildren,predicate:i=>this.getNodeValue(i)===n});return(r==null?void 0:r.length)??0}),A(this,"isSameNode",(n,r)=>this.getNodeValue(n)===this.getNodeValue(r)),A(this,"isRootNode",n=>this.isSameNode(n,this.rootNode)),A(this,"contains",(n,r)=>!n||!r?!1:r.slice(0,n.length).every((i,o)=>n[o]===r[o])),A(this,"getNextNode",(n,r={})=>{let i=!1,o;return it(this.rootNode,{getChildren:this.getNodeChildren,onEnter:(s,a)=>{var c;if(this.isRootNode(s))return;const l=this.getNodeValue(s);if((c=r.skip)!=null&&c.call(r,{value:l,node:s,indexPath:a}))return l===n&&(i=!0),"skip";if(i&&!this.getNodeDisabled(s))return o=s,"stop";l===n&&(i=!0)}}),o}),A(this,"getPreviousNode",(n,r={})=>{let i,o=!1;return it(this.rootNode,{getChildren:this.getNodeChildren,onEnter:(s,a)=>{var c;if(this.isRootNode(s))return;const l=this.getNodeValue(s);if((c=r.skip)!=null&&c.call(r,{value:l,node:s,indexPath:a}))return"skip";if(l===n)return o=!0,"stop";this.getNodeDisabled(s)||(i=s)}}),o?i:void 0}),A(this,"getParentNodes",n=>{var o;const r=(o=this.resolveIndexPath(n))==null?void 0:o.slice();if(!r)return[];const i=[];for(;r.length>0;){r.pop();const s=this.at(r);s&&!this.isRootNode(s)&&i.unshift(s)}return i}),A(this,"getDescendantNodes",(n,r)=>{const i=this.resolveNode(n);if(!i)return[];const o=[];return it(i,{getChildren:this.getNodeChildren,onEnter:(s,a)=>{a.length!==0&&(!(r!=null&&r.withBranch)&&this.isBranchNode(s)||o.push(s))}}),o}),A(this,"getDescendantValues",(n,r)=>this.getDescendantNodes(n,r).map(o=>this.getNodeValue(o))),A(this,"getParentIndexPath",n=>n.slice(0,-1)),A(this,"getParentNode",n=>{const r=this.resolveIndexPath(n);return r?this.at(this.getParentIndexPath(r)):void 0}),A(this,"visit",n=>{const{skip:r,...i}=n;it(this.rootNode,{...i,getChildren:this.getNodeChildren,onEnter:(o,s)=>{var a;if(!this.isRootNode(o))return r!=null&&r({value:this.getNodeValue(o),node:o,indexPath:s})?"skip":(a=i.onEnter)==null?void 0:a.call(i,o,s)}})}),A(this,"getPreviousSibling",n=>{const r=this.getParentNode(n);if(!r)return;const i=this.getNodeChildren(r);let o=n[n.length-1];for(;--o>=0;){const s=i[o];if(!this.getNodeDisabled(s))return s}}),A(this,"getNextSibling",n=>{const r=this.getParentNode(n);if(!r)return;const i=this.getNodeChildren(r);let o=n[n.length-1];for(;++o{const r=this.getParentNode(n);return r?this.getNodeChildren(r):[]}),A(this,"getValues",(n=this.rootNode)=>VS(n,{getChildren:this.getNodeChildren,transform:i=>[this.getNodeValue(i)]}).slice(1)),A(this,"isValidDepth",(n,r)=>r==null?!0:typeof r=="function"?r(n.length):n.length===r),A(this,"isBranchNode",n=>this.getNodeChildren(n).length>0||this.getNodeChildrenCount(n)!=null),A(this,"getBranchValues",(n=this.rootNode,r={})=>{let i=[];return it(n,{getChildren:this.getNodeChildren,onEnter:(o,s)=>{var l;if(s.length===0)return;const a=this.getNodeValue(o);if((l=r.skip)!=null&&l.call(r,{value:a,node:o,indexPath:s}))return"skip";this.isBranchNode(o)&&this.isValidDepth(s,r.depth)&&i.push(this.getNodeValue(o))}}),i}),A(this,"flatten",(n=this.rootNode)=>LS(n,{getChildren:this.getNodeChildren})),A(this,"_create",(n,r)=>this.getNodeChildren(n).length>0||r.length>0?{...n,children:r}:{...n}),A(this,"_insert",(n,r,i)=>this.copy(BS(n,{at:r,nodes:i,getChildren:this.getNodeChildren,create:this._create}))),A(this,"copy",n=>new gb({...this.options,rootNode:n})),A(this,"_replace",(n,r,i)=>this.copy(jS(n,{at:r,node:i,getChildren:this.getNodeChildren,create:this._create}))),A(this,"_move",(n,r,i)=>this.copy(HS(n,{indexPaths:r,to:i,getChildren:this.getNodeChildren,create:this._create}))),A(this,"_remove",(n,r)=>this.copy(WS(n,{indexPaths:r,getChildren:this.getNodeChildren,create:this._create}))),A(this,"replace",(n,r)=>this._replace(this.rootNode,n,r)),A(this,"remove",n=>this._remove(this.rootNode,n)),A(this,"insertBefore",(n,r)=>this.getParentNode(n)?this._insert(this.rootNode,n,r):void 0),A(this,"insertAfter",(n,r)=>{if(!this.getParentNode(n))return;const o=[...n.slice(0,-1),n[n.length-1]+1];return this._insert(this.rootNode,o,r)}),A(this,"move",(n,r)=>this._move(this.rootNode,n,r)),A(this,"filter",n=>{const r=FS(this.rootNode,{predicate:n,getChildren:this.getNodeChildren,create:this._create});return this.copy(r)}),A(this,"toJSON",()=>this.getValues(this.rootNode)),this.rootNode=t.rootNode}},Sr={nodeToValue(e){return typeof e=="string"?e:In(e)&&Yt(e,"value")?e.value:""},nodeToString(e){return typeof e=="string"?e:In(e)&&Yt(e,"label")?e.label:Sr.nodeToValue(e)},isNodeDisabled(e){return In(e)&&Yt(e,"disabled")?!!e.disabled:!1},nodeToChildren(e){return e.children},nodeToChildrenCount(e){if(In(e)&&Yt(e,"childrenCount"))return e.childrenCount}},wr=new WeakMap,Yo=new WeakMap,Qo={},Ja=0,qd=e=>e&&(e.host||qd(e.parentNode)),US=(e,t)=>t.map(n=>{if(e.contains(n))return n;const r=qd(n);return r&&e.contains(r)?r:(console.error("[zag-js > ariaHidden] target",n,"in not contained inside",e,". Doing nothing"),null)}).filter(n=>!!n),GS=new Set(["script","output","status","next-route-announcer"]),qS=e=>GS.has(e.localName)||e.role==="status"||e.hasAttribute("aria-live")?!0:e.matches("[data-live-announcer]"),KS=(e,t)=>{const{parentNode:n,markerName:r,controlAttribute:i}=t,o=US(n,Array.isArray(e)?e:[e]);Qo[r]||(Qo[r]=new WeakMap);const s=Qo[r],a=[],l=new Set,c=new Set(o),u=h=>{!h||l.has(h)||(l.add(h),u(h.parentNode))};o.forEach(u);const d=h=>{!h||c.has(h)||Array.prototype.forEach.call(h.children,m=>{if(l.has(m))d(m);else try{if(qS(m))return;const g=m.getAttribute(i)==="true",p=(wr.get(m)||0)+1,v=(s.get(m)||0)+1;wr.set(m,p),s.set(m,v),a.push(m),p===1&&g&&Yo.set(m,!0),v===1&&m.setAttribute(r,""),g||m.setAttribute(i,"true")}catch(f){console.error("[zag-js > ariaHidden] cannot operate on ",m,f)}})};return d(n),l.clear(),Ja++,()=>{a.forEach(h=>{const m=wr.get(h)-1,f=s.get(h)-1;wr.set(h,m),s.set(h,f),m||(Yo.has(h)||h.removeAttribute(i),Yo.delete(h)),f||h.removeAttribute(r)}),Ja--,Ja||(wr=new WeakMap,wr=new WeakMap,Yo=new WeakMap,Qo={})}},XS=e=>(Array.isArray(e)?e[0]:e).ownerDocument.body,YS=(e,t=XS(e),n="data-aria-hidden")=>{if(t)return KS(e,{parentNode:t,markerName:n,controlAttribute:"aria-hidden"})},QS=e=>{const t=requestAnimationFrame(()=>e());return()=>cancelAnimationFrame(t)};function Kd(e,t={}){const{defer:n=!0}=t,r=n?QS:o=>o(),i=[];return i.push(r(()=>{const s=(typeof e=="function"?e():e).filter(Boolean);s.length!==0&&i.push(YS(s))})),()=>{i.forEach(o=>o==null?void 0:o())}}var Xd=G("combobox").parts("root","clearTrigger","content","control","input","item","itemGroup","itemGroupLabel","itemIndicator","itemText","label","list","positioner","trigger");Xd.build();var Yd=e=>new qo(e);Yd.empty=()=>new qo({items:[]});var JS=e=>{var t;return((t=e.ids)==null?void 0:t.control)??`combobox:${e.id}:control`},ZS=e=>{var t;return((t=e.ids)==null?void 0:t.input)??`combobox:${e.id}:input`},ew=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`combobox:${e.id}:content`},tw=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`combobox:${e.id}:popper`},nw=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`combobox:${e.id}:toggle-btn`},rw=e=>{var t;return((t=e.ids)==null?void 0:t.clearTrigger)??`combobox:${e.id}:clear-btn`},rn=e=>e.getById(ew(e)),Er=e=>e.getById(ZS(e)),Qd=e=>e.getById(tw(e)),Jd=e=>e.getById(JS(e)),mi=e=>e.getById(nw(e)),Zd=e=>e.getById(rw(e)),vi=(e,t)=>{if(t==null)return null;const n=`[role=option][data-value="${CSS.escape(t)}"]`;return gx(rn(e),n)},eh=e=>{const t=Er(e);e.isActiveElement(t)||t==null||t.focus({preventScroll:!0})},iw=e=>{const t=mi(e);e.isActiveElement(t)||t==null||t.focus({preventScroll:!0})},{guards:ow,createMachine:sw,choose:aw}=Au(),{and:Pe,not:ot}=ow;sw({props({props:e}){return{loopFocus:!0,openOnClick:!1,defaultValue:[],closeOnSelect:!e.multiple,allowCustomValue:!1,inputBehavior:"none",selectionBehavior:e.multiple?"clear":"replace",openOnKeyPress:!0,openOnChange:!0,composite:!0,navigate({node:t}){Ou(t)},collection:Yd.empty(),...e,positioning:{placement:"bottom",sameWidth:!0,...e.positioning},translations:{triggerLabel:"Toggle suggestions",clearTriggerLabel:"Clear value",...e.translations}}},initialState({prop:e}){return e("open")||e("defaultOpen")?"suggesting":"idle"},context({prop:e,bindable:t,getContext:n,getEvent:r}){return{currentPlacement:t(()=>({defaultValue:void 0})),value:t(()=>({defaultValue:e("defaultValue"),value:e("value"),isEqual:gt,hash(i){return i.join(",")},onChange(i){var c;const o=n(),s=o.get("selectedItems"),a=e("collection"),l=i.map(u=>s.find(h=>a.getItemValue(h)===u)||a.find(u));o.set("selectedItems",l),(c=e("onValueChange"))==null||c({value:i,items:l})}})),highlightedValue:t(()=>({defaultValue:e("defaultHighlightedValue")||null,value:e("highlightedValue"),onChange(i){var s;const o=e("collection").find(i);(s=e("onHighlightChange"))==null||s({highlightedValue:i,highlightedItem:o})}})),inputValue:t(()=>{let i=e("inputValue")||e("defaultInputValue")||"";const o=e("defaultValue")||e("value")||[];if(!i.trim()&&!e("multiple")){const s=e("collection").stringifyMany(o);i=Mt(e("selectionBehavior"),{preserve:i||s,replace:s,clear:""})}return{defaultValue:i,value:e("inputValue"),onChange(s){var c;const a=r(),l=(a.previousEvent||a).src;(c=e("onInputValueChange"))==null||c({inputValue:s,reason:l})}}}),highlightedItem:t(()=>{const i=e("highlightedValue");return{defaultValue:e("collection").find(i)}}),selectedItems:t(()=>{const i=e("value")||e("defaultValue")||[];return{defaultValue:e("collection").findMany(i)}})}},computed:{isInputValueEmpty:({context:e})=>e.get("inputValue").length===0,isInteractive:({prop:e})=>!(e("readOnly")||e("disabled")),autoComplete:({prop:e})=>e("inputBehavior")==="autocomplete",autoHighlight:({prop:e})=>e("inputBehavior")==="autohighlight",hasSelectedItems:({context:e})=>e.get("value").length>0,valueAsString:({context:e,prop:t})=>t("collection").stringifyItems(e.get("selectedItems")),isCustomValue:({context:e,computed:t})=>e.get("inputValue")!==t("valueAsString")},watch({context:e,prop:t,track:n,action:r,send:i}){n([()=>e.hash("value")],()=>{r(["syncSelectedItems"])}),n([()=>e.get("inputValue")],()=>{r(["syncInputValue"])}),n([()=>e.get("highlightedValue")],()=>{r(["syncHighlightedItem","autofillInputValue"])}),n([()=>t("open")],()=>{r(["toggleVisibility"])}),n([()=>t("collection").toString()],()=>{i({type:"CHILDREN_CHANGE"})})},on:{"SELECTED_ITEMS.SYNC":{actions:["syncSelectedItems"]},"HIGHLIGHTED_VALUE.SET":{actions:["setHighlightedValue"]},"HIGHLIGHTED_VALUE.CLEAR":{actions:["clearHighlightedValue"]},"ITEM.SELECT":{actions:["selectItem"]},"ITEM.CLEAR":{actions:["clearItem"]},"VALUE.SET":{actions:["setValue"]},"INPUT_VALUE.SET":{actions:["setInputValue"]},"POSITIONING.SET":{actions:["reposition"]}},entry:aw([{guard:"autoFocus",actions:["setInitialFocus"]}]),states:{idle:{tags:["idle","closed"],entry:["scrollContentToTop","clearHighlightedValue"],on:{"CONTROLLED.OPEN":{target:"interacting"},"TRIGGER.CLICK":[{guard:"isOpenControlled",actions:["setInitialFocus","highlightFirstSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["setInitialFocus","highlightFirstSelectedItem","invokeOnOpen"]}],"INPUT.CLICK":[{guard:"isOpenControlled",actions:["highlightFirstSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["highlightFirstSelectedItem","invokeOnOpen"]}],"INPUT.FOCUS":{target:"focused"},OPEN:[{guard:"isOpenControlled",actions:["invokeOnOpen"]},{target:"interacting",actions:["invokeOnOpen"]}],"VALUE.CLEAR":{target:"focused",actions:["clearInputValue","clearSelectedItems","setInitialFocus"]}}},focused:{tags:["focused","closed"],entry:["scrollContentToTop","clearHighlightedValue"],on:{"CONTROLLED.OPEN":[{guard:"isChangeEvent",target:"suggesting"},{target:"interacting"}],"INPUT.CHANGE":[{guard:Pe("isOpenControlled","openOnChange"),actions:["setInputValue","invokeOnOpen","highlightFirstItemIfNeeded"]},{guard:"openOnChange",target:"suggesting",actions:["setInputValue","invokeOnOpen","highlightFirstItemIfNeeded"]},{actions:["setInputValue"]}],"LAYER.INTERACT_OUTSIDE":{target:"idle"},"INPUT.ESCAPE":{guard:Pe("isCustomValue",ot("allowCustomValue")),actions:["revertInputValue"]},"INPUT.BLUR":{target:"idle"},"INPUT.CLICK":[{guard:"isOpenControlled",actions:["highlightFirstSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["highlightFirstSelectedItem","invokeOnOpen"]}],"TRIGGER.CLICK":[{guard:"isOpenControlled",actions:["setInitialFocus","highlightFirstSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["setInitialFocus","highlightFirstSelectedItem","invokeOnOpen"]}],"INPUT.ARROW_DOWN":[{guard:Pe("isOpenControlled","autoComplete"),actions:["invokeOnOpen"]},{guard:"autoComplete",target:"interacting",actions:["invokeOnOpen"]},{guard:"isOpenControlled",actions:["highlightFirstOrSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["highlightFirstOrSelectedItem","invokeOnOpen"]}],"INPUT.ARROW_UP":[{guard:"autoComplete",target:"interacting",actions:["invokeOnOpen"]},{guard:"autoComplete",target:"interacting",actions:["invokeOnOpen"]},{target:"interacting",actions:["highlightLastOrSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["highlightLastOrSelectedItem","invokeOnOpen"]}],OPEN:[{guard:"isOpenControlled",actions:["invokeOnOpen"]},{target:"interacting",actions:["invokeOnOpen"]}],"VALUE.CLEAR":{actions:["clearInputValue","clearSelectedItems"]}}},interacting:{tags:["open","focused"],entry:["setInitialFocus"],effects:["scrollToHighlightedItem","trackDismissableLayer","trackPlacement","hideOtherElements"],on:{"CONTROLLED.CLOSE":[{guard:"restoreFocus",target:"focused",actions:["setFinalFocus"]},{target:"idle"}],CHILDREN_CHANGE:[{guard:"isHighlightedItemRemoved",actions:["clearHighlightedValue"]},{actions:["scrollToHighlightedItem"]}],"INPUT.HOME":{actions:["highlightFirstItem"]},"INPUT.END":{actions:["highlightLastItem"]},"INPUT.ARROW_DOWN":[{guard:Pe("autoComplete","isLastItemHighlighted"),actions:["clearHighlightedValue","scrollContentToTop"]},{actions:["highlightNextItem"]}],"INPUT.ARROW_UP":[{guard:Pe("autoComplete","isFirstItemHighlighted"),actions:["clearHighlightedValue"]},{actions:["highlightPrevItem"]}],"INPUT.ENTER":[{guard:Pe("isOpenControlled","isCustomValue",ot("hasHighlightedItem"),ot("allowCustomValue")),actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isCustomValue",ot("hasHighlightedItem"),ot("allowCustomValue")),target:"focused",actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isOpenControlled","closeOnSelect"),actions:["selectHighlightedItem","invokeOnClose"]},{guard:"closeOnSelect",target:"focused",actions:["selectHighlightedItem","invokeOnClose","setFinalFocus"]},{actions:["selectHighlightedItem"]}],"INPUT.CHANGE":[{guard:"autoComplete",target:"suggesting",actions:["setInputValue"]},{target:"suggesting",actions:["clearHighlightedValue","setInputValue"]}],"ITEM.POINTER_MOVE":{actions:["setHighlightedValue"]},"ITEM.POINTER_LEAVE":{actions:["clearHighlightedValue"]},"ITEM.CLICK":[{guard:Pe("isOpenControlled","closeOnSelect"),actions:["selectItem","invokeOnClose"]},{guard:"closeOnSelect",target:"focused",actions:["selectItem","invokeOnClose","setFinalFocus"]},{actions:["selectItem"]}],"LAYER.ESCAPE":[{guard:Pe("isOpenControlled","autoComplete"),actions:["syncInputValue","invokeOnClose"]},{guard:"autoComplete",target:"focused",actions:["syncInputValue","invokeOnClose"]},{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose","setFinalFocus"]}],"TRIGGER.CLICK":[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose"]}],"LAYER.INTERACT_OUTSIDE":[{guard:Pe("isOpenControlled","isCustomValue",ot("allowCustomValue")),actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isCustomValue",ot("allowCustomValue")),target:"idle",actions:["revertInputValue","invokeOnClose"]},{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"idle",actions:["invokeOnClose"]}],CLOSE:[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose","setFinalFocus"]}],"VALUE.CLEAR":[{guard:"isOpenControlled",actions:["clearInputValue","clearSelectedItems","invokeOnClose"]},{target:"focused",actions:["clearInputValue","clearSelectedItems","invokeOnClose","setFinalFocus"]}]}},suggesting:{tags:["open","focused"],effects:["trackDismissableLayer","scrollToHighlightedItem","trackPlacement","hideOtherElements"],entry:["setInitialFocus"],on:{"CONTROLLED.CLOSE":[{guard:"restoreFocus",target:"focused",actions:["setFinalFocus"]},{target:"idle"}],CHILDREN_CHANGE:[{guard:"autoHighlight",actions:["highlightFirstItem"]},{guard:"isHighlightedItemRemoved",actions:["clearHighlightedValue"]}],"INPUT.ARROW_DOWN":{target:"interacting",actions:["highlightNextItem"]},"INPUT.ARROW_UP":{target:"interacting",actions:["highlightPrevItem"]},"INPUT.HOME":{target:"interacting",actions:["highlightFirstItem"]},"INPUT.END":{target:"interacting",actions:["highlightLastItem"]},"INPUT.ENTER":[{guard:Pe("isOpenControlled","isCustomValue",ot("hasHighlightedItem"),ot("allowCustomValue")),actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isCustomValue",ot("hasHighlightedItem"),ot("allowCustomValue")),target:"focused",actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isOpenControlled","closeOnSelect"),actions:["selectHighlightedItem","invokeOnClose"]},{guard:"closeOnSelect",target:"focused",actions:["selectHighlightedItem","invokeOnClose","setFinalFocus"]},{actions:["selectHighlightedItem"]}],"INPUT.CHANGE":{actions:["setInputValue"]},"LAYER.ESCAPE":[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose"]}],"ITEM.POINTER_MOVE":{target:"interacting",actions:["setHighlightedValue"]},"ITEM.POINTER_LEAVE":{actions:["clearHighlightedValue"]},"LAYER.INTERACT_OUTSIDE":[{guard:Pe("isOpenControlled","isCustomValue",ot("allowCustomValue")),actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isCustomValue",ot("allowCustomValue")),target:"idle",actions:["revertInputValue","invokeOnClose"]},{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"idle",actions:["invokeOnClose"]}],"TRIGGER.CLICK":[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose"]}],"ITEM.CLICK":[{guard:Pe("isOpenControlled","closeOnSelect"),actions:["selectItem","invokeOnClose"]},{guard:"closeOnSelect",target:"focused",actions:["selectItem","invokeOnClose","setFinalFocus"]},{actions:["selectItem"]}],CLOSE:[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose","setFinalFocus"]}],"VALUE.CLEAR":[{guard:"isOpenControlled",actions:["clearInputValue","clearSelectedItems","invokeOnClose"]},{target:"focused",actions:["clearInputValue","clearSelectedItems","invokeOnClose","setFinalFocus"]}]}}},implementations:{guards:{isInputValueEmpty:({computed:e})=>e("isInputValueEmpty"),autoComplete:({computed:e,prop:t})=>e("autoComplete")&&!t("multiple"),autoHighlight:({computed:e})=>e("autoHighlight"),isFirstItemHighlighted:({prop:e,context:t})=>e("collection").firstValue===t.get("highlightedValue"),isLastItemHighlighted:({prop:e,context:t})=>e("collection").lastValue===t.get("highlightedValue"),isCustomValue:({computed:e})=>e("isCustomValue"),allowCustomValue:({prop:e})=>!!e("allowCustomValue"),hasHighlightedItem:({context:e})=>e.get("highlightedValue")!=null,closeOnSelect:({prop:e})=>!!e("closeOnSelect"),isOpenControlled:({prop:e})=>e("open")!=null,openOnChange:({prop:e,context:t})=>{const n=e("openOnChange");return Xy(n)?n:!!(n!=null&&n({inputValue:t.get("inputValue")}))},restoreFocus:({event:e})=>e.restoreFocus==null?!0:!!e.restoreFocus,isChangeEvent:({event:e})=>{var t;return((t=e.previousEvent)==null?void 0:t.type)==="INPUT.CHANGE"},autoFocus:({prop:e})=>!!e("autoFocus"),isHighlightedItemRemoved:({prop:e,context:t})=>!e("collection").has(t.get("highlightedValue"))},effects:{trackDismissableLayer({send:e,prop:t,scope:n}){return t("disableLayer")?void 0:Cr(()=>rn(n),{defer:!0,exclude:()=>[Er(n),mi(n),Zd(n)],onFocusOutside:t("onFocusOutside"),onPointerDownOutside:t("onPointerDownOutside"),onInteractOutside:t("onInteractOutside"),onEscapeKeyDown(i){i.preventDefault(),i.stopPropagation(),e({type:"LAYER.ESCAPE",src:"escape-key"})},onDismiss(){e({type:"LAYER.INTERACT_OUTSIDE",src:"interact-outside",restoreFocus:!1})}})},hideOtherElements({scope:e}){return Kd([Er(e),rn(e),mi(e),Zd(e)])},trackPlacement({context:e,prop:t,scope:n}){const r=()=>Jd(n)||mi(n),i=()=>Qd(n);return e.set("currentPlacement",t("positioning").placement),bt(r,i,{...t("positioning"),defer:!0,onComplete(o){e.set("currentPlacement",o.placement)}})},scrollToHighlightedItem({context:e,prop:t,scope:n,event:r}){const i=Er(n);let o=[];const s=c=>{const u=r.current().type.includes("POINTER"),d=e.get("highlightedValue");if(u||!d)return;const h=rn(n),m=t("scrollToIndexFn");if(m){const p=t("collection").indexOf(d);m({index:p,immediate:c,getElement:()=>vi(n,d)});return}const f=vi(n,d),g=Z(()=>{ko(f,{rootEl:h,block:"nearest"})});o.push(g)},a=Z(()=>s(!0));o.push(a);const l=wo(i,{attributes:["aria-activedescendant"],callback:()=>s(!1)});return o.push(l),()=>{o.forEach(c=>c())}}},actions:{reposition({context:e,prop:t,scope:n,event:r}){bt(()=>Jd(n),()=>Qd(n),{...t("positioning"),...r.options,defer:!0,listeners:!1,onComplete(s){e.set("currentPlacement",s.placement)}})},setHighlightedValue({context:e,event:t}){t.value!=null&&e.set("highlightedValue",t.value)},clearHighlightedValue({context:e}){e.set("highlightedValue",null)},selectHighlightedItem(e){var a;const{context:t,prop:n}=e,r=n("collection"),i=t.get("highlightedValue");if(!i||!r.has(i))return;const o=n("multiple")?dr(t.get("value"),i):[i];(a=n("onSelect"))==null||a({value:o,itemValue:i}),t.set("value",o);const s=Mt(n("selectionBehavior"),{preserve:t.get("inputValue"),replace:r.stringifyMany(o),clear:""});t.set("inputValue",s)},scrollToHighlightedItem({context:e,prop:t,scope:n}){wa(()=>{const r=e.get("highlightedValue");if(r==null)return;const i=vi(n,r),o=rn(n),s=t("scrollToIndexFn");if(s){const a=t("collection").indexOf(r);s({index:a,immediate:!0,getElement:()=>vi(n,r)});return}ko(i,{rootEl:o,block:"nearest"})})},selectItem(e){const{context:t,event:n,flush:r,prop:i}=e;n.value!=null&&r(()=>{var a;const o=i("multiple")?dr(t.get("value"),n.value):[n.value];(a=i("onSelect"))==null||a({value:o,itemValue:n.value}),t.set("value",o);const s=Mt(i("selectionBehavior"),{preserve:t.get("inputValue"),replace:i("collection").stringifyMany(o),clear:""});t.set("inputValue",s)})},clearItem(e){const{context:t,event:n,flush:r,prop:i}=e;n.value!=null&&r(()=>{const o=On(t.get("value"),n.value);t.set("value",o);const s=Mt(i("selectionBehavior"),{preserve:t.get("inputValue"),replace:i("collection").stringifyMany(o),clear:""});t.set("inputValue",s)})},setInitialFocus({scope:e}){Z(()=>{eh(e)})},setFinalFocus({scope:e}){Z(()=>{const t=mi(e);(t==null?void 0:t.dataset.focusable)==null?eh(e):iw(e)})},syncInputValue({context:e,scope:t,event:n}){const r=Er(t);r&&(r.value=e.get("inputValue"),queueMicrotask(()=>{n.current().type!=="INPUT.CHANGE"&&C0(r)}))},setInputValue({context:e,event:t}){e.set("inputValue",t.value)},clearInputValue({context:e}){e.set("inputValue","")},revertInputValue({context:e,prop:t,computed:n}){const r=t("selectionBehavior"),i=Mt(r,{replace:n("hasSelectedItems")?n("valueAsString"):"",preserve:e.get("inputValue"),clear:""});e.set("inputValue",i)},setValue(e){const{context:t,flush:n,event:r,prop:i}=e;n(()=>{t.set("value",r.value);const o=Mt(i("selectionBehavior"),{preserve:t.get("inputValue"),replace:i("collection").stringifyMany(r.value),clear:""});t.set("inputValue",o)})},clearSelectedItems(e){const{context:t,flush:n,prop:r}=e;n(()=>{t.set("value",[]);const i=Mt(r("selectionBehavior"),{preserve:t.get("inputValue"),replace:r("collection").stringifyMany([]),clear:""});t.set("inputValue",i)})},scrollContentToTop({prop:e,scope:t}){const n=e("scrollToIndexFn");if(n){const r=e("collection").firstValue;n({index:0,immediate:!0,getElement:()=>vi(t,r)})}else{const r=rn(t);if(!r)return;r.scrollTop=0}},invokeOnOpen({prop:e,event:t}){var r;const n=th(t);(r=e("onOpenChange"))==null||r({open:!0,reason:n})},invokeOnClose({prop:e,event:t}){var r;const n=th(t);(r=e("onOpenChange"))==null||r({open:!1,reason:n})},highlightFirstItem({context:e,prop:t,scope:n}){(rn(n)?queueMicrotask:Z)(()=>{const i=t("collection").firstValue;i&&e.set("highlightedValue",i)})},highlightFirstItemIfNeeded({computed:e,action:t}){e("autoHighlight")&&t(["highlightFirstItem"])},highlightLastItem({context:e,prop:t,scope:n}){(rn(n)?queueMicrotask:Z)(()=>{const i=t("collection").lastValue;i&&e.set("highlightedValue",i)})},highlightNextItem({context:e,prop:t}){let n=null;const r=e.get("highlightedValue"),i=t("collection");r?(n=i.getNextValue(r),!n&&t("loopFocus")&&(n=i.firstValue)):n=i.firstValue,n&&e.set("highlightedValue",n)},highlightPrevItem({context:e,prop:t}){let n=null;const r=e.get("highlightedValue"),i=t("collection");r?(n=i.getPreviousValue(r),!n&&t("loopFocus")&&(n=i.lastValue)):n=i.lastValue,n&&e.set("highlightedValue",n)},highlightFirstSelectedItem({context:e,prop:t}){Z(()=>{const[n]=t("collection").sort(e.get("value"));n&&e.set("highlightedValue",n)})},highlightFirstOrSelectedItem({context:e,prop:t,computed:n}){Z(()=>{let r=null;n("hasSelectedItems")?r=t("collection").sort(e.get("value"))[0]:r=t("collection").firstValue,r&&e.set("highlightedValue",r)})},highlightLastOrSelectedItem({context:e,prop:t,computed:n}){Z(()=>{const r=t("collection");let i=null;n("hasSelectedItems")?i=r.sort(e.get("value"))[0]:i=r.lastValue,i&&e.set("highlightedValue",i)})},autofillInputValue({context:e,computed:t,prop:n,event:r,scope:i}){const o=Er(i),s=n("collection");if(!t("autoComplete")||!o||!r.keypress)return;const a=s.stringify(e.get("highlightedValue"));Z(()=>{o.value=a||e.get("inputValue")})},syncSelectedItems(e){queueMicrotask(()=>{const{context:t,prop:n}=e,r=n("collection"),i=t.get("value"),o=i.map(a=>t.get("selectedItems").find(c=>r.getItemValue(c)===a)||r.find(a));t.set("selectedItems",o);const s=Mt(n("selectionBehavior"),{preserve:t.get("inputValue"),replace:r.stringifyMany(i),clear:""});t.set("inputValue",s)})},syncHighlightedItem({context:e,prop:t}){const n=t("collection").find(e.get("highlightedValue"));e.set("highlightedItem",n)},toggleVisibility({event:e,send:t,prop:n}){t({type:n("open")?"CONTROLLED.OPEN":"CONTROLLED.CLOSE",previousEvent:e})}}}});function th(e){return(e.previousEvent||e).src}U()(["allowCustomValue","autoFocus","closeOnSelect","collection","composite","defaultHighlightedValue","defaultInputValue","defaultOpen","defaultValue","dir","disabled","disableLayer","form","getRootNode","highlightedValue","id","ids","inputBehavior","inputValue","invalid","loopFocus","multiple","name","navigate","onFocusOutside","onHighlightChange","onInputValueChange","onInteractOutside","onOpenChange","onOpenChange","onPointerDownOutside","onSelect","onValueChange","open","openOnChange","openOnClick","openOnKeyPress","placeholder","positioning","readOnly","required","scrollToIndexFn","selectionBehavior","translations","value"]),U()(["htmlFor"]),U()(["id"]),U()(["item","persistFocus"]);const lw=Xd.extendWith("empty"),[nh,on]=hr({name:"DialogContext",hookName:"useDialogContext",providerName:""}),rh=E.forwardRef((e,t)=>{const n=on(),r=iS(),i=Ta({...r,present:n.open}),o=pt(n.getBackdropProps(),i.getPresenceProps(),e);return i.unmounted?null:y.jsx(en.div,{...o,ref:Ro(i.ref,t)})});rh.displayName="DialogBackdrop";const ih=E.forwardRef((e,t)=>{const n=on(),r=pt(n.getCloseTriggerProps(),e);return y.jsx(en.button,{...r,ref:t})});ih.displayName="DialogCloseTrigger";const oh=E.forwardRef((e,t)=>{const n=on(),r=Na(),i=pt(n.getContentProps(),r.getPresenceProps(),e);return r.unmounted?null:y.jsx(en.div,{...i,ref:Ro(r.ref,t)})});oh.displayName="DialogContent";const sh=E.forwardRef((e,t)=>{const n=on(),r=pt(n.getDescriptionProps(),e);return y.jsx(en.div,{...r,ref:t})});sh.displayName="DialogDescription";const ah=E.forwardRef((e,t)=>{const n=on(),r=pt(n.getPositionerProps(),e);return Na().unmounted?null:y.jsx(en.div,{...r,ref:t})});ah.displayName="DialogPositioner";var cw=Object.defineProperty,uw=(e,t,n)=>t in e?cw(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,fe=(e,t,n)=>uw(e,typeof t!="symbol"?t+"":t,n),lh={activateTrap(e,t){if(e.length>0){const r=e[e.length-1];r!==t&&r.pause()}const n=e.indexOf(t);n===-1||e.splice(n,1),e.push(t)},deactivateTrap(e,t){const n=e.indexOf(t);n!==-1&&e.splice(n,1),e.length>0&&e[e.length-1].unpause()}},dw=[],hw=class{constructor(e,t){fe(this,"trapStack"),fe(this,"config"),fe(this,"doc"),fe(this,"state",{containers:[],containerGroups:[],tabbableGroups:[],nodeFocusedBeforeActivation:null,mostRecentlyFocusedNode:null,active:!1,paused:!1,delayInitialFocusTimer:void 0,recentNavEvent:void 0}),fe(this,"listenerCleanups",[]),fe(this,"handleFocus",r=>{const i=tt(r),o=this.findContainerIndex(i,r)>=0;if(o||ma(i))o&&(this.state.mostRecentlyFocusedNode=i);else{r.stopImmediatePropagation();let s,a=!0;if(this.state.mostRecentlyFocusedNode)if(li(this.state.mostRecentlyFocusedNode)>0){const l=this.findContainerIndex(this.state.mostRecentlyFocusedNode),{tabbableNodes:c}=this.state.containerGroups[l];if(c.length>0){const u=c.findIndex(d=>d===this.state.mostRecentlyFocusedNode);u>=0&&(this.config.isKeyForward(this.state.recentNavEvent)?u+1=0&&(s=c[u-1],a=!1))}}else this.state.containerGroups.some(l=>l.tabbableNodes.some(c=>li(c)>0))||(a=!1);else a=!1;a&&(s=this.findNextNavNode({target:this.state.mostRecentlyFocusedNode,isBackward:this.config.isKeyBackward(this.state.recentNavEvent)})),s?this.tryFocus(s):this.tryFocus(this.state.mostRecentlyFocusedNode||this.getInitialFocusNode())}this.state.recentNavEvent=void 0}),fe(this,"handlePointerDown",r=>{const i=tt(r);if(!(this.findContainerIndex(i,r)>=0)){if(yi(this.config.clickOutsideDeactivates,r)){this.deactivate({returnFocus:this.config.returnFocusOnDeactivate});return}yi(this.config.allowOutsideClick,r)||r.preventDefault()}}),fe(this,"handleClick",r=>{const i=tt(r);this.findContainerIndex(i,r)>=0||yi(this.config.clickOutsideDeactivates,r)||yi(this.config.allowOutsideClick,r)||(r.preventDefault(),r.stopImmediatePropagation())}),fe(this,"handleTabKey",r=>{if(this.config.isKeyForward(r)||this.config.isKeyBackward(r)){this.state.recentNavEvent=r;const i=this.config.isKeyBackward(r),o=this.findNextNavNode({event:r,isBackward:i});if(!o)return;bi(r)&&r.preventDefault(),this.tryFocus(o)}}),fe(this,"handleEscapeKey",r=>{fw(r)&&yi(this.config.escapeDeactivates,r)!==!1&&(r.preventDefault(),this.deactivate())}),fe(this,"_mutationObserver"),fe(this,"setupMutationObserver",()=>{const r=this.doc.defaultView||window;this._mutationObserver=new r.MutationObserver(i=>{i.some(s=>Array.from(s.removedNodes).some(l=>l===this.state.mostRecentlyFocusedNode))&&this.tryFocus(this.getInitialFocusNode())})}),fe(this,"updateObservedNodes",()=>{var r;(r=this._mutationObserver)==null||r.disconnect(),this.state.active&&!this.state.paused&&this.state.containers.map(i=>{var o;(o=this._mutationObserver)==null||o.observe(i,{subtree:!0,childList:!0})})}),fe(this,"getInitialFocusNode",()=>{let r=this.getNodeForOption("initialFocus",{hasFallback:!0});if(r===!1)return!1;if(r===void 0||r&&!Jt(r))if(this.findContainerIndex(this.doc.activeElement)>=0)r=this.doc.activeElement;else{const i=this.state.tabbableGroups[0];r=i&&i.firstTabbableNode||this.getNodeForOption("fallbackFocus")}else r===null&&(r=this.getNodeForOption("fallbackFocus"));if(!r)throw new Error("Your focus-trap needs to have at least one focusable element");return r.isConnected||(r=this.getNodeForOption("fallbackFocus")),r}),fe(this,"tryFocus",r=>{if(r!==!1&&r!==xu(this.doc)){if(!r||!r.focus){this.tryFocus(this.getInitialFocusNode());return}r.focus({preventScroll:!!this.config.preventScroll}),this.state.mostRecentlyFocusedNode=r,gw(r)&&r.select()}}),fe(this,"deactivate",r=>{if(!this.state.active)return this;const i={onDeactivate:this.config.onDeactivate,onPostDeactivate:this.config.onPostDeactivate,checkCanReturnFocus:this.config.checkCanReturnFocus,...r};clearTimeout(this.state.delayInitialFocusTimer),this.state.delayInitialFocusTimer=void 0,this.removeListeners(),this.state.active=!1,this.state.paused=!1,this.updateObservedNodes(),lh.deactivateTrap(this.trapStack,this);const o=this.getOption(i,"onDeactivate"),s=this.getOption(i,"onPostDeactivate"),a=this.getOption(i,"checkCanReturnFocus"),l=this.getOption(i,"returnFocus","returnFocusOnDeactivate");o==null||o();const c=()=>{ch(()=>{if(l){const u=this.getReturnFocusNode(this.state.nodeFocusedBeforeActivation);this.tryFocus(u)}s==null||s()})};if(l&&a){const u=this.getReturnFocusNode(this.state.nodeFocusedBeforeActivation);return a(u).then(c,c),this}return c(),this}),fe(this,"pause",r=>{if(this.state.paused||!this.state.active)return this;const i=this.getOption(r,"onPause"),o=this.getOption(r,"onPostPause");return this.state.paused=!0,i==null||i(),this.removeListeners(),this.updateObservedNodes(),o==null||o(),this}),fe(this,"unpause",r=>{if(!this.state.paused||!this.state.active)return this;const i=this.getOption(r,"onUnpause"),o=this.getOption(r,"onPostUnpause");return this.state.paused=!1,i==null||i(),this.updateTabbableNodes(),this.addListeners(),this.updateObservedNodes(),o==null||o(),this}),fe(this,"updateContainerElements",r=>(this.state.containers=Array.isArray(r)?r.filter(Boolean):[r].filter(Boolean),this.state.active&&this.updateTabbableNodes(),this.updateObservedNodes(),this)),fe(this,"getReturnFocusNode",r=>{const i=this.getNodeForOption("setReturnFocus",{params:[r]});return i||(i===!1?!1:r)}),fe(this,"getOption",(r,i,o)=>r&&r[i]!==void 0?r[i]:this.config[o||i]),fe(this,"getNodeForOption",(r,{hasFallback:i=!1,params:o=[]}={})=>{let s=this.config[r];if(typeof s=="function"&&(s=s(...o)),s===!0&&(s=void 0),!s){if(s===void 0||s===!1)return s;throw new Error(`\`${r}\` was specified but was not a node, or did not return a node`)}let a=s;if(typeof s=="string"){try{a=this.doc.querySelector(s)}catch(l){throw new Error(`\`${r}\` appears to be an invalid selector; error="${l.message}"`)}if(!a&&!i)throw new Error(`\`${r}\` as selector refers to no known node`)}return a}),fe(this,"findNextNavNode",r=>{const{event:i,isBackward:o=!1}=r,s=r.target||tt(i);this.updateTabbableNodes();let a=null;if(this.state.tabbableGroups.length>0){const l=this.findContainerIndex(s,i),c=l>=0?this.state.containerGroups[l]:void 0;if(l<0)o?a=this.state.tabbableGroups[this.state.tabbableGroups.length-1].lastTabbableNode:a=this.state.tabbableGroups[0].firstTabbableNode;else if(o){let u=this.state.tabbableGroups.findIndex(({firstTabbableNode:d})=>s===d);if(u<0&&((c==null?void 0:c.container)===s||Jt(s)&&!Tn(s)&&!(c!=null&&c.nextTabbableNode(s,!1)))&&(u=l),u>=0){const d=u===0?this.state.tabbableGroups.length-1:u-1,h=this.state.tabbableGroups[d];a=li(s)>=0?h.lastTabbableNode:h.lastDomTabbableNode}else bi(i)||(a=c==null?void 0:c.nextTabbableNode(s,!1))}else{let u=this.state.tabbableGroups.findIndex(({lastTabbableNode:d})=>s===d);if(u<0&&((c==null?void 0:c.container)===s||Jt(s)&&!Tn(s)&&!(c!=null&&c.nextTabbableNode(s)))&&(u=l),u>=0){const d=u===this.state.tabbableGroups.length-1?0:u+1,h=this.state.tabbableGroups[d];a=li(s)>=0?h.firstTabbableNode:h.firstDomTabbableNode}else bi(i)||(a=c==null?void 0:c.nextTabbableNode(s))}}else a=this.getNodeForOption("fallbackFocus");return a}),this.trapStack=t.trapStack||dw;const n={returnFocusOnDeactivate:!0,escapeDeactivates:!0,delayInitialFocus:!0,isKeyForward(r){return bi(r)&&!r.shiftKey},isKeyBackward(r){return bi(r)&&r.shiftKey},...t};this.doc=n.document||Ge(Array.isArray(e)?e[0]:e),this.config=n,this.updateContainerElements(e),this.setupMutationObserver()}get active(){return this.state.active}get paused(){return this.state.paused}findContainerIndex(e,t){const n=typeof(t==null?void 0:t.composedPath)=="function"?t.composedPath():void 0;return this.state.containerGroups.findIndex(({container:r,tabbableNodes:i})=>r.contains(e)||(n==null?void 0:n.includes(r))||i.find(o=>o===e))}updateTabbableNodes(){if(this.state.containerGroups=this.state.containers.map(e=>{const t=Ca(e),n=ku(e),r=t.length>0?t[0]:void 0,i=t.length>0?t[t.length-1]:void 0,o=n.find(c=>Tn(c)),s=n.slice().reverse().find(c=>Tn(c)),a=!!t.find(c=>li(c)>0);function l(c,u=!0){const d=t.indexOf(c);return d<0?u?n.slice(n.indexOf(c)+1).find(h=>Tn(h)):n.slice(0,n.indexOf(c)).reverse().find(h=>Tn(h)):t[d+(u?1:-1)]}return{container:e,tabbableNodes:t,focusableNodes:n,posTabIndexesFound:a,firstTabbableNode:r,lastTabbableNode:i,firstDomTabbableNode:o,lastDomTabbableNode:s,nextTabbableNode:l}}),this.state.tabbableGroups=this.state.containerGroups.filter(e=>e.tabbableNodes.length>0),this.state.tabbableGroups.length<=0&&!this.getNodeForOption("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(this.state.containerGroups.find(e=>e.posTabIndexesFound)&&this.state.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")}addListeners(){if(this.state.active)return lh.activateTrap(this.trapStack,this),this.state.delayInitialFocusTimer=this.config.delayInitialFocus?ch(()=>{this.tryFocus(this.getInitialFocusNode())}):this.tryFocus(this.getInitialFocusNode()),this.listenerCleanups.push(he(this.doc,"focusin",this.handleFocus,!0),he(this.doc,"mousedown",this.handlePointerDown,{capture:!0,passive:!1}),he(this.doc,"touchstart",this.handlePointerDown,{capture:!0,passive:!1}),he(this.doc,"click",this.handleClick,{capture:!0,passive:!1}),he(this.doc,"keydown",this.handleTabKey,{capture:!0,passive:!1}),he(this.doc,"keydown",this.handleEscapeKey)),this}removeListeners(){if(this.state.active)return this.listenerCleanups.forEach(e=>e()),this.listenerCleanups=[],this}activate(e){if(this.state.active)return this;const t=this.getOption(e,"onActivate"),n=this.getOption(e,"onPostActivate"),r=this.getOption(e,"checkCanFocusTrap");r||this.updateTabbableNodes(),this.state.active=!0,this.state.paused=!1,this.state.nodeFocusedBeforeActivation=this.doc.activeElement||null,t==null||t();const i=()=>{r&&this.updateTabbableNodes(),this.addListeners(),this.updateObservedNodes(),n==null||n()};return r?(r(this.state.containers.concat()).then(i,i),this):(i(),this)}},bi=e=>e.key==="Tab",yi=(e,...t)=>typeof e=="function"?e(...t):e,fw=e=>!e.isComposing&&e.key==="Escape",ch=e=>setTimeout(e,0),gw=e=>e.localName==="input"&&"select"in e&&typeof e.select=="function";function pw(e,t={}){let n;const r=Z(()=>{const i=typeof e=="function"?e():e;if(i){n=new hw(i,{escapeDeactivates:!1,allowOutsideClick:!0,preventScroll:!0,returnFocusOnDeactivate:!0,delayInitialFocus:!1,fallbackFocus:i,...t,document:Ge(i)});try{n.activate()}catch{}}});return function(){n==null||n.deactivate(),r()}}var Za="data-scroll-lock";function mw(e){const t=e.getBoundingClientRect().left;return Math.round(t)+e.scrollLeft?"paddingLeft":"paddingRight"}function vw(e){const t=e??document,n=t.defaultView??window,{documentElement:r,body:i}=t;if(i.hasAttribute(Za))return;const s=n.innerWidth-r.clientWidth;i.setAttribute(Za,"");const a=()=>Sx(r,"--scrollbar-width",`${s}px`),l=mw(r),c=()=>Po(i,{overflow:"hidden",[l]:`${s}px`}),u=()=>{const{scrollX:h,scrollY:m,visualViewport:f}=n,g=(f==null?void 0:f.offsetLeft)??0,p=(f==null?void 0:f.offsetTop)??0,v=Po(i,{position:"fixed",overflow:"hidden",top:`${-(m-Math.floor(p))}px`,left:`${-(h-Math.floor(g))}px`,right:"0",[l]:`${s}px`});return()=>{v==null||v(),n.scrollTo({left:h,top:m,behavior:"instant"})}},d=[a(),xo()?u():c()];return()=>{d.forEach(h=>h==null?void 0:h()),i.removeAttribute(Za)}}var el=G("dialog").parts("trigger","backdrop","positioner","content","title","description","closeTrigger"),Vn=el.build(),uh=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`dialog:${e.id}:positioner`},dh=e=>{var t;return((t=e.ids)==null?void 0:t.backdrop)??`dialog:${e.id}:backdrop`},tl=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`dialog:${e.id}:content`},hh=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`dialog:${e.id}:trigger`},nl=e=>{var t;return((t=e.ids)==null?void 0:t.title)??`dialog:${e.id}:title`},rl=e=>{var t;return((t=e.ids)==null?void 0:t.description)??`dialog:${e.id}:description`},fh=e=>{var t;return((t=e.ids)==null?void 0:t.closeTrigger)??`dialog:${e.id}:close`},Jo=e=>e.getById(tl(e)),bw=e=>e.getById(uh(e)),yw=e=>e.getById(dh(e)),xw=e=>e.getById(hh(e)),Cw=e=>e.getById(nl(e)),Sw=e=>e.getById(rl(e)),ww=e=>e.getById(fh(e));function Ew(e,t){const{state:n,send:r,context:i,prop:o,scope:s}=e,a=o("aria-label"),l=n.matches("open");return{open:l,setOpen(c){n.matches("open")!==c&&r({type:c?"OPEN":"CLOSE"})},getTriggerProps(){return t.button({...Vn.trigger.attrs,dir:o("dir"),id:hh(s),"aria-haspopup":"dialog",type:"button","aria-expanded":l,"data-state":l?"open":"closed","aria-controls":tl(s),onClick(c){c.defaultPrevented||r({type:"TOGGLE"})}})},getBackdropProps(){return t.element({...Vn.backdrop.attrs,dir:o("dir"),hidden:!l,id:dh(s),"data-state":l?"open":"closed"})},getPositionerProps(){return t.element({...Vn.positioner.attrs,dir:o("dir"),id:uh(s),style:{pointerEvents:l?void 0:"none"}})},getContentProps(){const c=i.get("rendered");return t.element({...Vn.content.attrs,dir:o("dir"),role:o("role"),hidden:!l,id:tl(s),tabIndex:-1,"data-state":l?"open":"closed","aria-modal":!0,"aria-label":a||void 0,"aria-labelledby":a||!c.title?void 0:nl(s),"aria-describedby":c.description?rl(s):void 0})},getTitleProps(){return t.element({...Vn.title.attrs,dir:o("dir"),id:nl(s)})},getDescriptionProps(){return t.element({...Vn.description.attrs,dir:o("dir"),id:rl(s)})},getCloseTriggerProps(){return t.button({...Vn.closeTrigger.attrs,dir:o("dir"),id:fh(s),type:"button",onClick(c){c.defaultPrevented||(c.stopPropagation(),r({type:"CLOSE"}))}})}}}var kw={props({props:e,scope:t}){const n=e.role==="alertdialog",r=n?()=>ww(t):void 0,i=typeof e.modal=="boolean"?e.modal:!0;return{role:"dialog",modal:i,trapFocus:i,preventScroll:i,closeOnInteractOutside:!n,closeOnEscape:!0,restoreFocus:!0,initialFocusEl:r,...e}},initialState({prop:e}){return e("open")||e("defaultOpen")?"open":"closed"},context({bindable:e}){return{rendered:e(()=>({defaultValue:{title:!0,description:!0}}))}},watch({track:e,action:t,prop:n}){e([()=>n("open")],()=>{t(["toggleVisibility"])})},states:{open:{entry:["checkRenderedElements","syncZIndex"],effects:["trackDismissableElement","trapFocus","preventScroll","hideContentBelow"],on:{"CONTROLLED.CLOSE":{target:"closed"},CLOSE:[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"closed",actions:["invokeOnClose"]}],TOGGLE:[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"closed",actions:["invokeOnClose"]}]}},closed:{on:{"CONTROLLED.OPEN":{target:"open"},OPEN:[{guard:"isOpenControlled",actions:["invokeOnOpen"]},{target:"open",actions:["invokeOnOpen"]}],TOGGLE:[{guard:"isOpenControlled",actions:["invokeOnOpen"]},{target:"open",actions:["invokeOnOpen"]}]}}},implementations:{guards:{isOpenControlled:({prop:e})=>e("open")!=null},effects:{trackDismissableElement({scope:e,send:t,prop:n}){return Cr(()=>Jo(e),{defer:!0,pointerBlocking:n("modal"),exclude:[xw(e)],onInteractOutside(i){var o;(o=n("onInteractOutside"))==null||o(i),n("closeOnInteractOutside")||i.preventDefault()},persistentElements:n("persistentElements"),onFocusOutside:n("onFocusOutside"),onPointerDownOutside:n("onPointerDownOutside"),onRequestDismiss:n("onRequestDismiss"),onEscapeKeyDown(i){var o;(o=n("onEscapeKeyDown"))==null||o(i),n("closeOnEscape")||i.preventDefault()},onDismiss(){t({type:"CLOSE",src:"interact-outside"})}})},preventScroll({scope:e,prop:t}){if(t("preventScroll"))return vw(e.getDoc())},trapFocus({scope:e,prop:t}){return t("trapFocus")?pw(()=>Jo(e),{preventScroll:!0,returnFocusOnDeactivate:!!t("restoreFocus"),initialFocus:t("initialFocusEl"),setReturnFocus:r=>{var i;return((i=t("finalFocusEl"))==null?void 0:i())??r}}):void 0},hideContentBelow({scope:e,prop:t}){return t("modal")?Kd(()=>[Jo(e)],{defer:!0}):void 0}},actions:{checkRenderedElements({context:e,scope:t}){Z(()=>{e.set("rendered",{title:!!Cw(t),description:!!Sw(t)})})},syncZIndex({scope:e}){Z(()=>{const t=Jo(e);if(!t)return;const n=bo(t);[bw(e),yw(e)].forEach(i=>{i==null||i.style.setProperty("--z-index",n.zIndex),i==null||i.style.setProperty("--layer-index",n.getPropertyValue("--layer-index"))})})},invokeOnClose({prop:e}){var t;(t=e("onOpenChange"))==null||t({open:!1})},invokeOnOpen({prop:e}){var t;(t=e("onOpenChange"))==null||t({open:!0})},toggleVisibility({prop:e,send:t,event:n}){t({type:e("open")?"CONTROLLED.OPEN":"CONTROLLED.CLOSE",previousEvent:n})}}}};U()(["aria-label","closeOnEscape","closeOnInteractOutside","dir","finalFocusEl","getRootNode","getRootNode","id","id","ids","initialFocusEl","modal","onEscapeKeyDown","onFocusOutside","onInteractOutside","onOpenChange","onPointerDownOutside","onRequestDismiss","defaultOpen","open","persistentElements","preventScroll","restoreFocus","role","trapFocus"]);const Ow=e=>{const t=E.useId(),{getRootNode:n}=pu(),{dir:r}=Ax(),i={id:t,getRootNode:n,dir:r,...e},o=Lu(kw,i);return Ew(o,Mx)},Iw=e=>{const[t,{children:n,...r}]=Vu(e),[i]=Pd(t),o=Ow(r),s=Ta(pt({present:o.open},t));return y.jsx(nh,{value:o,children:y.jsx(Id,{value:i,children:y.jsx(Mu,{value:s,children:n})})})},Pw=e=>{const[t,{value:n,children:r}]=Vu(e),[i]=Pd(t),o=Ta(pt({present:n.open},t));return y.jsx(nh,{value:n,children:y.jsx(Id,{value:i,children:y.jsx(Mu,{value:o,children:r})})})},gh=E.forwardRef((e,t)=>{const n=on(),r=pt(n.getTitleProps(),e);return y.jsx(en.h2,{...r,ref:t})});gh.displayName="DialogTitle";const ph=E.forwardRef((e,t)=>{const n=on(),r=Na(),i=pt({...n.getTriggerProps(),"aria-controls":r.unmounted?void 0:n.getTriggerProps()["aria-controls"]},e);return y.jsx(en.button,{...i,ref:t})});ph.displayName="DialogTrigger";var mh=G("editable").parts("root","area","label","preview","input","editTrigger","submitTrigger","cancelTrigger","control");mh.build(),U()(["activationMode","autoResize","dir","disabled","finalFocusEl","form","getRootNode","id","ids","invalid","maxLength","name","onEditChange","onFocusOutside","onInteractOutside","onPointerDownOutside","onValueChange","onValueCommit","onValueRevert","placeholder","readOnly","required","selectOnFocus","edit","defaultEdit","submitMode","translations","defaultValue","value"]);const vh=G("field").parts("root","errorText","helperText","input","label","select","textarea","requiredIndicator");vh.build();var Rw=e=>{var c,u;if(!e)return;const t=bo(e),n=Ie(e),r=Ge(e),i=()=>{requestAnimationFrame(()=>{e.style.height="auto";let d;t.boxSizing==="content-box"?d=e.scrollHeight-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):d=e.scrollHeight+parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),t.maxHeight!=="none"&&d>parseFloat(t.maxHeight)?(t.overflowY==="hidden"&&(e.style.overflowY="scroll"),d=parseFloat(t.maxHeight)):t.overflowY!=="hidden"&&(e.style.overflowY="hidden"),e.style.height=`${d}px`})};e.addEventListener("input",i),(c=e.form)==null||c.addEventListener("reset",i);const o=Object.getPrototypeOf(e),s=Object.getOwnPropertyDescriptor(o,"value");Object.defineProperty(e,"value",{...s,set(){var d;(d=s==null?void 0:s.set)==null||d.apply(this,arguments),i()}});const a=new n.ResizeObserver(()=>{requestAnimationFrame(()=>i())});a.observe(e);const l=new n.MutationObserver(()=>i());return l.observe(e,{attributes:!0,attributeFilter:["rows","placeholder"]}),(u=r.fonts)==null||u.addEventListener("loadingdone",i),()=>{var d,h;e.removeEventListener("input",i),(d=e.form)==null||d.removeEventListener("reset",i),(h=r.fonts)==null||h.removeEventListener("loadingdone",i),a.disconnect(),l.disconnect()}};const bh=E.forwardRef((e,t)=>{const{autoresize:n,...r}=e,i=E.useRef(null),o=ES(),s=pt(o==null?void 0:o.getTextareaProps(),{style:{resize:n?"none":void 0}},r);return E.useEffect(()=>{if(n)return Rw(i.current)},[n]),y.jsx(en.textarea,{...s,ref:Ro(t,i)})});bh.displayName="FieldTextarea";const yh=G("fieldset").parts("root","errorText","helperText","legend");yh.build();var xh=G("file-upload").parts("root","dropzone","item","itemDeleteTrigger","itemGroup","itemName","itemPreview","itemPreviewImage","itemSizeText","label","trigger","clearTrigger");xh.build(),U()(["accept","acceptedFiles","allowDrop","capture","defaultAcceptedFiles","dir","directory","disabled","getRootNode","id","ids","invalid","locale","maxFiles","maxFileSize","minFileSize","name","onFileAccept","onFileChange","onFileReject","preventDocumentDrop","required","transformFiles","translations","validate"]),U()(["file"]);var Ch=G("hoverCard").parts("arrow","arrowTip","trigger","positioner","content");Ch.build();var Tw=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`hover-card:${e.id}:trigger`},Nw=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`hover-card:${e.id}:content`},Aw=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`hover-card:${e.id}:popper`},il=e=>e.getById(Tw(e)),_w=e=>e.getById(Nw(e)),Sh=e=>e.getById(Aw(e)),{not:Zo,and:wh}=Zt();wh("isOpenControlled",Zo("isPointer")),Zo("isPointer"),wh("isOpenControlled",Zo("isPointer")),Zo("isPointer"),U()(["closeDelay","dir","getRootNode","id","ids","disabled","onOpenChange","defaultOpen","open","openDelay","positioning","onInteractOutside","onPointerDownOutside","onFocusOutside"]);var Eh=G("tree-view").parts("branch","branchContent","branchControl","branchIndentGuide","branchIndicator","branchText","branchTrigger","item","itemIndicator","itemText","label","nodeCheckbox","root","tree");Eh.build();var kh=e=>new Gd(e);kh.empty=()=>new Gd({rootNode:{children:[]}});var Vw=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.node)==null?void 0:r.call(n,t))??`tree:${e.id}:node:${t}`},Fn=(e,t)=>{var n;t!=null&&((n=e.getById(Vw(e,t)))==null||n.focus())};function Fw(e,t,n){const r=e.getDescendantValues(t),i=r.every(o=>n.includes(o));return ur(i?On(n,...r):kn(n,...r))}function es(e,t){const{context:n,prop:r,refs:i}=e;if(!r("loadChildren")){n.set("expandedValue",g=>ur(kn(g,...t)));return}const o=n.get("loadingStatus"),[s,a]=nu(t,g=>o[g]==="loaded");if(s.length>0&&n.set("expandedValue",g=>ur(kn(g,...s))),a.length===0)return;const l=r("collection"),[c,u]=nu(a,g=>{const p=l.findNode(g);return l.getNodeChildren(p).length>0});if(c.length>0&&n.set("expandedValue",g=>ur(kn(g,...c))),u.length===0)return;n.set("loadingStatus",g=>({...g,...u.reduce((p,v)=>({...p,[v]:"loading"}),{})}));const d=u.map(g=>{const p=l.getIndexPath(g),v=l.getValuePath(p),x=l.findNode(g);return{id:g,indexPath:p,valuePath:v,node:x}}),h=i.get("pendingAborts"),m=r("loadChildren");gu(m,()=>"[zag-js/tree-view] `loadChildren` is required for async expansion");const f=d.map(({id:g,indexPath:p,valuePath:v,node:x})=>{const S=h.get(g);S&&(S.abort(),h.delete(g));const C=new AbortController;return h.set(g,C),m({valuePath:v,indexPath:p,node:x,signal:C.signal})});Promise.allSettled(f).then(g=>{var C,w;const p=[],v=[],x=n.get("loadingStatus");let S=r("collection");g.forEach((P,_)=>{const{id:R,indexPath:N,node:T,valuePath:j}=d[_];P.status==="fulfilled"?(x[R]="loaded",p.push(R),S=S.replace(N,{...T,children:P.value})):(h.delete(R),Reflect.deleteProperty(x,R),v.push({node:T,error:P.reason,indexPath:N,valuePath:j}))}),n.set("loadingStatus",x),p.length&&(n.set("expandedValue",P=>ur(kn(P,...p))),(C=r("onLoadChildrenComplete"))==null||C({collection:S})),v.length&&((w=r("onLoadChildrenError"))==null||w({nodes:v}))})}function sn(e){const{prop:t,context:n}=e;return function({indexPath:i}){return t("collection").getValuePath(i).slice(0,-1).some(s=>!n.get("expandedValue").includes(s))}}var{and:Nt}=Zt();Nt("isMultipleSelection","moveFocus"),Nt("isShiftKey","isMultipleSelection"),Nt("isShiftKey","isMultipleSelection"),Nt("isBranchFocused","isBranchExpanded"),Nt("isShiftKey","isMultipleSelection"),Nt("isShiftKey","isMultipleSelection"),Nt("isCtrlKey","isMultipleSelection"),Nt("isShiftKey","isMultipleSelection"),Nt("isCtrlKey","isMultipleSelection"),Nt("isShiftKey","isMultipleSelection"),U()(["ids","collection","dir","expandedValue","expandOnClick","defaultFocusedValue","focusedValue","getRootNode","id","onExpandedChange","onFocusChange","onSelectionChange","checkedValue","selectedValue","selectionMode","typeahead","defaultExpandedValue","defaultSelectedValue","defaultCheckedValue","onCheckedChange","onLoadChildrenComplete","onLoadChildrenError","loadChildren"]),U()(["node","indexPath"]);var Oh=G("listbox").parts("label","input","item","itemText","itemIndicator","itemGroup","itemGroupLabel","content","root","valueText");Oh.build(),U()(["collection","defaultHighlightedValue","defaultValue","dir","disabled","deselectable","disallowSelectAll","getRootNode","highlightedValue","id","ids","loopFocus","onHighlightChange","onSelect","onValueChange","orientation","scrollToIndexFn","selectionMode","selectOnHighlight","typeahead","value"]),U()(["item","highlightOnHover"]),U()(["id"]),U()(["htmlFor"]);const Lw=Oh.extendWith("empty");var Ih=G("menu").parts("arrow","arrowTip","content","contextTrigger","indicator","item","itemGroup","itemGroupLabel","itemIndicator","itemText","positioner","separator","trigger","triggerItem");Ih.build();var Ph=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`menu:${e.id}:trigger`},Dw=e=>{var t;return((t=e.ids)==null?void 0:t.contextTrigger)??`menu:${e.id}:ctx-trigger`},Rh=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`menu:${e.id}:content`},zw=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`menu:${e.id}:popper`},ol=(e,t)=>`${e.id}/${t}`,Ln=e=>(e==null?void 0:e.dataset.value)??null,an=e=>e.getById(Rh(e)),Th=e=>e.getById(zw(e)),ts=e=>e.getById(Ph(e)),Mw=(e,t)=>t?e.getById(ol(e,t)):null,sl=e=>e.getById(Dw(e)),xi=e=>{const n=`[role^="menuitem"][data-ownedby=${CSS.escape(Rh(e))}]:not([data-disabled])`;return Io(an(e),n)},$w=e=>oi(xi(e)),Bw=e=>ha(xi(e)),al=(e,t)=>t?e.id===t||e.dataset.value===t:!1,jw=(e,t)=>{const n=xi(e),r=n.findIndex(i=>al(i,t.value));return Uy(n,r,{loop:t.loop??t.loopFocus})},Ww=(e,t)=>{const n=xi(e),r=n.findIndex(i=>al(i,t.value));return qy(n,r,{loop:t.loop??t.loopFocus})},Hw=(e,t)=>{const n=xi(e),r=n.find(i=>al(i,t.value));return ci(n,{state:t.typeaheadState,key:t.key,activeId:(r==null?void 0:r.id)??null})},Uw=e=>{var t;return!!((t=e==null?void 0:e.getAttribute("role"))!=null&&t.startsWith("menuitem"))&&!!(e!=null&&e.hasAttribute("aria-controls"))},Gw="menu:select";function qw(e,t){if(!e)return;const n=Ie(e),r=new n.CustomEvent(Gw,{detail:{value:t}});e.dispatchEvent(r)}var{not:ct,and:kr,or:Kw}=Zt();ct("isSubmenu"),Kw("isOpenAutoFocusEvent","isArrowDownEvent"),kr(ct("isTriggerItem"),"isOpenControlled"),ct("isTriggerItem"),kr("isSubmenu","isOpenControlled"),ct("isPointerSuspended"),kr(ct("isPointerSuspended"),ct("isTriggerItem")),kr(ct("isTriggerItemHighlighted"),ct("isHighlightedItemEditable"),"closeOnSelect","isOpenControlled"),kr(ct("isTriggerItemHighlighted"),ct("isHighlightedItemEditable"),"closeOnSelect"),kr(ct("isTriggerItemHighlighted"),ct("isHighlightedItemEditable"));function Nh(e){let t=e.parent;for(;t&&t.context.get("isSubmenu");)t=t.refs.get("parent");t==null||t.send({type:"CLOSE"})}function Xw(e,t){return e?pS(e,t):!1}function Yw(e,t,n){const r=Object.keys(e).length>0;if(!t)return null;if(!r)return ol(n,t);for(const i in e){const o=e[i],s=Ph(o.scope);if(s===t)return s}return ol(n,t)}U()(["anchorPoint","aria-label","closeOnSelect","composite","defaultHighlightedValue","defaultOpen","dir","getRootNode","highlightedValue","id","ids","loopFocus","navigate","onEscapeKeyDown","onFocusOutside","onHighlightChange","onInteractOutside","onOpenChange","onPointerDownOutside","onRequestDismiss","onSelect","open","positioning","typeahead"]),U()(["closeOnSelect","disabled","value","valueText"]),U()(["htmlFor"]),U()(["id"]),U()(["checked","closeOnSelect","disabled","onCheckedChange","type","value","valueText"]);let ll=new Map,cl=!1;try{cl=new Intl.NumberFormat("de-DE",{signDisplay:"exceptZero"}).resolvedOptions().signDisplay==="exceptZero"}catch{}let ns=!1;try{ns=new Intl.NumberFormat("de-DE",{style:"unit",unit:"degree"}).resolvedOptions().style==="unit"}catch{}const Ah={degree:{narrow:{default:"°","ja-JP":" 度","zh-TW":"度","sl-SI":" °"}}};class Qw{format(t){let n="";if(!cl&&this.options.signDisplay!=null?n=Zw(this.numberFormatter,this.options.signDisplay,t):n=this.numberFormatter.format(t),this.options.style==="unit"&&!ns){var r;let{unit:i,unitDisplay:o="short",locale:s}=this.resolvedOptions();if(!i)return n;let a=(r=Ah[i])===null||r===void 0?void 0:r[o];n+=a[s]||a.default}return n}formatToParts(t){return this.numberFormatter.formatToParts(t)}formatRange(t,n){if(typeof this.numberFormatter.formatRange=="function")return this.numberFormatter.formatRange(t,n);if(n= start date");return`${this.format(t)} – ${this.format(n)}`}formatRangeToParts(t,n){if(typeof this.numberFormatter.formatRangeToParts=="function")return this.numberFormatter.formatRangeToParts(t,n);if(n= start date");let r=this.numberFormatter.formatToParts(t),i=this.numberFormatter.formatToParts(n);return[...r.map(o=>({...o,source:"startRange"})),{type:"literal",value:" – ",source:"shared"},...i.map(o=>({...o,source:"endRange"}))]}resolvedOptions(){let t=this.numberFormatter.resolvedOptions();return!cl&&this.options.signDisplay!=null&&(t={...t,signDisplay:this.options.signDisplay}),!ns&&this.options.style==="unit"&&(t={...t,style:"unit",unit:this.options.unit,unitDisplay:this.options.unitDisplay}),t}constructor(t,n={}){this.numberFormatter=Jw(t,n),this.options=n}}function Jw(e,t={}){let{numberingSystem:n}=t;if(n&&e.includes("-nu-")&&(e.includes("-u-")||(e+="-u-"),e+=`-nu-${n}`),t.style==="unit"&&!ns){var r;let{unit:s,unitDisplay:a="short"}=t;if(!s)throw new Error('unit option must be provided with style: "unit"');if(!(!((r=Ah[s])===null||r===void 0)&&r[a]))throw new Error(`Unsupported unit ${s} with unitDisplay = ${a}`);t={...t,style:"decimal"}}let i=e+(t?Object.entries(t).sort((s,a)=>s[0]0||Object.is(n,0):t==="exceptZero"&&(Object.is(n,-0)||Object.is(n,0)?n=Math.abs(n):r=n>0),r){let i=e.format(-n),o=e.format(n),s=i.replace(o,"").replace(/\u200e|\u061C/,"");return[...s].length!==1&&console.warn("@react-aria/i18n polyfill for NumberFormat signDisplay: Unsupported case"),i.replace(o,"!!!").replace(s,"+").replace("!!!",o)}else return e.format(n)}}const eE=new RegExp("^.*\\(.*\\).*$"),tE=["latn","arab","hanidec","deva","beng","fullwide"];class _h{parse(t){return ul(this.locale,this.options,t).parse(t)}isValidPartialNumber(t,n,r){return ul(this.locale,this.options,t).isValidPartialNumber(t,n,r)}getNumberingSystem(t){return ul(this.locale,this.options,t).options.numberingSystem}constructor(t,n={}){this.locale=t,this.options=n}}const Vh=new Map;function ul(e,t,n){let r=Fh(e,t);if(!e.includes("-nu-")&&!r.isValidPartialNumber(n)){for(let i of tE)if(i!==r.options.numberingSystem){let o=Fh(e+(e.includes("-u-")?"-nu-":"-u-nu-")+i,t);if(o.isValidPartialNumber(n))return o}}return r}function Fh(e,t){let n=e+(t?Object.entries(t).sort((i,o)=>i[0]-1&&(n=`-${n}`)}let r=n?+n:NaN;if(isNaN(r))return NaN;if(this.options.style==="percent"){var i,o;let s={...this.options,style:"decimal",minimumFractionDigits:Math.min(((i=this.options.minimumFractionDigits)!==null&&i!==void 0?i:0)+2,20),maximumFractionDigits:Math.min(((o=this.options.maximumFractionDigits)!==null&&o!==void 0?o:0)+2,20)};return new _h(this.locale,s).parse(new Qw(this.locale,s).format(r))}return this.options.currencySign==="accounting"&&eE.test(t)&&(r=-1*r),r}sanitize(t){return t=t.replace(this.symbols.literals,""),this.symbols.minusSign&&(t=t.replace("-",this.symbols.minusSign)),this.options.numberingSystem==="arab"&&(this.symbols.decimal&&(t=t.replace(",",this.symbols.decimal),t=t.replace("،",this.symbols.decimal)),this.symbols.group&&(t=Ci(t,".",this.symbols.group))),this.options.locale==="fr-FR"&&this.symbols.group&&(t=Ci(t," ",this.symbols.group),t=Ci(t,/\u00A0/g,this.symbols.group)),t}isValidPartialNumber(t,n=-1/0,r=1/0){return t=this.sanitize(t),this.symbols.minusSign&&t.startsWith(this.symbols.minusSign)&&n<0?t=t.slice(this.symbols.minusSign.length):this.symbols.plusSign&&t.startsWith(this.symbols.plusSign)&&r>0&&(t=t.slice(this.symbols.plusSign.length)),this.symbols.group&&t.startsWith(this.symbols.group)||this.symbols.decimal&&t.indexOf(this.symbols.decimal)>-1&&this.options.maximumFractionDigits===0?!1:(this.symbols.group&&(t=Ci(t,this.symbols.group,"")),t=t.replace(this.symbols.numeral,""),this.symbols.decimal&&(t=t.replace(this.symbols.decimal,"")),t.length===0)}constructor(t,n={}){this.locale=t,n.roundingIncrement!==1&&n.roundingIncrement!=null&&(n.maximumFractionDigits==null&&n.minimumFractionDigits==null?(n.maximumFractionDigits=0,n.minimumFractionDigits=0):n.maximumFractionDigits==null?n.maximumFractionDigits=n.minimumFractionDigits:n.minimumFractionDigits==null&&(n.minimumFractionDigits=n.maximumFractionDigits)),this.formatter=new Intl.NumberFormat(t,n),this.options=this.formatter.resolvedOptions(),this.symbols=iE(t,this.formatter,this.options,n);var r,i;this.options.style==="percent"&&(((r=this.options.minimumFractionDigits)!==null&&r!==void 0?r:0)>18||((i=this.options.maximumFractionDigits)!==null&&i!==void 0?i:0)>18)&&console.warn("NumberParser cannot handle percentages with greater than 18 decimal places, please reduce the number in your options.")}}const Lh=new Set(["decimal","fraction","integer","minusSign","plusSign","group"]),rE=[0,4,2,1,11,20,3,7,100,21,.1,1.1];function iE(e,t,n,r){var i,o,s,a;let l=new Intl.NumberFormat(e,{...n,minimumSignificantDigits:1,maximumSignificantDigits:21,roundingIncrement:1,roundingPriority:"auto",roundingMode:"halfExpand"}),c=l.formatToParts(-10000.111),u=l.formatToParts(10000.111),d=rE.map(T=>l.formatToParts(T));var h;let m=(h=(i=c.find(T=>T.type==="minusSign"))===null||i===void 0?void 0:i.value)!==null&&h!==void 0?h:"-",f=(o=u.find(T=>T.type==="plusSign"))===null||o===void 0?void 0:o.value;!f&&((r==null?void 0:r.signDisplay)==="exceptZero"||(r==null?void 0:r.signDisplay)==="always")&&(f="+");let p=(s=new Intl.NumberFormat(e,{...n,minimumFractionDigits:2,maximumFractionDigits:2}).formatToParts(.001).find(T=>T.type==="decimal"))===null||s===void 0?void 0:s.value,v=(a=c.find(T=>T.type==="group"))===null||a===void 0?void 0:a.value,x=c.filter(T=>!Lh.has(T.type)).map(T=>Dh(T.value)),S=d.flatMap(T=>T.filter(j=>!Lh.has(j.type)).map(j=>Dh(j.value))),C=[...new Set([...x,...S])].sort((T,j)=>j.length-T.length),w=C.length===0?new RegExp("[\\p{White_Space}]","gu"):new RegExp(`${C.join("|")}|[\\p{White_Space}]`,"gu"),P=[...new Intl.NumberFormat(n.locale,{useGrouping:!1}).format(9876543210)].reverse(),_=new Map(P.map((T,j)=>[T,j])),R=new RegExp(`[${P.join("")}]`,"g");return{minusSign:m,plusSign:f,decimal:p,group:v,literals:w,numeral:R,index:T=>String(_.get(T))}}function Ci(e,t,n){return e.replaceAll?e.replaceAll(t,n):e.split(t).join(n)}function Dh(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var zh=G("numberInput").parts("root","label","input","control","valueText","incrementTrigger","decrementTrigger","scrubber");zh.build();var oE=e=>{var t;return((t=e.ids)==null?void 0:t.input)??`number-input:${e.id}:input`},sE=e=>{var t;return((t=e.ids)==null?void 0:t.incrementTrigger)??`number-input:${e.id}:inc`},aE=e=>{var t;return((t=e.ids)==null?void 0:t.decrementTrigger)??`number-input:${e.id}:dec`},Mh=e=>`number-input:${e.id}:cursor`,rs=e=>e.getById(oE(e)),lE=e=>e.getById(sE(e)),cE=e=>e.getById(aE(e)),$h=e=>e.getDoc().getElementById(Mh(e)),uE=(e,t)=>{let n=null;return t==="increment"&&(n=lE(e)),t==="decrement"&&(n=cE(e)),n},dE=(e,t)=>{if(!wu())return gE(e,t),()=>{var n;(n=$h(e))==null||n.remove()}},hE=e=>{const t=e.getDoc(),n=t.documentElement,r=t.body;return r.style.pointerEvents="none",n.style.userSelect="none",n.style.cursor="ew-resize",()=>{r.style.pointerEvents="",n.style.userSelect="",n.style.cursor="",n.style.length||n.removeAttribute("style"),r.style.length||r.removeAttribute("style")}},fE=(e,t)=>{const{point:n,isRtl:r,event:i}=t,o=e.getWin(),s=pa(i.movementX,o.devicePixelRatio),a=pa(i.movementY,o.devicePixelRatio);let l=s>0?"increment":s<0?"decrement":null;r&&l==="increment"&&(l="decrement"),r&&l==="decrement"&&(l="increment");const c={x:n.x+s,y:n.y+a},u=o.innerWidth,d=pa(7.5,o.devicePixelRatio);return c.x=u0(c.x+d,u)-d,{hint:l,point:c}},gE=(e,t)=>{const n=e.getDoc(),r=n.createElement("div");r.className="scrubber--cursor",r.id=Mh(e),Object.assign(r.style,{width:"15px",height:"15px",position:"fixed",pointerEvents:"none",left:"0px",top:"0px",zIndex:w0,transform:t?`translate3d(${t.x}px, ${t.y}px, 0px)`:void 0,willChange:"transform"}),r.innerHTML=` + */var ke=typeof Symbol=="function"&&Symbol.for,Zs=ke?Symbol.for("react.element"):60103,ea=ke?Symbol.for("react.portal"):60106,to=ke?Symbol.for("react.fragment"):60107,no=ke?Symbol.for("react.strict_mode"):60108,ro=ke?Symbol.for("react.profiler"):60114,io=ke?Symbol.for("react.provider"):60109,oo=ke?Symbol.for("react.context"):60110,ta=ke?Symbol.for("react.async_mode"):60111,so=ke?Symbol.for("react.concurrent_mode"):60111,ao=ke?Symbol.for("react.forward_ref"):60112,lo=ke?Symbol.for("react.suspense"):60113,ny=ke?Symbol.for("react.suspense_list"):60120,co=ke?Symbol.for("react.memo"):60115,uo=ke?Symbol.for("react.lazy"):60116,ry=ke?Symbol.for("react.block"):60121,iy=ke?Symbol.for("react.fundamental"):60117,oy=ke?Symbol.for("react.responder"):60118,sy=ke?Symbol.for("react.scope"):60119;function et(e){if(typeof e=="object"&&e!==null){var t=e.$$typeof;switch(t){case Zs:switch(e=e.type,e){case ta:case so:case to:case ro:case no:case lo:return e;default:switch(e=e&&e.$$typeof,e){case oo:case ao:case uo:case co:case io:return e;default:return t}}case ea:return t}}}function zc(e){return et(e)===so}ae.AsyncMode=ta,ae.ConcurrentMode=so,ae.ContextConsumer=oo,ae.ContextProvider=io,ae.Element=Zs,ae.ForwardRef=ao,ae.Fragment=to,ae.Lazy=uo,ae.Memo=co,ae.Portal=ea,ae.Profiler=ro,ae.StrictMode=no,ae.Suspense=lo,ae.isAsyncMode=function(e){return zc(e)||et(e)===ta},ae.isConcurrentMode=zc,ae.isContextConsumer=function(e){return et(e)===oo},ae.isContextProvider=function(e){return et(e)===io},ae.isElement=function(e){return typeof e=="object"&&e!==null&&e.$$typeof===Zs},ae.isForwardRef=function(e){return et(e)===ao},ae.isFragment=function(e){return et(e)===to},ae.isLazy=function(e){return et(e)===uo},ae.isMemo=function(e){return et(e)===co},ae.isPortal=function(e){return et(e)===ea},ae.isProfiler=function(e){return et(e)===ro},ae.isStrictMode=function(e){return et(e)===no},ae.isSuspense=function(e){return et(e)===lo},ae.isValidElementType=function(e){return typeof e=="string"||typeof e=="function"||e===to||e===so||e===ro||e===no||e===lo||e===ny||typeof e=="object"&&e!==null&&(e.$$typeof===uo||e.$$typeof===co||e.$$typeof===io||e.$$typeof===oo||e.$$typeof===ao||e.$$typeof===iy||e.$$typeof===oy||e.$$typeof===sy||e.$$typeof===ry)},ae.typeOf=et,Dc.exports=ae;var ay=Dc.exports,Mc=ay,ly={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},cy={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},$c={};$c[Mc.ForwardRef]=ly,$c[Mc.Memo]=cy;var uy=!0;function Bc(e,t,n){var r="";return n.split(" ").forEach(function(i){e[i]!==void 0?t.push(e[i]+";"):i&&(r+=i+" ")}),r}var na=function(t,n,r){var i=t.key+"-"+n.name;(r===!1||uy===!1)&&t.registered[i]===void 0&&(t.registered[i]=n.styles)},ra=function(t,n,r){na(t,n,r);var i=t.key+"-"+n.name;if(t.inserted[n.name]===void 0){var o=n;do t.insert(n===o?"."+i:"",o,t.sheet,!0),o=o.next;while(o!==void 0)}};function dy(e){for(var t=0,n,r=0,i=e.length;i>=4;++r,i-=4)n=e.charCodeAt(r)&255|(e.charCodeAt(++r)&255)<<8|(e.charCodeAt(++r)&255)<<16|(e.charCodeAt(++r)&255)<<24,n=(n&65535)*1540483477+((n>>>16)*59797<<16),n^=n>>>24,t=(n&65535)*1540483477+((n>>>16)*59797<<16)^(t&65535)*1540483477+((t>>>16)*59797<<16);switch(i){case 3:t^=(e.charCodeAt(r+2)&255)<<16;case 2:t^=(e.charCodeAt(r+1)&255)<<8;case 1:t^=e.charCodeAt(r)&255,t=(t&65535)*1540483477+((t>>>16)*59797<<16)}return t^=t>>>13,t=(t&65535)*1540483477+((t>>>16)*59797<<16),((t^t>>>15)>>>0).toString(36)}var hy={animationIterationCount:1,aspectRatio:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,scale:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},fy=/[A-Z]|^ms/g,gy=/_EMO_([^_]+?)_([^]*?)_EMO_/g,jc=function(t){return t.charCodeAt(1)===45},Wc=function(t){return t!=null&&typeof t!="boolean"},ia=Oc(function(e){return jc(e)?e:e.replace(fy,"-$&").toLowerCase()}),Hc=function(t,n){switch(t){case"animation":case"animationName":if(typeof n=="string")return n.replace(gy,function(r,i,o){return Ot={name:i,styles:o,next:Ot},i})}return hy[t]!==1&&!jc(t)&&typeof n=="number"&&n!==0?n+"px":n};function ii(e,t,n){if(n==null)return"";var r=n;if(r.__emotion_styles!==void 0)return r;switch(typeof n){case"boolean":return"";case"object":{var i=n;if(i.anim===1)return Ot={name:i.name,styles:i.styles,next:Ot},i.name;var o=n;if(o.styles!==void 0){var s=o.next;if(s!==void 0)for(;s!==void 0;)Ot={name:s.name,styles:s.styles,next:Ot},s=s.next;var a=o.styles+";";return a}return py(e,t,n)}case"function":{if(e!==void 0){var l=Ot,c=n(e);return Ot=l,ii(e,t,c)}break}}var u=n;if(t==null)return u;var d=t[u];return d!==void 0?d:u}function py(e,t,n){var r="";if(Array.isArray(n))for(var i=0;ir==null?void 0:r(...n))}}const Sy=(...e)=>e.map(t=>{var n;return(n=t==null?void 0:t.trim)==null?void 0:n.call(t)}).filter(Boolean).join(" "),wy=/^on[A-Z]/;function oi(...e){let t={};for(let n of e){for(let r in t){if(wy.test(r)&&typeof t[r]=="function"&&typeof n[r]=="function"){t[r]=Cy(t[r],n[r]);continue}if(r==="className"||r==="class"){t[r]=Sy(t[r],n[r]);continue}if(r==="style"){t[r]=Object.assign({},t[r]??{},n[r]??{});continue}t[r]=n[r]!==void 0?n[r]:t[r]}for(let r in n)t[r]===void 0&&(t[r]=n[r])}return t}function Ey(e,t){if(e!=null){if(typeof e=="function"){e(t);return}try{e.current=t}catch{throw new Error(`Cannot assign value '${t}' to ref '${e}'`)}}}function ky(...e){return t=>{e.forEach(n=>{Ey(n,t)})}}function si(e){const t=Object.assign({},e);for(let n in t)t[n]===void 0&&delete t[n];return t}const st=(...e)=>e.filter(Boolean).map(t=>t.trim()).join(" ");function Oy(e){return e.default||e}const He=e=>e!=null&&typeof e=="object"&&!Array.isArray(e),It=e=>typeof e=="string",ua=e=>typeof e=="function";function Iy(e){var n;const t=O.version;return!It(t)||t.startsWith("18.")?e==null?void 0:e.ref:(n=e==null?void 0:e.props)==null?void 0:n.ref}const Jc=(...e)=>{const t=e.reduce((n,r)=>(r!=null&&r.forEach(i=>n.add(i)),n),new Set([]));return Array.from(t)};function Py(e,t){return`${e} returned \`undefined\`. Seems you forgot to wrap component within ${t}`}function ur(e={}){const{name:t,strict:n=!0,hookName:r="useContext",providerName:i="Provider",errorMessage:o,defaultValue:s}=e,a=E.createContext(s);a.displayName=t;function l(){var u;const c=E.useContext(a);if(!c&&n){const d=new Error(o??Py(r,i));throw d.name="ContextError",(u=Error.captureStackTrace)==null||u.call(Error,d,l),d}return c}return[a.Provider,l,a]}const[Ry,ho]=ur({name:"ChakraContext",strict:!0,providerName:""});function Ty(e){const{value:t,children:n}=e;return x.jsxs(Ry,{value:t,children:[!t._config.disableLayers&&x.jsx(Qc,{styles:t.layers.atRule}),x.jsx(Qc,{styles:t._global}),n]})}const Ny=(e,t)=>{const n={},r={},i=Object.keys(e);for(const o of i)t(o)?r[o]=e[o]:n[o]=e[o];return[r,n]},dr=(e,t)=>{const n=ua(t)?t:r=>t.includes(r);return Ny(e,n)},Ay=new Set(["htmlWidth","htmlHeight","htmlSize","htmlTranslate"]);function _y(e){return typeof e=="string"&&Ay.has(e)}function Vy(e,t,n){const{css:r,isValidProperty:i}=ho(),{children:o,...s}=e,a=E.useMemo(()=>{const[h,m]=dr(s,C=>n(C,t.variantKeys)),[f,g]=dr(m,t.variantKeys),[p,b]=dr(g,i);return{forwardedProps:h,variantProps:f,styleProps:p,elementProps:b}},[t.variantKeys,n,s,i]),{css:l,...c}=a.styleProps,u=E.useMemo(()=>{const h={...a.variantProps};return t.variantKeys.includes("colorPalette")||(h.colorPalette=s.colorPalette),t.variantKeys.includes("orientation")||(h.orientation=s.orientation),t(h)},[t,a.variantProps,s.colorPalette,s.orientation]);return{styles:E.useMemo(()=>r(u,...Fy(l),c),[r,u,l,c]),props:{...a.forwardedProps,...a.elementProps,children:o}}}const Fy=e=>(Array.isArray(e)?e:[e]).filter(Boolean).flat(),Ly=Oy(Ob),Dy=e=>e!=="theme",zy=(e,t,n)=>{let r;if(t){const i=t.shouldForwardProp;r=e.__emotion_forwardProp&&i?o=>e.__emotion_forwardProp(o)&&i(o):i}return typeof r!="function"&&n&&(r=e.__emotion_forwardProp),r};let My=typeof document<"u";const Zc=({cache:e,serialized:t,isStringTag:n})=>{na(e,t,n);const r=qc(()=>ra(e,t,n));if(!My&&r!==void 0){let i=t.name,o=t.next;for(;o!==void 0;)i=st(i,o.name),o=o.next;return x.jsx("style",{"data-emotion":st(e.key,i),dangerouslySetInnerHTML:{__html:r},nonce:e.sheet.nonce})}return null},eu={path:["d"],text:["x","y"],circle:["cx","cy","r"],rect:["width","height","x","y","rx","ry"],ellipse:["cx","cy","rx","ry"],g:["transform"],stop:["offset","stopOpacity"]},$y=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),da=((e,t={},n={})=>{if($y(eu,e)){n.forwardProps||(n.forwardProps=[]);const c=eu[e];n.forwardProps=Jc([...n.forwardProps,...c])}const r=e.__emotion_real===e,i=r&&e.__emotion_base||e;let o,s;n!==void 0&&(o=n.label,s=n.target);let a=[];const l=sa((c,u,d)=>{var z;const{cva:h,isValidProperty:m}=ho(),f=t.__cva__?t:h(t),g=By(e.__emotion_cva,f),p=_=>(j,W)=>_.includes(j)?!0:!(W!=null&&W.includes(j))&&!m(j);!n.shouldForwardProp&&n.forwardProps&&(n.shouldForwardProp=p(n.forwardProps));const b=(_,j)=>{const W=typeof e=="string"&&e.charCodeAt(0)>96?Ly:Dy,M=!(j!=null&&j.includes(_))&&!m(_);return W(_)&&M},C=zy(e,n,r)||b,S=O.useMemo(()=>Object.assign({},n.defaultProps,si(c)),[c]),{props:y,styles:k}=Vy(S,g,C);let R="",A=[k],T=y;if(y.theme==null){T={};for(let _ in y)T[_]=y[_];T.theme=O.useContext(aa)}typeof y.className=="string"?R=Bc(u.registered,A,y.className):y.className!=null&&(R=st(R,y.className));const N=oa(a.concat(A),u.registered,T);N.styles&&(R=st(R,`${u.key}-${N.name}`)),s!==void 0&&(R=st(R,s));const I=!C("as");let B=I&&y.as||i,P={};for(let _ in y)if(!(I&&_==="as")){if(_y(_)){const j=_.replace("html","").toLowerCase();P[j]=y[_];continue}C(_)&&(P[_]=y[_])}let F=R.trim();F?P.className=F:Reflect.deleteProperty(P,"className"),P.ref=d;const X=n.forwardAsChild||((z=n.forwardProps)==null?void 0:z.includes("asChild"));if(y.asChild&&!X){const _=O.isValidElement(y.children)?O.Children.only(y.children):O.Children.toArray(y.children).find(O.isValidElement);if(!_)throw new Error("[chakra-ui > factory] No valid child found");B=_.type,P.children=null,Reflect.deleteProperty(P,"asChild"),P=oi(P,_.props),P.ref=ky(d,Iy(_))}return P.as&&X?(P.as=void 0,x.jsxs(O.Fragment,{children:[x.jsx(Zc,{cache:u,serialized:N,isStringTag:typeof B=="string"}),x.jsx(B,{asChild:!0,...P,children:x.jsx(y.as,{children:P.children})})]})):x.jsxs(O.Fragment,{children:[x.jsx(Zc,{cache:u,serialized:N,isStringTag:typeof B=="string"}),x.jsx(B,{...P})]})});return l.displayName=o!==void 0?o:`chakra(${typeof i=="string"?i:i.displayName||i.name||"Component"})`,l.__emotion_real=l,l.__emotion_base=i,l.__emotion_forwardProp=n.shouldForwardProp,l.__emotion_cva=t,Object.defineProperty(l,"toString",{value(){return`.${s}`}}),l}).bind(),ha=new Map,Oe=new Proxy(da,{apply(e,t,n){return da(...n)},get(e,t){return ha.has(t)||ha.set(t,da(t)),ha.get(t)}}),By=(e,t)=>e&&!t?e:!e&&t?t:e.merge(t),$t=Oe("div");$t.displayName="Box";const jy=Object.freeze({}),Wy=Object.freeze({});function Hy(e){const{key:t,recipe:n}=e,r=ho();return E.useMemo(()=>{const i=n||(t!=null?r.getRecipe(t):{});return r.cva(structuredClone(i))},[t,n,r])}const Uy=e=>e.charAt(0).toUpperCase()+e.slice(1);function ai(e){const{key:t,recipe:n}=e,r=Uy(t||n.className||"Component"),[i,o]=ur({strict:!1,name:`${r}PropsContext`,providerName:`${r}PropsContext`});function s(c){const{unstyled:u,...d}=c,h=Hy({key:t,recipe:d.recipe||n}),[m,f]=E.useMemo(()=>h.splitVariantProps(d),[h,d]);return{styles:u?jy:h(m),className:h.className,props:f}}const a=(c,u)=>{const d=Oe(c,{},u),h=E.forwardRef((m,f)=>{const g=o(),p=E.useMemo(()=>oi(g,m),[m,g]),{styles:b,className:C,props:S}=s(p);return x.jsx(d,{...S,ref:f,css:[b,p.css],className:st(C,p.className)})});return h.displayName=c.displayName||c.name,h};function l(){return i}return{withContext:a,PropsProvider:i,withPropsProvider:l,usePropsContext:o,useRecipeResult:s}}function fo(e){return e==null?[]:Array.isArray(e)?e:[e]}var li=e=>e[0],fa=e=>e[e.length-1],Gy=(e,t)=>e.indexOf(t)!==-1,In=(e,...t)=>e.concat(t),Pn=(e,...t)=>e.filter(n=>!t.includes(n)),hr=e=>Array.from(new Set(e)),ga=(e,t)=>{const n=new Set(t);return e.filter(r=>!n.has(r))},fr=(e,t)=>Gy(e,t)?Pn(e,t):In(e,t);function tu(e,t,n={}){const{step:r=1,loop:i=!0}=n,o=t+r,s=e.length,a=s-1;return t===-1?r>0?0:a:o<0?i?a:0:o>=s?i?0:t>s?s:t:o}function qy(e,t,n={}){return e[tu(e,t,n)]}function Ky(e,t,n={}){const{step:r=1,loop:i=!0}=n;return tu(e,t,{step:-r,loop:i})}function Xy(e,t,n={}){return e[Ky(e,t,n)]}function nu(e,t){return e.reduce(([n,r],i)=>(t(i)?n.push(i):r.push(i),[n,r]),[[],[]])}var ru=e=>(e==null?void 0:e.constructor.name)==="Array",Yy=(e,t)=>{if(e.length!==t.length)return!1;for(let n=0;n{if(Object.is(e,t))return!0;if(e==null&&t!=null||e!=null&&t==null)return!1;if(typeof(e==null?void 0:e.isEqual)=="function"&&typeof(t==null?void 0:t.isEqual)=="function")return e.isEqual(t);if(typeof e=="function"&&typeof t=="function")return e.toString()===t.toString();if(ru(e)&&ru(t))return Yy(Array.from(e),Array.from(t));if(typeof e!="object"||typeof t!="object")return!1;const n=Object.keys(t??Object.create(null)),r=n.length;for(let i=0;iArray.isArray(e),Qy=e=>e===!0||e===!1,iu=e=>e!=null&&typeof e=="object",Rn=e=>iu(e)&&!ci(e),go=e=>typeof e=="string",Tn=e=>typeof e=="function",Jy=e=>e==null,en=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),Zy=e=>Object.prototype.toString.call(e),ou=Function.prototype.toString,e0=ou.call(Object),t0=e=>{if(!iu(e)||Zy(e)!="[object Object]"||i0(e))return!1;const t=Object.getPrototypeOf(e);if(t===null)return!0;const n=en(t,"constructor")&&t.constructor;return typeof n=="function"&&n instanceof n&&ou.call(n)==e0},n0=e=>typeof e=="object"&&e!==null&&"$$typeof"in e&&"props"in e,r0=e=>typeof e=="object"&&e!==null&&"__v_isVNode"in e,i0=e=>n0(e)||r0(e),po=(e,...t)=>(typeof e=="function"?e(...t):e)??void 0,o0=e=>e(),s0=()=>{},mo=(...e)=>(...t)=>{e.forEach(function(n){n==null||n(...t)})},a0=(()=>{let e=0;return()=>(e++,e.toString(36))})();function Bt(e,t,...n){var i;if(e in t){const o=t[e];return Tn(o)?o(...n):o}const r=new Error(`No matching key: ${JSON.stringify(e)} in ${JSON.stringify(Object.keys(t))}`);throw(i=Error.captureStackTrace)==null||i.call(Error,r,Bt),r}var su=(e,t)=>{var n;try{return e()}catch(r){return r instanceof Error&&((n=Error.captureStackTrace)==null||n.call(Error,r,su)),t==null?void 0:t()}},{floor:au,abs:lu,round:vo,min:l0,max:c0,pow:u0,sign:d0}=Math,pa=e=>Number.isNaN(e),tn=e=>pa(e)?0:e,cu=(e,t)=>(e%t+t)%t,h0=(e,t)=>(e%t+t)%t,f0=(e,t)=>tn(e)>=t,g0=(e,t)=>tn(e)<=t,p0=(e,t,n)=>{const r=tn(e),i=t==null||r>=t,o=n==null||r<=n;return i&&o},m0=(e,t,n)=>vo((tn(e)-t)/n)*n+t,Ue=(e,t,n)=>l0(c0(tn(e),t),n),v0=(e,t,n)=>(tn(e)-t)/(n-t),b0=(e,t,n,r)=>Ue(m0(e*(n-t)+t,t,r),t,n),uu=(e,t)=>{let n=e,r=t.toString(),i=r.indexOf("."),o=i>=0?r.length-i:0;if(o>0){let s=u0(10,o);n=vo(n*s)/s}return n},ma=(e,t)=>typeof t=="number"?au(e*t+.5)/t:vo(e),du=(e,t,n,r)=>{const i=t!=null?Number(t):0,o=Number(n),s=(e-i)%r;let a=lu(s)*2>=r?e+d0(s)*(r-lu(s)):e-s;if(a=uu(a,r),!pa(i)&&ao){const l=au((o-i)/r),c=i+l*r;a=l<=0||c{const r=Math.pow(n,t);return vo(e*r)/r},hu=e=>{if(!Number.isFinite(e))return 0;let t=1,n=0;for(;Math.round(e*t)/t!==e;)t*=10,n+=1;return n},fu=(e,t,n)=>{let r=t==="+"?e+n:e-n;if(e%1!==0||n%1!==0){const i=10**Math.max(hu(e),hu(n));e=Math.round(e*i),n=Math.round(n*i),r=t==="+"?e+n:e-n,r/=i}return r},y0=(e,t)=>fu(tn(e),"+",t),x0=(e,t)=>fu(tn(e),"-",t);function bo(e){if(!t0(e)||e===void 0)return e;const t=Reflect.ownKeys(e).filter(r=>typeof r=="string"),n={};for(const r of t){const i=e[r];i!==void 0&&(n[r]=bo(i))}return n}function C0(e,t=Object.is){let n={...e};const r=new Set,i=u=>(r.add(u),()=>r.delete(u)),o=()=>{r.forEach(u=>u())};return{subscribe:i,get:u=>n[u],set:(u,d)=>{t(n[u],d)||(n[u]=d,o())},update:u=>{let d=!1;for(const h in u){const m=u[h];m!==void 0&&!t(n[h],m)&&(n[h]=m,d=!0)}d&&o()},snapshot:()=>({...n})}}function ui(...e){e.length===1?e[0]:e[1],e.length===2&&e[0]}function gu(e,t){if(e==null)throw new Error(t())}function S0(e,t){return`${e} returned \`undefined\`. Seems you forgot to wrap component within ${t}`}function gr(e={}){const{name:t,strict:n=!0,hookName:r="useContext",providerName:i="Provider",errorMessage:o,defaultValue:s}=e,a=E.createContext(s);a.displayName=t;function l(){var u;const c=E.useContext(a);if(!c&&n){const d=new Error(o??S0(r,i));throw d.name="ContextError",(u=Error.captureStackTrace)==null||u.call(Error,d,l),d}return c}return[a.Provider,l,a]}const[r_,pu]=gr({name:"EnvironmentContext",hookName:"useEnvironmentContext",providerName:"",strict:!1,defaultValue:{getRootNode:()=>document,getDocument:()=>document,getWindow:()=>window}});function w0(e){if(!e)return;const t=e.selectionStart??0,n=e.selectionEnd??0;Math.abs(n-t)===0&&t===0&&e.setSelectionRange(e.value.length,e.value.length)}var mu=e=>Math.max(0,Math.min(1,e)),E0=(e,t)=>e.map((n,r)=>e[(Math.max(t,0)+r)%e.length]),vu=()=>{},yo=e=>typeof e=="object"&&e!==null,k0=2147483647,O0=1,I0=9,P0=11,Me=e=>yo(e)&&e.nodeType===O0&&typeof e.nodeName=="string",va=e=>yo(e)&&e.nodeType===I0,R0=e=>yo(e)&&e===e.window,bu=e=>Me(e)?e.localName||"":"#document";function T0(e){return["html","body","#document"].includes(bu(e))}var N0=e=>yo(e)&&e.nodeType!==void 0,pr=e=>N0(e)&&e.nodeType===P0&&"host"in e,A0=e=>Me(e)&&e.localName==="input",_0=e=>!!(e!=null&&e.matches("a[href]")),V0=e=>Me(e)?e.offsetWidth>0||e.offsetHeight>0||e.getClientRects().length>0:!1;function F0(e){if(!e)return!1;const t=e.getRootNode();return di(t)===e}var L0=/(textarea|select)/;function yu(e){if(e==null||!Me(e))return!1;try{return A0(e)&&e.selectionStart!=null||L0.test(e.localName)||e.isContentEditable||e.getAttribute("contenteditable")==="true"||e.getAttribute("contenteditable")===""}catch{return!1}}function Nn(e,t){var r;if(!e||!t||!Me(e)||!Me(t))return!1;const n=(r=t.getRootNode)==null?void 0:r.call(t);if(e===t||e.contains(t))return!0;if(n&&pr(n)){let i=t;for(;i;){if(e===i)return!0;i=i.parentNode||i.host}}return!1}function Ge(e){return va(e)?e:R0(e)?e.document:(e==null?void 0:e.ownerDocument)??document}function D0(e){return Ge(e).documentElement}function Ie(e){var t;return pr(e)?Ie(e.host):va(e)?e.defaultView??window:Me(e)?((t=e.ownerDocument)==null?void 0:t.defaultView)??window:window}function di(e){let t=e.activeElement;for(;t!=null&&t.shadowRoot;){const n=t.shadowRoot.activeElement;if(!n||n===t)break;t=n}return t}function z0(e){if(bu(e)==="html")return e;const t=e.assignedSlot||e.parentNode||pr(e)&&e.host||D0(e);return pr(t)?t.host:t}var ba=new WeakMap;function xo(e){return ba.has(e)||ba.set(e,Ie(e).getComputedStyle(e)),ba.get(e)}var Co=()=>typeof document<"u";function M0(){const e=navigator.userAgentData;return(e==null?void 0:e.platform)??navigator.platform}function $0(){const e=navigator.userAgentData;return e&&Array.isArray(e.brands)?e.brands.map(({brand:t,version:n})=>`${t}/${n}`).join(" "):navigator.userAgent}var ya=e=>Co()&&e.test(M0()),xu=e=>Co()&&e.test($0()),B0=e=>Co()&&e.test(navigator.vendor),Cu=()=>Co()&&!!navigator.maxTouchPoints,j0=()=>ya(/^iPhone/i),W0=()=>ya(/^iPad/i)||wo()&&navigator.maxTouchPoints>1,So=()=>j0()||W0(),H0=()=>wo()||So(),wo=()=>ya(/^Mac/i),Su=()=>H0()&&B0(/apple/i),U0=()=>xu(/Firefox/i),G0=()=>xu(/Android/i);function q0(e){var t,n,r;return((t=e.composedPath)==null?void 0:t.call(e))??((r=(n=e.nativeEvent)==null?void 0:n.composedPath)==null?void 0:r.call(n))}function tt(e){const t=q0(e);return(t==null?void 0:t[0])??e.target}function K0(e){return J0(e).isComposing||e.keyCode===229}function X0(e){return e.pointerType===""&&e.isTrusted?!0:G0()&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}var Y0=e=>e.button===2||wo()&&e.ctrlKey&&e.button===0,Q0=e=>"touches"in e&&e.touches.length>0;function J0(e){return e.nativeEvent??e}function wu(e,t="client"){const n=Q0(e)?e.touches[0]||e.changedTouches[0]:e;return{x:n[`${t}X`],y:n[`${t}Y`]}}var he=(e,t,n,r)=>{const i=typeof e=="function"?e():e;return i==null||i.addEventListener(t,n,r),()=>{i==null||i.removeEventListener(t,n,r)}};function Z0(e,t){const{type:n="HTMLInputElement",property:r="value"}=t,i=Ie(e)[n].prototype;return Object.getOwnPropertyDescriptor(i,r)??{}}function ex(e){if(e.localName==="input")return"HTMLInputElement";if(e.localName==="textarea")return"HTMLTextAreaElement";if(e.localName==="select")return"HTMLSelectElement"}function Eo(e,t,n="value"){var i;if(!e)return;const r=ex(e);r&&((i=Z0(e,{type:r,property:n}).set)==null||i.call(e,t)),e.setAttribute(n,t)}function tx(e,t){const{value:n,bubbles:r=!0}=t;if(!e)return;const i=Ie(e);e instanceof i.HTMLInputElement&&(Eo(e,`${n}`),e.dispatchEvent(new i.Event("input",{bubbles:r})))}function nx(e){return rx(e)?e.form:e.closest("form")}function rx(e){return e.matches("textarea, input, select, button")}function ix(e,t){if(!e)return;const n=nx(e),r=i=>{i.defaultPrevented||t()};return n==null||n.addEventListener("reset",r,{passive:!0}),()=>n==null?void 0:n.removeEventListener("reset",r)}function ox(e,t){const n=e==null?void 0:e.closest("fieldset");if(!n)return;t(n.disabled);const r=Ie(n),i=new r.MutationObserver(()=>t(n.disabled));return i.observe(n,{attributes:!0,attributeFilter:["disabled"]}),()=>i.disconnect()}function xa(e,t){if(!e)return;const{onFieldsetDisabledChange:n,onFormReset:r}=t,i=[ix(e,r),ox(e,n)];return()=>i.forEach(o=>o==null?void 0:o())}var Eu=e=>Me(e)&&e.tagName==="IFRAME",sx=e=>!Number.isNaN(parseInt(e.getAttribute("tabindex")||"0",10)),ax=e=>parseInt(e.getAttribute("tabindex")||"0",10)<0,Ca="input:not([type='hidden']):not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], button:not([disabled]), [tabindex], iframe, object, embed, area[href], audio[controls], video[controls], [contenteditable]:not([contenteditable='false']), details > summary:first-of-type",ku=(e,t=!1)=>{if(!e)return[];const n=Array.from(e.querySelectorAll(Ca));(t==!0||t=="if-empty"&&n.length===0)&&Me(e)&&nn(e)&&n.unshift(e);const i=n.filter(nn);return i.forEach((o,s)=>{if(Eu(o)&&o.contentDocument){const a=o.contentDocument.body;i.splice(s,1,...ku(a))}}),i};function nn(e){return!e||e.closest("[inert]")?!1:e.matches(Ca)&&V0(e)}function Sa(e,t){if(!e)return[];const r=Array.from(e.querySelectorAll(Ca)).filter(An);return r.forEach((i,o)=>{if(Eu(i)&&i.contentDocument){const s=i.contentDocument.body,a=Sa(s);r.splice(o,1,...a)}}),r.length,r}function An(e){return e!=null&&e.tabIndex>0?!0:nn(e)&&!ax(e)}function hi(e){return e.tabIndex<0&&(/^(audio|video|details)$/.test(e.localName)||yu(e))&&!sx(e)?0:e.tabIndex}function wa(e){const{root:t,getInitialEl:n,filter:r,enabled:i=!0}=e;if(!i)return;let o=null;if(o||(o=typeof n=="function"?n():n),o||(o=t==null?void 0:t.querySelector("[data-autofocus],[autofocus]")),!o){const s=Sa(t);o=r?s.filter(r)[0]:s[0]}return o||t||void 0}function Ea(e){const t=new Set;function n(r){const i=globalThis.requestAnimationFrame(r);t.add(()=>globalThis.cancelAnimationFrame(i))}return n(()=>n(e)),function(){t.forEach(i=>i())}}function Z(e){let t;const n=globalThis.requestAnimationFrame(()=>{t=e()});return()=>{globalThis.cancelAnimationFrame(n),t==null||t()}}function lx(e,t,n){const r=Z(()=>{e.removeEventListener(t,i,!0),n()}),i=()=>{r(),n()};return e.addEventListener(t,i,{once:!0,capture:!0}),r}function cx(e,t){if(!e)return;const{attributes:n,callback:r}=t,i=e.ownerDocument.defaultView||window,o=new i.MutationObserver(s=>{for(const a of s)a.type==="attributes"&&a.attributeName&&n.includes(a.attributeName)&&r(a)});return o.observe(e,{attributes:!0,attributeFilter:n}),()=>o.disconnect()}function ko(e,t){const{defer:n}=t,r=n?Z:o=>o(),i=[];return i.push(r(()=>{const o=typeof e=="function"?e():e;i.push(cx(o,t))})),()=>{i.forEach(o=>o==null?void 0:o())}}function Ou(e){const t=()=>{const n=Ie(e);e.dispatchEvent(new n.MouseEvent("click"))};U0()?lx(e,"keyup",t):queueMicrotask(t)}function Oo(e){const t=z0(e);return T0(t)?Ge(t).body:Me(t)&&ka(t)?t:Oo(t)}function Iu(e,t=[]){const n=Oo(e),r=n===e.ownerDocument.body,i=Ie(n);return r?t.concat(i,i.visualViewport||[],ka(n)?n:[]):t.concat(n,Iu(n,[]))}var ux=/auto|scroll|overlay|hidden|clip/,dx=new Set(["inline","contents"]);function ka(e){const t=Ie(e),{overflow:n,overflowX:r,overflowY:i,display:o}=t.getComputedStyle(e);return ux.test(n+i+r)&&!dx.has(o)}function hx(e){return e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth}function Io(e,t){const{rootEl:n,...r}=t||{};!e||!n||!ka(n)||!hx(n)||e.scrollIntoView(r)}function Pu(e,t){const{left:n,top:r,width:i,height:o}=t.getBoundingClientRect(),s={x:e.x-n,y:e.y-r},a={x:mu(s.x/i),y:mu(s.y/o)};function l(c={}){const{dir:u="ltr",orientation:d="horizontal",inverted:h}=c,m=typeof h=="object"?h.x:h,f=typeof h=="object"?h.y:h;return d==="horizontal"?u==="rtl"||m?1-a.x:a.x:f?1-a.y:a.y}return{offset:s,percent:a,getPercentValue:l}}function fx(e,t){const n=e.body,r="pointerLockElement"in e||"mozPointerLockElement"in e,i=()=>!!e.pointerLockElement;function o(){}function s(l){i(),console.error("PointerLock error occurred:",l),e.exitPointerLock()}if(!r)return;try{n.requestPointerLock()}catch{}const a=[he(e,"pointerlockchange",o,!1),he(e,"pointerlockerror",s,!1)];return()=>{a.forEach(l=>l()),e.exitPointerLock()}}var mr="default",Oa="",Po=new WeakMap;function gx(e={}){const{target:t,doc:n}=e,r=n??document,i=r.documentElement;return So()?(mr==="default"&&(Oa=i.style.webkitUserSelect,i.style.webkitUserSelect="none"),mr="disabled"):t&&(Po.set(t,t.style.userSelect),t.style.userSelect="none"),()=>px({target:t,doc:r})}function px(e={}){const{target:t,doc:n}=e,i=(n??document).documentElement;if(So()){if(mr!=="disabled")return;mr="restoring",setTimeout(()=>{Ea(()=>{mr==="restoring"&&(i.style.webkitUserSelect==="none"&&(i.style.webkitUserSelect=Oa||""),Oa="",mr="default")})},300)}else if(t&&Po.has(t)){const o=Po.get(t);t.style.userSelect==="none"&&(t.style.userSelect=o??""),t.getAttribute("style")===""&&t.removeAttribute("style"),Po.delete(t)}}function Ru(e={}){const{defer:t,target:n,...r}=e,i=t?Z:s=>s(),o=[];return o.push(i(()=>{const s=typeof n=="function"?n():n;o.push(gx({...r,target:s}))})),()=>{o.forEach(s=>s==null?void 0:s())}}function mx(e,t){const{onPointerMove:n,onPointerUp:r}=t,i=a=>{const l=wu(a),c=Math.sqrt(l.x**2+l.y**2),u=a.pointerType==="touch"?10:5;if(!(c{const l=wu(a);r({point:l,event:a})},s=[he(e,"pointermove",i,!1),he(e,"pointerup",o,!1),he(e,"pointercancel",o,!1),he(e,"contextmenu",o,!1),Ru({doc:e})];return()=>{s.forEach(a=>a())}}function Ro(e,t){return Array.from((e==null?void 0:e.querySelectorAll(t))??[])}function vx(e,t){return(e==null?void 0:e.querySelector(t))??null}var Ia=e=>e.id;function bx(e,t,n=Ia){return e.find(r=>n(r)===t)}function Pa(e,t,n=Ia){const r=bx(e,t,n);return r?e.indexOf(r):-1}function yx(e,t,n=!0){let r=Pa(e,t);return r=n?(r+1)%e.length:Math.min(r+1,e.length-1),e[r]}function xx(e,t,n=!0){let r=Pa(e,t);return r===-1?n?e[e.length-1]:null:(r=n?(r-1+e.length)%e.length:Math.max(0,r-1),e[r])}var Cx=e=>e.split("").map(t=>{const n=t.charCodeAt(0);return n>0&&n<128?t:n>=128&&n<=255?`/x${n.toString(16)}`.replace("/","\\"):""}).join("").trim(),Sx=e=>{var t;return Cx(((t=e.dataset)==null?void 0:t.valuetext)??e.textContent??"")},wx=(e,t)=>e.trim().toLowerCase().startsWith(t.toLowerCase());function Ex(e,t,n,r=Ia){const i=n?Pa(e,n,r):-1;let o=n?E0(e,i):e;return t.length===1&&(o=o.filter(a=>r(a)!==n)),o.find(a=>wx(Sx(a),t))}function To(e,t){if(!e)return vu;const n=Object.keys(t).reduce((r,i)=>(r[i]=e.style.getPropertyValue(i),r),{});return Object.assign(e.style,t),()=>{Object.assign(e.style,n),e.style.length===0&&e.removeAttribute("style")}}function kx(e,t,n){if(!e)return vu;const r=e.style.getPropertyValue(t);return e.style.setProperty(t,n),()=>{e.style.setProperty(t,r),e.style.length===0&&e.removeAttribute("style")}}function Ox(e,t){const{state:n,activeId:r,key:i,timeout:o=350,itemToId:s}=t,a=n.keysSoFar+i,c=a.length>1&&Array.from(a).every(f=>f===a[0])?a[0]:a;let u=e.slice();const d=Ex(u,c,r,s);function h(){clearTimeout(n.timer),n.timer=-1}function m(f){n.keysSoFar=f,h(),f!==""&&(n.timer=+setTimeout(()=>{m(""),h()},o))}return m(a),d}var fi=Object.assign(Ox,{defaultOptions:{keysSoFar:"",timer:-1},isValidEvent:Ix});function Ix(e){return e.key.length===1&&!e.ctrlKey&&!e.metaKey}function Px(e,t,n){const{signal:r}=t;return[new Promise((s,a)=>{const l=setTimeout(()=>{a(new Error(`Timeout of ${n}ms exceeded`))},n);r.addEventListener("abort",()=>{clearTimeout(l),a(new Error("Promise aborted"))}),e.then(c=>{r.aborted||(clearTimeout(l),s(c))}).catch(c=>{r.aborted||(clearTimeout(l),a(c))})}),()=>t.abort()]}function Rx(e,t){const{timeout:n,rootNode:r}=t,i=Ie(r),o=Ge(r),s=new i.AbortController;return Px(new Promise(a=>{const l=e();if(l){a(l);return}const c=new i.MutationObserver(()=>{const u=e();u&&u.isConnected&&(c.disconnect(),a(u))});c.observe(o.body,{childList:!0,subtree:!0})}),s,n)}var Tx=(...e)=>e.map(t=>{var n;return(n=t==null?void 0:t.trim)==null?void 0:n.call(t)}).filter(Boolean).join(" "),Nx=/((?:--)?(?:\w+-?)+)\s*:\s*([^;]*)/g,Tu=e=>{const t={};let n;for(;n=Nx.exec(e);)t[n[1]]=n[2];return t},Ax=(e,t)=>{if(go(e)){if(go(t))return`${e};${t}`;e=Tu(e)}else go(t)&&(t=Tu(t));return Object.assign({},e??{},t??{})};function mt(...e){let t={};for(let n of e){if(!n)continue;for(let i in t){if(i.startsWith("on")&&typeof t[i]=="function"&&typeof n[i]=="function"){t[i]=mo(n[i],t[i]);continue}if(i==="className"||i==="class"){t[i]=Tx(t[i],n[i]);continue}if(i==="style"){t[i]=Ax(t[i],n[i]);continue}t[i]=n[i]!==void 0?n[i]:t[i]}for(let i in n)t[i]===void 0&&(t[i]=n[i]);const r=Object.getOwnPropertySymbols(n);for(let i of r)t[i]=n[i]}return t}function Nu(e,t,n){let r=[],i;return o=>{const s=e(o);return(s.length!==r.length||s.some((l,c)=>!pt(r[c],l)))&&(r=s,i=t(s,o)),i}}function rn(){return{and:(...e)=>function(n){return e.every(r=>n.guard(r))},or:(...e)=>function(n){return e.some(r=>n.guard(r))},not:e=>function(n){return!n.guard(e)}}}function i_(e){return e}function Au(){return{guards:rn(),createMachine:e=>e,choose:e=>function({choose:n}){var r;return(r=n(e))==null?void 0:r.actions}}}var vr=(e=>(e.NotStarted="Not Started",e.Started="Started",e.Stopped="Stopped",e))(vr||{}),Ra="__init__";function _x(e){const t=()=>{var s;return((s=e.getRootNode)==null?void 0:s.call(e))??document},n=()=>Ge(t());return{...e,getRootNode:t,getDoc:n,getWin:()=>n().defaultView??window,getActiveElement:()=>di(t()),isActiveElement:F0,getById:s=>t().getElementById(s)}}function No(...e){return t=>{const n=[];for(const r of e)if(typeof r=="function"){const i=r(t);typeof i=="function"&&n.push(i)}else r&&(r.current=t);if(n.length)return()=>{for(const r of n)r()}}}function Vx(e){var r,i;let t=(r=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:r.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=(i=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:i.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}const Ta=e=>{const t=E.memo(E.forwardRef((n,r)=>{const{asChild:i,children:o,...s}=n;if(!i)return E.createElement(e,{...s,ref:r},o);if(!E.isValidElement(o))return null;const a=E.Children.only(o),l=Vx(a);return E.cloneElement(a,{...mt(s,a.props),ref:r?No(r,l):l})}));return t.displayName=e.displayName||e.name,t},on=(()=>{const e=new Map;return new Proxy(Ta,{apply(t,n,r){return Ta(r[0])},get(t,n){const r=n;return e.has(r)||e.set(r,Ta(r)),e.get(r)}})})(),[s_,Fx]=gr({name:"LocaleContext",hookName:"useLocaleContext",providerName:"",strict:!1,defaultValue:{dir:"ltr",locale:"en-US"}}),_u=()=>(e,t)=>t.reduce((n,r)=>{const[i,o]=n,s=r;return o[s]!==void 0&&(i[s]=o[s]),delete o[s],[i,o]},[{},{...e}]),Vu=e=>_u()(e,["immediate","lazyMount","onExitComplete","present","skipAnimationOnMount","unmountOnExit"]);function Lx(e){return new Proxy({},{get(t,n){return n==="style"?r=>e({style:r}).style:e}})}var q=()=>e=>Array.from(new Set(e));function Dx(e,t){const{state:n,send:r,context:i}=e,o=n.matches("mounted","unmountSuspended");return{skip:!i.get("initial"),present:o,setNode(s){s&&r({type:"NODE.SET",node:s})},unmount(){r({type:"UNMOUNT"})}}}var zx={props({props:e}){return{...e,present:!!e.present}},initialState({prop:e}){return e("present")?"mounted":"unmounted"},refs(){return{node:null,styles:null}},context({bindable:e}){return{unmountAnimationName:e(()=>({defaultValue:null})),prevAnimationName:e(()=>({defaultValue:null})),present:e(()=>({defaultValue:!1})),initial:e(()=>({sync:!0,defaultValue:!1}))}},exit:["clearInitial","cleanupNode"],watch({track:e,prop:t,send:n}){e([()=>t("present")],()=>{n({type:"PRESENCE.CHANGED"})})},on:{"NODE.SET":{actions:["setupNode"]},"PRESENCE.CHANGED":{actions:["setInitial","syncPresence"]}},states:{mounted:{on:{UNMOUNT:{target:"unmounted",actions:["clearPrevAnimationName","invokeOnExitComplete"]},"UNMOUNT.SUSPEND":{target:"unmountSuspended"}}},unmountSuspended:{effects:["trackAnimationEvents"],on:{MOUNT:{target:"mounted",actions:["setPrevAnimationName"]},UNMOUNT:{target:"unmounted",actions:["clearPrevAnimationName","invokeOnExitComplete"]}}},unmounted:{on:{MOUNT:{target:"mounted",actions:["setPrevAnimationName"]}}}},implementations:{actions:{setInitial:({context:e})=>{e.get("initial")||queueMicrotask(()=>{e.set("initial",!0)})},clearInitial:({context:e})=>{e.set("initial",!1)},invokeOnExitComplete:({prop:e})=>{var t;(t=e("onExitComplete"))==null||t()},setupNode:({refs:e,event:t})=>{e.get("node")!==t.node&&(e.set("node",t.node),e.set("styles",xo(t.node)))},cleanupNode:({refs:e})=>{e.set("node",null),e.set("styles",null)},syncPresence:({context:e,refs:t,send:n,prop:r})=>{const i=r("present");if(i)return n({type:"MOUNT",src:"presence.changed"});const o=t.get("node");if(!i&&(o==null?void 0:o.ownerDocument.visibilityState)==="hidden")return n({type:"UNMOUNT",src:"visibilitychange"});Z(()=>{var a,l;const s=Ao(t.get("styles"));e.set("unmountAnimationName",s),s==="none"||s===e.get("prevAnimationName")||((a=t.get("styles"))==null?void 0:a.display)==="none"||((l=t.get("styles"))==null?void 0:l.animationDuration)==="0s"?n({type:"UNMOUNT",src:"presence.changed"}):n({type:"UNMOUNT.SUSPEND"})})},setPrevAnimationName:({context:e,refs:t})=>{Z(()=>{e.set("prevAnimationName",Ao(t.get("styles")))})},clearPrevAnimationName:({context:e})=>{e.set("prevAnimationName",null)}},effects:{trackAnimationEvents:({context:e,refs:t,send:n})=>{const r=t.get("node");if(!r)return;const i=a=>{var c,u;(((u=(c=a.composedPath)==null?void 0:c.call(a))==null?void 0:u[0])??a.target)===r&&e.set("prevAnimationName",Ao(t.get("styles")))},o=a=>{const l=Ao(t.get("styles"));tt(a)===r&&l===e.get("unmountAnimationName")&&n({type:"UNMOUNT",src:"animationend"})};r.addEventListener("animationstart",i),r.addEventListener("animationcancel",o),r.addEventListener("animationend",o);const s=To(r,{animationFillMode:"forwards"});return()=>{r.removeEventListener("animationstart",i),r.removeEventListener("animationcancel",o),r.removeEventListener("animationend",o),Ea(()=>s())}}}}};function Ao(e){return(e==null?void 0:e.animationName)||"none"}q()(["onExitComplete","present","immediate"]);var Fu=typeof globalThis.document<"u"?E.useLayoutEffect:E.useEffect;function _o(e){const t=e().value??e().defaultValue,n=e().isEqual??Object.is,[r]=E.useState(t),[i,o]=E.useState(r),s=e().value!==void 0,a=E.useRef(i);a.current=s?e().value:i;const l=E.useRef(a.current);Fu(()=>{l.current=a.current},[i,e().value]);const c=d=>{var f,g;const h=l.current,m=Tn(d)?d(h):d;e().debug&&console.log(`[bindable > ${e().debug}] setValue`,{next:m,prev:h}),s||o(m),n(m,h)||(g=(f=e()).onChange)==null||g.call(f,m,h)};function u(){return s?e().value:i}return{initial:r,ref:a,get:u,set(d){(e().sync?te.flushSync:o0)(()=>c(d))},invoke(d,h){var m,f;(f=(m=e()).onChange)==null||f.call(m,d,h)},hash(d){var h,m;return((m=(h=e()).hash)==null?void 0:m.call(h,d))??String(d)}}}_o.cleanup=e=>{E.useEffect(()=>e,[])},_o.ref=e=>{const t=E.useRef(e);return{get:()=>t.current,set:n=>{t.current=n}}};function Mx(e){const t=E.useRef(e);return{get(n){return t.current[n]},set(n,r){t.current[n]=r}}}var $x=(e,t)=>{const n=E.useRef(!1),r=E.useRef(!1);E.useEffect(()=>{if(n.current&&r.current)return t();r.current=!0},[...(e??[]).map(i=>typeof i=="function"?i():i)]),E.useEffect(()=>(n.current=!0,()=>{n.current=!1}),[])};function Lu(e,t={}){var B,P,F,X;const n=E.useMemo(()=>{const{id:z,ids:_,getRootNode:j}=t;return _x({id:z,ids:_,getRootNode:j})},[t]),r=(...z)=>{e.debug&&console.log(...z)},i=((B=e.props)==null?void 0:B.call(e,{props:bo(t),scope:n}))??t,o=Bx(i),s=(P=e.context)==null?void 0:P.call(e,{prop:o,bindable:_o,scope:n,flush:zu,getContext(){return l},getComputed(){return k},getRefs(){return g},getEvent(){return m()}}),a=Du(s),l={get(z){var _;return(_=a.current)==null?void 0:_[z].ref.current},set(z,_){var j;(j=a.current)==null||j[z].set(_)},initial(z){var _;return(_=a.current)==null?void 0:_[z].initial},hash(z){var j,W;const _=(j=a.current)==null?void 0:j[z].get();return(W=a.current)==null?void 0:W[z].hash(_)}},c=E.useRef(new Map),u=E.useRef(null),d=E.useRef(null),h=E.useRef({type:""}),m=()=>({...h.current,current(){return h.current},previous(){return d.current}}),f=()=>({...R,matches(...z){return z.includes(R.ref.current)},hasTag(z){var _,j;return!!((j=(_=e.states[R.ref.current])==null?void 0:_.tags)!=null&&j.includes(z))}}),g=Mx(((F=e.refs)==null?void 0:F.call(e,{prop:o,context:l}))??{}),p=()=>({state:f(),context:l,event:m(),prop:o,send:I,action:b,guard:C,track:$x,refs:g,computed:k,flush:zu,scope:n,choose:y}),b=z=>{const _=Tn(z)?z(p()):z;if(!_)return;const j=_.map(W=>{var U,G;const M=(G=(U=e.implementations)==null?void 0:U.actions)==null?void 0:G[W];return M||ui(`[zag-js] No implementation found for action "${JSON.stringify(W)}"`),M});for(const W of j)W==null||W(p())},C=z=>{var _,j;return Tn(z)?z(p()):(j=(_=e.implementations)==null?void 0:_.guards)==null?void 0:j[z](p())},S=z=>{const _=Tn(z)?z(p()):z;if(!_)return;const j=_.map(M=>{var G,re;const U=(re=(G=e.implementations)==null?void 0:G.effects)==null?void 0:re[M];return U||ui(`[zag-js] No implementation found for effect "${JSON.stringify(M)}"`),U}),W=[];for(const M of j){const U=M==null?void 0:M(p());U&&W.push(U)}return()=>W.forEach(M=>M==null?void 0:M())},y=z=>fo(z).find(_=>{let j=!_.guard;return go(_.guard)?j=!!C(_.guard):Tn(_.guard)&&(j=_.guard(p())),j}),k=z=>{gu(e.computed,()=>"[zag-js] No computed object found on machine");const _=e.computed[z];return _({context:l,event:m(),prop:o,refs:g,scope:n,computed:k})},R=_o(()=>({defaultValue:e.initialState({prop:o}),onChange(z,_){var W,M,U,G;if(_){const re=c.current.get(_);re==null||re(),c.current.delete(_)}_&&b((W=e.states[_])==null?void 0:W.exit),b((M=u.current)==null?void 0:M.actions);const j=S((U=e.states[z])==null?void 0:U.effects);if(j&&c.current.set(z,j),_===Ra){b(e.entry);const re=S(e.effects);re&&c.current.set(Ra,re)}b((G=e.states[z])==null?void 0:G.entry)}})),A=E.useRef(void 0),T=E.useRef(vr.NotStarted);Fu(()=>{queueMicrotask(()=>{const j=T.current===vr.Started;T.current=vr.Started,r(j?"rehydrating...":"initializing...");const W=A.current??R.initial;R.invoke(W,j?R.get():Ra)});const z=c.current,_=R.ref.current;return()=>{r("unmounting..."),A.current=_,T.current=vr.Stopped,z.forEach(j=>j==null?void 0:j()),c.current=new Map,u.current=null,queueMicrotask(()=>{b(e.exit)})}},[]);const N=()=>"ref"in R?R.ref.current:R.get(),I=z=>{queueMicrotask(()=>{var G,re;if(T.current!==vr.Started)return;d.current=h.current,h.current=z;let _=N();const j=((G=e.states[_].on)==null?void 0:G[z.type])??((re=e.on)==null?void 0:re[z.type]),W=y(j);if(!W)return;u.current=W;const M=W.target??_;r("transition",z.type,W.target||_,`(${W.actions})`);const U=M!==_;U?te.flushSync(()=>R.set(M)):W.reenter&&!U?R.invoke(_,_):b(W.actions??[])})};return(X=e.watch)==null||X.call(e,p()),{state:f(),send:I,context:l,prop:o,scope:n,refs:g,computed:k,event:m(),getStatus:()=>T.current}}function Du(e){const t=E.useRef(e);return t.current=e,t}function Bx(e){const t=Du(e);return function(r){return t.current[r]}}function zu(e){queueMicrotask(()=>{te.flushSync(()=>e())})}var jx=Lx(e=>e);function Wx(e,t={}){const{sync:n=!1}=t,r=Hx(e);return E.useCallback((...i)=>{var o;return n?queueMicrotask(()=>{var s;return(s=r.current)==null?void 0:s.call(r,...i)}):(o=r.current)==null?void 0:o.call(r,...i)},[n,r])}function Hx(e){const t=E.useRef(e);return t.current=e,t}const Na=(e={})=>{const{lazyMount:t,unmountOnExit:n,present:r,skipAnimationOnMount:i=!1,...o}=e,s=E.useRef(!1),a={...o,present:r,onExitComplete:Wx(e.onExitComplete)},l=Lu(zx,a),c=Dx(l);c.present&&(s.current=!0);const u=!c.present&&!s.current&&t||n&&!c.present&&s.current,d=()=>({"data-state":c.skip&&i?void 0:r?"open":"closed",hidden:!c.present});return{ref:c.setNode,getPresenceProps:d,present:c.present,unmounted:u}},[Mu,Aa]=gr({name:"PresenceContext",hookName:"usePresenceContext",providerName:""}),Vo=Oe("span"),{withContext:Ux}=ai({key:"text"}),Gx=Ux("p");function $u(e,t=[]){const n=E.useRef(()=>{throw new Error("Cannot call an event handler while rendering.")});return E.useInsertionEffect(()=>{n.current=e}),E.useCallback((...r)=>{var i;return(i=n.current)==null?void 0:i.call(n,...r)},t)}function qx(e={}){const t=$u(e.onOpen),n=$u(e.onClose),[r,i]=E.useState(e.defaultOpen||!1),o=e.open!==void 0?e.open:r,s=e.open!==void 0,a=E.useCallback(()=>{s||i(!1),n==null||n()},[s,n]),l=E.useCallback(()=>{s||i(!0),t==null||t()},[s,t]),c=E.useCallback(()=>{o?a():l()},[o,l,a]);return{open:o,onOpen:l,onClose:a,onToggle:c,setOpen:i}}var K=(e,t=[])=>({parts:(...n)=>{if(Kx(t))return K(e,n);throw new Error("createAnatomy().parts(...) should only be called once. Did you mean to use .extendWith(...) ?")},extendWith:(...n)=>K(e,[...t,...n]),omit:(...n)=>K(e,t.filter(r=>!n.includes(r))),rename:n=>K(n,t),keys:()=>t,build:()=>[...new Set(t)].reduce((n,r)=>Object.assign(n,{[r]:{selector:[`&[data-scope="${br(e)}"][data-part="${br(r)}"]`,`& [data-scope="${br(e)}"][data-part="${br(r)}"]`].join(", "),attrs:{"data-scope":br(e),"data-part":br(r)}}}),{})}),br=e=>e.replace(/([A-Z])([A-Z])/g,"$1-$2").replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase(),Kx=e=>e.length===0,Bu=K("collapsible").parts("root","trigger","content","indicator");Bu.build(),q()(["dir","disabled","getRootNode","id","ids","onExitComplete","onOpenChange","defaultOpen","open"]);var Xx=Object.defineProperty,Yx=(e,t,n)=>t in e?Xx(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,_a=(e,t,n)=>Yx(e,t+"",n),Qx=(e,t)=>{if(Object.keys(e).length!==Object.keys(t).length)return!1;for(let n in e)if(e[n]!==t[n])return!1;return!0},Va=class{toHexInt(){return this.toFormat("rgba").toHexInt()}getChannelValue(e){if(e in this)return this[e];throw new Error("Unsupported color channel: "+e)}getChannelValuePercent(e,t){const n=t??this.getChannelValue(e),{minValue:r,maxValue:i}=this.getChannelRange(e);return v0(n,r,i)}getChannelPercentValue(e,t){const{minValue:n,maxValue:r,step:i}=this.getChannelRange(e),o=b0(t,n,r,i);return du(o,n,r,i)}withChannelValue(e,t){const{minValue:n,maxValue:r}=this.getChannelRange(e);if(e in this){let i=this.clone();return i[e]=Ue(t,n,r),i}throw new Error("Unsupported color channel: "+e)}getColorAxes(e){let{xChannel:t,yChannel:n}=e,r=t||this.getChannels().find(s=>s!==n),i=n||this.getChannels().find(s=>s!==r),o=this.getChannels().find(s=>s!==r&&s!==i);return{xChannel:r,yChannel:i,zChannel:o}}incrementChannel(e,t){const{minValue:n,maxValue:r,step:i}=this.getChannelRange(e),o=du(Ue(this.getChannelValue(e)+t,n,r),n,r,i);return this.withChannelValue(e,o)}decrementChannel(e,t){return this.incrementChannel(e,-t)}isEqual(e){return Qx(this.toJSON(),e.toJSON())&&this.getChannelValue("alpha")===e.getChannelValue("alpha")}},Jx=/^#[\da-f]+$/i,Zx=/^rgba?\((.*)\)$/,e1=/[^#]/gi,ju=class Ws extends Va{constructor(t,n,r,i){super(),this.red=t,this.green=n,this.blue=r,this.alpha=i}static parse(t){let n=[];if(Jx.test(t)&&[4,5,7,9].includes(t.length)){const i=(t.length<6?t.replace(e1,"$&$&"):t).slice(1).split("");for(;i.length>0;)n.push(parseInt(i.splice(0,2).join(""),16));n[3]=n[3]!==void 0?n[3]/255:void 0}const r=t.match(Zx);return r!=null&&r[1]&&(n=r[1].split(",").map(i=>Number(i.trim())).map((i,o)=>Ue(i,0,o<3?255:1))),n.length<3?void 0:new Ws(n[0],n[1],n[2],n[3]??1)}toString(t){switch(t){case"hex":return"#"+(this.red.toString(16).padStart(2,"0")+this.green.toString(16).padStart(2,"0")+this.blue.toString(16).padStart(2,"0")).toUpperCase();case"hexa":return"#"+(this.red.toString(16).padStart(2,"0")+this.green.toString(16).padStart(2,"0")+this.blue.toString(16).padStart(2,"0")+Math.round(this.alpha*255).toString(16).padStart(2,"0")).toUpperCase();case"rgb":return`rgb(${this.red}, ${this.green}, ${this.blue})`;case"css":case"rgba":return`rgba(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`;case"hsl":return this.toHSL().toString("hsl");case"hsb":return this.toHSB().toString("hsb");default:return this.toFormat(t).toString(t)}}toFormat(t){switch(t){case"rgba":return this;case"hsba":return this.toHSB();case"hsla":return this.toHSL();default:throw new Error("Unsupported color conversion: rgb -> "+t)}}toHexInt(){return this.red<<16|this.green<<8|this.blue}toHSB(){const t=this.red/255,n=this.green/255,r=this.blue/255,i=Math.min(t,n,r),o=Math.max(t,n,r),s=o-i,a=o===0?0:s/o;let l=0;if(s!==0){switch(o){case t:l=(n-r)/s+(nNumber(a.trim().replace("%","")));return new Hs(cu(r,360),Ue(i,0,100),Ue(o,0,100),Ue(s??1,0,1))}}toString(t){switch(t){case"hex":return this.toRGB().toString("hex");case"hexa":return this.toRGB().toString("hexa");case"hsl":return`hsl(${this.hue}, ${ue(this.saturation,2)}%, ${ue(this.lightness,2)}%)`;case"css":case"hsla":return`hsla(${this.hue}, ${ue(this.saturation,2)}%, ${ue(this.lightness,2)}%, ${this.alpha})`;case"hsb":return this.toHSB().toString("hsb");case"rgb":return this.toRGB().toString("rgb");default:return this.toFormat(t).toString(t)}}toFormat(t){switch(t){case"hsla":return this;case"hsba":return this.toHSB();case"rgba":return this.toRGB();default:throw new Error("Unsupported color conversion: hsl -> "+t)}}toHSB(){let t=this.saturation/100,n=this.lightness/100,r=n+t*Math.min(n,1-n);return t=r===0?0:2*(1-n/r),new Da(ue(this.hue,2),ue(t*100,2),ue(r*100,2),ue(this.alpha,2))}toRGB(){let t=this.hue,n=this.saturation/100,r=this.lightness/100,i=n*Math.min(r,1-r),o=(s,a=(s+t/30)%12)=>r-i*Math.max(Math.min(a-3,9-a,1),-1);return new Fa(Math.round(o(0)*255),Math.round(o(8)*255),Math.round(o(4)*255),ue(this.alpha,2))}clone(){return new Hs(this.hue,this.saturation,this.lightness,this.alpha)}getChannelFormatOptions(t){switch(t){case"hue":return{style:"unit",unit:"degree",unitDisplay:"narrow"};case"saturation":case"lightness":case"alpha":return{style:"percent"};default:throw new Error("Unknown color channel: "+t)}}formatChannelValue(t,n){let r=this.getChannelFormatOptions(t),i=this.getChannelValue(t);return(t==="saturation"||t==="lightness")&&(i/=100),new Intl.NumberFormat(n,r).format(i)}getChannelRange(t){switch(t){case"hue":return{minValue:0,maxValue:360,step:1,pageSize:15};case"saturation":case"lightness":return{minValue:0,maxValue:100,step:1,pageSize:10};case"alpha":return{minValue:0,maxValue:1,step:.01,pageSize:.1};default:throw new Error("Unknown color channel: "+t)}}toJSON(){return{h:this.hue,s:this.saturation,l:this.lightness,a:this.alpha}}getFormat(){return"hsla"}getChannels(){return Hs.colorChannels}};_a(Wu,"colorChannels",["hue","saturation","lightness"]);var La=Wu,n1=/hsb\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%)\)|hsba\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d(.\d+)?)\)/,Hu=class Us extends Va{constructor(t,n,r,i){super(),this.hue=t,this.saturation=n,this.brightness=r,this.alpha=i}static parse(t){let n;if(n=t.match(n1)){const[r,i,o,s]=(n[1]??n[2]).split(",").map(a=>Number(a.trim().replace("%","")));return new Us(cu(r,360),Ue(i,0,100),Ue(o,0,100),Ue(s??1,0,1))}}toString(t){switch(t){case"css":return this.toHSL().toString("css");case"hex":return this.toRGB().toString("hex");case"hexa":return this.toRGB().toString("hexa");case"hsb":return`hsb(${this.hue}, ${ue(this.saturation,2)}%, ${ue(this.brightness,2)}%)`;case"hsba":return`hsba(${this.hue}, ${ue(this.saturation,2)}%, ${ue(this.brightness,2)}%, ${this.alpha})`;case"hsl":return this.toHSL().toString("hsl");case"rgb":return this.toRGB().toString("rgb");default:return this.toFormat(t).toString(t)}}toFormat(t){switch(t){case"hsba":return this;case"hsla":return this.toHSL();case"rgba":return this.toRGB();default:throw new Error("Unsupported color conversion: hsb -> "+t)}}toHSL(){let t=this.saturation/100,n=this.brightness/100,r=n*(1-t/2);return t=r===0||r===1?0:(n-r)/Math.min(r,1-r),new La(ue(this.hue,2),ue(t*100,2),ue(r*100,2),ue(this.alpha,2))}toRGB(){let t=this.hue,n=this.saturation/100,r=this.brightness/100,i=(o,s=(o+t/60)%6)=>r-n*r*Math.max(Math.min(s,4-s,1),0);return new Fa(Math.round(i(5)*255),Math.round(i(3)*255),Math.round(i(1)*255),ue(this.alpha,2))}clone(){return new Us(this.hue,this.saturation,this.brightness,this.alpha)}getChannelFormatOptions(t){switch(t){case"hue":return{style:"unit",unit:"degree",unitDisplay:"narrow"};case"saturation":case"brightness":case"alpha":return{style:"percent"};default:throw new Error("Unknown color channel: "+t)}}formatChannelValue(t,n){let r=this.getChannelFormatOptions(t),i=this.getChannelValue(t);return(t==="saturation"||t==="brightness")&&(i/=100),new Intl.NumberFormat(n,r).format(i)}getChannelRange(t){switch(t){case"hue":return{minValue:0,maxValue:360,step:1,pageSize:15};case"saturation":case"brightness":return{minValue:0,maxValue:100,step:1,pageSize:10};case"alpha":return{minValue:0,maxValue:1,step:.01,pageSize:.1};default:throw new Error("Unknown color channel: "+t)}}toJSON(){return{h:this.hue,s:this.saturation,b:this.brightness,a:this.alpha}}getFormat(){return"hsba"}getChannels(){return Us.colorChannels}};_a(Hu,"colorChannels",["hue","saturation","brightness"]);var Da=Hu,r1="aliceblue:f0f8ff,antiquewhite:faebd7,aqua:00ffff,aquamarine:7fffd4,azure:f0ffff,beige:f5f5dc,bisque:ffe4c4,black:000000,blanchedalmond:ffebcd,blue:0000ff,blueviolet:8a2be2,brown:a52a2a,burlywood:deb887,cadetblue:5f9ea0,chartreuse:7fff00,chocolate:d2691e,coral:ff7f50,cornflowerblue:6495ed,cornsilk:fff8dc,crimson:dc143c,cyan:00ffff,darkblue:00008b,darkcyan:008b8b,darkgoldenrod:b8860b,darkgray:a9a9a9,darkgreen:006400,darkkhaki:bdb76b,darkmagenta:8b008b,darkolivegreen:556b2f,darkorange:ff8c00,darkorchid:9932cc,darkred:8b0000,darksalmon:e9967a,darkseagreen:8fbc8f,darkslateblue:483d8b,darkslategray:2f4f4f,darkturquoise:00ced1,darkviolet:9400d3,deeppink:ff1493,deepskyblue:00bfff,dimgray:696969,dodgerblue:1e90ff,firebrick:b22222,floralwhite:fffaf0,forestgreen:228b22,fuchsia:ff00ff,gainsboro:dcdcdc,ghostwhite:f8f8ff,gold:ffd700,goldenrod:daa520,gray:808080,green:008000,greenyellow:adff2f,honeydew:f0fff0,hotpink:ff69b4,indianred:cd5c5c,indigo:4b0082,ivory:fffff0,khaki:f0e68c,lavender:e6e6fa,lavenderblush:fff0f5,lawngreen:7cfc00,lemonchiffon:fffacd,lightblue:add8e6,lightcoral:f08080,lightcyan:e0ffff,lightgoldenrodyellow:fafad2,lightgrey:d3d3d3,lightgreen:90ee90,lightpink:ffb6c1,lightsalmon:ffa07a,lightseagreen:20b2aa,lightskyblue:87cefa,lightslategray:778899,lightsteelblue:b0c4de,lightyellow:ffffe0,lime:00ff00,limegreen:32cd32,linen:faf0e6,magenta:ff00ff,maroon:800000,mediumaquamarine:66cdaa,mediumblue:0000cd,mediumorchid:ba55d3,mediumpurple:9370d8,mediumseagreen:3cb371,mediumslateblue:7b68ee,mediumspringgreen:00fa9a,mediumturquoise:48d1cc,mediumvioletred:c71585,midnightblue:191970,mintcream:f5fffa,mistyrose:ffe4e1,moccasin:ffe4b5,navajowhite:ffdead,navy:000080,oldlace:fdf5e6,olive:808000,olivedrab:6b8e23,orange:ffa500,orangered:ff4500,orchid:da70d6,palegoldenrod:eee8aa,palegreen:98fb98,paleturquoise:afeeee,palevioletred:d87093,papayawhip:ffefd5,peachpuff:ffdab9,peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple:800080,rebeccapurple:663399,red:ff0000,rosybrown:bc8f8f,royalblue:4169e1,saddlebrown:8b4513,salmon:fa8072,sandybrown:f4a460,seagreen:2e8b57,seashell:fff5ee,sienna:a0522d,silver:c0c0c0,skyblue:87ceeb,slateblue:6a5acd,slategray:708090,snow:fffafa,springgreen:00ff7f,steelblue:4682b4,tan:d2b48c,teal:008080,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32",i1=e=>{const t=new Map,n=e.split(",");for(let r=0;r{var n;if(Uu.has(e))return Fo(Uu.get(e));const t=Fa.parse(e)||Da.parse(e)||La.parse(e);if(!t){const r=new Error("Invalid color value: "+e);throw(n=Error.captureStackTrace)==null||n.call(Error,r,Fo),r}return t};const o1=["top","right","bottom","left"],sn=Math.min,nt=Math.max,Lo=Math.round,Do=Math.floor,Pt=e=>({x:e,y:e}),s1={left:"right",right:"left",bottom:"top",top:"bottom"},a1={start:"end",end:"start"};function za(e,t,n){return nt(e,sn(t,n))}function jt(e,t){return typeof e=="function"?e(t):e}function Wt(e){return e.split("-")[0]}function yr(e){return e.split("-")[1]}function Ma(e){return e==="x"?"y":"x"}function $a(e){return e==="y"?"height":"width"}const l1=new Set(["top","bottom"]);function Rt(e){return l1.has(Wt(e))?"y":"x"}function Ba(e){return Ma(Rt(e))}function c1(e,t,n){n===void 0&&(n=!1);const r=yr(e),i=Ba(e),o=$a(i);let s=i==="x"?r===(n?"end":"start")?"right":"left":r==="start"?"bottom":"top";return t.reference[o]>t.floating[o]&&(s=zo(s)),[s,zo(s)]}function u1(e){const t=zo(e);return[ja(e),t,ja(t)]}function ja(e){return e.replace(/start|end/g,t=>a1[t])}const Gu=["left","right"],qu=["right","left"],d1=["top","bottom"],h1=["bottom","top"];function f1(e,t,n){switch(e){case"top":case"bottom":return n?t?qu:Gu:t?Gu:qu;case"left":case"right":return t?d1:h1;default:return[]}}function g1(e,t,n,r){const i=yr(e);let o=f1(Wt(e),n==="start",r);return i&&(o=o.map(s=>s+"-"+i),t&&(o=o.concat(o.map(ja)))),o}function zo(e){return e.replace(/left|right|bottom|top/g,t=>s1[t])}function p1(e){return{top:0,right:0,bottom:0,left:0,...e}}function Ku(e){return typeof e!="number"?p1(e):{top:e,right:e,bottom:e,left:e}}function Mo(e){const{x:t,y:n,width:r,height:i}=e;return{width:r,height:i,top:n,left:t,right:t+r,bottom:n+i,x:t,y:n}}function Xu(e,t,n){let{reference:r,floating:i}=e;const o=Rt(t),s=Ba(t),a=$a(s),l=Wt(t),c=o==="y",u=r.x+r.width/2-i.width/2,d=r.y+r.height/2-i.height/2,h=r[a]/2-i[a]/2;let m;switch(l){case"top":m={x:u,y:r.y-i.height};break;case"bottom":m={x:u,y:r.y+r.height};break;case"right":m={x:r.x+r.width,y:d};break;case"left":m={x:r.x-i.width,y:d};break;default:m={x:r.x,y:r.y}}switch(yr(t)){case"start":m[s]-=h*(n&&c?-1:1);break;case"end":m[s]+=h*(n&&c?-1:1);break}return m}const m1=async(e,t,n)=>{const{placement:r="bottom",strategy:i="absolute",middleware:o=[],platform:s}=n,a=o.filter(Boolean),l=await(s.isRTL==null?void 0:s.isRTL(t));let c=await s.getElementRects({reference:e,floating:t,strategy:i}),{x:u,y:d}=Xu(c,r,l),h=r,m={},f=0;for(let g=0;g({name:"arrow",options:e,async fn(t){const{x:n,y:r,placement:i,rects:o,platform:s,elements:a,middlewareData:l}=t,{element:c,padding:u=0}=jt(e,t)||{};if(c==null)return{};const d=Ku(u),h={x:n,y:r},m=Ba(i),f=$a(m),g=await s.getDimensions(c),p=m==="y",b=p?"top":"left",C=p?"bottom":"right",S=p?"clientHeight":"clientWidth",y=o.reference[f]+o.reference[m]-h[m]-o.floating[f],k=h[m]-o.reference[m],R=await(s.getOffsetParent==null?void 0:s.getOffsetParent(c));let A=R?R[S]:0;(!A||!await(s.isElement==null?void 0:s.isElement(R)))&&(A=a.floating[S]||o.floating[f]);const T=y/2-k/2,N=A/2-g[f]/2-1,I=sn(d[b],N),B=sn(d[C],N),P=I,F=A-g[f]-B,X=A/2-g[f]/2+T,z=za(P,X,F),_=!l.arrow&&yr(i)!=null&&X!==z&&o.reference[f]/2-(XX<=0)){var B,P;const X=(((B=o.flip)==null?void 0:B.index)||0)+1,z=A[X];if(z&&(!(d==="alignment"?C!==Rt(z):!1)||I.every(W=>Rt(W.placement)===C?W.overflows[0]>0:!0)))return{data:{index:X,overflows:I},reset:{placement:z}};let _=(P=I.filter(j=>j.overflows[0]<=0).sort((j,W)=>j.overflows[1]-W.overflows[1])[0])==null?void 0:P.placement;if(!_)switch(m){case"bestFit":{var F;const j=(F=I.filter(W=>{if(R){const M=Rt(W.placement);return M===C||M==="y"}return!0}).map(W=>[W.placement,W.overflows.filter(M=>M>0).reduce((M,U)=>M+U,0)]).sort((W,M)=>W[1]-M[1])[0])==null?void 0:F[0];j&&(_=j);break}case"initialPlacement":_=a;break}if(i!==_)return{reset:{placement:_}}}return{}}}};function Yu(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function Qu(e){return o1.some(t=>e[t]>=0)}const y1=function(e){return e===void 0&&(e={}),{name:"hide",options:e,async fn(t){const{rects:n}=t,{strategy:r="referenceHidden",...i}=jt(e,t);switch(r){case"referenceHidden":{const o=await gi(t,{...i,elementContext:"reference"}),s=Yu(o,n.reference);return{data:{referenceHiddenOffsets:s,referenceHidden:Qu(s)}}}case"escaped":{const o=await gi(t,{...i,altBoundary:!0}),s=Yu(o,n.floating);return{data:{escapedOffsets:s,escaped:Qu(s)}}}default:return{}}}}},Ju=new Set(["left","top"]);async function x1(e,t){const{placement:n,platform:r,elements:i}=e,o=await(r.isRTL==null?void 0:r.isRTL(i.floating)),s=Wt(n),a=yr(n),l=Rt(n)==="y",c=Ju.has(s)?-1:1,u=o&&l?-1:1,d=jt(t,e);let{mainAxis:h,crossAxis:m,alignmentAxis:f}=typeof d=="number"?{mainAxis:d,crossAxis:0,alignmentAxis:null}:{mainAxis:d.mainAxis||0,crossAxis:d.crossAxis||0,alignmentAxis:d.alignmentAxis};return a&&typeof f=="number"&&(m=a==="end"?f*-1:f),l?{x:m*u,y:h*c}:{x:h*c,y:m*u}}const C1=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var n,r;const{x:i,y:o,placement:s,middlewareData:a}=t,l=await x1(t,e);return s===((n=a.offset)==null?void 0:n.placement)&&(r=a.arrow)!=null&&r.alignmentOffset?{}:{x:i+l.x,y:o+l.y,data:{...l,placement:s}}}}},S1=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){const{x:n,y:r,placement:i}=t,{mainAxis:o=!0,crossAxis:s=!1,limiter:a={fn:p=>{let{x:b,y:C}=p;return{x:b,y:C}}},...l}=jt(e,t),c={x:n,y:r},u=await gi(t,l),d=Rt(Wt(i)),h=Ma(d);let m=c[h],f=c[d];if(o){const p=h==="y"?"top":"left",b=h==="y"?"bottom":"right",C=m+u[p],S=m-u[b];m=za(C,m,S)}if(s){const p=d==="y"?"top":"left",b=d==="y"?"bottom":"right",C=f+u[p],S=f-u[b];f=za(C,f,S)}const g=a.fn({...t,[h]:m,[d]:f});return{...g,data:{x:g.x-n,y:g.y-r,enabled:{[h]:o,[d]:s}}}}}},w1=function(e){return e===void 0&&(e={}),{options:e,fn(t){const{x:n,y:r,placement:i,rects:o,middlewareData:s}=t,{offset:a=0,mainAxis:l=!0,crossAxis:c=!0}=jt(e,t),u={x:n,y:r},d=Rt(i),h=Ma(d);let m=u[h],f=u[d];const g=jt(a,t),p=typeof g=="number"?{mainAxis:g,crossAxis:0}:{mainAxis:0,crossAxis:0,...g};if(l){const S=h==="y"?"height":"width",y=o.reference[h]-o.floating[S]+p.mainAxis,k=o.reference[h]+o.reference[S]-p.mainAxis;mk&&(m=k)}if(c){var b,C;const S=h==="y"?"width":"height",y=Ju.has(Wt(i)),k=o.reference[d]-o.floating[S]+(y&&((b=s.offset)==null?void 0:b[d])||0)+(y?0:p.crossAxis),R=o.reference[d]+o.reference[S]+(y?0:((C=s.offset)==null?void 0:C[d])||0)-(y?p.crossAxis:0);fR&&(f=R)}return{[h]:m,[d]:f}}}},E1=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){var n,r;const{placement:i,rects:o,platform:s,elements:a}=t,{apply:l=()=>{},...c}=jt(e,t),u=await gi(t,c),d=Wt(i),h=yr(i),m=Rt(i)==="y",{width:f,height:g}=o.floating;let p,b;d==="top"||d==="bottom"?(p=d,b=h===(await(s.isRTL==null?void 0:s.isRTL(a.floating))?"start":"end")?"left":"right"):(b=d,p=h==="end"?"top":"bottom");const C=g-u.top-u.bottom,S=f-u.left-u.right,y=sn(g-u[p],C),k=sn(f-u[b],S),R=!t.middlewareData.shift;let A=y,T=k;if((n=t.middlewareData.shift)!=null&&n.enabled.x&&(T=S),(r=t.middlewareData.shift)!=null&&r.enabled.y&&(A=C),R&&!h){const I=nt(u.left,0),B=nt(u.right,0),P=nt(u.top,0),F=nt(u.bottom,0);m?T=f-2*(I!==0||B!==0?I+B:nt(u.left,u.right)):A=g-2*(P!==0||F!==0?P+F:nt(u.top,u.bottom))}await l({...t,availableWidth:T,availableHeight:A});const N=await s.getDimensions(a.floating);return f!==N.width||g!==N.height?{reset:{rects:!0}}:{}}}};function $o(){return typeof window<"u"}function xr(e){return Zu(e)?(e.nodeName||"").toLowerCase():"#document"}function rt(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function Tt(e){var t;return(t=(Zu(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function Zu(e){return $o()?e instanceof Node||e instanceof rt(e).Node:!1}function vt(e){return $o()?e instanceof Element||e instanceof rt(e).Element:!1}function Nt(e){return $o()?e instanceof HTMLElement||e instanceof rt(e).HTMLElement:!1}function ed(e){return!$o()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof rt(e).ShadowRoot}const k1=new Set(["inline","contents"]);function pi(e){const{overflow:t,overflowX:n,overflowY:r,display:i}=bt(e);return/auto|scroll|overlay|hidden|clip/.test(t+r+n)&&!k1.has(i)}const O1=new Set(["table","td","th"]);function I1(e){return O1.has(xr(e))}const P1=[":popover-open",":modal"];function Bo(e){return P1.some(t=>{try{return e.matches(t)}catch{return!1}})}const R1=["transform","translate","scale","rotate","perspective"],T1=["transform","translate","scale","rotate","perspective","filter"],N1=["paint","layout","strict","content"];function Wa(e){const t=Ha(),n=vt(e)?bt(e):e;return R1.some(r=>n[r]?n[r]!=="none":!1)||(n.containerType?n.containerType!=="normal":!1)||!t&&(n.backdropFilter?n.backdropFilter!=="none":!1)||!t&&(n.filter?n.filter!=="none":!1)||T1.some(r=>(n.willChange||"").includes(r))||N1.some(r=>(n.contain||"").includes(r))}function A1(e){let t=an(e);for(;Nt(t)&&!Cr(t);){if(Wa(t))return t;if(Bo(t))return null;t=an(t)}return null}function Ha(){return typeof CSS>"u"||!CSS.supports?!1:CSS.supports("-webkit-backdrop-filter","none")}const _1=new Set(["html","body","#document"]);function Cr(e){return _1.has(xr(e))}function bt(e){return rt(e).getComputedStyle(e)}function jo(e){return vt(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function an(e){if(xr(e)==="html")return e;const t=e.assignedSlot||e.parentNode||ed(e)&&e.host||Tt(e);return ed(t)?t.host:t}function td(e){const t=an(e);return Cr(t)?e.ownerDocument?e.ownerDocument.body:e.body:Nt(t)&&pi(t)?t:td(t)}function mi(e,t,n){var r;t===void 0&&(t=[]),n===void 0&&(n=!0);const i=td(e),o=i===((r=e.ownerDocument)==null?void 0:r.body),s=rt(i);if(o){const a=Ua(s);return t.concat(s,s.visualViewport||[],pi(i)?i:[],a&&n?mi(a):[])}return t.concat(i,mi(i,[],n))}function Ua(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function nd(e){const t=bt(e);let n=parseFloat(t.width)||0,r=parseFloat(t.height)||0;const i=Nt(e),o=i?e.offsetWidth:n,s=i?e.offsetHeight:r,a=Lo(n)!==o||Lo(r)!==s;return a&&(n=o,r=s),{width:n,height:r,$:a}}function Ga(e){return vt(e)?e:e.contextElement}function Sr(e){const t=Ga(e);if(!Nt(t))return Pt(1);const n=t.getBoundingClientRect(),{width:r,height:i,$:o}=nd(t);let s=(o?Lo(n.width):n.width)/r,a=(o?Lo(n.height):n.height)/i;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}const V1=Pt(0);function rd(e){const t=rt(e);return!Ha()||!t.visualViewport?V1:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function F1(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==rt(e)?!1:t}function _n(e,t,n,r){t===void 0&&(t=!1),n===void 0&&(n=!1);const i=e.getBoundingClientRect(),o=Ga(e);let s=Pt(1);t&&(r?vt(r)&&(s=Sr(r)):s=Sr(e));const a=F1(o,n,r)?rd(o):Pt(0);let l=(i.left+a.x)/s.x,c=(i.top+a.y)/s.y,u=i.width/s.x,d=i.height/s.y;if(o){const h=rt(o),m=r&&vt(r)?rt(r):r;let f=h,g=Ua(f);for(;g&&r&&m!==f;){const p=Sr(g),b=g.getBoundingClientRect(),C=bt(g),S=b.left+(g.clientLeft+parseFloat(C.paddingLeft))*p.x,y=b.top+(g.clientTop+parseFloat(C.paddingTop))*p.y;l*=p.x,c*=p.y,u*=p.x,d*=p.y,l+=S,c+=y,f=rt(g),g=Ua(f)}}return Mo({width:u,height:d,x:l,y:c})}function Wo(e,t){const n=jo(e).scrollLeft;return t?t.left+n:_n(Tt(e)).left+n}function id(e,t){const n=e.getBoundingClientRect(),r=n.left+t.scrollLeft-Wo(e,n),i=n.top+t.scrollTop;return{x:r,y:i}}function L1(e){let{elements:t,rect:n,offsetParent:r,strategy:i}=e;const o=i==="fixed",s=Tt(r),a=t?Bo(t.floating):!1;if(r===s||a&&o)return n;let l={scrollLeft:0,scrollTop:0},c=Pt(1);const u=Pt(0),d=Nt(r);if((d||!d&&!o)&&((xr(r)!=="body"||pi(s))&&(l=jo(r)),Nt(r))){const m=_n(r);c=Sr(r),u.x=m.x+r.clientLeft,u.y=m.y+r.clientTop}const h=s&&!d&&!o?id(s,l):Pt(0);return{width:n.width*c.x,height:n.height*c.y,x:n.x*c.x-l.scrollLeft*c.x+u.x+h.x,y:n.y*c.y-l.scrollTop*c.y+u.y+h.y}}function D1(e){return Array.from(e.getClientRects())}function z1(e){const t=Tt(e),n=jo(e),r=e.ownerDocument.body,i=nt(t.scrollWidth,t.clientWidth,r.scrollWidth,r.clientWidth),o=nt(t.scrollHeight,t.clientHeight,r.scrollHeight,r.clientHeight);let s=-n.scrollLeft+Wo(e);const a=-n.scrollTop;return bt(r).direction==="rtl"&&(s+=nt(t.clientWidth,r.clientWidth)-i),{width:i,height:o,x:s,y:a}}const od=25;function M1(e,t){const n=rt(e),r=Tt(e),i=n.visualViewport;let o=r.clientWidth,s=r.clientHeight,a=0,l=0;if(i){o=i.width,s=i.height;const u=Ha();(!u||u&&t==="fixed")&&(a=i.offsetLeft,l=i.offsetTop)}const c=Wo(r);if(c<=0){const u=r.ownerDocument,d=u.body,h=getComputedStyle(d),m=u.compatMode==="CSS1Compat"&&parseFloat(h.marginLeft)+parseFloat(h.marginRight)||0,f=Math.abs(r.clientWidth-d.clientWidth-m);f<=od&&(o-=f)}else c<=od&&(o+=c);return{width:o,height:s,x:a,y:l}}const $1=new Set(["absolute","fixed"]);function B1(e,t){const n=_n(e,!0,t==="fixed"),r=n.top+e.clientTop,i=n.left+e.clientLeft,o=Nt(e)?Sr(e):Pt(1),s=e.clientWidth*o.x,a=e.clientHeight*o.y,l=i*o.x,c=r*o.y;return{width:s,height:a,x:l,y:c}}function sd(e,t,n){let r;if(t==="viewport")r=M1(e,n);else if(t==="document")r=z1(Tt(e));else if(vt(t))r=B1(t,n);else{const i=rd(e);r={x:t.x-i.x,y:t.y-i.y,width:t.width,height:t.height}}return Mo(r)}function ad(e,t){const n=an(e);return n===t||!vt(n)||Cr(n)?!1:bt(n).position==="fixed"||ad(n,t)}function j1(e,t){const n=t.get(e);if(n)return n;let r=mi(e,[],!1).filter(a=>vt(a)&&xr(a)!=="body"),i=null;const o=bt(e).position==="fixed";let s=o?an(e):e;for(;vt(s)&&!Cr(s);){const a=bt(s),l=Wa(s);!l&&a.position==="fixed"&&(i=null),(o?!l&&!i:!l&&a.position==="static"&&!!i&&$1.has(i.position)||pi(s)&&!l&&ad(e,s))?r=r.filter(u=>u!==s):i=a,s=an(s)}return t.set(e,r),r}function W1(e){let{element:t,boundary:n,rootBoundary:r,strategy:i}=e;const s=[...n==="clippingAncestors"?Bo(t)?[]:j1(t,this._c):[].concat(n),r],a=s[0],l=s.reduce((c,u)=>{const d=sd(t,u,i);return c.top=nt(d.top,c.top),c.right=sn(d.right,c.right),c.bottom=sn(d.bottom,c.bottom),c.left=nt(d.left,c.left),c},sd(t,a,i));return{width:l.right-l.left,height:l.bottom-l.top,x:l.left,y:l.top}}function H1(e){const{width:t,height:n}=nd(e);return{width:t,height:n}}function U1(e,t,n){const r=Nt(t),i=Tt(t),o=n==="fixed",s=_n(e,!0,o,t);let a={scrollLeft:0,scrollTop:0};const l=Pt(0);function c(){l.x=Wo(i)}if(r||!r&&!o)if((xr(t)!=="body"||pi(i))&&(a=jo(t)),r){const m=_n(t,!0,o,t);l.x=m.x+t.clientLeft,l.y=m.y+t.clientTop}else i&&c();o&&!r&&i&&c();const u=i&&!r&&!o?id(i,a):Pt(0),d=s.left+a.scrollLeft-l.x-u.x,h=s.top+a.scrollTop-l.y-u.y;return{x:d,y:h,width:s.width,height:s.height}}function qa(e){return bt(e).position==="static"}function ld(e,t){if(!Nt(e)||bt(e).position==="fixed")return null;if(t)return t(e);let n=e.offsetParent;return Tt(e)===n&&(n=n.ownerDocument.body),n}function cd(e,t){const n=rt(e);if(Bo(e))return n;if(!Nt(e)){let i=an(e);for(;i&&!Cr(i);){if(vt(i)&&!qa(i))return i;i=an(i)}return n}let r=ld(e,t);for(;r&&I1(r)&&qa(r);)r=ld(r,t);return r&&Cr(r)&&qa(r)&&!Wa(r)?n:r||A1(e)||n}const G1=async function(e){const t=this.getOffsetParent||cd,n=this.getDimensions,r=await n(e.floating);return{reference:U1(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:r.width,height:r.height}}};function q1(e){return bt(e).direction==="rtl"}const K1={convertOffsetParentRelativeRectToViewportRelativeRect:L1,getDocumentElement:Tt,getClippingRect:W1,getOffsetParent:cd,getElementRects:G1,getClientRects:D1,getDimensions:H1,getScale:Sr,isElement:vt,isRTL:q1};function ud(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function X1(e,t){let n=null,r;const i=Tt(e);function o(){var a;clearTimeout(r),(a=n)==null||a.disconnect(),n=null}function s(a,l){a===void 0&&(a=!1),l===void 0&&(l=1),o();const c=e.getBoundingClientRect(),{left:u,top:d,width:h,height:m}=c;if(a||t(),!h||!m)return;const f=Do(d),g=Do(i.clientWidth-(u+h)),p=Do(i.clientHeight-(d+m)),b=Do(u),S={rootMargin:-f+"px "+-g+"px "+-p+"px "+-b+"px",threshold:nt(0,sn(1,l))||1};let y=!0;function k(R){const A=R[0].intersectionRatio;if(A!==l){if(!y)return s();A?s(!1,A):r=setTimeout(()=>{s(!1,1e-7)},1e3)}A===1&&!ud(c,e.getBoundingClientRect())&&s(),y=!1}try{n=new IntersectionObserver(k,{...S,root:i.ownerDocument})}catch{n=new IntersectionObserver(k,S)}n.observe(e)}return s(!0),o}function Y1(e,t,n,r){r===void 0&&(r={});const{ancestorScroll:i=!0,ancestorResize:o=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:l=!1}=r,c=Ga(e),u=i||o?[...c?mi(c):[],...mi(t)]:[];u.forEach(b=>{i&&b.addEventListener("scroll",n,{passive:!0}),o&&b.addEventListener("resize",n)});const d=c&&a?X1(c,n):null;let h=-1,m=null;s&&(m=new ResizeObserver(b=>{let[C]=b;C&&C.target===c&&m&&(m.unobserve(t),cancelAnimationFrame(h),h=requestAnimationFrame(()=>{var S;(S=m)==null||S.observe(t)})),n()}),c&&!l&&m.observe(c),m.observe(t));let f,g=l?_n(e):null;l&&p();function p(){const b=_n(e);g&&!ud(g,b)&&n(),g=b,f=requestAnimationFrame(p)}return n(),()=>{var b;u.forEach(C=>{i&&C.removeEventListener("scroll",n),o&&C.removeEventListener("resize",n)}),d==null||d(),(b=m)==null||b.disconnect(),m=null,l&&cancelAnimationFrame(f)}}const Q1=C1,J1=S1,Z1=b1,eC=E1,tC=y1,nC=v1,rC=w1,iC=(e,t,n)=>{const r=new Map,i={platform:K1,...n},o={...i.platform,_c:r};return m1(e,t,{...i,platform:o})};function dd(e=0,t=0,n=0,r=0){if(typeof DOMRect=="function")return new DOMRect(e,t,n,r);const i={x:e,y:t,width:n,height:r,top:t,right:e+n,bottom:t+r,left:e};return{...i,toJSON:()=>i}}function oC(e){if(!e)return dd();const{x:t,y:n,width:r,height:i}=e;return dd(t,n,r,i)}function sC(e,t){return{contextElement:Me(e)?e:void 0,getBoundingClientRect:()=>{const n=e,r=t==null?void 0:t(n);return r||!n?oC(r):n.getBoundingClientRect()}}}var hd=e=>({variable:e,reference:`var(${e})`}),fd={transformOrigin:hd("--transform-origin"),arrowOffset:hd("--arrow-offset")},aC=e=>e==="top"||e==="bottom"?"y":"x";function lC(e,t){return{name:"transformOrigin",fn(n){var N,I,B,P;const{elements:r,middlewareData:i,placement:o,rects:s,y:a}=n,l=o.split("-")[0],c=aC(l),u=((N=i.arrow)==null?void 0:N.x)||0,d=((I=i.arrow)==null?void 0:I.y)||0,h=(t==null?void 0:t.clientWidth)||0,m=(t==null?void 0:t.clientHeight)||0,f=u+h/2,g=d+m/2,p=Math.abs(((B=i.shift)==null?void 0:B.y)||0),b=s.reference.height/2,C=m/2,S=((P=e.offset)==null?void 0:P.mainAxis)??e.gutter,y=typeof S=="number"?S+C:S??C,k=p>y,R={top:`${f}px calc(100% + ${y}px)`,bottom:`${f}px ${-y}px`,left:`calc(100% + ${y}px) ${g}px`,right:`${-y}px ${g}px`}[l],A=`${f}px ${s.reference.y+b-a}px`,T=!!e.overlap&&c==="y"&&k;return r.floating.style.setProperty(fd.transformOrigin.variable,T?A:R),{data:{transformOrigin:T?A:R}}}}}var cC={name:"rects",fn({rects:e}){return{data:e}}},uC=e=>{if(e)return{name:"shiftArrow",fn({placement:t,middlewareData:n}){if(!n.arrow)return{};const{x:r,y:i}=n.arrow,o=t.split("-")[0];return Object.assign(e.style,{left:r!=null?`${r}px`:"",top:i!=null?`${i}px`:"",[o]:`calc(100% + ${fd.arrowOffset.reference})`}),{}}}};function dC(e){const[t,n]=e.split("-");return{side:t,align:n,hasAlign:n!=null}}function hC(e){return e.split("-")[0]}var fC={strategy:"absolute",placement:"bottom",listeners:!0,gutter:8,flip:!0,slide:!0,overlap:!1,sameWidth:!1,fitViewport:!1,overflowPadding:8,arrowPadding:4};function gd(e,t){const n=e.devicePixelRatio||1;return Math.round(t*n)/n}function Ka(e){return typeof e=="function"?e():e==="clipping-ancestors"?"clippingAncestors":e}function gC(e,t,n){const r=e||t.createElement("div");return nC({element:r,padding:n.arrowPadding})}function pC(e,t){if(!Jy(t.offset??t.gutter))return Q1(({placement:n})=>{var c,u;const r=((e==null?void 0:e.clientHeight)||0)/2,i=((c=t.offset)==null?void 0:c.mainAxis)??t.gutter,o=typeof i=="number"?i+r:i??r,{hasAlign:s}=dC(n),a=s?void 0:t.shift,l=((u=t.offset)==null?void 0:u.crossAxis)??a;return bo({crossAxis:l,mainAxis:o,alignmentAxis:t.shift})})}function mC(e){if(!e.flip)return;const t=Ka(e.boundary);return Z1({...t?{boundary:t}:void 0,padding:e.overflowPadding,fallbackPlacements:e.flip===!0?void 0:e.flip})}function vC(e){if(!e.slide&&!e.overlap)return;const t=Ka(e.boundary);return J1({...t?{boundary:t}:void 0,mainAxis:e.slide,crossAxis:e.overlap,padding:e.overflowPadding,limiter:rC()})}function bC(e){return eC({padding:e.overflowPadding,apply({elements:t,rects:n,availableHeight:r,availableWidth:i}){const o=t.floating,s=Math.round(n.reference.width),a=Math.round(n.reference.height);i=Math.floor(i),r=Math.floor(r),o.style.setProperty("--reference-width",`${s}px`),o.style.setProperty("--reference-height",`${a}px`),o.style.setProperty("--available-width",`${i}px`),o.style.setProperty("--available-height",`${r}px`)}})}function yC(e){if(e.hideWhenDetached)return tC({strategy:"referenceHidden",boundary:Ka(e.boundary)??"clippingAncestors"})}function xC(e){return e?e===!0?{ancestorResize:!0,ancestorScroll:!0,elementResize:!0,layoutShift:!0}:e:{}}function CC(e,t,n={}){const r=sC(e,n.getAnchorRect);if(!t||!r)return;const i=Object.assign({},fC,n),o=t.querySelector("[data-part=arrow]"),s=[pC(o,i),mC(i),vC(i),gC(o,t.ownerDocument,i),uC(o),lC({gutter:i.gutter,offset:i.offset,overlap:i.overlap},o),bC(i),yC(i),cC],{placement:a,strategy:l,onComplete:c,onPositioned:u}=i,d=async()=>{var y;if(!r||!t)return;const g=await iC(r,t,{placement:a,middleware:s,strategy:l});c==null||c(g),u==null||u({placed:!0});const p=Ie(t),b=gd(p,g.x),C=gd(p,g.y);t.style.setProperty("--x",`${b}px`),t.style.setProperty("--y",`${C}px`),i.hideWhenDetached&&(((y=g.middlewareData.hide)==null?void 0:y.referenceHidden)?(t.style.setProperty("visibility","hidden"),t.style.setProperty("pointer-events","none")):(t.style.removeProperty("visibility"),t.style.removeProperty("pointer-events")));const S=t.firstElementChild;if(S){const k=xo(S);t.style.setProperty("--z-index",k.zIndex)}},h=async()=>{n.updatePosition?(await n.updatePosition({updatePosition:d,floatingElement:t}),u==null||u({placed:!0})):await d()},m=xC(i.listeners),f=i.listeners?Y1(r,t,h,m):s0;return h(),()=>{f==null||f(),u==null||u({placed:!1})}}function yt(e,t,n={}){const{defer:r,...i}=n,o=r?Z:a=>a(),s=[];return s.push(o(()=>{const a=typeof e=="function"?e():e,l=typeof t=="function"?t():t;s.push(CC(a,l,i))})),()=>{s.forEach(a=>a==null?void 0:a())}}function SC(e){const t={each(n){var r;for(let i=0;i<((r=e.frames)==null?void 0:r.length);i+=1){const o=e.frames[i];o&&n(o)}},addEventListener(n,r,i){return t.each(o=>{try{o.document.addEventListener(n,r,i)}catch{}}),()=>{try{t.removeEventListener(n,r,i)}catch{}}},removeEventListener(n,r,i){t.each(o=>{try{o.document.removeEventListener(n,r,i)}catch{}})}};return t}function wC(e){const t=e.frameElement!=null?e.parent:null;return{addEventListener:(n,r,i)=>{try{t==null||t.addEventListener(n,r,i)}catch{}return()=>{try{t==null||t.removeEventListener(n,r,i)}catch{}}},removeEventListener:(n,r,i)=>{try{t==null||t.removeEventListener(n,r,i)}catch{}}}}var pd="pointerdown.outside",md="focus.outside";function EC(e){for(const t of e)if(Me(t)&&nn(t))return!0;return!1}var vd=e=>"clientY"in e;function kC(e,t){if(!vd(t)||!e)return!1;const n=e.getBoundingClientRect();return n.width===0||n.height===0?!1:n.top<=t.clientY&&t.clientY<=n.top+n.height&&n.left<=t.clientX&&t.clientX<=n.left+n.width}function OC(e,t){return e.y<=t.y&&t.y<=e.y+e.height&&e.x<=t.x&&t.x<=e.x+e.width}function bd(e,t){if(!t||!vd(e))return!1;const n=t.scrollHeight>t.clientHeight,r=n&&e.clientX>t.offsetLeft+t.clientWidth,i=t.scrollWidth>t.clientWidth,o=i&&e.clientY>t.offsetTop+t.clientHeight,s={x:t.offsetLeft,y:t.offsetTop,width:t.clientWidth+(n?16:0),height:t.clientHeight+(i?16:0)},a={x:e.clientX,y:e.clientY};return OC(s,a)?r||o:!1}function IC(e,t){const{exclude:n,onFocusOutside:r,onPointerDownOutside:i,onInteractOutside:o,defer:s}=t;if(!e)return;const a=Ge(e),l=Ie(e),c=SC(l),u=wC(l);function d(C,S){if(!Me(S)||!S.isConnected||Nn(e,S)||kC(e,C))return!1;const y=a.querySelector(`[aria-controls="${e.id}"]`);if(y){const R=Oo(y);if(bd(C,R))return!1}const k=Oo(e);return bd(C,k)?!1:!(n!=null&&n(S))}const h=new Set,m=pr(e==null?void 0:e.getRootNode());function f(C){function S(y){var T;const k=s&&!Cu()?Z:N=>N(),R=y??C,A=((T=R==null?void 0:R.composedPath)==null?void 0:T.call(R))??[R==null?void 0:R.target];k(()=>{const N=m?A[0]:tt(C);if(!(!e||!d(C,N))){if(i||o){const I=mo(i,o);e.addEventListener(pd,I,{once:!0})}yd(e,pd,{bubbles:!1,cancelable:!0,detail:{originalEvent:R,contextmenu:Y0(R),focusable:EC(A),target:N}})}})}C.pointerType==="touch"?(h.forEach(y=>y()),h.add(he(a,"click",S,{once:!0})),h.add(u.addEventListener("click",S,{once:!0})),h.add(c.addEventListener("click",S,{once:!0}))):S()}const g=new Set,p=setTimeout(()=>{g.add(he(a,"pointerdown",f,!0)),g.add(u.addEventListener("pointerdown",f,!0)),g.add(c.addEventListener("pointerdown",f,!0))},0);function b(C){(s?Z:y=>y())(()=>{const y=tt(C);if(!(!e||!d(C,y))){if(r||o){const k=mo(r,o);e.addEventListener(md,k,{once:!0})}yd(e,md,{bubbles:!1,cancelable:!0,detail:{originalEvent:C,contextmenu:!1,focusable:nn(y),target:y}})}})}return Cu()||(g.add(he(a,"focusin",b,!0)),g.add(u.addEventListener("focusin",b,!0)),g.add(c.addEventListener("focusin",b,!0))),()=>{clearTimeout(p),h.forEach(C=>C()),g.forEach(C=>C())}}function PC(e,t){const{defer:n}=t,r=n?Z:o=>o(),i=[];return i.push(r(()=>{const o=typeof e=="function"?e():e;i.push(IC(o,t))})),()=>{i.forEach(o=>o==null?void 0:o())}}function yd(e,t,n){const r=e.ownerDocument.defaultView||window,i=new r.CustomEvent(t,n);return e.dispatchEvent(i)}function RC(e,t){const n=r=>{r.key==="Escape"&&(r.isComposing||t==null||t(r))};return he(Ge(e),"keydown",n,{capture:!0})}var xd="layer:request-dismiss",at={layers:[],branches:[],count(){return this.layers.length},pointerBlockingLayers(){return this.layers.filter(e=>e.pointerBlocking)},topMostPointerBlockingLayer(){return[...this.pointerBlockingLayers()].slice(-1)[0]},hasPointerBlockingLayer(){return this.pointerBlockingLayers().length>0},isBelowPointerBlockingLayer(e){var r;const t=this.indexOf(e),n=this.topMostPointerBlockingLayer()?this.indexOf((r=this.topMostPointerBlockingLayer())==null?void 0:r.node):-1;return tt.type===e)},getNestedLayersByType(e,t){const n=this.indexOf(e);return n===-1?[]:this.layers.slice(n+1).filter(r=>r.type===t)},getParentLayerOfType(e,t){const n=this.indexOf(e);if(!(n<=0))return this.layers.slice(0,n).reverse().find(r=>r.type===t)},countNestedLayersOfType(e,t){return this.getNestedLayersByType(e,t).length},isInNestedLayer(e,t){return this.getNestedLayers(e).some(n=>Nn(n.node,t))},isInBranch(e){return Array.from(this.branches).some(t=>Nn(t,e))},add(e){this.layers.push(e),this.syncLayers()},addBranch(e){this.branches.push(e)},remove(e){const t=this.indexOf(e);t<0||(tat.dismiss(r.node,e)),this.layers.splice(t,1),this.syncLayers())},removeBranch(e){const t=this.branches.indexOf(e);t>=0&&this.branches.splice(t,1)},syncLayers(){this.layers.forEach((e,t)=>{e.node.style.setProperty("--layer-index",`${t}`),e.node.removeAttribute("data-nested"),e.node.removeAttribute("data-has-nested"),this.getParentLayerOfType(e.node,e.type)&&e.node.setAttribute("data-nested",e.type);const r=this.countNestedLayersOfType(e.node,e.type);r>0&&e.node.setAttribute("data-has-nested",e.type),e.node.style.setProperty("--nested-layer-count",`${r}`)})},indexOf(e){return this.layers.findIndex(t=>t.node===e)},dismiss(e,t){const n=this.indexOf(e);if(n===-1)return;const r=this.layers[n];NC(e,xd,i=>{var o;(o=r.requestDismiss)==null||o.call(r,i),i.defaultPrevented||r==null||r.dismiss()}),TC(e,xd,{originalLayer:e,targetLayer:t,originalIndex:n,targetIndex:t?this.indexOf(t):-1}),this.syncLayers()},clear(){this.remove(this.layers[0].node)}};function TC(e,t,n){const r=e.ownerDocument.defaultView||window,i=new r.CustomEvent(t,{cancelable:!0,bubbles:!0,detail:n});return e.dispatchEvent(i)}function NC(e,t,n){e.addEventListener(t,n,{once:!0})}var Cd;function Sd(){at.layers.forEach(({node:e})=>{e.style.pointerEvents=at.isBelowPointerBlockingLayer(e)?"none":"auto"})}function AC(e){e.style.pointerEvents=""}function _C(e,t){const n=Ge(e),r=[];return at.hasPointerBlockingLayer()&&!n.body.hasAttribute("data-inert")&&(Cd=document.body.style.pointerEvents,queueMicrotask(()=>{n.body.style.pointerEvents="none",n.body.setAttribute("data-inert","")})),t==null||t.forEach(i=>{const[o,s]=Rx(()=>{const a=i();return Me(a)?a:null},{timeout:1e3});o.then(a=>r.push(To(a,{pointerEvents:"auto"}))),r.push(s)}),()=>{at.hasPointerBlockingLayer()||(queueMicrotask(()=>{n.body.style.pointerEvents=Cd,n.body.removeAttribute("data-inert"),n.body.style.length===0&&n.body.removeAttribute("style")}),r.forEach(i=>i()))}}function VC(e,t){const{warnOnMissingNode:n=!0}=t;if(n&&!e){ui("[@zag-js/dismissable] node is `null` or `undefined`");return}if(!e)return;const{onDismiss:r,onRequestDismiss:i,pointerBlocking:o,exclude:s,debug:a,type:l="dialog"}=t,c={dismiss:r,node:e,type:l,pointerBlocking:o,requestDismiss:i};at.add(c),Sd();function u(g){var b,C;const p=tt(g.detail.originalEvent);at.isBelowPointerBlockingLayer(e)||at.isInBranch(p)||((b=t.onPointerDownOutside)==null||b.call(t,g),(C=t.onInteractOutside)==null||C.call(t,g),!g.defaultPrevented&&(a&&console.log("onPointerDownOutside:",g.detail.originalEvent),r==null||r()))}function d(g){var b,C;const p=tt(g.detail.originalEvent);at.isInBranch(p)||((b=t.onFocusOutside)==null||b.call(t,g),(C=t.onInteractOutside)==null||C.call(t,g),!g.defaultPrevented&&(a&&console.log("onFocusOutside:",g.detail.originalEvent),r==null||r()))}function h(g){var p;at.isTopMost(e)&&((p=t.onEscapeKeyDown)==null||p.call(t,g),!g.defaultPrevented&&r&&(g.preventDefault(),r()))}function m(g){var S;if(!e)return!1;const p=typeof s=="function"?s():s,b=Array.isArray(p)?p:[p],C=(S=t.persistentElements)==null?void 0:S.map(y=>y()).filter(Me);return C&&b.push(...C),b.some(y=>Nn(y,g))||at.isInNestedLayer(e,g)}const f=[o?_C(e,t.persistentElements):void 0,RC(e,h),PC(e,{exclude:m,onFocusOutside:d,onPointerDownOutside:u,defer:t.defer})];return()=>{at.remove(e),Sd(),AC(e),f.forEach(g=>g==null?void 0:g())}}function wr(e,t){const{defer:n}=t,r=n?Z:o=>o(),i=[];return i.push(r(()=>{const o=Tn(e)?e():e;i.push(VC(o,t))})),()=>{i.forEach(o=>o==null?void 0:o())}}var wd=K("color-picker",["root","label","control","trigger","positioner","content","area","areaThumb","valueText","areaBackground","channelSlider","channelSliderLabel","channelSliderTrack","channelSliderThumb","channelSliderValueText","channelInput","transparencyGrid","swatchGroup","swatchTrigger","swatchIndicator","swatch","eyeDropperTrigger","formatTrigger","formatSelect"]);wd.build();var FC=e=>{var t;return((t=e.ids)==null?void 0:t.hiddenInput)??`color-picker:${e.id}:hidden-input`},LC=e=>{var t;return((t=e.ids)==null?void 0:t.control)??`color-picker:${e.id}:control`},DC=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`color-picker:${e.id}:trigger`},zC=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`color-picker:${e.id}:content`},MC=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`color-picker:${e.id}:positioner`},$C=e=>{var t;return((t=e.ids)==null?void 0:t.formatSelect)??`color-picker:${e.id}:format-select`},BC=e=>{var t;return((t=e.ids)==null?void 0:t.area)??`color-picker:${e.id}:area`},jC=e=>{var t;return((t=e.ids)==null?void 0:t.areaThumb)??`color-picker:${e.id}:area-thumb`},WC=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.channelSliderTrack)==null?void 0:r.call(n,t))??`color-picker:${e.id}:slider-track:${t}`},HC=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.channelSliderThumb)==null?void 0:r.call(n,t))??`color-picker:${e.id}:slider-thumb:${t}`},Ho=e=>e.getById(zC(e)),UC=e=>e.getById(jC(e)),GC=(e,t)=>e.getById(HC(e,t)),qC=e=>e.getById($C(e)),Ed=e=>e.getById(FC(e)),KC=e=>e.getById(BC(e)),XC=(e,t,n)=>{const r=KC(e);if(!r)return;const{getPercentValue:i}=Pu(t,r);return{x:i({dir:n,orientation:"horizontal"}),y:i({orientation:"vertical"})}},YC=e=>e.getById(LC(e)),Xa=e=>e.getById(DC(e)),QC=e=>e.getById(MC(e)),JC=(e,t)=>e.getById(WC(e,t)),ZC=(e,t,n,r)=>{const i=JC(e,n);if(!i)return;const{getPercentValue:o}=Pu(t,i);return{x:o({dir:r,orientation:"horizontal"}),y:o({orientation:"vertical"})}},eS=e=>[...Ro(Ho(e),"input[data-channel]"),...Ro(YC(e),"input[data-channel]")];function tS(e,t){if(t==null)return"";if(t==="hex")return e.toString("hex");if(t==="css")return e.toString("css");if(t in e)return e.getChannelValue(t).toString();const n=e.getFormat()==="hsla";switch(t){case"hue":return n?e.toFormat("hsla").getChannelValue("hue").toString():e.toFormat("hsba").getChannelValue("hue").toString();case"saturation":return n?e.toFormat("hsla").getChannelValue("saturation").toString():e.toFormat("hsba").getChannelValue("saturation").toString();case"lightness":return e.toFormat("hsla").getChannelValue("lightness").toString();case"brightness":return e.toFormat("hsba").getChannelValue("brightness").toString();case"red":case"green":case"blue":return e.toFormat("rgba").getChannelValue(t).toString();default:return e.getChannelValue(t).toString()}}var kd=e=>Fo(e),nS=/^[0-9a-fA-F]{3,8}$/;function rS(e){return nS.test(e)}function iS(e){return e.startsWith("#")?e:rS(e)?`#${e}`:e}var{and:oS}=rn();oS("isOpenControlled","closeOnSelect");function Od(e,t,n){const r=eS(e);Z(()=>{r.forEach(i=>{const o=i.dataset.channel;Eo(i,tS(n||t,o))})})}function sS(e,t){const n=qC(e);n&&Z(()=>Eo(n,t))}q()(["closeOnSelect","dir","disabled","format","defaultFormat","getRootNode","id","ids","initialFocusEl","inline","name","positioning","onFocusOutside","onFormatChange","onInteractOutside","onOpenChange","onPointerDownOutside","onValueChange","onValueChangeEnd","defaultOpen","open","positioning","required","readOnly","value","defaultValue","invalid","openAutoFocus"]),q()(["xChannel","yChannel"]),q()(["channel","orientation"]),q()(["value","disabled"]),q()(["value","respectAlpha"]),q()(["size"]);const[Id,aS]=gr({name:"RenderStrategyContext",hookName:"useRenderStrategyContext",providerName:""}),Pd=e=>_u()(e,["lazyMount","unmountOnExit"]);var Rd=K("accordion").parts("root","item","itemTrigger","itemContent","itemIndicator");Rd.build();var Td=e=>{var t;return((t=e.ids)==null?void 0:t.root)??`accordion:${e.id}`},Nd=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.itemTrigger)==null?void 0:r.call(n,t))??`accordion:${e.id}:trigger:${t}`},lS=e=>e.getById(Td(e)),Uo=e=>{const n=`[aria-controls][data-ownedby='${CSS.escape(Td(e))}']:not([disabled])`;return Ro(lS(e),n)},cS=e=>li(Uo(e)),uS=e=>fa(Uo(e)),dS=(e,t)=>yx(Uo(e),Nd(e,t)),hS=(e,t)=>xx(Uo(e),Nd(e,t)),{and:fS,not:gS}=rn();fS("isExpanded","canToggle"),gS("isExpanded"),q()(["collapsible","dir","disabled","getRootNode","id","ids","multiple","onFocusChange","onValueChange","orientation","value","defaultValue"]),q()(["value","disabled"]);var vi=(e,t)=>({x:e,y:t});function pS(e){const{x:t,y:n,width:r,height:i}=e,o=t+r/2,s=n+i/2;return{x:t,y:n,width:r,height:i,minX:t,minY:n,maxX:t+r,maxY:n+i,midX:o,midY:s,center:vi(o,s)}}function mS(e){const t=vi(e.minX,e.minY),n=vi(e.maxX,e.minY),r=vi(e.maxX,e.maxY),i=vi(e.minX,e.maxY);return{top:t,right:n,bottom:r,left:i}}function vS(e,t){const n=pS(e),{top:r,right:i,left:o,bottom:s}=mS(n),[a]=t.split("-");return{top:[o,r,i,s],right:[r,i,s,o],bottom:[r,o,s,i],left:[i,r,o,s]}[a]}function bS(e,t){const{x:n,y:r}=t;let i=!1;for(let o=0,s=e.length-1;or!=u>r&&n<(c-a)*(r-l)/(u-l)+a&&(i=!i)}return i}var Ad=K("avatar").parts("root","image","fallback");Ad.build(),q()(["dir","id","ids","onStatusChange","getRootNode"]);function yS(e){return!(e.metaKey||!wo()&&e.altKey||e.ctrlKey||e.key==="Control"||e.key==="Shift"||e.key==="Meta")}var xS=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);function CS(e,t,n){const r=n?tt(n):null,i=Ie(r);return e=e||r instanceof i.HTMLInputElement&&!xS.has(r==null?void 0:r.type)||r instanceof i.HTMLTextAreaElement||r instanceof i.HTMLElement&&r.isContentEditable,!(e&&t==="keyboard"&&n instanceof i.KeyboardEvent&&!Reflect.has(SS,n.key))}var Vn=null,Ya=new Set,bi=new Map,Fn=!1,Qa=!1,SS={Tab:!0,Escape:!0};function Go(e,t){for(let n of Ya)n(e,t)}function qo(e){Fn=!0,yS(e)&&(Vn="keyboard",Go("keyboard",e))}function lt(e){Vn="pointer",(e.type==="mousedown"||e.type==="pointerdown")&&(Fn=!0,Go("pointer",e))}function _d(e){X0(e)&&(Fn=!0,Vn="virtual")}function Vd(e){const t=tt(e);t===Ie(t)||t===Ge(t)||(!Fn&&!Qa&&(Vn="virtual",Go("virtual",e)),Fn=!1,Qa=!1)}function Fd(){Fn=!1,Qa=!0}function wS(e){if(typeof window>"u"||bi.get(Ie(e)))return;const t=Ie(e),n=Ge(e);let r=t.HTMLElement.prototype.focus;function i(){Vn="virtual",Go("virtual",null),Fn=!0,r.apply(this,arguments)}Object.defineProperty(t.HTMLElement.prototype,"focus",{configurable:!0,value:i}),n.addEventListener("keydown",qo,!0),n.addEventListener("keyup",qo,!0),n.addEventListener("click",_d,!0),t.addEventListener("focus",Vd,!0),t.addEventListener("blur",Fd,!1),typeof t.PointerEvent<"u"?(n.addEventListener("pointerdown",lt,!0),n.addEventListener("pointermove",lt,!0),n.addEventListener("pointerup",lt,!0)):(n.addEventListener("mousedown",lt,!0),n.addEventListener("mousemove",lt,!0),n.addEventListener("mouseup",lt,!0)),t.addEventListener("beforeunload",()=>{ES(e)},{once:!0}),bi.set(t,{focus:r})}var ES=(e,t)=>{const n=Ie(e),r=Ge(e);bi.has(n)&&(n.HTMLElement.prototype.focus=bi.get(n).focus,r.removeEventListener("keydown",qo,!0),r.removeEventListener("keyup",qo,!0),r.removeEventListener("click",_d,!0),n.removeEventListener("focus",Vd,!0),n.removeEventListener("blur",Fd,!1),typeof n.PointerEvent<"u"?(r.removeEventListener("pointerdown",lt,!0),r.removeEventListener("pointermove",lt,!0),r.removeEventListener("pointerup",lt,!0)):(r.removeEventListener("mousedown",lt,!0),r.removeEventListener("mousemove",lt,!0),r.removeEventListener("mouseup",lt,!0)),bi.delete(n))};function Ld(){return Vn==="keyboard"}function kS(e={}){const{isTextInput:t,autoFocus:n,onChange:r,root:i}=e;wS(i),r==null||r({isFocusVisible:n||Ld(),modality:Vn});const o=(s,a)=>{CS(!!t,s,a)&&(r==null||r({isFocusVisible:Ld(),modality:s}))};return Ya.add(o),()=>{Ya.delete(o)}}var Dd=K("checkbox").parts("root","label","control","indicator");Dd.build(),q()(["defaultChecked","checked","dir","disabled","form","getRootNode","id","ids","invalid","name","onCheckedChange","readOnly","required","value"]);const OS=Dd.extendWith("group"),[a_,IS]=gr({name:"FieldContext",hookName:"useFieldContext",providerName:"",strict:!1});var zd=K("clipboard").parts("root","control","trigger","indicator","input","label");zd.build(),q()(["getRootNode","id","ids","value","defaultValue","timeout","onStatusChange","onValueChange"]),q()(["copied"]);const PS=wd.extendWith("view");var RS=Object.defineProperty,TS=(e,t,n)=>t in e?RS(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,V=(e,t,n)=>TS(e,typeof t!="symbol"?t+"":t,n),Ko={itemToValue(e){return typeof e=="string"?e:Rn(e)&&en(e,"value")?e.value:""},itemToString(e){return typeof e=="string"?e:Rn(e)&&en(e,"label")?e.label:Ko.itemToValue(e)},isItemDisabled(e){return Rn(e)&&en(e,"disabled")?!!e.disabled:!1}},Xo=class pb{constructor(t){this.options=t,V(this,"items"),V(this,"indexMap",null),V(this,"copy",n=>new pb({...this.options,items:n??[...this.items]})),V(this,"isEqual",n=>pt(this.items,n.items)),V(this,"setItems",n=>this.copy(n)),V(this,"getValues",(n=this.items)=>{const r=[];for(const i of n){const o=this.getItemValue(i);o!=null&&r.push(o)}return r}),V(this,"find",n=>{if(n==null)return null;const r=this.indexOf(n);return r!==-1?this.at(r):null}),V(this,"findMany",n=>{const r=[];for(const i of n){const o=this.find(i);o!=null&&r.push(o)}return r}),V(this,"at",n=>{if(!this.options.groupBy&&!this.options.groupSort)return this.items[n]??null;let r=0;const i=this.group();for(const[,o]of i)for(const s of o){if(r===n)return s;r++}return null}),V(this,"sortFn",(n,r)=>{const i=this.indexOf(n),o=this.indexOf(r);return(i??0)-(o??0)}),V(this,"sort",n=>[...n].sort(this.sortFn.bind(this))),V(this,"getItemValue",n=>{var r,i;return n==null?null:((i=(r=this.options).itemToValue)==null?void 0:i.call(r,n))??Ko.itemToValue(n)}),V(this,"getItemDisabled",n=>{var r,i;return n==null?!1:((i=(r=this.options).isItemDisabled)==null?void 0:i.call(r,n))??Ko.isItemDisabled(n)}),V(this,"stringifyItem",n=>{var r,i;return n==null?null:((i=(r=this.options).itemToString)==null?void 0:i.call(r,n))??Ko.itemToString(n)}),V(this,"stringify",n=>n==null?null:this.stringifyItem(this.find(n))),V(this,"stringifyItems",(n,r=", ")=>{const i=[];for(const o of n){const s=this.stringifyItem(o);s!=null&&i.push(s)}return i.join(r)}),V(this,"stringifyMany",(n,r)=>this.stringifyItems(this.findMany(n),r)),V(this,"has",n=>this.indexOf(n)!==-1),V(this,"hasItem",n=>n==null?!1:this.has(this.getItemValue(n))),V(this,"group",()=>{const{groupBy:n,groupSort:r}=this.options;if(!n)return[["",[...this.items]]];const i=new Map;this.items.forEach((s,a)=>{const l=n(s,a);i.has(l)||i.set(l,[]),i.get(l).push(s)});let o=Array.from(i.entries());return r&&o.sort(([s],[a])=>{if(typeof r=="function")return r(s,a);if(Array.isArray(r)){const l=r.indexOf(s),c=r.indexOf(a);return l===-1?1:c===-1?-1:l-c}return r==="asc"?s.localeCompare(a):r==="desc"?a.localeCompare(s):0}),o}),V(this,"getNextValue",(n,r=1,i=!1)=>{let o=this.indexOf(n);if(o===-1)return null;for(o=i?Math.min(o+r,this.size-1):o+r;o<=this.size&&this.getItemDisabled(this.at(o));)o++;return this.getItemValue(this.at(o))}),V(this,"getPreviousValue",(n,r=1,i=!1)=>{let o=this.indexOf(n);if(o===-1)return null;for(o=i?Math.max(o-r,0):o-r;o>=0&&this.getItemDisabled(this.at(o));)o--;return this.getItemValue(this.at(o))}),V(this,"indexOf",n=>{if(n==null)return-1;if(!this.options.groupBy&&!this.options.groupSort)return this.items.findIndex(r=>this.getItemValue(r)===n);if(!this.indexMap){this.indexMap=new Map;let r=0;const i=this.group();for(const[,o]of i)for(const s of o){const a=this.getItemValue(s);a!=null&&this.indexMap.set(a,r),r++}}return this.indexMap.get(n)??-1}),V(this,"getByText",(n,r)=>{const i=r!=null?this.indexOf(r):-1,o=n.length===1;for(let s=0;s{const{state:i,currentValue:o,timeout:s=350}=r,a=i.keysSoFar+n,c=a.length>1&&Array.from(a).every(f=>f===a[0])?a[0]:a,u=this.getByText(c,o),d=this.getItemValue(u);function h(){clearTimeout(i.timer),i.timer=-1}function m(f){i.keysSoFar=f,h(),f!==""&&(i.timer=+setTimeout(()=>{m(""),h()},s))}return m(a),d}),V(this,"update",(n,r)=>{let i=this.indexOf(n);return i===-1?this:this.copy([...this.items.slice(0,i),r,...this.items.slice(i+1)])}),V(this,"upsert",(n,r,i="append")=>{let o=this.indexOf(n);return o===-1?(i==="append"?this.append:this.prepend)(r):this.copy([...this.items.slice(0,o),r,...this.items.slice(o+1)])}),V(this,"insert",(n,...r)=>this.copy(yi(this.items,n,...r))),V(this,"insertBefore",(n,...r)=>{let i=this.indexOf(n);if(i===-1)if(this.items.length===0)i=0;else return this;return this.copy(yi(this.items,i,...r))}),V(this,"insertAfter",(n,...r)=>{let i=this.indexOf(n);if(i===-1)if(this.items.length===0)i=0;else return this;return this.copy(yi(this.items,i+1,...r))}),V(this,"prepend",(...n)=>this.copy(yi(this.items,0,...n))),V(this,"append",(...n)=>this.copy(yi(this.items,this.items.length,...n))),V(this,"filter",n=>{const r=this.items.filter((i,o)=>n(this.stringifyItem(i),o,i));return this.copy(r)}),V(this,"remove",(...n)=>{const r=n.map(i=>typeof i=="string"?i:this.getItemValue(i));return this.copy(this.items.filter(i=>{const o=this.getItemValue(i);return o==null?!1:!r.includes(o)}))}),V(this,"move",(n,r)=>{const i=this.indexOf(n);return i===-1?this:this.copy(Yo(this.items,[i],r))}),V(this,"moveBefore",(n,...r)=>{let i=this.items.findIndex(s=>this.getItemValue(s)===n);if(i===-1)return this;let o=r.map(s=>this.items.findIndex(a=>this.getItemValue(a)===s)).sort((s,a)=>s-a);return this.copy(Yo(this.items,o,i))}),V(this,"moveAfter",(n,...r)=>{let i=this.items.findIndex(s=>this.getItemValue(s)===n);if(i===-1)return this;let o=r.map(s=>this.items.findIndex(a=>this.getItemValue(a)===s)).sort((s,a)=>s-a);return this.copy(Yo(this.items,o,i+1))}),V(this,"reorder",(n,r)=>this.copy(Yo(this.items,[n],r))),V(this,"compareValue",(n,r)=>{const i=this.indexOf(n),o=this.indexOf(r);return io?1:0}),V(this,"range",(n,r)=>{let i=[],o=n;for(;o!=null;){if(this.find(o)&&i.push(o),o===r)return i;o=this.getNextValue(o)}return[]}),V(this,"getValueRange",(n,r)=>n&&r?this.compareValue(n,r)<=0?this.range(n,r):this.range(r,n):[]),V(this,"toString",()=>{let n="";for(const r of this.items){const i=this.getItemValue(r),o=this.stringifyItem(r),s=this.getItemDisabled(r),a=[i,o,s].filter(Boolean).join(":");n+=a+","}return n}),V(this,"toJSON",()=>({size:this.size,first:this.firstValue,last:this.lastValue})),this.items=[...t.items]}get size(){return this.items.length}get firstValue(){let t=0;for(;this.getItemDisabled(this.at(t));)t++;return this.getItemValue(this.at(t))}get lastValue(){let t=this.size-1;for(;this.getItemDisabled(this.at(t));)t--;return this.getItemValue(this.at(t))}*[Symbol.iterator](){yield*this.items}},NS=(e,t)=>!!(e!=null&&e.toLowerCase().startsWith(t.toLowerCase()));function yi(e,t,...n){return[...e.slice(0,t),...n,...e.slice(t)]}function Yo(e,t,n){t=[...t].sort((i,o)=>i-o);const r=t.map(i=>e[i]);for(let i=t.length-1;i>=0;i--)e=[...e.slice(0,t[i]),...e.slice(t[i]+1)];return n=Math.max(0,n-t.filter(i=>it[n])return 1}return e.length-t.length}function _S(e){return e.sort($d)}function VS(e,t){let n;return it(e,{...t,onEnter:(r,i)=>{if(t.predicate(r,i))return n=r,"stop"}}),n}function FS(e,t){const n=[];return it(e,{onEnter:(r,i)=>{t.predicate(r,i)&&n.push(r)},getChildren:t.getChildren}),n}function Bd(e,t){let n;return it(e,{onEnter:(r,i)=>{if(t.predicate(r,i))return n=[...i],"stop"},getChildren:t.getChildren}),n}function LS(e,t){let n=t.initialResult;return it(e,{...t,onEnter:(r,i)=>{n=t.nextResult(n,r,i)}}),n}function DS(e,t){return LS(e,{...t,initialResult:[],nextResult:(n,r,i)=>(n.push(...t.transform(r,i)),n)})}function zS(e,t){const{predicate:n,create:r,getChildren:i}=t,o=(s,a)=>{const l=i(s,a),c=[];l.forEach((m,f)=>{const g=[...a,f],p=o(m,g);p&&c.push(p)});const u=a.length===0,d=n(s,a),h=c.length>0;return u||d||h?r(s,c,a):null};return o(e,[])||r(e,[],[])}function MS(e,t){const n=[];let r=0;const i=new Map,o=new Map;return it(e,{getChildren:t.getChildren,onEnter:(s,a)=>{i.has(s)||i.set(s,r++);const l=t.getChildren(s,a);l.forEach(m=>{o.has(m)||o.set(m,s),i.has(m)||i.set(m,r++)});const c=l.length>0?l.map(m=>i.get(m)):void 0,u=o.get(s),d=u?i.get(u):void 0,h=i.get(s);n.push({...s,_children:c,_parent:d,_index:h})}}),n}function $S(e,t){return{type:"insert",index:e,nodes:t}}function BS(e){return{type:"remove",indexes:e}}function Ja(){return{type:"replace"}}function jd(e){return[e.slice(0,-1),e[e.length-1]]}function Wd(e,t,n=new Map){var s;const[r,i]=jd(e);for(let a=r.length-1;a>=0;a--){const l=r.slice(0,a).join();switch((s=n.get(l))==null?void 0:s.type){case"remove":continue}n.set(l,Ja())}const o=n.get(r.join());switch(o==null?void 0:o.type){case"remove":n.set(r.join(),{type:"removeThenInsert",removeIndexes:o.indexes,insertIndex:i,insertNodes:t});break;default:n.set(r.join(),$S(i,t))}return n}function Hd(e){const t=new Map,n=new Map;for(const r of e){const i=r.slice(0,-1).join(),o=n.get(i)??[];o.push(r[r.length-1]),n.set(i,o.sort((s,a)=>s-a))}for(const r of e)for(let i=r.length-2;i>=0;i--){const o=r.slice(0,i).join();t.has(o)||t.set(o,Ja())}for(const[r,i]of n)t.set(r,BS(i));return t}function jS(e,t){const n=new Map,[r,i]=jd(e);for(let o=r.length-1;o>=0;o--){const s=r.slice(0,o).join();n.set(s,Ja())}return n.set(r.join(),{type:"removeThenInsert",removeIndexes:[i],insertIndex:i,insertNodes:[t]}),n}function Qo(e,t,n){return WS(e,{...n,getChildren:(r,i)=>{const o=i.join(),s=t.get(o);switch(s==null?void 0:s.type){case"replace":case"remove":case"removeThenInsert":case"insert":return n.getChildren(r,i);default:return[]}},transform:(r,i,o)=>{const s=o.join(),a=t.get(s);switch(a==null?void 0:a.type){case"remove":return n.create(r,i.filter((u,d)=>!a.indexes.includes(d)),o);case"removeThenInsert":const l=i.filter((u,d)=>!a.removeIndexes.includes(d)),c=a.removeIndexes.reduce((u,d)=>d{const o=[0,...i],s=o.join(),a=t.transform(r,n[s]??[],i),l=o.slice(0,-1).join(),c=n[l]??[];c.push(a),n[l]=c}}),n[""][0]}function HS(e,t){const{nodes:n,at:r}=t;if(r.length===0)throw new Error("Can't insert nodes at the root");const i=Wd(r,n);return Qo(e,i,t)}function US(e,t){if(t.at.length===0)return t.node;const n=jS(t.at,t.node);return Qo(e,n,t)}function GS(e,t){if(t.indexPaths.length===0)return e;for(const r of t.indexPaths)if(r.length===0)throw new Error("Can't remove the root node");const n=Hd(t.indexPaths);return Qo(e,n,t)}function qS(e,t){if(t.indexPaths.length===0)return e;for(const o of t.indexPaths)if(o.length===0)throw new Error("Can't move the root node");if(t.to.length===0)throw new Error("Can't move nodes to the root");const n=AS(t.indexPaths),r=n.map(o=>Md(e,o,t)),i=Wd(t.to,r,Hd(n));return Qo(e,i,t)}function it(e,t){const{onEnter:n,onLeave:r,getChildren:i}=t;let o=[],s=[{node:e}];const a=t.reuseIndexPath?()=>o:()=>o.slice();for(;s.length>0;){let l=s[s.length-1];if(l.state===void 0){const u=n==null?void 0:n(l.node,a());if(u==="stop")return;l.state=u==="skip"?-1:0}const c=l.children||i(l.node,a());if(l.children||(l.children=c),l.state!==-1){if(l.statept(this.rootNode,n.rootNode)),V(this,"getNodeChildren",n=>{var r,i;return((i=(r=this.options).nodeToChildren)==null?void 0:i.call(r,n))??Er.nodeToChildren(n)??[]}),V(this,"resolveIndexPath",n=>typeof n=="string"?this.getIndexPath(n):n),V(this,"resolveNode",n=>{const r=this.resolveIndexPath(n);return r?this.at(r):void 0}),V(this,"getNodeChildrenCount",n=>{var r,i;return((i=(r=this.options).nodeToChildrenCount)==null?void 0:i.call(r,n))??Er.nodeToChildrenCount(n)}),V(this,"getNodeValue",n=>{var r,i;return((i=(r=this.options).nodeToValue)==null?void 0:i.call(r,n))??Er.nodeToValue(n)}),V(this,"getNodeDisabled",n=>{var r,i;return((i=(r=this.options).isNodeDisabled)==null?void 0:i.call(r,n))??Er.isNodeDisabled(n)}),V(this,"stringify",n=>{const r=this.findNode(n);return r?this.stringifyNode(r):null}),V(this,"stringifyNode",n=>{var r,i;return((i=(r=this.options).nodeToString)==null?void 0:i.call(r,n))??Er.nodeToString(n)}),V(this,"getFirstNode",(n=this.rootNode)=>{let r;return it(n,{getChildren:this.getNodeChildren,onEnter:(i,o)=>{if(!r&&o.length>0&&!this.getNodeDisabled(i))return r=i,"stop"}}),r}),V(this,"getLastNode",(n=this.rootNode,r={})=>{let i;return it(n,{getChildren:this.getNodeChildren,onEnter:(o,s)=>{var a;if(!this.isSameNode(o,n)){if((a=r.skip)!=null&&a.call(r,{value:this.getNodeValue(o),node:o,indexPath:s}))return"skip";s.length>0&&!this.getNodeDisabled(o)&&(i=o)}}}),i}),V(this,"at",n=>Md(this.rootNode,n,{getChildren:this.getNodeChildren})),V(this,"findNode",(n,r=this.rootNode)=>VS(r,{getChildren:this.getNodeChildren,predicate:i=>this.getNodeValue(i)===n})),V(this,"findNodes",(n,r=this.rootNode)=>{const i=new Set(n.filter(o=>o!=null));return FS(r,{getChildren:this.getNodeChildren,predicate:o=>i.has(this.getNodeValue(o))})}),V(this,"sort",n=>n.reduce((r,i)=>{const o=this.getIndexPath(i);return o&&r.push({value:i,indexPath:o}),r},[]).sort((r,i)=>$d(r.indexPath,i.indexPath)).map(({value:r})=>r)),V(this,"getIndexPath",n=>Bd(this.rootNode,{getChildren:this.getNodeChildren,predicate:r=>this.getNodeValue(r)===n})),V(this,"getValue",n=>{const r=this.at(n);return r?this.getNodeValue(r):void 0}),V(this,"getValuePath",n=>{if(!n)return[];const r=[];let i=[...n];for(;i.length>0;){const o=this.at(i);o&&r.unshift(this.getNodeValue(o)),i.pop()}return r}),V(this,"getDepth",n=>{const r=Bd(this.rootNode,{getChildren:this.getNodeChildren,predicate:i=>this.getNodeValue(i)===n});return(r==null?void 0:r.length)??0}),V(this,"isSameNode",(n,r)=>this.getNodeValue(n)===this.getNodeValue(r)),V(this,"isRootNode",n=>this.isSameNode(n,this.rootNode)),V(this,"contains",(n,r)=>!n||!r?!1:r.slice(0,n.length).every((i,o)=>n[o]===r[o])),V(this,"getNextNode",(n,r={})=>{let i=!1,o;return it(this.rootNode,{getChildren:this.getNodeChildren,onEnter:(s,a)=>{var c;if(this.isRootNode(s))return;const l=this.getNodeValue(s);if((c=r.skip)!=null&&c.call(r,{value:l,node:s,indexPath:a}))return l===n&&(i=!0),"skip";if(i&&!this.getNodeDisabled(s))return o=s,"stop";l===n&&(i=!0)}}),o}),V(this,"getPreviousNode",(n,r={})=>{let i,o=!1;return it(this.rootNode,{getChildren:this.getNodeChildren,onEnter:(s,a)=>{var c;if(this.isRootNode(s))return;const l=this.getNodeValue(s);if((c=r.skip)!=null&&c.call(r,{value:l,node:s,indexPath:a}))return"skip";if(l===n)return o=!0,"stop";this.getNodeDisabled(s)||(i=s)}}),o?i:void 0}),V(this,"getParentNodes",n=>{var o;const r=(o=this.resolveIndexPath(n))==null?void 0:o.slice();if(!r)return[];const i=[];for(;r.length>0;){r.pop();const s=this.at(r);s&&!this.isRootNode(s)&&i.unshift(s)}return i}),V(this,"getDescendantNodes",(n,r)=>{const i=this.resolveNode(n);if(!i)return[];const o=[];return it(i,{getChildren:this.getNodeChildren,onEnter:(s,a)=>{a.length!==0&&(!(r!=null&&r.withBranch)&&this.isBranchNode(s)||o.push(s))}}),o}),V(this,"getDescendantValues",(n,r)=>this.getDescendantNodes(n,r).map(o=>this.getNodeValue(o))),V(this,"getParentIndexPath",n=>n.slice(0,-1)),V(this,"getParentNode",n=>{const r=this.resolveIndexPath(n);return r?this.at(this.getParentIndexPath(r)):void 0}),V(this,"visit",n=>{const{skip:r,...i}=n;it(this.rootNode,{...i,getChildren:this.getNodeChildren,onEnter:(o,s)=>{var a;if(!this.isRootNode(o))return r!=null&&r({value:this.getNodeValue(o),node:o,indexPath:s})?"skip":(a=i.onEnter)==null?void 0:a.call(i,o,s)}})}),V(this,"getPreviousSibling",n=>{const r=this.getParentNode(n);if(!r)return;const i=this.getNodeChildren(r);let o=n[n.length-1];for(;--o>=0;){const s=i[o];if(!this.getNodeDisabled(s))return s}}),V(this,"getNextSibling",n=>{const r=this.getParentNode(n);if(!r)return;const i=this.getNodeChildren(r);let o=n[n.length-1];for(;++o{const r=this.getParentNode(n);return r?this.getNodeChildren(r):[]}),V(this,"getValues",(n=this.rootNode)=>DS(n,{getChildren:this.getNodeChildren,transform:i=>[this.getNodeValue(i)]}).slice(1)),V(this,"isValidDepth",(n,r)=>r==null?!0:typeof r=="function"?r(n.length):n.length===r),V(this,"isBranchNode",n=>this.getNodeChildren(n).length>0||this.getNodeChildrenCount(n)!=null),V(this,"getBranchValues",(n=this.rootNode,r={})=>{let i=[];return it(n,{getChildren:this.getNodeChildren,onEnter:(o,s)=>{var l;if(s.length===0)return;const a=this.getNodeValue(o);if((l=r.skip)!=null&&l.call(r,{value:a,node:o,indexPath:s}))return"skip";this.isBranchNode(o)&&this.isValidDepth(s,r.depth)&&i.push(this.getNodeValue(o))}}),i}),V(this,"flatten",(n=this.rootNode)=>MS(n,{getChildren:this.getNodeChildren})),V(this,"_create",(n,r)=>this.getNodeChildren(n).length>0||r.length>0?{...n,children:r}:{...n}),V(this,"_insert",(n,r,i)=>this.copy(HS(n,{at:r,nodes:i,getChildren:this.getNodeChildren,create:this._create}))),V(this,"copy",n=>new mb({...this.options,rootNode:n})),V(this,"_replace",(n,r,i)=>this.copy(US(n,{at:r,node:i,getChildren:this.getNodeChildren,create:this._create}))),V(this,"_move",(n,r,i)=>this.copy(qS(n,{indexPaths:r,to:i,getChildren:this.getNodeChildren,create:this._create}))),V(this,"_remove",(n,r)=>this.copy(GS(n,{indexPaths:r,getChildren:this.getNodeChildren,create:this._create}))),V(this,"replace",(n,r)=>this._replace(this.rootNode,n,r)),V(this,"remove",n=>this._remove(this.rootNode,n)),V(this,"insertBefore",(n,r)=>this.getParentNode(n)?this._insert(this.rootNode,n,r):void 0),V(this,"insertAfter",(n,r)=>{if(!this.getParentNode(n))return;const o=[...n.slice(0,-1),n[n.length-1]+1];return this._insert(this.rootNode,o,r)}),V(this,"move",(n,r)=>this._move(this.rootNode,n,r)),V(this,"filter",n=>{const r=zS(this.rootNode,{predicate:n,getChildren:this.getNodeChildren,create:this._create});return this.copy(r)}),V(this,"toJSON",()=>this.getValues(this.rootNode)),this.rootNode=t.rootNode}},Er={nodeToValue(e){return typeof e=="string"?e:Rn(e)&&en(e,"value")?e.value:""},nodeToString(e){return typeof e=="string"?e:Rn(e)&&en(e,"label")?e.label:Er.nodeToValue(e)},isNodeDisabled(e){return Rn(e)&&en(e,"disabled")?!!e.disabled:!1},nodeToChildren(e){return e.children},nodeToChildrenCount(e){if(Rn(e)&&en(e,"childrenCount"))return e.childrenCount}},kr=new WeakMap,Jo=new WeakMap,Zo={},Za=0,qd=e=>e&&(e.host||qd(e.parentNode)),KS=(e,t)=>t.map(n=>{if(e.contains(n))return n;const r=qd(n);return r&&e.contains(r)?r:(console.error("[zag-js > ariaHidden] target",n,"in not contained inside",e,". Doing nothing"),null)}).filter(n=>!!n),XS=new Set(["script","output","status","next-route-announcer"]),YS=e=>XS.has(e.localName)||e.role==="status"||e.hasAttribute("aria-live")?!0:e.matches("[data-live-announcer]"),QS=(e,t)=>{const{parentNode:n,markerName:r,controlAttribute:i}=t,o=KS(n,Array.isArray(e)?e:[e]);Zo[r]||(Zo[r]=new WeakMap);const s=Zo[r],a=[],l=new Set,c=new Set(o),u=h=>{!h||l.has(h)||(l.add(h),u(h.parentNode))};o.forEach(u);const d=h=>{!h||c.has(h)||Array.prototype.forEach.call(h.children,m=>{if(l.has(m))d(m);else try{if(YS(m))return;const g=m.getAttribute(i)==="true",p=(kr.get(m)||0)+1,b=(s.get(m)||0)+1;kr.set(m,p),s.set(m,b),a.push(m),p===1&&g&&Jo.set(m,!0),b===1&&m.setAttribute(r,""),g||m.setAttribute(i,"true")}catch(f){console.error("[zag-js > ariaHidden] cannot operate on ",m,f)}})};return d(n),l.clear(),Za++,()=>{a.forEach(h=>{const m=kr.get(h)-1,f=s.get(h)-1;kr.set(h,m),s.set(h,f),m||(Jo.has(h)||h.removeAttribute(i),Jo.delete(h)),f||h.removeAttribute(r)}),Za--,Za||(kr=new WeakMap,kr=new WeakMap,Jo=new WeakMap,Zo={})}},JS=e=>(Array.isArray(e)?e[0]:e).ownerDocument.body,ZS=(e,t=JS(e),n="data-aria-hidden")=>{if(t)return QS(e,{parentNode:t,markerName:n,controlAttribute:"aria-hidden"})},ew=e=>{const t=requestAnimationFrame(()=>e());return()=>cancelAnimationFrame(t)};function Kd(e,t={}){const{defer:n=!0}=t,r=n?ew:o=>o(),i=[];return i.push(r(()=>{const s=(typeof e=="function"?e():e).filter(Boolean);s.length!==0&&i.push(ZS(s))})),()=>{i.forEach(o=>o==null?void 0:o())}}var Xd=K("combobox").parts("root","clearTrigger","content","control","input","item","itemGroup","itemGroupLabel","itemIndicator","itemText","label","list","positioner","trigger");Xd.build();var Yd=e=>new Xo(e);Yd.empty=()=>new Xo({items:[]});var tw=e=>{var t;return((t=e.ids)==null?void 0:t.control)??`combobox:${e.id}:control`},nw=e=>{var t;return((t=e.ids)==null?void 0:t.input)??`combobox:${e.id}:input`},rw=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`combobox:${e.id}:content`},iw=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`combobox:${e.id}:popper`},ow=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`combobox:${e.id}:toggle-btn`},sw=e=>{var t;return((t=e.ids)==null?void 0:t.clearTrigger)??`combobox:${e.id}:clear-btn`},ln=e=>e.getById(rw(e)),Or=e=>e.getById(nw(e)),Qd=e=>e.getById(iw(e)),Jd=e=>e.getById(tw(e)),xi=e=>e.getById(ow(e)),Zd=e=>e.getById(sw(e)),Ci=(e,t)=>{if(t==null)return null;const n=`[role=option][data-value="${CSS.escape(t)}"]`;return vx(ln(e),n)},eh=e=>{const t=Or(e);e.isActiveElement(t)||t==null||t.focus({preventScroll:!0})},aw=e=>{const t=xi(e);e.isActiveElement(t)||t==null||t.focus({preventScroll:!0})},{guards:lw,createMachine:cw,choose:uw}=Au(),{and:Pe,not:ot}=lw;cw({props({props:e}){return{loopFocus:!0,openOnClick:!1,defaultValue:[],closeOnSelect:!e.multiple,allowCustomValue:!1,alwaysSubmitOnEnter:!1,inputBehavior:"none",selectionBehavior:e.multiple?"clear":"replace",openOnKeyPress:!0,openOnChange:!0,composite:!0,navigate({node:t}){Ou(t)},collection:Yd.empty(),...e,positioning:{placement:"bottom",sameWidth:!0,...e.positioning},translations:{triggerLabel:"Toggle suggestions",clearTriggerLabel:"Clear value",...e.translations}}},initialState({prop:e}){return e("open")||e("defaultOpen")?"suggesting":"idle"},context({prop:e,bindable:t,getContext:n,getEvent:r}){return{currentPlacement:t(()=>({defaultValue:void 0})),value:t(()=>({defaultValue:e("defaultValue"),value:e("value"),isEqual:pt,hash(i){return i.join(",")},onChange(i){var c;const o=n(),s=o.get("selectedItems"),a=e("collection"),l=i.map(u=>s.find(h=>a.getItemValue(h)===u)||a.find(u));o.set("selectedItems",l),(c=e("onValueChange"))==null||c({value:i,items:l})}})),highlightedValue:t(()=>({defaultValue:e("defaultHighlightedValue")||null,value:e("highlightedValue"),onChange(i){var s;const o=e("collection").find(i);(s=e("onHighlightChange"))==null||s({highlightedValue:i,highlightedItem:o})}})),inputValue:t(()=>{let i=e("inputValue")||e("defaultInputValue")||"";const o=e("defaultValue")||e("value")||[];if(!i.trim()&&!e("multiple")){const s=e("collection").stringifyMany(o);i=Bt(e("selectionBehavior"),{preserve:i||s,replace:s,clear:""})}return{defaultValue:i,value:e("inputValue"),onChange(s){var c;const a=r(),l=(a.previousEvent||a).src;(c=e("onInputValueChange"))==null||c({inputValue:s,reason:l})}}}),highlightedItem:t(()=>{const i=e("highlightedValue");return{defaultValue:e("collection").find(i)}}),selectedItems:t(()=>{const i=e("value")||e("defaultValue")||[];return{defaultValue:e("collection").findMany(i)}})}},computed:{isInputValueEmpty:({context:e})=>e.get("inputValue").length===0,isInteractive:({prop:e})=>!(e("readOnly")||e("disabled")),autoComplete:({prop:e})=>e("inputBehavior")==="autocomplete",autoHighlight:({prop:e})=>e("inputBehavior")==="autohighlight",hasSelectedItems:({context:e})=>e.get("value").length>0,valueAsString:({context:e,prop:t})=>t("collection").stringifyItems(e.get("selectedItems")),isCustomValue:({context:e,computed:t})=>e.get("inputValue")!==t("valueAsString")},watch({context:e,prop:t,track:n,action:r,send:i}){n([()=>e.hash("value")],()=>{r(["syncSelectedItems"])}),n([()=>e.get("inputValue")],()=>{r(["syncInputValue"])}),n([()=>e.get("highlightedValue")],()=>{r(["syncHighlightedItem","autofillInputValue"])}),n([()=>t("open")],()=>{r(["toggleVisibility"])}),n([()=>t("collection").toString()],()=>{i({type:"CHILDREN_CHANGE"})})},on:{"SELECTED_ITEMS.SYNC":{actions:["syncSelectedItems"]},"HIGHLIGHTED_VALUE.SET":{actions:["setHighlightedValue"]},"HIGHLIGHTED_VALUE.CLEAR":{actions:["clearHighlightedValue"]},"ITEM.SELECT":{actions:["selectItem"]},"ITEM.CLEAR":{actions:["clearItem"]},"VALUE.SET":{actions:["setValue"]},"INPUT_VALUE.SET":{actions:["setInputValue"]},"POSITIONING.SET":{actions:["reposition"]}},entry:uw([{guard:"autoFocus",actions:["setInitialFocus"]}]),states:{idle:{tags:["idle","closed"],entry:["scrollContentToTop","clearHighlightedValue"],on:{"CONTROLLED.OPEN":{target:"interacting"},"TRIGGER.CLICK":[{guard:"isOpenControlled",actions:["setInitialFocus","highlightFirstSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["setInitialFocus","highlightFirstSelectedItem","invokeOnOpen"]}],"INPUT.CLICK":[{guard:"isOpenControlled",actions:["highlightFirstSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["highlightFirstSelectedItem","invokeOnOpen"]}],"INPUT.FOCUS":{target:"focused"},OPEN:[{guard:"isOpenControlled",actions:["invokeOnOpen"]},{target:"interacting",actions:["invokeOnOpen"]}],"VALUE.CLEAR":{target:"focused",actions:["clearInputValue","clearSelectedItems","setInitialFocus"]}}},focused:{tags:["focused","closed"],entry:["scrollContentToTop","clearHighlightedValue"],on:{"CONTROLLED.OPEN":[{guard:"isChangeEvent",target:"suggesting"},{target:"interacting"}],"INPUT.CHANGE":[{guard:Pe("isOpenControlled","openOnChange"),actions:["setInputValue","invokeOnOpen","highlightFirstItemIfNeeded"]},{guard:"openOnChange",target:"suggesting",actions:["setInputValue","invokeOnOpen","highlightFirstItemIfNeeded"]},{actions:["setInputValue"]}],"LAYER.INTERACT_OUTSIDE":{target:"idle"},"INPUT.ESCAPE":{guard:Pe("isCustomValue",ot("allowCustomValue")),actions:["revertInputValue"]},"INPUT.BLUR":{target:"idle"},"INPUT.CLICK":[{guard:"isOpenControlled",actions:["highlightFirstSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["highlightFirstSelectedItem","invokeOnOpen"]}],"TRIGGER.CLICK":[{guard:"isOpenControlled",actions:["setInitialFocus","highlightFirstSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["setInitialFocus","highlightFirstSelectedItem","invokeOnOpen"]}],"INPUT.ARROW_DOWN":[{guard:Pe("isOpenControlled","autoComplete"),actions:["invokeOnOpen"]},{guard:"autoComplete",target:"interacting",actions:["invokeOnOpen"]},{guard:"isOpenControlled",actions:["highlightFirstOrSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["highlightFirstOrSelectedItem","invokeOnOpen"]}],"INPUT.ARROW_UP":[{guard:"autoComplete",target:"interacting",actions:["invokeOnOpen"]},{guard:"autoComplete",target:"interacting",actions:["invokeOnOpen"]},{target:"interacting",actions:["highlightLastOrSelectedItem","invokeOnOpen"]},{target:"interacting",actions:["highlightLastOrSelectedItem","invokeOnOpen"]}],OPEN:[{guard:"isOpenControlled",actions:["invokeOnOpen"]},{target:"interacting",actions:["invokeOnOpen"]}],"VALUE.CLEAR":{actions:["clearInputValue","clearSelectedItems"]}}},interacting:{tags:["open","focused"],entry:["setInitialFocus"],effects:["scrollToHighlightedItem","trackDismissableLayer","trackPlacement","hideOtherElements"],on:{"CONTROLLED.CLOSE":[{guard:"restoreFocus",target:"focused",actions:["setFinalFocus"]},{target:"idle"}],CHILDREN_CHANGE:[{guard:"isHighlightedItemRemoved",actions:["clearHighlightedValue"]},{actions:["scrollToHighlightedItem"]}],"INPUT.HOME":{actions:["highlightFirstItem"]},"INPUT.END":{actions:["highlightLastItem"]},"INPUT.ARROW_DOWN":[{guard:Pe("autoComplete","isLastItemHighlighted"),actions:["clearHighlightedValue","scrollContentToTop"]},{actions:["highlightNextItem"]}],"INPUT.ARROW_UP":[{guard:Pe("autoComplete","isFirstItemHighlighted"),actions:["clearHighlightedValue"]},{actions:["highlightPrevItem"]}],"INPUT.ENTER":[{guard:Pe("isOpenControlled","isCustomValue",ot("hasHighlightedItem"),ot("allowCustomValue")),actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isCustomValue",ot("hasHighlightedItem"),ot("allowCustomValue")),target:"focused",actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isOpenControlled","closeOnSelect"),actions:["selectHighlightedItem","invokeOnClose"]},{guard:"closeOnSelect",target:"focused",actions:["selectHighlightedItem","invokeOnClose","setFinalFocus"]},{actions:["selectHighlightedItem"]}],"INPUT.CHANGE":[{guard:"autoComplete",target:"suggesting",actions:["setInputValue"]},{target:"suggesting",actions:["clearHighlightedValue","setInputValue"]}],"ITEM.POINTER_MOVE":{actions:["setHighlightedValue"]},"ITEM.POINTER_LEAVE":{actions:["clearHighlightedValue"]},"ITEM.CLICK":[{guard:Pe("isOpenControlled","closeOnSelect"),actions:["selectItem","invokeOnClose"]},{guard:"closeOnSelect",target:"focused",actions:["selectItem","invokeOnClose","setFinalFocus"]},{actions:["selectItem"]}],"LAYER.ESCAPE":[{guard:Pe("isOpenControlled","autoComplete"),actions:["syncInputValue","invokeOnClose"]},{guard:"autoComplete",target:"focused",actions:["syncInputValue","invokeOnClose"]},{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose","setFinalFocus"]}],"TRIGGER.CLICK":[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose"]}],"LAYER.INTERACT_OUTSIDE":[{guard:Pe("isOpenControlled","isCustomValue",ot("allowCustomValue")),actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isCustomValue",ot("allowCustomValue")),target:"idle",actions:["revertInputValue","invokeOnClose"]},{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"idle",actions:["invokeOnClose"]}],CLOSE:[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose","setFinalFocus"]}],"VALUE.CLEAR":[{guard:"isOpenControlled",actions:["clearInputValue","clearSelectedItems","invokeOnClose"]},{target:"focused",actions:["clearInputValue","clearSelectedItems","invokeOnClose","setFinalFocus"]}]}},suggesting:{tags:["open","focused"],effects:["trackDismissableLayer","scrollToHighlightedItem","trackPlacement","hideOtherElements"],entry:["setInitialFocus"],on:{"CONTROLLED.CLOSE":[{guard:"restoreFocus",target:"focused",actions:["setFinalFocus"]},{target:"idle"}],CHILDREN_CHANGE:[{guard:"autoHighlight",actions:["highlightFirstItem"]},{guard:"isHighlightedItemRemoved",actions:["clearHighlightedValue"]}],"INPUT.ARROW_DOWN":{target:"interacting",actions:["highlightNextItem"]},"INPUT.ARROW_UP":{target:"interacting",actions:["highlightPrevItem"]},"INPUT.HOME":{target:"interacting",actions:["highlightFirstItem"]},"INPUT.END":{target:"interacting",actions:["highlightLastItem"]},"INPUT.ENTER":[{guard:Pe("isOpenControlled","isCustomValue",ot("hasHighlightedItem"),ot("allowCustomValue")),actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isCustomValue",ot("hasHighlightedItem"),ot("allowCustomValue")),target:"focused",actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isOpenControlled","closeOnSelect"),actions:["selectHighlightedItem","invokeOnClose"]},{guard:"closeOnSelect",target:"focused",actions:["selectHighlightedItem","invokeOnClose","setFinalFocus"]},{actions:["selectHighlightedItem"]}],"INPUT.CHANGE":{actions:["setInputValue"]},"LAYER.ESCAPE":[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose"]}],"ITEM.POINTER_MOVE":{target:"interacting",actions:["setHighlightedValue"]},"ITEM.POINTER_LEAVE":{actions:["clearHighlightedValue"]},"LAYER.INTERACT_OUTSIDE":[{guard:Pe("isOpenControlled","isCustomValue",ot("allowCustomValue")),actions:["revertInputValue","invokeOnClose"]},{guard:Pe("isCustomValue",ot("allowCustomValue")),target:"idle",actions:["revertInputValue","invokeOnClose"]},{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"idle",actions:["invokeOnClose"]}],"TRIGGER.CLICK":[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose"]}],"ITEM.CLICK":[{guard:Pe("isOpenControlled","closeOnSelect"),actions:["selectItem","invokeOnClose"]},{guard:"closeOnSelect",target:"focused",actions:["selectItem","invokeOnClose","setFinalFocus"]},{actions:["selectItem"]}],CLOSE:[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"focused",actions:["invokeOnClose","setFinalFocus"]}],"VALUE.CLEAR":[{guard:"isOpenControlled",actions:["clearInputValue","clearSelectedItems","invokeOnClose"]},{target:"focused",actions:["clearInputValue","clearSelectedItems","invokeOnClose","setFinalFocus"]}]}}},implementations:{guards:{isInputValueEmpty:({computed:e})=>e("isInputValueEmpty"),autoComplete:({computed:e,prop:t})=>e("autoComplete")&&!t("multiple"),autoHighlight:({computed:e})=>e("autoHighlight"),isFirstItemHighlighted:({prop:e,context:t})=>e("collection").firstValue===t.get("highlightedValue"),isLastItemHighlighted:({prop:e,context:t})=>e("collection").lastValue===t.get("highlightedValue"),isCustomValue:({computed:e})=>e("isCustomValue"),allowCustomValue:({prop:e})=>!!e("allowCustomValue"),hasHighlightedItem:({context:e})=>e.get("highlightedValue")!=null,closeOnSelect:({prop:e})=>!!e("closeOnSelect"),isOpenControlled:({prop:e})=>e("open")!=null,openOnChange:({prop:e,context:t})=>{const n=e("openOnChange");return Qy(n)?n:!!(n!=null&&n({inputValue:t.get("inputValue")}))},restoreFocus:({event:e})=>e.restoreFocus==null?!0:!!e.restoreFocus,isChangeEvent:({event:e})=>{var t;return((t=e.previousEvent)==null?void 0:t.type)==="INPUT.CHANGE"},autoFocus:({prop:e})=>!!e("autoFocus"),isHighlightedItemRemoved:({prop:e,context:t})=>!e("collection").has(t.get("highlightedValue"))},effects:{trackDismissableLayer({send:e,prop:t,scope:n}){return t("disableLayer")?void 0:wr(()=>ln(n),{type:"listbox",defer:!0,exclude:()=>[Or(n),xi(n),Zd(n)],onFocusOutside:t("onFocusOutside"),onPointerDownOutside:t("onPointerDownOutside"),onInteractOutside:t("onInteractOutside"),onEscapeKeyDown(i){i.preventDefault(),i.stopPropagation(),e({type:"LAYER.ESCAPE",src:"escape-key"})},onDismiss(){e({type:"LAYER.INTERACT_OUTSIDE",src:"interact-outside",restoreFocus:!1})}})},hideOtherElements({scope:e}){return Kd([Or(e),ln(e),xi(e),Zd(e)])},trackPlacement({context:e,prop:t,scope:n}){const r=()=>Jd(n)||xi(n),i=()=>Qd(n);return e.set("currentPlacement",t("positioning").placement),yt(r,i,{...t("positioning"),defer:!0,onComplete(o){e.set("currentPlacement",o.placement)}})},scrollToHighlightedItem({context:e,prop:t,scope:n,event:r}){const i=Or(n);let o=[];const s=c=>{const u=r.current().type.includes("POINTER"),d=e.get("highlightedValue");if(u||!d)return;const h=ln(n),m=t("scrollToIndexFn");if(m){const p=t("collection").indexOf(d);m({index:p,immediate:c,getElement:()=>Ci(n,d)});return}const f=Ci(n,d),g=Z(()=>{Io(f,{rootEl:h,block:"nearest"})});o.push(g)},a=Z(()=>s(!0));o.push(a);const l=ko(i,{attributes:["aria-activedescendant"],callback:()=>s(!1)});return o.push(l),()=>{o.forEach(c=>c())}}},actions:{reposition({context:e,prop:t,scope:n,event:r}){yt(()=>Jd(n),()=>Qd(n),{...t("positioning"),...r.options,defer:!0,listeners:!1,onComplete(s){e.set("currentPlacement",s.placement)}})},setHighlightedValue({context:e,event:t}){t.value!=null&&e.set("highlightedValue",t.value)},clearHighlightedValue({context:e}){e.set("highlightedValue",null)},selectHighlightedItem(e){var a;const{context:t,prop:n}=e,r=n("collection"),i=t.get("highlightedValue");if(!i||!r.has(i))return;const o=n("multiple")?fr(t.get("value"),i):[i];(a=n("onSelect"))==null||a({value:o,itemValue:i}),t.set("value",o);const s=Bt(n("selectionBehavior"),{preserve:t.get("inputValue"),replace:r.stringifyMany(o),clear:""});t.set("inputValue",s)},scrollToHighlightedItem({context:e,prop:t,scope:n}){Ea(()=>{const r=e.get("highlightedValue");if(r==null)return;const i=Ci(n,r),o=ln(n),s=t("scrollToIndexFn");if(s){const a=t("collection").indexOf(r);s({index:a,immediate:!0,getElement:()=>Ci(n,r)});return}Io(i,{rootEl:o,block:"nearest"})})},selectItem(e){const{context:t,event:n,flush:r,prop:i}=e;n.value!=null&&r(()=>{var a;const o=i("multiple")?fr(t.get("value"),n.value):[n.value];(a=i("onSelect"))==null||a({value:o,itemValue:n.value}),t.set("value",o);const s=Bt(i("selectionBehavior"),{preserve:t.get("inputValue"),replace:i("collection").stringifyMany(o),clear:""});t.set("inputValue",s)})},clearItem(e){const{context:t,event:n,flush:r,prop:i}=e;n.value!=null&&r(()=>{const o=Pn(t.get("value"),n.value);t.set("value",o);const s=Bt(i("selectionBehavior"),{preserve:t.get("inputValue"),replace:i("collection").stringifyMany(o),clear:""});t.set("inputValue",s)})},setInitialFocus({scope:e}){Z(()=>{eh(e)})},setFinalFocus({scope:e}){Z(()=>{const t=xi(e);(t==null?void 0:t.dataset.focusable)==null?eh(e):aw(e)})},syncInputValue({context:e,scope:t,event:n}){const r=Or(t);r&&(r.value=e.get("inputValue"),queueMicrotask(()=>{n.current().type!=="INPUT.CHANGE"&&w0(r)}))},setInputValue({context:e,event:t}){e.set("inputValue",t.value)},clearInputValue({context:e}){e.set("inputValue","")},revertInputValue({context:e,prop:t,computed:n}){const r=t("selectionBehavior"),i=Bt(r,{replace:n("hasSelectedItems")?n("valueAsString"):"",preserve:e.get("inputValue"),clear:""});e.set("inputValue",i)},setValue(e){const{context:t,flush:n,event:r,prop:i}=e;n(()=>{t.set("value",r.value);const o=Bt(i("selectionBehavior"),{preserve:t.get("inputValue"),replace:i("collection").stringifyMany(r.value),clear:""});t.set("inputValue",o)})},clearSelectedItems(e){const{context:t,flush:n,prop:r}=e;n(()=>{t.set("value",[]);const i=Bt(r("selectionBehavior"),{preserve:t.get("inputValue"),replace:r("collection").stringifyMany([]),clear:""});t.set("inputValue",i)})},scrollContentToTop({prop:e,scope:t}){const n=e("scrollToIndexFn");if(n){const r=e("collection").firstValue;n({index:0,immediate:!0,getElement:()=>Ci(t,r)})}else{const r=ln(t);if(!r)return;r.scrollTop=0}},invokeOnOpen({prop:e,event:t}){var r;const n=th(t);(r=e("onOpenChange"))==null||r({open:!0,reason:n})},invokeOnClose({prop:e,event:t}){var r;const n=th(t);(r=e("onOpenChange"))==null||r({open:!1,reason:n})},highlightFirstItem({context:e,prop:t,scope:n}){(ln(n)?queueMicrotask:Z)(()=>{const i=t("collection").firstValue;i&&e.set("highlightedValue",i)})},highlightFirstItemIfNeeded({computed:e,action:t}){e("autoHighlight")&&t(["highlightFirstItem"])},highlightLastItem({context:e,prop:t,scope:n}){(ln(n)?queueMicrotask:Z)(()=>{const i=t("collection").lastValue;i&&e.set("highlightedValue",i)})},highlightNextItem({context:e,prop:t}){let n=null;const r=e.get("highlightedValue"),i=t("collection");r?(n=i.getNextValue(r),!n&&t("loopFocus")&&(n=i.firstValue)):n=i.firstValue,n&&e.set("highlightedValue",n)},highlightPrevItem({context:e,prop:t}){let n=null;const r=e.get("highlightedValue"),i=t("collection");r?(n=i.getPreviousValue(r),!n&&t("loopFocus")&&(n=i.lastValue)):n=i.lastValue,n&&e.set("highlightedValue",n)},highlightFirstSelectedItem({context:e,prop:t}){Z(()=>{const[n]=t("collection").sort(e.get("value"));n&&e.set("highlightedValue",n)})},highlightFirstOrSelectedItem({context:e,prop:t,computed:n}){Z(()=>{let r=null;n("hasSelectedItems")?r=t("collection").sort(e.get("value"))[0]:r=t("collection").firstValue,r&&e.set("highlightedValue",r)})},highlightLastOrSelectedItem({context:e,prop:t,computed:n}){Z(()=>{const r=t("collection");let i=null;n("hasSelectedItems")?i=r.sort(e.get("value"))[0]:i=r.lastValue,i&&e.set("highlightedValue",i)})},autofillInputValue({context:e,computed:t,prop:n,event:r,scope:i}){const o=Or(i),s=n("collection");if(!t("autoComplete")||!o||!r.keypress)return;const a=s.stringify(e.get("highlightedValue"));Z(()=>{o.value=a||e.get("inputValue")})},syncSelectedItems(e){queueMicrotask(()=>{const{context:t,prop:n}=e,r=n("collection"),i=t.get("value"),o=i.map(a=>t.get("selectedItems").find(c=>r.getItemValue(c)===a)||r.find(a));t.set("selectedItems",o);const s=Bt(n("selectionBehavior"),{preserve:t.get("inputValue"),replace:r.stringifyMany(i),clear:""});t.set("inputValue",s)})},syncHighlightedItem({context:e,prop:t}){const n=t("collection").find(e.get("highlightedValue"));e.set("highlightedItem",n)},toggleVisibility({event:e,send:t,prop:n}){t({type:n("open")?"CONTROLLED.OPEN":"CONTROLLED.CLOSE",previousEvent:e})}}}});function th(e){return(e.previousEvent||e).src}q()(["allowCustomValue","autoFocus","closeOnSelect","collection","composite","defaultHighlightedValue","defaultInputValue","defaultOpen","defaultValue","dir","disabled","disableLayer","form","getRootNode","highlightedValue","id","ids","inputBehavior","inputValue","invalid","loopFocus","multiple","name","navigate","onFocusOutside","onHighlightChange","onInputValueChange","onInteractOutside","onOpenChange","onOpenChange","onPointerDownOutside","onSelect","onValueChange","open","openOnChange","openOnClick","openOnKeyPress","placeholder","positioning","readOnly","required","scrollToIndexFn","selectionBehavior","translations","value","alwaysSubmitOnEnter"]),q()(["htmlFor"]),q()(["id"]),q()(["item","persistFocus"]);const dw=Xd.extendWith("empty"),[nh,cn]=gr({name:"DialogContext",hookName:"useDialogContext",providerName:""}),rh=E.forwardRef((e,t)=>{const n=cn(),r=aS(),i=Na({...r,present:n.open}),o=mt(n.getBackdropProps(),i.getPresenceProps(),e);return i.unmounted?null:x.jsx(on.div,{...o,ref:No(i.ref,t)})});rh.displayName="DialogBackdrop";const ih=E.forwardRef((e,t)=>{const n=cn(),r=mt(n.getCloseTriggerProps(),e);return x.jsx(on.button,{...r,ref:t})});ih.displayName="DialogCloseTrigger";const oh=E.forwardRef((e,t)=>{const n=cn(),r=Aa(),i=mt(n.getContentProps(),r.getPresenceProps(),e);return r.unmounted?null:x.jsx(on.div,{...i,ref:No(r.ref,t)})});oh.displayName="DialogContent";const sh=E.forwardRef((e,t)=>{const n=cn(),r=mt(n.getDescriptionProps(),e);return x.jsx(on.div,{...r,ref:t})});sh.displayName="DialogDescription";const ah=E.forwardRef((e,t)=>{const n=cn(),r=mt(n.getPositionerProps(),e);return Aa().unmounted?null:x.jsx(on.div,{...r,ref:t})});ah.displayName="DialogPositioner";var hw=Object.defineProperty,fw=(e,t,n)=>t in e?hw(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,fe=(e,t,n)=>fw(e,typeof t!="symbol"?t+"":t,n),lh={activateTrap(e,t){if(e.length>0){const r=e[e.length-1];r!==t&&r.pause()}const n=e.indexOf(t);n===-1||e.splice(n,1),e.push(t)},deactivateTrap(e,t){const n=e.indexOf(t);n!==-1&&e.splice(n,1),e.length>0&&e[e.length-1].unpause()}},gw=[],pw=class{constructor(e,t){fe(this,"trapStack"),fe(this,"config"),fe(this,"doc"),fe(this,"state",{containers:[],containerGroups:[],tabbableGroups:[],nodeFocusedBeforeActivation:null,mostRecentlyFocusedNode:null,active:!1,paused:!1,delayInitialFocusTimer:void 0,recentNavEvent:void 0}),fe(this,"listenerCleanups",[]),fe(this,"handleFocus",r=>{const i=tt(r),o=this.findContainerIndex(i,r)>=0;if(o||va(i))o&&(this.state.mostRecentlyFocusedNode=i);else{r.stopImmediatePropagation();let s,a=!0;if(this.state.mostRecentlyFocusedNode)if(hi(this.state.mostRecentlyFocusedNode)>0){const l=this.findContainerIndex(this.state.mostRecentlyFocusedNode),{tabbableNodes:c}=this.state.containerGroups[l];if(c.length>0){const u=c.findIndex(d=>d===this.state.mostRecentlyFocusedNode);u>=0&&(this.config.isKeyForward(this.state.recentNavEvent)?u+1=0&&(s=c[u-1],a=!1))}}else this.state.containerGroups.some(l=>l.tabbableNodes.some(c=>hi(c)>0))||(a=!1);else a=!1;a&&(s=this.findNextNavNode({target:this.state.mostRecentlyFocusedNode,isBackward:this.config.isKeyBackward(this.state.recentNavEvent)})),s?this.tryFocus(s):this.tryFocus(this.state.mostRecentlyFocusedNode||this.getInitialFocusNode())}this.state.recentNavEvent=void 0}),fe(this,"handlePointerDown",r=>{const i=tt(r);if(!(this.findContainerIndex(i,r)>=0)){if(wi(this.config.clickOutsideDeactivates,r)){this.deactivate({returnFocus:this.config.returnFocusOnDeactivate});return}wi(this.config.allowOutsideClick,r)||r.preventDefault()}}),fe(this,"handleClick",r=>{const i=tt(r);this.findContainerIndex(i,r)>=0||wi(this.config.clickOutsideDeactivates,r)||wi(this.config.allowOutsideClick,r)||(r.preventDefault(),r.stopImmediatePropagation())}),fe(this,"handleTabKey",r=>{if(this.config.isKeyForward(r)||this.config.isKeyBackward(r)){this.state.recentNavEvent=r;const i=this.config.isKeyBackward(r),o=this.findNextNavNode({event:r,isBackward:i});if(!o)return;Si(r)&&r.preventDefault(),this.tryFocus(o)}}),fe(this,"handleEscapeKey",r=>{mw(r)&&wi(this.config.escapeDeactivates,r)!==!1&&(r.preventDefault(),this.deactivate())}),fe(this,"_mutationObserver"),fe(this,"setupMutationObserver",()=>{const r=this.doc.defaultView||window;this._mutationObserver=new r.MutationObserver(i=>{i.some(s=>Array.from(s.removedNodes).some(l=>l===this.state.mostRecentlyFocusedNode))&&this.tryFocus(this.getInitialFocusNode())})}),fe(this,"updateObservedNodes",()=>{var r;(r=this._mutationObserver)==null||r.disconnect(),this.state.active&&!this.state.paused&&this.state.containers.map(i=>{var o;(o=this._mutationObserver)==null||o.observe(i,{subtree:!0,childList:!0})})}),fe(this,"getInitialFocusNode",()=>{let r=this.getNodeForOption("initialFocus",{hasFallback:!0});if(r===!1)return!1;if(r===void 0||r&&!nn(r)){const i=di(this.doc);if(i&&this.findContainerIndex(i)>=0)r=i;else{const o=this.state.tabbableGroups[0];r=o&&o.firstTabbableNode||this.getNodeForOption("fallbackFocus")}}else r===null&&(r=this.getNodeForOption("fallbackFocus"));if(!r)throw new Error("Your focus-trap needs to have at least one focusable element");return r.isConnected||(r=this.getNodeForOption("fallbackFocus")),r}),fe(this,"tryFocus",r=>{if(r!==!1&&r!==di(this.doc)){if(!r||!r.focus){this.tryFocus(this.getInitialFocusNode());return}r.focus({preventScroll:!!this.config.preventScroll}),this.state.mostRecentlyFocusedNode=r,vw(r)&&r.select()}}),fe(this,"deactivate",r=>{if(!this.state.active)return this;const i={onDeactivate:this.config.onDeactivate,onPostDeactivate:this.config.onPostDeactivate,checkCanReturnFocus:this.config.checkCanReturnFocus,...r};clearTimeout(this.state.delayInitialFocusTimer),this.state.delayInitialFocusTimer=void 0,this.removeListeners(),this.state.active=!1,this.state.paused=!1,this.updateObservedNodes(),lh.deactivateTrap(this.trapStack,this);const o=this.getOption(i,"onDeactivate"),s=this.getOption(i,"onPostDeactivate"),a=this.getOption(i,"checkCanReturnFocus"),l=this.getOption(i,"returnFocus","returnFocusOnDeactivate");o==null||o();const c=()=>{ch(()=>{if(l){const u=this.getReturnFocusNode(this.state.nodeFocusedBeforeActivation);this.tryFocus(u)}s==null||s()})};if(l&&a){const u=this.getReturnFocusNode(this.state.nodeFocusedBeforeActivation);return a(u).then(c,c),this}return c(),this}),fe(this,"pause",r=>{if(this.state.paused||!this.state.active)return this;const i=this.getOption(r,"onPause"),o=this.getOption(r,"onPostPause");return this.state.paused=!0,i==null||i(),this.removeListeners(),this.updateObservedNodes(),o==null||o(),this}),fe(this,"unpause",r=>{if(!this.state.paused||!this.state.active)return this;const i=this.getOption(r,"onUnpause"),o=this.getOption(r,"onPostUnpause");return this.state.paused=!1,i==null||i(),this.updateTabbableNodes(),this.addListeners(),this.updateObservedNodes(),o==null||o(),this}),fe(this,"updateContainerElements",r=>(this.state.containers=Array.isArray(r)?r.filter(Boolean):[r].filter(Boolean),this.state.active&&this.updateTabbableNodes(),this.updateObservedNodes(),this)),fe(this,"getReturnFocusNode",r=>{const i=this.getNodeForOption("setReturnFocus",{params:[r]});return i||(i===!1?!1:r)}),fe(this,"getOption",(r,i,o)=>r&&r[i]!==void 0?r[i]:this.config[o||i]),fe(this,"getNodeForOption",(r,{hasFallback:i=!1,params:o=[]}={})=>{let s=this.config[r];if(typeof s=="function"&&(s=s(...o)),s===!0&&(s=void 0),!s){if(s===void 0||s===!1)return s;throw new Error(`\`${r}\` was specified but was not a node, or did not return a node`)}let a=s;if(typeof s=="string"){try{a=this.doc.querySelector(s)}catch(l){throw new Error(`\`${r}\` appears to be an invalid selector; error="${l.message}"`)}if(!a&&!i)throw new Error(`\`${r}\` as selector refers to no known node`)}return a}),fe(this,"findNextNavNode",r=>{const{event:i,isBackward:o=!1}=r,s=r.target||tt(i);this.updateTabbableNodes();let a=null;if(this.state.tabbableGroups.length>0){const l=this.findContainerIndex(s,i),c=l>=0?this.state.containerGroups[l]:void 0;if(l<0)o?a=this.state.tabbableGroups[this.state.tabbableGroups.length-1].lastTabbableNode:a=this.state.tabbableGroups[0].firstTabbableNode;else if(o){let u=this.state.tabbableGroups.findIndex(({firstTabbableNode:d})=>s===d);if(u<0&&((c==null?void 0:c.container)===s||nn(s)&&!An(s)&&!(c!=null&&c.nextTabbableNode(s,!1)))&&(u=l),u>=0){const d=u===0?this.state.tabbableGroups.length-1:u-1,h=this.state.tabbableGroups[d];a=hi(s)>=0?h.lastTabbableNode:h.lastDomTabbableNode}else Si(i)||(a=c==null?void 0:c.nextTabbableNode(s,!1))}else{let u=this.state.tabbableGroups.findIndex(({lastTabbableNode:d})=>s===d);if(u<0&&((c==null?void 0:c.container)===s||nn(s)&&!An(s)&&!(c!=null&&c.nextTabbableNode(s)))&&(u=l),u>=0){const d=u===this.state.tabbableGroups.length-1?0:u+1,h=this.state.tabbableGroups[d];a=hi(s)>=0?h.firstTabbableNode:h.firstDomTabbableNode}else Si(i)||(a=c==null?void 0:c.nextTabbableNode(s))}}else a=this.getNodeForOption("fallbackFocus");return a}),this.trapStack=t.trapStack||gw;const n={returnFocusOnDeactivate:!0,escapeDeactivates:!0,delayInitialFocus:!0,isKeyForward(r){return Si(r)&&!r.shiftKey},isKeyBackward(r){return Si(r)&&r.shiftKey},...t};this.doc=n.document||Ge(Array.isArray(e)?e[0]:e),this.config=n,this.updateContainerElements(e),this.setupMutationObserver()}get active(){return this.state.active}get paused(){return this.state.paused}findContainerIndex(e,t){const n=typeof(t==null?void 0:t.composedPath)=="function"?t.composedPath():void 0;return this.state.containerGroups.findIndex(({container:r,tabbableNodes:i})=>r.contains(e)||(n==null?void 0:n.includes(r))||i.find(o=>o===e))}updateTabbableNodes(){if(this.state.containerGroups=this.state.containers.map(e=>{const t=Sa(e),n=ku(e),r=t.length>0?t[0]:void 0,i=t.length>0?t[t.length-1]:void 0,o=n.find(c=>An(c)),s=n.slice().reverse().find(c=>An(c)),a=!!t.find(c=>hi(c)>0);function l(c,u=!0){const d=t.indexOf(c);return d<0?u?n.slice(n.indexOf(c)+1).find(h=>An(h)):n.slice(0,n.indexOf(c)).reverse().find(h=>An(h)):t[d+(u?1:-1)]}return{container:e,tabbableNodes:t,focusableNodes:n,posTabIndexesFound:a,firstTabbableNode:r,lastTabbableNode:i,firstDomTabbableNode:o,lastDomTabbableNode:s,nextTabbableNode:l}}),this.state.tabbableGroups=this.state.containerGroups.filter(e=>e.tabbableNodes.length>0),this.state.tabbableGroups.length<=0&&!this.getNodeForOption("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(this.state.containerGroups.find(e=>e.posTabIndexesFound)&&this.state.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")}addListeners(){if(this.state.active)return lh.activateTrap(this.trapStack,this),this.state.delayInitialFocusTimer=this.config.delayInitialFocus?ch(()=>{this.tryFocus(this.getInitialFocusNode())}):this.tryFocus(this.getInitialFocusNode()),this.listenerCleanups.push(he(this.doc,"focusin",this.handleFocus,!0),he(this.doc,"mousedown",this.handlePointerDown,{capture:!0,passive:!1}),he(this.doc,"touchstart",this.handlePointerDown,{capture:!0,passive:!1}),he(this.doc,"click",this.handleClick,{capture:!0,passive:!1}),he(this.doc,"keydown",this.handleTabKey,{capture:!0,passive:!1}),he(this.doc,"keydown",this.handleEscapeKey)),this}removeListeners(){if(this.state.active)return this.listenerCleanups.forEach(e=>e()),this.listenerCleanups=[],this}activate(e){if(this.state.active)return this;const t=this.getOption(e,"onActivate"),n=this.getOption(e,"onPostActivate"),r=this.getOption(e,"checkCanFocusTrap");r||this.updateTabbableNodes(),this.state.active=!0,this.state.paused=!1,this.state.nodeFocusedBeforeActivation=di(this.doc),t==null||t();const i=()=>{r&&this.updateTabbableNodes(),this.addListeners(),this.updateObservedNodes(),n==null||n()};return r?(r(this.state.containers.concat()).then(i,i),this):(i(),this)}},Si=e=>e.key==="Tab",wi=(e,...t)=>typeof e=="function"?e(...t):e,mw=e=>!e.isComposing&&e.key==="Escape",ch=e=>setTimeout(e,0),vw=e=>e.localName==="input"&&"select"in e&&typeof e.select=="function";function bw(e,t={}){let n;const r=Z(()=>{const i=typeof e=="function"?e():e;if(i){n=new pw(i,{escapeDeactivates:!1,allowOutsideClick:!0,preventScroll:!0,returnFocusOnDeactivate:!0,delayInitialFocus:!1,fallbackFocus:i,...t,document:Ge(i)});try{n.activate()}catch{}}});return function(){n==null||n.deactivate(),r()}}var el="data-scroll-lock";function yw(e){const t=e.getBoundingClientRect().left;return Math.round(t)+e.scrollLeft?"paddingLeft":"paddingRight"}function xw(e){const t=e??document,n=t.defaultView??window,{documentElement:r,body:i}=t;if(i.hasAttribute(el))return;const s=n.innerWidth-r.clientWidth;i.setAttribute(el,"");const a=()=>kx(r,"--scrollbar-width",`${s}px`),l=yw(r),c=()=>To(i,{overflow:"hidden",[l]:`${s}px`}),u=()=>{const{scrollX:h,scrollY:m,visualViewport:f}=n,g=(f==null?void 0:f.offsetLeft)??0,p=(f==null?void 0:f.offsetTop)??0,b=To(i,{position:"fixed",overflow:"hidden",top:`${-(m-Math.floor(p))}px`,left:`${-(h-Math.floor(g))}px`,right:"0",[l]:`${s}px`});return()=>{b==null||b(),n.scrollTo({left:h,top:m,behavior:"instant"})}},d=[a(),So()?u():c()];return()=>{d.forEach(h=>h==null?void 0:h()),i.removeAttribute(el)}}var tl=K("dialog").parts("trigger","backdrop","positioner","content","title","description","closeTrigger"),Ln=tl.build(),uh=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`dialog:${e.id}:positioner`},dh=e=>{var t;return((t=e.ids)==null?void 0:t.backdrop)??`dialog:${e.id}:backdrop`},nl=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`dialog:${e.id}:content`},hh=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`dialog:${e.id}:trigger`},rl=e=>{var t;return((t=e.ids)==null?void 0:t.title)??`dialog:${e.id}:title`},il=e=>{var t;return((t=e.ids)==null?void 0:t.description)??`dialog:${e.id}:description`},fh=e=>{var t;return((t=e.ids)==null?void 0:t.closeTrigger)??`dialog:${e.id}:close`},es=e=>e.getById(nl(e)),Cw=e=>e.getById(uh(e)),Sw=e=>e.getById(dh(e)),ww=e=>e.getById(hh(e)),Ew=e=>e.getById(rl(e)),kw=e=>e.getById(il(e)),Ow=e=>e.getById(fh(e));function Iw(e,t){const{state:n,send:r,context:i,prop:o,scope:s}=e,a=o("aria-label"),l=n.matches("open");return{open:l,setOpen(c){n.matches("open")!==c&&r({type:c?"OPEN":"CLOSE"})},getTriggerProps(){return t.button({...Ln.trigger.attrs,dir:o("dir"),id:hh(s),"aria-haspopup":"dialog",type:"button","aria-expanded":l,"data-state":l?"open":"closed","aria-controls":nl(s),onClick(c){c.defaultPrevented||r({type:"TOGGLE"})}})},getBackdropProps(){return t.element({...Ln.backdrop.attrs,dir:o("dir"),hidden:!l,id:dh(s),"data-state":l?"open":"closed"})},getPositionerProps(){return t.element({...Ln.positioner.attrs,dir:o("dir"),id:uh(s),style:{pointerEvents:l?void 0:"none"}})},getContentProps(){const c=i.get("rendered");return t.element({...Ln.content.attrs,dir:o("dir"),role:o("role"),hidden:!l,id:nl(s),tabIndex:-1,"data-state":l?"open":"closed","aria-modal":!0,"aria-label":a||void 0,"aria-labelledby":a||!c.title?void 0:rl(s),"aria-describedby":c.description?il(s):void 0})},getTitleProps(){return t.element({...Ln.title.attrs,dir:o("dir"),id:rl(s)})},getDescriptionProps(){return t.element({...Ln.description.attrs,dir:o("dir"),id:il(s)})},getCloseTriggerProps(){return t.button({...Ln.closeTrigger.attrs,dir:o("dir"),id:fh(s),type:"button",onClick(c){c.defaultPrevented||(c.stopPropagation(),r({type:"CLOSE"}))}})}}}var Pw={props({props:e,scope:t}){const n=e.role==="alertdialog",r=n?()=>Ow(t):void 0,i=typeof e.modal=="boolean"?e.modal:!0;return{role:"dialog",modal:i,trapFocus:i,preventScroll:i,closeOnInteractOutside:!n,closeOnEscape:!0,restoreFocus:!0,initialFocusEl:r,...e}},initialState({prop:e}){return e("open")||e("defaultOpen")?"open":"closed"},context({bindable:e}){return{rendered:e(()=>({defaultValue:{title:!0,description:!0}}))}},watch({track:e,action:t,prop:n}){e([()=>n("open")],()=>{t(["toggleVisibility"])})},states:{open:{entry:["checkRenderedElements","syncZIndex"],effects:["trackDismissableElement","trapFocus","preventScroll","hideContentBelow"],on:{"CONTROLLED.CLOSE":{target:"closed"},CLOSE:[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"closed",actions:["invokeOnClose"]}],TOGGLE:[{guard:"isOpenControlled",actions:["invokeOnClose"]},{target:"closed",actions:["invokeOnClose"]}]}},closed:{on:{"CONTROLLED.OPEN":{target:"open"},OPEN:[{guard:"isOpenControlled",actions:["invokeOnOpen"]},{target:"open",actions:["invokeOnOpen"]}],TOGGLE:[{guard:"isOpenControlled",actions:["invokeOnOpen"]},{target:"open",actions:["invokeOnOpen"]}]}}},implementations:{guards:{isOpenControlled:({prop:e})=>e("open")!=null},effects:{trackDismissableElement({scope:e,send:t,prop:n}){return wr(()=>es(e),{type:"dialog",defer:!0,pointerBlocking:n("modal"),exclude:[ww(e)],onInteractOutside(i){var o;(o=n("onInteractOutside"))==null||o(i),n("closeOnInteractOutside")||i.preventDefault()},persistentElements:n("persistentElements"),onFocusOutside:n("onFocusOutside"),onPointerDownOutside:n("onPointerDownOutside"),onRequestDismiss:n("onRequestDismiss"),onEscapeKeyDown(i){var o;(o=n("onEscapeKeyDown"))==null||o(i),n("closeOnEscape")||i.preventDefault()},onDismiss(){t({type:"CLOSE",src:"interact-outside"})}})},preventScroll({scope:e,prop:t}){if(t("preventScroll"))return xw(e.getDoc())},trapFocus({scope:e,prop:t}){return t("trapFocus")?bw(()=>es(e),{preventScroll:!0,returnFocusOnDeactivate:!!t("restoreFocus"),initialFocus:t("initialFocusEl"),setReturnFocus:r=>{var i;return((i=t("finalFocusEl"))==null?void 0:i())??r}}):void 0},hideContentBelow({scope:e,prop:t}){return t("modal")?Kd(()=>[es(e)],{defer:!0}):void 0}},actions:{checkRenderedElements({context:e,scope:t}){Z(()=>{e.set("rendered",{title:!!Ew(t),description:!!kw(t)})})},syncZIndex({scope:e}){Z(()=>{const t=es(e);if(!t)return;const n=xo(t);[Cw(e),Sw(e)].forEach(i=>{i==null||i.style.setProperty("--z-index",n.zIndex),i==null||i.style.setProperty("--layer-index",n.getPropertyValue("--layer-index"))})})},invokeOnClose({prop:e}){var t;(t=e("onOpenChange"))==null||t({open:!1})},invokeOnOpen({prop:e}){var t;(t=e("onOpenChange"))==null||t({open:!0})},toggleVisibility({prop:e,send:t,event:n}){t({type:e("open")?"CONTROLLED.OPEN":"CONTROLLED.CLOSE",previousEvent:n})}}}};q()(["aria-label","closeOnEscape","closeOnInteractOutside","dir","finalFocusEl","getRootNode","getRootNode","id","id","ids","initialFocusEl","modal","onEscapeKeyDown","onFocusOutside","onInteractOutside","onOpenChange","onPointerDownOutside","onRequestDismiss","defaultOpen","open","persistentElements","preventScroll","restoreFocus","role","trapFocus"]);const Rw=e=>{const t=E.useId(),{getRootNode:n}=pu(),{dir:r}=Fx(),i={id:t,getRootNode:n,dir:r,...e},o=Lu(Pw,i);return Iw(o,jx)},Tw=e=>{const[t,{children:n,...r}]=Vu(e),[i]=Pd(t),o=Rw(r),s=Na(mt({present:o.open},t));return x.jsx(nh,{value:o,children:x.jsx(Id,{value:i,children:x.jsx(Mu,{value:s,children:n})})})},Nw=e=>{const[t,{value:n,children:r}]=Vu(e),[i]=Pd(t),o=Na(mt({present:n.open},t));return x.jsx(nh,{value:n,children:x.jsx(Id,{value:i,children:x.jsx(Mu,{value:o,children:r})})})},gh=E.forwardRef((e,t)=>{const n=cn(),r=mt(n.getTitleProps(),e);return x.jsx(on.h2,{...r,ref:t})});gh.displayName="DialogTitle";const ph=E.forwardRef((e,t)=>{const n=cn(),r=Aa(),i=mt({...n.getTriggerProps(),"aria-controls":r.unmounted?void 0:n.getTriggerProps()["aria-controls"]},e);return x.jsx(on.button,{...i,ref:t})});ph.displayName="DialogTrigger";var mh=K("editable").parts("root","area","label","preview","input","editTrigger","submitTrigger","cancelTrigger","control");mh.build(),q()(["activationMode","autoResize","dir","disabled","finalFocusEl","form","getRootNode","id","ids","invalid","maxLength","name","onEditChange","onFocusOutside","onInteractOutside","onPointerDownOutside","onValueChange","onValueCommit","onValueRevert","placeholder","readOnly","required","selectOnFocus","edit","defaultEdit","submitMode","translations","defaultValue","value"]);const vh=K("field").parts("root","errorText","helperText","input","label","select","textarea","requiredIndicator");vh.build();var Aw=e=>{var c,u;if(!e)return;const t=xo(e),n=Ie(e),r=Ge(e),i=()=>{requestAnimationFrame(()=>{e.style.height="auto";let d;t.boxSizing==="content-box"?d=e.scrollHeight-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):d=e.scrollHeight+parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),t.maxHeight!=="none"&&d>parseFloat(t.maxHeight)?(t.overflowY==="hidden"&&(e.style.overflowY="scroll"),d=parseFloat(t.maxHeight)):t.overflowY!=="hidden"&&(e.style.overflowY="hidden"),e.style.height=`${d}px`})};e.addEventListener("input",i),(c=e.form)==null||c.addEventListener("reset",i);const o=Object.getPrototypeOf(e),s=Object.getOwnPropertyDescriptor(o,"value");Object.defineProperty(e,"value",{...s,set(){var d;(d=s==null?void 0:s.set)==null||d.apply(this,arguments),i()}});const a=new n.ResizeObserver(()=>{requestAnimationFrame(()=>i())});a.observe(e);const l=new n.MutationObserver(()=>i());return l.observe(e,{attributes:!0,attributeFilter:["rows","placeholder"]}),(u=r.fonts)==null||u.addEventListener("loadingdone",i),()=>{var d,h;e.removeEventListener("input",i),(d=e.form)==null||d.removeEventListener("reset",i),(h=r.fonts)==null||h.removeEventListener("loadingdone",i),a.disconnect(),l.disconnect()}};const bh=E.forwardRef((e,t)=>{const{autoresize:n,...r}=e,i=E.useRef(null),o=IS(),s=mt(o==null?void 0:o.getTextareaProps(),{style:{resize:n?"none":void 0}},r);return E.useEffect(()=>{if(n)return Aw(i.current)},[n]),x.jsx(on.textarea,{...s,ref:No(t,i)})});bh.displayName="FieldTextarea";const yh=K("fieldset").parts("root","errorText","helperText","legend");yh.build();var xh=K("file-upload").parts("root","dropzone","item","itemDeleteTrigger","itemGroup","itemName","itemPreview","itemPreviewImage","itemSizeText","label","trigger","clearTrigger");xh.build(),q()(["accept","acceptedFiles","allowDrop","capture","defaultAcceptedFiles","dir","directory","disabled","getRootNode","id","ids","invalid","locale","maxFiles","maxFileSize","minFileSize","name","onFileAccept","onFileChange","onFileReject","preventDocumentDrop","required","transformFiles","translations","validate"]),q()(["file","type"]);var Ch=K("hoverCard").parts("arrow","arrowTip","trigger","positioner","content");Ch.build();var _w=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`hover-card:${e.id}:trigger`},Vw=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`hover-card:${e.id}:content`},Fw=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`hover-card:${e.id}:popper`},ol=e=>e.getById(_w(e)),Lw=e=>e.getById(Vw(e)),Sh=e=>e.getById(Fw(e)),{not:ts,and:wh}=rn();wh("isOpenControlled",ts("isPointer")),ts("isPointer"),wh("isOpenControlled",ts("isPointer")),ts("isPointer"),q()(["closeDelay","dir","getRootNode","id","ids","disabled","onOpenChange","defaultOpen","open","openDelay","positioning","onInteractOutside","onPointerDownOutside","onFocusOutside"]);var Eh=K("tree-view").parts("branch","branchContent","branchControl","branchIndentGuide","branchIndicator","branchText","branchTrigger","item","itemIndicator","itemText","label","nodeCheckbox","root","tree");Eh.build();var kh=e=>new Gd(e);kh.empty=()=>new Gd({rootNode:{children:[]}});var Dw=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.node)==null?void 0:r.call(n,t))??`tree:${e.id}:node:${t}`},Dn=(e,t)=>{var n;t!=null&&((n=e.getById(Dw(e,t)))==null||n.focus())};function zw(e,t,n){const r=e.getDescendantValues(t),i=r.every(o=>n.includes(o));return hr(i?Pn(n,...r):In(n,...r))}function ns(e,t){const{context:n,prop:r,refs:i}=e;if(!r("loadChildren")){n.set("expandedValue",g=>hr(In(g,...t)));return}const o=n.get("loadingStatus"),[s,a]=nu(t,g=>o[g]==="loaded");if(s.length>0&&n.set("expandedValue",g=>hr(In(g,...s))),a.length===0)return;const l=r("collection"),[c,u]=nu(a,g=>{const p=l.findNode(g);return l.getNodeChildren(p).length>0});if(c.length>0&&n.set("expandedValue",g=>hr(In(g,...c))),u.length===0)return;n.set("loadingStatus",g=>({...g,...u.reduce((p,b)=>({...p,[b]:"loading"}),{})}));const d=u.map(g=>{const p=l.getIndexPath(g),b=l.getValuePath(p),C=l.findNode(g);return{id:g,indexPath:p,valuePath:b,node:C}}),h=i.get("pendingAborts"),m=r("loadChildren");gu(m,()=>"[zag-js/tree-view] `loadChildren` is required for async expansion");const f=d.map(({id:g,indexPath:p,valuePath:b,node:C})=>{const S=h.get(g);S&&(S.abort(),h.delete(g));const y=new AbortController;return h.set(g,y),m({valuePath:b,indexPath:p,node:C,signal:y.signal})});Promise.allSettled(f).then(g=>{var y,k;const p=[],b=[],C=n.get("loadingStatus");let S=r("collection");g.forEach((R,A)=>{const{id:T,indexPath:N,node:I,valuePath:B}=d[A];R.status==="fulfilled"?(C[T]="loaded",p.push(T),S=S.replace(N,{...I,children:R.value})):(h.delete(T),Reflect.deleteProperty(C,T),b.push({node:I,error:R.reason,indexPath:N,valuePath:B}))}),n.set("loadingStatus",C),p.length&&(n.set("expandedValue",R=>hr(In(R,...p))),(y=r("onLoadChildrenComplete"))==null||y({collection:S})),b.length&&((k=r("onLoadChildrenError"))==null||k({nodes:b}))})}function un(e){const{prop:t,context:n}=e;return function({indexPath:i}){return t("collection").getValuePath(i).slice(0,-1).some(s=>!n.get("expandedValue").includes(s))}}var{and:At}=rn();At("isMultipleSelection","moveFocus"),At("isShiftKey","isMultipleSelection"),At("isShiftKey","isMultipleSelection"),At("isBranchFocused","isBranchExpanded"),At("isShiftKey","isMultipleSelection"),At("isShiftKey","isMultipleSelection"),At("isCtrlKey","isMultipleSelection"),At("isShiftKey","isMultipleSelection"),At("isCtrlKey","isMultipleSelection"),At("isShiftKey","isMultipleSelection"),q()(["ids","collection","dir","expandedValue","expandOnClick","defaultFocusedValue","focusedValue","getRootNode","id","onExpandedChange","onFocusChange","onSelectionChange","checkedValue","selectedValue","selectionMode","typeahead","defaultExpandedValue","defaultSelectedValue","defaultCheckedValue","onCheckedChange","onLoadChildrenComplete","onLoadChildrenError","loadChildren"]),q()(["node","indexPath"]);var Oh=K("listbox").parts("label","input","item","itemText","itemIndicator","itemGroup","itemGroupLabel","content","root","valueText");Oh.build(),q()(["collection","defaultHighlightedValue","defaultValue","dir","disabled","deselectable","disallowSelectAll","getRootNode","highlightedValue","id","ids","loopFocus","onHighlightChange","onSelect","onValueChange","orientation","scrollToIndexFn","selectionMode","selectOnHighlight","typeahead","value"]),q()(["item","highlightOnHover"]),q()(["id"]),q()(["htmlFor"]);const Mw=Oh.extendWith("empty");var Ih=K("menu").parts("arrow","arrowTip","content","contextTrigger","indicator","item","itemGroup","itemGroupLabel","itemIndicator","itemText","positioner","separator","trigger","triggerItem");Ih.build();var Ph=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`menu:${e.id}:trigger`},$w=e=>{var t;return((t=e.ids)==null?void 0:t.contextTrigger)??`menu:${e.id}:ctx-trigger`},Rh=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`menu:${e.id}:content`},Bw=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`menu:${e.id}:popper`},sl=(e,t)=>`${e.id}/${t}`,zn=e=>(e==null?void 0:e.dataset.value)??null,dn=e=>e.getById(Rh(e)),Th=e=>e.getById(Bw(e)),rs=e=>e.getById(Ph(e)),jw=(e,t)=>t?e.getById(sl(e,t)):null,al=e=>e.getById($w(e)),Ei=e=>{const n=`[role^="menuitem"][data-ownedby=${CSS.escape(Rh(e))}]:not([data-disabled])`;return Ro(dn(e),n)},Ww=e=>li(Ei(e)),Hw=e=>fa(Ei(e)),ll=(e,t)=>t?e.id===t||e.dataset.value===t:!1,Uw=(e,t)=>{const n=Ei(e),r=n.findIndex(i=>ll(i,t.value));return qy(n,r,{loop:t.loop??t.loopFocus})},Gw=(e,t)=>{const n=Ei(e),r=n.findIndex(i=>ll(i,t.value));return Xy(n,r,{loop:t.loop??t.loopFocus})},qw=(e,t)=>{const n=Ei(e),r=n.find(i=>ll(i,t.value));return fi(n,{state:t.typeaheadState,key:t.key,activeId:(r==null?void 0:r.id)??null})},Kw=e=>{var t;return!!((t=e==null?void 0:e.getAttribute("role"))!=null&&t.startsWith("menuitem"))&&!!(e!=null&&e.hasAttribute("aria-controls"))},Xw="menu:select";function Yw(e,t){if(!e)return;const n=Ie(e),r=new n.CustomEvent(Xw,{detail:{value:t}});e.dispatchEvent(r)}var{not:ct,and:Ir,or:Qw}=rn();ct("isSubmenu"),Qw("isOpenAutoFocusEvent","isArrowDownEvent"),Ir(ct("isTriggerItem"),"isOpenControlled"),ct("isTriggerItem"),Ir("isSubmenu","isOpenControlled"),ct("isPointerSuspended"),Ir(ct("isPointerSuspended"),ct("isTriggerItem")),Ir(ct("isTriggerItemHighlighted"),ct("isHighlightedItemEditable"),"closeOnSelect","isOpenControlled"),Ir(ct("isTriggerItemHighlighted"),ct("isHighlightedItemEditable"),"closeOnSelect"),Ir(ct("isTriggerItemHighlighted"),ct("isHighlightedItemEditable"));function Nh(e){let t=e.parent;for(;t&&t.context.get("isSubmenu");)t=t.refs.get("parent");t==null||t.send({type:"CLOSE"})}function Jw(e,t){return e?bS(e,t):!1}function Zw(e,t,n){const r=Object.keys(e).length>0;if(!t)return null;if(!r)return sl(n,t);for(const i in e){const o=e[i],s=Ph(o.scope);if(s===t)return s}return sl(n,t)}q()(["anchorPoint","aria-label","closeOnSelect","composite","defaultHighlightedValue","defaultOpen","dir","getRootNode","highlightedValue","id","ids","loopFocus","navigate","onEscapeKeyDown","onFocusOutside","onHighlightChange","onInteractOutside","onOpenChange","onPointerDownOutside","onRequestDismiss","onSelect","open","positioning","typeahead"]),q()(["closeOnSelect","disabled","value","valueText"]),q()(["htmlFor"]),q()(["id"]),q()(["checked","closeOnSelect","disabled","onCheckedChange","type","value","valueText"]);let cl=new Map,ul=!1;try{ul=new Intl.NumberFormat("de-DE",{signDisplay:"exceptZero"}).resolvedOptions().signDisplay==="exceptZero"}catch{}let is=!1;try{is=new Intl.NumberFormat("de-DE",{style:"unit",unit:"degree"}).resolvedOptions().style==="unit"}catch{}const Ah={degree:{narrow:{default:"°","ja-JP":" 度","zh-TW":"度","sl-SI":" °"}}};class eE{format(t){let n="";if(!ul&&this.options.signDisplay!=null?n=nE(this.numberFormatter,this.options.signDisplay,t):n=this.numberFormatter.format(t),this.options.style==="unit"&&!is){var r;let{unit:i,unitDisplay:o="short",locale:s}=this.resolvedOptions();if(!i)return n;let a=(r=Ah[i])===null||r===void 0?void 0:r[o];n+=a[s]||a.default}return n}formatToParts(t){return this.numberFormatter.formatToParts(t)}formatRange(t,n){if(typeof this.numberFormatter.formatRange=="function")return this.numberFormatter.formatRange(t,n);if(n= start date");return`${this.format(t)} – ${this.format(n)}`}formatRangeToParts(t,n){if(typeof this.numberFormatter.formatRangeToParts=="function")return this.numberFormatter.formatRangeToParts(t,n);if(n= start date");let r=this.numberFormatter.formatToParts(t),i=this.numberFormatter.formatToParts(n);return[...r.map(o=>({...o,source:"startRange"})),{type:"literal",value:" – ",source:"shared"},...i.map(o=>({...o,source:"endRange"}))]}resolvedOptions(){let t=this.numberFormatter.resolvedOptions();return!ul&&this.options.signDisplay!=null&&(t={...t,signDisplay:this.options.signDisplay}),!is&&this.options.style==="unit"&&(t={...t,style:"unit",unit:this.options.unit,unitDisplay:this.options.unitDisplay}),t}constructor(t,n={}){this.numberFormatter=tE(t,n),this.options=n}}function tE(e,t={}){let{numberingSystem:n}=t;if(n&&e.includes("-nu-")&&(e.includes("-u-")||(e+="-u-"),e+=`-nu-${n}`),t.style==="unit"&&!is){var r;let{unit:s,unitDisplay:a="short"}=t;if(!s)throw new Error('unit option must be provided with style: "unit"');if(!(!((r=Ah[s])===null||r===void 0)&&r[a]))throw new Error(`Unsupported unit ${s} with unitDisplay = ${a}`);t={...t,style:"decimal"}}let i=e+(t?Object.entries(t).sort((s,a)=>s[0]0||Object.is(n,0):t==="exceptZero"&&(Object.is(n,-0)||Object.is(n,0)?n=Math.abs(n):r=n>0),r){let i=e.format(-n),o=e.format(n),s=i.replace(o,"").replace(/\u200e|\u061C/,"");return[...s].length!==1&&console.warn("@react-aria/i18n polyfill for NumberFormat signDisplay: Unsupported case"),i.replace(o,"!!!").replace(s,"+").replace("!!!",o)}else return e.format(n)}}const rE=new RegExp("^.*\\(.*\\).*$"),iE=["latn","arab","hanidec","deva","beng","fullwide"];class _h{parse(t){return dl(this.locale,this.options,t).parse(t)}isValidPartialNumber(t,n,r){return dl(this.locale,this.options,t).isValidPartialNumber(t,n,r)}getNumberingSystem(t){return dl(this.locale,this.options,t).options.numberingSystem}constructor(t,n={}){this.locale=t,this.options=n}}const Vh=new Map;function dl(e,t,n){let r=Fh(e,t);if(!e.includes("-nu-")&&!r.isValidPartialNumber(n)){for(let i of iE)if(i!==r.options.numberingSystem){let o=Fh(e+(e.includes("-u-")?"-nu-":"-u-nu-")+i,t);if(o.isValidPartialNumber(n))return o}}return r}function Fh(e,t){let n=e+(t?Object.entries(t).sort((i,o)=>i[0]-1&&(n=`-${n}`)}let r=n?+n:NaN;if(isNaN(r))return NaN;if(this.options.style==="percent"){var i,o;let s={...this.options,style:"decimal",minimumFractionDigits:Math.min(((i=this.options.minimumFractionDigits)!==null&&i!==void 0?i:0)+2,20),maximumFractionDigits:Math.min(((o=this.options.maximumFractionDigits)!==null&&o!==void 0?o:0)+2,20)};return new _h(this.locale,s).parse(new eE(this.locale,s).format(r))}return this.options.currencySign==="accounting"&&rE.test(t)&&(r=-1*r),r}sanitize(t){return t=t.replace(this.symbols.literals,""),this.symbols.minusSign&&(t=t.replace("-",this.symbols.minusSign)),this.options.numberingSystem==="arab"&&(this.symbols.decimal&&(t=t.replace(",",this.symbols.decimal),t=t.replace("،",this.symbols.decimal)),this.symbols.group&&(t=Pr(t,".",this.symbols.group))),this.symbols.group==="’"&&t.includes("'")&&(t=Pr(t,"'",this.symbols.group)),this.options.locale==="fr-FR"&&this.symbols.group&&(t=Pr(t," ",this.symbols.group),t=Pr(t,/\u00A0/g,this.symbols.group)),t}isValidPartialNumber(t,n=-1/0,r=1/0){return t=this.sanitize(t),this.symbols.minusSign&&t.startsWith(this.symbols.minusSign)&&n<0?t=t.slice(this.symbols.minusSign.length):this.symbols.plusSign&&t.startsWith(this.symbols.plusSign)&&r>0&&(t=t.slice(this.symbols.plusSign.length)),this.symbols.group&&t.startsWith(this.symbols.group)||this.symbols.decimal&&t.indexOf(this.symbols.decimal)>-1&&this.options.maximumFractionDigits===0?!1:(this.symbols.group&&(t=Pr(t,this.symbols.group,"")),t=t.replace(this.symbols.numeral,""),this.symbols.decimal&&(t=t.replace(this.symbols.decimal,"")),t.length===0)}constructor(t,n={}){this.locale=t,n.roundingIncrement!==1&&n.roundingIncrement!=null&&(n.maximumFractionDigits==null&&n.minimumFractionDigits==null?(n.maximumFractionDigits=0,n.minimumFractionDigits=0):n.maximumFractionDigits==null?n.maximumFractionDigits=n.minimumFractionDigits:n.minimumFractionDigits==null&&(n.minimumFractionDigits=n.maximumFractionDigits)),this.formatter=new Intl.NumberFormat(t,n),this.options=this.formatter.resolvedOptions(),this.symbols=aE(t,this.formatter,this.options,n);var r,i;this.options.style==="percent"&&(((r=this.options.minimumFractionDigits)!==null&&r!==void 0?r:0)>18||((i=this.options.maximumFractionDigits)!==null&&i!==void 0?i:0)>18)&&console.warn("NumberParser cannot handle percentages with greater than 18 decimal places, please reduce the number in your options.")}}const Lh=new Set(["decimal","fraction","integer","minusSign","plusSign","group"]),sE=[0,4,2,1,11,20,3,7,100,21,.1,1.1];function aE(e,t,n,r){var i,o,s,a;let l=new Intl.NumberFormat(e,{...n,minimumSignificantDigits:1,maximumSignificantDigits:21,roundingIncrement:1,roundingPriority:"auto",roundingMode:"halfExpand"}),c=l.formatToParts(-10000.111),u=l.formatToParts(10000.111),d=sE.map(I=>l.formatToParts(I));var h;let m=(h=(i=c.find(I=>I.type==="minusSign"))===null||i===void 0?void 0:i.value)!==null&&h!==void 0?h:"-",f=(o=u.find(I=>I.type==="plusSign"))===null||o===void 0?void 0:o.value;!f&&((r==null?void 0:r.signDisplay)==="exceptZero"||(r==null?void 0:r.signDisplay)==="always")&&(f="+");let p=(s=new Intl.NumberFormat(e,{...n,minimumFractionDigits:2,maximumFractionDigits:2}).formatToParts(.001).find(I=>I.type==="decimal"))===null||s===void 0?void 0:s.value,b=(a=c.find(I=>I.type==="group"))===null||a===void 0?void 0:a.value,C=c.filter(I=>!Lh.has(I.type)).map(I=>Dh(I.value)),S=d.flatMap(I=>I.filter(B=>!Lh.has(B.type)).map(B=>Dh(B.value))),y=[...new Set([...C,...S])].sort((I,B)=>B.length-I.length),k=y.length===0?new RegExp("[\\p{White_Space}]","gu"):new RegExp(`${y.join("|")}|[\\p{White_Space}]`,"gu"),R=[...new Intl.NumberFormat(n.locale,{useGrouping:!1}).format(9876543210)].reverse(),A=new Map(R.map((I,B)=>[I,B])),T=new RegExp(`[${R.join("")}]`,"g");return{minusSign:m,plusSign:f,decimal:p,group:b,literals:k,numeral:T,index:I=>String(A.get(I))}}function Pr(e,t,n){return e.replaceAll?e.replaceAll(t,n):e.split(t).join(n)}function Dh(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var zh=K("numberInput").parts("root","label","input","control","valueText","incrementTrigger","decrementTrigger","scrubber");zh.build();var lE=e=>{var t;return((t=e.ids)==null?void 0:t.input)??`number-input:${e.id}:input`},cE=e=>{var t;return((t=e.ids)==null?void 0:t.incrementTrigger)??`number-input:${e.id}:inc`},uE=e=>{var t;return((t=e.ids)==null?void 0:t.decrementTrigger)??`number-input:${e.id}:dec`},Mh=e=>`number-input:${e.id}:cursor`,os=e=>e.getById(lE(e)),dE=e=>e.getById(cE(e)),hE=e=>e.getById(uE(e)),$h=e=>e.getDoc().getElementById(Mh(e)),fE=(e,t)=>{let n=null;return t==="increment"&&(n=dE(e)),t==="decrement"&&(n=hE(e)),n},gE=(e,t)=>{if(!Su())return vE(e,t),()=>{var n;(n=$h(e))==null||n.remove()}},pE=e=>{const t=e.getDoc(),n=t.documentElement,r=t.body;return r.style.pointerEvents="none",n.style.userSelect="none",n.style.cursor="ew-resize",()=>{r.style.pointerEvents="",n.style.userSelect="",n.style.cursor="",n.style.length||n.removeAttribute("style"),r.style.length||r.removeAttribute("style")}},mE=(e,t)=>{const{point:n,isRtl:r,event:i}=t,o=e.getWin(),s=ma(i.movementX,o.devicePixelRatio),a=ma(i.movementY,o.devicePixelRatio);let l=s>0?"increment":s<0?"decrement":null;r&&l==="increment"&&(l="decrement"),r&&l==="decrement"&&(l="increment");const c={x:n.x+s,y:n.y+a},u=o.innerWidth,d=ma(7.5,o.devicePixelRatio);return c.x=h0(c.x+d,u)-d,{hint:l,point:c}},vE=(e,t)=>{const n=e.getDoc(),r=n.createElement("div");r.className="scrubber--cursor",r.id=Mh(e),Object.assign(r.style,{width:"15px",height:"15px",position:"fixed",pointerEvents:"none",left:"0px",top:"0px",zIndex:k0,transform:t?`translate3d(${t.x}px, ${t.y}px, 0px)`:void 0,willChange:"transform"}),r.innerHTML=` - `,n.body.appendChild(r)};function pE(e){if(!(!e||e.ownerDocument.activeElement!==e))try{const{selectionStart:t,selectionEnd:n,value:r}=e,i=r.substring(0,t),o=r.substring(n);return{start:t,end:n,value:r,beforeTxt:i,afterTxt:o}}catch{}}function mE(e,t){if(!(!e||e.ownerDocument.activeElement!==e)){if(!t){e.setSelectionRange(e.value.length,e.value.length);return}try{const{value:n}=e,{beforeTxt:r="",afterTxt:i="",start:o}=t;let s=n.length;if(n.endsWith(i))s=n.length-i.length;else if(n.startsWith(r))s=r.length;else if(o!=null){const a=r[o-1],l=n.indexOf(a,o-1);l!==-1&&(s=l+1)}e.setSelectionRange(s,s)}catch{}}}var vE=(e,t={})=>new Intl.NumberFormat(e,t),bE=(e,t={})=>new _h(e,t),dl=(e,t)=>{const{prop:n,computed:r}=t;return n("formatOptions")?e===""?Number.NaN:r("parser").parse(e):parseFloat(e)},Dn=(e,t)=>{const{prop:n,computed:r}=t;return Number.isNaN(e)?"":n("formatOptions")?r("formatter").format(e):e.toString()},yE=(e,t)=>{let n=e!==void 0&&!Number.isNaN(e)?e:1;return(t==null?void 0:t.style)==="percent"&&(e===void 0||Number.isNaN(e))&&(n=.01),n},{choose:xE,guards:CE,createMachine:SE}=Au(),{not:Bh,and:jh}=CE;SE({props({props:e}){const t=yE(e.step,e.formatOptions);return{dir:"ltr",locale:"en-US",focusInputOnChange:!0,clampValueOnBlur:!e.allowOverflow,allowOverflow:!1,inputMode:"decimal",pattern:"-?[0-9]*(.[0-9]+)?",defaultValue:"",step:t,min:Number.MIN_SAFE_INTEGER,max:Number.MAX_SAFE_INTEGER,spinOnPress:!0,...e,translations:{incrementLabel:"increment value",decrementLabel:"decrease value",...e.translations}}},initialState(){return"idle"},context({prop:e,bindable:t,getComputed:n}){return{value:t(()=>({defaultValue:e("defaultValue"),value:e("value"),onChange(r){var s;const i=n(),o=dl(r,{computed:i,prop:e});(s=e("onValueChange"))==null||s({value:r,valueAsNumber:o})}})),hint:t(()=>({defaultValue:null})),scrubberCursorPoint:t(()=>({defaultValue:null,hash(r){return r?`x:${r.x}, y:${r.y}`:""}})),fieldsetDisabled:t(()=>({defaultValue:!1}))}},computed:{isRtl:({prop:e})=>e("dir")==="rtl",valueAsNumber:({context:e,computed:t,prop:n})=>dl(e.get("value"),{computed:t,prop:n}),formattedValue:({computed:e,prop:t})=>Dn(e("valueAsNumber"),{computed:e,prop:t}),isAtMin:({computed:e,prop:t})=>h0(e("valueAsNumber"),t("min")),isAtMax:({computed:e,prop:t})=>d0(e("valueAsNumber"),t("max")),isOutOfRange:({computed:e,prop:t})=>!f0(e("valueAsNumber"),t("min"),t("max")),isValueEmpty:({context:e})=>e.get("value")==="",isDisabled:({prop:e,context:t})=>!!e("disabled")||t.get("fieldsetDisabled"),canIncrement:({prop:e,computed:t})=>e("allowOverflow")||!t("isAtMax"),canDecrement:({prop:e,computed:t})=>e("allowOverflow")||!t("isAtMin"),valueText:({prop:e,context:t})=>{var n,r;return(r=(n=e("translations")).valueText)==null?void 0:r.call(n,t.get("value"))},formatter:Nu(({prop:e})=>[e("locale"),e("formatOptions")],(e,t)=>vE(e,t)),parser:Nu(({prop:e})=>[e("locale"),e("formatOptions")],(e,t)=>bE(e,t))},watch({track:e,action:t,context:n,computed:r,prop:i}){e([()=>n.get("value"),()=>i("locale")],()=>{t(["syncInputElement"])}),e([()=>r("isOutOfRange")],()=>{t(["invokeOnInvalid"])}),e([()=>n.hash("scrubberCursorPoint")],()=>{t(["setVirtualCursorPosition"])})},effects:["trackFormControl"],on:{"VALUE.SET":{actions:["setRawValue"]},"VALUE.CLEAR":{actions:["clearValue"]},"VALUE.INCREMENT":{actions:["increment"]},"VALUE.DECREMENT":{actions:["decrement"]}},states:{idle:{on:{"TRIGGER.PRESS_DOWN":[{guard:"isTouchPointer",target:"before:spin",actions:["setHint"]},{target:"before:spin",actions:["focusInput","invokeOnFocus","setHint"]}],"SCRUBBER.PRESS_DOWN":{target:"scrubbing",actions:["focusInput","invokeOnFocus","setHint","setCursorPoint"]},"INPUT.FOCUS":{target:"focused",actions:["focusInput","invokeOnFocus"]}}},focused:{tags:["focus"],effects:["attachWheelListener"],on:{"TRIGGER.PRESS_DOWN":[{guard:"isTouchPointer",target:"before:spin",actions:["setHint"]},{target:"before:spin",actions:["focusInput","setHint"]}],"SCRUBBER.PRESS_DOWN":{target:"scrubbing",actions:["focusInput","setHint","setCursorPoint"]},"INPUT.ARROW_UP":{actions:["increment"]},"INPUT.ARROW_DOWN":{actions:["decrement"]},"INPUT.HOME":{actions:["decrementToMin"]},"INPUT.END":{actions:["incrementToMax"]},"INPUT.CHANGE":{actions:["setValue","setHint"]},"INPUT.BLUR":[{guard:jh("clampValueOnBlur",Bh("isInRange")),target:"idle",actions:["setClampedValue","clearHint","invokeOnBlur"]},{guard:Bh("isInRange"),target:"idle",actions:["setFormattedValue","clearHint","invokeOnBlur","invokeOnInvalid"]},{target:"idle",actions:["setFormattedValue","clearHint","invokeOnBlur"]}],"INPUT.ENTER":{actions:["setFormattedValue","clearHint","invokeOnBlur"]}}},"before:spin":{tags:["focus"],effects:["trackButtonDisabled","waitForChangeDelay"],entry:xE([{guard:"isIncrementHint",actions:["increment"]},{guard:"isDecrementHint",actions:["decrement"]}]),on:{CHANGE_DELAY:{target:"spinning",guard:jh("isInRange","spinOnPress")},"TRIGGER.PRESS_UP":[{guard:"isTouchPointer",target:"focused",actions:["clearHint"]},{target:"focused",actions:["focusInput","clearHint"]}]}},spinning:{tags:["focus"],effects:["trackButtonDisabled","spinValue"],on:{SPIN:[{guard:"isIncrementHint",actions:["increment"]},{guard:"isDecrementHint",actions:["decrement"]}],"TRIGGER.PRESS_UP":{target:"focused",actions:["focusInput","clearHint"]}}},scrubbing:{tags:["focus"],effects:["activatePointerLock","trackMousemove","setupVirtualCursor","preventTextSelection"],on:{"SCRUBBER.POINTER_UP":{target:"focused",actions:["focusInput","clearCursorPoint"]},"SCRUBBER.POINTER_MOVE":[{guard:"isIncrementHint",actions:["increment","setCursorPoint"]},{guard:"isDecrementHint",actions:["decrement","setCursorPoint"]}]}}},implementations:{guards:{clampValueOnBlur:({prop:e})=>e("clampValueOnBlur"),spinOnPress:({prop:e})=>!!e("spinOnPress"),isInRange:({computed:e})=>!e("isOutOfRange"),isDecrementHint:({context:e,event:t})=>(t.hint??e.get("hint"))==="decrement",isIncrementHint:({context:e,event:t})=>(t.hint??e.get("hint"))==="increment",isTouchPointer:({event:e})=>e.pointerType==="touch"},effects:{waitForChangeDelay({send:e}){const t=setTimeout(()=>{e({type:"CHANGE_DELAY"})},300);return()=>clearTimeout(t)},spinValue({send:e}){const t=setInterval(()=>{e({type:"SPIN"})},50);return()=>clearInterval(t)},trackFormControl({context:e,scope:t}){const n=rs(t);return ya(n,{onFieldsetDisabledChange(r){e.set("fieldsetDisabled",r)},onFormReset(){e.set("value",e.initial("value"))}})},setupVirtualCursor({context:e,scope:t}){const n=e.get("scrubberCursorPoint");return dE(t,n)},preventTextSelection({scope:e}){return hE(e)},trackButtonDisabled({context:e,scope:t,send:n}){const r=e.get("hint"),i=uE(t,r);return wo(i,{attributes:["disabled"],callback(){n({type:"TRIGGER.PRESS_UP",src:"attr"})}})},attachWheelListener({scope:e,send:t,prop:n}){const r=rs(e);if(!r||!e.isActiveElement(r)||!n("allowMouseWheel"))return;function i(o){o.preventDefault();const s=Math.sign(o.deltaY)*-1;s===1?t({type:"VALUE.INCREMENT"}):s===-1&&t({type:"VALUE.DECREMENT"})}return he(r,"wheel",i,{passive:!1})},activatePointerLock({scope:e}){if(!wu())return ux(e.getDoc())},trackMousemove({scope:e,send:t,context:n,computed:r}){const i=e.getDoc();function o(a){const l=n.get("scrubberCursorPoint"),c=r("isRtl"),u=fE(e,{point:l,isRtl:c,event:a});u.hint&&t({type:"SCRUBBER.POINTER_MOVE",hint:u.hint,point:u.point})}function s(){t({type:"SCRUBBER.POINTER_UP"})}return go(he(i,"mousemove",o,!1),he(i,"mouseup",s,!1))}},actions:{focusInput({scope:e,prop:t}){if(!t("focusInputOnChange"))return;const n=rs(e);e.isActiveElement(n)||Z(()=>n==null?void 0:n.focus({preventScroll:!0}))},increment({context:e,event:t,prop:n,computed:r}){let i=v0(r("valueAsNumber"),t.step??n("step"));n("allowOverflow")||(i=Ue(i,n("min"),n("max"))),e.set("value",Dn(i,{computed:r,prop:n}))},decrement({context:e,event:t,prop:n,computed:r}){let i=b0(r("valueAsNumber"),t.step??n("step"));n("allowOverflow")||(i=Ue(i,n("min"),n("max"))),e.set("value",Dn(i,{computed:r,prop:n}))},setClampedValue({context:e,prop:t,computed:n}){const r=Ue(n("valueAsNumber"),t("min"),t("max"));e.set("value",Dn(r,{computed:n,prop:t}))},setRawValue({context:e,event:t,prop:n,computed:r}){let i=dl(t.value,{computed:r,prop:n});n("allowOverflow")||(i=Ue(i,n("min"),n("max"))),e.set("value",Dn(i,{computed:r,prop:n}))},setValue({context:e,event:t}){var r;const n=((r=t.target)==null?void 0:r.value)??t.value;e.set("value",n)},clearValue({context:e}){e.set("value","")},incrementToMax({context:e,prop:t,computed:n}){const r=Dn(t("max"),{computed:n,prop:t});e.set("value",r)},decrementToMin({context:e,prop:t,computed:n}){const r=Dn(t("min"),{computed:n,prop:t});e.set("value",r)},setHint({context:e,event:t}){e.set("hint",t.hint)},clearHint({context:e}){e.set("hint",null)},invokeOnFocus({computed:e,prop:t}){var n;(n=t("onFocusChange"))==null||n({focused:!0,value:e("formattedValue"),valueAsNumber:e("valueAsNumber")})},invokeOnBlur({computed:e,prop:t}){var n;(n=t("onFocusChange"))==null||n({focused:!1,value:e("formattedValue"),valueAsNumber:e("valueAsNumber")})},invokeOnInvalid({computed:e,prop:t,event:n}){var i;if(n.type==="INPUT.CHANGE")return;const r=e("valueAsNumber")>t("max")?"rangeOverflow":"rangeUnderflow";(i=t("onValueInvalid"))==null||i({reason:r,value:e("formattedValue"),valueAsNumber:e("valueAsNumber")})},syncInputElement({context:e,event:t,computed:n,scope:r}){const i=t.type.endsWith("CHANGE")?e.get("value"):n("formattedValue"),o=rs(r),s=pE(o);Z(()=>{So(o,i),mE(o,s)})},setFormattedValue({context:e,computed:t}){e.set("value",t("formattedValue"))},setCursorPoint({context:e,event:t}){e.set("scrubberCursorPoint",t.point)},clearCursorPoint({context:e}){e.set("scrubberCursorPoint",null)},setVirtualCursorPosition({context:e,scope:t}){const n=$h(t),r=e.get("scrubberCursorPoint");!n||!r||(n.style.transform=`translate3d(${r.x}px, ${r.y}px, 0px)`)}}}}),U()(["allowMouseWheel","allowOverflow","clampValueOnBlur","dir","disabled","focusInputOnChange","form","formatOptions","getRootNode","id","ids","inputMode","invalid","locale","max","min","name","onFocusChange","onValueChange","onValueInvalid","pattern","required","readOnly","spinOnPress","step","translations","value","defaultValue"]);var Wh=G("pinInput").parts("root","label","input","control");Wh.build(),U()(["autoFocus","blurOnComplete","count","defaultValue","dir","disabled","form","getRootNode","id","ids","invalid","mask","name","onValueChange","onValueComplete","onValueInvalid","otp","pattern","placeholder","readOnly","required","selectOnFocus","translations","type","value"]);var Hh=G("popover").parts("arrow","arrowTip","anchor","trigger","indicator","positioner","content","title","description","closeTrigger");Hh.build(),U()(["autoFocus","closeOnEscape","closeOnInteractOutside","dir","getRootNode","id","ids","initialFocusEl","modal","onEscapeKeyDown","onFocusOutside","onInteractOutside","onOpenChange","onPointerDownOutside","onRequestDismiss","defaultOpen","open","persistentElements","portalled","positioning"]);const wE=e=>{var l;const{children:t,disabled:n}=e,[r,i]=E.useState((l=e.container)==null?void 0:l.current),o=E.useSyncExternalStore(kE,()=>!1,()=>!0),{getRootNode:s}=pu();if(E.useEffect(()=>{i(()=>{var c;return(c=e.container)==null?void 0:c.current})},[e.container]),o||n)return y.jsx(y.Fragment,{children:t});const a=r??EE(s);return y.jsx(y.Fragment,{children:E.Children.map(t,c=>te.createPortal(c,a))})},EE=e=>{const t=e==null?void 0:e(),n=t.getRootNode();return fr(n)?n:Ge(t).body},kE=()=>()=>{};var hl=G("progress").parts("root","label","track","range","valueText","view","circle","circleTrack","circleRange");hl.build(),U()(["dir","getRootNode","id","ids","max","min","orientation","translations","value","onValueChange","defaultValue","formatOptions","locale"]);var Uh=G("qr-code").parts("root","frame","pattern","overlay","downloadTrigger");Uh.build(),U()(["ids","defaultValue","value","id","encoding","dir","getRootNode","onValueChange","pixelSize"]);var fl=G("radio-group").parts("root","label","item","itemText","itemControl","indicator");fl.build(),U()(["dir","disabled","form","getRootNode","id","ids","name","onValueChange","orientation","readOnly","value","defaultValue"]),U()(["value","disabled","invalid"]);var Gh=G("rating-group").parts("root","label","item","control");Gh.build(),U()(["allowHalf","autoFocus","count","dir","disabled","form","getRootNode","id","ids","name","onHoverChange","onValueChange","required","readOnly","translations","value","defaultValue"]),U()(["index"]);var qh=G("scroll-area").parts("root","viewport","content","scrollbar","thumb","corner");qh.build(),U()(["dir","getRootNode","ids","id"]);const Kh=fl.rename("segment-group");Kh.build();var Xh=G("select").parts("label","positioner","trigger","indicator","clearTrigger","item","itemText","itemIndicator","itemGroup","itemGroupLabel","list","content","root","control","valueText");Xh.build();var Yh=e=>new qo(e);Yh.empty=()=>new qo({items:[]});var OE=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`select:${e.id}:content`},IE=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`select:${e.id}:trigger`},PE=e=>{var t;return((t=e.ids)==null?void 0:t.clearTrigger)??`select:${e.id}:clear-trigger`},RE=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.item)==null?void 0:r.call(n,t))??`select:${e.id}:option:${t}`},TE=e=>{var t;return((t=e.ids)==null?void 0:t.hiddenSelect)??`select:${e.id}:select`},NE=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`select:${e.id}:positioner`},gl=e=>e.getById(TE(e)),Si=e=>e.getById(OE(e)),is=e=>e.getById(IE(e)),AE=e=>e.getById(PE(e)),Qh=e=>e.getById(NE(e)),pl=(e,t)=>t==null?null:e.getById(RE(e,t)),{and:wi,not:zn,or:_E}=Zt();_E("isTriggerArrowDownEvent","isTriggerEnterEvent"),wi(zn("multiple"),"hasSelectedItems"),zn("multiple"),wi(zn("multiple"),"hasSelectedItems"),zn("multiple"),zn("multiple"),zn("multiple"),zn("multiple"),wi("closeOnSelect","isOpenControlled"),wi("hasHighlightedItem","loop","isLastItemHighlighted"),wi("hasHighlightedItem","loop","isFirstItemHighlighted");function Jh(e){var n;const t=e.restoreFocus??((n=e.previousEvent)==null?void 0:n.restoreFocus);return t==null||!!t}U()(["closeOnSelect","collection","composite","defaultHighlightedValue","defaultOpen","defaultValue","deselectable","dir","disabled","form","getRootNode","highlightedValue","id","ids","invalid","loopFocus","multiple","name","onFocusOutside","onHighlightChange","onInteractOutside","onOpenChange","onPointerDownOutside","onSelect","onValueChange","open","positioning","readOnly","required","scrollToIndexFn","value"]),U()(["item","persistFocus"]),U()(["id"]),U()(["htmlFor"]);var Zh=G("slider").parts("root","label","thumb","valueText","track","range","control","markerGroup","marker","draggingIndicator");Zh.build(),U()(["aria-label","aria-labelledby","dir","disabled","form","getAriaValueText","getRootNode","id","ids","invalid","max","min","minStepsBetweenThumbs","name","onFocusChange","onValueChange","onValueChangeEnd","orientation","origin","readOnly","step","thumbAlignment","thumbAlignment","thumbSize","value","defaultValue"]),U()(["index","name"]);var ef=G("switch").parts("root","label","control","thumb");ef.build(),U()(["checked","defaultChecked","dir","disabled","form","getRootNode","id","ids","invalid","label","name","onCheckedChange","readOnly","required","value"]);var VE=G("toast").parts("group","root","title","description","actionTrigger","closeTrigger");VE.build();var FE=(e,t)=>({...t,...mo(e)});function LE(e){const t=FE(e,{placement:"bottom",overlap:!1,max:24,gap:16,offsets:"1rem",hotkey:["altKey","KeyT"],removeDelay:200,pauseOnPageIdle:!0});let n=[],r=[],i=new Set,o=[];const s=I=>(n.push(I),()=>{const F=n.indexOf(I);n.splice(F,1)}),a=I=>(n.forEach(F=>F(I)),I),l=I=>{if(r.length>=t.max){o.push(I);return}a(I),r.unshift(I)},c=()=>{for(;o.length>0&&r.length{const F=I.id??`toast:${o0()}`,Y=r.find(z=>z.id===F);return i.has(F)&&i.delete(F),Y?r=r.map(z=>z.id===F?a({...z,...I,id:F}):z):l({id:F,duration:t.duration,removeDelay:t.removeDelay,type:"info",...I,stacked:!t.overlap,gap:t.gap}),F},d=I=>(i.add(I),I?(n.forEach(F=>F({id:I,dismiss:!0})),r=r.filter(F=>F.id!==I),c()):(r.forEach(F=>{n.forEach(Y=>Y({id:F.id,dismiss:!0}))}),r=[],o=[]),I);return{attrs:t,subscribe:s,create:u,update:(I,F)=>u({id:I,...F}),remove:d,dismiss:I=>{I!=null?r=r.map(F=>F.id===I?a({...F,message:"DISMISS"}):F):r=r.map(F=>a({...F,message:"DISMISS"}))},error:I=>u({...I,type:"error"}),success:I=>u({...I,type:"success"}),info:I=>u({...I,type:"info"}),warning:I=>u({...I,type:"warning"}),loading:I=>u({...I,type:"loading"}),getVisibleToasts:()=>r.filter(I=>!i.has(I.id)),getCount:()=>r.length,promise:(I,F,Y={})=>{if(!F||!F.loading){ai("[zag-js > toast] toaster.promise() requires at least a 'loading' option to be specified");return}const z=u({...Y,...F.loading,promise:I,type:"loading"});let V=!0,B;const K=fo(I).then(async H=>{if(B=["resolve",H],DE(H)&&!H.ok){V=!1;const X=fo(F.error,`HTTP Error! status: ${H.status}`);u({...Y,...X,id:z,type:"error"})}else if(F.success!==void 0){V=!1;const X=fo(F.success,H);u({...Y,...X,id:z,type:"success"})}}).catch(async H=>{if(B=["reject",H],F.error!==void 0){V=!1;const X=fo(F.error,H);u({...Y,...X,id:z,type:"error"})}}).finally(()=>{var H;V&&d(z),(H=F.finally)==null||H.call(F)});return{id:z,unwrap:()=>new Promise((H,X)=>K.then(()=>B[0]==="reject"?X(B[1]):H(B[1])).catch(X))}},pause:I=>{I!=null?r=r.map(F=>F.id===I?a({...F,message:"PAUSE"}):F):r=r.map(F=>a({...F,message:"PAUSE"}))},resume:I=>{I!=null?r=r.map(F=>F.id===I?a({...F,message:"RESUME"}):F):r=r.map(F=>a({...F,message:"RESUME"}))},isVisible:I=>!i.has(I)&&!!r.find(F=>F.id===I),isDismissed:I=>i.has(I),expand:()=>{r=r.map(I=>a({...I,stacked:!0}))},collapse:()=>{r=r.map(I=>a({...I,stacked:!1}))}}}var DE=e=>e&&typeof e=="object"&&"ok"in e&&typeof e.ok=="boolean"&&"status"in e&&typeof e.status=="number";const zE=e=>LE(e);var tf=G("tooltip").parts("trigger","arrow","arrowTip","positioner","content");tf.build();var ME=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`tooltip:${e.id}:trigger`},$E=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`tooltip:${e.id}:popper`},ml=e=>e.getById(ME(e)),nf=e=>e.getById($E(e)),Mn=y0({id:null}),{and:BE,not:rf}=Zt();BE("noVisibleTooltip",rf("hasPointerMoveOpened")),rf("hasPointerMoveOpened"),U()(["aria-label","closeDelay","closeOnEscape","closeOnPointerDown","closeOnScroll","closeOnClick","dir","disabled","getRootNode","id","ids","interactive","onOpenChange","defaultOpen","open","openDelay","positioning"]);function of(e,t=[]){const n=Object.assign({},e);for(const r of t)r in n&&delete n[r];return n}const jE=(e,t)=>{var l;if(!e||typeof e!="string")return{invalid:!0,value:e};const[n,r]=e.split("/");if(!n||!r||n==="currentBg")return{invalid:!0,value:n};const i=t(`colors.${n}`),o=(l=t.raw(`opacity.${r}`))==null?void 0:l.value;if(!o&&isNaN(Number(r)))return{invalid:!0,value:n};const s=o?Number(o)*100+"%":`${r}%`,a=i??n;return{invalid:!1,color:a,value:`color-mix(in srgb, ${a} ${s}, transparent)`}},ae=e=>(t,n)=>{const r=n.utils.colorMix(t);if(r.invalid)return{[e]:t};const i="--mix-"+e;return{[i]:r.value,[e]:`var(${i}, ${r.color})`}};function vl(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(n=>vl(n));const t=Object.create(Object.getPrototypeOf(e));for(const n of Object.keys(e))t[n]=vl(e[n]);return t}function bl(e,t){if(t==null)return e;for(const n of Object.keys(t))if(!(t[n]===void 0||n==="__proto__"))if(!He(e[n])&&He(t[n]))Object.assign(e,{[n]:t[n]});else if(e[n]&&He(t[n]))bl(e[n],t[n]);else if(Array.isArray(t[n])&&Array.isArray(e[n])){let r=0;for(;re!=null;function At(e,t,n={}){const{stop:r,getKey:i}=n;function o(s,a=[]){if(He(s)||Array.isArray(s)){const l={};for(const[c,u]of Object.entries(s)){const d=(i==null?void 0:i(c,u))??c,h=[...a,d];if(r!=null&&r(s,h))return t(s,a);const m=o(u,h);yl(m)&&(l[d]=m)}return l}return t(s,a)}return o(e)}function sf(e,t){return Array.isArray(e)?e.map(n=>yl(n)?t(n):n):He(e)?At(e,n=>t(n)):yl(e)?t(e):e}const os=["value","type","description"],WE=e=>e&&typeof e=="object"&&!Array.isArray(e),af=(...e)=>{var n;const t=Or({},...e.map(vl));return(n=t.theme)!=null&&n.tokens&&At(t.theme.tokens,r=>{const s=Object.keys(r).filter(l=>!os.includes(l)).length>0,a=os.some(l=>r[l]!=null);return s&&a&&(r.DEFAULT||(r.DEFAULT={}),os.forEach(l=>{var c;r[l]!=null&&((c=r.DEFAULT)[l]||(c[l]=r[l]),delete r[l])})),r},{stop(r){return WE(r)&&Object.keys(r).some(i=>os.includes(i)||i!==i.toLowerCase()&&i!==i.toUpperCase())}}),t},HE=e=>e,Se=e=>e,q=e=>e,UE=e=>e,GE=e=>e,Ir=e=>e,qE=e=>e,KE=e=>e,XE=e=>e;function lf(){const e=t=>t;return new Proxy(e,{get(){return e}})}const xe=lf(),xl=lf(),Cl=e=>e,YE=/[^a-zA-Z0-9_\u0081-\uffff-]/g;function QE(e){return`${e}`.replace(YE,t=>`\\${t}`)}const JE=/[A-Z]/g;function ZE(e){return e.replace(JE,t=>`-${t.toLowerCase()}`)}function cf(e,t={}){const{fallback:n="",prefix:r=""}=t,i=ZE(["-",r,QE(e)].filter(Boolean).join("-"));return{var:i,ref:`var(${i}${n?`, ${n}`:""})`}}const ek=e=>/^var\(--.+\)$/.test(e),Re=(e,t)=>t!=null?`${e}(${t})`:t,$n=e=>{if(ek(e)||e==null)return e;const t=typeof e=="string"&&!e.endsWith("deg");return typeof e=="number"||t?`${e}deg`:e},uf=e=>({values:["outside","inside","mixed","none"],transform(t,{token:n}){const r=n("colors.colorPalette.focusRing");return{inside:{"--focus-ring-color":r,[e]:{outlineOffset:"0px",outlineWidth:"var(--focus-ring-width, 1px)",outlineColor:"var(--focus-ring-color)",outlineStyle:"var(--focus-ring-style, solid)",borderColor:"var(--focus-ring-color)"}},outside:{"--focus-ring-color":r,[e]:{outlineWidth:"var(--focus-ring-width, 2px)",outlineOffset:"var(--focus-ring-offset, 2px)",outlineStyle:"var(--focus-ring-style, solid)",outlineColor:"var(--focus-ring-color)"}},mixed:{"--focus-ring-color":r,[e]:{outlineWidth:"var(--focus-ring-width, 3px)",outlineStyle:"var(--focus-ring-style, solid)",outlineColor:"color-mix(in srgb, var(--focus-ring-color), transparent 60%)",borderColor:"var(--focus-ring-color)"}},none:{"--focus-ring-color":r,[e]:{outline:"none"}}}[t]??{}}}),tk=ae("borderColor"),jt=e=>({transition:e,transitionTimingFunction:"cubic-bezier(0.4, 0, 0.2, 1)",transitionDuration:"150ms"}),nk=HE({hover:["@media (hover: hover)","&:is(:hover, [data-hover]):not(:disabled, [data-disabled])"],active:"&:is(:active, [data-active]):not(:disabled, [data-disabled], [data-state=open])",focus:"&:is(:focus, [data-focus])",focusWithin:"&:is(:focus-within, [data-focus-within])",focusVisible:"&:is(:focus-visible, [data-focus-visible])",disabled:"&:is(:disabled, [disabled], [data-disabled], [aria-disabled=true])",visited:"&:visited",target:"&:target",readOnly:"&:is([data-readonly], [aria-readonly=true], [readonly])",readWrite:"&:read-write",empty:"&:is(:empty, [data-empty])",checked:"&:is(:checked, [data-checked], [aria-checked=true], [data-state=checked])",enabled:"&:enabled",expanded:"&:is([aria-expanded=true], [data-expanded], [data-state=expanded])",highlighted:"&[data-highlighted]",complete:"&[data-complete]",incomplete:"&[data-incomplete]",dragging:"&[data-dragging]",before:"&::before",after:"&::after",firstLetter:"&::first-letter",firstLine:"&::first-line",marker:"&::marker",selection:"&::selection",file:"&::file-selector-button",backdrop:"&::backdrop",first:"&:first-of-type",last:"&:last-of-type",notFirst:"&:not(:first-of-type)",notLast:"&:not(:last-of-type)",only:"&:only-child",even:"&:nth-of-type(even)",odd:"&:nth-of-type(odd)",peerFocus:".peer:is(:focus, [data-focus]) ~ &",peerHover:".peer:is(:hover, [data-hover]):not(:disabled, [data-disabled]) ~ &",peerActive:".peer:is(:active, [data-active]):not(:disabled, [data-disabled]) ~ &",peerFocusWithin:".peer:focus-within ~ &",peerFocusVisible:".peer:is(:focus-visible, [data-focus-visible]) ~ &",peerDisabled:".peer:is(:disabled, [disabled], [data-disabled]) ~ &",peerChecked:".peer:is(:checked, [data-checked], [aria-checked=true], [data-state=checked]) ~ &",peerInvalid:".peer:is(:invalid, [data-invalid], [aria-invalid=true]) ~ &",peerExpanded:".peer:is([aria-expanded=true], [data-expanded], [data-state=expanded]) ~ &",peerPlaceholderShown:".peer:placeholder-shown ~ &",groupFocus:".group:is(:focus, [data-focus]) &",groupHover:".group:is(:hover, [data-hover]):not(:disabled, [data-disabled]) &",groupActive:".group:is(:active, [data-active]):not(:disabled, [data-disabled]) &",groupFocusWithin:".group:focus-within &",groupFocusVisible:".group:is(:focus-visible, [data-focus-visible]) &",groupDisabled:".group:is(:disabled, [disabled], [data-disabled]) &",groupChecked:".group:is(:checked, [data-checked], [aria-checked=true], [data-state=checked]) &",groupExpanded:".group:is([aria-expanded=true], [data-expanded], [data-state=expanded]) &",groupInvalid:".group:invalid &",indeterminate:"&:is(:indeterminate, [data-indeterminate], [aria-checked=mixed], [data-state=indeterminate])",required:"&:is([data-required], [aria-required=true])",valid:"&:is([data-valid], [data-state=valid])",invalid:"&:is([data-invalid], [aria-invalid=true], [data-state=invalid])",autofill:"&:autofill",inRange:"&:is(:in-range, [data-in-range])",outOfRange:"&:is(:out-of-range, [data-outside-range])",placeholder:"&::placeholder, &[data-placeholder]",placeholderShown:"&:is(:placeholder-shown, [data-placeholder-shown])",pressed:"&:is([aria-pressed=true], [data-pressed])",selected:"&:is([aria-selected=true], [data-selected])",grabbed:"&:is([aria-grabbed=true], [data-grabbed])",underValue:"&[data-state=under-value]",overValue:"&[data-state=over-value]",atValue:"&[data-state=at-value]",default:"&:default",optional:"&:optional",open:"&:is([open], [data-open], [data-state=open])",closed:"&:is([closed], [data-closed], [data-state=closed])",fullscreen:"&:is(:fullscreen, [data-fullscreen])",loading:"&:is([data-loading], [aria-busy=true])",hidden:"&:is([hidden], [data-hidden])",current:"&[data-current]",currentPage:"&[aria-current=page]",currentStep:"&[aria-current=step]",today:"&[data-today]",unavailable:"&[data-unavailable]",rangeStart:"&[data-range-start]",rangeEnd:"&[data-range-end]",now:"&[data-now]",topmost:"&[data-topmost]",motionReduce:"@media (prefers-reduced-motion: reduce)",motionSafe:"@media (prefers-reduced-motion: no-preference)",print:"@media print",landscape:"@media (orientation: landscape)",portrait:"@media (orientation: portrait)",dark:".dark &, .dark .chakra-theme:not(.light) &",light:":root &, .light &",osDark:"@media (prefers-color-scheme: dark)",osLight:"@media (prefers-color-scheme: light)",highContrast:"@media (forced-colors: active)",lessContrast:"@media (prefers-contrast: less)",moreContrast:"@media (prefers-contrast: more)",ltr:"[dir=ltr] &",rtl:"[dir=rtl] &",scrollbar:"&::-webkit-scrollbar",scrollbarThumb:"&::-webkit-scrollbar-thumb",scrollbarTrack:"&::-webkit-scrollbar-track",horizontal:"&[data-orientation=horizontal]",vertical:"&[data-orientation=vertical]",icon:"& :where(svg)",starting:"@starting-style"}),Pr=cf("bg-currentcolor"),df=e=>e===Pr.ref||e==="currentBg",le=e=>({...e("colors"),currentBg:Pr}),rk=Cl({conditions:nk,utilities:{background:{values:le,shorthand:["bg"],transform(e,t){if(df(t.raw))return{background:Pr.ref};const n=ae("background")(e,t);return{...n,[Pr.var]:n==null?void 0:n.background}}},backgroundColor:{values:le,shorthand:["bgColor"],transform(e,t){if(df(t.raw))return{backgroundColor:Pr.ref};const n=ae("backgroundColor")(e,t);return{...n,[Pr.var]:n==null?void 0:n.backgroundColor}}},backgroundSize:{shorthand:["bgSize"]},backgroundPosition:{shorthand:["bgPos"]},backgroundRepeat:{shorthand:["bgRepeat"]},backgroundAttachment:{shorthand:["bgAttachment"]},backgroundClip:{shorthand:["bgClip"],values:["text"],transform(e){return e==="text"?{color:"transparent",backgroundClip:"text"}:{backgroundClip:e}}},backgroundGradient:{shorthand:["bgGradient"],values(e){return{...e("gradients"),"to-t":"linear-gradient(to top, var(--gradient))","to-tr":"linear-gradient(to top right, var(--gradient))","to-r":"linear-gradient(to right, var(--gradient))","to-br":"linear-gradient(to bottom right, var(--gradient))","to-b":"linear-gradient(to bottom, var(--gradient))","to-bl":"linear-gradient(to bottom left, var(--gradient))","to-l":"linear-gradient(to left, var(--gradient))","to-tl":"linear-gradient(to top left, var(--gradient))"}},transform(e){return{"--gradient-stops":"var(--gradient-from), var(--gradient-to)","--gradient":"var(--gradient-via-stops, var(--gradient-stops))",backgroundImage:e}}},gradientFrom:{values:le,transform:ae("--gradient-from")},gradientTo:{values:le,transform:ae("--gradient-to")},gradientVia:{values:le,transform(e,t){return{...ae("--gradient-via")(e,t),"--gradient-via-stops":"var(--gradient-from), var(--gradient-via), var(--gradient-to)"}}},backgroundImage:{values(e){return{...e("gradients"),...e("assets")}},shorthand:["bgImg","bgImage"]},border:{values:"borders"},borderTop:{values:"borders"},borderLeft:{values:"borders"},borderBlockStart:{values:"borders"},borderRight:{values:"borders"},borderBottom:{values:"borders"},borderBlockEnd:{values:"borders"},borderInlineStart:{values:"borders",shorthand:["borderStart"]},borderInlineEnd:{values:"borders",shorthand:["borderEnd"]},borderInline:{values:"borders",shorthand:["borderX"]},borderBlock:{values:"borders",shorthand:["borderY"]},borderColor:{values:le,transform:ae("borderColor")},borderTopColor:{values:le,transform:ae("borderTopColor")},borderBlockStartColor:{values:le,transform:ae("borderBlockStartColor")},borderBottomColor:{values:le,transform:ae("borderBottomColor")},borderBlockEndColor:{values:le,transform:ae("borderBlockEndColor")},borderLeftColor:{values:le,transform:ae("borderLeftColor")},borderInlineStartColor:{values:le,shorthand:["borderStartColor"],transform:ae("borderInlineStartColor")},borderRightColor:{values:le,transform:ae("borderRightColor")},borderInlineEndColor:{values:le,shorthand:["borderEndColor"],transform:ae("borderInlineEndColor")},borderStyle:{values:"borderStyles"},borderTopStyle:{values:"borderStyles"},borderBlockStartStyle:{values:"borderStyles"},borderBottomStyle:{values:"borderStyles"},borderBlockEndStyle:{values:"borderStyles"},borderInlineStartStyle:{values:"borderStyles",shorthand:["borderStartStyle"]},borderInlineEndStyle:{values:"borderStyles",shorthand:["borderEndStyle"]},borderLeftStyle:{values:"borderStyles"},borderRightStyle:{values:"borderStyles"},borderRadius:{values:"radii",shorthand:["rounded"]},borderTopLeftRadius:{values:"radii",shorthand:["roundedTopLeft"]},borderStartStartRadius:{values:"radii",shorthand:["roundedStartStart","borderTopStartRadius"]},borderEndStartRadius:{values:"radii",shorthand:["roundedEndStart","borderBottomStartRadius"]},borderTopRightRadius:{values:"radii",shorthand:["roundedTopRight"]},borderStartEndRadius:{values:"radii",shorthand:["roundedStartEnd","borderTopEndRadius"]},borderEndEndRadius:{values:"radii",shorthand:["roundedEndEnd","borderBottomEndRadius"]},borderBottomLeftRadius:{values:"radii",shorthand:["roundedBottomLeft"]},borderBottomRightRadius:{values:"radii",shorthand:["roundedBottomRight"]},borderInlineStartRadius:{values:"radii",property:"borderRadius",shorthand:["roundedStart","borderStartRadius"],transform:e=>({borderStartStartRadius:e,borderEndStartRadius:e})},borderInlineEndRadius:{values:"radii",property:"borderRadius",shorthand:["roundedEnd","borderEndRadius"],transform:e=>({borderStartEndRadius:e,borderEndEndRadius:e})},borderTopRadius:{values:"radii",property:"borderRadius",shorthand:["roundedTop"],transform:e=>({borderTopLeftRadius:e,borderTopRightRadius:e})},borderBottomRadius:{values:"radii",property:"borderRadius",shorthand:["roundedBottom"],transform:e=>({borderBottomLeftRadius:e,borderBottomRightRadius:e})},borderLeftRadius:{values:"radii",property:"borderRadius",shorthand:["roundedLeft"],transform:e=>({borderTopLeftRadius:e,borderBottomLeftRadius:e})},borderRightRadius:{values:"radii",property:"borderRadius",shorthand:["roundedRight"],transform:e=>({borderTopRightRadius:e,borderBottomRightRadius:e})},borderWidth:{values:"borderWidths"},borderBlockStartWidth:{values:"borderWidths"},borderTopWidth:{values:"borderWidths"},borderBottomWidth:{values:"borderWidths"},borderBlockEndWidth:{values:"borderWidths"},borderRightWidth:{values:"borderWidths"},borderInlineWidth:{values:"borderWidths",shorthand:["borderXWidth"]},borderInlineStartWidth:{values:"borderWidths",shorthand:["borderStartWidth"]},borderInlineEndWidth:{values:"borderWidths",shorthand:["borderEndWidth"]},borderLeftWidth:{values:"borderWidths"},borderBlockWidth:{values:"borderWidths",shorthand:["borderYWidth"]},color:{values:le,transform:ae("color")},fill:{values:le,transform:ae("fill")},stroke:{values:le,transform:ae("stroke")},accentColor:{values:le,transform:ae("accentColor")},divideX:{values:{type:"string"},transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{borderInlineStartWidth:e,borderInlineEndWidth:"0px"}}}},divideY:{values:{type:"string"},transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{borderTopWidth:e,borderBottomWidth:"0px"}}}},divideColor:{values:le,transform(e,t){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":tk(e,t)}}},divideStyle:{property:"borderStyle",transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{borderStyle:e}}}},boxShadow:{values:"shadows",shorthand:["shadow"]},boxShadowColor:{values:le,transform:ae("--shadow-color"),shorthand:["shadowColor"]},mixBlendMode:{shorthand:["blendMode"]},backgroundBlendMode:{shorthand:["bgBlendMode"]},opacity:{values:"opacity"},filter:{transform(e){return e!=="auto"?{filter:e}:{filter:"var(--blur) var(--brightness) var(--contrast) var(--grayscale) var(--hue-rotate) var(--invert) var(--saturate) var(--sepia) var(--drop-shadow)"}}},blur:{values:"blurs",transform:e=>({"--blur":Re("blur",e)})},brightness:{transform:e=>({"--brightness":Re("brightness",e)})},contrast:{transform:e=>({"--contrast":Re("contrast",e)})},grayscale:{transform:e=>({"--grayscale":Re("grayscale",e)})},hueRotate:{transform:e=>({"--hue-rotate":Re("hue-rotate",$n(e))})},invert:{transform:e=>({"--invert":Re("invert",e)})},saturate:{transform:e=>({"--saturate":Re("saturate",e)})},sepia:{transform:e=>({"--sepia":Re("sepia",e)})},dropShadow:{transform:e=>({"--drop-shadow":Re("drop-shadow",e)})},backdropFilter:{transform(e){return e!=="auto"?{backdropFilter:e}:{backdropFilter:"var(--backdrop-blur) var(--backdrop-brightness) var(--backdrop-contrast) var(--backdrop-grayscale) var(--backdrop-hue-rotate) var(--backdrop-invert) var(--backdrop-opacity) var(--backdrop-saturate) var(--backdrop-sepia)"}}},backdropBlur:{values:"blurs",transform:e=>({"--backdrop-blur":Re("blur",e)})},backdropBrightness:{transform:e=>({"--backdrop-brightness":Re("brightness",e)})},backdropContrast:{transform:e=>({"--backdrop-contrast":Re("contrast",e)})},backdropGrayscale:{transform:e=>({"--backdrop-grayscale":Re("grayscale",e)})},backdropHueRotate:{transform:e=>({"--backdrop-hue-rotate":Re("hue-rotate",$n(e))})},backdropInvert:{transform:e=>({"--backdrop-invert":Re("invert",e)})},backdropOpacity:{transform:e=>({"--backdrop-opacity":Re("opacity",e)})},backdropSaturate:{transform:e=>({"--backdrop-saturate":Re("saturate",e)})},backdropSepia:{transform:e=>({"--backdrop-sepia":Re("sepia",e)})},flexBasis:{values:"sizes"},gap:{values:"spacing"},rowGap:{values:"spacing",shorthand:["gapY"]},columnGap:{values:"spacing",shorthand:["gapX"]},flexDirection:{shorthand:["flexDir"]},gridGap:{values:"spacing"},gridColumnGap:{values:"spacing"},gridRowGap:{values:"spacing"},outlineColor:{values:le,transform:ae("outlineColor")},focusRing:uf("&:is(:focus, [data-focus])"),focusVisibleRing:uf("&:is(:focus-visible, [data-focus-visible])"),focusRingColor:{values:le,transform:ae("--focus-ring-color")},focusRingOffset:{values:"spacing",transform:e=>({"--focus-ring-offset":e})},focusRingWidth:{values:"borderWidths",property:"outlineWidth",transform:e=>({"--focus-ring-width":e})},focusRingStyle:{values:"borderStyles",property:"outlineStyle",transform:e=>({"--focus-ring-style":e})},aspectRatio:{values:"aspectRatios"},width:{values:"sizes",shorthand:["w"]},inlineSize:{values:"sizes"},height:{values:"sizes",shorthand:["h"]},blockSize:{values:"sizes"},boxSize:{values:"sizes",property:"width",transform:e=>({width:e,height:e})},minWidth:{values:"sizes",shorthand:["minW"]},minInlineSize:{values:"sizes"},minHeight:{values:"sizes",shorthand:["minH"]},minBlockSize:{values:"sizes"},maxWidth:{values:"sizes",shorthand:["maxW"]},maxInlineSize:{values:"sizes"},maxHeight:{values:"sizes",shorthand:["maxH"]},maxBlockSize:{values:"sizes"},hideFrom:{values:"breakpoints",transform:(e,{raw:t,token:n})=>({[n.raw(`breakpoints.${t}`)?`@breakpoint ${t}`:`@media screen and (min-width: ${e})`]:{display:"none"}})},hideBelow:{values:"breakpoints",transform(e,{raw:t,token:n}){return{[n.raw(`breakpoints.${t}`)?`@breakpoint ${t}Down`:`@media screen and (max-width: ${e})`]:{display:"none"}}}},overscrollBehavior:{shorthand:["overscroll"]},overscrollBehaviorX:{shorthand:["overscrollX"]},overscrollBehaviorY:{shorthand:["overscrollY"]},scrollbar:{values:["visible","hidden"],transform(e){switch(e){case"visible":return{msOverflowStyle:"auto",scrollbarWidth:"auto","&::-webkit-scrollbar":{display:"block"}};case"hidden":return{msOverflowStyle:"none",scrollbarWidth:"none","&::-webkit-scrollbar":{display:"none"}};default:return{}}}},scrollbarColor:{values:le,transform:ae("scrollbarColor")},scrollbarGutter:{values:"spacing"},scrollbarWidth:{values:"sizes"},scrollMargin:{values:"spacing"},scrollMarginTop:{values:"spacing"},scrollMarginBottom:{values:"spacing"},scrollMarginLeft:{values:"spacing"},scrollMarginRight:{values:"spacing"},scrollMarginX:{values:"spacing",transform:e=>({scrollMarginLeft:e,scrollMarginRight:e})},scrollMarginY:{values:"spacing",transform:e=>({scrollMarginTop:e,scrollMarginBottom:e})},scrollPadding:{values:"spacing"},scrollPaddingTop:{values:"spacing"},scrollPaddingBottom:{values:"spacing"},scrollPaddingLeft:{values:"spacing"},scrollPaddingRight:{values:"spacing"},scrollPaddingInline:{values:"spacing",shorthand:["scrollPaddingX"]},scrollPaddingBlock:{values:"spacing",shorthand:["scrollPaddingY"]},scrollSnapType:{values:{none:"none",x:"x var(--scroll-snap-strictness)",y:"y var(--scroll-snap-strictness)",both:"both var(--scroll-snap-strictness)"}},scrollSnapStrictness:{values:["mandatory","proximity"],transform:e=>({"--scroll-snap-strictness":e})},scrollSnapMargin:{values:"spacing"},scrollSnapMarginTop:{values:"spacing"},scrollSnapMarginBottom:{values:"spacing"},scrollSnapMarginLeft:{values:"spacing"},scrollSnapMarginRight:{values:"spacing"},listStylePosition:{shorthand:["listStylePos"]},listStyleImage:{values:"assets",shorthand:["listStyleImg"]},position:{shorthand:["pos"]},zIndex:{values:"zIndex"},inset:{values:"spacing"},insetInline:{values:"spacing",shorthand:["insetX"]},insetBlock:{values:"spacing",shorthand:["insetY"]},top:{values:"spacing"},insetBlockStart:{values:"spacing"},bottom:{values:"spacing"},insetBlockEnd:{values:"spacing"},left:{values:"spacing"},right:{values:"spacing"},insetInlineStart:{values:"spacing",shorthand:["insetStart"]},insetInlineEnd:{values:"spacing",shorthand:["insetEnd"]},ring:{transform(e){return{"--ring-offset-shadow":"var(--ring-inset) 0 0 0 var(--ring-offset-width) var(--ring-offset-color)","--ring-shadow":"var(--ring-inset) 0 0 0 calc(var(--ring-width) + var(--ring-offset-width)) var(--ring-color)","--ring-width":e,boxShadow:"var(--ring-offset-shadow), var(--ring-shadow), var(--shadow, 0 0 #0000)"}}},ringColor:{values:le,transform:ae("--ring-color")},ringOffset:{transform:e=>({"--ring-offset-width":e})},ringOffsetColor:{values:le,transform:ae("--ring-offset-color")},ringInset:{transform:e=>({"--ring-inset":e})},margin:{values:"spacing",shorthand:["m"]},marginTop:{values:"spacing",shorthand:["mt"]},marginBlockStart:{values:"spacing"},marginRight:{values:"spacing",shorthand:["mr"]},marginBottom:{values:"spacing",shorthand:["mb"]},marginBlockEnd:{values:"spacing"},marginLeft:{values:"spacing",shorthand:["ml"]},marginInlineStart:{values:"spacing",shorthand:["ms","marginStart"]},marginInlineEnd:{values:"spacing",shorthand:["me","marginEnd"]},marginInline:{values:"spacing",shorthand:["mx","marginX"]},marginBlock:{values:"spacing",shorthand:["my","marginY"]},padding:{values:"spacing",shorthand:["p"]},paddingTop:{values:"spacing",shorthand:["pt"]},paddingRight:{values:"spacing",shorthand:["pr"]},paddingBottom:{values:"spacing",shorthand:["pb"]},paddingBlockStart:{values:"spacing"},paddingBlockEnd:{values:"spacing"},paddingLeft:{values:"spacing",shorthand:["pl"]},paddingInlineStart:{values:"spacing",shorthand:["ps","paddingStart"]},paddingInlineEnd:{values:"spacing",shorthand:["pe","paddingEnd"]},paddingInline:{values:"spacing",shorthand:["px","paddingX"]},paddingBlock:{values:"spacing",shorthand:["py","paddingY"]},textDecoration:{shorthand:["textDecor"]},textDecorationColor:{values:le,transform:ae("textDecorationColor")},textShadow:{values:"shadows"},transform:{transform:e=>{let t=e;return e==="auto"&&(t="translateX(var(--translate-x, 0)) translateY(var(--translate-y, 0)) rotate(var(--rotate, 0)) scaleX(var(--scale-x, 1)) scaleY(var(--scale-y, 1)) skewX(var(--skew-x, 0)) skewY(var(--skew-y, 0))"),e==="auto-gpu"&&(t="translate3d(var(--translate-x, 0), var(--translate-y, 0), 0) rotate(var(--rotate, 0)) scaleX(var(--scale-x, 1)) scaleY(var(--scale-y, 1)) skewX(var(--skew-x, 0)) skewY(var(--skew-y, 0))"),{transform:t}}},skewX:{transform:e=>({"--skew-x":$n(e)})},skewY:{transform:e=>({"--skew-y":$n(e)})},scaleX:{transform:e=>({"--scale-x":e})},scaleY:{transform:e=>({"--scale-y":e})},scale:{transform(e){return e!=="auto"?{scale:e}:{scale:"var(--scale-x, 1) var(--scale-y, 1)"}}},spaceXReverse:{values:{type:"boolean"},transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{"--space-x-reverse":e?"1":void 0}}}},spaceX:{property:"marginInlineStart",values:"spacing",transform:e=>({"& > :not(style, [hidden]) ~ :not(style, [hidden])":{"--space-x-reverse":"0",marginInlineStart:`calc(${e} * calc(1 - var(--space-x-reverse)))`,marginInlineEnd:`calc(${e} * var(--space-x-reverse))`}})},spaceYReverse:{values:{type:"boolean"},transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{"--space-y-reverse":e?"1":void 0}}}},spaceY:{property:"marginTop",values:"spacing",transform:e=>({"& > :not(style, [hidden]) ~ :not(style, [hidden])":{"--space-y-reverse":"0",marginTop:`calc(${e} * calc(1 - var(--space-y-reverse)))`,marginBottom:`calc(${e} * var(--space-y-reverse))`}})},rotate:{transform(e){return e!=="auto"?{rotate:$n(e)}:{rotate:"var(--rotate-x, 0) var(--rotate-y, 0) var(--rotate-z, 0)"}}},rotateX:{transform(e){return{"--rotate-x":$n(e)}}},rotateY:{transform(e){return{"--rotate-y":$n(e)}}},translate:{transform(e){return e!=="auto"?{translate:e}:{translate:"var(--translate-x) var(--translate-y)"}}},translateX:{values:"spacing",transform:e=>({"--translate-x":e})},translateY:{values:"spacing",transform:e=>({"--translate-y":e})},transition:{values:["all","common","colors","opacity","position","backgrounds","size","shadow","transform"],transform(e){switch(e){case"all":return jt("all");case"position":return jt("left, right, top, bottom, inset-inline, inset-block");case"colors":return jt("color, background-color, border-color, text-decoration-color, fill, stroke");case"opacity":return jt("opacity");case"shadow":return jt("box-shadow");case"transform":return jt("transform");case"size":return jt("width, height");case"backgrounds":return jt("background, background-color, background-image, background-position");case"common":return jt("color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter");default:return{transition:e}}}},transitionDuration:{values:"durations"},transitionProperty:{values:{common:"background-color, border-color, color, fill, stroke, opacity, box-shadow, translate, transform",colors:"background-color, border-color, color, fill, stroke",size:"width, height",position:"left, right, top, bottom, inset-inline, inset-block",background:"background, background-color, background-image, background-position"}},transitionTimingFunction:{values:"easings"},animation:{values:"animations"},animationDuration:{values:"durations"},animationDelay:{values:"durations"},animationTimingFunction:{values:"easings"},fontFamily:{values:"fonts"},fontSize:{values:"fontSizes"},fontWeight:{values:"fontWeights"},lineHeight:{values:"lineHeights"},letterSpacing:{values:"letterSpacings"},textIndent:{values:"spacing"},truncate:{values:{type:"boolean"},transform(e){return e===!0?{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}:{}}},lineClamp:{transform(e){return e==="none"?{WebkitLineClamp:"unset"}:{overflow:"hidden",display:"-webkit-box",WebkitLineClamp:e,WebkitBoxOrient:"vertical",textWrap:"wrap"}}},borderSpacing:{values:e=>({...e("spacing"),auto:"var(--border-spacing-x, 0) var(--border-spacing-y, 0)"})},borderSpacingX:{values:"spacing",transform(e){return{"--border-spacing-x":e}}},borderSpacingY:{values:"spacing",transform(e){return{"--border-spacing-y":e}}},srOnly:{values:{type:"boolean"},transform(e){return ik[e]||{}}},debug:{values:{type:"boolean"},transform(e){return e?{outline:"1px solid blue !important","& > *":{outline:"1px solid red !important"}}:{}}},caretColor:{values:le,transform:ae("caretColor")},cursor:{values:"cursor"}}}),ik={true:{position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"},false:{position:"static",width:"auto",height:"auto",padding:"0",margin:"0",overflow:"visible",clip:"auto",whiteSpace:"normal"}};var ok="",sk=ok.split(","),ak="WebkitAppearance,WebkitBorderBefore,WebkitBorderBeforeColor,WebkitBorderBeforeStyle,WebkitBorderBeforeWidth,WebkitBoxReflect,WebkitLineClamp,WebkitMask,WebkitMaskAttachment,WebkitMaskClip,WebkitMaskComposite,WebkitMaskImage,WebkitMaskOrigin,WebkitMaskPosition,WebkitMaskPositionX,WebkitMaskPositionY,WebkitMaskRepeat,WebkitMaskRepeatX,WebkitMaskRepeatY,WebkitMaskSize,WebkitOverflowScrolling,WebkitTapHighlightColor,WebkitTextFillColor,WebkitTextStroke,WebkitTextStrokeColor,WebkitTextStrokeWidth,WebkitTouchCallout,WebkitUserModify,WebkitUserSelect,accentColor,alignContent,alignItems,alignSelf,alignTracks,all,anchorName,anchorScope,animation,animationComposition,animationDelay,animationDirection,animationDuration,animationFillMode,animationIterationCount,animationName,animationPlayState,animationRange,animationRangeEnd,animationRangeStart,animationTimeline,animationTimingFunction,appearance,aspectRatio,backdropFilter,backfaceVisibility,background,backgroundAttachment,backgroundBlendMode,backgroundClip,backgroundColor,backgroundImage,backgroundOrigin,backgroundPosition,backgroundPositionX,backgroundPositionY,backgroundRepeat,backgroundSize,blockSize,border,borderBlock,borderBlockColor,borderBlockEnd,borderBlockEndColor,borderBlockEndStyle,borderBlockEndWidth,borderBlockStart,borderBlockStartColor,borderBlockStartStyle,borderBlockStartWidth,borderBlockStyle,borderBlockWidth,borderBottom,borderBottomColor,borderBottomLeftRadius,borderBottomRightRadius,borderBottomStyle,borderBottomWidth,borderCollapse,borderColor,borderEndEndRadius,borderEndStartRadius,borderImage,borderImageOutset,borderImageRepeat,borderImageSlice,borderImageSource,borderImageWidth,borderInline,borderInlineColor,borderInlineEnd,borderInlineEndColor,borderInlineEndStyle,borderInlineEndWidth,borderInlineStart,borderInlineStartColor,borderInlineStartStyle,borderInlineStartWidth,borderInlineStyle,borderInlineWidth,borderLeft,borderLeftColor,borderLeftStyle,borderLeftWidth,borderRadius,borderRight,borderRightColor,borderRightStyle,borderRightWidth,borderSpacing,borderStartEndRadius,borderStartStartRadius,borderStyle,borderTop,borderTopColor,borderTopLeftRadius,borderTopRightRadius,borderTopStyle,borderTopWidth,borderWidth,bottom,boxAlign,boxDecorationBreak,boxDirection,boxFlex,boxFlexGroup,boxLines,boxOrdinalGroup,boxOrient,boxPack,boxShadow,boxSizing,breakAfter,breakBefore,breakInside,captionSide,caret,caretColor,caretShape,clear,clip,clipPath,clipRule,color,colorInterpolationFilters,colorScheme,columnCount,columnFill,columnGap,columnRule,columnRuleColor,columnRuleStyle,columnRuleWidth,columnSpan,columnWidth,columns,contain,containIntrinsicBlockSize,containIntrinsicHeight,containIntrinsicInlineSize,containIntrinsicSize,containIntrinsicWidth,container,containerName,containerType,content,contentVisibility,counterIncrement,counterReset,counterSet,cursor,cx,cy,d,direction,display,dominantBaseline,emptyCells,fieldSizing,fill,fillOpacity,fillRule,filter,flex,flexBasis,flexDirection,flexFlow,flexGrow,flexShrink,flexWrap,float,floodColor,floodOpacity,font,fontFamily,fontFeatureSettings,fontKerning,fontLanguageOverride,fontOpticalSizing,fontPalette,fontSize,fontSizeAdjust,fontSmooth,fontStretch,fontStyle,fontSynthesis,fontSynthesisPosition,fontSynthesisSmallCaps,fontSynthesisStyle,fontSynthesisWeight,fontVariant,fontVariantAlternates,fontVariantCaps,fontVariantEastAsian,fontVariantEmoji,fontVariantLigatures,fontVariantNumeric,fontVariantPosition,fontVariationSettings,fontWeight,forcedColorAdjust,gap,grid,gridArea,gridAutoColumns,gridAutoFlow,gridAutoRows,gridColumn,gridColumnEnd,gridColumnGap,gridColumnStart,gridGap,gridRow,gridRowEnd,gridRowGap,gridRowStart,gridTemplate,gridTemplateAreas,gridTemplateColumns,gridTemplateRows,hangingPunctuation,height,hyphenateCharacter,hyphenateLimitChars,hyphens,imageOrientation,imageRendering,imageResolution,imeMode,initialLetter,initialLetterAlign,inlineSize,inset,insetBlock,insetBlockEnd,insetBlockStart,insetInline,insetInlineEnd,insetInlineStart,interpolateSize,isolation,justifyContent,justifyItems,justifySelf,justifyTracks,left,letterSpacing,lightingColor,lineBreak,lineClamp,lineHeight,lineHeightStep,listStyle,listStyleImage,listStylePosition,listStyleType,margin,marginBlock,marginBlockEnd,marginBlockStart,marginBottom,marginInline,marginInlineEnd,marginInlineStart,marginLeft,marginRight,marginTop,marginTrim,marker,markerEnd,markerMid,markerStart,mask,maskBorder,maskBorderMode,maskBorderOutset,maskBorderRepeat,maskBorderSlice,maskBorderSource,maskBorderWidth,maskClip,maskComposite,maskImage,maskMode,maskOrigin,maskPosition,maskRepeat,maskSize,maskType,masonryAutoFlow,mathDepth,mathShift,mathStyle,maxBlockSize,maxHeight,maxInlineSize,maxLines,maxWidth,minBlockSize,minHeight,minInlineSize,minWidth,mixBlendMode,objectFit,objectPosition,offset,offsetAnchor,offsetDistance,offsetPath,offsetPosition,offsetRotate,opacity,order,orphans,outline,outlineColor,outlineOffset,outlineStyle,outlineWidth,overflow,overflowAnchor,overflowBlock,overflowClipBox,overflowClipMargin,overflowInline,overflowWrap,overflowX,overflowY,overlay,overscrollBehavior,overscrollBehaviorBlock,overscrollBehaviorInline,overscrollBehaviorX,overscrollBehaviorY,padding,paddingBlock,paddingBlockEnd,paddingBlockStart,paddingBottom,paddingInline,paddingInlineEnd,paddingInlineStart,paddingLeft,paddingRight,paddingTop,page,pageBreakAfter,pageBreakBefore,pageBreakInside,paintOrder,perspective,perspectiveOrigin,placeContent,placeItems,placeSelf,pointerEvents,position,positionAnchor,positionArea,positionTry,positionTryFallbacks,positionTryOrder,positionVisibility,printColorAdjust,quotes,r,resize,right,rotate,rowGap,rubyAlign,rubyMerge,rubyPosition,rx,ry,scale,scrollBehavior,scrollMargin,scrollMarginBlock,scrollMarginBlockEnd,scrollMarginBlockStart,scrollMarginBottom,scrollMarginInline,scrollMarginInlineEnd,scrollMarginInlineStart,scrollMarginLeft,scrollMarginRight,scrollMarginTop,scrollPadding,scrollPaddingBlock,scrollPaddingBlockEnd,scrollPaddingBlockStart,scrollPaddingBottom,scrollPaddingInline,scrollPaddingInlineEnd,scrollPaddingInlineStart,scrollPaddingLeft,scrollPaddingRight,scrollPaddingTop,scrollSnapAlign,scrollSnapCoordinate,scrollSnapDestination,scrollSnapPointsX,scrollSnapPointsY,scrollSnapStop,scrollSnapType,scrollSnapTypeX,scrollSnapTypeY,scrollTimeline,scrollTimelineAxis,scrollTimelineName,scrollbarColor,scrollbarGutter,scrollbarWidth,shapeImageThreshold,shapeMargin,shapeOutside,shapeRendering,stopColor,stopOpacity,stroke,strokeDasharray,strokeDashoffset,strokeLinecap,strokeLinejoin,strokeMiterlimit,strokeOpacity,strokeWidth,tabSize,tableLayout,textAlign,textAlignLast,textAnchor,textBox,textBoxEdge,textBoxTrim,textCombineUpright,textDecoration,textDecorationColor,textDecorationLine,textDecorationSkip,textDecorationSkipInk,textDecorationStyle,textDecorationThickness,textEmphasis,textEmphasisColor,textEmphasisPosition,textEmphasisStyle,textIndent,textJustify,textOrientation,textOverflow,textRendering,textShadow,textSizeAdjust,textSpacingTrim,textTransform,textUnderlineOffset,textUnderlinePosition,textWrap,textWrapMode,textWrapStyle,timelineScope,top,touchAction,transform,transformBox,transformOrigin,transformStyle,transition,transitionBehavior,transitionDelay,transitionDuration,transitionProperty,transitionTimingFunction,translate,unicodeBidi,userSelect,vectorEffect,verticalAlign,viewTimeline,viewTimelineAxis,viewTimelineInset,viewTimelineName,viewTransitionName,visibility,whiteSpace,whiteSpaceCollapse,widows,width,willChange,wordBreak,wordSpacing,wordWrap,writingMode,x,y,zIndex,zoom,alignmentBaseline,baselineShift,colorInterpolation,colorRendering,glyphOrientationVertical",lk=ak.split(",").concat(sk),ck=new Map(lk.map(e=>[e,!0]));function uk(e){const t=Object.create(null);return n=>(t[n]===void 0&&(t[n]=e(n)),t[n])}var dk=/&|@/,hk=uk(e=>ck.has(e)||e.startsWith("--")||dk.test(e));function hf(e,t){const n={};return At(e,(r,i)=>{r&&(n[i.join(".")]=r.value)},{stop:t}),n}var fk=Ei;Ei.default=Ei,Ei.stable=pf,Ei.stableStringify=pf;var ss="[...]",ff="[Circular]",Bn=[],jn=[];function gf(){return{depthLimit:Number.MAX_SAFE_INTEGER,edgesLimit:Number.MAX_SAFE_INTEGER}}function Ei(e,t,n,r){typeof r>"u"&&(r=gf()),Sl(e,"",0,[],void 0,0,r);var i;try{jn.length===0?i=JSON.stringify(e,t,n):i=JSON.stringify(e,mf(t),n)}catch{return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]")}finally{for(;Bn.length!==0;){var o=Bn.pop();o.length===4?Object.defineProperty(o[0],o[1],o[3]):o[0][o[1]]=o[2]}}return i}function Rr(e,t,n,r){var i=Object.getOwnPropertyDescriptor(r,n);i.get!==void 0?i.configurable?(Object.defineProperty(r,n,{value:e}),Bn.push([r,n,t,i])):jn.push([t,n,e]):(r[n]=e,Bn.push([r,n,t]))}function Sl(e,t,n,r,i,o,s){o+=1;var a;if(typeof e=="object"&&e!==null){for(a=0;as.depthLimit){Rr(ss,e,t,i);return}if(typeof s.edgesLimit<"u"&&n+1>s.edgesLimit){Rr(ss,e,t,i);return}if(r.push(e),Array.isArray(e))for(a=0;at?1:0}function pf(e,t,n,r){typeof r>"u"&&(r=gf());var i=wl(e,"",0,[],void 0,0,r)||e,o;try{jn.length===0?o=JSON.stringify(i,t,n):o=JSON.stringify(i,mf(t),n)}catch{return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]")}finally{for(;Bn.length!==0;){var s=Bn.pop();s.length===4?Object.defineProperty(s[0],s[1],s[3]):s[0][s[1]]=s[2]}}return o}function wl(e,t,n,r,i,o,s){o+=1;var a;if(typeof e=="object"&&e!==null){for(a=0;as.depthLimit){Rr(ss,e,t,i);return}if(typeof s.edgesLimit<"u"&&n+1>s.edgesLimit){Rr(ss,e,t,i);return}if(r.push(e),Array.isArray(e))for(a=0;a0)for(var r=0;r{const t=Object.create(null);function n(...r){const i=r.map(o=>pk(o)).join("|");return t[i]===void 0&&(t[i]=e(...r)),t[i]}return n},vf=16,as="px",El="em",ki="rem";function bf(e=""){const t=new RegExp(String.raw`-?\d+(?:\.\d+|\d*)`),n=new RegExp(`${as}|${El}|${ki}`),r=e.match(new RegExp(`${t.source}(${n.source})`));return r==null?void 0:r[1]}function yf(e=""){if(typeof e=="number")return`${e}px`;const t=bf(e);if(!t||t===as)return e;if(t===El||t===ki)return`${parseFloat(e)*vf}${as}`}function xf(e=""){const t=bf(e);if(!t||t===ki)return e;if(t===El)return`${parseFloat(e)}${ki}`;if(t===as)return`${parseFloat(e)/vf}${ki}`}const mk=e=>e.charAt(0).toUpperCase()+e.slice(1);function vk(e){const t=bk(e),n=Object.fromEntries(t);function r(h){return n[h]}function i(h){return Tr(r(h))}function o(){const h=Object.keys(n),m=yk(h),f=h.flatMap(g=>{const p=r(g),v=[`${g}Down`,Tr({max:ls(p.min)})],x=[g,Tr({min:p.min})],S=[`${g}Only`,i(g)];return[x,S,v]}).filter(([,g])=>g!=="").concat(m.map(([g,p])=>{const v=r(g),x=r(p);return[`${g}To${mk(p)}`,Tr({min:v.min,max:ls(x.min)})]}));return Object.fromEntries(f)}function s(){const h=o();return Object.fromEntries(Object.entries(h))}const a=s(),l=h=>a[h];function c(){return["base",...Object.keys(n)]}function u(h){return Tr({min:r(h).min})}function d(h){return Tr({max:ls(r(h).min)})}return{values:Object.values(n),only:i,keys:c,conditions:a,getCondition:l,up:u,down:d}}function ls(e){const t=parseFloat(yf(e)??"")-.04;return xf(`${t}px`)}function bk(e){return Object.entries(e).sort(([,n],[,r])=>parseInt(n,10){var a;let s=null;return i<=o.length-1&&(s=(a=o[i+1])==null?void 0:a[1]),s!=null&&(s=ls(s)),[n,{name:n,min:xf(r),max:s}]})}function yk(e){const t=[];return e.forEach((n,r)=>{let i=r;i++;let o=e[i];for(;o;)t.push([n,o]),i++,o=e[i]}),t}function Tr({min:e,max:t}){return e==null&&t==null?"":["@media screen",e&&`(min-width: ${e})`,t&&`(max-width: ${t})`].filter(Boolean).join(" and ")}const xk=(e,t)=>Object.fromEntries(Object.entries(e).map(([n,r])=>t(n,r))),Ck=e=>{const{breakpoints:t,conditions:n={}}=e,r=xk(n,(u,d)=>[`_${u}`,d]),i=Object.assign({},r,t.conditions);function o(){return Object.keys(i)}function s(u){return o().includes(u)||/^@|&|&$/.test(u)||u.startsWith("_")}function a(u){return u.filter(d=>d!=="base").sort((d,h)=>{const m=s(d),f=s(h);return m&&!f?1:!m&&f?-1:0})}function l(u){return u.startsWith("@breakpoint")?t.getCondition(u.replace("@breakpoint ","")):u}function c(u){return Reflect.get(i,u)||u}return{keys:o,sort:a,has:s,resolve:c,breakpoints:t.keys(),expandAtRule:l}},Cf=e=>({minMax:new RegExp(`(!?\\(\\s*min(-device-)?-${e})(.| + `,n.body.appendChild(r)};function bE(e,t){if(!(!e||!t.isActiveElement(e)))try{const{selectionStart:n,selectionEnd:r,value:i}=e,o=i.substring(0,n),s=i.substring(r);return{start:n,end:r,value:i,beforeTxt:o,afterTxt:s}}catch{}}function yE(e,t,n){if(!(!e||!n.isActiveElement(e))){if(!t){e.setSelectionRange(e.value.length,e.value.length);return}try{const{value:r}=e,{beforeTxt:i="",afterTxt:o="",start:s}=t;let a=r.length;if(r.endsWith(o))a=r.length-o.length;else if(r.startsWith(i))a=i.length;else if(s!=null){const l=i[s-1],c=r.indexOf(l,s-1);c!==-1&&(a=c+1)}e.setSelectionRange(a,a)}catch{}}}var xE=(e,t={})=>new Intl.NumberFormat(e,t),CE=(e,t={})=>new _h(e,t),hl=(e,t)=>{const{prop:n,computed:r}=t;return n("formatOptions")?e===""?Number.NaN:r("parser").parse(e):parseFloat(e)},Mn=(e,t)=>{const{prop:n,computed:r}=t;return Number.isNaN(e)?"":n("formatOptions")?r("formatter").format(e):e.toString()},SE=(e,t)=>{let n=e!==void 0&&!Number.isNaN(e)?e:1;return(t==null?void 0:t.style)==="percent"&&(e===void 0||Number.isNaN(e))&&(n=.01),n},{choose:wE,guards:EE,createMachine:kE}=Au(),{not:Bh,and:jh}=EE;kE({props({props:e}){const t=SE(e.step,e.formatOptions);return{dir:"ltr",locale:"en-US",focusInputOnChange:!0,clampValueOnBlur:!e.allowOverflow,allowOverflow:!1,inputMode:"decimal",pattern:"-?[0-9]*(.[0-9]+)?",defaultValue:"",step:t,min:Number.MIN_SAFE_INTEGER,max:Number.MAX_SAFE_INTEGER,spinOnPress:!0,...e,translations:{incrementLabel:"increment value",decrementLabel:"decrease value",...e.translations}}},initialState(){return"idle"},context({prop:e,bindable:t,getComputed:n}){return{value:t(()=>({defaultValue:e("defaultValue"),value:e("value"),onChange(r){var s;const i=n(),o=hl(r,{computed:i,prop:e});(s=e("onValueChange"))==null||s({value:r,valueAsNumber:o})}})),hint:t(()=>({defaultValue:null})),scrubberCursorPoint:t(()=>({defaultValue:null,hash(r){return r?`x:${r.x}, y:${r.y}`:""}})),fieldsetDisabled:t(()=>({defaultValue:!1}))}},computed:{isRtl:({prop:e})=>e("dir")==="rtl",valueAsNumber:({context:e,computed:t,prop:n})=>hl(e.get("value"),{computed:t,prop:n}),formattedValue:({computed:e,prop:t})=>Mn(e("valueAsNumber"),{computed:e,prop:t}),isAtMin:({computed:e,prop:t})=>g0(e("valueAsNumber"),t("min")),isAtMax:({computed:e,prop:t})=>f0(e("valueAsNumber"),t("max")),isOutOfRange:({computed:e,prop:t})=>!p0(e("valueAsNumber"),t("min"),t("max")),isValueEmpty:({context:e})=>e.get("value")==="",isDisabled:({prop:e,context:t})=>!!e("disabled")||t.get("fieldsetDisabled"),canIncrement:({prop:e,computed:t})=>e("allowOverflow")||!t("isAtMax"),canDecrement:({prop:e,computed:t})=>e("allowOverflow")||!t("isAtMin"),valueText:({prop:e,context:t})=>{var n,r;return(r=(n=e("translations")).valueText)==null?void 0:r.call(n,t.get("value"))},formatter:Nu(({prop:e})=>[e("locale"),e("formatOptions")],([e,t])=>xE(e,t)),parser:Nu(({prop:e})=>[e("locale"),e("formatOptions")],([e,t])=>CE(e,t))},watch({track:e,action:t,context:n,computed:r,prop:i}){e([()=>n.get("value"),()=>i("locale")],()=>{t(["syncInputElement"])}),e([()=>r("isOutOfRange")],()=>{t(["invokeOnInvalid"])}),e([()=>n.hash("scrubberCursorPoint")],()=>{t(["setVirtualCursorPosition"])})},effects:["trackFormControl"],on:{"VALUE.SET":{actions:["setRawValue"]},"VALUE.CLEAR":{actions:["clearValue"]},"VALUE.INCREMENT":{actions:["increment"]},"VALUE.DECREMENT":{actions:["decrement"]}},states:{idle:{on:{"TRIGGER.PRESS_DOWN":[{guard:"isTouchPointer",target:"before:spin",actions:["setHint"]},{target:"before:spin",actions:["focusInput","invokeOnFocus","setHint"]}],"SCRUBBER.PRESS_DOWN":{target:"scrubbing",actions:["focusInput","invokeOnFocus","setHint","setCursorPoint"]},"INPUT.FOCUS":{target:"focused",actions:["focusInput","invokeOnFocus"]}}},focused:{tags:["focus"],effects:["attachWheelListener"],on:{"TRIGGER.PRESS_DOWN":[{guard:"isTouchPointer",target:"before:spin",actions:["setHint"]},{target:"before:spin",actions:["focusInput","setHint"]}],"SCRUBBER.PRESS_DOWN":{target:"scrubbing",actions:["focusInput","setHint","setCursorPoint"]},"INPUT.ARROW_UP":{actions:["increment"]},"INPUT.ARROW_DOWN":{actions:["decrement"]},"INPUT.HOME":{actions:["decrementToMin"]},"INPUT.END":{actions:["incrementToMax"]},"INPUT.CHANGE":{actions:["setValue","setHint"]},"INPUT.BLUR":[{guard:jh("clampValueOnBlur",Bh("isInRange")),target:"idle",actions:["setClampedValue","clearHint","invokeOnBlur"]},{guard:Bh("isInRange"),target:"idle",actions:["setFormattedValue","clearHint","invokeOnBlur","invokeOnInvalid"]},{target:"idle",actions:["setFormattedValue","clearHint","invokeOnBlur"]}],"INPUT.ENTER":{actions:["setFormattedValue","clearHint","invokeOnBlur"]}}},"before:spin":{tags:["focus"],effects:["trackButtonDisabled","waitForChangeDelay"],entry:wE([{guard:"isIncrementHint",actions:["increment"]},{guard:"isDecrementHint",actions:["decrement"]}]),on:{CHANGE_DELAY:{target:"spinning",guard:jh("isInRange","spinOnPress")},"TRIGGER.PRESS_UP":[{guard:"isTouchPointer",target:"focused",actions:["clearHint"]},{target:"focused",actions:["focusInput","clearHint"]}]}},spinning:{tags:["focus"],effects:["trackButtonDisabled","spinValue"],on:{SPIN:[{guard:"isIncrementHint",actions:["increment"]},{guard:"isDecrementHint",actions:["decrement"]}],"TRIGGER.PRESS_UP":{target:"focused",actions:["focusInput","clearHint"]}}},scrubbing:{tags:["focus"],effects:["activatePointerLock","trackMousemove","setupVirtualCursor","preventTextSelection"],on:{"SCRUBBER.POINTER_UP":{target:"focused",actions:["focusInput","clearCursorPoint"]},"SCRUBBER.POINTER_MOVE":[{guard:"isIncrementHint",actions:["increment","setCursorPoint"]},{guard:"isDecrementHint",actions:["decrement","setCursorPoint"]}]}}},implementations:{guards:{clampValueOnBlur:({prop:e})=>e("clampValueOnBlur"),spinOnPress:({prop:e})=>!!e("spinOnPress"),isInRange:({computed:e})=>!e("isOutOfRange"),isDecrementHint:({context:e,event:t})=>(t.hint??e.get("hint"))==="decrement",isIncrementHint:({context:e,event:t})=>(t.hint??e.get("hint"))==="increment",isTouchPointer:({event:e})=>e.pointerType==="touch"},effects:{waitForChangeDelay({send:e}){const t=setTimeout(()=>{e({type:"CHANGE_DELAY"})},300);return()=>clearTimeout(t)},spinValue({send:e}){const t=setInterval(()=>{e({type:"SPIN"})},50);return()=>clearInterval(t)},trackFormControl({context:e,scope:t}){const n=os(t);return xa(n,{onFieldsetDisabledChange(r){e.set("fieldsetDisabled",r)},onFormReset(){e.set("value",e.initial("value"))}})},setupVirtualCursor({context:e,scope:t}){const n=e.get("scrubberCursorPoint");return gE(t,n)},preventTextSelection({scope:e}){return pE(e)},trackButtonDisabled({context:e,scope:t,send:n}){const r=e.get("hint"),i=fE(t,r);return ko(i,{attributes:["disabled"],callback(){n({type:"TRIGGER.PRESS_UP",src:"attr"})}})},attachWheelListener({scope:e,send:t,prop:n}){const r=os(e);if(!r||!e.isActiveElement(r)||!n("allowMouseWheel"))return;function i(o){o.preventDefault();const s=Math.sign(o.deltaY)*-1;s===1?t({type:"VALUE.INCREMENT"}):s===-1&&t({type:"VALUE.DECREMENT"})}return he(r,"wheel",i,{passive:!1})},activatePointerLock({scope:e}){if(!Su())return fx(e.getDoc())},trackMousemove({scope:e,send:t,context:n,computed:r}){const i=e.getDoc();function o(a){const l=n.get("scrubberCursorPoint"),c=r("isRtl"),u=mE(e,{point:l,isRtl:c,event:a});u.hint&&t({type:"SCRUBBER.POINTER_MOVE",hint:u.hint,point:u.point})}function s(){t({type:"SCRUBBER.POINTER_UP"})}return mo(he(i,"mousemove",o,!1),he(i,"mouseup",s,!1))}},actions:{focusInput({scope:e,prop:t}){if(!t("focusInputOnChange"))return;const n=os(e);e.isActiveElement(n)||Z(()=>n==null?void 0:n.focus({preventScroll:!0}))},increment({context:e,event:t,prop:n,computed:r}){let i=y0(r("valueAsNumber"),t.step??n("step"));n("allowOverflow")||(i=Ue(i,n("min"),n("max"))),e.set("value",Mn(i,{computed:r,prop:n}))},decrement({context:e,event:t,prop:n,computed:r}){let i=x0(r("valueAsNumber"),t.step??n("step"));n("allowOverflow")||(i=Ue(i,n("min"),n("max"))),e.set("value",Mn(i,{computed:r,prop:n}))},setClampedValue({context:e,prop:t,computed:n}){const r=Ue(n("valueAsNumber"),t("min"),t("max"));e.set("value",Mn(r,{computed:n,prop:t}))},setRawValue({context:e,event:t,prop:n,computed:r}){let i=hl(t.value,{computed:r,prop:n});n("allowOverflow")||(i=Ue(i,n("min"),n("max"))),e.set("value",Mn(i,{computed:r,prop:n}))},setValue({context:e,event:t}){var r;const n=((r=t.target)==null?void 0:r.value)??t.value;e.set("value",n)},clearValue({context:e}){e.set("value","")},incrementToMax({context:e,prop:t,computed:n}){const r=Mn(t("max"),{computed:n,prop:t});e.set("value",r)},decrementToMin({context:e,prop:t,computed:n}){const r=Mn(t("min"),{computed:n,prop:t});e.set("value",r)},setHint({context:e,event:t}){e.set("hint",t.hint)},clearHint({context:e}){e.set("hint",null)},invokeOnFocus({computed:e,prop:t}){var n;(n=t("onFocusChange"))==null||n({focused:!0,value:e("formattedValue"),valueAsNumber:e("valueAsNumber")})},invokeOnBlur({computed:e,prop:t}){var n;(n=t("onFocusChange"))==null||n({focused:!1,value:e("formattedValue"),valueAsNumber:e("valueAsNumber")})},invokeOnInvalid({computed:e,prop:t,event:n}){var i;if(n.type==="INPUT.CHANGE")return;const r=e("valueAsNumber")>t("max")?"rangeOverflow":"rangeUnderflow";(i=t("onValueInvalid"))==null||i({reason:r,value:e("formattedValue"),valueAsNumber:e("valueAsNumber")})},syncInputElement({context:e,event:t,computed:n,scope:r}){const i=t.type.endsWith("CHANGE")?e.get("value"):n("formattedValue"),o=os(r),s=bE(o,r);Z(()=>{Eo(o,i),yE(o,s,r)})},setFormattedValue({context:e,computed:t}){e.set("value",t("formattedValue"))},setCursorPoint({context:e,event:t}){e.set("scrubberCursorPoint",t.point)},clearCursorPoint({context:e}){e.set("scrubberCursorPoint",null)},setVirtualCursorPosition({context:e,scope:t}){const n=$h(t),r=e.get("scrubberCursorPoint");!n||!r||(n.style.transform=`translate3d(${r.x}px, ${r.y}px, 0px)`)}}}}),q()(["allowMouseWheel","allowOverflow","clampValueOnBlur","dir","disabled","focusInputOnChange","form","formatOptions","getRootNode","id","ids","inputMode","invalid","locale","max","min","name","onFocusChange","onValueChange","onValueInvalid","pattern","required","readOnly","spinOnPress","step","translations","value","defaultValue"]);var Wh=K("pinInput").parts("root","label","input","control");Wh.build(),q()(["autoFocus","blurOnComplete","count","defaultValue","dir","disabled","form","getRootNode","id","ids","invalid","mask","name","onValueChange","onValueComplete","onValueInvalid","otp","pattern","placeholder","readOnly","required","selectOnFocus","translations","type","value"]);var Hh=K("popover").parts("arrow","arrowTip","anchor","trigger","indicator","positioner","content","title","description","closeTrigger");Hh.build(),q()(["autoFocus","closeOnEscape","closeOnInteractOutside","dir","getRootNode","id","ids","initialFocusEl","modal","onEscapeKeyDown","onFocusOutside","onInteractOutside","onOpenChange","onPointerDownOutside","onRequestDismiss","defaultOpen","open","persistentElements","portalled","positioning"]);const OE=e=>{var l;const{children:t,disabled:n}=e,[r,i]=E.useState((l=e.container)==null?void 0:l.current),o=E.useSyncExternalStore(PE,()=>!1,()=>!0),{getRootNode:s}=pu();if(E.useEffect(()=>{i(()=>{var c;return(c=e.container)==null?void 0:c.current})},[e.container]),o||n)return x.jsx(x.Fragment,{children:t});const a=r??IE(s);return x.jsx(x.Fragment,{children:E.Children.map(t,c=>te.createPortal(c,a))})},IE=e=>{const t=e==null?void 0:e(),n=t.getRootNode();return pr(n)?n:Ge(t).body},PE=()=>()=>{};var fl=K("progress").parts("root","label","track","range","valueText","view","circle","circleTrack","circleRange");fl.build(),q()(["dir","getRootNode","id","ids","max","min","orientation","translations","value","onValueChange","defaultValue","formatOptions","locale"]);var Uh=K("qr-code").parts("root","frame","pattern","overlay","downloadTrigger");Uh.build(),q()(["ids","defaultValue","value","id","encoding","dir","getRootNode","onValueChange","pixelSize"]);var gl=K("radio-group").parts("root","label","item","itemText","itemControl","indicator");gl.build(),q()(["dir","disabled","form","getRootNode","id","ids","name","onValueChange","orientation","readOnly","value","defaultValue"]),q()(["value","disabled","invalid"]);var Gh=K("rating-group").parts("root","label","item","control");Gh.build(),q()(["allowHalf","autoFocus","count","dir","disabled","form","getRootNode","id","ids","name","onHoverChange","onValueChange","required","readOnly","translations","value","defaultValue"]),q()(["index"]);var qh=K("scroll-area").parts("root","viewport","content","scrollbar","thumb","corner");qh.build(),q()(["dir","getRootNode","ids","id"]);const Kh=gl.rename("segment-group");Kh.build();var Xh=K("select").parts("label","positioner","trigger","indicator","clearTrigger","item","itemText","itemIndicator","itemGroup","itemGroupLabel","list","content","root","control","valueText");Xh.build();var Yh=e=>new Xo(e);Yh.empty=()=>new Xo({items:[]});var RE=e=>{var t;return((t=e.ids)==null?void 0:t.content)??`select:${e.id}:content`},TE=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`select:${e.id}:trigger`},NE=e=>{var t;return((t=e.ids)==null?void 0:t.clearTrigger)??`select:${e.id}:clear-trigger`},AE=(e,t)=>{var n,r;return((r=(n=e.ids)==null?void 0:n.item)==null?void 0:r.call(n,t))??`select:${e.id}:option:${t}`},_E=e=>{var t;return((t=e.ids)==null?void 0:t.hiddenSelect)??`select:${e.id}:select`},VE=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`select:${e.id}:positioner`},pl=e=>e.getById(_E(e)),ki=e=>e.getById(RE(e)),ss=e=>e.getById(TE(e)),FE=e=>e.getById(NE(e)),Qh=e=>e.getById(VE(e)),ml=(e,t)=>t==null?null:e.getById(AE(e,t)),{and:Oi,not:$n,or:LE}=rn();LE("isTriggerArrowDownEvent","isTriggerEnterEvent"),Oi($n("multiple"),"hasSelectedItems"),$n("multiple"),Oi($n("multiple"),"hasSelectedItems"),$n("multiple"),$n("multiple"),$n("multiple"),$n("multiple"),Oi("closeOnSelect","isOpenControlled"),Oi("hasHighlightedItem","loop","isLastItemHighlighted"),Oi("hasHighlightedItem","loop","isFirstItemHighlighted");function Jh(e){var n;const t=e.restoreFocus??((n=e.previousEvent)==null?void 0:n.restoreFocus);return t==null||!!t}q()(["closeOnSelect","collection","composite","defaultHighlightedValue","defaultOpen","defaultValue","deselectable","dir","disabled","form","getRootNode","highlightedValue","id","ids","invalid","loopFocus","multiple","name","onFocusOutside","onHighlightChange","onInteractOutside","onOpenChange","onPointerDownOutside","onSelect","onValueChange","open","positioning","readOnly","required","scrollToIndexFn","value"]),q()(["item","persistFocus"]),q()(["id"]),q()(["htmlFor"]);var Zh=K("slider").parts("root","label","thumb","valueText","track","range","control","markerGroup","marker","draggingIndicator");Zh.build(),q()(["aria-label","aria-labelledby","dir","disabled","form","getAriaValueText","getRootNode","id","ids","invalid","max","min","minStepsBetweenThumbs","name","onFocusChange","onValueChange","onValueChangeEnd","orientation","origin","readOnly","step","thumbAlignment","thumbAlignment","thumbSize","value","defaultValue"]),q()(["index","name"]);var ef=K("switch").parts("root","label","control","thumb");ef.build(),q()(["checked","defaultChecked","dir","disabled","form","getRootNode","id","ids","invalid","label","name","onCheckedChange","readOnly","required","value"]);var DE=K("toast").parts("group","root","title","description","actionTrigger","closeTrigger");DE.build();var zE=(e,t)=>({...t,...bo(e)});function ME(e={}){const t=zE(e,{placement:"bottom",overlap:!1,max:24,gap:16,offsets:"1rem",hotkey:["altKey","KeyT"],removeDelay:200,pauseOnPageIdle:!0});let n=[],r=[],i=new Set,o=[];const s=P=>(n.push(P),()=>{const F=n.indexOf(P);n.splice(F,1)}),a=P=>(n.forEach(F=>F(P)),P),l=P=>{if(r.length>=t.max){o.push(P);return}a(P),r.unshift(P)},c=()=>{for(;o.length>0&&r.length{const F=P.id??`toast:${a0()}`,X=r.find(z=>z.id===F);return i.has(F)&&i.delete(F),X?r=r.map(z=>z.id===F?a({...z,...P,id:F}):z):l({id:F,duration:t.duration,removeDelay:t.removeDelay,type:"info",...P,stacked:!t.overlap,gap:t.gap}),F},d=P=>(i.add(P),P?(n.forEach(F=>F({id:P,dismiss:!0})),r=r.filter(F=>F.id!==P),c()):(r.forEach(F=>{n.forEach(X=>X({id:F.id,dismiss:!0}))}),r=[],o=[]),P);return{attrs:t,subscribe:s,create:u,update:(P,F)=>u({id:P,...F}),remove:d,dismiss:P=>{P!=null?r=r.map(F=>F.id===P?a({...F,message:"DISMISS"}):F):r=r.map(F=>a({...F,message:"DISMISS"}))},error:P=>u({...P,type:"error"}),success:P=>u({...P,type:"success"}),info:P=>u({...P,type:"info"}),warning:P=>u({...P,type:"warning"}),loading:P=>u({...P,type:"loading"}),getVisibleToasts:()=>r.filter(P=>!i.has(P.id)),getCount:()=>r.length,promise:(P,F,X={})=>{if(!F||!F.loading){ui("[zag-js > toast] toaster.promise() requires at least a 'loading' option to be specified");return}const z=u({...X,...F.loading,promise:P,type:"loading"});let _=!0,j;const W=po(P).then(async U=>{if(j=["resolve",U],$E(U)&&!U.ok){_=!1;const G=po(F.error,`HTTP Error! status: ${U.status}`);u({...X,...G,id:z,type:"error"})}else if(F.success!==void 0){_=!1;const G=po(F.success,U);u({...X,...G,id:z,type:"success"})}}).catch(async U=>{if(j=["reject",U],F.error!==void 0){_=!1;const G=po(F.error,U);u({...X,...G,id:z,type:"error"})}}).finally(()=>{var U;_&&d(z),(U=F.finally)==null||U.call(F)});return{id:z,unwrap:()=>new Promise((U,G)=>W.then(()=>j[0]==="reject"?G(j[1]):U(j[1])).catch(G))}},pause:P=>{P!=null?r=r.map(F=>F.id===P?a({...F,message:"PAUSE"}):F):r=r.map(F=>a({...F,message:"PAUSE"}))},resume:P=>{P!=null?r=r.map(F=>F.id===P?a({...F,message:"RESUME"}):F):r=r.map(F=>a({...F,message:"RESUME"}))},isVisible:P=>!i.has(P)&&!!r.find(F=>F.id===P),isDismissed:P=>i.has(P),expand:()=>{r=r.map(P=>a({...P,stacked:!0}))},collapse:()=>{r=r.map(P=>a({...P,stacked:!1}))}}}var $E=e=>e&&typeof e=="object"&&"ok"in e&&typeof e.ok=="boolean"&&"status"in e&&typeof e.status=="number";const BE=e=>ME(e);var tf=K("tooltip").parts("trigger","arrow","arrowTip","positioner","content");tf.build();var jE=e=>{var t;return((t=e.ids)==null?void 0:t.trigger)??`tooltip:${e.id}:trigger`},WE=e=>{var t;return((t=e.ids)==null?void 0:t.positioner)??`tooltip:${e.id}:popper`},vl=e=>e.getById(jE(e)),nf=e=>e.getById(WE(e)),Bn=C0({id:null}),{and:HE,not:rf}=rn();HE("noVisibleTooltip",rf("hasPointerMoveOpened")),rf("hasPointerMoveOpened"),q()(["aria-label","closeDelay","closeOnEscape","closeOnPointerDown","closeOnScroll","closeOnClick","dir","disabled","getRootNode","id","ids","interactive","onOpenChange","defaultOpen","open","openDelay","positioning"]);function of(e,t=[]){const n=Object.assign({},e);for(const r of t)r in n&&delete n[r];return n}const UE=(e,t)=>{var l;if(!e||typeof e!="string")return{invalid:!0,value:e};const[n,r]=e.split("/");if(!n||!r||n==="currentBg")return{invalid:!0,value:n};const i=t(`colors.${n}`),o=(l=t.raw(`opacity.${r}`))==null?void 0:l.value;if(!o&&isNaN(Number(r)))return{invalid:!0,value:n};const s=o?Number(o)*100+"%":`${r}%`,a=i??n;return{invalid:!1,color:a,value:`color-mix(in srgb, ${a} ${s}, transparent)`}},le=e=>(t,n)=>{const r=n.utils.colorMix(t);if(r.invalid)return{[e]:t};const i="--mix-"+e;return{[i]:r.value,[e]:`var(${i}, ${r.color})`}};function bl(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(n=>bl(n));const t=Object.create(Object.getPrototypeOf(e));for(const n of Object.keys(e))t[n]=bl(e[n]);return t}function yl(e,t){if(t==null)return e;for(const n of Object.keys(t))if(!(t[n]===void 0||n==="__proto__"))if(!He(e[n])&&He(t[n]))Object.assign(e,{[n]:t[n]});else if(e[n]&&He(t[n]))yl(e[n],t[n]);else if(Array.isArray(t[n])&&Array.isArray(e[n])){let r=0;for(;re!=null;function _t(e,t,n={}){const{stop:r,getKey:i}=n;function o(s,a=[]){if(He(s)||Array.isArray(s)){const l={};for(const[c,u]of Object.entries(s)){const d=(i==null?void 0:i(c,u))??c,h=[...a,d];if(r!=null&&r(s,h))return t(s,a);const m=o(u,h);xl(m)&&(l[d]=m)}return l}return t(s,a)}return o(e)}function sf(e,t){return Array.isArray(e)?e.map(n=>xl(n)?t(n):n):He(e)?_t(e,n=>t(n)):xl(e)?t(e):e}const as=["value","type","description"],GE=e=>e&&typeof e=="object"&&!Array.isArray(e),af=(...e)=>{var n;const t=Rr({},...e.map(bl));return(n=t.theme)!=null&&n.tokens&&_t(t.theme.tokens,r=>{const s=Object.keys(r).filter(l=>!as.includes(l)).length>0,a=as.some(l=>r[l]!=null);return s&&a&&(r.DEFAULT||(r.DEFAULT={}),as.forEach(l=>{var c;r[l]!=null&&((c=r.DEFAULT)[l]||(c[l]=r[l]),delete r[l])})),r},{stop(r){return GE(r)&&Object.keys(r).some(i=>as.includes(i)||i!==i.toLowerCase()&&i!==i.toUpperCase())}}),t},qE=e=>e,Se=e=>e,Y=e=>e,KE=e=>e,XE=e=>e,Tr=e=>e,YE=e=>e,QE=e=>e,JE=e=>e;function lf(){const e=t=>t;return new Proxy(e,{get(){return e}})}const xe=lf(),Cl=lf(),Sl=e=>e,ZE=/[^a-zA-Z0-9_\u0081-\uffff-]/g;function ek(e){return`${e}`.replace(ZE,t=>`\\${t}`)}const tk=/[A-Z]/g;function nk(e){return e.replace(tk,t=>`-${t.toLowerCase()}`)}function cf(e,t={}){const{fallback:n="",prefix:r=""}=t,i=nk(["-",r,ek(e)].filter(Boolean).join("-"));return{var:i,ref:`var(${i}${n?`, ${n}`:""})`}}const rk=e=>/^var\(--.+\)$/.test(e),Re=(e,t)=>t!=null?`${e}(${t})`:t,jn=e=>{if(rk(e)||e==null)return e;const t=typeof e=="string"&&!e.endsWith("deg");return typeof e=="number"||t?`${e}deg`:e},uf=e=>({values:["outside","inside","mixed","none"],transform(t,{token:n}){const r=n("colors.colorPalette.focusRing");return{inside:{"--focus-ring-color":r,[e]:{outlineOffset:"0px",outlineWidth:"var(--focus-ring-width, 1px)",outlineColor:"var(--focus-ring-color)",outlineStyle:"var(--focus-ring-style, solid)",borderColor:"var(--focus-ring-color)"}},outside:{"--focus-ring-color":r,[e]:{outlineWidth:"var(--focus-ring-width, 2px)",outlineOffset:"var(--focus-ring-offset, 2px)",outlineStyle:"var(--focus-ring-style, solid)",outlineColor:"var(--focus-ring-color)"}},mixed:{"--focus-ring-color":r,[e]:{outlineWidth:"var(--focus-ring-width, 3px)",outlineStyle:"var(--focus-ring-style, solid)",outlineColor:"color-mix(in srgb, var(--focus-ring-color), transparent 60%)",borderColor:"var(--focus-ring-color)"}},none:{"--focus-ring-color":r,[e]:{outline:"none"}}}[t]??{}}}),ik=le("borderColor"),Ht=e=>({transition:e,transitionTimingFunction:"cubic-bezier(0.4, 0, 0.2, 1)",transitionDuration:"150ms"}),ok=qE({hover:["@media (hover: hover)","&:is(:hover, [data-hover]):not(:disabled, [data-disabled])"],active:"&:is(:active, [data-active]):not(:disabled, [data-disabled], [data-state=open])",focus:"&:is(:focus, [data-focus])",focusWithin:"&:is(:focus-within, [data-focus-within])",focusVisible:"&:is(:focus-visible, [data-focus-visible])",disabled:"&:is(:disabled, [disabled], [data-disabled], [aria-disabled=true])",visited:"&:visited",target:"&:target",readOnly:"&:is([data-readonly], [aria-readonly=true], [readonly])",readWrite:"&:read-write",empty:"&:is(:empty, [data-empty])",checked:"&:is(:checked, [data-checked], [aria-checked=true], [data-state=checked])",enabled:"&:enabled",expanded:"&:is([aria-expanded=true], [data-expanded], [data-state=expanded])",highlighted:"&[data-highlighted]",complete:"&[data-complete]",incomplete:"&[data-incomplete]",dragging:"&[data-dragging]",before:"&::before",after:"&::after",firstLetter:"&::first-letter",firstLine:"&::first-line",marker:"&::marker",selection:"&::selection",file:"&::file-selector-button",backdrop:"&::backdrop",first:"&:first-of-type",last:"&:last-of-type",notFirst:"&:not(:first-of-type)",notLast:"&:not(:last-of-type)",only:"&:only-child",even:"&:nth-of-type(even)",odd:"&:nth-of-type(odd)",peerFocus:".peer:is(:focus, [data-focus]) ~ &",peerHover:".peer:is(:hover, [data-hover]):not(:disabled, [data-disabled]) ~ &",peerActive:".peer:is(:active, [data-active]):not(:disabled, [data-disabled]) ~ &",peerFocusWithin:".peer:focus-within ~ &",peerFocusVisible:".peer:is(:focus-visible, [data-focus-visible]) ~ &",peerDisabled:".peer:is(:disabled, [disabled], [data-disabled]) ~ &",peerChecked:".peer:is(:checked, [data-checked], [aria-checked=true], [data-state=checked]) ~ &",peerInvalid:".peer:is(:invalid, [data-invalid], [aria-invalid=true]) ~ &",peerExpanded:".peer:is([aria-expanded=true], [data-expanded], [data-state=expanded]) ~ &",peerPlaceholderShown:".peer:placeholder-shown ~ &",groupFocus:".group:is(:focus, [data-focus]) &",groupHover:".group:is(:hover, [data-hover]):not(:disabled, [data-disabled]) &",groupActive:".group:is(:active, [data-active]):not(:disabled, [data-disabled]) &",groupFocusWithin:".group:focus-within &",groupFocusVisible:".group:is(:focus-visible, [data-focus-visible]) &",groupDisabled:".group:is(:disabled, [disabled], [data-disabled]) &",groupChecked:".group:is(:checked, [data-checked], [aria-checked=true], [data-state=checked]) &",groupExpanded:".group:is([aria-expanded=true], [data-expanded], [data-state=expanded]) &",groupInvalid:".group:invalid &",indeterminate:"&:is(:indeterminate, [data-indeterminate], [aria-checked=mixed], [data-state=indeterminate])",required:"&:is([data-required], [aria-required=true])",valid:"&:is([data-valid], [data-state=valid])",invalid:"&:is([data-invalid], [aria-invalid=true], [data-state=invalid])",autofill:"&:autofill",inRange:"&:is(:in-range, [data-in-range])",outOfRange:"&:is(:out-of-range, [data-outside-range])",placeholder:"&::placeholder, &[data-placeholder]",placeholderShown:"&:is(:placeholder-shown, [data-placeholder-shown])",pressed:"&:is([aria-pressed=true], [data-pressed])",selected:"&:is([aria-selected=true], [data-selected])",grabbed:"&:is([aria-grabbed=true], [data-grabbed])",underValue:"&[data-state=under-value]",overValue:"&[data-state=over-value]",atValue:"&[data-state=at-value]",default:"&:default",optional:"&:optional",open:"&:is([open], [data-open], [data-state=open])",closed:"&:is([closed], [data-closed], [data-state=closed])",fullscreen:"&:is(:fullscreen, [data-fullscreen])",loading:"&:is([data-loading], [aria-busy=true])",hidden:"&:is([hidden], [data-hidden])",current:"&[data-current]",currentPage:"&[aria-current=page]",currentStep:"&[aria-current=step]",today:"&[data-today]",unavailable:"&[data-unavailable]",rangeStart:"&[data-range-start]",rangeEnd:"&[data-range-end]",now:"&[data-now]",topmost:"&[data-topmost]",motionReduce:"@media (prefers-reduced-motion: reduce)",motionSafe:"@media (prefers-reduced-motion: no-preference)",print:"@media print",landscape:"@media (orientation: landscape)",portrait:"@media (orientation: portrait)",dark:".dark &, .dark .chakra-theme:not(.light) &",light:":root &, .light &",osDark:"@media (prefers-color-scheme: dark)",osLight:"@media (prefers-color-scheme: light)",highContrast:"@media (forced-colors: active)",lessContrast:"@media (prefers-contrast: less)",moreContrast:"@media (prefers-contrast: more)",ltr:"[dir=ltr] &",rtl:"[dir=rtl] &",scrollbar:"&::-webkit-scrollbar",scrollbarThumb:"&::-webkit-scrollbar-thumb",scrollbarTrack:"&::-webkit-scrollbar-track",horizontal:"&[data-orientation=horizontal]",vertical:"&[data-orientation=vertical]",icon:"& :where(svg)",starting:"@starting-style"}),Nr=cf("bg-currentcolor"),df=e=>e===Nr.ref||e==="currentBg",ce=e=>({...e("colors"),currentBg:Nr}),sk=Sl({conditions:ok,utilities:{background:{values:ce,shorthand:["bg"],transform(e,t){if(df(t.raw))return{background:Nr.ref};const n=le("background")(e,t);return{...n,[Nr.var]:n==null?void 0:n.background}}},backgroundColor:{values:ce,shorthand:["bgColor"],transform(e,t){if(df(t.raw))return{backgroundColor:Nr.ref};const n=le("backgroundColor")(e,t);return{...n,[Nr.var]:n==null?void 0:n.backgroundColor}}},backgroundSize:{shorthand:["bgSize"]},backgroundPosition:{shorthand:["bgPos"]},backgroundRepeat:{shorthand:["bgRepeat"]},backgroundAttachment:{shorthand:["bgAttachment"]},backgroundClip:{shorthand:["bgClip"],values:["text"],transform(e){return e==="text"?{color:"transparent",backgroundClip:"text"}:{backgroundClip:e}}},backgroundGradient:{shorthand:["bgGradient"],values(e){return{...e("gradients"),"to-t":"linear-gradient(to top, var(--gradient))","to-tr":"linear-gradient(to top right, var(--gradient))","to-r":"linear-gradient(to right, var(--gradient))","to-br":"linear-gradient(to bottom right, var(--gradient))","to-b":"linear-gradient(to bottom, var(--gradient))","to-bl":"linear-gradient(to bottom left, var(--gradient))","to-l":"linear-gradient(to left, var(--gradient))","to-tl":"linear-gradient(to top left, var(--gradient))"}},transform(e){return{"--gradient-stops":"var(--gradient-from), var(--gradient-to)","--gradient":"var(--gradient-via-stops, var(--gradient-stops))",backgroundImage:e}}},gradientFrom:{values:ce,transform:le("--gradient-from")},gradientTo:{values:ce,transform:le("--gradient-to")},gradientVia:{values:ce,transform(e,t){return{...le("--gradient-via")(e,t),"--gradient-via-stops":"var(--gradient-from), var(--gradient-via), var(--gradient-to)"}}},backgroundImage:{values(e){return{...e("gradients"),...e("assets")}},shorthand:["bgImg","bgImage"]},border:{values:"borders"},borderTop:{values:"borders"},borderLeft:{values:"borders"},borderBlockStart:{values:"borders"},borderRight:{values:"borders"},borderBottom:{values:"borders"},borderBlockEnd:{values:"borders"},borderInlineStart:{values:"borders",shorthand:["borderStart"]},borderInlineEnd:{values:"borders",shorthand:["borderEnd"]},borderInline:{values:"borders",shorthand:["borderX"]},borderBlock:{values:"borders",shorthand:["borderY"]},borderColor:{values:ce,transform:le("borderColor")},borderTopColor:{values:ce,transform:le("borderTopColor")},borderBlockStartColor:{values:ce,transform:le("borderBlockStartColor")},borderBottomColor:{values:ce,transform:le("borderBottomColor")},borderBlockEndColor:{values:ce,transform:le("borderBlockEndColor")},borderLeftColor:{values:ce,transform:le("borderLeftColor")},borderInlineStartColor:{values:ce,shorthand:["borderStartColor"],transform:le("borderInlineStartColor")},borderRightColor:{values:ce,transform:le("borderRightColor")},borderInlineEndColor:{values:ce,shorthand:["borderEndColor"],transform:le("borderInlineEndColor")},borderStyle:{values:"borderStyles"},borderTopStyle:{values:"borderStyles"},borderBlockStartStyle:{values:"borderStyles"},borderBottomStyle:{values:"borderStyles"},borderBlockEndStyle:{values:"borderStyles"},borderInlineStartStyle:{values:"borderStyles",shorthand:["borderStartStyle"]},borderInlineEndStyle:{values:"borderStyles",shorthand:["borderEndStyle"]},borderLeftStyle:{values:"borderStyles"},borderRightStyle:{values:"borderStyles"},borderRadius:{values:"radii",shorthand:["rounded"]},borderTopLeftRadius:{values:"radii",shorthand:["roundedTopLeft"]},borderStartStartRadius:{values:"radii",shorthand:["roundedStartStart","borderTopStartRadius"]},borderEndStartRadius:{values:"radii",shorthand:["roundedEndStart","borderBottomStartRadius"]},borderTopRightRadius:{values:"radii",shorthand:["roundedTopRight"]},borderStartEndRadius:{values:"radii",shorthand:["roundedStartEnd","borderTopEndRadius"]},borderEndEndRadius:{values:"radii",shorthand:["roundedEndEnd","borderBottomEndRadius"]},borderBottomLeftRadius:{values:"radii",shorthand:["roundedBottomLeft"]},borderBottomRightRadius:{values:"radii",shorthand:["roundedBottomRight"]},borderInlineStartRadius:{values:"radii",property:"borderRadius",shorthand:["roundedStart","borderStartRadius"],transform:e=>({borderStartStartRadius:e,borderEndStartRadius:e})},borderInlineEndRadius:{values:"radii",property:"borderRadius",shorthand:["roundedEnd","borderEndRadius"],transform:e=>({borderStartEndRadius:e,borderEndEndRadius:e})},borderTopRadius:{values:"radii",property:"borderRadius",shorthand:["roundedTop"],transform:e=>({borderTopLeftRadius:e,borderTopRightRadius:e})},borderBottomRadius:{values:"radii",property:"borderRadius",shorthand:["roundedBottom"],transform:e=>({borderBottomLeftRadius:e,borderBottomRightRadius:e})},borderLeftRadius:{values:"radii",property:"borderRadius",shorthand:["roundedLeft"],transform:e=>({borderTopLeftRadius:e,borderBottomLeftRadius:e})},borderRightRadius:{values:"radii",property:"borderRadius",shorthand:["roundedRight"],transform:e=>({borderTopRightRadius:e,borderBottomRightRadius:e})},borderWidth:{values:"borderWidths"},borderBlockStartWidth:{values:"borderWidths"},borderTopWidth:{values:"borderWidths"},borderBottomWidth:{values:"borderWidths"},borderBlockEndWidth:{values:"borderWidths"},borderRightWidth:{values:"borderWidths"},borderInlineWidth:{values:"borderWidths",shorthand:["borderXWidth"]},borderInlineStartWidth:{values:"borderWidths",shorthand:["borderStartWidth"]},borderInlineEndWidth:{values:"borderWidths",shorthand:["borderEndWidth"]},borderLeftWidth:{values:"borderWidths"},borderBlockWidth:{values:"borderWidths",shorthand:["borderYWidth"]},color:{values:ce,transform:le("color")},fill:{values:ce,transform:le("fill")},stroke:{values:ce,transform:le("stroke")},accentColor:{values:ce,transform:le("accentColor")},divideX:{values:{type:"string"},transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{borderInlineStartWidth:e,borderInlineEndWidth:"0px"}}}},divideY:{values:{type:"string"},transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{borderTopWidth:e,borderBottomWidth:"0px"}}}},divideColor:{values:ce,transform(e,t){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":ik(e,t)}}},divideStyle:{property:"borderStyle",transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{borderStyle:e}}}},boxShadow:{values:"shadows",shorthand:["shadow"]},boxShadowColor:{values:ce,transform:le("--shadow-color"),shorthand:["shadowColor"]},mixBlendMode:{shorthand:["blendMode"]},backgroundBlendMode:{shorthand:["bgBlendMode"]},opacity:{values:"opacity"},filter:{transform(e){return e!=="auto"?{filter:e}:{filter:"var(--blur) var(--brightness) var(--contrast) var(--grayscale) var(--hue-rotate) var(--invert) var(--saturate) var(--sepia) var(--drop-shadow)"}}},blur:{values:"blurs",transform:e=>({"--blur":Re("blur",e)})},brightness:{transform:e=>({"--brightness":Re("brightness",e)})},contrast:{transform:e=>({"--contrast":Re("contrast",e)})},grayscale:{transform:e=>({"--grayscale":Re("grayscale",e)})},hueRotate:{transform:e=>({"--hue-rotate":Re("hue-rotate",jn(e))})},invert:{transform:e=>({"--invert":Re("invert",e)})},saturate:{transform:e=>({"--saturate":Re("saturate",e)})},sepia:{transform:e=>({"--sepia":Re("sepia",e)})},dropShadow:{transform:e=>({"--drop-shadow":Re("drop-shadow",e)})},backdropFilter:{transform(e){return e!=="auto"?{backdropFilter:e}:{backdropFilter:"var(--backdrop-blur) var(--backdrop-brightness) var(--backdrop-contrast) var(--backdrop-grayscale) var(--backdrop-hue-rotate) var(--backdrop-invert) var(--backdrop-opacity) var(--backdrop-saturate) var(--backdrop-sepia)"}}},backdropBlur:{values:"blurs",transform:e=>({"--backdrop-blur":Re("blur",e)})},backdropBrightness:{transform:e=>({"--backdrop-brightness":Re("brightness",e)})},backdropContrast:{transform:e=>({"--backdrop-contrast":Re("contrast",e)})},backdropGrayscale:{transform:e=>({"--backdrop-grayscale":Re("grayscale",e)})},backdropHueRotate:{transform:e=>({"--backdrop-hue-rotate":Re("hue-rotate",jn(e))})},backdropInvert:{transform:e=>({"--backdrop-invert":Re("invert",e)})},backdropOpacity:{transform:e=>({"--backdrop-opacity":Re("opacity",e)})},backdropSaturate:{transform:e=>({"--backdrop-saturate":Re("saturate",e)})},backdropSepia:{transform:e=>({"--backdrop-sepia":Re("sepia",e)})},flexBasis:{values:"sizes"},gap:{values:"spacing"},rowGap:{values:"spacing",shorthand:["gapY"]},columnGap:{values:"spacing",shorthand:["gapX"]},flexDirection:{shorthand:["flexDir"]},gridGap:{values:"spacing"},gridColumnGap:{values:"spacing"},gridRowGap:{values:"spacing"},outlineColor:{values:ce,transform:le("outlineColor")},focusRing:uf("&:is(:focus, [data-focus])"),focusVisibleRing:uf("&:is(:focus-visible, [data-focus-visible])"),focusRingColor:{values:ce,transform:le("--focus-ring-color")},focusRingOffset:{values:"spacing",transform:e=>({"--focus-ring-offset":e})},focusRingWidth:{values:"borderWidths",property:"outlineWidth",transform:e=>({"--focus-ring-width":e})},focusRingStyle:{values:"borderStyles",property:"outlineStyle",transform:e=>({"--focus-ring-style":e})},aspectRatio:{values:"aspectRatios"},width:{values:"sizes",shorthand:["w"]},inlineSize:{values:"sizes"},height:{values:"sizes",shorthand:["h"]},blockSize:{values:"sizes"},boxSize:{values:"sizes",property:"width",transform:e=>({width:e,height:e})},minWidth:{values:"sizes",shorthand:["minW"]},minInlineSize:{values:"sizes"},minHeight:{values:"sizes",shorthand:["minH"]},minBlockSize:{values:"sizes"},maxWidth:{values:"sizes",shorthand:["maxW"]},maxInlineSize:{values:"sizes"},maxHeight:{values:"sizes",shorthand:["maxH"]},maxBlockSize:{values:"sizes"},hideFrom:{values:"breakpoints",transform:(e,{raw:t,token:n})=>({[n.raw(`breakpoints.${t}`)?`@breakpoint ${t}`:`@media screen and (min-width: ${e})`]:{display:"none"}})},hideBelow:{values:"breakpoints",transform(e,{raw:t,token:n}){return{[n.raw(`breakpoints.${t}`)?`@breakpoint ${t}Down`:`@media screen and (max-width: ${e})`]:{display:"none"}}}},overscrollBehavior:{shorthand:["overscroll"]},overscrollBehaviorX:{shorthand:["overscrollX"]},overscrollBehaviorY:{shorthand:["overscrollY"]},scrollbar:{values:["visible","hidden"],transform(e){switch(e){case"visible":return{msOverflowStyle:"auto",scrollbarWidth:"auto","&::-webkit-scrollbar":{display:"block"}};case"hidden":return{msOverflowStyle:"none",scrollbarWidth:"none","&::-webkit-scrollbar":{display:"none"}};default:return{}}}},scrollbarColor:{values:ce,transform:le("scrollbarColor")},scrollbarGutter:{values:"spacing"},scrollbarWidth:{values:"sizes"},scrollMargin:{values:"spacing"},scrollMarginTop:{values:"spacing"},scrollMarginBottom:{values:"spacing"},scrollMarginLeft:{values:"spacing"},scrollMarginRight:{values:"spacing"},scrollMarginX:{values:"spacing",transform:e=>({scrollMarginLeft:e,scrollMarginRight:e})},scrollMarginY:{values:"spacing",transform:e=>({scrollMarginTop:e,scrollMarginBottom:e})},scrollPadding:{values:"spacing"},scrollPaddingTop:{values:"spacing"},scrollPaddingBottom:{values:"spacing"},scrollPaddingLeft:{values:"spacing"},scrollPaddingRight:{values:"spacing"},scrollPaddingInline:{values:"spacing",shorthand:["scrollPaddingX"]},scrollPaddingBlock:{values:"spacing",shorthand:["scrollPaddingY"]},scrollSnapType:{values:{none:"none",x:"x var(--scroll-snap-strictness)",y:"y var(--scroll-snap-strictness)",both:"both var(--scroll-snap-strictness)"}},scrollSnapStrictness:{values:["mandatory","proximity"],transform:e=>({"--scroll-snap-strictness":e})},scrollSnapMargin:{values:"spacing"},scrollSnapMarginTop:{values:"spacing"},scrollSnapMarginBottom:{values:"spacing"},scrollSnapMarginLeft:{values:"spacing"},scrollSnapMarginRight:{values:"spacing"},listStylePosition:{shorthand:["listStylePos"]},listStyleImage:{values:"assets",shorthand:["listStyleImg"]},position:{shorthand:["pos"]},zIndex:{values:"zIndex"},inset:{values:"spacing"},insetInline:{values:"spacing",shorthand:["insetX"]},insetBlock:{values:"spacing",shorthand:["insetY"]},top:{values:"spacing"},insetBlockStart:{values:"spacing"},bottom:{values:"spacing"},insetBlockEnd:{values:"spacing"},left:{values:"spacing"},right:{values:"spacing"},insetInlineStart:{values:"spacing",shorthand:["insetStart"]},insetInlineEnd:{values:"spacing",shorthand:["insetEnd"]},ring:{transform(e){return{"--ring-offset-shadow":"var(--ring-inset) 0 0 0 var(--ring-offset-width) var(--ring-offset-color)","--ring-shadow":"var(--ring-inset) 0 0 0 calc(var(--ring-width) + var(--ring-offset-width)) var(--ring-color)","--ring-width":e,boxShadow:"var(--ring-offset-shadow), var(--ring-shadow), var(--shadow, 0 0 #0000)"}}},ringColor:{values:ce,transform:le("--ring-color")},ringOffset:{transform:e=>({"--ring-offset-width":e})},ringOffsetColor:{values:ce,transform:le("--ring-offset-color")},ringInset:{transform:e=>({"--ring-inset":e})},margin:{values:"spacing",shorthand:["m"]},marginTop:{values:"spacing",shorthand:["mt"]},marginBlockStart:{values:"spacing"},marginRight:{values:"spacing",shorthand:["mr"]},marginBottom:{values:"spacing",shorthand:["mb"]},marginBlockEnd:{values:"spacing"},marginLeft:{values:"spacing",shorthand:["ml"]},marginInlineStart:{values:"spacing",shorthand:["ms","marginStart"]},marginInlineEnd:{values:"spacing",shorthand:["me","marginEnd"]},marginInline:{values:"spacing",shorthand:["mx","marginX"]},marginBlock:{values:"spacing",shorthand:["my","marginY"]},padding:{values:"spacing",shorthand:["p"]},paddingTop:{values:"spacing",shorthand:["pt"]},paddingRight:{values:"spacing",shorthand:["pr"]},paddingBottom:{values:"spacing",shorthand:["pb"]},paddingBlockStart:{values:"spacing"},paddingBlockEnd:{values:"spacing"},paddingLeft:{values:"spacing",shorthand:["pl"]},paddingInlineStart:{values:"spacing",shorthand:["ps","paddingStart"]},paddingInlineEnd:{values:"spacing",shorthand:["pe","paddingEnd"]},paddingInline:{values:"spacing",shorthand:["px","paddingX"]},paddingBlock:{values:"spacing",shorthand:["py","paddingY"]},textDecoration:{shorthand:["textDecor"]},textDecorationColor:{values:ce,transform:le("textDecorationColor")},textShadow:{values:"shadows"},transform:{transform:e=>{let t=e;return e==="auto"&&(t="translateX(var(--translate-x, 0)) translateY(var(--translate-y, 0)) rotate(var(--rotate, 0)) scaleX(var(--scale-x, 1)) scaleY(var(--scale-y, 1)) skewX(var(--skew-x, 0)) skewY(var(--skew-y, 0))"),e==="auto-gpu"&&(t="translate3d(var(--translate-x, 0), var(--translate-y, 0), 0) rotate(var(--rotate, 0)) scaleX(var(--scale-x, 1)) scaleY(var(--scale-y, 1)) skewX(var(--skew-x, 0)) skewY(var(--skew-y, 0))"),{transform:t}}},skewX:{transform:e=>({"--skew-x":jn(e)})},skewY:{transform:e=>({"--skew-y":jn(e)})},scaleX:{transform:e=>({"--scale-x":e})},scaleY:{transform:e=>({"--scale-y":e})},scale:{transform(e){return e!=="auto"?{scale:e}:{scale:"var(--scale-x, 1) var(--scale-y, 1)"}}},spaceXReverse:{values:{type:"boolean"},transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{"--space-x-reverse":e?"1":void 0}}}},spaceX:{property:"marginInlineStart",values:"spacing",transform:e=>({"& > :not(style, [hidden]) ~ :not(style, [hidden])":{"--space-x-reverse":"0",marginInlineStart:`calc(${e} * calc(1 - var(--space-x-reverse)))`,marginInlineEnd:`calc(${e} * var(--space-x-reverse))`}})},spaceYReverse:{values:{type:"boolean"},transform(e){return{"& > :not(style, [hidden]) ~ :not(style, [hidden])":{"--space-y-reverse":e?"1":void 0}}}},spaceY:{property:"marginTop",values:"spacing",transform:e=>({"& > :not(style, [hidden]) ~ :not(style, [hidden])":{"--space-y-reverse":"0",marginTop:`calc(${e} * calc(1 - var(--space-y-reverse)))`,marginBottom:`calc(${e} * var(--space-y-reverse))`}})},rotate:{transform(e){return e!=="auto"?{rotate:jn(e)}:{rotate:"var(--rotate-x, 0) var(--rotate-y, 0) var(--rotate-z, 0)"}}},rotateX:{transform(e){return{"--rotate-x":jn(e)}}},rotateY:{transform(e){return{"--rotate-y":jn(e)}}},translate:{transform(e){return e!=="auto"?{translate:e}:{translate:"var(--translate-x) var(--translate-y)"}}},translateX:{values:"spacing",transform:e=>({"--translate-x":e})},translateY:{values:"spacing",transform:e=>({"--translate-y":e})},transition:{values:["all","common","colors","opacity","position","backgrounds","size","shadow","transform"],transform(e){switch(e){case"all":return Ht("all");case"position":return Ht("left, right, top, bottom, inset-inline, inset-block");case"colors":return Ht("color, background-color, border-color, text-decoration-color, fill, stroke");case"opacity":return Ht("opacity");case"shadow":return Ht("box-shadow");case"transform":return Ht("transform");case"size":return Ht("width, height");case"backgrounds":return Ht("background, background-color, background-image, background-position");case"common":return Ht("color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter");default:return{transition:e}}}},transitionDuration:{values:"durations"},transitionProperty:{values:{common:"background-color, border-color, color, fill, stroke, opacity, box-shadow, translate, transform",colors:"background-color, border-color, color, fill, stroke",size:"width, height",position:"left, right, top, bottom, inset-inline, inset-block",background:"background, background-color, background-image, background-position"}},transitionTimingFunction:{values:"easings"},animation:{values:"animations"},animationDuration:{values:"durations"},animationDelay:{values:"durations"},animationTimingFunction:{values:"easings"},fontFamily:{values:"fonts"},fontSize:{values:"fontSizes"},fontWeight:{values:"fontWeights"},lineHeight:{values:"lineHeights"},letterSpacing:{values:"letterSpacings"},textIndent:{values:"spacing"},truncate:{values:{type:"boolean"},transform(e){return e===!0?{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}:{}}},lineClamp:{transform(e){return e==="none"?{WebkitLineClamp:"unset"}:{overflow:"hidden",display:"-webkit-box",WebkitLineClamp:e,WebkitBoxOrient:"vertical",textWrap:"wrap"}}},borderSpacing:{values:e=>({...e("spacing"),auto:"var(--border-spacing-x, 0) var(--border-spacing-y, 0)"})},borderSpacingX:{values:"spacing",transform(e){return{"--border-spacing-x":e}}},borderSpacingY:{values:"spacing",transform(e){return{"--border-spacing-y":e}}},srOnly:{values:{type:"boolean"},transform(e){return ak[e]||{}}},debug:{values:{type:"boolean"},transform(e){return e?{outline:"1px solid blue !important","& > *":{outline:"1px solid red !important"}}:{}}},caretColor:{values:ce,transform:le("caretColor")},cursor:{values:"cursor"}}}),ak={true:{position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"},false:{position:"static",width:"auto",height:"auto",padding:"0",margin:"0",overflow:"visible",clip:"auto",whiteSpace:"normal"}};var lk="",ck=lk.split(","),uk="WebkitAppearance,WebkitBorderBefore,WebkitBorderBeforeColor,WebkitBorderBeforeStyle,WebkitBorderBeforeWidth,WebkitBoxReflect,WebkitLineClamp,WebkitMask,WebkitMaskAttachment,WebkitMaskClip,WebkitMaskComposite,WebkitMaskImage,WebkitMaskOrigin,WebkitMaskPosition,WebkitMaskPositionX,WebkitMaskPositionY,WebkitMaskRepeat,WebkitMaskRepeatX,WebkitMaskRepeatY,WebkitMaskSize,WebkitOverflowScrolling,WebkitTapHighlightColor,WebkitTextFillColor,WebkitTextStroke,WebkitTextStrokeColor,WebkitTextStrokeWidth,WebkitTouchCallout,WebkitUserModify,WebkitUserSelect,accentColor,alignContent,alignItems,alignSelf,alignTracks,all,anchorName,anchorScope,animation,animationComposition,animationDelay,animationDirection,animationDuration,animationFillMode,animationIterationCount,animationName,animationPlayState,animationRange,animationRangeEnd,animationRangeStart,animationTimeline,animationTimingFunction,appearance,aspectRatio,backdropFilter,backfaceVisibility,background,backgroundAttachment,backgroundBlendMode,backgroundClip,backgroundColor,backgroundImage,backgroundOrigin,backgroundPosition,backgroundPositionX,backgroundPositionY,backgroundRepeat,backgroundSize,blockSize,border,borderBlock,borderBlockColor,borderBlockEnd,borderBlockEndColor,borderBlockEndStyle,borderBlockEndWidth,borderBlockStart,borderBlockStartColor,borderBlockStartStyle,borderBlockStartWidth,borderBlockStyle,borderBlockWidth,borderBottom,borderBottomColor,borderBottomLeftRadius,borderBottomRightRadius,borderBottomStyle,borderBottomWidth,borderCollapse,borderColor,borderEndEndRadius,borderEndStartRadius,borderImage,borderImageOutset,borderImageRepeat,borderImageSlice,borderImageSource,borderImageWidth,borderInline,borderInlineColor,borderInlineEnd,borderInlineEndColor,borderInlineEndStyle,borderInlineEndWidth,borderInlineStart,borderInlineStartColor,borderInlineStartStyle,borderInlineStartWidth,borderInlineStyle,borderInlineWidth,borderLeft,borderLeftColor,borderLeftStyle,borderLeftWidth,borderRadius,borderRight,borderRightColor,borderRightStyle,borderRightWidth,borderSpacing,borderStartEndRadius,borderStartStartRadius,borderStyle,borderTop,borderTopColor,borderTopLeftRadius,borderTopRightRadius,borderTopStyle,borderTopWidth,borderWidth,bottom,boxAlign,boxDecorationBreak,boxDirection,boxFlex,boxFlexGroup,boxLines,boxOrdinalGroup,boxOrient,boxPack,boxShadow,boxSizing,breakAfter,breakBefore,breakInside,captionSide,caret,caretColor,caretShape,clear,clip,clipPath,clipRule,color,colorInterpolationFilters,colorScheme,columnCount,columnFill,columnGap,columnRule,columnRuleColor,columnRuleStyle,columnRuleWidth,columnSpan,columnWidth,columns,contain,containIntrinsicBlockSize,containIntrinsicHeight,containIntrinsicInlineSize,containIntrinsicSize,containIntrinsicWidth,container,containerName,containerType,content,contentVisibility,counterIncrement,counterReset,counterSet,cursor,cx,cy,d,direction,display,dominantBaseline,emptyCells,fieldSizing,fill,fillOpacity,fillRule,filter,flex,flexBasis,flexDirection,flexFlow,flexGrow,flexShrink,flexWrap,float,floodColor,floodOpacity,font,fontFamily,fontFeatureSettings,fontKerning,fontLanguageOverride,fontOpticalSizing,fontPalette,fontSize,fontSizeAdjust,fontSmooth,fontStretch,fontStyle,fontSynthesis,fontSynthesisPosition,fontSynthesisSmallCaps,fontSynthesisStyle,fontSynthesisWeight,fontVariant,fontVariantAlternates,fontVariantCaps,fontVariantEastAsian,fontVariantEmoji,fontVariantLigatures,fontVariantNumeric,fontVariantPosition,fontVariationSettings,fontWeight,forcedColorAdjust,gap,grid,gridArea,gridAutoColumns,gridAutoFlow,gridAutoRows,gridColumn,gridColumnEnd,gridColumnGap,gridColumnStart,gridGap,gridRow,gridRowEnd,gridRowGap,gridRowStart,gridTemplate,gridTemplateAreas,gridTemplateColumns,gridTemplateRows,hangingPunctuation,height,hyphenateCharacter,hyphenateLimitChars,hyphens,imageOrientation,imageRendering,imageResolution,imeMode,initialLetter,initialLetterAlign,inlineSize,inset,insetBlock,insetBlockEnd,insetBlockStart,insetInline,insetInlineEnd,insetInlineStart,interpolateSize,isolation,justifyContent,justifyItems,justifySelf,justifyTracks,left,letterSpacing,lightingColor,lineBreak,lineClamp,lineHeight,lineHeightStep,listStyle,listStyleImage,listStylePosition,listStyleType,margin,marginBlock,marginBlockEnd,marginBlockStart,marginBottom,marginInline,marginInlineEnd,marginInlineStart,marginLeft,marginRight,marginTop,marginTrim,marker,markerEnd,markerMid,markerStart,mask,maskBorder,maskBorderMode,maskBorderOutset,maskBorderRepeat,maskBorderSlice,maskBorderSource,maskBorderWidth,maskClip,maskComposite,maskImage,maskMode,maskOrigin,maskPosition,maskRepeat,maskSize,maskType,masonryAutoFlow,mathDepth,mathShift,mathStyle,maxBlockSize,maxHeight,maxInlineSize,maxLines,maxWidth,minBlockSize,minHeight,minInlineSize,minWidth,mixBlendMode,objectFit,objectPosition,offset,offsetAnchor,offsetDistance,offsetPath,offsetPosition,offsetRotate,opacity,order,orphans,outline,outlineColor,outlineOffset,outlineStyle,outlineWidth,overflow,overflowAnchor,overflowBlock,overflowClipBox,overflowClipMargin,overflowInline,overflowWrap,overflowX,overflowY,overlay,overscrollBehavior,overscrollBehaviorBlock,overscrollBehaviorInline,overscrollBehaviorX,overscrollBehaviorY,padding,paddingBlock,paddingBlockEnd,paddingBlockStart,paddingBottom,paddingInline,paddingInlineEnd,paddingInlineStart,paddingLeft,paddingRight,paddingTop,page,pageBreakAfter,pageBreakBefore,pageBreakInside,paintOrder,perspective,perspectiveOrigin,placeContent,placeItems,placeSelf,pointerEvents,position,positionAnchor,positionArea,positionTry,positionTryFallbacks,positionTryOrder,positionVisibility,printColorAdjust,quotes,r,resize,right,rotate,rowGap,rubyAlign,rubyMerge,rubyPosition,rx,ry,scale,scrollBehavior,scrollMargin,scrollMarginBlock,scrollMarginBlockEnd,scrollMarginBlockStart,scrollMarginBottom,scrollMarginInline,scrollMarginInlineEnd,scrollMarginInlineStart,scrollMarginLeft,scrollMarginRight,scrollMarginTop,scrollPadding,scrollPaddingBlock,scrollPaddingBlockEnd,scrollPaddingBlockStart,scrollPaddingBottom,scrollPaddingInline,scrollPaddingInlineEnd,scrollPaddingInlineStart,scrollPaddingLeft,scrollPaddingRight,scrollPaddingTop,scrollSnapAlign,scrollSnapCoordinate,scrollSnapDestination,scrollSnapPointsX,scrollSnapPointsY,scrollSnapStop,scrollSnapType,scrollSnapTypeX,scrollSnapTypeY,scrollTimeline,scrollTimelineAxis,scrollTimelineName,scrollbarColor,scrollbarGutter,scrollbarWidth,shapeImageThreshold,shapeMargin,shapeOutside,shapeRendering,stopColor,stopOpacity,stroke,strokeDasharray,strokeDashoffset,strokeLinecap,strokeLinejoin,strokeMiterlimit,strokeOpacity,strokeWidth,tabSize,tableLayout,textAlign,textAlignLast,textAnchor,textBox,textBoxEdge,textBoxTrim,textCombineUpright,textDecoration,textDecorationColor,textDecorationLine,textDecorationSkip,textDecorationSkipInk,textDecorationStyle,textDecorationThickness,textEmphasis,textEmphasisColor,textEmphasisPosition,textEmphasisStyle,textIndent,textJustify,textOrientation,textOverflow,textRendering,textShadow,textSizeAdjust,textSpacingTrim,textTransform,textUnderlineOffset,textUnderlinePosition,textWrap,textWrapMode,textWrapStyle,timelineScope,top,touchAction,transform,transformBox,transformOrigin,transformStyle,transition,transitionBehavior,transitionDelay,transitionDuration,transitionProperty,transitionTimingFunction,translate,unicodeBidi,userSelect,vectorEffect,verticalAlign,viewTimeline,viewTimelineAxis,viewTimelineInset,viewTimelineName,viewTransitionName,visibility,whiteSpace,whiteSpaceCollapse,widows,width,willChange,wordBreak,wordSpacing,wordWrap,writingMode,x,y,zIndex,zoom,alignmentBaseline,baselineShift,colorInterpolation,colorRendering,glyphOrientationVertical",dk=uk.split(",").concat(ck),hk=new Map(dk.map(e=>[e,!0]));function fk(e){const t=Object.create(null);return n=>(t[n]===void 0&&(t[n]=e(n)),t[n])}var gk=/&|@/,pk=fk(e=>hk.has(e)||e.startsWith("--")||gk.test(e));function hf(e,t){const n={};return _t(e,(r,i)=>{r&&(n[i.join(".")]=r.value)},{stop:t}),n}var mk=Ii;Ii.default=Ii,Ii.stable=pf,Ii.stableStringify=pf;var ls="[...]",ff="[Circular]",Wn=[],Hn=[];function gf(){return{depthLimit:Number.MAX_SAFE_INTEGER,edgesLimit:Number.MAX_SAFE_INTEGER}}function Ii(e,t,n,r){typeof r>"u"&&(r=gf()),wl(e,"",0,[],void 0,0,r);var i;try{Hn.length===0?i=JSON.stringify(e,t,n):i=JSON.stringify(e,mf(t),n)}catch{return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]")}finally{for(;Wn.length!==0;){var o=Wn.pop();o.length===4?Object.defineProperty(o[0],o[1],o[3]):o[0][o[1]]=o[2]}}return i}function Ar(e,t,n,r){var i=Object.getOwnPropertyDescriptor(r,n);i.get!==void 0?i.configurable?(Object.defineProperty(r,n,{value:e}),Wn.push([r,n,t,i])):Hn.push([t,n,e]):(r[n]=e,Wn.push([r,n,t]))}function wl(e,t,n,r,i,o,s){o+=1;var a;if(typeof e=="object"&&e!==null){for(a=0;as.depthLimit){Ar(ls,e,t,i);return}if(typeof s.edgesLimit<"u"&&n+1>s.edgesLimit){Ar(ls,e,t,i);return}if(r.push(e),Array.isArray(e))for(a=0;at?1:0}function pf(e,t,n,r){typeof r>"u"&&(r=gf());var i=El(e,"",0,[],void 0,0,r)||e,o;try{Hn.length===0?o=JSON.stringify(i,t,n):o=JSON.stringify(i,mf(t),n)}catch{return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]")}finally{for(;Wn.length!==0;){var s=Wn.pop();s.length===4?Object.defineProperty(s[0],s[1],s[3]):s[0][s[1]]=s[2]}}return o}function El(e,t,n,r,i,o,s){o+=1;var a;if(typeof e=="object"&&e!==null){for(a=0;as.depthLimit){Ar(ls,e,t,i);return}if(typeof s.edgesLimit<"u"&&n+1>s.edgesLimit){Ar(ls,e,t,i);return}if(r.push(e),Array.isArray(e))for(a=0;a0)for(var r=0;r{const t=Object.create(null);function n(...r){const i=r.map(o=>bk(o)).join("|");return t[i]===void 0&&(t[i]=e(...r)),t[i]}return n},vf=16,cs="px",kl="em",Pi="rem";function bf(e=""){const t=new RegExp(String.raw`-?\d+(?:\.\d+|\d*)`),n=new RegExp(`${cs}|${kl}|${Pi}`),r=e.match(new RegExp(`${t.source}(${n.source})`));return r==null?void 0:r[1]}function yf(e=""){if(typeof e=="number")return`${e}px`;const t=bf(e);if(!t||t===cs)return e;if(t===kl||t===Pi)return`${parseFloat(e)*vf}${cs}`}function xf(e=""){const t=bf(e);if(!t||t===Pi)return e;if(t===kl)return`${parseFloat(e)}${Pi}`;if(t===cs)return`${parseFloat(e)/vf}${Pi}`}const yk=e=>e.charAt(0).toUpperCase()+e.slice(1);function xk(e){const t=Ck(e),n=Object.fromEntries(t);function r(h){return n[h]}function i(h){return _r(r(h))}function o(){const h=Object.keys(n),m=Sk(h),f=h.flatMap(g=>{const p=r(g),b=[`${g}Down`,_r({max:us(p.min)})],C=[g,_r({min:p.min})],S=[`${g}Only`,i(g)];return[C,S,b]}).filter(([,g])=>g!=="").concat(m.map(([g,p])=>{const b=r(g),C=r(p);return[`${g}To${yk(p)}`,_r({min:b.min,max:us(C.min)})]}));return Object.fromEntries(f)}function s(){const h=o();return Object.fromEntries(Object.entries(h))}const a=s(),l=h=>a[h];function c(){return["base",...Object.keys(n)]}function u(h){return _r({min:r(h).min})}function d(h){return _r({max:us(r(h).min)})}return{values:Object.values(n),only:i,keys:c,conditions:a,getCondition:l,up:u,down:d}}function us(e){const t=parseFloat(yf(e)??"")-.04;return xf(`${t}px`)}function Ck(e){return Object.entries(e).sort(([,n],[,r])=>parseInt(n,10){var a;let s=null;return i<=o.length-1&&(s=(a=o[i+1])==null?void 0:a[1]),s!=null&&(s=us(s)),[n,{name:n,min:xf(r),max:s}]})}function Sk(e){const t=[];return e.forEach((n,r)=>{let i=r;i++;let o=e[i];for(;o;)t.push([n,o]),i++,o=e[i]}),t}function _r({min:e,max:t}){return e==null&&t==null?"":["@media screen",e&&`(min-width: ${e})`,t&&`(max-width: ${t})`].filter(Boolean).join(" and ")}const wk=(e,t)=>Object.fromEntries(Object.entries(e).map(([n,r])=>t(n,r))),Ek=e=>{const{breakpoints:t,conditions:n={}}=e,r=wk(n,(u,d)=>[`_${u}`,d]),i=Object.assign({},r,t.conditions);function o(){return Object.keys(i)}function s(u){return o().includes(u)||/^@|&|&$/.test(u)||u.startsWith("_")}function a(u){return u.filter(d=>d!=="base").sort((d,h)=>{const m=s(d),f=s(h);return m&&!f?1:!m&&f?-1:0})}function l(u){return u.startsWith("@breakpoint")?t.getCondition(u.replace("@breakpoint ","")):u}function c(u){return Reflect.get(i,u)||u}return{keys:o,sort:a,has:s,resolve:c,breakpoints:t.keys(),expandAtRule:l}},Cf=e=>({minMax:new RegExp(`(!?\\(\\s*min(-device-)?-${e})(.| )+\\(\\s*max(-device)?-${e}`,"i"),min:new RegExp(`\\(\\s*min(-device)?-${e}`,"i"),maxMin:new RegExp(`(!?\\(\\s*max(-device)?-${e})(.| -)+\\(\\s*min(-device)?-${e}`,"i"),max:new RegExp(`\\(\\s*max(-device)?-${e}`,"i")}),Sk=Cf("width"),wk=Cf("height"),Sf=e=>({isMin:Pf(e.minMax,e.maxMin,e.min),isMax:Pf(e.maxMin,e.minMax,e.max)}),{isMin:kl,isMax:wf}=Sf(Sk),{isMin:Ol,isMax:Ef}=Sf(wk),kf=/print/i,Of=/^print$/i,Ek=/(-?\d*\.?\d+)(ch|em|ex|px|rem)/,kk=/(\d)/,Oi=Number.MAX_VALUE,Ok={ch:8.8984375,em:16,rem:16,ex:8.296875,px:1};function If(e){const t=Ek.exec(e)||(kl(e)||Ol(e)?kk.exec(e):null);if(!t)return Oi;if(t[0]==="0")return 0;const n=parseFloat(t[1]),r=t[2];return n*(Ok[r]||1)}function Pf(e,t,n){return r=>e.test(r)||!t.test(r)&&n.test(r)}function Ik(e,t){const n=kf.test(e),r=Of.test(e),i=kf.test(t),o=Of.test(t);return n&&i?!r&&o?1:r&&!o?-1:e.localeCompare(t):n?1:i?-1:null}const Pk=yt((e,t)=>{const n=Ik(e,t);if(n!==null)return n;const r=kl(e)||Ol(e),i=wf(e)||Ef(e),o=kl(t)||Ol(t),s=wf(t)||Ef(t);if(r&&s)return-1;if(i&&o)return 1;const a=If(e),l=If(t);return a===Oi&&l===Oi?e.localeCompare(t):a===Oi?1:l===Oi?-1:a!==l?a>l?i?-1:1:i?1:-1:e.localeCompare(t)});function Rf(e){return e.sort(([t],[n])=>Pk(t,n))}function Tf(e){const t=[],n=[],r={};for(const[s,a]of Object.entries(e))s.startsWith("@media")?t.push([s,a]):s.startsWith("@container")?n.push([s,a]):He(a)?r[s]=Tf(a):r[s]=a;const i=Rf(t),o=Rf(n);return{...r,...Object.fromEntries(i),...Object.fromEntries(o)}}const Nf=/\s*!(important)?/i,Rk=e=>Ot(e)?Nf.test(e):!1,Tk=e=>Ot(e)?e.replace(Nf,"").trim():e;function Af(e){const{transform:t,conditions:n,normalize:r}=e,i=_k(e);return yt(function(...s){const a=i(...s),l=r(a),c=Object.create(null);return At(l,(u,d)=>{const h=Rk(u);if(u==null)return;const[m,...f]=n.sort(d).map(n.resolve);h&&(u=Tk(u));let g=t(m,u)??Object.create(null);g=At(g,p=>Ot(p)&&h?`${p} !important`:p,{getKey:p=>n.expandAtRule(p)}),Nk(c,f.flat(),g)}),Tf(c)})}function Nk(e,t,n){let r=e;for(const i of t)i&&(r[i]||(r[i]=Object.create(null)),r=r[i]);Or(r,n)}function Ak(...e){return e.filter(t=>He(t)&&Object.keys(ri(t)).length>0)}function _k(e){function t(n){const r=Ak(...n);return r.length===1?r:r.map(i=>e.normalize(i))}return yt(function(...r){return Or({},...t(r))})}const _f=e=>({base:{},variants:{},defaultVariants:{},compoundVariants:[],...e});function Vk(e){const{css:t,conditions:n,normalize:r,layers:i}=e;function o(a={}){const{base:l,variants:c,defaultVariants:u,compoundVariants:d}=_f(a),h=Af({conditions:n,normalize:r,transform(x,S){var C;return(C=c[x])==null?void 0:C[S]}}),m=(x={})=>{const S=r({...u,...ri(x)});let C={...l};Or(C,h(S));const w=s(d,S);return i.wrap("recipes",t(C,w))},f=Object.keys(c),g=x=>{const S=of(x,["recipe"]),[C,w]=cr(S,f);return f.includes("colorPalette")||(C.colorPalette=x.colorPalette||u.colorPalette),f.includes("orientation")&&(w.orientation=x.orientation),[C,w]},p=Object.fromEntries(Object.entries(c).map(([x,S])=>[x,Object.keys(S)]));return Object.assign(x=>t(m(x)),{className:a.className,__cva__:!0,variantMap:p,variantKeys:f,raw:m,config:a,splitVariantProps:g,merge(x){return o(Fk(e)(this,x))}})}function s(a,l){let c={};return a.forEach(u=>{Object.entries(u).every(([h,m])=>h==="css"?!0:(Array.isArray(m)?m:[m]).some(g=>l[h]===g))&&(c=t(c,u.css))}),c}return o}function Fk(e){const{css:t}=e;return function(r,i){const o=_f(i.config),s=Jc(r.variantKeys,Object.keys(i.variants)),a=t(r.base,o.base),l=Object.fromEntries(s.map(h=>[h,t(r.config.variants[h],o.variants[h])])),c=Or(r.config.defaultVariants,o.defaultVariants),u=[...r.compoundVariants,...o.compoundVariants];return{className:st(r.className,i.className),base:a,variants:l,defaultVariants:c,compoundVariants:u}}}const Lk={reset:"reset",base:"base",tokens:"tokens",recipes:"recipes"},Vf={reset:0,base:1,tokens:2,recipes:3};function Dk(e){const t=e.layers??Lk,r=Object.values(t).sort((i,o)=>Vf[i]-Vf[o]);return{names:r,atRule:`@layer ${r.join(", ")};`,wrap(i,o){return e.disableLayers?o:{[`@layer ${t[i]}`]:o}}}}function zk(e){const{utility:t,normalize:n}=e,{hasShorthand:r,resolveShorthand:i}=t;return function(o){return At(o,n,{stop:s=>Array.isArray(s),getKey:r?i:void 0})}}function Mk(e){const{preflight:t}=e;if(!t)return{};const{scope:n="",level:r="parent"}=He(t)?t:{};let i="";n&&r==="parent"?i=`${n} `:n&&r==="element"&&(i=`&${n}`);const o={"*":{margin:"0px",padding:"0px",font:"inherit",wordWrap:"break-word",WebkitTapHighlightColor:"transparent"},"*, *::before, *::after, *::backdrop":{boxSizing:"border-box",borderWidth:"0px",borderStyle:"solid",borderColor:"var(--global-color-border, currentColor)"},hr:{height:"0px",color:"inherit",borderTopWidth:"1px"},body:{minHeight:"100dvh",position:"relative"},img:{borderStyle:"none"},"img, svg, video, canvas, audio, iframe, embed, object":{display:"block",verticalAlign:"middle"},iframe:{border:"none"},"img, video":{maxWidth:"100%",height:"auto"},"p, h1, h2, h3, h4, h5, h6":{overflowWrap:"break-word"},"ol, ul":{listStyle:"none"},"code, kbd, pre, samp":{fontSize:"1em"},"button, [type='button'], [type='reset'], [type='submit']":{WebkitAppearance:"button",backgroundColor:"transparent",backgroundImage:"none"},"button, input, optgroup, select, textarea":{color:"inherit"},"button, select":{textTransform:"none"},table:{textIndent:"0px",borderColor:"inherit",borderCollapse:"collapse"},"*::placeholder":{opacity:"unset",color:"#9ca3af",userSelect:"none"},textarea:{resize:"vertical"},summary:{display:"list-item"},small:{fontSize:"80%"},"sub, sup":{fontSize:"75%",lineHeight:0,position:"relative",verticalAlign:"baseline"},sub:{bottom:"-0.25em"},sup:{top:"-0.5em"},dialog:{padding:"0px"},a:{color:"inherit",textDecoration:"inherit"},"abbr:where([title])":{textDecoration:"underline dotted"},"b, strong":{fontWeight:"bolder"},"code, kbd, samp, pre":{fontSize:"1em","--font-mono-fallback":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New'",fontFamily:"var(--global-font-mono, var(--font-mono-fallback))"},'input[type="text"], input[type="email"], input[type="search"], input[type="password"]':{WebkitAppearance:"none",MozAppearance:"none"},"input[type='search']":{WebkitAppearance:"textfield",outlineOffset:"-2px"},"::-webkit-search-decoration, ::-webkit-search-cancel-button":{WebkitAppearance:"none"},"::-webkit-file-upload-button":{WebkitAppearance:"button",font:"inherit"},'input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button':{height:"auto"},"input[type='number']":{MozAppearance:"textfield"},":-moz-ui-invalid":{boxShadow:"none"},":-moz-focusring":{outline:"auto"},"[hidden]:where(:not([hidden='until-found']))":{display:"none !important"}},s={[n||"html"]:{lineHeight:1.5,"--font-fallback":"ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",WebkitTextSizeAdjust:"100%",WebkitFontSmoothing:"antialiased",MozOsxFontSmoothing:"grayscale",textRendering:"optimizeLegibility",touchAction:"manipulation",MozTabSize:"4",tabSize:"4",fontFamily:"var(--global-font-body, var(--font-fallback))"}};if(r==="element"){const a=Object.entries(o).reduce((l,[c,u])=>(l[c]={[i]:u},l),{});Object.assign(s,a)}else i?s[i]=o:Object.assign(s,o);return s}function $k(e){const{conditions:t,isValidProperty:n}=e;return function(i){return At(i,o=>o,{getKey:(o,s)=>He(s)&&!t.has(o)&&!n(o)?Bk(o).map(a=>"&"+a).join(", "):o})}}function Bk(e){const t=[];let n=0,r="",i=!1;for(let o=0;o{const t=i=>{var o;return{base:((o=e.base)==null?void 0:o[i])??{},variants:{},defaultVariants:e.defaultVariants??{},compoundVariants:e.compoundVariants?Wk(e.compoundVariants,i):[]}},r=(e.slots??[]).map(i=>[i,t(i)]);for(const[i,o]of Object.entries(e.variants??{}))for(const[s,a]of Object.entries(o))r.forEach(([l,c])=>{var u;(u=c.variants)[i]??(u[i]={}),c.variants[i][s]=a[l]??{}});return Object.fromEntries(r)},Wk=(e,t)=>e.filter(n=>n.css[t]).map(n=>({...n,css:n.css[t]}));function Hk(e){const{cva:t}=e;return function(r={}){const i=Object.entries(jk(r)).map(([d,h])=>[d,t(h)]);function o(d){const h=i.map(([m,f])=>[m,f(d)]);return Object.fromEntries(h)}const s=r.variants??{},a=Object.keys(s);function l(d){var g;const h=of(d,["recipe"]),[m,f]=cr(h,a);return a.includes("colorPalette")||(m.colorPalette=d.colorPalette||((g=r.defaultVariants)==null?void 0:g.colorPalette)),a.includes("orientation")&&(f.orientation=d.orientation),[m,f]}const c=Object.fromEntries(Object.entries(s).map(([d,h])=>[d,Object.keys(h)]));let u={};return r.className&&(u=Object.fromEntries(r.slots.map(d=>[d,`${r.className}__${d}`]))),Object.assign(o,{variantMap:c,variantKeys:a,splitVariantProps:l,classNameMap:u})}}const Uk=()=>e=>Array.from(new Set(e)),Gk=/([\0-\x1f\x7f]|^-?\d)|^-$|^-|[^\x80-\uFFFF\w-]/g,qk=function(e,t){return t?e==="\0"?"�":e==="-"&&e.length===1?"\\-":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16):"\\"+e},Ff=e=>(e+"").replace(Gk,qk),Lf=(e,t)=>{let n="",r=0,i="char",o="",s="";const a=[];for(;r{let t=0;const n=["("];for(;t{n instanceof Map?t[r]=Object.fromEntries(n):t[r]=n}),t}const zf=/({([^}]*)})/g,Xk=/[{}]/g,Yk=/\w+\.\w+/,Mf=e=>{if(!Ot(e))return[];const t=e.match(zf);return t?t.map(n=>n.replace(Xk,"")).map(n=>n.trim()):[]},Qk=e=>zf.test(e);function $f(e){var n,r,i;if(!((n=e.extensions)!=null&&n.references))return((i=(r=e.extensions)==null?void 0:r.cssVar)==null?void 0:i.ref)??e.value;const t=e.extensions.references??{};return e.value=Object.keys(t).reduce((o,s)=>{const a=t[s];if(a.extensions.conditions)return o;const l=$f(a);return o.replace(`{${s}}`,l)},e.value),delete e.extensions.references,e.value}function Bf(e){return He(e)&&e.reference?e.reference:String(e)}const cs=(e,...t)=>t.map(Bf).join(` ${e} `).replace(/calc/g,""),jf=(...e)=>`calc(${cs("+",...e)})`,Wf=(...e)=>`calc(${cs("-",...e)})`,Il=(...e)=>`calc(${cs("*",...e)})`,Hf=(...e)=>`calc(${cs("/",...e)})`,Uf=e=>{const t=Bf(e);return t!=null&&!Number.isNaN(parseFloat(t))?String(t).startsWith("-")?String(t).slice(1):`-${t}`:Il(t,-1)},Nr=Object.assign(e=>({add:(...t)=>Nr(jf(e,...t)),subtract:(...t)=>Nr(Wf(e,...t)),multiply:(...t)=>Nr(Il(e,...t)),divide:(...t)=>Nr(Hf(e,...t)),negate:()=>Nr(Uf(e)),toString:()=>e.toString()}),{add:jf,subtract:Wf,multiply:Il,divide:Hf,negate:Uf}),Jk={enforce:"pre",transform(e){const{prefix:t,allTokens:n,formatCssVar:r,formatTokenName:i,registerToken:o}=e;n.filter(({extensions:a})=>a.category==="spacing").forEach(a=>{const l=a.path.slice(),c=r(l,t);if(Ot(a.value)&&a.value==="0rem")return;const u=structuredClone(a);Object.assign(u.extensions,{negative:!0,prop:`-${a.extensions.prop}`,originalPath:l}),u.value=Nr.negate(c.ref);const d=u.path[u.path.length-1];d!=null&&(u.path[u.path.length-1]=`-${d}`),u.path&&(u.name=i(u.path)),o(u)})}},Zk=new Set(["spacing","sizes","borderWidths","fontSizes","radii"]),eO=[Jk,{enforce:"post",transform(e){const{allTokens:t,registerToken:n,formatTokenName:r}=e,i=t.filter(({extensions:a})=>a.category==="colors"),o=new Map,s=new Map;i.forEach(a=>{const{colorPalette:l}=a.extensions;l&&(l.keys.forEach(c=>{o.set(r(c),c)}),l.roots.forEach(c=>{var h;const u=r(c),d=s.get(u)||[];if(d.push(a),s.set(u,d),a.extensions.default&&c.length===1){const m=(h=l.keys[0])==null?void 0:h.filter(Boolean);if(!m.length)return;const f=c.concat(m);o.set(r(f),[])}}))}),o.forEach(a=>{const l=["colors","colorPalette",...a].filter(Boolean),c=r(l),u=r(l.slice(1));n({name:c,value:c,originalValue:c,path:l,extensions:{condition:"base",originalPath:l,category:"colors",prop:u,virtual:!0}},"pre")})}},{enforce:"post",transform(e){e.allTokens.filter(n=>Zk.has(n.extensions.category)&&!n.extensions.negative).forEach(n=>{Object.assign(n.extensions,{pixelValue:yf(n.value)})})}},{enforce:"post",transform(e){e.allTokens=e.allTokens.filter(t=>t.value!=="")}}],tO=[{type:"extensions",enforce:"pre",name:"tokens/css-var",transform(e,t){const{prefix:n,formatCssVar:r}=t,{negative:i,originalPath:o}=e.extensions,s=i?o:e.path;return{cssVar:r(s.filter(Boolean),n)}}},{enforce:"post",type:"value",name:"tokens/conditionals",transform(e,t){const{prefix:n,formatCssVar:r}=t,i=Mf(e.value);return i.length&&i.forEach(o=>{const s=r(o.split("."),n);e.value=e.value.replace(`{${s.ref}}`,s)}),e.value}},{type:"extensions",enforce:"pre",name:"tokens/colors/colorPalette",match(e){return e.extensions.category==="colors"&&!e.extensions.virtual},transform(e,t){let n=e.path.slice();if(n.pop(),n.shift(),n.length===0){const a=[...e.path];a.shift(),n=a}if(n.length===0)return{};const r=n.reduce((a,l,c,u)=>{const d=u.slice(0,c+1);return a.push(d),a},[]),i=n[0],o=t.formatTokenName(n),s=e.path.slice(e.path.indexOf(i)+1).reduce((a,l,c,u)=>(a.push(u.slice(c)),a),[]);return s.length===0&&s.push([""]),{colorPalette:{value:o,roots:r,keys:s}}}}],Gf=e=>He(e)&&Object.prototype.hasOwnProperty.call(e,"value");function nO(e){return e?{breakpoints:sf(e,t=>({value:t})),sizes:Object.fromEntries(Object.entries(e).map(([t,n])=>[`breakpoint-${t}`,{value:n}]))}:{breakpoints:{},sizes:{}}}function rO(e){const{prefix:t="",tokens:n={},semanticTokens:r={},breakpoints:i={}}=e,o=D=>D.join("."),s=(D,L)=>cf(D.join("-"),{prefix:L}),a=[],l=new Map,c=new Map,u=new Map,d=new Map,h=new Map,m=new Map,f=new Map,g=new Map,p=[];function v(D,L){a.push(D),l.set(D.name,D),L&&g.forEach(ne=>{ne.enforce===L&&H(ne,D)})}const x=nO(i),S=ri({...n,breakpoints:x.breakpoints,sizes:{...n.sizes,...x.sizes}});function C(){At(S,(D,L)=>{const ne=L.includes("DEFAULT");L=qf(L);const de=L[0],Ee=o(L),Le=Ot(D)?{value:D}:D,Kt={value:Le.value,originalValue:Le.value,name:Ee,path:L,extensions:{condition:"base",originalPath:L,category:de,prop:o(L.slice(1))}};ne&&(Kt.extensions.default=!0),v(Kt)},{stop:Gf}),At(r,(D,L)=>{const ne=L.includes("DEFAULT");L=Kf(qf(L));const de=L[0],Ee=o(L),Le=Ot(D.value)?{value:{base:D.value}}:D,Kt={value:Le.value.base||"",originalValue:Le.value.base||"",name:Ee,path:L,extensions:{originalPath:L,category:de,conditions:Le.value,condition:"base",prop:o(L.slice(1))}};ne&&(Kt.extensions.default=!0),v(Kt)},{stop:Gf})}function w(D){return l.get(D)}function P(D){const{condition:L}=D.extensions;L&&(c.has(L)||c.set(L,new Set),c.get(L).add(D))}function _(D){const{category:L,prop:ne}=D.extensions;L&&(f.has(L)||f.set(L,new Map),f.get(L).set(ne,D))}function R(D){const{condition:L,negative:ne,virtual:de,cssVar:Ee}=D.extensions;ne||de||!L||!Ee||(u.has(L)||u.set(L,new Map),u.get(L).set(Ee.var,D.value))}function N(D){const{category:L,prop:ne,cssVar:de,negative:Ee}=D.extensions;if(!L)return;m.has(L)||m.set(L,new Map);const Le=Ee?D.extensions.conditions?D.originalValue:D.value:de.ref;m.get(L).set(ne,Le),h.set([L,ne].join("."),Le)}function T(D){const{colorPalette:L,virtual:ne,default:de}=D.extensions;!L||ne||L.roots.forEach(Ee=>{var lb;const Le=o(Ee);d.has(Le)||d.set(Le,new Map);const Kt=oO([...D.path],[...Ee]),$s=o(Kt),Yr=w($s);if(!Yr||!Yr.extensions.cssVar)return;const{var:qA}=Yr.extensions.cssVar;if(d.get(Le).set(qA,D.extensions.cssVar.ref),de&&Ee.length===1){const KA=o(["colors","colorPalette"]),cb=w(KA);if(!cb)return;const XA=o(D.path),ub=w(XA);if(!ub)return;const db=(lb=L.keys[0])==null?void 0:lb.filter(Boolean);if(!db.length)return;const gc=o(Ee.concat(db));d.has(gc)||d.set(gc,new Map),d.get(gc).set(cb.extensions.cssVar.var,ub.extensions.cssVar.ref)}})}let j={};function I(){a.forEach(D=>{P(D),_(D),R(D),N(D),T(D)}),j=Df(m)}const F=(D,L)=>{var Yr;if(!D||typeof D!="string")return{invalid:!0,value:D};const[ne,de]=D.split("/");if(!ne||!de)return{invalid:!0,value:ne};const Ee=L(ne),Le=(Yr=w(`opacity.${de}`))==null?void 0:Yr.value;if(!Le&&isNaN(Number(de)))return{invalid:!0,value:ne};const Kt=Le?Number(Le)*100+"%":`${de}%`,$s=Ee??ne;return{invalid:!1,color:$s,value:`color-mix(in srgb, ${$s} ${Kt}, transparent)`}},Y=yt((D,L)=>h.get(D)??L),z=yt(D=>j[D]||null),V=yt(D=>Lf(D,L=>{if(!L)return;if(L.includes("/")){const de=F(L,Ee=>Y(Ee));if(de.invalid)throw new Error("Invalid color mix at "+L+": "+de.value);return de.value}const ne=Y(L);return ne||(Yk.test(L)?Ff(L):L)})),B={prefix:t,allTokens:a,tokenMap:l,registerToken:v,getByName:w,formatTokenName:o,formatCssVar:s,flatMap:h,cssVarMap:u,categoryMap:f,colorPaletteMap:d,getVar:Y,getCategoryValues:z,expandReferenceInValue:V};function K(...D){D.forEach(L=>{g.set(L.name,L)})}function $(...D){p.push(...D)}function H(D,L){if(L.extensions.references||ca(D.match)&&!D.match(L))return;const de=(Ee=>D.transform(Ee,B))(L);switch(!0){case D.type==="extensions":Object.assign(L.extensions,de);break;case D.type==="value":L.value=de;break;default:L[D.type]=de;break}}function X(D){p.forEach(L=>{L.enforce===D&&L.transform(B)})}function ue(D){g.forEach(L=>{L.enforce===D&&a.forEach(ne=>{H(L,ne)})})}function wn(){a.forEach(D=>{const L=iO(D);!L||L.length===0||L.forEach(ne=>{v(ne)})})}function ji(D){return Mf(D).map(ne=>w(ne)).filter(Boolean)}function Xr(){a.forEach(D=>{if(!Qk(D.value))return;const L=ji(D.value);D.extensions.references=L.reduce((ne,de)=>(ne[de.name]=de,ne),{})})}function fc(){a.forEach(D=>{$f(D)})}function GA(){X("pre"),ue("pre"),wn(),Xr(),fc(),X("post"),ue("post"),I()}return C(),K(...tO),$(...eO),GA(),B}function qf(e){return e[0]==="DEFAULT"?e:e.filter(t=>t!=="DEFAULT")}function Kf(e){return e.filter(t=>t!=="base")}function iO(e){if(!e.extensions.conditions)return;const{conditions:t}=e.extensions,n=[];return At(t,(r,i)=>{const o=Kf(i);if(!o.length)return;const s=structuredClone(e);s.value=r,s.extensions.condition=o.join(":"),n.push(s)}),n}function oO(e,t){const n=e.findIndex((r,i)=>t.every((o,s)=>e[i+s]===o));return n===-1||(e.splice(n,t.length),e.splice(n,0,"colorPalette")),e}Uk()(["aspectRatios","zIndex","opacity","colors","fonts","fontSizes","fontWeights","lineHeights","letterSpacings","sizes","shadows","spacing","radii","cursor","borders","borderWidths","borderStyles","durations","easings","animations","blurs","gradients","breakpoints","assets"]);function h5(e){return e}function sO(e){return Object.fromEntries(Object.entries(e).map(([t,n])=>[t,n]))}function aO(e){const t=sO(e.config),n=e.tokens,r=new Map,i=new Map;function o(R,N){t[R]=N,s(R,N)}const s=(R,N)=>{const T=g(N);T&&(i.set(R,T),d(R,N))},a=()=>{for(const[R,N]of Object.entries(t))N&&s(R,N)},l=()=>{for(const[R,N]of Object.entries(t)){const{shorthand:T}=N??{};if(!T)continue;(Array.isArray(T)?T:[T]).forEach(I=>r.set(I,R))}},c=()=>{const R=Df(n.colorPaletteMap);o("colorPalette",{values:Object.keys(R),transform:yt(N=>R[N])})},u=new Map,d=(R,N)=>{if(!N)return;const T=g(N,I=>`type:Tokens["${I}"]`);if(typeof T=="object"&&T.type){u.set(R,new Set([`type:${T.type}`]));return}if(T){const I=new Set(Object.keys(T));u.set(R,I)}const j=u.get(R)??new Set;N.property&&u.set(R,j.add(`CssProperties["${N.property}"]`))},h=()=>{for(const[R,N]of Object.entries(t))N&&d(R,N)},m=(R,N)=>{const T=u.get(R)??new Set;u.set(R,new Set([...T,...N]))},f=()=>{const R=new Map;for(const[N,T]of u.entries()){if(T.size===0){R.set(N,["string"]);continue}const j=Array.from(T).map(I=>I.startsWith("CssProperties")?I:I.startsWith("type:")?I.replace("type:",""):JSON.stringify(I));R.set(N,j)}return R},g=(R,N)=>{const{values:T}=R,j=I=>{const F=N==null?void 0:N(I);return F?{[F]:F}:void 0};return Ot(T)?(j==null?void 0:j(T))??n.getCategoryValues(T)??{}:Array.isArray(T)?T.reduce((I,F)=>(I[F]=F,I),{}):ca(T)?T(N?j:n.getCategoryValues):T},p=yt((R,N)=>({[R]:R.startsWith("--")?n.getVar(N,N):N})),v=Object.assign(n.getVar,{raw:R=>n.getByName(R)}),x=yt((R,N)=>{var Y;const T=w(R);Ot(N)&&!N.includes("_EMO_")&&(N=n.expandReferenceInValue(N));const j=t[T];if(!j)return p(T,N);const I=(Y=i.get(T))==null?void 0:Y[N];if(!j.transform)return p(R,I??N);const F=z=>jE(z,v);return j.transform(I??N,{raw:N,token:v,utils:{colorMix:F}})});function S(){l(),c(),a(),h()}S();const C=r.size>0,w=yt(R=>r.get(R)??R);return{keys:()=>[...Array.from(r.keys()),...Object.keys(t)],hasShorthand:C,transform:x,shorthands:r,resolveShorthand:w,register:o,getTypes:f,addPropertyType:m}}const qe={};function Xf(...e){const t=af(...e),{theme:n={},utilities:r={},globalCss:i={},cssVarsRoot:o=":where(:root, :host)",cssVarsPrefix:s="chakra",preflight:a}=t,l=Dk(t),c=rO({breakpoints:n.breakpoints,tokens:n.tokens,semanticTokens:n.semanticTokens,prefix:s}),u=vk(n.breakpoints??qe),d=Ck({conditions:t.conditions??qe,breakpoints:u}),h=aO({config:r,tokens:c});function m(){const{textStyles:$,layerStyles:H,animationStyles:X}=n,ue=ri({textStyle:$,layerStyle:H,animationStyle:X});for(const[wn,ji]of Object.entries(ue)){const Xr=hf(ji??qe,Yf);h.register(wn,{values:Object.keys(Xr),transform(fc){return S(Xr[fc])}})}}m(),h.addPropertyType("animationName",Object.keys(n.keyframes??qe));const f=new Set(["css",...h.keys(),...d.keys()]),g=yt($=>f.has($)||hk($)),p=$=>Array.isArray($)?$.reduce((H,X,ue)=>{const wn=d.breakpoints[ue];return X!=null&&(H[wn]=X),H},{}):$,v=zk({utility:h,normalize:p}),x=$k({conditions:d,isValidProperty:g}),S=Af({transform:h.transform,conditions:d,normalize:v}),C=Vk({css:S,conditions:d,normalize:v,layers:l}),w=Hk({cva:C});function P(){const $={};for(const[H,X]of c.cssVarMap.entries()){const ue=Object.fromEntries(X);if(Object.keys(ue).length===0)continue;const wn=H==="base"?o:d.resolve(H),ji=wn.startsWith("@"),Xr=S(x({[wn]:ji?{[o]:ue}:ue}));Or($,Xr)}return l.wrap("tokens",$)}function _(){const $=Object.fromEntries(Object.entries(n.keyframes??qe).map(([X,ue])=>[`@keyframes ${X}`,ue])),H=Object.assign({},$,S(x(i)));return l.wrap("base",H)}function R($){return cr($,g)}function N(){const $=Mk({preflight:a});return l.wrap("reset",$)}const T=lO(c),j=($,H)=>{var X;return((X=T.get($))==null?void 0:X.value)||H};j.var=($,H)=>{var X;return((X=T.get($))==null?void 0:X.variable)||H};function I($,H){var X;return((X=n.recipes)==null?void 0:X[$])??H}function F($,H){var X;return((X=n.slotRecipes)==null?void 0:X[$])??H}function Y($){return Object.hasOwnProperty.call(n.recipes??qe,$)}function z($){return Object.hasOwnProperty.call(n.slotRecipes??qe,$)}function V($){return Y($)||z($)}const B=[N(),_(),P()],K={layerStyles:Pl(n.layerStyles??qe),textStyles:Pl(n.textStyles??qe),animationStyles:Pl(n.animationStyles??qe),tokens:Qf(c,Object.keys(n.tokens??qe),($,H)=>!$.extensions.conditions&&!H.includes("colorPalette")),semanticTokens:Qf(c,Object.keys(n.semanticTokens??qe),$=>!!$.extensions.conditions),keyframes:Jf(n.keyframes??qe),breakpoints:Jf(n.breakpoints??qe)};return{$$chakra:!0,_config:t,_global:B,breakpoints:u,tokens:c,conditions:d,utility:h,token:j,properties:f,layers:l,isValidProperty:g,splitCssProps:R,normalizeValue:p,getTokenCss:P,getGlobalCss:_,getPreflightCss:N,css:S,cva:C,sva:w,getRecipe:I,getSlotRecipe:F,hasRecipe:V,isRecipe:Y,isSlotRecipe:z,query:K}}function lO(e){const t=new Map;return e.allTokens.forEach(n=>{const{cssVar:r,virtual:i,conditions:o}=n.extensions,s=o||i?r.ref:n.value;t.set(n.name,{value:s,variable:r.ref})}),t}const Yf=e=>He(e)&&"value"in e,Pl=e=>({list(){return Object.keys(hf(e,Yf))},search(t){return this.list().filter(n=>n.includes(t))}}),Qf=(e,t,n)=>({categoryKeys:t,list(r){var i;return Array.from(((i=e.categoryMap.get(r))==null?void 0:i.entries())??[]).reduce((o,[s,a])=>(n(a,s)&&o.push(s),o),[])},search(r,i){return this.list(r).filter(o=>o.includes(i))}}),Jf=e=>({list(){return Object.keys(e)},search(t){return this.list().filter(n=>n.includes(t))}}),cO={sm:"480px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},Rl="var(--chakra-empty,/*!*/ /*!*/)",uO=GE({"*":{fontFeatureSettings:'"cv11"',"--ring-inset":Rl,"--ring-offset-width":"0px","--ring-offset-color":"#fff","--ring-color":"rgba(66, 153, 225, 0.6)","--ring-offset-shadow":"0 0 #0000","--ring-shadow":"0 0 #0000",...Object.fromEntries(["brightness","contrast","grayscale","hue-rotate","invert","saturate","sepia","drop-shadow"].map(e=>[`--${e}`,Rl])),...Object.fromEntries(["blur","brightness","contrast","grayscale","hue-rotate","invert","opacity","saturate","sepia"].map(e=>[`--backdrop-${e}`,Rl])),"--global-font-mono":"fonts.mono","--global-font-body":"fonts.body","--global-color-border":"colors.border"},html:{color:"fg",bg:"bg",lineHeight:"1.5",colorPalette:"gray"},"*::placeholder, *[data-placeholder]":{color:"fg.muted/80"},"*::selection":{bg:"colorPalette.emphasized/80"}}),dO=XE({"fill.muted":{value:{background:"colorPalette.muted",color:"colorPalette.fg"}},"fill.subtle":{value:{background:"colorPalette.subtle",color:"colorPalette.fg"}},"fill.surface":{value:{background:"colorPalette.subtle",color:"colorPalette.fg",boxShadow:"0 0 0px 1px var(--shadow-color)",boxShadowColor:"colorPalette.muted"}},"fill.solid":{value:{background:"colorPalette.solid",color:"colorPalette.contrast"}},"outline.subtle":{value:{color:"colorPalette.fg",boxShadow:"inset 0 0 0px 1px var(--shadow-color)",boxShadowColor:"colorPalette.subtle"}},"outline.solid":{value:{borderWidth:"1px",borderColor:"colorPalette.solid",color:"colorPalette.fg"}},"indicator.bottom":{value:{position:"relative","--indicator-color-fallback":"colors.colorPalette.solid",_before:{content:'""',position:"absolute",bottom:"var(--indicator-offset-y, 0)",insetInline:"var(--indicator-offset-x, 0)",height:"var(--indicator-thickness, 2px)",background:"var(--indicator-color, var(--indicator-color-fallback))"}}},"indicator.top":{value:{position:"relative","--indicator-color-fallback":"colors.colorPalette.solid",_before:{content:'""',position:"absolute",top:"var(--indicator-offset-y, 0)",insetInline:"var(--indicator-offset-x, 0)",height:"var(--indicator-thickness, 2px)",background:"var(--indicator-color, var(--indicator-color-fallback))"}}},"indicator.start":{value:{position:"relative","--indicator-color-fallback":"colors.colorPalette.solid",_before:{content:'""',position:"absolute",insetInlineStart:"var(--indicator-offset-x, 0)",insetBlock:"var(--indicator-offset-y, 0)",width:"var(--indicator-thickness, 2px)",background:"var(--indicator-color, var(--indicator-color-fallback))"}}},"indicator.end":{value:{position:"relative","--indicator-color-fallback":"colors.colorPalette.solid",_before:{content:'""',position:"absolute",insetInlineEnd:"var(--indicator-offset-x, 0)",insetBlock:"var(--indicator-offset-y, 0)",width:"var(--indicator-thickness, 2px)",background:"var(--indicator-color, var(--indicator-color-fallback))"}}},disabled:{value:{opacity:"0.5",cursor:"not-allowed"}},none:{value:{}}}),hO=KE({"slide-fade-in":{value:{transformOrigin:"var(--transform-origin)","&[data-placement^=top]":{animationName:"slide-from-bottom, fade-in"},"&[data-placement^=bottom]":{animationName:"slide-from-top, fade-in"},"&[data-placement^=left]":{animationName:"slide-from-right, fade-in"},"&[data-placement^=right]":{animationName:"slide-from-left, fade-in"}}},"slide-fade-out":{value:{transformOrigin:"var(--transform-origin)","&[data-placement^=top]":{animationName:"slide-to-bottom, fade-out"},"&[data-placement^=bottom]":{animationName:"slide-to-top, fade-out"},"&[data-placement^=left]":{animationName:"slide-to-right, fade-out"},"&[data-placement^=right]":{animationName:"slide-to-left, fade-out"}}},"scale-fade-in":{value:{transformOrigin:"var(--transform-origin)",animationName:"scale-in, fade-in"}},"scale-fade-out":{value:{transformOrigin:"var(--transform-origin)",animationName:"scale-out, fade-out"}}}),Tl=Se({className:"chakra-badge",base:{display:"inline-flex",alignItems:"center",borderRadius:"l2",gap:"1",fontWeight:"medium",fontVariantNumeric:"tabular-nums",whiteSpace:"nowrap",userSelect:"none"},variants:{variant:{solid:{bg:"colorPalette.solid",color:"colorPalette.contrast"},subtle:{bg:"colorPalette.subtle",color:"colorPalette.fg"},outline:{color:"colorPalette.fg",shadow:"inset 0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted"},surface:{bg:"colorPalette.subtle",color:"colorPalette.fg",shadow:"inset 0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted"},plain:{color:"colorPalette.fg"}},size:{xs:{textStyle:"2xs",px:"1",minH:"4"},sm:{textStyle:"xs",px:"1.5",minH:"5"},md:{textStyle:"sm",px:"2",minH:"6"},lg:{textStyle:"sm",px:"2.5",minH:"7"}}},defaultVariants:{variant:"subtle",size:"sm"}}),fO=Se({className:"chakra-button",base:{display:"inline-flex",appearance:"none",alignItems:"center",justifyContent:"center",userSelect:"none",position:"relative",borderRadius:"l2",whiteSpace:"nowrap",verticalAlign:"middle",borderWidth:"1px",borderColor:"transparent",cursor:"button",flexShrink:"0",outline:"0",lineHeight:"1.2",isolation:"isolate",fontWeight:"medium",transitionProperty:"common",transitionDuration:"moderate",focusVisibleRing:"outside",_disabled:{layerStyle:"disabled"},_icon:{flexShrink:"0"}},variants:{size:{"2xs":{h:"6",minW:"6",textStyle:"xs",px:"2",gap:"1",_icon:{width:"3.5",height:"3.5"}},xs:{h:"8",minW:"8",textStyle:"xs",px:"2.5",gap:"1",_icon:{width:"4",height:"4"}},sm:{h:"9",minW:"9",px:"3.5",textStyle:"sm",gap:"2",_icon:{width:"4",height:"4"}},md:{h:"10",minW:"10",textStyle:"sm",px:"4",gap:"2",_icon:{width:"5",height:"5"}},lg:{h:"11",minW:"11",textStyle:"md",px:"5",gap:"3",_icon:{width:"5",height:"5"}},xl:{h:"12",minW:"12",textStyle:"md",px:"5",gap:"2.5",_icon:{width:"5",height:"5"}},"2xl":{h:"16",minW:"16",textStyle:"lg",px:"7",gap:"3",_icon:{width:"6",height:"6"}}},variant:{solid:{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"transparent",_hover:{bg:"colorPalette.solid/90"},_expanded:{bg:"colorPalette.solid/90"}},subtle:{bg:"colorPalette.subtle",color:"colorPalette.fg",borderColor:"transparent",_hover:{bg:"colorPalette.muted"},_expanded:{bg:"colorPalette.muted"}},surface:{bg:"colorPalette.subtle",color:"colorPalette.fg",shadow:"0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted",_hover:{bg:"colorPalette.muted"},_expanded:{bg:"colorPalette.muted"}},outline:{borderWidth:"1px",borderColor:"colorPalette.muted",color:"colorPalette.fg",_hover:{bg:"colorPalette.subtle"},_expanded:{bg:"colorPalette.subtle"}},ghost:{bg:"transparent",color:"colorPalette.fg",_hover:{bg:"colorPalette.subtle"},_expanded:{bg:"colorPalette.subtle"}},plain:{color:"colorPalette.fg"}}},defaultVariants:{size:"md",variant:"solid"}}),Ve=Se({className:"chakra-checkmark",base:{display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:"0",color:"white",borderWidth:"1px",borderColor:"transparent",borderRadius:"l1",cursor:"checkbox",focusVisibleRing:"outside",_icon:{boxSize:"full"},_invalid:{colorPalette:"red",borderColor:"border.error"},_disabled:{opacity:"0.5",cursor:"disabled"}},variants:{size:{xs:{boxSize:"3"},sm:{boxSize:"4"},md:{boxSize:"5",p:"0.5"},lg:{boxSize:"6",p:"0.5"}},variant:{solid:{borderColor:"border.emphasized","&:is([data-state=checked], [data-state=indeterminate])":{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"colorPalette.solid"}},outline:{borderColor:"border","&:is([data-state=checked], [data-state=indeterminate])":{color:"colorPalette.fg",borderColor:"colorPalette.solid"}},subtle:{bg:"colorPalette.muted",borderColor:"colorPalette.muted","&:is([data-state=checked], [data-state=indeterminate])":{color:"colorPalette.fg"}},plain:{"&:is([data-state=checked], [data-state=indeterminate])":{color:"colorPalette.fg"}},inverted:{borderColor:"border",color:"colorPalette.fg","&:is([data-state=checked], [data-state=indeterminate])":{borderColor:"colorPalette.solid"}}},filled:{true:{bg:"bg"}}},defaultVariants:{variant:"solid",size:"md"}}),{variants:gO,defaultVariants:pO}=Tl,mO=Se({className:"chakra-code",base:{fontFamily:"mono",alignItems:"center",display:"inline-flex",borderRadius:"l2"},variants:gO,defaultVariants:pO}),Zf=Se({className:"color-swatch",base:{boxSize:"var(--swatch-size)",shadow:"inset 0 0 0 1px rgba(0, 0, 0, 0.1)","--checker-size":"8px","--checker-bg":"colors.bg","--checker-fg":"colors.bg.emphasized",background:"linear-gradient(var(--color), var(--color)), repeating-conic-gradient(var(--checker-fg) 0%, var(--checker-fg) 25%, var(--checker-bg) 0%, var(--checker-bg) 50%) 0% 50% / var(--checker-size) var(--checker-size) !important",display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:"0"},variants:{size:{"2xs":{"--swatch-size":"sizes.3.5"},xs:{"--swatch-size":"sizes.4"},sm:{"--swatch-size":"sizes.4.5"},md:{"--swatch-size":"sizes.5"},lg:{"--swatch-size":"sizes.6"},xl:{"--swatch-size":"sizes.7"},"2xl":{"--swatch-size":"sizes.8"},inherit:{"--swatch-size":"inherit"},full:{"--swatch-size":"100%"}},shape:{square:{borderRadius:"none"},circle:{borderRadius:"full"},rounded:{borderRadius:"l1"}}},defaultVariants:{size:"md",shape:"rounded"}}),vO=Se({className:"chakra-container",base:{position:"relative",maxWidth:"8xl",w:"100%",mx:"auto",px:{base:"4",md:"6",lg:"8"}},variants:{centerContent:{true:{display:"flex",flexDirection:"column",alignItems:"center"}},fluid:{true:{maxWidth:"full"}}}}),bO=Se({className:"chakra-heading",base:{fontFamily:"heading",fontWeight:"semibold"},variants:{size:{xs:{textStyle:"xs"},sm:{textStyle:"sm"},md:{textStyle:"md"},lg:{textStyle:"lg"},xl:{textStyle:"xl"},"2xl":{textStyle:"2xl"},"3xl":{textStyle:"3xl"},"4xl":{textStyle:"4xl"},"5xl":{textStyle:"5xl"},"6xl":{textStyle:"6xl"},"7xl":{textStyle:"7xl"}}},defaultVariants:{size:"xl"}}),yO=Se({className:"chakra-icon",base:{display:"inline-block",lineHeight:"1em",flexShrink:"0",color:"currentcolor",verticalAlign:"middle"},variants:{size:{inherit:{},xs:{boxSize:"3"},sm:{boxSize:"4"},md:{boxSize:"5"},lg:{boxSize:"6"},xl:{boxSize:"7"},"2xl":{boxSize:"8"}}},defaultVariants:{size:"inherit"}}),Ce=Se({className:"chakra-input",base:{width:"100%",minWidth:"0",outline:"0",position:"relative",appearance:"none",textAlign:"start",borderRadius:"l2",_disabled:{layerStyle:"disabled"},height:"var(--input-height)",minW:"var(--input-height)","--focus-color":"colors.colorPalette.focusRing","--error-color":"colors.border.error",_invalid:{focusRingColor:"var(--error-color)",borderColor:"var(--error-color)"}},variants:{size:{"2xs":{textStyle:"xs",px:"2","--input-height":"sizes.7"},xs:{textStyle:"xs",px:"2","--input-height":"sizes.8"},sm:{textStyle:"sm",px:"2.5","--input-height":"sizes.9"},md:{textStyle:"sm",px:"3","--input-height":"sizes.10"},lg:{textStyle:"md",px:"4","--input-height":"sizes.11"},xl:{textStyle:"md",px:"4.5","--input-height":"sizes.12"},"2xl":{textStyle:"lg",px:"5","--input-height":"sizes.16"}},variant:{outline:{bg:"transparent",borderWidth:"1px",borderColor:"border",focusVisibleRing:"inside",focusRingColor:"var(--focus-color)"},subtle:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted",focusVisibleRing:"inside",focusRingColor:"var(--focus-color)"},flushed:{bg:"transparent",borderBottomWidth:"1px",borderBottomColor:"border",borderRadius:"0",px:"0",_focusVisible:{borderColor:"var(--focus-color)",boxShadow:"0px 1px 0px 0px var(--focus-color)",_invalid:{borderColor:"var(--error-color)",boxShadow:"0px 1px 0px 0px var(--error-color)"}}}}},defaultVariants:{size:"md",variant:"outline"}}),xO=Se({className:"chakra-input-addon",base:{flex:"0 0 auto",width:"auto",display:"flex",alignItems:"center",whiteSpace:"nowrap",alignSelf:"stretch",borderRadius:"l2"},variants:{size:Ce.variants.size,variant:{outline:{borderWidth:"1px",borderColor:"border",bg:"bg.muted"},subtle:{borderWidth:"1px",borderColor:"transparent",bg:"bg.emphasized"},flushed:{borderBottom:"1px solid",borderColor:"inherit",borderRadius:"0",px:"0",bg:"transparent"}}},defaultVariants:{size:"md",variant:"outline"}}),CO=Se({className:"chakra-kbd",base:{display:"inline-flex",alignItems:"center",fontWeight:"medium",fontFamily:"mono",flexShrink:"0",whiteSpace:"nowrap",wordSpacing:"-0.5em",userSelect:"none",px:"1",borderRadius:"l2"},variants:{variant:{raised:{bg:"colorPalette.subtle",color:"colorPalette.fg",borderWidth:"1px",borderBottomWidth:"2px",borderColor:"colorPalette.muted"},outline:{borderWidth:"1px",color:"colorPalette.fg"},subtle:{bg:"colorPalette.muted",color:"colorPalette.fg"},plain:{color:"colorPalette.fg"}},size:{sm:{textStyle:"xs",height:"4.5"},md:{textStyle:"sm",height:"5"},lg:{textStyle:"md",height:"6"}}},defaultVariants:{size:"md",variant:"raised"}}),SO=Se({className:"chakra-link",base:{display:"inline-flex",alignItems:"center",outline:"none",gap:"1.5",cursor:"pointer",borderRadius:"l1",focusRing:"outside"},variants:{variant:{underline:{color:"colorPalette.fg",textDecoration:"underline",textUnderlineOffset:"3px",textDecorationColor:"currentColor/20"},plain:{color:"colorPalette.fg",_hover:{textDecoration:"underline",textUnderlineOffset:"3px",textDecorationColor:"currentColor/20"}}}},defaultVariants:{variant:"plain"}}),wO=Se({className:"chakra-mark",base:{bg:"transparent",color:"inherit",whiteSpace:"nowrap"},variants:{variant:{subtle:{bg:"colorPalette.subtle",color:"inherit"},solid:{bg:"colorPalette.solid",color:"colorPalette.contrast"},text:{fontWeight:"medium"},plain:{}}}}),Fe=Se({className:"chakra-radiomark",base:{display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:0,verticalAlign:"top",color:"white",borderWidth:"1px",borderColor:"transparent",borderRadius:"full",cursor:"radio",_focusVisible:{outline:"2px solid",outlineColor:"colorPalette.focusRing",outlineOffset:"2px"},_invalid:{colorPalette:"red",borderColor:"red.500"},_disabled:{opacity:"0.5",cursor:"disabled"},"& .dot":{height:"100%",width:"100%",borderRadius:"full",bg:"currentColor",scale:"0.4"}},variants:{variant:{solid:{borderWidth:"1px",borderColor:"border.emphasized",_checked:{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"colorPalette.solid"}},subtle:{borderWidth:"1px",bg:"colorPalette.muted",borderColor:"colorPalette.muted",color:"transparent",_checked:{color:"colorPalette.fg"}},outline:{borderWidth:"1px",borderColor:"inherit",_checked:{color:"colorPalette.fg",borderColor:"colorPalette.solid"},"& .dot":{scale:"0.6"}},inverted:{bg:"bg",borderWidth:"1px",borderColor:"inherit",_checked:{color:"colorPalette.solid",borderColor:"currentcolor"}}},size:{xs:{boxSize:"3"},sm:{boxSize:"4"},md:{boxSize:"5"},lg:{boxSize:"6"}},filled:{true:{bg:"bg"}}},defaultVariants:{variant:"solid",size:"md"}}),EO=Se({className:"chakra-separator",base:{display:"block",borderColor:"border"},variants:{variant:{solid:{borderStyle:"solid"},dashed:{borderStyle:"dashed"},dotted:{borderStyle:"dotted"}},orientation:{vertical:{borderInlineStartWidth:"var(--separator-thickness)"},horizontal:{borderTopWidth:"var(--separator-thickness)"}},size:{xs:{"--separator-thickness":"0.5px"},sm:{"--separator-thickness":"1px"},md:{"--separator-thickness":"2px"},lg:{"--separator-thickness":"3px"}}},defaultVariants:{size:"sm",variant:"solid",orientation:"horizontal"}}),kO=Se({className:"chakra-skeleton",base:{},variants:{loading:{true:{borderRadius:"l2",boxShadow:"none",backgroundClip:"padding-box",cursor:"default",color:"transparent",pointerEvents:"none",userSelect:"none",flexShrink:"0","&::before, &::after, *":{visibility:"hidden"}},false:{background:"unset",animation:"fade-in var(--fade-duration, 0.1s) ease-out !important"}},variant:{pulse:{background:"bg.emphasized",animation:"pulse",animationDuration:"var(--duration, 1.2s)"},shine:{"--animate-from":"200%","--animate-to":"-200%","--start-color":"colors.bg.muted","--end-color":"colors.bg.emphasized",backgroundImage:"linear-gradient(270deg,var(--start-color),var(--end-color),var(--end-color),var(--start-color))",backgroundSize:"400% 100%",animation:"bg-position var(--duration, 5s) ease-in-out infinite"},none:{animation:"none"}}},defaultVariants:{variant:"pulse",loading:!0}}),OO=Se({className:"chakra-skip-nav",base:{display:"inline-flex",bg:"bg.panel",padding:"2.5",borderRadius:"l2",fontWeight:"semibold",focusVisibleRing:"outside",textStyle:"sm",userSelect:"none",border:"0",height:"1px",width:"1px",margin:"-1px",outline:"0",overflow:"hidden",position:"absolute",clip:"rect(0 0 0 0)",_focusVisible:{clip:"auto",width:"auto",height:"auto",position:"fixed",top:"6",insetStart:"6"}}}),IO=Se({className:"chakra-spinner",base:{display:"inline-block",borderColor:"currentColor",borderStyle:"solid",borderWidth:"2px",borderRadius:"full",width:"var(--spinner-size)",height:"var(--spinner-size)",animation:"spin",animationDuration:"slowest","--spinner-track-color":"transparent",borderBottomColor:"var(--spinner-track-color)",borderInlineStartColor:"var(--spinner-track-color)"},variants:{size:{inherit:{"--spinner-size":"1em"},xs:{"--spinner-size":"sizes.3"},sm:{"--spinner-size":"sizes.4"},md:{"--spinner-size":"sizes.5"},lg:{"--spinner-size":"sizes.8"},xl:{"--spinner-size":"sizes.10"}}},defaultVariants:{size:"md"}}),PO=Se({className:"chakra-textarea",base:{width:"100%",minWidth:"0",outline:"0",position:"relative",appearance:"none",textAlign:"start",borderRadius:"l2",_disabled:{layerStyle:"disabled"},"--focus-color":"colors.colorPalette.focusRing","--error-color":"colors.border.error",_invalid:{focusRingColor:"var(--error-color)",borderColor:"var(--error-color)"}},variants:{size:{xs:{textStyle:"xs",px:"2",py:"1.5",scrollPaddingBottom:"1.5"},sm:{textStyle:"sm",px:"2.5",py:"2",scrollPaddingBottom:"2"},md:{textStyle:"sm",px:"3",py:"2",scrollPaddingBottom:"2"},lg:{textStyle:"md",px:"4",py:"3",scrollPaddingBottom:"3"},xl:{textStyle:"md",px:"4.5",py:"3.5",scrollPaddingBottom:"3.5"}},variant:{outline:{bg:"transparent",borderWidth:"1px",borderColor:"border",focusVisibleRing:"inside"},subtle:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted",focusVisibleRing:"inside"},flushed:{bg:"transparent",borderBottomWidth:"1px",borderBottomColor:"border",borderRadius:"0",px:"0",_focusVisible:{borderColor:"var(--focus-color)",boxShadow:"0px 1px 0px 0px var(--focus-color)"}}}},defaultVariants:{size:"md",variant:"outline"}}),RO={badge:Tl,button:fO,code:mO,container:vO,heading:bO,input:Ce,inputAddon:xO,kbd:CO,link:SO,mark:wO,separator:EO,skeleton:kO,skipNavLink:OO,spinner:IO,textarea:PO,icon:yO,checkmark:Ve,radiomark:Fe,colorSwatch:Zf},TO=xl.colors({bg:{DEFAULT:{value:{_light:"{colors.white}",_dark:"{colors.black}"}},subtle:{value:{_light:"{colors.gray.50}",_dark:"{colors.gray.950}"}},muted:{value:{_light:"{colors.gray.100}",_dark:"{colors.gray.900}"}},emphasized:{value:{_light:"{colors.gray.200}",_dark:"{colors.gray.800}"}},inverted:{value:{_light:"{colors.black}",_dark:"{colors.white}"}},panel:{value:{_light:"{colors.white}",_dark:"{colors.gray.950}"}},error:{value:{_light:"{colors.red.50}",_dark:"{colors.red.950}"}},warning:{value:{_light:"{colors.orange.50}",_dark:"{colors.orange.950}"}},success:{value:{_light:"{colors.green.50}",_dark:"{colors.green.950}"}},info:{value:{_light:"{colors.blue.50}",_dark:"{colors.blue.950}"}}},fg:{DEFAULT:{value:{_light:"{colors.black}",_dark:"{colors.gray.50}"}},muted:{value:{_light:"{colors.gray.600}",_dark:"{colors.gray.400}"}},subtle:{value:{_light:"{colors.gray.400}",_dark:"{colors.gray.500}"}},inverted:{value:{_light:"{colors.gray.50}",_dark:"{colors.black}"}},error:{value:{_light:"{colors.red.500}",_dark:"{colors.red.400}"}},warning:{value:{_light:"{colors.orange.600}",_dark:"{colors.orange.300}"}},success:{value:{_light:"{colors.green.600}",_dark:"{colors.green.300}"}},info:{value:{_light:"{colors.blue.600}",_dark:"{colors.blue.300}"}}},border:{DEFAULT:{value:{_light:"{colors.gray.200}",_dark:"{colors.gray.800}"}},muted:{value:{_light:"{colors.gray.100}",_dark:"{colors.gray.900}"}},subtle:{value:{_light:"{colors.gray.50}",_dark:"{colors.gray.950}"}},emphasized:{value:{_light:"{colors.gray.300}",_dark:"{colors.gray.700}"}},inverted:{value:{_light:"{colors.gray.800}",_dark:"{colors.gray.200}"}},error:{value:{_light:"{colors.red.500}",_dark:"{colors.red.400}"}},warning:{value:{_light:"{colors.orange.500}",_dark:"{colors.orange.400}"}},success:{value:{_light:"{colors.green.500}",_dark:"{colors.green.400}"}},info:{value:{_light:"{colors.blue.500}",_dark:"{colors.blue.400}"}}},gray:{contrast:{value:{_light:"{colors.white}",_dark:"{colors.black}"}},fg:{value:{_light:"{colors.gray.800}",_dark:"{colors.gray.200}"}},subtle:{value:{_light:"{colors.gray.100}",_dark:"{colors.gray.900}"}},muted:{value:{_light:"{colors.gray.200}",_dark:"{colors.gray.800}"}},emphasized:{value:{_light:"{colors.gray.300}",_dark:"{colors.gray.700}"}},solid:{value:{_light:"{colors.gray.900}",_dark:"{colors.white}"}},focusRing:{value:{_light:"{colors.gray.400}",_dark:"{colors.gray.400}"}}},red:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.red.700}",_dark:"{colors.red.300}"}},subtle:{value:{_light:"{colors.red.100}",_dark:"{colors.red.900}"}},muted:{value:{_light:"{colors.red.200}",_dark:"{colors.red.800}"}},emphasized:{value:{_light:"{colors.red.300}",_dark:"{colors.red.700}"}},solid:{value:{_light:"{colors.red.600}",_dark:"{colors.red.600}"}},focusRing:{value:{_light:"{colors.red.500}",_dark:"{colors.red.500}"}}},orange:{contrast:{value:{_light:"white",_dark:"black"}},fg:{value:{_light:"{colors.orange.700}",_dark:"{colors.orange.300}"}},subtle:{value:{_light:"{colors.orange.100}",_dark:"{colors.orange.900}"}},muted:{value:{_light:"{colors.orange.200}",_dark:"{colors.orange.800}"}},emphasized:{value:{_light:"{colors.orange.300}",_dark:"{colors.orange.700}"}},solid:{value:{_light:"{colors.orange.600}",_dark:"{colors.orange.500}"}},focusRing:{value:{_light:"{colors.orange.500}",_dark:"{colors.orange.500}"}}},green:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.green.700}",_dark:"{colors.green.300}"}},subtle:{value:{_light:"{colors.green.100}",_dark:"{colors.green.900}"}},muted:{value:{_light:"{colors.green.200}",_dark:"{colors.green.800}"}},emphasized:{value:{_light:"{colors.green.300}",_dark:"{colors.green.700}"}},solid:{value:{_light:"{colors.green.600}",_dark:"{colors.green.600}"}},focusRing:{value:{_light:"{colors.green.500}",_dark:"{colors.green.500}"}}},blue:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.blue.700}",_dark:"{colors.blue.300}"}},subtle:{value:{_light:"{colors.blue.100}",_dark:"{colors.blue.900}"}},muted:{value:{_light:"{colors.blue.200}",_dark:"{colors.blue.800}"}},emphasized:{value:{_light:"{colors.blue.300}",_dark:"{colors.blue.700}"}},solid:{value:{_light:"{colors.blue.600}",_dark:"{colors.blue.600}"}},focusRing:{value:{_light:"{colors.blue.500}",_dark:"{colors.blue.500}"}}},yellow:{contrast:{value:{_light:"black",_dark:"black"}},fg:{value:{_light:"{colors.yellow.800}",_dark:"{colors.yellow.300}"}},subtle:{value:{_light:"{colors.yellow.100}",_dark:"{colors.yellow.900}"}},muted:{value:{_light:"{colors.yellow.200}",_dark:"{colors.yellow.800}"}},emphasized:{value:{_light:"{colors.yellow.300}",_dark:"{colors.yellow.700}"}},solid:{value:{_light:"{colors.yellow.300}",_dark:"{colors.yellow.300}"}},focusRing:{value:{_light:"{colors.yellow.500}",_dark:"{colors.yellow.500}"}}},teal:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.teal.700}",_dark:"{colors.teal.300}"}},subtle:{value:{_light:"{colors.teal.100}",_dark:"{colors.teal.900}"}},muted:{value:{_light:"{colors.teal.200}",_dark:"{colors.teal.800}"}},emphasized:{value:{_light:"{colors.teal.300}",_dark:"{colors.teal.700}"}},solid:{value:{_light:"{colors.teal.600}",_dark:"{colors.teal.600}"}},focusRing:{value:{_light:"{colors.teal.500}",_dark:"{colors.teal.500}"}}},purple:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.purple.700}",_dark:"{colors.purple.300}"}},subtle:{value:{_light:"{colors.purple.100}",_dark:"{colors.purple.900}"}},muted:{value:{_light:"{colors.purple.200}",_dark:"{colors.purple.800}"}},emphasized:{value:{_light:"{colors.purple.300}",_dark:"{colors.purple.700}"}},solid:{value:{_light:"{colors.purple.600}",_dark:"{colors.purple.600}"}},focusRing:{value:{_light:"{colors.purple.500}",_dark:"{colors.purple.500}"}}},pink:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.pink.700}",_dark:"{colors.pink.300}"}},subtle:{value:{_light:"{colors.pink.100}",_dark:"{colors.pink.900}"}},muted:{value:{_light:"{colors.pink.200}",_dark:"{colors.pink.800}"}},emphasized:{value:{_light:"{colors.pink.300}",_dark:"{colors.pink.700}"}},solid:{value:{_light:"{colors.pink.600}",_dark:"{colors.pink.600}"}},focusRing:{value:{_light:"{colors.pink.500}",_dark:"{colors.pink.500}"}}},cyan:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.cyan.700}",_dark:"{colors.cyan.300}"}},subtle:{value:{_light:"{colors.cyan.100}",_dark:"{colors.cyan.900}"}},muted:{value:{_light:"{colors.cyan.200}",_dark:"{colors.cyan.800}"}},emphasized:{value:{_light:"{colors.cyan.300}",_dark:"{colors.cyan.700}"}},solid:{value:{_light:"{colors.cyan.600}",_dark:"{colors.cyan.600}"}},focusRing:{value:{_light:"{colors.cyan.500}",_dark:"{colors.cyan.500}"}}}}),NO=xl.radii({l1:{value:"{radii.xs}"},l2:{value:"{radii.sm}"},l3:{value:"{radii.md}"}}),AO=xl.shadows({xs:{value:{_light:"0px 1px 2px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/20}",_dark:"0px 1px 1px {black/64}, 0px 0px 1px inset {colors.gray.300/20}"}},sm:{value:{_light:"0px 2px 4px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 2px 4px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},md:{value:{_light:"0px 4px 8px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 4px 8px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},lg:{value:{_light:"0px 8px 16px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 8px 16px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},xl:{value:{_light:"0px 16px 24px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 16px 24px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},"2xl":{value:{_light:"0px 24px 40px {colors.gray.900/16}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 24px 40px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},inner:{value:{_light:"inset 0 2px 4px 0 {black/5}",_dark:"inset 0 2px 4px 0 black"}},inset:{value:{_light:"inset 0 0 0 1px {black/5}",_dark:"inset 0 0 0 1px {colors.gray.300/5}"}}}),_O=Rd.extendWith("itemBody"),VO=G("action-bar").parts("positioner","content","separator","selectionTrigger","closeTrigger"),FO=G("alert").parts("title","description","root","indicator","content"),LO=G("breadcrumb").parts("link","currentLink","item","list","root","ellipsis","separator"),DO=G("blockquote").parts("root","icon","content","caption"),zO=G("card").parts("root","header","body","footer","title","description"),MO=G("checkbox-card",["root","control","label","description","addon","indicator","content"]),$O=G("data-list").parts("root","item","itemLabel","itemValue"),BO=el.extendWith("header","body","footer","backdrop"),jO=el.extendWith("header","body","footer","backdrop"),WO=mh.extendWith("textarea"),HO=G("empty-state",["root","content","indicator","title","description"]),UO=vh.extendWith("requiredIndicator"),GO=yh.extendWith("content"),qO=xh.extendWith("itemContent","dropzoneContent","fileText"),KO=G("list").parts("root","item","indicator"),XO=Ih.extendWith("itemCommand"),YO=G("select").parts("root","field","indicator"),QO=Hh.extendWith("header","body","footer"),eg=fl.extendWith("itemAddon","itemIndicator"),JO=eg.extendWith("itemContent","itemDescription"),ZO=Gh.extendWith("itemIndicator"),eI=Xh.extendWith("indicatorGroup"),tI=lw.extendWith("indicatorGroup","empty"),nI=Zh.extendWith("markerIndicator"),rI=G("stat").parts("root","label","helpText","valueText","valueUnit","indicator"),iI=G("status").parts("root","indicator"),oI=G("steps",["root","list","item","trigger","indicator","separator","content","title","description","nextTrigger","prevTrigger","progress"]),sI=ef.extendWith("indicator"),aI=G("table").parts("root","header","body","row","columnHeader","cell","footer","caption"),lI=G("toast").parts("root","title","description","indicator","closeTrigger","actionTrigger"),cI=G("tabs").parts("root","trigger","list","content","contentGroup","indicator"),uI=G("tag").parts("root","label","closeTrigger","startElement","endElement"),dI=G("timeline").parts("root","item","content","separator","indicator","connector","title","description"),hI=kS.extendWith("channelText"),fI=G("code-block",["root","content","title","header","footer","control","overlay","code","codeText","copyTrigger","copyIndicator","collapseTrigger","collapseIndicator","collapseText"]);zd.extendWith("valueText");const gI=Lw,pI=q({className:"chakra-accordion",slots:_O.keys(),base:{root:{width:"full","--accordion-radius":"radii.l2"},item:{overflowAnchor:"none"},itemTrigger:{display:"flex",alignItems:"center",textAlign:"start",width:"full",outline:"0",gap:"3",fontWeight:"medium",borderRadius:"var(--accordion-radius)",_focusVisible:{outline:"2px solid",outlineColor:"colorPalette.focusRing"},_disabled:{layerStyle:"disabled"}},itemBody:{pt:"var(--accordion-padding-y)",pb:"calc(var(--accordion-padding-y) * 2)"},itemContent:{overflow:"hidden",borderRadius:"var(--accordion-radius)",_open:{animationName:"expand-height, fade-in",animationDuration:"moderate"},_closed:{animationName:"collapse-height, fade-out",animationDuration:"moderate"}},itemIndicator:{transition:"rotate 0.2s",transformOrigin:"center",color:"fg.subtle",_open:{rotate:"180deg"},_icon:{width:"1.2em",height:"1.2em"}}},variants:{variant:{outline:{item:{borderBottomWidth:"1px"}},subtle:{itemTrigger:{px:"var(--accordion-padding-x)"},itemContent:{px:"var(--accordion-padding-x)"},item:{borderRadius:"var(--accordion-radius)",_open:{bg:"colorPalette.subtle"}}},enclosed:{root:{borderWidth:"1px",borderRadius:"var(--accordion-radius)",divideY:"1px",overflow:"hidden"},itemTrigger:{px:"var(--accordion-padding-x)"},itemContent:{px:"var(--accordion-padding-x)"},item:{_open:{bg:"bg.subtle"}}},plain:{}},size:{sm:{root:{"--accordion-padding-x":"spacing.3","--accordion-padding-y":"spacing.2"},itemTrigger:{textStyle:"sm",py:"var(--accordion-padding-y)"}},md:{root:{"--accordion-padding-x":"spacing.4","--accordion-padding-y":"spacing.2"},itemTrigger:{textStyle:"md",py:"var(--accordion-padding-y)"}},lg:{root:{"--accordion-padding-x":"spacing.4.5","--accordion-padding-y":"spacing.2.5"},itemTrigger:{textStyle:"lg",py:"var(--accordion-padding-y)"}}}},defaultVariants:{size:"md",variant:"outline"}}),mI=q({className:"chakra-action-bar",slots:VO.keys(),base:{positioner:{position:"fixed",display:"flex",justifyContent:"center",pointerEvents:"none",insetInline:"0",top:"unset",bottom:"calc(env(safe-area-inset-bottom) + 20px)"},content:{bg:"bg.panel",shadow:"md",display:"flex",alignItems:"center",gap:"3",borderRadius:"l3",py:"2.5",px:"3",pointerEvents:"auto",translate:"calc(-1 * var(--scrollbar-width) / 2) 0px",_open:{animationName:"slide-from-bottom, fade-in",animationDuration:"moderate"},_closed:{animationName:"slide-to-bottom, fade-out",animationDuration:"faster"}},separator:{width:"1px",height:"5",bg:"border"},selectionTrigger:{display:"inline-flex",alignItems:"center",gap:"2",alignSelf:"stretch",textStyle:"sm",px:"4",py:"1",borderRadius:"l2",borderWidth:"1px",borderStyle:"dashed"}}}),vI=q({slots:FO.keys(),className:"chakra-alert",base:{root:{width:"full",display:"flex",alignItems:"flex-start",position:"relative",borderRadius:"l3"},title:{fontWeight:"medium"},description:{display:"inline"},indicator:{display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:"0",width:"1em",height:"1em",_icon:{boxSize:"full"}},content:{display:"flex",flex:"1",gap:"1"}},variants:{status:{info:{root:{colorPalette:"blue"}},warning:{root:{colorPalette:"orange"}},success:{root:{colorPalette:"green"}},error:{root:{colorPalette:"red"}},neutral:{root:{colorPalette:"gray"}}},inline:{true:{content:{display:"inline-flex",flexDirection:"row",alignItems:"center"}},false:{content:{display:"flex",flexDirection:"column"}}},variant:{subtle:{root:{bg:"colorPalette.subtle",color:"colorPalette.fg"}},surface:{root:{bg:"colorPalette.subtle",color:"colorPalette.fg",shadow:"inset 0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted"},indicator:{color:"colorPalette.fg"}},outline:{root:{color:"colorPalette.fg",shadow:"inset 0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted"},indicator:{color:"colorPalette.fg"}},solid:{root:{bg:"colorPalette.solid",color:"colorPalette.contrast"},indicator:{color:"colorPalette.contrast"}}},size:{sm:{root:{gap:"2",px:"3",py:"3",textStyle:"xs"},indicator:{textStyle:"lg"}},md:{root:{gap:"3",px:"4",py:"4",textStyle:"sm"},indicator:{textStyle:"xl"}},lg:{root:{gap:"3",px:"4",py:"4",textStyle:"md"},indicator:{textStyle:"2xl"}}}},defaultVariants:{status:"info",variant:"subtle",size:"md",inline:!1}}),bI=q({slots:Ad.keys(),className:"chakra-avatar",base:{root:{display:"inline-flex",alignItems:"center",justifyContent:"center",fontWeight:"medium",position:"relative",verticalAlign:"top",flexShrink:"0",userSelect:"none",width:"var(--avatar-size)",height:"var(--avatar-size)",fontSize:"var(--avatar-font-size)",borderRadius:"var(--avatar-radius)","&[data-group-item]":{borderWidth:"2px",borderColor:"bg"}},image:{width:"100%",height:"100%",objectFit:"cover",borderRadius:"var(--avatar-radius)"},fallback:{lineHeight:"1",textTransform:"uppercase",fontWeight:"medium",fontSize:"var(--avatar-font-size)",borderRadius:"var(--avatar-radius)"}},variants:{size:{full:{root:{"--avatar-size":"100%","--avatar-font-size":"100%"}},"2xs":{root:{"--avatar-font-size":"fontSizes.2xs","--avatar-size":"sizes.6"}},xs:{root:{"--avatar-font-size":"fontSizes.xs","--avatar-size":"sizes.8"}},sm:{root:{"--avatar-font-size":"fontSizes.sm","--avatar-size":"sizes.9"}},md:{root:{"--avatar-font-size":"fontSizes.md","--avatar-size":"sizes.10"}},lg:{root:{"--avatar-font-size":"fontSizes.md","--avatar-size":"sizes.11"}},xl:{root:{"--avatar-font-size":"fontSizes.lg","--avatar-size":"sizes.12"}},"2xl":{root:{"--avatar-font-size":"fontSizes.xl","--avatar-size":"sizes.16"}}},variant:{solid:{root:{bg:"colorPalette.solid",color:"colorPalette.contrast"}},subtle:{root:{bg:"colorPalette.muted",color:"colorPalette.fg"}},outline:{root:{color:"colorPalette.fg",borderWidth:"1px",borderColor:"colorPalette.muted"}}},shape:{square:{},rounded:{root:{"--avatar-radius":"radii.l3"}},full:{root:{"--avatar-radius":"radii.full"}}},borderless:{true:{root:{"&[data-group-item]":{borderWidth:"0px"}}}}},defaultVariants:{size:"md",shape:"full",variant:"subtle"}}),yI=q({className:"chakra-blockquote",slots:DO.keys(),base:{root:{position:"relative",display:"flex",flexDirection:"column",gap:"2"},caption:{textStyle:"sm",color:"fg.muted"},icon:{boxSize:"5"}},variants:{justify:{start:{root:{alignItems:"flex-start",textAlign:"start"}},center:{root:{alignItems:"center",textAlign:"center"}},end:{root:{alignItems:"flex-end",textAlign:"end"}}},variant:{subtle:{root:{paddingX:"5",borderStartWidth:"4px",borderStartColor:"colorPalette.muted"},icon:{color:"colorPalette.fg"}},solid:{root:{paddingX:"5",borderStartWidth:"4px",borderStartColor:"colorPalette.solid"},icon:{color:"colorPalette.solid"}},plain:{root:{paddingX:"5"},icon:{color:"colorPalette.solid"}}}},defaultVariants:{variant:"subtle",justify:"start"}}),xI=q({className:"chakra-breadcrumb",slots:LO.keys(),base:{list:{display:"flex",alignItems:"center",wordBreak:"break-word",color:"fg.muted",listStyle:"none"},link:{outline:"0",textDecoration:"none",borderRadius:"l1",focusRing:"outside",display:"inline-flex",alignItems:"center",gap:"2"},item:{display:"inline-flex",alignItems:"center"},separator:{color:"fg.muted",opacity:"0.8",_icon:{boxSize:"1em"},_rtl:{rotate:"180deg"}},ellipsis:{display:"inline-flex",alignItems:"center",justifyContent:"center",_icon:{boxSize:"1em"}}},variants:{variant:{underline:{link:{color:"colorPalette.fg",textDecoration:"underline",textUnderlineOffset:"0.2em",textDecorationColor:"colorPalette.muted"},currentLink:{color:"colorPalette.fg"}},plain:{link:{color:"fg.muted",_hover:{color:"fg"}},currentLink:{color:"fg"}}},size:{sm:{list:{gap:"1",textStyle:"xs"}},md:{list:{gap:"1.5",textStyle:"sm"}},lg:{list:{gap:"2",textStyle:"md"}}}},defaultVariants:{variant:"plain",size:"md"}}),CI=q({className:"chakra-card",slots:zO.keys(),base:{root:{display:"flex",flexDirection:"column",position:"relative",minWidth:"0",wordWrap:"break-word",borderRadius:"l3",color:"fg",textAlign:"start"},title:{fontWeight:"semibold"},description:{color:"fg.muted",fontSize:"sm"},header:{paddingInline:"var(--card-padding)",paddingTop:"var(--card-padding)",display:"flex",flexDirection:"column",gap:"1.5"},body:{padding:"var(--card-padding)",flex:"1",display:"flex",flexDirection:"column"},footer:{display:"flex",alignItems:"center",gap:"2",paddingInline:"var(--card-padding)",paddingBottom:"var(--card-padding)"}},variants:{size:{sm:{root:{"--card-padding":"spacing.4"},title:{textStyle:"md"}},md:{root:{"--card-padding":"spacing.6"},title:{textStyle:"lg"}},lg:{root:{"--card-padding":"spacing.7"},title:{textStyle:"xl"}}},variant:{elevated:{root:{bg:"bg.panel",boxShadow:"md"}},outline:{root:{bg:"bg.panel",borderWidth:"1px",borderColor:"border"}},subtle:{root:{bg:"bg.muted"}}}},defaultVariants:{variant:"outline",size:"md"}}),SI=q({slots:wS.keys(),className:"chakra-checkbox",base:{root:{display:"inline-flex",gap:"2",alignItems:"center",verticalAlign:"top",position:"relative"},control:Ve.base,label:{fontWeight:"medium",userSelect:"none",_disabled:{opacity:"0.5"}}},variants:{size:{xs:{root:{gap:"1.5"},label:{textStyle:"xs"},control:(fm=(hm=Ve.variants)==null?void 0:hm.size)==null?void 0:fm.xs},sm:{root:{gap:"2"},label:{textStyle:"sm"},control:(pm=(gm=Ve.variants)==null?void 0:gm.size)==null?void 0:pm.sm},md:{root:{gap:"2.5"},label:{textStyle:"sm"},control:(vm=(mm=Ve.variants)==null?void 0:mm.size)==null?void 0:vm.md},lg:{root:{gap:"3"},label:{textStyle:"md"},control:(ym=(bm=Ve.variants)==null?void 0:bm.size)==null?void 0:ym.lg}},variant:{outline:{control:(Cm=(xm=Ve.variants)==null?void 0:xm.variant)==null?void 0:Cm.outline},solid:{control:(wm=(Sm=Ve.variants)==null?void 0:Sm.variant)==null?void 0:wm.solid},subtle:{control:(km=(Em=Ve.variants)==null?void 0:Em.variant)==null?void 0:km.subtle}}},defaultVariants:{variant:"solid",size:"md"}}),wI=q({slots:MO.keys(),className:"chakra-checkbox-card",base:{root:{display:"flex",flexDirection:"column",userSelect:"none",position:"relative",borderRadius:"l2",flex:"1",focusVisibleRing:"outside",_disabled:{opacity:"0.8"},_invalid:{outline:"2px solid",outlineColor:"border.error"}},control:{display:"inline-flex",flex:"1",position:"relative",borderRadius:"inherit",justifyContent:"var(--checkbox-card-justify)",alignItems:"var(--checkbox-card-align)"},label:{fontWeight:"medium",display:"flex",alignItems:"center",gap:"2",flex:"1",_disabled:{opacity:"0.5"}},description:{opacity:"0.64",textStyle:"sm",_disabled:{opacity:"0.5"}},addon:{_disabled:{opacity:"0.5"}},indicator:Ve.base,content:{display:"flex",flexDirection:"column",flex:"1",gap:"1",justifyContent:"var(--checkbox-card-justify)",alignItems:"var(--checkbox-card-align)"}},variants:{size:{sm:{root:{textStyle:"sm"},control:{padding:"3",gap:"1.5"},addon:{px:"3",py:"1.5",borderTopWidth:"1px"},indicator:(Om=Ve.variants)==null?void 0:Om.size.sm},md:{root:{textStyle:"sm"},control:{padding:"4",gap:"2.5"},addon:{px:"4",py:"2",borderTopWidth:"1px"},indicator:(Im=Ve.variants)==null?void 0:Im.size.md},lg:{root:{textStyle:"md"},control:{padding:"4",gap:"3.5"},addon:{px:"4",py:"2",borderTopWidth:"1px"},indicator:(Pm=Ve.variants)==null?void 0:Pm.size.lg}},variant:{surface:{root:{borderWidth:"1px",borderColor:"border",_checked:{bg:"colorPalette.subtle",color:"colorPalette.fg",borderColor:"colorPalette.muted"},_disabled:{bg:"bg.muted"}},indicator:(Rm=Ve.variants)==null?void 0:Rm.variant.solid},subtle:{root:{bg:"bg.muted"},control:{_checked:{bg:"colorPalette.muted",color:"colorPalette.fg"}},indicator:(Tm=Ve.variants)==null?void 0:Tm.variant.plain},outline:{root:{borderWidth:"1px",borderColor:"border",_checked:{boxShadow:"0 0 0 1px var(--shadow-color)",boxShadowColor:"colorPalette.solid",borderColor:"colorPalette.solid"}},indicator:(Nm=Ve.variants)==null?void 0:Nm.variant.solid},solid:{root:{borderWidth:"1px",_checked:{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"colorPalette.solid"}},indicator:(Am=Ve.variants)==null?void 0:Am.variant.inverted}},justify:{start:{root:{"--checkbox-card-justify":"flex-start"}},end:{root:{"--checkbox-card-justify":"flex-end"}},center:{root:{"--checkbox-card-justify":"center"}}},align:{start:{root:{"--checkbox-card-align":"flex-start"},content:{textAlign:"start"}},end:{root:{"--checkbox-card-align":"flex-end"},content:{textAlign:"end"}},center:{root:{"--checkbox-card-align":"center"},content:{textAlign:"center"}}},orientation:{vertical:{control:{flexDirection:"column"}},horizontal:{control:{flexDirection:"row"}}}},defaultVariants:{size:"md",variant:"outline",align:"start",orientation:"horizontal"}}),EI=q({slots:fI.keys(),className:"code-block",base:{root:{colorPalette:"gray",rounded:"var(--code-block-radius)",overflow:"hidden",bg:"bg",color:"fg",borderWidth:"1px","--code-block-max-height":"320px","--code-block-bg":"colors.bg","--code-block-fg":"colors.fg","--code-block-obscured-opacity":"0.5","--code-block-obscured-blur":"1px","--code-block-line-number-width":"sizes.3","--code-block-line-number-margin":"spacing.4","--code-block-highlight-bg":"{colors.teal.focusRing/20}","--code-block-highlight-border":"colors.teal.focusRing","--code-block-highlight-added-bg":"{colors.green.focusRing/20}","--code-block-highlight-added-border":"colors.green.focusRing","--code-block-highlight-removed-bg":"{colors.red.focusRing/20}","--code-block-highlight-removed-border":"colors.red.focusRing"},header:{display:"flex",alignItems:"center",gap:"2",position:"relative",px:"var(--code-block-padding)",minH:"var(--code-block-header-height)",mb:"calc(var(--code-block-padding) / 2 * -1)"},title:{display:"inline-flex",alignItems:"center",gap:"1.5",flex:"1",color:"fg.muted"},control:{gap:"1.5",display:"inline-flex",alignItems:"center"},footer:{display:"flex",alignItems:"center",justifyContent:"center",gap:"2",px:"var(--code-block-padding)",minH:"var(--code-block-header-height)"},content:{position:"relative",colorScheme:"dark",overflow:"hidden",borderBottomRadius:"var(--code-block-radius)",maxHeight:"var(--code-block-max-height)","& ::selection":{bg:"blue.500/40"},_expanded:{maxHeight:"unset"}},overlay:{"--bg":"{colors.black/50}",display:"flex",alignItems:"flex-end",justifyContent:"center",padding:"4",bgImage:"linear-gradient(0deg,var(--bg) 25%,transparent 100%)",color:"white",minH:"5rem",pos:"absolute",bottom:"0",insetInline:"0",zIndex:"1",fontWeight:"medium",_expanded:{display:"none"}},code:{fontFamily:"mono",lineHeight:"tall",whiteSpace:"pre",counterReset:"line 0"},codeText:{px:"var(--code-block-padding)",py:"var(--code-block-padding)",position:"relative",display:"block",width:"100%","&[data-has-focused]":{"& [data-line]:not([data-focused])":{transitionProperty:"opacity, filter",transitionDuration:"moderate",transitionTimingFunction:"ease-in-out",opacity:"var(--code-block-obscured-opacity)",filter:"blur(var(--code-block-obscured-blur))"},"&:hover":{"--code-block-obscured-opacity":"1","--code-block-obscured-blur":"0px"}},"&[data-has-line-numbers][data-plaintext]":{paddingInlineStart:"calc(var(--code-block-line-number-width) + var(--code-block-line-number-margin) + var(--code-block-padding))"},"& [data-line]":{position:"relative","--highlight-bg":"var(--code-block-highlight-bg)","--highlight-border":"var(--code-block-highlight-border)","&[data-highlight], &[data-diff]":{display:"inline-block",width:"full","&:after":{content:"''",display:"block",position:"absolute",insetStart:"calc(var(--code-block-padding) * -1)",insetEnd:"0px",width:"calc(100% + var(--code-block-padding) * 2)",height:"100%",bg:"var(--highlight-bg)",borderStartWidth:"2px",borderStartColor:"var(--highlight-border)"}},"&[data-diff='added']":{"--highlight-bg":"var(--code-block-highlight-added-bg)","--highlight-border":"var(--code-block-highlight-added-border)"},"&[data-diff='removed']":{"--highlight-bg":"var(--code-block-highlight-removed-bg)","--highlight-border":"var(--code-block-highlight-removed-border)"}},"&[data-word-wrap]":{"&[data-plaintext], & [data-line]":{whiteSpace:"pre-wrap",wordBreak:"break-all"}},"&[data-has-line-numbers]":{"--content":"counter(line)","& [data-line]:before":{content:"var(--content)",counterIncrement:"line",width:"var(--code-block-line-number-width)",marginRight:"var(--code-block-line-number-margin)",display:"inline-block",textAlign:"end",userSelect:"none",opacity:.4},"& [data-diff='added']:before":{content:"'+'"},"& [data-diff='removed']:before":{content:"'-'"}}}},variants:{size:{sm:{root:{"--code-block-padding":"spacing.4","--code-block-radius":"radii.md","--code-block-header-height":"sizes.8"},title:{textStyle:"xs"},code:{fontSize:"xs"}},md:{root:{"--code-block-padding":"spacing.4","--code-block-radius":"radii.lg","--code-block-header-height":"sizes.10"},title:{textStyle:"xs"},code:{fontSize:"sm"}},lg:{root:{"--code-block-padding":"spacing.5","--code-block-radius":"radii.xl","--code-block-header-height":"sizes.12"},title:{textStyle:"sm"},code:{fontSize:"sm"}}}},defaultVariants:{size:"md"}}),kI=q({slots:Bu.keys(),className:"chakra-collapsible",base:{content:{overflow:"hidden",_open:{animationName:"expand-height, fade-in",animationDuration:"moderate"},_closed:{animationName:"collapse-height, fade-out",animationDuration:"moderate"}}}}),OI=q({className:"colorPicker",slots:hI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5"},label:{color:"fg",fontWeight:"medium",textStyle:"sm",_disabled:{opacity:"0.5"}},valueText:{textAlign:"start"},control:{display:"flex",alignItems:"center",flexDirection:"row",gap:"2",position:"relative"},swatchTrigger:{display:"flex",alignItems:"center",justifyContent:"center"},trigger:{display:"flex",alignItems:"center",justifyContent:"center",flexDirection:"row",flexShrink:"0",gap:"2",textStyle:"sm",minH:"var(--input-height)",minW:"var(--input-height)",px:"1",rounded:"l2",_disabled:{opacity:"0.5"},"--focus-color":"colors.colorPalette.focusRing","&:focus-visible":{borderColor:"var(--focus-color)",outline:"1px solid var(--focus-color)"},"&[data-fit-content]":{"--input-height":"unset",px:"0",border:"0"}},content:{display:"flex",flexDirection:"column",bg:"bg.panel",borderRadius:"l3",boxShadow:"lg",width:"64",p:"4",gap:"3",zIndex:"dropdown",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"faster"}},area:{height:"180px",borderRadius:"l2",overflow:"hidden"},areaThumb:{borderRadius:"full",height:"var(--thumb-size)",width:"var(--thumb-size)",borderWidth:"2px",borderColor:"white",shadow:"sm",focusVisibleRing:"mixed",focusRingColor:"white"},areaBackground:{height:"full"},channelSlider:{borderRadius:"l2",flex:"1"},channelSliderTrack:{height:"var(--slider-height)",borderRadius:"inherit",boxShadow:"inset 0 0 0 1px rgba(0,0,0,0.1)"},channelText:{textStyle:"xs",color:"fg.muted",fontWeight:"medium",textTransform:"capitalize"},swatchGroup:{display:"flex",flexDirection:"row",flexWrap:"wrap",gap:"2"},swatch:{...Zf.base,borderRadius:"l1"},swatchIndicator:{color:"white",rounded:"full"},channelSliderThumb:{borderRadius:"full",height:"var(--thumb-size)",width:"var(--thumb-size)",borderWidth:"2px",borderColor:"white",shadow:"sm",transform:"translate(-50%, -50%)",focusVisibleRing:"outside",focusRingOffset:"1px"},channelInput:{...Ce.base,"&::-webkit-inner-spin-button, &::-webkit-outer-spin-button":{WebkitAppearance:"none",margin:0}},formatSelect:{textStyle:"xs",textTransform:"uppercase",borderWidth:"1px",minH:"6",focusRing:"inside",rounded:"l2"},transparencyGrid:{borderRadius:"l2"},view:{display:"flex",flexDirection:"column",gap:"2"}},variants:{size:{"2xs":{channelInput:(Vm=(_m=Ce.variants)==null?void 0:_m.size)==null?void 0:Vm["2xs"],swatch:{"--swatch-size":"sizes.4.5"},trigger:{"--input-height":"sizes.7"},area:{"--thumb-size":"sizes.3"},channelSlider:{"--slider-height":"sizes.3","--thumb-size":"sizes.3"}},xs:{channelInput:(Lm=(Fm=Ce.variants)==null?void 0:Fm.size)==null?void 0:Lm.xs,swatch:{"--swatch-size":"sizes.5"},trigger:{"--input-height":"sizes.8"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},sm:{channelInput:(zm=(Dm=Ce.variants)==null?void 0:Dm.size)==null?void 0:zm.sm,swatch:{"--swatch-size":"sizes.6"},trigger:{"--input-height":"sizes.9"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},md:{channelInput:($m=(Mm=Ce.variants)==null?void 0:Mm.size)==null?void 0:$m.md,swatch:{"--swatch-size":"sizes.7"},trigger:{"--input-height":"sizes.10"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},lg:{channelInput:(jm=(Bm=Ce.variants)==null?void 0:Bm.size)==null?void 0:jm.lg,swatch:{"--swatch-size":"sizes.7"},trigger:{"--input-height":"sizes.11"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},xl:{channelInput:(Hm=(Wm=Ce.variants)==null?void 0:Wm.size)==null?void 0:Hm.xl,swatch:{"--swatch-size":"sizes.8"},trigger:{"--input-height":"sizes.12"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},"2xl":{channelInput:(Gm=(Um=Ce.variants)==null?void 0:Um.size)==null?void 0:Gm["2xl"],swatch:{"--swatch-size":"sizes.10"},trigger:{"--input-height":"sizes.16"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}}},variant:{outline:{channelInput:(Km=(qm=Ce.variants)==null?void 0:qm.variant)==null?void 0:Km.outline,trigger:{borderWidth:"1px"}},subtle:{channelInput:(Ym=(Xm=Ce.variants)==null?void 0:Xm.variant)==null?void 0:Ym.subtle,trigger:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted"}}}},defaultVariants:{size:"md",variant:"outline"}}),II=q({className:"chakra-combobox",slots:tI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5",width:"full"},label:{fontWeight:"medium",userSelect:"none",textStyle:"sm",_disabled:{layerStyle:"disabled"}},input:{display:"flex",alignItems:"center",justifyContent:"space-between",background:"bg.panel",width:"full",minH:"var(--combobox-input-height)",px:"var(--combobox-input-padding-x)","--input-height":"var(--combobox-input-height)",borderRadius:"l2",outline:0,userSelect:"none",textAlign:"start",_placeholderShown:{color:"fg.muted"},_disabled:{layerStyle:"disabled"},"--focus-color":"colors.colorPalette.focusRing","--error-color":"colors.border.error",_invalid:{focusRingColor:"var(--error-color)",borderColor:"var(--error-color)"}},trigger:{display:"inline-flex",alignItems:"center",justifyContent:"center","--input-height":"var(--combobox-input-height)"},clearTrigger:{color:"fg.muted",pointerEvents:"auto",focusVisibleRing:"inside",focusRingWidth:"2px",rounded:"l1"},control:{pos:"relative"},indicatorGroup:{display:"flex",alignItems:"center",justifyContent:"center",gap:"1",pos:"absolute",insetEnd:"0",top:"0",bottom:"0",px:"var(--combobox-input-padding-x)",_icon:{boxSize:"var(--combobox-indicator-size)"},"[data-disabled] &":{opacity:.5}},content:{background:"bg.panel",display:"flex",flexDirection:"column",zIndex:"dropdown",borderRadius:"l2",outline:0,maxH:"96",overflowY:"auto",boxShadow:"md",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"0s"},"&[data-empty]:not(:has([data-scope=combobox][data-part=empty]))":{opacity:0}},item:{position:"relative",userSelect:"none",display:"flex",alignItems:"center",gap:"2",py:"var(--combobox-item-padding-y)",px:"var(--combobox-item-padding-x)",cursor:"option",justifyContent:"space-between",flex:"1",textAlign:"start",borderRadius:"l1",_highlighted:{bg:"bg.emphasized/60"},_disabled:{pointerEvents:"none",opacity:"0.5"},_icon:{boxSize:"var(--combobox-indicator-size)"}},empty:{py:"var(--combobox-item-padding-y)",px:"var(--combobox-item-padding-x)"},itemText:{flex:"1"},itemGroup:{pb:"var(--combobox-item-padding-y)",_last:{pb:"0"}},itemGroupLabel:{fontWeight:"medium",py:"var(--combobox-item-padding-y)",px:"var(--combobox-item-padding-x)"}},variants:{variant:{outline:{input:{bg:"transparent",borderWidth:"1px",borderColor:"border",focusVisibleRing:"inside"}},subtle:{input:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted",focusVisibleRing:"inside"}},flushed:{input:{bg:"transparent",borderBottomWidth:"1px",borderBottomColor:"border",borderRadius:"0",px:"0",_focusVisible:{borderColor:"var(--focus-color)",boxShadow:"0px 1px 0px 0px var(--focus-color)"}},indicatorGroup:{px:"0"}}},size:{xs:{root:{"--combobox-input-height":"sizes.8","--combobox-input-padding-x":"spacing.2","--combobox-indicator-size":"sizes.3.5"},input:{textStyle:"xs"},content:{"--combobox-item-padding-x":"spacing.1.5","--combobox-item-padding-y":"spacing.1","--combobox-indicator-size":"sizes.3.5",p:"1",textStyle:"xs"},trigger:{textStyle:"xs",gap:"1"}},sm:{root:{"--combobox-input-height":"sizes.9","--combobox-input-padding-x":"spacing.2.5","--combobox-indicator-size":"sizes.4"},input:{textStyle:"sm"},content:{"--combobox-item-padding-x":"spacing.2","--combobox-item-padding-y":"spacing.1.5","--combobox-indicator-size":"sizes.4",p:"1",textStyle:"sm"},trigger:{textStyle:"sm",gap:"1"}},md:{root:{"--combobox-input-height":"sizes.10","--combobox-input-padding-x":"spacing.3","--combobox-indicator-size":"sizes.4"},input:{textStyle:"sm"},content:{"--combobox-item-padding-x":"spacing.2","--combobox-item-padding-y":"spacing.1.5","--combobox-indicator-size":"sizes.4",p:"1",textStyle:"sm"},itemIndicator:{display:"flex",alignItems:"center",justifyContent:"center"},trigger:{textStyle:"sm",gap:"2"}},lg:{root:{"--combobox-input-height":"sizes.12","--combobox-input-padding-x":"spacing.4","--combobox-indicator-size":"sizes.5"},input:{textStyle:"md"},content:{"--combobox-item-padding-y":"spacing.2","--combobox-item-padding-x":"spacing.3","--combobox-indicator-size":"sizes.5",p:"1.5",textStyle:"md"},trigger:{textStyle:"md",py:"3",gap:"2"}}}},defaultVariants:{size:"md",variant:"outline"}}),PI=q({slots:$O.keys(),className:"chakra-data-list",base:{itemLabel:{display:"flex",alignItems:"center",gap:"1"},itemValue:{display:"flex",minWidth:"0",flex:"1"}},variants:{orientation:{horizontal:{root:{display:"flex",flexDirection:"column"},item:{display:"inline-flex",alignItems:"center",gap:"4"},itemLabel:{minWidth:"120px"}},vertical:{root:{display:"flex",flexDirection:"column"},item:{display:"flex",flexDirection:"column",gap:"1"}}},size:{sm:{root:{gap:"3"},item:{textStyle:"xs"}},md:{root:{gap:"4"},item:{textStyle:"sm"}},lg:{root:{gap:"5"},item:{textStyle:"md"}}},variant:{subtle:{itemLabel:{color:"fg.muted"}},bold:{itemLabel:{fontWeight:"medium"},itemValue:{color:"fg.muted"}}}},defaultVariants:{size:"md",orientation:"vertical",variant:"subtle"}}),RI=q({slots:BO.keys(),className:"chakra-dialog",base:{backdrop:{bg:"blackAlpha.500",pos:"fixed",left:0,top:0,w:"100dvw",h:"100dvh",zIndex:"var(--z-index)",_open:{animationName:"fade-in",animationDuration:"slow"},_closed:{animationName:"fade-out",animationDuration:"moderate"}},positioner:{display:"flex",width:"100dvw",height:"100dvh",position:"fixed",left:0,top:0,"--dialog-z-index":"zIndex.modal",zIndex:"calc(var(--dialog-z-index) + var(--layer-index, 0))",justifyContent:"center",overscrollBehaviorY:"none"},content:{display:"flex",flexDirection:"column",position:"relative",width:"100%",outline:0,borderRadius:"l3",textStyle:"sm",my:"var(--dialog-margin, var(--dialog-base-margin))","--dialog-z-index":"zIndex.modal",zIndex:"calc(var(--dialog-z-index) + var(--layer-index, 0))",bg:"bg.panel",boxShadow:"lg",_open:{animationDuration:"moderate"},_closed:{animationDuration:"faster"}},header:{display:"flex",gap:"2",flex:0,px:"6",pt:"6",pb:"4"},body:{flex:"1",px:"6",pt:"2",pb:"6"},footer:{display:"flex",alignItems:"center",justifyContent:"flex-end",gap:"3",px:"6",pt:"2",pb:"4"},title:{textStyle:"lg",fontWeight:"semibold"},description:{color:"fg.muted"},closeTrigger:{pos:"absolute",top:"2",insetEnd:"2"}},variants:{placement:{center:{positioner:{alignItems:"center"},content:{"--dialog-base-margin":"auto",mx:"auto"}},top:{positioner:{alignItems:"flex-start"},content:{"--dialog-base-margin":"spacing.16",mx:"auto"}},bottom:{positioner:{alignItems:"flex-end"},content:{"--dialog-base-margin":"spacing.16",mx:"auto"}}},scrollBehavior:{inside:{positioner:{overflow:"hidden"},content:{maxH:"calc(100% - 7.5rem)"},body:{overflow:"auto"}},outside:{positioner:{overflow:"auto",pointerEvents:"auto"}}},size:{xs:{content:{maxW:"sm"}},sm:{content:{maxW:"md"}},md:{content:{maxW:"lg"}},lg:{content:{maxW:"2xl"}},xl:{content:{maxW:"4xl"}},cover:{positioner:{padding:"10"},content:{width:"100%",height:"100%","--dialog-margin":"0"}},full:{content:{maxW:"100dvw",minH:"100dvh","--dialog-margin":"0",borderRadius:"0"}}},motionPreset:{scale:{content:{_open:{animationName:"scale-in, fade-in"},_closed:{animationName:"scale-out, fade-out"}}},"slide-in-bottom":{content:{_open:{animationName:"slide-from-bottom, fade-in"},_closed:{animationName:"slide-to-bottom, fade-out"}}},"slide-in-top":{content:{_open:{animationName:"slide-from-top, fade-in"},_closed:{animationName:"slide-to-top, fade-out"}}},"slide-in-left":{content:{_open:{animationName:"slide-from-left, fade-in"},_closed:{animationName:"slide-to-left, fade-out"}}},"slide-in-right":{content:{_open:{animationName:"slide-from-right, fade-in"},_closed:{animationName:"slide-to-right, fade-out"}}},none:{}}},defaultVariants:{size:"md",scrollBehavior:"outside",placement:"top",motionPreset:"scale"}}),TI=q({slots:jO.keys(),className:"chakra-drawer",base:{backdrop:{bg:"blackAlpha.500",pos:"fixed",insetInlineStart:0,top:0,w:"100vw",h:"100dvh",zIndex:"overlay",_open:{animationName:"fade-in",animationDuration:"slow"},_closed:{animationName:"fade-out",animationDuration:"moderate"}},positioner:{display:"flex",width:"100vw",height:"100dvh",position:"fixed",insetInlineStart:0,top:0,zIndex:"modal",overscrollBehaviorY:"none"},content:{display:"flex",flexDirection:"column",position:"relative",width:"100%",outline:0,zIndex:"modal",textStyle:"sm",maxH:"100dvh",color:"inherit",bg:"bg.panel",boxShadow:"lg",_open:{animationDuration:"slowest",animationTimingFunction:"ease-in-smooth"},_closed:{animationDuration:"slower",animationTimingFunction:"ease-in-smooth"}},header:{display:"flex",alignItems:"center",gap:"2",flex:0,px:"6",pt:"6",pb:"4"},body:{px:"6",py:"2",flex:"1",overflow:"auto"},footer:{display:"flex",alignItems:"center",justifyContent:"flex-end",gap:"3",px:"6",pt:"2",pb:"4"},title:{flex:"1",textStyle:"lg",fontWeight:"semibold"},description:{color:"fg.muted"},closeTrigger:{pos:"absolute",top:"3",insetEnd:"2"}},variants:{size:{xs:{content:{maxW:"xs"}},sm:{content:{maxW:"md"}},md:{content:{maxW:"lg"}},lg:{content:{maxW:"2xl"}},xl:{content:{maxW:"4xl"}},full:{content:{maxW:"100vw",h:"100dvh"}}},placement:{start:{positioner:{justifyContent:"flex-start",alignItems:"stretch"},content:{_open:{animationName:{base:"slide-from-left-full, fade-in",_rtl:"slide-from-right-full, fade-in"}},_closed:{animationName:{base:"slide-to-left-full, fade-out",_rtl:"slide-to-right-full, fade-out"}}}},end:{positioner:{justifyContent:"flex-end",alignItems:"stretch"},content:{_open:{animationName:{base:"slide-from-right-full, fade-in",_rtl:"slide-from-left-full, fade-in"}},_closed:{animationName:{base:"slide-to-right-full, fade-out",_rtl:"slide-to-left-full, fade-out"}}}},top:{positioner:{justifyContent:"stretch",alignItems:"flex-start"},content:{maxW:"100%",_open:{animationName:"slide-from-top-full, fade-in"},_closed:{animationName:"slide-to-top-full, fade-out"}}},bottom:{positioner:{justifyContent:"stretch",alignItems:"flex-end"},content:{maxW:"100%",_open:{animationName:"slide-from-bottom-full, fade-in"},_closed:{animationName:"slide-to-bottom-full, fade-out"}}}},contained:{true:{positioner:{padding:"4"},content:{borderRadius:"l3"}}}},defaultVariants:{size:"xs",placement:"end"}}),tg=Ir({fontSize:"inherit",fontWeight:"inherit",textAlign:"inherit",bg:"transparent",borderRadius:"l2"}),NI=q({slots:WO.keys(),className:"chakra-editable",base:{root:{display:"inline-flex",alignItems:"center",position:"relative",gap:"1.5",width:"full"},preview:{...tg,py:"1",px:"1",display:"inline-flex",alignItems:"center",transitionProperty:"common",transitionDuration:"moderate",cursor:"text",_hover:{bg:"bg.muted"},_disabled:{userSelect:"none"}},input:{...tg,outline:"0",py:"1",px:"1",transitionProperty:"common",transitionDuration:"normal",width:"full",focusVisibleRing:"inside",focusRingWidth:"2px",_placeholder:{opacity:.6}},control:{display:"inline-flex",alignItems:"center",gap:"1.5"}},variants:{size:{sm:{root:{textStyle:"sm"},preview:{minH:"8"},input:{minH:"8"}},md:{root:{textStyle:"sm"},preview:{minH:"9"},input:{minH:"9"}},lg:{root:{textStyle:"md"},preview:{minH:"10"},input:{minH:"10"}}}},defaultVariants:{size:"md"}}),AI=q({slots:HO.keys(),className:"chakra-empty-state",base:{root:{width:"full"},content:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},indicator:{display:"flex",alignItems:"center",justifyContent:"center",color:"fg.subtle",_icon:{boxSize:"1em"}},title:{fontWeight:"semibold"},description:{textStyle:"sm",color:"fg.muted"}},variants:{size:{sm:{root:{px:"4",py:"6"},title:{textStyle:"md"},content:{gap:"4"},indicator:{textStyle:"2xl"}},md:{root:{px:"8",py:"12"},title:{textStyle:"lg"},content:{gap:"6"},indicator:{textStyle:"4xl"}},lg:{root:{px:"12",py:"16"},title:{textStyle:"xl"},content:{gap:"8"},indicator:{textStyle:"6xl"}}}},defaultVariants:{size:"md"}}),_I=q({className:"chakra-field",slots:UO.keys(),base:{requiredIndicator:{color:"fg.error",lineHeight:"1"},root:{display:"flex",width:"100%",position:"relative",gap:"1.5"},label:{display:"flex",alignItems:"center",textAlign:"start",textStyle:"sm",fontWeight:"medium",gap:"1",userSelect:"none",_disabled:{opacity:"0.5"}},errorText:{display:"inline-flex",alignItems:"center",fontWeight:"medium",gap:"1",color:"fg.error",textStyle:"xs"},helperText:{color:"fg.muted",textStyle:"xs"}},variants:{orientation:{vertical:{root:{flexDirection:"column",alignItems:"flex-start"}},horizontal:{root:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},label:{flex:"0 0 var(--field-label-width, 80px)"}}}},defaultVariants:{orientation:"vertical"}}),VI=q({className:"fieldset",slots:GO.keys(),base:{root:{display:"flex",flexDirection:"column",width:"full"},content:{display:"flex",flexDirection:"column",width:"full"},legend:{color:"fg",fontWeight:"medium",_disabled:{opacity:"0.5"}},helperText:{color:"fg.muted",textStyle:"sm"},errorText:{display:"inline-flex",alignItems:"center",color:"fg.error",gap:"2",fontWeight:"medium",textStyle:"sm"}},variants:{size:{sm:{root:{spaceY:"2"},content:{gap:"1.5"},legend:{textStyle:"sm"}},md:{root:{spaceY:"4"},content:{gap:"4"},legend:{textStyle:"sm"}},lg:{root:{spaceY:"6"},content:{gap:"4"},legend:{textStyle:"md"}}}},defaultVariants:{size:"md"}}),FI=q({className:"chakra-file-upload",slots:qO.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"4",width:"100%",alignItems:"flex-start"},label:{fontWeight:"medium",textStyle:"sm"},dropzone:{background:"bg",borderRadius:"l3",borderWidth:"2px",borderStyle:"dashed",display:"flex",alignItems:"center",flexDirection:"column",gap:"4",justifyContent:"center",minHeight:"2xs",px:"3",py:"2",transition:"backgrounds",focusVisibleRing:"outside",_hover:{bg:"bg.subtle"},_dragging:{bg:"colorPalette.subtle",borderStyle:"solid",borderColor:"colorPalette.solid"}},dropzoneContent:{display:"flex",flexDirection:"column",alignItems:"center",textAlign:"center",gap:"1",textStyle:"sm"},item:{pos:"relative",textStyle:"sm",animationName:"fade-in",animationDuration:"moderate",background:"bg",borderRadius:"l2",borderWidth:"1px",width:"100%",display:"flex",alignItems:"center",gap:"3",p:"4"},itemGroup:{width:"100%",display:"flex",flexDirection:"column",gap:"3",_empty:{display:"none"}},itemName:{color:"fg",fontWeight:"medium",lineClamp:"1"},itemContent:{display:"flex",flexDirection:"column",gap:"0.5",flex:"1"},itemSizeText:{color:"fg.muted",textStyle:"xs"},itemDeleteTrigger:{display:"flex",alignItems:"center",justifyContent:"center",alignSelf:"flex-start",boxSize:"5",p:"2px",color:"fg.muted",cursor:"button"},itemPreview:{color:"fg.muted",_icon:{boxSize:"4.5"}}},defaultVariants:{}}),LI=q({className:"chakra-hover-card",slots:Ch.keys(),base:{content:{position:"relative",display:"flex",flexDirection:"column",textStyle:"sm","--hovercard-bg":"colors.bg.panel",bg:"var(--hovercard-bg)",boxShadow:"lg",maxWidth:"80",borderRadius:"l3",zIndex:"popover",transformOrigin:"var(--transform-origin)",outline:"0",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"faster"}},arrow:{"--arrow-size":"sizes.3","--arrow-background":"var(--hovercard-bg)"},arrowTip:{borderTopWidth:"0.5px",borderInlineStartWidth:"0.5px"}},variants:{size:{xs:{content:{padding:"3"}},sm:{content:{padding:"4"}},md:{content:{padding:"5"}},lg:{content:{padding:"6"}}}},defaultVariants:{size:"md"}}),DI=q({className:"chakra-list",slots:KO.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"var(--list-gap)","& :where(ul, ol)":{marginTop:"var(--list-gap)"}},item:{whiteSpace:"normal",display:"list-item"},indicator:{marginEnd:"2",minHeight:"1lh",flexShrink:0,display:"inline-block",verticalAlign:"middle"}},variants:{variant:{marker:{root:{listStyle:"revert"},item:{_marker:{color:"fg.subtle"}}},plain:{item:{alignItems:"flex-start",display:"inline-flex"}}},align:{center:{item:{alignItems:"center"}},start:{item:{alignItems:"flex-start"}},end:{item:{alignItems:"flex-end"}}}},defaultVariants:{variant:"marker"}}),zI=q({className:"chakra-listbox",slots:gI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5",width:"full"},content:{display:"flex",maxH:"96",p:"1",gap:"1",textStyle:"sm",outline:"none",scrollPadding:"1",_horizontal:{flexDirection:"row",overflowX:"auto"},_vertical:{flexDirection:"column",overflowY:"auto"},"--listbox-item-padding-x":"spacing.2","--listbox-item-padding-y":"spacing.1.5"},item:{position:"relative",userSelect:"none",display:"flex",alignItems:"center",gap:"2",cursor:"pointer",justifyContent:"space-between",flex:"1",textAlign:"start",borderRadius:"l1",py:"var(--listbox-item-padding-y)",px:"var(--listbox-item-padding-x)",_highlighted:{outline:"2px solid",outlineColor:"border.emphasized"},_disabled:{pointerEvents:"none",opacity:"0.5"}},empty:{py:"var(--listbox-item-padding-y)",px:"var(--listbox-item-padding-x)"},itemText:{flex:"1"},itemGroup:{mt:"1.5",_first:{mt:"0"}},itemGroupLabel:{py:"1.5",px:"2",fontWeight:"medium"},label:{fontWeight:"medium",userSelect:"none",textStyle:"sm",_disabled:{layerStyle:"disabled"}},valueText:{lineClamp:"1",maxW:"80%"},itemIndicator:{display:"flex",alignItems:"center",justifyContent:"center",_icon:{boxSize:"4"}}},variants:{variant:{subtle:{content:{bg:"bg.panel",borderWidth:"1px",borderRadius:"l2"},item:{_hover:{bg:"bg.emphasized/60"},_selected:{bg:"bg.muted"}}},solid:{content:{bg:"bg.panel",borderWidth:"1px",borderRadius:"l2"},item:{_selected:{bg:"colorPalette.solid",color:"colorPalette.contrast"}}},plain:{}}},defaultVariants:{variant:"subtle"}}),MI=q({className:"chakra-menu",slots:XO.keys(),base:{content:{outline:0,bg:"bg.panel",boxShadow:"lg",color:"fg",maxHeight:"var(--available-height)","--menu-z-index":"zIndex.dropdown",zIndex:"calc(var(--menu-z-index) + var(--layer-index, 0))",borderRadius:"l2",overflow:"hidden",overflowY:"auto",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"faster"}},item:{textDecoration:"none",color:"fg",userSelect:"none",borderRadius:"l1",width:"100%",display:"flex",cursor:"menuitem",alignItems:"center",textAlign:"start",position:"relative",flex:"0 0 auto",outline:0,_disabled:{layerStyle:"disabled"},"&[data-type]":{ps:"8"}},itemText:{flex:"1"},itemIndicator:{position:"absolute",insetStart:"2",transform:"translateY(-50%)",top:"50%"},itemGroupLabel:{px:"2",py:"1.5",fontWeight:"semibold",textStyle:"sm"},indicator:{display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:"0"},itemCommand:{opacity:"0.6",textStyle:"xs",ms:"auto",ps:"4",letterSpacing:"widest",fontFamily:"inherit"},separator:{height:"1px",bg:"bg.muted",my:"1",mx:"-1"}},variants:{variant:{subtle:{item:{_highlighted:{bg:"bg.emphasized/60"}}},solid:{item:{_highlighted:{bg:"colorPalette.solid",color:"colorPalette.contrast"}}}},size:{sm:{content:{minW:"8rem",padding:"1",scrollPadding:"1"},item:{gap:"1",textStyle:"xs",py:"1",px:"1.5"}},md:{content:{minW:"8rem",padding:"1.5",scrollPadding:"1.5"},item:{gap:"2",textStyle:"sm",py:"1.5",px:"2"}}}},defaultVariants:{size:"md",variant:"subtle"}}),us=q({className:"chakra-select",slots:eI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5",width:"full"},trigger:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"full",minH:"var(--select-trigger-height)","--input-height":"var(--select-trigger-height)",px:"var(--select-trigger-padding-x)",borderRadius:"l2",userSelect:"none",textAlign:"start",focusVisibleRing:"inside",_placeholderShown:{color:"fg.muted/80"},_disabled:{layerStyle:"disabled"},_invalid:{borderColor:"border.error"}},indicatorGroup:{display:"flex",alignItems:"center",gap:"1",pos:"absolute",insetEnd:"0",top:"0",bottom:"0",px:"var(--select-trigger-padding-x)",pointerEvents:"none"},indicator:{display:"flex",alignItems:"center",justifyContent:"center",color:{base:"fg.muted",_disabled:"fg.subtle",_invalid:"fg.error"}},content:{background:"bg.panel",display:"flex",flexDirection:"column",zIndex:"dropdown",borderRadius:"l2",outline:0,maxH:"96",overflowY:"auto",boxShadow:"md",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"fastest"}},item:{position:"relative",userSelect:"none",display:"flex",alignItems:"center",gap:"2",cursor:"option",justifyContent:"space-between",flex:"1",textAlign:"start",borderRadius:"l1",_highlighted:{bg:"bg.emphasized/60"},_disabled:{pointerEvents:"none",opacity:"0.5"},_icon:{width:"4",height:"4"}},control:{pos:"relative"},itemText:{flex:"1"},itemGroup:{_first:{mt:"0"}},itemGroupLabel:{py:"1",fontWeight:"medium"},label:{fontWeight:"medium",userSelect:"none",textStyle:"sm",_disabled:{layerStyle:"disabled"}},valueText:{lineClamp:"1",maxW:"80%"},clearTrigger:{color:"fg.muted",pointerEvents:"auto",focusVisibleRing:"inside",focusRingWidth:"2px",rounded:"l1"}},variants:{variant:{outline:{trigger:{bg:"transparent",borderWidth:"1px",borderColor:"border",_expanded:{borderColor:"border.emphasized"}}},subtle:{trigger:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted"}}},size:{xs:{root:{"--select-trigger-height":"sizes.8","--select-trigger-padding-x":"spacing.2"},content:{p:"1",gap:"1",textStyle:"xs"},trigger:{textStyle:"xs",gap:"1"},item:{py:"1",px:"2"},itemGroupLabel:{py:"1",px:"2"},indicator:{_icon:{width:"3.5",height:"3.5"}}},sm:{root:{"--select-trigger-height":"sizes.9","--select-trigger-padding-x":"spacing.2.5"},content:{p:"1",textStyle:"sm"},trigger:{textStyle:"sm",gap:"1"},indicator:{_icon:{width:"4",height:"4"}},item:{py:"1",px:"1.5"},itemGroup:{mt:"1"},itemGroupLabel:{py:"1",px:"1.5"}},md:{root:{"--select-trigger-height":"sizes.10","--select-trigger-padding-x":"spacing.3"},content:{p:"1",textStyle:"sm"},itemGroup:{mt:"1.5"},item:{py:"1.5",px:"2"},itemIndicator:{display:"flex",alignItems:"center",justifyContent:"center"},itemGroupLabel:{py:"1.5",px:"2"},trigger:{textStyle:"sm",gap:"2"},indicator:{_icon:{width:"4",height:"4"}}},lg:{root:{"--select-trigger-height":"sizes.12","--select-trigger-padding-x":"spacing.4"},content:{p:"1.5",textStyle:"md"},itemGroup:{mt:"2"},item:{py:"2",px:"3"},itemGroupLabel:{py:"2",px:"3"},trigger:{textStyle:"md",py:"3",gap:"2"},indicator:{_icon:{width:"5",height:"5"}}}}},defaultVariants:{size:"md",variant:"outline"}}),$I=q({className:"chakra-native-select",slots:YO.keys(),base:{root:{height:"fit-content",display:"flex",width:"100%",position:"relative"},field:{width:"100%",minWidth:"0",outline:"0",appearance:"none",borderRadius:"l2","--error-color":"colors.border.error","--input-height":"var(--select-field-height)",height:"var(--select-field-height)",_disabled:{layerStyle:"disabled"},_invalid:{focusRingColor:"var(--error-color)",borderColor:"var(--error-color)"},focusVisibleRing:"inside",lineHeight:"normal","& > option, & > optgroup":{bg:"bg"}},indicator:{position:"absolute",display:"inline-flex",alignItems:"center",justifyContent:"center",pointerEvents:"none",top:"50%",transform:"translateY(-50%)",height:"100%",color:"fg.muted",_disabled:{opacity:"0.5"},_invalid:{color:"fg.error"},_icon:{width:"1em",height:"1em"}}},variants:{variant:{outline:{field:(Qm=us.variants)==null?void 0:Qm.variant.outline.trigger},subtle:{field:(Jm=us.variants)==null?void 0:Jm.variant.subtle.trigger},plain:{field:{bg:"transparent",color:"fg",focusRingWidth:"2px"}}},size:{xs:{root:{"--select-field-height":"sizes.8"},field:{textStyle:"xs",ps:"2",pe:"6"},indicator:{textStyle:"sm",insetEnd:"1.5"}},sm:{root:{"--select-field-height":"sizes.9"},field:{textStyle:"sm",ps:"2.5",pe:"8"},indicator:{textStyle:"md",insetEnd:"2"}},md:{root:{"--select-field-height":"sizes.10"},field:{textStyle:"sm",ps:"3",pe:"8"},indicator:{textStyle:"lg",insetEnd:"2"}},lg:{root:{"--select-field-height":"sizes.11"},field:{textStyle:"md",ps:"4",pe:"8"},indicator:{textStyle:"xl",insetEnd:"3"}},xl:{root:{"--select-field-height":"sizes.12"},field:{textStyle:"md",ps:"4.5",pe:"10"},indicator:{textStyle:"xl",insetEnd:"3"}}}},defaultVariants:us.defaultVariants});function Nl(e,t){const n={};for(const r in e){const i=t(r,e[r]);n[i[0]]=i[1]}return n}const ng=Ir({display:"flex",justifyContent:"center",alignItems:"center",flex:"1",userSelect:"none",cursor:"button",lineHeight:"1",color:"fg.muted","--stepper-base-radius":"radii.l1","--stepper-radius":"calc(var(--stepper-base-radius) + 1px)",_icon:{boxSize:"1em"},_disabled:{opacity:"0.5"},_hover:{bg:"bg.muted"},_active:{bg:"bg.emphasized"}}),BI=q({className:"chakra-number-input",slots:zh.keys(),base:{root:{position:"relative",zIndex:"0",isolation:"isolate"},input:{...Ce.base,verticalAlign:"top",pe:"calc(var(--stepper-width) + 0.5rem)"},control:{display:"flex",flexDirection:"column",position:"absolute",top:"0",insetEnd:"0px",margin:"1px",width:"var(--stepper-width)",height:"calc(100% - 2px)",zIndex:"1",borderStartWidth:"1px",divideY:"1px"},incrementTrigger:{...ng,borderTopEndRadius:"var(--stepper-radius)"},decrementTrigger:{...ng,borderBottomEndRadius:"var(--stepper-radius)"},valueText:{fontWeight:"medium",fontFeatureSettings:"pnum",fontVariantNumeric:"proportional-nums"}},variants:{size:{xs:{input:Ce.variants.size.xs,control:{fontSize:"2xs","--stepper-width":"sizes.4"}},sm:{input:Ce.variants.size.sm,control:{fontSize:"xs","--stepper-width":"sizes.5"}},md:{input:Ce.variants.size.md,control:{fontSize:"sm","--stepper-width":"sizes.6"}},lg:{input:Ce.variants.size.lg,control:{fontSize:"sm","--stepper-width":"sizes.6"}}},variant:Nl(Ce.variants.variant,(e,t)=>[e,{input:t}])},defaultVariants:{size:"md",variant:"outline"}}),{variants:rg,defaultVariants:jI}=Ce,WI=q({className:"chakra-pin-input",slots:Wh.keys(),base:{input:{...Ce.base,textAlign:"center",width:"var(--input-height)"},control:{display:"inline-flex",gap:"2",isolation:"isolate"}},variants:{size:Nl(rg.size,(e,t)=>[e,{input:{...t,px:"1"}}]),variant:Nl(rg.variant,(e,t)=>[e,{input:t}]),attached:{true:{control:{gap:"0",spaceX:"-1px"},input:{_notFirst:{borderStartRadius:"0"},_notLast:{borderEndRadius:"0"},_focusVisible:{zIndex:"1"}}}}},defaultVariants:jI}),HI=q({className:"chakra-popover",slots:QO.keys(),base:{content:{position:"relative",display:"flex",flexDirection:"column",textStyle:"sm","--popover-bg":"colors.bg.panel",bg:"var(--popover-bg)",boxShadow:"lg","--popover-size":"sizes.xs","--popover-mobile-size":"calc(100dvw - 1rem)",width:{base:"min(var(--popover-mobile-size), var(--popover-size))",sm:"var(--popover-size)"},borderRadius:"l3","--popover-z-index":"zIndex.popover",zIndex:"calc(var(--popover-z-index) + var(--layer-index, 0))",outline:"0",transformOrigin:"var(--transform-origin)",maxHeight:"var(--available-height)",_open:{animationStyle:"scale-fade-in",animationDuration:"fast"},_closed:{animationStyle:"scale-fade-out",animationDuration:"faster"}},header:{paddingInline:"var(--popover-padding)",paddingTop:"var(--popover-padding)"},body:{padding:"var(--popover-padding)",flex:"1"},footer:{display:"flex",alignItems:"center",paddingInline:"var(--popover-padding)",paddingBottom:"var(--popover-padding)"},arrow:{"--arrow-size":"sizes.3","--arrow-background":"var(--popover-bg)"},arrowTip:{borderTopWidth:"1px",borderInlineStartWidth:"1px"}},variants:{size:{xs:{content:{"--popover-padding":"spacing.3"}},sm:{content:{"--popover-padding":"spacing.4"}},md:{content:{"--popover-padding":"spacing.5"}},lg:{content:{"--popover-padding":"spacing.6"}}}},defaultVariants:{size:"md"}}),UI=q({slots:hl.keys(),className:"chakra-progress",base:{root:{textStyle:"sm",position:"relative"},track:{overflow:"hidden",position:"relative"},range:{display:"flex",alignItems:"center",justifyContent:"center",transitionProperty:"width, height",transitionDuration:"slow",height:"100%",bgColor:"var(--track-color)",_indeterminate:{"--animate-from-x":"-40%","--animate-to-x":"100%",position:"absolute",willChange:"left",minWidth:"50%",animation:"position 1s ease infinite normal none running",backgroundImage:"linear-gradient(to right, transparent 0%, var(--track-color) 50%, transparent 100%)"}},label:{display:"inline-flex",fontWeight:"medium",alignItems:"center",gap:"1"},valueText:{textStyle:"xs",lineHeight:"1",fontWeight:"medium"}},variants:{variant:{outline:{track:{shadow:"inset",bgColor:"bg.muted"},range:{bgColor:"colorPalette.solid"}},subtle:{track:{bgColor:"colorPalette.muted"},range:{bgColor:"colorPalette.solid/72"}}},shape:{square:{},rounded:{track:{borderRadius:"l1"}},full:{track:{borderRadius:"full"}}},striped:{true:{range:{backgroundImage:"linear-gradient(45deg, var(--stripe-color) 25%, transparent 25%, transparent 50%, var(--stripe-color) 50%, var(--stripe-color) 75%, transparent 75%, transparent)",backgroundSize:"var(--stripe-size) var(--stripe-size)","--stripe-size":"1rem","--stripe-color":{_light:"rgba(255, 255, 255, 0.3)",_dark:"rgba(0, 0, 0, 0.3)"}}}},animated:{true:{range:{"--animate-from":"var(--stripe-size)",animation:"bg-position 1s linear infinite"}}},size:{xs:{track:{h:"1.5"}},sm:{track:{h:"2"}},md:{track:{h:"2.5"}},lg:{track:{h:"3"}},xl:{track:{h:"4"}}}},defaultVariants:{variant:"outline",size:"md",shape:"rounded"}}),GI=q({className:"chakra-progress-circle",slots:hl.keys(),base:{root:{display:"inline-flex",textStyle:"sm",position:"relative"},circle:{_indeterminate:{animation:"spin 2s linear infinite"}},circleTrack:{"--track-color":"colors.colorPalette.muted",stroke:"var(--track-color)"},circleRange:{stroke:"colorPalette.solid",transitionProperty:"stroke-dashoffset, stroke-dasharray",transitionDuration:"0.6s",_indeterminate:{animation:"circular-progress 1.5s linear infinite"}},label:{display:"inline-flex"},valueText:{lineHeight:"1",fontWeight:"medium",letterSpacing:"tight",fontVariantNumeric:"tabular-nums"}},variants:{size:{xs:{circle:{"--size":"24px","--thickness":"4px"},valueText:{textStyle:"2xs"}},sm:{circle:{"--size":"32px","--thickness":"5px"},valueText:{textStyle:"2xs"}},md:{circle:{"--size":"40px","--thickness":"6px"},valueText:{textStyle:"xs"}},lg:{circle:{"--size":"48px","--thickness":"7px"},valueText:{textStyle:"sm"}},xl:{circle:{"--size":"64px","--thickness":"8px"},valueText:{textStyle:"sm"}}}},defaultVariants:{size:"md"}}),qI=q({slots:Uh.keys(),className:"chakra-qr-code",base:{root:{position:"relative",width:"fit-content","--qr-code-overlay-size":"calc(var(--qr-code-size) / 3)"},frame:{width:"var(--qr-code-size)",height:"var(--qr-code-size)",fill:"currentColor"},overlay:{display:"flex",alignItems:"center",justifyContent:"center",width:"var(--qr-code-overlay-size)",height:"var(--qr-code-overlay-size)",padding:"1",bg:"bg",rounded:"l1"}},variants:{size:{"2xs":{root:{"--qr-code-size":"40px"}},xs:{root:{"--qr-code-size":"64px"}},sm:{root:{"--qr-code-size":"80px"}},md:{root:{"--qr-code-size":"120px"}},lg:{root:{"--qr-code-size":"160px"}},xl:{root:{"--qr-code-size":"200px"}},"2xl":{root:{"--qr-code-size":"240px"}},full:{root:{"--qr-code-size":"100%"}}}},defaultVariants:{size:"md"}}),KI=q({className:"chakra-radio-card",slots:JO.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5",isolation:"isolate"},item:{flex:"1",display:"flex",flexDirection:"column",userSelect:"none",position:"relative",borderRadius:"l2",_focus:{bg:"colorPalette.muted/20"},_disabled:{opacity:"0.8",borderColor:"border.disabled"},_checked:{zIndex:"1"}},label:{display:"inline-flex",fontWeight:"medium",textStyle:"sm",_disabled:{opacity:"0.5"}},itemText:{fontWeight:"medium",flex:"1"},itemDescription:{opacity:"0.64",textStyle:"sm"},itemControl:{display:"inline-flex",flex:"1",pos:"relative",rounded:"inherit",justifyContent:"var(--radio-card-justify)",alignItems:"var(--radio-card-align)",_disabled:{bg:"bg.muted"}},itemIndicator:Fe.base,itemAddon:{roundedBottom:"inherit",_disabled:{color:"fg.muted"}},itemContent:{display:"flex",flexDirection:"column",flex:"1",gap:"1",justifyContent:"var(--radio-card-justify)",alignItems:"var(--radio-card-align)"}},variants:{size:{sm:{item:{textStyle:"sm"},itemControl:{padding:"3",gap:"1.5"},itemAddon:{px:"3",py:"1.5",borderTopWidth:"1px"},itemIndicator:(Zm=Fe.variants)==null?void 0:Zm.size.sm},md:{item:{textStyle:"sm"},itemControl:{padding:"4",gap:"2.5"},itemAddon:{px:"4",py:"2",borderTopWidth:"1px"},itemIndicator:(ev=Fe.variants)==null?void 0:ev.size.md},lg:{item:{textStyle:"md"},itemControl:{padding:"4",gap:"3.5"},itemAddon:{px:"4",py:"2",borderTopWidth:"1px"},itemIndicator:(tv=Fe.variants)==null?void 0:tv.size.lg}},variant:{surface:{item:{borderWidth:"1px",_checked:{bg:"colorPalette.subtle",color:"colorPalette.fg",borderColor:"colorPalette.muted"}},itemIndicator:(nv=Fe.variants)==null?void 0:nv.variant.solid},subtle:{item:{bg:"bg.muted"},itemControl:{_checked:{bg:"colorPalette.muted",color:"colorPalette.fg"}},itemIndicator:(rv=Fe.variants)==null?void 0:rv.variant.outline},outline:{item:{borderWidth:"1px",_checked:{boxShadow:"0 0 0 1px var(--shadow-color)",boxShadowColor:"colorPalette.solid",borderColor:"colorPalette.solid"}},itemIndicator:(iv=Fe.variants)==null?void 0:iv.variant.solid},solid:{item:{borderWidth:"1px",_checked:{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"colorPalette.solid"}},itemIndicator:(ov=Fe.variants)==null?void 0:ov.variant.inverted}},justify:{start:{item:{"--radio-card-justify":"flex-start"}},end:{item:{"--radio-card-justify":"flex-end"}},center:{item:{"--radio-card-justify":"center"}}},align:{start:{item:{"--radio-card-align":"flex-start"},itemControl:{textAlign:"start"}},end:{item:{"--radio-card-align":"flex-end"},itemControl:{textAlign:"end"}},center:{item:{"--radio-card-align":"center"},itemControl:{textAlign:"center"}}},orientation:{vertical:{itemControl:{flexDirection:"column"}},horizontal:{itemControl:{flexDirection:"row"}}}},defaultVariants:{size:"md",variant:"outline",align:"start",orientation:"horizontal"}}),XI=q({className:"chakra-radio-group",slots:eg.keys(),base:{item:{display:"inline-flex",alignItems:"center",position:"relative",fontWeight:"medium",_disabled:{cursor:"disabled"}},itemControl:Fe.base,label:{userSelect:"none",textStyle:"sm",_disabled:{opacity:"0.5"}}},variants:{variant:{outline:{itemControl:(av=(sv=Fe.variants)==null?void 0:sv.variant)==null?void 0:av.outline},subtle:{itemControl:(cv=(lv=Fe.variants)==null?void 0:lv.variant)==null?void 0:cv.subtle},solid:{itemControl:(dv=(uv=Fe.variants)==null?void 0:uv.variant)==null?void 0:dv.solid}},size:{xs:{item:{textStyle:"xs",gap:"1.5"},itemControl:(fv=(hv=Fe.variants)==null?void 0:hv.size)==null?void 0:fv.xs},sm:{item:{textStyle:"sm",gap:"2"},itemControl:(pv=(gv=Fe.variants)==null?void 0:gv.size)==null?void 0:pv.sm},md:{item:{textStyle:"sm",gap:"2.5"},itemControl:(vv=(mv=Fe.variants)==null?void 0:mv.size)==null?void 0:vv.md},lg:{item:{textStyle:"md",gap:"3"},itemControl:(yv=(bv=Fe.variants)==null?void 0:bv.size)==null?void 0:yv.lg}}},defaultVariants:{size:"md",variant:"solid"}}),YI=q({className:"chakra-rating-group",slots:ZO.keys(),base:{root:{display:"inline-flex"},control:{display:"inline-flex",alignItems:"center"},item:{display:"inline-flex",alignItems:"center",justifyContent:"center",userSelect:"none"},itemIndicator:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:"1em",height:"1em",position:"relative","--clip-path":{base:"inset(0 50% 0 0)",_rtl:"inset(0 0 0 50%)"},_icon:{stroke:"currentColor",width:"100%",height:"100%",display:"inline-block",flexShrink:0,position:"absolute",left:0,top:0},"& [data-bg]":{color:"bg.emphasized"},"& [data-fg]":{color:"transparent"},"&[data-highlighted]:not([data-half])":{"& [data-fg]":{color:"colorPalette.solid"}},"&[data-half]":{"& [data-fg]":{color:"colorPalette.solid",clipPath:"var(--clip-path)"}}}},variants:{size:{xs:{item:{textStyle:"sm"}},sm:{item:{textStyle:"md"}},md:{item:{textStyle:"xl"}},lg:{item:{textStyle:"2xl"}}}},defaultVariants:{size:"md"}}),QI=q({className:"chakra-scroll-area",slots:qh.keys(),base:{root:{display:"flex",flexDirection:"column",width:"100%",height:"100%",position:"relative",overflow:"hidden","--scrollbar-margin":"2px","--scrollbar-click-area":"calc(var(--scrollbar-size) + calc(var(--scrollbar-margin) * 2))"},viewport:{display:"flex",flexDirection:"column",height:"100%",width:"100%",borderRadius:"inherit",WebkitOverflowScrolling:"touch",scrollbarWidth:"none","&::-webkit-scrollbar":{display:"none"}},content:{minWidth:"100%"},scrollbar:{display:"flex",userSelect:"none",touchAction:"none",borderRadius:"full",colorPalette:"gray",transition:"opacity 150ms 300ms",position:"relative",margin:"var(--scrollbar-margin)","&:not([data-overflow-x], [data-overflow-y])":{display:"none"},bg:"{colors.colorPalette.solid/10}","--thumb-bg":"{colors.colorPalette.solid/25}","&:is(:hover, :active)":{"--thumb-bg":"{colors.colorPalette.solid/50}"},_before:{content:'""',position:"absolute"},_vertical:{width:"var(--scrollbar-size)",flexDirection:"column","&::before":{width:"var(--scrollbar-click-area)",height:"100%",insetInlineStart:"calc(var(--scrollbar-margin) * -1)"}},_horizontal:{height:"var(--scrollbar-size)",flexDirection:"row","&::before":{height:"var(--scrollbar-click-area)",width:"100%",top:"calc(var(--scrollbar-margin) * -1)"}}},thumb:{borderRadius:"inherit",bg:"var(--thumb-bg)",transition:"backgrounds",_vertical:{width:"full"},_horizontal:{height:"full"}},corner:{bg:"bg.muted",margin:"var(--scrollbar-margin)",opacity:0,transition:"opacity 150ms 300ms","&[data-hover]":{transitionDelay:"0ms",opacity:1}}},variants:{variant:{hover:{scrollbar:{opacity:"0","&[data-hover], &[data-scrolling]":{opacity:"1",transitionDuration:"faster",transitionDelay:"0ms"}}},always:{scrollbar:{opacity:"1"}}},size:{xs:{root:{"--scrollbar-size":"sizes.1"}},sm:{root:{"--scrollbar-size":"sizes.1.5"}},md:{root:{"--scrollbar-size":"sizes.2"}},lg:{root:{"--scrollbar-size":"sizes.3"}}}},defaultVariants:{size:"md",variant:"hover"}}),JI=q({className:"chakra-segment-group",slots:Kh.keys(),base:{root:{"--segment-radius":"radii.l2",borderRadius:"l2",display:"inline-flex",boxShadow:"inset",minW:"max-content",textAlign:"center",position:"relative",isolation:"isolate",bg:"bg.muted",_vertical:{flexDirection:"column"}},item:{display:"flex",alignItems:"center",justifyContent:"center",userSelect:"none",fontSize:"sm",position:"relative",color:"fg",borderRadius:"var(--segment-radius)",_disabled:{opacity:"0.5"},"&:has(input:focus-visible)":{focusRing:"outside"},_before:{content:'""',position:"absolute",bg:"border",transition:"opacity 0.2s"},_horizontal:{_before:{insetInlineStart:0,insetBlock:"1.5",width:"1px"}},_vertical:{_before:{insetBlockStart:0,insetInline:"1.5",height:"1px"}},"& + &[data-state=checked], &[data-state=checked] + &, &:first-of-type":{_before:{opacity:"0"}},"&[data-state=checked][data-ssr]":{shadow:"sm",bg:"bg",borderRadius:"var(--segment-radius)"}},indicator:{shadow:"sm",pos:"absolute",bg:{_light:"bg",_dark:"bg.emphasized"},width:"var(--width)",height:"var(--height)",top:"var(--top)",left:"var(--left)",zIndex:-1,borderRadius:"var(--segment-radius)"}},variants:{size:{xs:{item:{textStyle:"xs",px:"3",gap:"1",height:"6"}},sm:{item:{textStyle:"sm",px:"4",gap:"2",height:"8"}},md:{item:{textStyle:"sm",px:"4",gap:"2",height:"10"}},lg:{item:{textStyle:"md",px:"4.5",gap:"3",height:"11"}}}},defaultVariants:{size:"md"}}),ZI=q({className:"chakra-slider",slots:nI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1",textStyle:"sm",position:"relative",isolation:"isolate",touchAction:"none"},label:{fontWeight:"medium",textStyle:"sm"},control:{display:"inline-flex",alignItems:"center",position:"relative"},track:{overflow:"hidden",borderRadius:"full",flex:"1"},range:{width:"inherit",height:"inherit",_disabled:{bg:"border.emphasized!"}},markerGroup:{position:"absolute!",zIndex:"1"},marker:{"--marker-bg":{base:"white",_underValue:"colors.bg"},display:"flex",alignItems:"center",gap:"calc(var(--slider-thumb-size) / 2)",color:"fg.muted",textStyle:"xs"},markerIndicator:{width:"var(--slider-marker-size)",height:"var(--slider-marker-size)",borderRadius:"full",bg:"var(--marker-bg)"},thumb:{width:"var(--slider-thumb-size)",height:"var(--slider-thumb-size)",display:"flex",alignItems:"center",justifyContent:"center",outline:0,zIndex:"2",borderRadius:"full",_focusVisible:{ring:"2px",ringColor:"colorPalette.focusRing",ringOffset:"2px",ringOffsetColor:"bg"}}},variants:{size:{sm:{root:{"--slider-thumb-size":"sizes.4","--slider-track-size":"sizes.1.5","--slider-marker-center":"6px","--slider-marker-size":"sizes.1","--slider-marker-inset":"3px"}},md:{root:{"--slider-thumb-size":"sizes.5","--slider-track-size":"sizes.2","--slider-marker-center":"8px","--slider-marker-size":"sizes.1","--slider-marker-inset":"4px"}},lg:{root:{"--slider-thumb-size":"sizes.6","--slider-track-size":"sizes.2.5","--slider-marker-center":"9px","--slider-marker-size":"sizes.1.5","--slider-marker-inset":"5px"}}},variant:{outline:{track:{shadow:"inset",bg:"bg.emphasized/72"},range:{bg:"colorPalette.solid"},thumb:{borderWidth:"2px",borderColor:"colorPalette.solid",bg:"bg",_disabled:{bg:"border.emphasized",borderColor:"border.emphasized"}}},solid:{track:{bg:"colorPalette.subtle",_disabled:{bg:"bg.muted"}},range:{bg:"colorPalette.solid"},thumb:{bg:"colorPalette.solid",_disabled:{bg:"border.emphasized"}}}},orientation:{vertical:{root:{display:"inline-flex"},control:{flexDirection:"column",height:"100%",minWidth:"var(--slider-thumb-size)","&[data-has-mark-label], &:has(.chakra-slider__marker-label)":{marginEnd:"4"}},track:{width:"var(--slider-track-size)"},thumb:{left:"50%",translate:"-50% 0"},markerGroup:{insetStart:"var(--slider-marker-center)",insetBlock:"var(--slider-marker-inset)"},marker:{flexDirection:"row"}},horizontal:{control:{flexDirection:"row",width:"100%",minHeight:"var(--slider-thumb-size)","&[data-has-mark-label], &:has(.chakra-slider__marker-label)":{marginBottom:"4"}},track:{height:"var(--slider-track-size)"},thumb:{top:"50%",translate:"0 -50%"},markerGroup:{top:"var(--slider-marker-center)",insetInline:"var(--slider-marker-inset)"},marker:{flexDirection:"column"}}}},defaultVariants:{size:"md",variant:"outline",orientation:"horizontal"}}),eP=q({className:"chakra-stat",slots:rI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1",position:"relative",flex:"1"},label:{display:"inline-flex",gap:"1.5",alignItems:"center",color:"fg.muted",textStyle:"sm"},helpText:{color:"fg.muted",textStyle:"xs"},valueUnit:{color:"fg.muted",textStyle:"xs",fontWeight:"initial",letterSpacing:"initial"},valueText:{verticalAlign:"baseline",fontWeight:"semibold",letterSpacing:"tight",fontFeatureSettings:"pnum",fontVariantNumeric:"proportional-nums",display:"inline-flex",gap:"1"},indicator:{display:"inline-flex",alignItems:"center",justifyContent:"center",marginEnd:1,"& :where(svg)":{w:"1em",h:"1em"},"&[data-type=up]":{color:"fg.success"},"&[data-type=down]":{color:"fg.error"}}},variants:{size:{sm:{valueText:{textStyle:"xl"}},md:{valueText:{textStyle:"2xl"}},lg:{valueText:{textStyle:"3xl"}}}},defaultVariants:{size:"md"}}),tP=q({className:"chakra-status",slots:iI.keys(),base:{root:{display:"inline-flex",alignItems:"center",gap:"2"},indicator:{width:"0.64em",height:"0.64em",flexShrink:0,borderRadius:"full",forcedColorAdjust:"none",bg:"colorPalette.solid"}},variants:{size:{sm:{root:{textStyle:"xs"}},md:{root:{textStyle:"sm"}},lg:{root:{textStyle:"md"}}}},defaultVariants:{size:"md"}}),nP=q({className:"chakra-steps",slots:oI.keys(),base:{root:{display:"flex",width:"full"},list:{display:"flex",justifyContent:"space-between","--steps-gutter":"spacing.3","--steps-thickness":"2px"},title:{fontWeight:"medium",color:"fg"},description:{color:"fg.muted"},separator:{bg:"border",flex:"1"},indicator:{display:"flex",justifyContent:"center",alignItems:"center",flexShrink:"0",borderRadius:"full",fontWeight:"medium",width:"var(--steps-size)",height:"var(--steps-size)",_icon:{flexShrink:"0",width:"var(--steps-icon-size)",height:"var(--steps-icon-size)"}},item:{position:"relative",display:"flex",gap:"3",flex:"1 0 0","&:last-of-type":{flex:"initial","& [data-part=separator]":{display:"none"}}},trigger:{display:"flex",alignItems:"center",gap:"3",textAlign:"start",focusVisibleRing:"outside",borderRadius:"l2"},content:{focusVisibleRing:"outside"}},variants:{orientation:{vertical:{root:{flexDirection:"row",height:"100%"},list:{flexDirection:"column",alignItems:"flex-start"},separator:{position:"absolute",width:"var(--steps-thickness)",height:"100%",maxHeight:"calc(100% - var(--steps-size) - var(--steps-gutter) * 2)",top:"calc(var(--steps-size) + var(--steps-gutter))",insetStart:"calc(var(--steps-size) / 2 - 1px)"},item:{alignItems:"flex-start"}},horizontal:{root:{flexDirection:"column",width:"100%"},list:{flexDirection:"row",alignItems:"center"},separator:{width:"100%",height:"var(--steps-thickness)",marginX:"var(--steps-gutter)"},item:{alignItems:"center"}}},variant:{solid:{indicator:{_incomplete:{borderWidth:"var(--steps-thickness)"},_current:{bg:"colorPalette.muted",borderWidth:"var(--steps-thickness)",borderColor:"colorPalette.solid",color:"colorPalette.fg"},_complete:{bg:"colorPalette.solid",borderColor:"colorPalette.solid",color:"colorPalette.contrast"}},separator:{_complete:{bg:"colorPalette.solid"}}},subtle:{indicator:{_incomplete:{bg:"bg.muted"},_current:{bg:"colorPalette.muted",color:"colorPalette.fg"},_complete:{bg:"colorPalette.emphasized",color:"colorPalette.fg"}},separator:{_complete:{bg:"colorPalette.emphasized"}}}},size:{xs:{root:{gap:"2.5"},list:{"--steps-size":"sizes.6","--steps-icon-size":"sizes.3.5",textStyle:"xs"},title:{textStyle:"sm"}},sm:{root:{gap:"3"},list:{"--steps-size":"sizes.8","--steps-icon-size":"sizes.4",textStyle:"xs"},title:{textStyle:"sm"}},md:{root:{gap:"4"},list:{"--steps-size":"sizes.10","--steps-icon-size":"sizes.4",textStyle:"sm"},title:{textStyle:"sm"}},lg:{root:{gap:"6"},list:{"--steps-size":"sizes.11","--steps-icon-size":"sizes.5",textStyle:"md"},title:{textStyle:"md"}}}},defaultVariants:{size:"md",variant:"solid",orientation:"horizontal"}}),rP=q({slots:sI.keys(),className:"chakra-switch",base:{root:{display:"inline-flex",gap:"2.5",alignItems:"center",position:"relative",verticalAlign:"middle","--switch-diff":"calc(var(--switch-width) - var(--switch-height))","--switch-x":{base:"var(--switch-diff)",_rtl:"calc(var(--switch-diff) * -1)"}},label:{lineHeight:"1",userSelect:"none",fontSize:"sm",fontWeight:"medium",_disabled:{opacity:"0.5"}},indicator:{position:"absolute",height:"var(--switch-height)",width:"var(--switch-height)",fontSize:"var(--switch-indicator-font-size)",fontWeight:"medium",flexShrink:0,userSelect:"none",display:"grid",placeContent:"center",transition:"inset-inline-start 0.12s ease",insetInlineStart:"calc(var(--switch-x) - 2px)",_checked:{insetInlineStart:"2px"}},control:{display:"inline-flex",gap:"0.5rem",flexShrink:0,justifyContent:"flex-start",cursor:"switch",borderRadius:"full",position:"relative",width:"var(--switch-width)",height:"var(--switch-height)",transition:"backgrounds",_disabled:{opacity:"0.5",cursor:"not-allowed"},_invalid:{outline:"2px solid",outlineColor:"border.error",outlineOffset:"2px"}},thumb:{display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,transitionProperty:"translate",transitionDuration:"fast",borderRadius:"inherit",_checked:{translate:"var(--switch-x) 0"}}},variants:{variant:{solid:{control:{borderRadius:"full",bg:"bg.emphasized",focusVisibleRing:"outside",_checked:{bg:"colorPalette.solid"}},thumb:{bg:"white",width:"var(--switch-height)",height:"var(--switch-height)",scale:"0.8",boxShadow:"sm",_checked:{bg:"colorPalette.contrast"}}},raised:{control:{borderRadius:"full",height:"calc(var(--switch-height) / 2)",bg:"bg.muted",boxShadow:"inset",_checked:{bg:"colorPalette.solid/60"}},thumb:{width:"var(--switch-height)",height:"var(--switch-height)",position:"relative",top:"calc(var(--switch-height) * -0.25)",bg:"white",boxShadow:"xs",focusVisibleRing:"outside",_checked:{bg:"colorPalette.solid"}}}},size:{xs:{root:{"--switch-width":"sizes.6","--switch-height":"sizes.3","--switch-indicator-font-size":"fontSizes.xs"}},sm:{root:{"--switch-width":"sizes.8","--switch-height":"sizes.4","--switch-indicator-font-size":"fontSizes.xs"}},md:{root:{"--switch-width":"sizes.10","--switch-height":"sizes.5","--switch-indicator-font-size":"fontSizes.sm"}},lg:{root:{"--switch-width":"sizes.12","--switch-height":"sizes.6","--switch-indicator-font-size":"fontSizes.md"}}}},defaultVariants:{variant:"solid",size:"md"}}),iP=q({className:"chakra-table",slots:aI.keys(),base:{root:{fontVariantNumeric:"lining-nums tabular-nums",borderCollapse:"collapse",width:"full",textAlign:"start",verticalAlign:"top"},row:{_selected:{bg:"colorPalette.subtle"}},cell:{textAlign:"start",alignItems:"center"},columnHeader:{fontWeight:"medium",textAlign:"start",color:"fg"},caption:{fontWeight:"medium",textStyle:"xs"},footer:{fontWeight:"medium"}},variants:{interactive:{true:{body:{"& tr":{_hover:{bg:"colorPalette.subtle"}}}}},stickyHeader:{true:{header:{"& :where(tr)":{top:"var(--table-sticky-offset, 0)",position:"sticky",zIndex:1}}}},striped:{true:{row:{"&:nth-of-type(odd) td":{bg:"bg.muted"}}}},showColumnBorder:{true:{columnHeader:{"&:not(:last-of-type)":{borderInlineEndWidth:"1px"}},cell:{"&:not(:last-of-type)":{borderInlineEndWidth:"1px"}}}},variant:{line:{columnHeader:{borderBottomWidth:"1px"},cell:{borderBottomWidth:"1px"},row:{bg:"bg"}},outline:{root:{boxShadow:"0 0 0 1px {colors.border}",overflow:"hidden"},columnHeader:{borderBottomWidth:"1px"},header:{bg:"bg.muted"},row:{"&:not(:last-of-type)":{borderBottomWidth:"1px"}},footer:{borderTopWidth:"1px"}}},size:{sm:{root:{textStyle:"sm"},columnHeader:{px:"2",py:"2"},cell:{px:"2",py:"2"}},md:{root:{textStyle:"sm"},columnHeader:{px:"3",py:"3"},cell:{px:"3",py:"3"}},lg:{root:{textStyle:"md"},columnHeader:{px:"4",py:"3"},cell:{px:"4",py:"3"}}}},defaultVariants:{variant:"line",size:"md"}}),oP=q({slots:cI.keys(),className:"chakra-tabs",base:{root:{"--tabs-trigger-radius":"radii.l2",position:"relative",_horizontal:{display:"block"},_vertical:{display:"flex"}},list:{display:"inline-flex",position:"relative",isolation:"isolate","--tabs-indicator-shadow":"shadows.xs","--tabs-indicator-bg":"colors.bg",minH:"var(--tabs-height)",_horizontal:{flexDirection:"row"},_vertical:{flexDirection:"column"}},trigger:{outline:"0",minW:"var(--tabs-height)",height:"var(--tabs-height)",display:"flex",alignItems:"center",fontWeight:"medium",position:"relative",cursor:"button",gap:"2",_focusVisible:{zIndex:1,outline:"2px solid",outlineColor:"colorPalette.focusRing"},_disabled:{cursor:"not-allowed",opacity:.5}},content:{focusVisibleRing:"inside",_horizontal:{width:"100%",pt:"var(--tabs-content-padding)"},_vertical:{height:"100%",ps:"var(--tabs-content-padding)"}},indicator:{width:"var(--width)",height:"var(--height)",borderRadius:"var(--tabs-indicator-radius)",bg:"var(--tabs-indicator-bg)",shadow:"var(--tabs-indicator-shadow)",zIndex:-1}},variants:{fitted:{true:{list:{display:"flex"},trigger:{flex:1,textAlign:"center",justifyContent:"center"}}},justify:{start:{list:{justifyContent:"flex-start"}},center:{list:{justifyContent:"center"}},end:{list:{justifyContent:"flex-end"}}},size:{sm:{root:{"--tabs-height":"sizes.9","--tabs-content-padding":"spacing.3"},trigger:{py:"1",px:"3",textStyle:"sm"}},md:{root:{"--tabs-height":"sizes.10","--tabs-content-padding":"spacing.4"},trigger:{py:"2",px:"4",textStyle:"sm"}},lg:{root:{"--tabs-height":"sizes.11","--tabs-content-padding":"spacing.4.5"},trigger:{py:"2",px:"4.5",textStyle:"md"}}},variant:{line:{list:{display:"flex",borderColor:"border",_horizontal:{borderBottomWidth:"1px"},_vertical:{borderEndWidth:"1px"}},trigger:{color:"fg.muted",_disabled:{_active:{bg:"initial"}},_selected:{color:"fg",_horizontal:{layerStyle:"indicator.bottom","--indicator-offset-y":"-1px","--indicator-color":"colors.colorPalette.solid"},_vertical:{layerStyle:"indicator.end","--indicator-offset-x":"-1px"}}}},subtle:{trigger:{borderRadius:"var(--tabs-trigger-radius)",color:"fg.muted",_selected:{bg:"colorPalette.subtle",color:"colorPalette.fg"}}},enclosed:{list:{bg:"bg.muted",padding:"1",borderRadius:"l3",minH:"calc(var(--tabs-height) - 4px)"},trigger:{justifyContent:"center",color:"fg.muted",borderRadius:"var(--tabs-trigger-radius)",_selected:{bg:"bg",color:"colorPalette.fg",shadow:"xs"}}},outline:{list:{"--line-thickness":"1px","--line-offset":"calc(var(--line-thickness) * -1)",borderColor:"border",display:"flex",_horizontal:{_before:{content:'""',position:"absolute",bottom:"0px",width:"100%",borderBottomWidth:"var(--line-thickness)",borderBottomColor:"border"}},_vertical:{_before:{content:'""',position:"absolute",insetInline:"var(--line-offset)",height:"calc(100% - calc(var(--line-thickness) * 2))",borderEndWidth:"var(--line-thickness)",borderEndColor:"border"}}},trigger:{color:"fg.muted",borderWidth:"1px",borderColor:"transparent",_selected:{bg:"currentBg",color:"colorPalette.fg"},_horizontal:{borderTopRadius:"var(--tabs-trigger-radius)",marginBottom:"var(--line-offset)",marginEnd:{_notLast:"var(--line-offset)"},_selected:{borderColor:"border",borderBottomColor:"transparent"}},_vertical:{borderStartRadius:"var(--tabs-trigger-radius)",marginEnd:"var(--line-offset)",marginBottom:{_notLast:"var(--line-offset)"},_selected:{borderColor:"border",borderEndColor:"transparent"}}}},plain:{trigger:{color:"fg.muted",_selected:{color:"colorPalette.fg"},borderRadius:"var(--tabs-trigger-radius)","&[data-selected][data-ssr]":{bg:"var(--tabs-indicator-bg)",shadow:"var(--tabs-indicator-shadow)",borderRadius:"var(--tabs-indicator-radius)"}}}}},defaultVariants:{size:"md",variant:"line"}}),ut=(xv=Tl.variants)==null?void 0:xv.variant,sP=q({slots:uI.keys(),className:"chakra-tag",base:{root:{display:"inline-flex",alignItems:"center",verticalAlign:"top",maxWidth:"100%",userSelect:"none",borderRadius:"l2",focusVisibleRing:"outside"},label:{lineClamp:"1"},closeTrigger:{display:"flex",alignItems:"center",justifyContent:"center",outline:"0",borderRadius:"l1",color:"currentColor",focusVisibleRing:"inside",focusRingWidth:"2px"},startElement:{flexShrink:0,boxSize:"var(--tag-element-size)",ms:"var(--tag-element-offset)","&:has([data-scope=avatar])":{boxSize:"var(--tag-avatar-size)",ms:"calc(var(--tag-element-offset) * 1.5)"},_icon:{boxSize:"100%"}},endElement:{flexShrink:0,boxSize:"var(--tag-element-size)",me:"var(--tag-element-offset)",_icon:{boxSize:"100%"},"&:has(button)":{ms:"calc(var(--tag-element-offset) * -1)"}}},variants:{size:{sm:{root:{px:"1.5",minH:"4.5",gap:"1","--tag-avatar-size":"spacing.3","--tag-element-size":"spacing.3","--tag-element-offset":"-2px"},label:{textStyle:"xs"}},md:{root:{px:"1.5",minH:"5",gap:"1","--tag-avatar-size":"spacing.3.5","--tag-element-size":"spacing.3.5","--tag-element-offset":"-2px"},label:{textStyle:"xs"}},lg:{root:{px:"2",minH:"6",gap:"1.5","--tag-avatar-size":"spacing.4.5","--tag-element-size":"spacing.4","--tag-element-offset":"-3px"},label:{textStyle:"sm"}},xl:{root:{px:"2.5",minH:"8",gap:"1.5","--tag-avatar-size":"spacing.6","--tag-element-size":"spacing.4.5","--tag-element-offset":"-4px"},label:{textStyle:"sm"}}},variant:{subtle:{root:ut==null?void 0:ut.subtle},solid:{root:ut==null?void 0:ut.solid},outline:{root:ut==null?void 0:ut.outline},surface:{root:ut==null?void 0:ut.surface}}},defaultVariants:{size:"md",variant:"surface"}}),aP=q({slots:dI.keys(),className:"chakra-timeline",base:{root:{display:"flex",flexDirection:"column",width:"full","--timeline-thickness":"1px","--timeline-gutter":"4px"},item:{display:"flex",position:"relative",alignItems:"flex-start",flexShrink:0,gap:"4",_last:{"& :where(.chakra-timeline__separator)":{display:"none"}}},separator:{position:"absolute",borderStartWidth:"var(--timeline-thickness)",ms:"calc(-1 * var(--timeline-thickness) / 2)",insetInlineStart:"calc(var(--timeline-indicator-size) / 2)",insetBlock:"0",borderColor:"border"},indicator:{outline:"2px solid {colors.bg}",position:"relative",flexShrink:"0",boxSize:"var(--timeline-indicator-size)",fontSize:"var(--timeline-font-size)",display:"flex",alignItems:"center",justifyContent:"center",borderRadius:"full",fontWeight:"medium"},connector:{alignSelf:"stretch",position:"relative"},content:{pb:"6",display:"flex",flexDirection:"column",width:"full",gap:"2"},title:{display:"flex",fontWeight:"medium",flexWrap:"wrap",gap:"1.5",alignItems:"center",mt:"var(--timeline-margin)"},description:{color:"fg.muted",textStyle:"xs"}},variants:{variant:{subtle:{indicator:{bg:"colorPalette.muted"}},solid:{indicator:{bg:"colorPalette.solid",color:"colorPalette.contrast"}},outline:{indicator:{bg:"currentBg",borderWidth:"1px",borderColor:"colorPalette.muted"}},plain:{}},size:{sm:{root:{"--timeline-indicator-size":"sizes.4","--timeline-font-size":"fontSizes.2xs"},title:{textStyle:"xs"}},md:{root:{"--timeline-indicator-size":"sizes.5","--timeline-font-size":"fontSizes.xs"},title:{textStyle:"sm"}},lg:{root:{"--timeline-indicator-size":"sizes.6","--timeline-font-size":"fontSizes.xs"},title:{mt:"0.5",textStyle:"sm"}},xl:{root:{"--timeline-indicator-size":"sizes.8","--timeline-font-size":"fontSizes.sm"},title:{mt:"1.5",textStyle:"sm"}}}},defaultVariants:{size:"md",variant:"solid"}}),lP=q({slots:lI.keys(),className:"chakra-toast",base:{root:{width:"full",display:"flex",alignItems:"flex-start",position:"relative",gap:"3",py:"4",ps:"4",pe:"6",borderRadius:"l2",translate:"var(--x) var(--y)",scale:"var(--scale)",zIndex:"var(--z-index)",height:"var(--height)",opacity:"var(--opacity)",willChange:"translate, opacity, scale",transition:"translate 400ms, scale 400ms, opacity 400ms, height 400ms, box-shadow 200ms",transitionTimingFunction:"cubic-bezier(0.21, 1.02, 0.73, 1)",_closed:{transition:"translate 400ms, scale 400ms, opacity 200ms",transitionTimingFunction:"cubic-bezier(0.06, 0.71, 0.55, 1)"},bg:"bg.panel",color:"fg",boxShadow:"xl","--toast-trigger-bg":"colors.bg.muted","&[data-type=warning]":{bg:"orange.solid",color:"orange.contrast","--toast-trigger-bg":"{white/10}","--toast-border-color":"{white/40}"},"&[data-type=success]":{bg:"green.solid",color:"green.contrast","--toast-trigger-bg":"{white/10}","--toast-border-color":"{white/40}"},"&[data-type=error]":{bg:"red.solid",color:"red.contrast","--toast-trigger-bg":"{white/10}","--toast-border-color":"{white/40}"}},title:{fontWeight:"medium",textStyle:"sm",marginEnd:"2"},description:{display:"inline",textStyle:"sm",opacity:"0.8"},indicator:{flexShrink:"0",boxSize:"5"},actionTrigger:{textStyle:"sm",fontWeight:"medium",height:"8",px:"3",borderRadius:"l2",alignSelf:"center",borderWidth:"1px",borderColor:"var(--toast-border-color, inherit)",transition:"background 200ms",_hover:{bg:"var(--toast-trigger-bg)"}},closeTrigger:{position:"absolute",top:"1",insetEnd:"1",padding:"1",display:"inline-flex",alignItems:"center",justifyContent:"center",color:"{currentColor/60}",borderRadius:"l2",textStyle:"md",transition:"background 200ms",_icon:{boxSize:"1em"}}}}),cP=q({slots:tf.keys(),className:"chakra-tooltip",base:{content:{"--tooltip-bg":"colors.bg.inverted",bg:"var(--tooltip-bg)",color:"fg.inverted",px:"2.5",py:"1",borderRadius:"l2",fontWeight:"medium",textStyle:"xs",boxShadow:"md",maxW:"xs",zIndex:"tooltip",transformOrigin:"var(--transform-origin)",_open:{animationStyle:"scale-fade-in",animationDuration:"fast"},_closed:{animationStyle:"scale-fade-out",animationDuration:"fast"}},arrow:{"--arrow-size":"sizes.2","--arrow-background":"var(--tooltip-bg)"},arrowTip:{borderTopWidth:"1px",borderInlineStartWidth:"1px",borderColor:"var(--tooltip-bg)"}}}),ig=Ir({display:"flex",alignItems:"center",gap:"var(--tree-item-gap)",rounded:"l2",userSelect:"none",position:"relative","--tree-depth":"calc(var(--depth) - 1)","--tree-indentation-offset":"calc(var(--tree-indentation) * var(--tree-depth))","--tree-icon-offset":"calc(var(--tree-icon-size) * var(--tree-depth) * 0.5)","--tree-offset":"calc(var(--tree-padding-inline) + var(--tree-indentation-offset) + var(--tree-icon-offset))",ps:"var(--tree-offset)",pe:"var(--tree-padding-inline)",py:"var(--tree-padding-block)",focusVisibleRing:"inside",focusRingColor:"border.emphasized",focusRingWidth:"2px","&:hover, &:focus-visible":{bg:"bg.muted"},_disabled:{layerStyle:"disabled"}}),og=Ir({flex:"1"}),sg=Ir({_selected:{bg:"colorPalette.subtle",color:"colorPalette.fg"}}),ag=Ir({_selected:{layerStyle:"fill.solid"}}),uP=q({slots:Eh.keys(),className:"chakra-tree-view",base:{root:{width:"full",display:"flex",flexDirection:"column",gap:"2"},tree:{display:"flex",flexDirection:"column","--tree-item-gap":"spacing.2",_icon:{boxSize:"var(--tree-icon-size)"}},label:{fontWeight:"medium",textStyle:"sm"},branch:{position:"relative"},branchContent:{position:"relative"},branchIndentGuide:{height:"100%",width:"1px",bg:"border",position:"absolute","--tree-depth":"calc(var(--depth) - 1)","--tree-indentation-offset":"calc(var(--tree-indentation) * var(--tree-depth))","--tree-offset":"calc(var(--tree-padding-inline) + var(--tree-indentation-offset))","--tree-icon-offset":"calc(var(--tree-icon-size) * 0.5 * var(--depth))",insetInlineStart:"calc(var(--tree-offset) + var(--tree-icon-offset))",zIndex:"1"},branchIndicator:{color:"fg.muted",transformOrigin:"center",transitionDuration:"normal",transitionProperty:"transform",transitionTimingFunction:"default",_open:{transform:"rotate(90deg)"}},branchTrigger:{display:"inline-flex",alignItems:"center",justifyContent:"center"},branchControl:ig,item:ig,itemText:og,branchText:og,nodeCheckbox:{display:"inline-flex"}},variants:{size:{md:{tree:{textStyle:"sm","--tree-indentation":"spacing.4","--tree-padding-inline":"spacing.3","--tree-padding-block":"spacing.1.5","--tree-icon-size":"spacing.4"}},sm:{tree:{textStyle:"sm","--tree-indentation":"spacing.4","--tree-padding-inline":"spacing.3","--tree-padding-block":"spacing.1","--tree-icon-size":"spacing.3"}},xs:{tree:{textStyle:"xs","--tree-indentation":"spacing.4","--tree-padding-inline":"spacing.2","--tree-padding-block":"spacing.1","--tree-icon-size":"spacing.3"}}},variant:{subtle:{branchControl:sg,item:sg},solid:{branchControl:ag,item:ag}},animateContent:{true:{branchContent:{_open:{animationName:"expand-height, fade-in",animationDuration:"moderate"},_closed:{animationName:"collapse-height, fade-out",animationDuration:"moderate"}}}}},defaultVariants:{size:"md",variant:"subtle"}}),dP={accordion:pI,actionBar:mI,alert:vI,avatar:bI,blockquote:yI,breadcrumb:xI,card:CI,checkbox:SI,checkboxCard:wI,codeBlock:EI,collapsible:kI,dataList:PI,dialog:RI,drawer:TI,editable:NI,emptyState:AI,field:_I,fieldset:VI,fileUpload:FI,hoverCard:LI,list:DI,listbox:zI,menu:MI,nativeSelect:$I,numberInput:BI,pinInput:WI,popover:HI,progress:UI,progressCircle:GI,radioCard:KI,radioGroup:XI,ratingGroup:YI,scrollArea:QI,segmentGroup:JI,select:us,combobox:II,slider:ZI,stat:eP,steps:nP,switch:rP,table:iP,tabs:oP,tag:sP,toast:lP,tooltip:cP,status:tP,timeline:aP,colorPicker:OI,qrCode:qI,treeView:uP},hP=qE({"2xs":{value:{fontSize:"2xs",lineHeight:"0.75rem"}},xs:{value:{fontSize:"xs",lineHeight:"1rem"}},sm:{value:{fontSize:"sm",lineHeight:"1.25rem"}},md:{value:{fontSize:"md",lineHeight:"1.5rem"}},lg:{value:{fontSize:"lg",lineHeight:"1.75rem"}},xl:{value:{fontSize:"xl",lineHeight:"1.875rem"}},"2xl":{value:{fontSize:"2xl",lineHeight:"2rem"}},"3xl":{value:{fontSize:"3xl",lineHeight:"2.375rem"}},"4xl":{value:{fontSize:"4xl",lineHeight:"2.75rem",letterSpacing:"-0.025em"}},"5xl":{value:{fontSize:"5xl",lineHeight:"3.75rem",letterSpacing:"-0.025em"}},"6xl":{value:{fontSize:"6xl",lineHeight:"4.5rem",letterSpacing:"-0.025em"}},"7xl":{value:{fontSize:"7xl",lineHeight:"5.75rem",letterSpacing:"-0.025em"}},none:{value:{}},label:{value:{fontSize:"sm",lineHeight:"1.25rem",fontWeight:"medium"}}}),fP=xe.animations({spin:{value:"spin 1s linear infinite"},ping:{value:"ping 1s cubic-bezier(0, 0, 0.2, 1) infinite"},pulse:{value:"pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"},bounce:{value:"bounce 1s infinite"}}),gP=xe.aspectRatios({square:{value:"1 / 1"},landscape:{value:"4 / 3"},portrait:{value:"3 / 4"},wide:{value:"16 / 9"},ultrawide:{value:"18 / 5"},golden:{value:"1.618 / 1"}}),pP=xe.blurs({none:{value:" "},sm:{value:"4px"},md:{value:"8px"},lg:{value:"12px"},xl:{value:"16px"},"2xl":{value:"24px"},"3xl":{value:"40px"},"4xl":{value:"64px"}}),mP=xe.borders({xs:{value:"0.5px solid"},sm:{value:"1px solid"},md:{value:"2px solid"},lg:{value:"4px solid"},xl:{value:"8px solid"}}),vP=xe.colors({transparent:{value:"transparent"},current:{value:"currentColor"},black:{value:"#09090B"},white:{value:"#FFFFFF"},whiteAlpha:{50:{value:"rgba(255, 255, 255, 0.04)"},100:{value:"rgba(255, 255, 255, 0.06)"},200:{value:"rgba(255, 255, 255, 0.08)"},300:{value:"rgba(255, 255, 255, 0.16)"},400:{value:"rgba(255, 255, 255, 0.24)"},500:{value:"rgba(255, 255, 255, 0.36)"},600:{value:"rgba(255, 255, 255, 0.48)"},700:{value:"rgba(255, 255, 255, 0.64)"},800:{value:"rgba(255, 255, 255, 0.80)"},900:{value:"rgba(255, 255, 255, 0.92)"},950:{value:"rgba(255, 255, 255, 0.95)"}},blackAlpha:{50:{value:"rgba(0, 0, 0, 0.04)"},100:{value:"rgba(0, 0, 0, 0.06)"},200:{value:"rgba(0, 0, 0, 0.08)"},300:{value:"rgba(0, 0, 0, 0.16)"},400:{value:"rgba(0, 0, 0, 0.24)"},500:{value:"rgba(0, 0, 0, 0.36)"},600:{value:"rgba(0, 0, 0, 0.48)"},700:{value:"rgba(0, 0, 0, 0.64)"},800:{value:"rgba(0, 0, 0, 0.80)"},900:{value:"rgba(0, 0, 0, 0.92)"},950:{value:"rgba(0, 0, 0, 0.95)"}},gray:{50:{value:"#fafafa"},100:{value:"#f4f4f5"},200:{value:"#e4e4e7"},300:{value:"#d4d4d8"},400:{value:"#a1a1aa"},500:{value:"#71717a"},600:{value:"#52525b"},700:{value:"#3f3f46"},800:{value:"#27272a"},900:{value:"#18181b"},950:{value:"#111111"}},red:{50:{value:"#fef2f2"},100:{value:"#fee2e2"},200:{value:"#fecaca"},300:{value:"#fca5a5"},400:{value:"#f87171"},500:{value:"#ef4444"},600:{value:"#dc2626"},700:{value:"#991919"},800:{value:"#511111"},900:{value:"#300c0c"},950:{value:"#1f0808"}},orange:{50:{value:"#fff7ed"},100:{value:"#ffedd5"},200:{value:"#fed7aa"},300:{value:"#fdba74"},400:{value:"#fb923c"},500:{value:"#f97316"},600:{value:"#ea580c"},700:{value:"#92310a"},800:{value:"#6c2710"},900:{value:"#3b1106"},950:{value:"#220a04"}},yellow:{50:{value:"#fefce8"},100:{value:"#fef9c3"},200:{value:"#fef08a"},300:{value:"#fde047"},400:{value:"#facc15"},500:{value:"#eab308"},600:{value:"#ca8a04"},700:{value:"#845209"},800:{value:"#713f12"},900:{value:"#422006"},950:{value:"#281304"}},green:{50:{value:"#f0fdf4"},100:{value:"#dcfce7"},200:{value:"#bbf7d0"},300:{value:"#86efac"},400:{value:"#4ade80"},500:{value:"#22c55e"},600:{value:"#16a34a"},700:{value:"#116932"},800:{value:"#124a28"},900:{value:"#042713"},950:{value:"#03190c"}},teal:{50:{value:"#f0fdfa"},100:{value:"#ccfbf1"},200:{value:"#99f6e4"},300:{value:"#5eead4"},400:{value:"#2dd4bf"},500:{value:"#14b8a6"},600:{value:"#0d9488"},700:{value:"#0c5d56"},800:{value:"#114240"},900:{value:"#032726"},950:{value:"#021716"}},blue:{50:{value:"#eff6ff"},100:{value:"#dbeafe"},200:{value:"#bfdbfe"},300:{value:"#a3cfff"},400:{value:"#60a5fa"},500:{value:"#3b82f6"},600:{value:"#2563eb"},700:{value:"#173da6"},800:{value:"#1a3478"},900:{value:"#14204a"},950:{value:"#0c142e"}},cyan:{50:{value:"#ecfeff"},100:{value:"#cffafe"},200:{value:"#a5f3fc"},300:{value:"#67e8f9"},400:{value:"#22d3ee"},500:{value:"#06b6d4"},600:{value:"#0891b2"},700:{value:"#0c5c72"},800:{value:"#134152"},900:{value:"#072a38"},950:{value:"#051b24"}},purple:{50:{value:"#faf5ff"},100:{value:"#f3e8ff"},200:{value:"#e9d5ff"},300:{value:"#d8b4fe"},400:{value:"#c084fc"},500:{value:"#a855f7"},600:{value:"#9333ea"},700:{value:"#641ba3"},800:{value:"#4a1772"},900:{value:"#2f0553"},950:{value:"#1a032e"}},pink:{50:{value:"#fdf2f8"},100:{value:"#fce7f3"},200:{value:"#fbcfe8"},300:{value:"#f9a8d4"},400:{value:"#f472b6"},500:{value:"#ec4899"},600:{value:"#db2777"},700:{value:"#a41752"},800:{value:"#6d0e34"},900:{value:"#45061f"},950:{value:"#2c0514"}}}),bP=xe.cursor({button:{value:"pointer"},checkbox:{value:"default"},disabled:{value:"not-allowed"},menuitem:{value:"default"},option:{value:"default"},radio:{value:"default"},slider:{value:"default"},switch:{value:"pointer"}}),yP=xe.durations({fastest:{value:"50ms"},faster:{value:"100ms"},fast:{value:"150ms"},moderate:{value:"200ms"},slow:{value:"300ms"},slower:{value:"400ms"},slowest:{value:"500ms"}}),xP=xe.easings({"ease-in":{value:"cubic-bezier(0.42, 0, 1, 1)"},"ease-out":{value:"cubic-bezier(0, 0, 0.58, 1)"},"ease-in-out":{value:"cubic-bezier(0.42, 0, 0.58, 1)"},"ease-in-smooth":{value:"cubic-bezier(0.32, 0.72, 0, 1)"}}),CP=xe.fontSizes({"2xs":{value:"0.625rem"},xs:{value:"0.75rem"},sm:{value:"0.875rem"},md:{value:"1rem"},lg:{value:"1.125rem"},xl:{value:"1.25rem"},"2xl":{value:"1.5rem"},"3xl":{value:"1.875rem"},"4xl":{value:"2.25rem"},"5xl":{value:"3rem"},"6xl":{value:"3.75rem"},"7xl":{value:"4.5rem"},"8xl":{value:"6rem"},"9xl":{value:"8rem"}}),SP=xe.fontWeights({thin:{value:"100"},extralight:{value:"200"},light:{value:"300"},normal:{value:"400"},medium:{value:"500"},semibold:{value:"600"},bold:{value:"700"},extrabold:{value:"800"},black:{value:"900"}}),lg='-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',wP=xe.fonts({heading:{value:`Inter, ${lg}`},body:{value:`Inter, ${lg}`},mono:{value:'SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace'}}),EP=UE({spin:{"0%":{transform:"rotate(0deg)"},"100%":{transform:"rotate(360deg)"}},pulse:{"50%":{opacity:"0.5"}},ping:{"75%, 100%":{transform:"scale(2)",opacity:"0"}},bounce:{"0%, 100%":{transform:"translateY(-25%)",animationTimingFunction:"cubic-bezier(0.8,0,1,1)"},"50%":{transform:"none",animationTimingFunction:"cubic-bezier(0,0,0.2,1)"}},"bg-position":{from:{backgroundPosition:"var(--animate-from, 1rem) 0"},to:{backgroundPosition:"var(--animate-to, 0) 0"}},position:{from:{insetInlineStart:"var(--animate-from-x)",insetBlockStart:"var(--animate-from-y)"},to:{insetInlineStart:"var(--animate-to-x)",insetBlockStart:"var(--animate-to-y)"}},"circular-progress":{"0%":{strokeDasharray:"1, 400",strokeDashoffset:"0"},"50%":{strokeDasharray:"400, 400",strokeDashoffset:"-100%"},"100%":{strokeDasharray:"400, 400",strokeDashoffset:"-260%"}},"expand-height":{from:{height:"0"},to:{height:"var(--height)"}},"collapse-height":{from:{height:"var(--height)"},to:{height:"0"}},"expand-width":{from:{width:"0"},to:{width:"var(--width)"}},"collapse-width":{from:{height:"var(--width)"},to:{height:"0"}},"fade-in":{from:{opacity:0},to:{opacity:1}},"fade-out":{from:{opacity:1},to:{opacity:0}},"slide-from-left-full":{from:{translate:"-100% 0"},to:{translate:"0 0"}},"slide-from-right-full":{from:{translate:"100% 0"},to:{translate:"0 0"}},"slide-from-top-full":{from:{translate:"0 -100%"},to:{translate:"0 0"}},"slide-from-bottom-full":{from:{translate:"0 100%"},to:{translate:"0 0"}},"slide-to-left-full":{from:{translate:"0 0"},to:{translate:"-100% 0"}},"slide-to-right-full":{from:{translate:"0 0"},to:{translate:"100% 0"}},"slide-to-top-full":{from:{translate:"0 0"},to:{translate:"0 -100%"}},"slide-to-bottom-full":{from:{translate:"0 0"},to:{translate:"0 100%"}},"slide-from-top":{"0%":{translate:"0 -0.5rem"},to:{translate:"0"}},"slide-from-bottom":{"0%":{translate:"0 0.5rem"},to:{translate:"0"}},"slide-from-left":{"0%":{translate:"-0.5rem 0"},to:{translate:"0"}},"slide-from-right":{"0%":{translate:"0.5rem 0"},to:{translate:"0"}},"slide-to-top":{"0%":{translate:"0"},to:{translate:"0 -0.5rem"}},"slide-to-bottom":{"0%":{translate:"0"},to:{translate:"0 0.5rem"}},"slide-to-left":{"0%":{translate:"0"},to:{translate:"-0.5rem 0"}},"slide-to-right":{"0%":{translate:"0"},to:{translate:"0.5rem 0"}},"scale-in":{from:{scale:"0.95"},to:{scale:"1"}},"scale-out":{from:{scale:"1"},to:{scale:"0.95"}}}),kP=xe.letterSpacings({tighter:{value:"-0.05em"},tight:{value:"-0.025em"},wide:{value:"0.025em"},wider:{value:"0.05em"},widest:{value:"0.1em"}}),OP=xe.lineHeights({shorter:{value:1.25},short:{value:1.375},moderate:{value:1.5},tall:{value:1.625},taller:{value:2}}),IP=xe.radii({none:{value:"0"},"2xs":{value:"0.0625rem"},xs:{value:"0.125rem"},sm:{value:"0.25rem"},md:{value:"0.375rem"},lg:{value:"0.5rem"},xl:{value:"0.75rem"},"2xl":{value:"1rem"},"3xl":{value:"1.5rem"},"4xl":{value:"2rem"},full:{value:"9999px"}}),cg=xe.spacing({.5:{value:"0.125rem"},1:{value:"0.25rem"},1.5:{value:"0.375rem"},2:{value:"0.5rem"},2.5:{value:"0.625rem"},3:{value:"0.75rem"},3.5:{value:"0.875rem"},4:{value:"1rem"},4.5:{value:"1.125rem"},5:{value:"1.25rem"},6:{value:"1.5rem"},7:{value:"1.75rem"},8:{value:"2rem"},9:{value:"2.25rem"},10:{value:"2.5rem"},11:{value:"2.75rem"},12:{value:"3rem"},14:{value:"3.5rem"},16:{value:"4rem"},20:{value:"5rem"},24:{value:"6rem"},28:{value:"7rem"},32:{value:"8rem"},36:{value:"9rem"},40:{value:"10rem"},44:{value:"11rem"},48:{value:"12rem"},52:{value:"13rem"},56:{value:"14rem"},60:{value:"15rem"},64:{value:"16rem"},72:{value:"18rem"},80:{value:"20rem"},96:{value:"24rem"}}),PP=xe.sizes({"3xs":{value:"14rem"},"2xs":{value:"16rem"},xs:{value:"20rem"},sm:{value:"24rem"},md:{value:"28rem"},lg:{value:"32rem"},xl:{value:"36rem"},"2xl":{value:"42rem"},"3xl":{value:"48rem"},"4xl":{value:"56rem"},"5xl":{value:"64rem"},"6xl":{value:"72rem"},"7xl":{value:"80rem"},"8xl":{value:"90rem"}}),RP=xe.sizes({max:{value:"max-content"},min:{value:"min-content"},fit:{value:"fit-content"},prose:{value:"60ch"},full:{value:"100%"},dvh:{value:"100dvh"},svh:{value:"100svh"},lvh:{value:"100lvh"},dvw:{value:"100dvw"},svw:{value:"100svw"},lvw:{value:"100lvw"},vw:{value:"100vw"},vh:{value:"100vh"}}),TP=xe.sizes({"1/2":{value:"50%"},"1/3":{value:"33.333333%"},"2/3":{value:"66.666667%"},"1/4":{value:"25%"},"3/4":{value:"75%"},"1/5":{value:"20%"},"2/5":{value:"40%"},"3/5":{value:"60%"},"4/5":{value:"80%"},"1/6":{value:"16.666667%"},"2/6":{value:"33.333333%"},"3/6":{value:"50%"},"4/6":{value:"66.666667%"},"5/6":{value:"83.333333%"},"1/12":{value:"8.333333%"},"2/12":{value:"16.666667%"},"3/12":{value:"25%"},"4/12":{value:"33.333333%"},"5/12":{value:"41.666667%"},"6/12":{value:"50%"},"7/12":{value:"58.333333%"},"8/12":{value:"66.666667%"},"9/12":{value:"75%"},"10/12":{value:"83.333333%"},"11/12":{value:"91.666667%"}}),NP=xe.sizes({...PP,...cg,...TP,...RP}),AP=xe.zIndex({hide:{value:-1},base:{value:0},docked:{value:10},dropdown:{value:1e3},sticky:{value:1100},banner:{value:1200},overlay:{value:1300},modal:{value:1400},popover:{value:1500},skipNav:{value:1600},toast:{value:1700},tooltip:{value:1800},max:{value:2147483647}}),_P=Cl({preflight:!0,cssVarsPrefix:"chakra",cssVarsRoot:":where(html, .chakra-theme)",globalCss:uO,theme:{breakpoints:cO,keyframes:EP,tokens:{aspectRatios:gP,animations:fP,blurs:pP,borders:mP,colors:vP,durations:yP,easings:xP,fonts:wP,fontSizes:CP,fontWeights:SP,letterSpacings:kP,lineHeights:OP,radii:IP,spacing:cg,sizes:NP,zIndex:AP,cursor:bP},semanticTokens:{colors:TO,shadows:AO,radii:NO},recipes:RO,slotRecipes:dP,textStyles:hP,layerStyles:dO,animationStyles:hO}}),dt=af(rk,_P);Xf(dt);function VP(e){const{key:t,recipe:n}=e,r=co();return E.useMemo(()=>{const i=n||(t!=null?r.getSlotRecipe(t):{});return r.sva(structuredClone(i))},[t,n,r])}const FP=e=>e.charAt(0).toUpperCase()+e.slice(1),Al=e=>{const{key:t,recipe:n}=e,r=FP(t||n.className||"Component"),[i,o]=lr({name:`${r}StylesContext`,errorMessage:`use${r}Styles returned is 'undefined'. Seems you forgot to wrap the components in "<${r}.Root />" `}),[s,a]=lr({name:`${r}ClassNameContext`,errorMessage:`use${r}ClassNames returned is 'undefined'. Seems you forgot to wrap the components in "<${r}.Root />" `,strict:!1}),[l,c]=lr({strict:!1,name:`${r}PropsContext`,providerName:`${r}PropsContext`,defaultValue:{}});function u(f){const{unstyled:g,...p}=f,v=VP({key:t,recipe:p.recipe||n}),[x,S]=E.useMemo(()=>v.splitVariantProps(p),[p,v]);return{styles:E.useMemo(()=>g?By:v(x),[g,x,v]),classNames:v.classNameMap,props:S}}function d(f,g={}){const{defaultProps:p}=g,v=x=>{const S=c(),C=E.useMemo(()=>ni(p,S,x),[S,x]),{styles:w,classNames:P,props:_}=u(C);return y.jsx(i,{value:w,children:y.jsx(s,{value:P,children:y.jsx(f,{..._})})})};return v.displayName=f.displayName||f.name,v}return{StylesProvider:i,ClassNamesProvider:s,PropsProvider:l,usePropsContext:c,useRecipeResult:u,withProvider:(f,g,p)=>{const{defaultProps:v,...x}=p??{},S=Oe(f,{},x),C=E.forwardRef((w,P)=>{var Y;const _=c(),R=E.useMemo(()=>ni(v??{},_,w),[_,w]),{styles:N,props:T,classNames:j}=u(R),I=j[g],F=y.jsx(i,{value:N,children:y.jsx(s,{value:j,children:y.jsx(S,{ref:P,...T,css:[N[g],R.css],className:st(R.className,I)})})});return((Y=p==null?void 0:p.wrapElement)==null?void 0:Y.call(p,F,R))??F});return C.displayName=f.displayName||f.name,C},withContext:(f,g,p)=>{const v=Oe(f,{},p),x=E.forwardRef((S,C)=>{const{unstyled:w,...P}=S,_=o(),R=a(),N=R==null?void 0:R[g];return y.jsx(v,{...P,css:[!w&&g?_[g]:void 0,S.css],ref:C,className:st(S.className,N)})});return x.displayName=f.displayName||f.name,x},withRootProvider:d,useStyles:o,useClassNames:a}},ug=Oe("div",{base:{position:"absolute",display:"flex",alignItems:"center",justifyContent:"center"},variants:{axis:{horizontal:{insetStart:"50%",translate:"-50%",_rtl:{translate:"50%"}},vertical:{top:"50%",translate:"0 -50%"},both:{insetStart:"50%",top:"50%",translate:"-50% -50%",_rtl:{translate:"50% -50%"}}}},defaultVariants:{axis:"both"}});ug.displayName="AbsoluteCenter";const LP=e=>y.jsx(Oe.svg,{stroke:"currentColor",fill:"currentColor",strokeWidth:"0",viewBox:"0 0 24 24",...e,children:y.jsx("path",{d:"M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11.0026 16L6.75999 11.7574L8.17421 10.3431L11.0026 13.1716L16.6595 7.51472L18.0737 8.92893L11.0026 16Z"})}),dg=e=>y.jsx(Oe.svg,{stroke:"currentColor",fill:"currentColor",strokeWidth:"0",viewBox:"0 0 24 24",...e,children:y.jsx("path",{d:"M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z"})}),hg=e=>y.jsx(Oe.svg,{viewBox:"0 0 24 24",fill:"currentColor",stroke:"currentColor",strokeWidth:"0",...e,children:y.jsx("path",{d:"M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 7H13V9H11V7ZM11 11H13V17H11V11Z"})}),DP=e=>y.jsx(Oe.svg,{viewBox:"0 0 24 24",fill:"currentColor",...e,children:y.jsx("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.29289 17.2929C4.90237 17.6834 4.90237 18.3166 5.29289 18.7071C5.68342 19.0976 6.31658 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711Z"})}),[zP,MP]=lr({name:"AlertStatusContext",hookName:"useAlertStatusContext",providerName:""}),{withProvider:$P,withContext:_l,useStyles:BP}=Al({key:"alert"}),jP=$P("div","root",{forwardAsChild:!0,wrapElement(e,t){return y.jsx(zP,{value:{status:t.status||"info"},children:e})}}),fg=_l("div","title"),WP=_l("div","description"),HP=_l("div","content"),UP={info:hg,warning:dg,success:LP,error:dg,neutral:hg},GP=E.forwardRef(function(t,n){const r=MP(),i=BP(),o=typeof r.status=="string"?UP[r.status]:E.Fragment,{children:s=y.jsx(o,{}),...a}=t;return y.jsx(Oe.span,{ref:n,...a,css:[i.indicator,t.css],children:s})}),qP=e=>e?"":void 0,{withContext:KP}=ii({key:"badge"}),gg=KP("span"),{withContext:XP}=ii({key:"spinner"}),YP=XP("span"),QP=O.forwardRef(function(t,n){const{spinner:r=y.jsx(YP,{size:"inherit",borderWidth:"0.125em",color:"inherit"}),spinnerPlacement:i="start",children:o,text:s,visible:a=!0,...l}=t;return a?s?y.jsxs(Ao,{ref:n,display:"contents",...l,children:[i==="start"&&r,s,i==="end"&&r]}):r?y.jsxs(Ao,{ref:n,display:"contents",...l,children:[y.jsx(ug,{display:"inline-flex",children:r}),y.jsx(Ao,{visibility:"hidden",display:"contents",children:o})]}):y.jsx(Ao,{ref:n,display:"contents",...l,children:o}):o}),{useRecipeResult:JP,usePropsContext:ZP}=ii({key:"button"}),Vl=E.forwardRef(function(t,n){const r=ZP(),i=E.useMemo(()=>ni(r,t),[r,t]),o=JP(i),{loading:s,loadingText:a,children:l,spinner:c,spinnerPlacement:u,...d}=o.props;return y.jsx(Oe.button,{type:"button",ref:n,...d,"data-loading":qP(s),disabled:s||d.disabled,className:st(o.className,i.className),css:[o.styles,i.css],children:!i.asChild&&s?y.jsx(QP,{spinner:c,text:a,spinnerPlacement:u,children:l}):l})}),ds=E.forwardRef(function(t,n){return y.jsx(Vl,{px:"0",py:"0",_icon:{fontSize:"1.2em"},ref:n,...t})}),eR=O.forwardRef(function(t,n){return y.jsx(ds,{variant:"ghost","aria-label":"Close",ref:n,...t,children:t.children??y.jsx(DP,{})})}),pg=Oe("div",{base:{display:"flex",alignItems:"center",justifyContent:"center"},variants:{inline:{true:{display:"inline-flex"}}}});pg.displayName="Center";function tR(e){const{gap:t,direction:n}=e,r={column:{marginY:t,marginX:0,borderInlineStartWidth:0,borderTopWidth:"1px"},"column-reverse":{marginY:t,marginX:0,borderInlineStartWidth:0,borderTopWidth:"1px"},row:{marginX:t,marginY:0,borderInlineStartWidth:"1px",borderTopWidth:0},"row-reverse":{marginX:t,marginY:0,borderInlineStartWidth:"1px",borderTopWidth:0}};return{"&":sf(n,i=>r[i])}}function nR(e){return E.Children.toArray(e).filter(t=>E.isValidElement(t))}const mg=E.forwardRef(function(t,n){const{direction:r="column",align:i,justify:o,gap:s="0.5rem",wrap:a,children:l,separator:c,className:u,...d}=t,h=E.useMemo(()=>tR({gap:s,direction:r}),[s,r]),m=E.useMemo(()=>E.isValidElement(c)?nR(l).map((f,g,p)=>{const v=typeof f.key<"u"?f.key:g,x=c,S=E.cloneElement(x,{css:[h,x.props.css]});return y.jsxs(E.Fragment,{children:[f,g===p.length-1?null:S]},v)}):l,[l,c,h]);return y.jsx(Oe.div,{ref:n,display:"flex",alignItems:i,justifyContent:o,flexDirection:r,flexWrap:a,gap:c?void 0:s,className:st("chakra-stack",u),...d,children:m})}),{withRootProvider:vg,withContext:_t}=Al({key:"dialog"});vg(Pw,{defaultProps:{unmountOnExit:!0,lazyMount:!0}});const rR=vg(Iw,{defaultProps:{unmountOnExit:!0,lazyMount:!0}});_t(ph,"trigger",{forwardAsChild:!0});const iR=_t(ah,"positioner",{forwardAsChild:!0}),oR=_t(oh,"content",{forwardAsChild:!0});_t(sh,"description",{forwardAsChild:!0});const sR=_t(gh,"title",{forwardAsChild:!0}),aR=_t(ih,"closeTrigger",{forwardAsChild:!0}),lR=E.forwardRef(function(t,n){const r=on();return y.jsx(Oe.button,{...t,ref:n,onClick:()=>r.setOpen(!1)})}),cR=_t(rh,"backdrop",{forwardAsChild:!0}),uR=_t("div","body"),dR=_t("div","footer"),hR=_t("div","header"),Fl=E.forwardRef(function(t,n){const{direction:r,align:i,justify:o,wrap:s,basis:a,grow:l,shrink:c,inline:u,...d}=t;return y.jsx(Oe.div,{ref:n,...d,css:{display:u?"inline-flex":"flex",flexDirection:r,alignItems:i,justifyContent:o,flexWrap:s,flexBasis:a,flexGrow:l,flexShrink:c,...t.css}})}),fR=E.forwardRef(function(t,n){return y.jsx(mg,{align:"center",...t,direction:"row",ref:n})}),gR=E.forwardRef(function(t,n){return y.jsx(mg,{align:"center",...t,direction:"column",ref:n})}),{StylesProvider:pR,ClassNamesProvider:mR,useRecipeResult:vR,withContext:Wt}=Al({key:"table"}),bg=E.forwardRef(function({native:t,...n},r){const{styles:i,props:o,classNames:s}=vR(n),a=E.useMemo(()=>t?{...i.root,"& thead":i.header,"& tbody":i.body,"& tfoot":i.footer,"& thead th":i.columnHeader,"& tr":i.row,"& td":i.cell,"& caption":i.caption}:i.root,[i,t]);return y.jsx(mR,{value:s,children:y.jsx(pR,{value:i,children:y.jsx(Oe.table,{ref:r,...o,css:[a,n.css],className:st(s==null?void 0:s.root,n.className)})})})}),hs=Wt("tr","row");Oe("div",{base:{display:"block",whiteSpace:"nowrap",WebkitOverflowScrolling:"touch",overflow:"auto",maxWidth:"100%"}});const yg=Wt("thead","header");Wt("tfoot","footer");const Te=Wt("th","columnHeader"),Ne=Wt("td","cell");Wt("caption","caption",{defaultProps:{captionSide:"bottom"}});const xg=Wt("tbody","body");Wt("colgroup"),Wt("col");const{withContext:bR}=ii({key:"textarea"}),yR=bR(bh);var Ar=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(e){return this.listeners.add(e),this.onSubscribe(),()=>{this.listeners.delete(e),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}},xR={setTimeout:(e,t)=>setTimeout(e,t),clearTimeout:e=>clearTimeout(e),setInterval:(e,t)=>setInterval(e,t),clearInterval:e=>clearInterval(e)},CR=(Cv=class{constructor(){W(this,fn,xR);W(this,hc,!1)}setTimeoutProvider(e){M(this,fn,e)}setTimeout(e,t){return b(this,fn).setTimeout(e,t)}clearTimeout(e){b(this,fn).clearTimeout(e)}setInterval(e,t){return b(this,fn).setInterval(e,t)}clearInterval(e){b(this,fn).clearInterval(e)}},fn=new WeakMap,hc=new WeakMap,Cv),Wn=new CR;function SR(e){setTimeout(e,0)}var Hn=typeof window>"u"||"Deno"in globalThis;function $e(){}function wR(e,t){return typeof e=="function"?e(t):e}function Ll(e){return typeof e=="number"&&e>=0&&e!==1/0}function Cg(e,t){return Math.max(e+(t||0)-Date.now(),0)}function ln(e,t){return typeof e=="function"?e(t):e}function ht(e,t){return typeof e=="function"?e(t):e}function Sg(e,t){const{type:n="all",exact:r,fetchStatus:i,predicate:o,queryKey:s,stale:a}=e;if(s){if(r){if(t.queryHash!==Dl(s,t.options))return!1}else if(!Ii(t.queryKey,s))return!1}if(n!=="all"){const l=t.isActive();if(n==="active"&&!l||n==="inactive"&&l)return!1}return!(typeof a=="boolean"&&t.isStale()!==a||i&&i!==t.state.fetchStatus||o&&!o(t))}function wg(e,t){const{exact:n,status:r,predicate:i,mutationKey:o}=e;if(o){if(!t.options.mutationKey)return!1;if(n){if(Un(t.options.mutationKey)!==Un(o))return!1}else if(!Ii(t.options.mutationKey,o))return!1}return!(r&&t.state.status!==r||i&&!i(t))}function Dl(e,t){return((t==null?void 0:t.queryKeyHashFn)||Un)(e)}function Un(e){return JSON.stringify(e,(t,n)=>zl(n)?Object.keys(n).sort().reduce((r,i)=>(r[i]=n[i],r),{}):n)}function Ii(e,t){return e===t?!0:typeof e!=typeof t?!1:e&&t&&typeof e=="object"&&typeof t=="object"?Object.keys(t).every(n=>Ii(e[n],t[n])):!1}var ER=Object.prototype.hasOwnProperty;function Eg(e,t){if(e===t)return e;const n=kg(e)&&kg(t);if(!n&&!(zl(e)&&zl(t)))return t;const i=(n?e:Object.keys(e)).length,o=n?t:Object.keys(t),s=o.length,a=n?new Array(s):{};let l=0;for(let c=0;c{Wn.setTimeout(t,e)})}function Ml(e,t,n){return typeof n.structuralSharing=="function"?n.structuralSharing(e,t):n.structuralSharing!==!1?Eg(e,t):t}function OR(e,t,n=0){const r=[...e,t];return n&&r.length>n?r.slice(1):r}function IR(e,t,n=0){const r=[t,...e];return n&&r.length>n?r.slice(0,-1):r}var $l=Symbol();function Ig(e,t){return!e.queryFn&&(t!=null&&t.initialPromise)?()=>t.initialPromise:!e.queryFn||e.queryFn===$l?()=>Promise.reject(new Error(`Missing queryFn: '${e.queryHash}'`)):e.queryFn}function Pg(e,t){return typeof e=="function"?e(...t):!!e}var PR=(Sv=class extends Ar{constructor(){super();W(this,Yn);W(this,gn);W(this,Dr);M(this,Dr,t=>{if(!Hn&&window.addEventListener){const n=()=>t();return window.addEventListener("visibilitychange",n,!1),()=>{window.removeEventListener("visibilitychange",n)}}})}onSubscribe(){b(this,gn)||this.setEventListener(b(this,Dr))}onUnsubscribe(){var t;this.hasListeners()||((t=b(this,gn))==null||t.call(this),M(this,gn,void 0))}setEventListener(t){var n;M(this,Dr,t),(n=b(this,gn))==null||n.call(this),M(this,gn,t(r=>{typeof r=="boolean"?this.setFocused(r):this.onFocus()}))}setFocused(t){b(this,Yn)!==t&&(M(this,Yn,t),this.onFocus())}onFocus(){const t=this.isFocused();this.listeners.forEach(n=>{n(t)})}isFocused(){var t;return typeof b(this,Yn)=="boolean"?b(this,Yn):((t=globalThis.document)==null?void 0:t.visibilityState)!=="hidden"}},Yn=new WeakMap,gn=new WeakMap,Dr=new WeakMap,Sv),Bl=new PR;function jl(){let e,t;const n=new Promise((i,o)=>{e=i,t=o});n.status="pending",n.catch(()=>{});function r(i){Object.assign(n,i),delete n.resolve,delete n.reject}return n.resolve=i=>{r({status:"fulfilled",value:i}),e(i)},n.reject=i=>{r({status:"rejected",reason:i}),t(i)},n}var RR=SR;function TR(){let e=[],t=0,n=a=>{a()},r=a=>{a()},i=RR;const o=a=>{t?e.push(a):i(()=>{n(a)})},s=()=>{const a=e;e=[],a.length&&i(()=>{r(()=>{a.forEach(l=>{n(l)})})})};return{batch:a=>{let l;t++;try{l=a()}finally{t--,t||s()}return l},batchCalls:a=>(...l)=>{o(()=>{a(...l)})},schedule:o,setNotifyFunction:a=>{n=a},setBatchNotifyFunction:a=>{r=a},setScheduler:a=>{i=a}}}var we=TR(),NR=(wv=class extends Ar{constructor(){super();W(this,zr,!0);W(this,pn);W(this,Mr);M(this,Mr,t=>{if(!Hn&&window.addEventListener){const n=()=>t(!0),r=()=>t(!1);return window.addEventListener("online",n,!1),window.addEventListener("offline",r,!1),()=>{window.removeEventListener("online",n),window.removeEventListener("offline",r)}}})}onSubscribe(){b(this,pn)||this.setEventListener(b(this,Mr))}onUnsubscribe(){var t;this.hasListeners()||((t=b(this,pn))==null||t.call(this),M(this,pn,void 0))}setEventListener(t){var n;M(this,Mr,t),(n=b(this,pn))==null||n.call(this),M(this,pn,t(this.setOnline.bind(this)))}setOnline(t){b(this,zr)!==t&&(M(this,zr,t),this.listeners.forEach(r=>{r(t)}))}isOnline(){return b(this,zr)}},zr=new WeakMap,pn=new WeakMap,Mr=new WeakMap,wv),gs=new NR;function AR(e){return Math.min(1e3*2**e,3e4)}function Rg(e){return(e??"online")==="online"?gs.isOnline():!0}var Wl=class extends Error{constructor(e){super("CancelledError"),this.revert=e==null?void 0:e.revert,this.silent=e==null?void 0:e.silent}};function Tg(e){let t=!1,n=0,r;const i=jl(),o=()=>i.status!=="pending",s=g=>{var p;if(!o()){const v=new Wl(g);h(v),(p=e.onCancel)==null||p.call(e,v)}},a=()=>{t=!0},l=()=>{t=!1},c=()=>Bl.isFocused()&&(e.networkMode==="always"||gs.isOnline())&&e.canRun(),u=()=>Rg(e.networkMode)&&e.canRun(),d=g=>{o()||(r==null||r(),i.resolve(g))},h=g=>{o()||(r==null||r(),i.reject(g))},m=()=>new Promise(g=>{var p;r=v=>{(o()||c())&&g(v)},(p=e.onPause)==null||p.call(e)}).then(()=>{var g;r=void 0,o()||(g=e.onContinue)==null||g.call(e)}),f=()=>{if(o())return;let g;const p=n===0?e.initialPromise:void 0;try{g=p??e.fn()}catch(v){g=Promise.reject(v)}Promise.resolve(g).then(d).catch(v=>{var P;if(o())return;const x=e.retry??(Hn?0:3),S=e.retryDelay??AR,C=typeof S=="function"?S(n,v):S,w=x===!0||typeof x=="number"&&nc()?void 0:m()).then(()=>{t?h(v):f()})})};return{promise:i,status:()=>i.status,cancel:s,continue:()=>(r==null||r(),i),cancelRetry:a,continueRetry:l,canStart:u,start:()=>(u()?f():m().then(f),i)}}var Ng=(Ev=class{constructor(){W(this,Qn)}destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),Ll(this.gcTime)&&M(this,Qn,Wn.setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(e){this.gcTime=Math.max(this.gcTime||0,e??(Hn?1/0:5*60*1e3))}clearGcTimeout(){b(this,Qn)&&(Wn.clearTimeout(b(this,Qn)),M(this,Qn,void 0))}},Qn=new WeakMap,Ev),_R=(kv=class extends Ng{constructor(t){super();W(this,Ct);W(this,Jn);W(this,$r);W(this,ft);W(this,Zn);W(this,Ae);W(this,zi);W(this,er);M(this,er,!1),M(this,zi,t.defaultOptions),this.setOptions(t.options),this.observers=[],M(this,Zn,t.client),M(this,ft,b(this,Zn).getQueryCache()),this.queryKey=t.queryKey,this.queryHash=t.queryHash,M(this,Jn,_g(this.options)),this.state=t.state??b(this,Jn),this.scheduleGc()}get meta(){return this.options.meta}get promise(){var t;return(t=b(this,Ae))==null?void 0:t.promise}setOptions(t){if(this.options={...b(this,zi),...t},this.updateGcTime(this.options.gcTime),this.state&&this.state.data===void 0){const n=_g(this.options);n.data!==void 0&&(this.setData(n.data,{updatedAt:n.dataUpdatedAt,manual:!0}),M(this,Jn,n))}}optionalRemove(){!this.observers.length&&this.state.fetchStatus==="idle"&&b(this,ft).remove(this)}setData(t,n){const r=Ml(this.state.data,t,this.options);return J(this,Ct,Xt).call(this,{data:r,type:"success",dataUpdatedAt:n==null?void 0:n.updatedAt,manual:n==null?void 0:n.manual}),r}setState(t,n){J(this,Ct,Xt).call(this,{type:"setState",state:t,setStateOptions:n})}cancel(t){var r,i;const n=(r=b(this,Ae))==null?void 0:r.promise;return(i=b(this,Ae))==null||i.cancel(t),n?n.then($e).catch($e):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}reset(){this.destroy(),this.setState(b(this,Jn))}isActive(){return this.observers.some(t=>ht(t.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===$l||this.state.dataUpdateCount+this.state.errorUpdateCount===0}isStatic(){return this.getObserversCount()>0?this.observers.some(t=>ln(t.options.staleTime,this)==="static"):!1}isStale(){return this.getObserversCount()>0?this.observers.some(t=>t.getCurrentResult().isStale):this.state.data===void 0||this.state.isInvalidated}isStaleByTime(t=0){return this.state.data===void 0?!0:t==="static"?!1:this.state.isInvalidated?!0:!Cg(this.state.dataUpdatedAt,t)}onFocus(){var n;const t=this.observers.find(r=>r.shouldFetchOnWindowFocus());t==null||t.refetch({cancelRefetch:!1}),(n=b(this,Ae))==null||n.continue()}onOnline(){var n;const t=this.observers.find(r=>r.shouldFetchOnReconnect());t==null||t.refetch({cancelRefetch:!1}),(n=b(this,Ae))==null||n.continue()}addObserver(t){this.observers.includes(t)||(this.observers.push(t),this.clearGcTimeout(),b(this,ft).notify({type:"observerAdded",query:this,observer:t}))}removeObserver(t){this.observers.includes(t)&&(this.observers=this.observers.filter(n=>n!==t),this.observers.length||(b(this,Ae)&&(b(this,er)?b(this,Ae).cancel({revert:!0}):b(this,Ae).cancelRetry()),this.scheduleGc()),b(this,ft).notify({type:"observerRemoved",query:this,observer:t}))}getObserversCount(){return this.observers.length}invalidate(){this.state.isInvalidated||J(this,Ct,Xt).call(this,{type:"invalidate"})}async fetch(t,n){var l,c,u,d,h,m,f,g,p,v,x,S;if(this.state.fetchStatus!=="idle"&&((l=b(this,Ae))==null?void 0:l.status())!=="rejected"){if(this.state.data!==void 0&&(n!=null&&n.cancelRefetch))this.cancel({silent:!0});else if(b(this,Ae))return b(this,Ae).continueRetry(),b(this,Ae).promise}if(t&&this.setOptions(t),!this.options.queryFn){const C=this.observers.find(w=>w.options.queryFn);C&&this.setOptions(C.options)}const r=new AbortController,i=C=>{Object.defineProperty(C,"signal",{enumerable:!0,get:()=>(M(this,er,!0),r.signal)})},o=()=>{const C=Ig(this.options,n),P=(()=>{const _={client:b(this,Zn),queryKey:this.queryKey,meta:this.meta};return i(_),_})();return M(this,er,!1),this.options.persister?this.options.persister(C,P,this):C(P)},a=(()=>{const C={fetchOptions:n,options:this.options,queryKey:this.queryKey,client:b(this,Zn),state:this.state,fetchFn:o};return i(C),C})();(c=this.options.behavior)==null||c.onFetch(a,this),M(this,$r,this.state),(this.state.fetchStatus==="idle"||this.state.fetchMeta!==((u=a.fetchOptions)==null?void 0:u.meta))&&J(this,Ct,Xt).call(this,{type:"fetch",meta:(d=a.fetchOptions)==null?void 0:d.meta}),M(this,Ae,Tg({initialPromise:n==null?void 0:n.initialPromise,fn:a.fetchFn,onCancel:C=>{C instanceof Wl&&C.revert&&this.setState({...b(this,$r),fetchStatus:"idle"}),r.abort()},onFail:(C,w)=>{J(this,Ct,Xt).call(this,{type:"failed",failureCount:C,error:w})},onPause:()=>{J(this,Ct,Xt).call(this,{type:"pause"})},onContinue:()=>{J(this,Ct,Xt).call(this,{type:"continue"})},retry:a.options.retry,retryDelay:a.options.retryDelay,networkMode:a.options.networkMode,canRun:()=>!0}));try{const C=await b(this,Ae).start();if(C===void 0)throw new Error(`${this.queryHash} data is undefined`);return this.setData(C),(m=(h=b(this,ft).config).onSuccess)==null||m.call(h,C,this),(g=(f=b(this,ft).config).onSettled)==null||g.call(f,C,this.state.error,this),C}catch(C){if(C instanceof Wl){if(C.silent)return b(this,Ae).promise;if(C.revert){if(this.state.data===void 0)throw C;return this.state.data}}throw J(this,Ct,Xt).call(this,{type:"error",error:C}),(v=(p=b(this,ft).config).onError)==null||v.call(p,C,this),(S=(x=b(this,ft).config).onSettled)==null||S.call(x,this.state.data,C,this),C}finally{this.scheduleGc()}}},Jn=new WeakMap,$r=new WeakMap,ft=new WeakMap,Zn=new WeakMap,Ae=new WeakMap,zi=new WeakMap,er=new WeakMap,Ct=new WeakSet,Xt=function(t){const n=r=>{switch(t.type){case"failed":return{...r,fetchFailureCount:t.failureCount,fetchFailureReason:t.error};case"pause":return{...r,fetchStatus:"paused"};case"continue":return{...r,fetchStatus:"fetching"};case"fetch":return{...r,...Ag(r.data,this.options),fetchMeta:t.meta??null};case"success":const i={...r,data:t.data,dataUpdateCount:r.dataUpdateCount+1,dataUpdatedAt:t.dataUpdatedAt??Date.now(),error:null,isInvalidated:!1,status:"success",...!t.manual&&{fetchStatus:"idle",fetchFailureCount:0,fetchFailureReason:null}};return M(this,$r,t.manual?i:void 0),i;case"error":const o=t.error;return{...r,error:o,errorUpdateCount:r.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:r.fetchFailureCount+1,fetchFailureReason:o,fetchStatus:"idle",status:"error"};case"invalidate":return{...r,isInvalidated:!0};case"setState":return{...r,...t.state}}};this.state=n(this.state),we.batch(()=>{this.observers.forEach(r=>{r.onQueryUpdate()}),b(this,ft).notify({query:this,type:"updated",action:t})})},kv);function Ag(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:Rg(t.networkMode)?"fetching":"paused",...e===void 0&&{error:null,status:"pending"}}}function _g(e){const t=typeof e.initialData=="function"?e.initialData():e.initialData,n=t!==void 0,r=n?typeof e.initialDataUpdatedAt=="function"?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:n?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:n?"success":"pending",fetchStatus:"idle"}}var VR=(Ov=class extends Ar{constructor(t,n){super();W(this,oe);W(this,Ye);W(this,ee);W(this,Mi);W(this,Be);W(this,tr);W(this,Br);W(this,Ht);W(this,mn);W(this,$i);W(this,jr);W(this,Wr);W(this,nr);W(this,rr);W(this,vn);W(this,Hr,new Set);this.options=n,M(this,Ye,t),M(this,mn,null),M(this,Ht,jl()),this.bindMethods(),this.setOptions(n)}bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(b(this,ee).addObserver(this),Vg(b(this,ee),this.options)?J(this,oe,Wi).call(this):this.updateResult(),J(this,oe,yc).call(this))}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return Hl(b(this,ee),this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return Hl(b(this,ee),this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,J(this,oe,xc).call(this),J(this,oe,Cc).call(this),b(this,ee).removeObserver(this)}setOptions(t){const n=this.options,r=b(this,ee);if(this.options=b(this,Ye).defaultQueryOptions(t),this.options.enabled!==void 0&&typeof this.options.enabled!="boolean"&&typeof this.options.enabled!="function"&&typeof ht(this.options.enabled,b(this,ee))!="boolean")throw new Error("Expected enabled to be a boolean or a callback that returns a boolean");J(this,oe,Sc).call(this),b(this,ee).setOptions(this.options),n._defaulted&&!fs(this.options,n)&&b(this,Ye).getQueryCache().notify({type:"observerOptionsUpdated",query:b(this,ee),observer:this});const i=this.hasListeners();i&&Fg(b(this,ee),r,this.options,n)&&J(this,oe,Wi).call(this),this.updateResult(),i&&(b(this,ee)!==r||ht(this.options.enabled,b(this,ee))!==ht(n.enabled,b(this,ee))||ln(this.options.staleTime,b(this,ee))!==ln(n.staleTime,b(this,ee)))&&J(this,oe,mc).call(this);const o=J(this,oe,vc).call(this);i&&(b(this,ee)!==r||ht(this.options.enabled,b(this,ee))!==ht(n.enabled,b(this,ee))||o!==b(this,vn))&&J(this,oe,bc).call(this,o)}getOptimisticResult(t){const n=b(this,Ye).getQueryCache().build(b(this,Ye),t),r=this.createResult(n,t);return LR(this,r)&&(M(this,Be,r),M(this,Br,this.options),M(this,tr,b(this,ee).state)),r}getCurrentResult(){return b(this,Be)}trackResult(t,n){return new Proxy(t,{get:(r,i)=>(this.trackProp(i),n==null||n(i),i==="promise"&&!this.options.experimental_prefetchInRender&&b(this,Ht).status==="pending"&&b(this,Ht).reject(new Error("experimental_prefetchInRender feature flag is not enabled")),Reflect.get(r,i))})}trackProp(t){b(this,Hr).add(t)}getCurrentQuery(){return b(this,ee)}refetch({...t}={}){return this.fetch({...t})}fetchOptimistic(t){const n=b(this,Ye).defaultQueryOptions(t),r=b(this,Ye).getQueryCache().build(b(this,Ye),n);return r.fetch().then(()=>this.createResult(r,n))}fetch(t){return J(this,oe,Wi).call(this,{...t,cancelRefetch:t.cancelRefetch??!0}).then(()=>(this.updateResult(),b(this,Be)))}createResult(t,n){var N;const r=b(this,ee),i=this.options,o=b(this,Be),s=b(this,tr),a=b(this,Br),c=t!==r?t.state:b(this,Mi),{state:u}=t;let d={...u},h=!1,m;if(n._optimisticResults){const T=this.hasListeners(),j=!T&&Vg(t,n),I=T&&Fg(t,r,n,i);(j||I)&&(d={...d,...Ag(u.data,t.options)}),n._optimisticResults==="isRestoring"&&(d.fetchStatus="idle")}let{error:f,errorUpdatedAt:g,status:p}=d;m=d.data;let v=!1;if(n.placeholderData!==void 0&&m===void 0&&p==="pending"){let T;o!=null&&o.isPlaceholderData&&n.placeholderData===(a==null?void 0:a.placeholderData)?(T=o.data,v=!0):T=typeof n.placeholderData=="function"?n.placeholderData((N=b(this,Wr))==null?void 0:N.state.data,b(this,Wr)):n.placeholderData,T!==void 0&&(p="success",m=Ml(o==null?void 0:o.data,T,n),h=!0)}if(n.select&&m!==void 0&&!v)if(o&&m===(s==null?void 0:s.data)&&n.select===b(this,$i))m=b(this,jr);else try{M(this,$i,n.select),m=n.select(m),m=Ml(o==null?void 0:o.data,m,n),M(this,jr,m),M(this,mn,null)}catch(T){M(this,mn,T)}b(this,mn)&&(f=b(this,mn),m=b(this,jr),g=Date.now(),p="error");const x=d.fetchStatus==="fetching",S=p==="pending",C=p==="error",w=S&&x,P=m!==void 0,R={status:p,fetchStatus:d.fetchStatus,isPending:S,isSuccess:p==="success",isError:C,isInitialLoading:w,isLoading:w,data:m,dataUpdatedAt:d.dataUpdatedAt,error:f,errorUpdatedAt:g,failureCount:d.fetchFailureCount,failureReason:d.fetchFailureReason,errorUpdateCount:d.errorUpdateCount,isFetched:d.dataUpdateCount>0||d.errorUpdateCount>0,isFetchedAfterMount:d.dataUpdateCount>c.dataUpdateCount||d.errorUpdateCount>c.errorUpdateCount,isFetching:x,isRefetching:x&&!S,isLoadingError:C&&!P,isPaused:d.fetchStatus==="paused",isPlaceholderData:h,isRefetchError:C&&P,isStale:Ul(t,n),refetch:this.refetch,promise:b(this,Ht),isEnabled:ht(n.enabled,t)!==!1};if(this.options.experimental_prefetchInRender){const T=F=>{R.status==="error"?F.reject(R.error):R.data!==void 0&&F.resolve(R.data)},j=()=>{const F=M(this,Ht,R.promise=jl());T(F)},I=b(this,Ht);switch(I.status){case"pending":t.queryHash===r.queryHash&&T(I);break;case"fulfilled":(R.status==="error"||R.data!==I.value)&&j();break;case"rejected":(R.status!=="error"||R.error!==I.reason)&&j();break}}return R}updateResult(){const t=b(this,Be),n=this.createResult(b(this,ee),this.options);if(M(this,tr,b(this,ee).state),M(this,Br,this.options),b(this,tr).data!==void 0&&M(this,Wr,b(this,ee)),fs(n,t))return;M(this,Be,n);const r=()=>{if(!t)return!0;const{notifyOnChangeProps:i}=this.options,o=typeof i=="function"?i():i;if(o==="all"||!o&&!b(this,Hr).size)return!0;const s=new Set(o??b(this,Hr));return this.options.throwOnError&&s.add("error"),Object.keys(b(this,Be)).some(a=>{const l=a;return b(this,Be)[l]!==t[l]&&s.has(l)})};J(this,oe,pb).call(this,{listeners:r()})}onQueryUpdate(){this.updateResult(),this.hasListeners()&&J(this,oe,yc).call(this)}},Ye=new WeakMap,ee=new WeakMap,Mi=new WeakMap,Be=new WeakMap,tr=new WeakMap,Br=new WeakMap,Ht=new WeakMap,mn=new WeakMap,$i=new WeakMap,jr=new WeakMap,Wr=new WeakMap,nr=new WeakMap,rr=new WeakMap,vn=new WeakMap,Hr=new WeakMap,oe=new WeakSet,Wi=function(t){J(this,oe,Sc).call(this);let n=b(this,ee).fetch(this.options,t);return t!=null&&t.throwOnError||(n=n.catch($e)),n},mc=function(){J(this,oe,xc).call(this);const t=ln(this.options.staleTime,b(this,ee));if(Hn||b(this,Be).isStale||!Ll(t))return;const r=Cg(b(this,Be).dataUpdatedAt,t)+1;M(this,nr,Wn.setTimeout(()=>{b(this,Be).isStale||this.updateResult()},r))},vc=function(){return(typeof this.options.refetchInterval=="function"?this.options.refetchInterval(b(this,ee)):this.options.refetchInterval)??!1},bc=function(t){J(this,oe,Cc).call(this),M(this,vn,t),!(Hn||ht(this.options.enabled,b(this,ee))===!1||!Ll(b(this,vn))||b(this,vn)===0)&&M(this,rr,Wn.setInterval(()=>{(this.options.refetchIntervalInBackground||Bl.isFocused())&&J(this,oe,Wi).call(this)},b(this,vn)))},yc=function(){J(this,oe,mc).call(this),J(this,oe,bc).call(this,J(this,oe,vc).call(this))},xc=function(){b(this,nr)&&(Wn.clearTimeout(b(this,nr)),M(this,nr,void 0))},Cc=function(){b(this,rr)&&(Wn.clearInterval(b(this,rr)),M(this,rr,void 0))},Sc=function(){const t=b(this,Ye).getQueryCache().build(b(this,Ye),this.options);if(t===b(this,ee))return;const n=b(this,ee);M(this,ee,t),M(this,Mi,t.state),this.hasListeners()&&(n==null||n.removeObserver(this),t.addObserver(this))},pb=function(t){we.batch(()=>{t.listeners&&this.listeners.forEach(n=>{n(b(this,Be))}),b(this,Ye).getQueryCache().notify({query:b(this,ee),type:"observerResultsUpdated"})})},Ov);function FR(e,t){return ht(t.enabled,e)!==!1&&e.state.data===void 0&&!(e.state.status==="error"&&t.retryOnMount===!1)}function Vg(e,t){return FR(e,t)||e.state.data!==void 0&&Hl(e,t,t.refetchOnMount)}function Hl(e,t,n){if(ht(t.enabled,e)!==!1&&ln(t.staleTime,e)!=="static"){const r=typeof n=="function"?n(e):n;return r==="always"||r!==!1&&Ul(e,t)}return!1}function Fg(e,t,n,r){return(e!==t||ht(r.enabled,e)===!1)&&(!n.suspense||e.state.status!=="error")&&Ul(e,n)}function Ul(e,t){return ht(t.enabled,e)!==!1&&e.isStaleByTime(ln(t.staleTime,e))}function LR(e,t){return!fs(e.getCurrentResult(),t)}function Lg(e){return{onFetch:(t,n)=>{var u,d,h,m,f;const r=t.options,i=(h=(d=(u=t.fetchOptions)==null?void 0:u.meta)==null?void 0:d.fetchMore)==null?void 0:h.direction,o=((m=t.state.data)==null?void 0:m.pages)||[],s=((f=t.state.data)==null?void 0:f.pageParams)||[];let a={pages:[],pageParams:[]},l=0;const c=async()=>{let g=!1;const p=S=>{Object.defineProperty(S,"signal",{enumerable:!0,get:()=>(t.signal.aborted?g=!0:t.signal.addEventListener("abort",()=>{g=!0}),t.signal)})},v=Ig(t.options,t.fetchOptions),x=async(S,C,w)=>{if(g)return Promise.reject();if(C==null&&S.pages.length)return Promise.resolve(S);const _=(()=>{const j={client:t.client,queryKey:t.queryKey,pageParam:C,direction:w?"backward":"forward",meta:t.options.meta};return p(j),j})(),R=await v(_),{maxPages:N}=t.options,T=w?IR:OR;return{pages:T(S.pages,R,N),pageParams:T(S.pageParams,C,N)}};if(i&&o.length){const S=i==="backward",C=S?DR:Dg,w={pages:o,pageParams:s},P=C(r,w);a=await x(w,P,S)}else{const S=e??o.length;do{const C=l===0?s[0]??r.initialPageParam:Dg(r,a);if(l>0&&C==null)break;a=await x(a,C),l++}while(l{var g,p;return(p=(g=t.options).persister)==null?void 0:p.call(g,c,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n)}:t.fetchFn=c}}}function Dg(e,{pages:t,pageParams:n}){const r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function DR(e,{pages:t,pageParams:n}){var r;return t.length>0?(r=e.getPreviousPageParam)==null?void 0:r.call(e,t[0],t,n[0],n):void 0}var zR=(Iv=class extends Ng{constructor(t){super();W(this,Lt);W(this,Ft);W(this,je);W(this,ir);this.mutationId=t.mutationId,M(this,je,t.mutationCache),M(this,Ft,[]),this.state=t.state||zg(),this.setOptions(t.options),this.scheduleGc()}setOptions(t){this.options=t,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(t){b(this,Ft).includes(t)||(b(this,Ft).push(t),this.clearGcTimeout(),b(this,je).notify({type:"observerAdded",mutation:this,observer:t}))}removeObserver(t){M(this,Ft,b(this,Ft).filter(n=>n!==t)),this.scheduleGc(),b(this,je).notify({type:"observerRemoved",mutation:this,observer:t})}optionalRemove(){b(this,Ft).length||(this.state.status==="pending"?this.scheduleGc():b(this,je).remove(this))}continue(){var t;return((t=b(this,ir))==null?void 0:t.continue())??this.execute(this.state.variables)}async execute(t){var o,s,a,l,c,u,d,h,m,f,g,p,v,x,S,C,w,P,_,R;const n=()=>{J(this,Lt,En).call(this,{type:"continue"})};M(this,ir,Tg({fn:()=>this.options.mutationFn?this.options.mutationFn(t):Promise.reject(new Error("No mutationFn found")),onFail:(N,T)=>{J(this,Lt,En).call(this,{type:"failed",failureCount:N,error:T})},onPause:()=>{J(this,Lt,En).call(this,{type:"pause"})},onContinue:n,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>b(this,je).canRun(this)}));const r=this.state.status==="pending",i=!b(this,ir).canStart();try{if(r)n();else{J(this,Lt,En).call(this,{type:"pending",variables:t,isPaused:i}),await((s=(o=b(this,je).config).onMutate)==null?void 0:s.call(o,t,this));const T=await((l=(a=this.options).onMutate)==null?void 0:l.call(a,t));T!==this.state.context&&J(this,Lt,En).call(this,{type:"pending",context:T,variables:t,isPaused:i})}const N=await b(this,ir).start();return await((u=(c=b(this,je).config).onSuccess)==null?void 0:u.call(c,N,t,this.state.context,this)),await((h=(d=this.options).onSuccess)==null?void 0:h.call(d,N,t,this.state.context)),await((f=(m=b(this,je).config).onSettled)==null?void 0:f.call(m,N,null,this.state.variables,this.state.context,this)),await((p=(g=this.options).onSettled)==null?void 0:p.call(g,N,null,t,this.state.context)),J(this,Lt,En).call(this,{type:"success",data:N}),N}catch(N){try{throw await((x=(v=b(this,je).config).onError)==null?void 0:x.call(v,N,t,this.state.context,this)),await((C=(S=this.options).onError)==null?void 0:C.call(S,N,t,this.state.context)),await((P=(w=b(this,je).config).onSettled)==null?void 0:P.call(w,void 0,N,this.state.variables,this.state.context,this)),await((R=(_=this.options).onSettled)==null?void 0:R.call(_,void 0,N,t,this.state.context)),N}finally{J(this,Lt,En).call(this,{type:"error",error:N})}}finally{b(this,je).runNext(this)}}},Ft=new WeakMap,je=new WeakMap,ir=new WeakMap,Lt=new WeakSet,En=function(t){const n=r=>{switch(t.type){case"failed":return{...r,failureCount:t.failureCount,failureReason:t.error};case"pause":return{...r,isPaused:!0};case"continue":return{...r,isPaused:!1};case"pending":return{...r,context:t.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:t.isPaused,status:"pending",variables:t.variables,submittedAt:Date.now()};case"success":return{...r,data:t.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...r,data:void 0,error:t.error,failureCount:r.failureCount+1,failureReason:t.error,isPaused:!1,status:"error"}}};this.state=n(this.state),we.batch(()=>{b(this,Ft).forEach(r=>{r.onMutationUpdate(t)}),b(this,je).notify({mutation:this,type:"updated",action:t})})},Iv);function zg(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}var MR=(Pv=class extends Ar{constructor(t={}){super();W(this,Ut);W(this,St);W(this,Bi);this.config=t,M(this,Ut,new Set),M(this,St,new Map),M(this,Bi,0)}build(t,n,r){const i=new zR({mutationCache:this,mutationId:++Bs(this,Bi)._,options:t.defaultMutationOptions(n),state:r});return this.add(i),i}add(t){b(this,Ut).add(t);const n=ps(t);if(typeof n=="string"){const r=b(this,St).get(n);r?r.push(t):b(this,St).set(n,[t])}this.notify({type:"added",mutation:t})}remove(t){if(b(this,Ut).delete(t)){const n=ps(t);if(typeof n=="string"){const r=b(this,St).get(n);if(r)if(r.length>1){const i=r.indexOf(t);i!==-1&&r.splice(i,1)}else r[0]===t&&b(this,St).delete(n)}}this.notify({type:"removed",mutation:t})}canRun(t){const n=ps(t);if(typeof n=="string"){const r=b(this,St).get(n),i=r==null?void 0:r.find(o=>o.state.status==="pending");return!i||i===t}else return!0}runNext(t){var r;const n=ps(t);if(typeof n=="string"){const i=(r=b(this,St).get(n))==null?void 0:r.find(o=>o!==t&&o.state.isPaused);return(i==null?void 0:i.continue())??Promise.resolve()}else return Promise.resolve()}clear(){we.batch(()=>{b(this,Ut).forEach(t=>{this.notify({type:"removed",mutation:t})}),b(this,Ut).clear(),b(this,St).clear()})}getAll(){return Array.from(b(this,Ut))}find(t){const n={exact:!0,...t};return this.getAll().find(r=>wg(n,r))}findAll(t={}){return this.getAll().filter(n=>wg(t,n))}notify(t){we.batch(()=>{this.listeners.forEach(n=>{n(t)})})}resumePausedMutations(){const t=this.getAll().filter(n=>n.state.isPaused);return we.batch(()=>Promise.all(t.map(n=>n.continue().catch($e))))}},Ut=new WeakMap,St=new WeakMap,Bi=new WeakMap,Pv);function ps(e){var t;return(t=e.options.scope)==null?void 0:t.id}var $R=(Rv=class extends Ar{constructor(t,n){super();W(this,qt);W(this,bn);W(this,yn);W(this,Qe);W(this,Gt);M(this,bn,t),this.setOptions(n),this.bindMethods(),J(this,qt,Us).call(this)}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(t){var r;const n=this.options;this.options=b(this,bn).defaultMutationOptions(t),fs(this.options,n)||b(this,bn).getMutationCache().notify({type:"observerOptionsUpdated",mutation:b(this,Qe),observer:this}),n!=null&&n.mutationKey&&this.options.mutationKey&&Un(n.mutationKey)!==Un(this.options.mutationKey)?this.reset():((r=b(this,Qe))==null?void 0:r.state.status)==="pending"&&b(this,Qe).setOptions(this.options)}onUnsubscribe(){var t;this.hasListeners()||(t=b(this,Qe))==null||t.removeObserver(this)}onMutationUpdate(t){J(this,qt,Us).call(this),J(this,qt,wc).call(this,t)}getCurrentResult(){return b(this,yn)}reset(){var t;(t=b(this,Qe))==null||t.removeObserver(this),M(this,Qe,void 0),J(this,qt,Us).call(this),J(this,qt,wc).call(this)}mutate(t,n){var r;return M(this,Gt,n),(r=b(this,Qe))==null||r.removeObserver(this),M(this,Qe,b(this,bn).getMutationCache().build(b(this,bn),this.options)),b(this,Qe).addObserver(this),b(this,Qe).execute(t)}},bn=new WeakMap,yn=new WeakMap,Qe=new WeakMap,Gt=new WeakMap,qt=new WeakSet,Us=function(){var n;const t=((n=b(this,Qe))==null?void 0:n.state)??zg();M(this,yn,{...t,isPending:t.status==="pending",isSuccess:t.status==="success",isError:t.status==="error",isIdle:t.status==="idle",mutate:this.mutate,reset:this.reset})},wc=function(t){we.batch(()=>{var n,r,i,o,s,a,l,c;if(b(this,Gt)&&this.hasListeners()){const u=b(this,yn).variables,d=b(this,yn).context;(t==null?void 0:t.type)==="success"?((r=(n=b(this,Gt)).onSuccess)==null||r.call(n,t.data,u,d),(o=(i=b(this,Gt)).onSettled)==null||o.call(i,t.data,null,u,d)):(t==null?void 0:t.type)==="error"&&((a=(s=b(this,Gt)).onError)==null||a.call(s,t.error,u,d),(c=(l=b(this,Gt)).onSettled)==null||c.call(l,void 0,t.error,u,d))}this.listeners.forEach(u=>{u(b(this,yn))})})},Rv),BR=(Tv=class extends Ar{constructor(t={}){super();W(this,Dt);this.config=t,M(this,Dt,new Map)}build(t,n,r){const i=n.queryKey,o=n.queryHash??Dl(i,n);let s=this.get(o);return s||(s=new _R({client:t,queryKey:i,queryHash:o,options:t.defaultQueryOptions(n),state:r,defaultOptions:t.getQueryDefaults(i)}),this.add(s)),s}add(t){b(this,Dt).has(t.queryHash)||(b(this,Dt).set(t.queryHash,t),this.notify({type:"added",query:t}))}remove(t){const n=b(this,Dt).get(t.queryHash);n&&(t.destroy(),n===t&&b(this,Dt).delete(t.queryHash),this.notify({type:"removed",query:t}))}clear(){we.batch(()=>{this.getAll().forEach(t=>{this.remove(t)})})}get(t){return b(this,Dt).get(t)}getAll(){return[...b(this,Dt).values()]}find(t){const n={exact:!0,...t};return this.getAll().find(r=>Sg(n,r))}findAll(t={}){const n=this.getAll();return Object.keys(t).length>0?n.filter(r=>Sg(t,r)):n}notify(t){we.batch(()=>{this.listeners.forEach(n=>{n(t)})})}onFocus(){we.batch(()=>{this.getAll().forEach(t=>{t.onFocus()})})}onOnline(){we.batch(()=>{this.getAll().forEach(t=>{t.onOnline()})})}},Dt=new WeakMap,Tv),jR=(Nv=class{constructor(e={}){W(this,me);W(this,xn);W(this,Cn);W(this,Ur);W(this,Gr);W(this,Sn);W(this,qr);W(this,Kr);M(this,me,e.queryCache||new BR),M(this,xn,e.mutationCache||new MR),M(this,Cn,e.defaultOptions||{}),M(this,Ur,new Map),M(this,Gr,new Map),M(this,Sn,0)}mount(){Bs(this,Sn)._++,b(this,Sn)===1&&(M(this,qr,Bl.subscribe(async e=>{e&&(await this.resumePausedMutations(),b(this,me).onFocus())})),M(this,Kr,gs.subscribe(async e=>{e&&(await this.resumePausedMutations(),b(this,me).onOnline())})))}unmount(){var e,t;Bs(this,Sn)._--,b(this,Sn)===0&&((e=b(this,qr))==null||e.call(this),M(this,qr,void 0),(t=b(this,Kr))==null||t.call(this),M(this,Kr,void 0))}isFetching(e){return b(this,me).findAll({...e,fetchStatus:"fetching"}).length}isMutating(e){return b(this,xn).findAll({...e,status:"pending"}).length}getQueryData(e){var n;const t=this.defaultQueryOptions({queryKey:e});return(n=b(this,me).get(t.queryHash))==null?void 0:n.state.data}ensureQueryData(e){const t=this.defaultQueryOptions(e),n=b(this,me).build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(ln(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return b(this,me).findAll(e).map(({queryKey:t,state:n})=>{const r=n.data;return[t,r]})}setQueryData(e,t,n){const r=this.defaultQueryOptions({queryKey:e}),i=b(this,me).get(r.queryHash),o=i==null?void 0:i.state.data,s=wR(t,o);if(s!==void 0)return b(this,me).build(this,r).setData(s,{...n,manual:!0})}setQueriesData(e,t,n){return we.batch(()=>b(this,me).findAll(e).map(({queryKey:r})=>[r,this.setQueryData(r,t,n)]))}getQueryState(e){var n;const t=this.defaultQueryOptions({queryKey:e});return(n=b(this,me).get(t.queryHash))==null?void 0:n.state}removeQueries(e){const t=b(this,me);we.batch(()=>{t.findAll(e).forEach(n=>{t.remove(n)})})}resetQueries(e,t){const n=b(this,me);return we.batch(()=>(n.findAll(e).forEach(r=>{r.reset()}),this.refetchQueries({type:"active",...e},t)))}cancelQueries(e,t={}){const n={revert:!0,...t},r=we.batch(()=>b(this,me).findAll(e).map(i=>i.cancel(n)));return Promise.all(r).then($e).catch($e)}invalidateQueries(e,t={}){return we.batch(()=>(b(this,me).findAll(e).forEach(n=>{n.invalidate()}),(e==null?void 0:e.refetchType)==="none"?Promise.resolve():this.refetchQueries({...e,type:(e==null?void 0:e.refetchType)??(e==null?void 0:e.type)??"active"},t)))}refetchQueries(e,t={}){const n={...t,cancelRefetch:t.cancelRefetch??!0},r=we.batch(()=>b(this,me).findAll(e).filter(i=>!i.isDisabled()&&!i.isStatic()).map(i=>{let o=i.fetch(void 0,n);return n.throwOnError||(o=o.catch($e)),i.state.fetchStatus==="paused"?Promise.resolve():o}));return Promise.all(r).then($e)}fetchQuery(e){const t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);const n=b(this,me).build(this,t);return n.isStaleByTime(ln(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then($e).catch($e)}fetchInfiniteQuery(e){return e.behavior=Lg(e.pages),this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then($e).catch($e)}ensureInfiniteQueryData(e){return e.behavior=Lg(e.pages),this.ensureQueryData(e)}resumePausedMutations(){return gs.isOnline()?b(this,xn).resumePausedMutations():Promise.resolve()}getQueryCache(){return b(this,me)}getMutationCache(){return b(this,xn)}getDefaultOptions(){return b(this,Cn)}setDefaultOptions(e){M(this,Cn,e)}setQueryDefaults(e,t){b(this,Ur).set(Un(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){const t=[...b(this,Ur).values()],n={};return t.forEach(r=>{Ii(e,r.queryKey)&&Object.assign(n,r.defaultOptions)}),n}setMutationDefaults(e,t){b(this,Gr).set(Un(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){const t=[...b(this,Gr).values()],n={};return t.forEach(r=>{Ii(e,r.mutationKey)&&Object.assign(n,r.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;const t={...b(this,Cn).queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||(t.queryHash=Dl(t.queryKey,t)),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!=="always"),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode="offlineFirst"),t.queryFn===$l&&(t.enabled=!1),t}defaultMutationOptions(e){return e!=null&&e._defaulted?e:{...b(this,Cn).mutations,...(e==null?void 0:e.mutationKey)&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){b(this,me).clear(),b(this,xn).clear()}},me=new WeakMap,xn=new WeakMap,Cn=new WeakMap,Ur=new WeakMap,Gr=new WeakMap,Sn=new WeakMap,qr=new WeakMap,Kr=new WeakMap,Nv),Mg=O.createContext(void 0),$g=e=>{const t=O.useContext(Mg);if(!t)throw new Error("No QueryClient set, use QueryClientProvider to set one");return t},WR=({client:e,children:t})=>(O.useEffect(()=>(e.mount(),()=>{e.unmount()}),[e]),y.jsx(Mg.Provider,{value:e,children:t})),Bg=O.createContext(!1),HR=()=>O.useContext(Bg);Bg.Provider;function UR(){let e=!1;return{clearReset:()=>{e=!1},reset:()=>{e=!0},isReset:()=>e}}var GR=O.createContext(UR()),qR=()=>O.useContext(GR),KR=(e,t)=>{(e.suspense||e.throwOnError||e.experimental_prefetchInRender)&&(t.isReset()||(e.retryOnMount=!1))},XR=e=>{O.useEffect(()=>{e.clearReset()},[e])},YR=({result:e,errorResetBoundary:t,throwOnError:n,query:r,suspense:i})=>e.isError&&!t.isReset()&&!e.isFetching&&r&&(i&&e.data===void 0||Pg(n,[e.error,r])),QR=e=>{if(e.suspense){const n=i=>i==="static"?i:Math.max(i??1e3,1e3),r=e.staleTime;e.staleTime=typeof r=="function"?(...i)=>n(r(...i)):n(r),typeof e.gcTime=="number"&&(e.gcTime=Math.max(e.gcTime,1e3))}},JR=(e,t)=>e.isLoading&&e.isFetching&&!t,ZR=(e,t)=>(e==null?void 0:e.suspense)&&t.isPending,jg=(e,t,n)=>t.fetchOptimistic(e).catch(()=>{n.clearReset()});function eT(e,t,n){var d,h,m,f,g;const r=HR(),i=qR(),o=$g(),s=o.defaultQueryOptions(e);(h=(d=o.getDefaultOptions().queries)==null?void 0:d._experimental_beforeQuery)==null||h.call(d,s),s._optimisticResults=r?"isRestoring":"optimistic",QR(s),KR(s,i),XR(i);const a=!o.getQueryCache().get(s.queryHash),[l]=O.useState(()=>new t(o,s)),c=l.getOptimisticResult(s),u=!r&&e.subscribed!==!1;if(O.useSyncExternalStore(O.useCallback(p=>{const v=u?l.subscribe(we.batchCalls(p)):$e;return l.updateResult(),v},[l,u]),()=>l.getCurrentResult(),()=>l.getCurrentResult()),O.useEffect(()=>{l.setOptions(s)},[s,l]),ZR(s,c))throw jg(s,l,i);if(YR({result:c,errorResetBoundary:i,throwOnError:s.throwOnError,query:o.getQueryCache().get(s.queryHash),suspense:s.suspense}))throw c.error;if((f=(m=o.getDefaultOptions().queries)==null?void 0:m._experimental_afterQuery)==null||f.call(m,s,c),s.experimental_prefetchInRender&&!Hn&&JR(c,r)){const p=a?jg(s,l,i):(g=o.getQueryCache().get(s.queryHash))==null?void 0:g.promise;p==null||p.catch($e).finally(()=>{l.updateResult()})}return s.notifyOnChangeProps?c:l.trackResult(c)}function Wg(e,t){return eT(e,VR)}function Hg(e,t){const n=$g(),[r]=O.useState(()=>new $R(n,e));O.useEffect(()=>{r.setOptions(e)},[r,e]);const i=O.useSyncExternalStore(O.useCallback(s=>r.subscribe(we.batchCalls(s)),[r]),()=>r.getCurrentResult(),()=>r.getCurrentResult()),o=O.useCallback((s,a)=>{r.mutate(s,a).catch($e)},[r]);if(i.error&&Pg(r.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:o,mutateAsync:i.mutate}}function Ug(e,t){return function(){return e.apply(t,arguments)}}const{toString:tT}=Object.prototype,{getPrototypeOf:Gl}=Object,{iterator:ms,toStringTag:Gg}=Symbol,vs=(e=>t=>{const n=tT.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),xt=e=>(e=e.toLowerCase(),t=>vs(t)===e),bs=e=>t=>typeof t===e,{isArray:_r}=Array,Pi=bs("undefined");function Ri(e){return e!==null&&!Pi(e)&&e.constructor!==null&&!Pi(e.constructor)&&Ke(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const qg=xt("ArrayBuffer");function nT(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&qg(e.buffer),t}const rT=bs("string"),Ke=bs("function"),Kg=bs("number"),Ti=e=>e!==null&&typeof e=="object",iT=e=>e===!0||e===!1,ys=e=>{if(vs(e)!=="object")return!1;const t=Gl(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Gg in e)&&!(ms in e)},oT=e=>{if(!Ti(e)||Ri(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},sT=xt("Date"),aT=xt("File"),lT=xt("Blob"),cT=xt("FileList"),uT=e=>Ti(e)&&Ke(e.pipe),dT=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||Ke(e.append)&&((t=vs(e))==="formdata"||t==="object"&&Ke(e.toString)&&e.toString()==="[object FormData]"))},hT=xt("URLSearchParams"),[fT,gT,pT,mT]=["ReadableStream","Request","Response","Headers"].map(xt),vT=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function Ni(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let r,i;if(typeof e!="object"&&(e=[e]),_r(e))for(r=0,i=e.length;r0;)if(i=n[r],t===i.toLowerCase())return i;return null}const Gn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:globalThis,Yg=e=>!Pi(e)&&e!==Gn;function ql(){const{caseless:e}=Yg(this)&&this||{},t={},n=(r,i)=>{const o=e&&Xg(t,i)||i;ys(t[o])&&ys(r)?t[o]=ql(t[o],r):ys(r)?t[o]=ql({},r):_r(r)?t[o]=r.slice():t[o]=r};for(let r=0,i=arguments.length;r(Ni(t,(i,o)=>{n&&Ke(i)?e[o]=Ug(i,n):e[o]=i},{allOwnKeys:r}),e),yT=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),xT=(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},CT=(e,t,n,r)=>{let i,o,s;const a={};if(t=t||{},e==null)return t;do{for(i=Object.getOwnPropertyNames(e),o=i.length;o-- >0;)s=i[o],(!r||r(s,e,t))&&!a[s]&&(t[s]=e[s],a[s]=!0);e=n!==!1&&Gl(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},ST=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return r!==-1&&r===n},wT=e=>{if(!e)return null;if(_r(e))return e;let t=e.length;if(!Kg(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},ET=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&Gl(Uint8Array)),kT=(e,t)=>{const r=(e&&e[ms]).call(e);let i;for(;(i=r.next())&&!i.done;){const o=i.value;t.call(e,o[0],o[1])}},OT=(e,t)=>{let n;const r=[];for(;(n=e.exec(t))!==null;)r.push(n);return r},IT=xt("HTMLFormElement"),PT=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,i){return r.toUpperCase()+i}),Qg=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),RT=xt("RegExp"),Jg=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};Ni(n,(i,o)=>{let s;(s=t(i,o,e))!==!1&&(r[o]=s||i)}),Object.defineProperties(e,r)},TT=e=>{Jg(e,(t,n)=>{if(Ke(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const r=e[n];if(Ke(r)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},NT=(e,t)=>{const n={},r=i=>{i.forEach(o=>{n[o]=!0})};return _r(e)?r(e):r(String(e).split(t)),n},AT=()=>{},_T=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function VT(e){return!!(e&&Ke(e.append)&&e[Gg]==="FormData"&&e[ms])}const FT=e=>{const t=new Array(10),n=(r,i)=>{if(Ti(r)){if(t.indexOf(r)>=0)return;if(Ri(r))return r;if(!("toJSON"in r)){t[i]=r;const o=_r(r)?[]:{};return Ni(r,(s,a)=>{const l=n(s,i+1);!Pi(l)&&(o[a]=l)}),t[i]=void 0,o}}return r};return n(e,0)},LT=xt("AsyncFunction"),DT=e=>e&&(Ti(e)||Ke(e))&&Ke(e.then)&&Ke(e.catch),Zg=((e,t)=>e?setImmediate:t?((n,r)=>(Gn.addEventListener("message",({source:i,data:o})=>{i===Gn&&o===n&&r.length&&r.shift()()},!1),i=>{r.push(i),Gn.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",Ke(Gn.postMessage)),zT=typeof queueMicrotask<"u"?queueMicrotask.bind(Gn):typeof process<"u"&&process.nextTick||Zg,k={isArray:_r,isArrayBuffer:qg,isBuffer:Ri,isFormData:dT,isArrayBufferView:nT,isString:rT,isNumber:Kg,isBoolean:iT,isObject:Ti,isPlainObject:ys,isEmptyObject:oT,isReadableStream:fT,isRequest:gT,isResponse:pT,isHeaders:mT,isUndefined:Pi,isDate:sT,isFile:aT,isBlob:lT,isRegExp:RT,isFunction:Ke,isStream:uT,isURLSearchParams:hT,isTypedArray:ET,isFileList:cT,forEach:Ni,merge:ql,extend:bT,trim:vT,stripBOM:yT,inherits:xT,toFlatObject:CT,kindOf:vs,kindOfTest:xt,endsWith:ST,toArray:wT,forEachEntry:kT,matchAll:OT,isHTMLForm:IT,hasOwnProperty:Qg,hasOwnProp:Qg,reduceDescriptors:Jg,freezeMethods:TT,toObjectSet:NT,toCamelCase:PT,noop:AT,toFiniteNumber:_T,findKey:Xg,global:Gn,isContextDefined:Yg,isSpecCompliantForm:VT,toJSONObject:FT,isAsyncFn:LT,isThenable:DT,setImmediate:Zg,asap:zT,isIterable:e=>e!=null&&Ke(e[ms])};function Q(e,t,n,r,i){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),i&&(this.response=i,this.status=i.status?i.status:null)}k.inherits(Q,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:k.toJSONObject(this.config),code:this.code,status:this.status}}});const ep=Q.prototype,tp={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{tp[e]={value:e}}),Object.defineProperties(Q,tp),Object.defineProperty(ep,"isAxiosError",{value:!0}),Q.from=(e,t,n,r,i,o)=>{const s=Object.create(ep);return k.toFlatObject(e,s,function(l){return l!==Error.prototype},a=>a!=="isAxiosError"),Q.call(s,e.message,t,n,r,i),s.cause=e,s.name=e.name,o&&Object.assign(s,o),s};const MT=null;function Kl(e){return k.isPlainObject(e)||k.isArray(e)}function np(e){return k.endsWith(e,"[]")?e.slice(0,-2):e}function rp(e,t,n){return e?e.concat(t).map(function(i,o){return i=np(i),!n&&o?"["+i+"]":i}).join(n?".":""):t}function $T(e){return k.isArray(e)&&!e.some(Kl)}const BT=k.toFlatObject(k,{},null,function(t){return/^is[A-Z]/.test(t)});function xs(e,t,n){if(!k.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=k.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(g,p){return!k.isUndefined(p[g])});const r=n.metaTokens,i=n.visitor||u,o=n.dots,s=n.indexes,l=(n.Blob||typeof Blob<"u"&&Blob)&&k.isSpecCompliantForm(t);if(!k.isFunction(i))throw new TypeError("visitor must be a function");function c(f){if(f===null)return"";if(k.isDate(f))return f.toISOString();if(k.isBoolean(f))return f.toString();if(!l&&k.isBlob(f))throw new Q("Blob is not supported. Use a Buffer instead.");return k.isArrayBuffer(f)||k.isTypedArray(f)?l&&typeof Blob=="function"?new Blob([f]):Buffer.from(f):f}function u(f,g,p){let v=f;if(f&&!p&&typeof f=="object"){if(k.endsWith(g,"{}"))g=r?g:g.slice(0,-2),f=JSON.stringify(f);else if(k.isArray(f)&&$T(f)||(k.isFileList(f)||k.endsWith(g,"[]"))&&(v=k.toArray(f)))return g=np(g),v.forEach(function(S,C){!(k.isUndefined(S)||S===null)&&t.append(s===!0?rp([g],C,o):s===null?g:g+"[]",c(S))}),!1}return Kl(f)?!0:(t.append(rp(p,g,o),c(f)),!1)}const d=[],h=Object.assign(BT,{defaultVisitor:u,convertValue:c,isVisitable:Kl});function m(f,g){if(!k.isUndefined(f)){if(d.indexOf(f)!==-1)throw Error("Circular reference detected in "+g.join("."));d.push(f),k.forEach(f,function(v,x){(!(k.isUndefined(v)||v===null)&&i.call(t,v,k.isString(x)?x.trim():x,g,h))===!0&&m(v,g?g.concat(x):[x])}),d.pop()}}if(!k.isObject(e))throw new TypeError("data must be an object");return m(e),t}function ip(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(r){return t[r]})}function Xl(e,t){this._pairs=[],e&&xs(e,this,t)}const op=Xl.prototype;op.append=function(t,n){this._pairs.push([t,n])},op.toString=function(t){const n=t?function(r){return t.call(this,r,ip)}:ip;return this._pairs.map(function(i){return n(i[0])+"="+n(i[1])},"").join("&")};function jT(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function sp(e,t,n){if(!t)return e;const r=n&&n.encode||jT;k.isFunction(n)&&(n={serialize:n});const i=n&&n.serialize;let o;if(i?o=i(t,n):o=k.isURLSearchParams(t)?t.toString():new Xl(t,n).toString(r),o){const s=e.indexOf("#");s!==-1&&(e=e.slice(0,s)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class ap{constructor(){this.handlers=[]}use(t,n,r){return this.handlers.push({fulfilled:t,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){k.forEach(this.handlers,function(r){r!==null&&t(r)})}}const lp={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},WT={isBrowser:!0,classes:{URLSearchParams:typeof URLSearchParams<"u"?URLSearchParams:Xl,FormData:typeof FormData<"u"?FormData:null,Blob:typeof Blob<"u"?Blob:null},protocols:["http","https","file","blob","url","data"]},Yl=typeof window<"u"&&typeof document<"u",Ql=typeof navigator=="object"&&navigator||void 0,HT=Yl&&(!Ql||["ReactNative","NativeScript","NS"].indexOf(Ql.product)<0),UT=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",GT=Yl&&window.location.href||"http://localhost",ze={...Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Yl,hasStandardBrowserEnv:HT,hasStandardBrowserWebWorkerEnv:UT,navigator:Ql,origin:GT},Symbol.toStringTag,{value:"Module"})),...WT};function qT(e,t){return xs(e,new ze.classes.URLSearchParams,{visitor:function(n,r,i,o){return ze.isNode&&k.isBuffer(n)?(this.append(r,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)},...t})}function KT(e){return k.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function XT(e){const t={},n=Object.keys(e);let r;const i=n.length;let o;for(r=0;r=n.length;return s=!s&&k.isArray(i)?i.length:s,l?(k.hasOwnProp(i,s)?i[s]=[i[s],r]:i[s]=r,!a):((!i[s]||!k.isObject(i[s]))&&(i[s]=[]),t(n,r,i[s],o)&&k.isArray(i[s])&&(i[s]=XT(i[s])),!a)}if(k.isFormData(e)&&k.isFunction(e.entries)){const n={};return k.forEachEntry(e,(r,i)=>{t(KT(r),i,n,0)}),n}return null}function YT(e,t,n){if(k.isString(e))try{return(t||JSON.parse)(e),k.trim(e)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(e)}const Ai={transitional:lp,adapter:["xhr","http","fetch"],transformRequest:[function(t,n){const r=n.getContentType()||"",i=r.indexOf("application/json")>-1,o=k.isObject(t);if(o&&k.isHTMLForm(t)&&(t=new FormData(t)),k.isFormData(t))return i?JSON.stringify(cp(t)):t;if(k.isArrayBuffer(t)||k.isBuffer(t)||k.isStream(t)||k.isFile(t)||k.isBlob(t)||k.isReadableStream(t))return t;if(k.isArrayBufferView(t))return t.buffer;if(k.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let a;if(o){if(r.indexOf("application/x-www-form-urlencoded")>-1)return qT(t,this.formSerializer).toString();if((a=k.isFileList(t))||r.indexOf("multipart/form-data")>-1){const l=this.env&&this.env.FormData;return xs(a?{"files[]":t}:t,l&&new l,this.formSerializer)}}return o||i?(n.setContentType("application/json",!1),YT(t)):t}],transformResponse:[function(t){const n=this.transitional||Ai.transitional,r=n&&n.forcedJSONParsing,i=this.responseType==="json";if(k.isResponse(t)||k.isReadableStream(t))return t;if(t&&k.isString(t)&&(r&&!this.responseType||i)){const s=!(n&&n.silentJSONParsing)&&i;try{return JSON.parse(t)}catch(a){if(s)throw a.name==="SyntaxError"?Q.from(a,Q.ERR_BAD_RESPONSE,this,null,this.response):a}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:ze.classes.FormData,Blob:ze.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};k.forEach(["delete","get","head","post","put","patch"],e=>{Ai.headers[e]={}});const QT=k.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),JT=e=>{const t={};let n,r,i;return e&&e.split(` -`).forEach(function(s){i=s.indexOf(":"),n=s.substring(0,i).trim().toLowerCase(),r=s.substring(i+1).trim(),!(!n||t[n]&&QT[n])&&(n==="set-cookie"?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)}),t},up=Symbol("internals");function _i(e){return e&&String(e).trim().toLowerCase()}function Cs(e){return e===!1||e==null?e:k.isArray(e)?e.map(Cs):String(e)}function ZT(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}const e2=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Jl(e,t,n,r,i){if(k.isFunction(r))return r.call(this,t,n);if(i&&(t=n),!!k.isString(t)){if(k.isString(r))return t.indexOf(r)!==-1;if(k.isRegExp(r))return r.test(t)}}function t2(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,r)=>n.toUpperCase()+r)}function n2(e,t){const n=k.toCamelCase(" "+t);["get","set","has"].forEach(r=>{Object.defineProperty(e,r+n,{value:function(i,o,s){return this[r].call(this,t,i,o,s)},configurable:!0})})}let Xe=class{constructor(t){t&&this.set(t)}set(t,n,r){const i=this;function o(a,l,c){const u=_i(l);if(!u)throw new Error("header name must be a non-empty string");const d=k.findKey(i,u);(!d||i[d]===void 0||c===!0||c===void 0&&i[d]!==!1)&&(i[d||l]=Cs(a))}const s=(a,l)=>k.forEach(a,(c,u)=>o(c,u,l));if(k.isPlainObject(t)||t instanceof this.constructor)s(t,n);else if(k.isString(t)&&(t=t.trim())&&!e2(t))s(JT(t),n);else if(k.isObject(t)&&k.isIterable(t)){let a={},l,c;for(const u of t){if(!k.isArray(u))throw TypeError("Object iterator must return a key-value pair");a[c=u[0]]=(l=a[c])?k.isArray(l)?[...l,u[1]]:[l,u[1]]:u[1]}s(a,n)}else t!=null&&o(n,t,r);return this}get(t,n){if(t=_i(t),t){const r=k.findKey(this,t);if(r){const i=this[r];if(!n)return i;if(n===!0)return ZT(i);if(k.isFunction(n))return n.call(this,i,r);if(k.isRegExp(n))return n.exec(i);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=_i(t),t){const r=k.findKey(this,t);return!!(r&&this[r]!==void 0&&(!n||Jl(this,this[r],r,n)))}return!1}delete(t,n){const r=this;let i=!1;function o(s){if(s=_i(s),s){const a=k.findKey(r,s);a&&(!n||Jl(r,r[a],a,n))&&(delete r[a],i=!0)}}return k.isArray(t)?t.forEach(o):o(t),i}clear(t){const n=Object.keys(this);let r=n.length,i=!1;for(;r--;){const o=n[r];(!t||Jl(this,this[o],o,t,!0))&&(delete this[o],i=!0)}return i}normalize(t){const n=this,r={};return k.forEach(this,(i,o)=>{const s=k.findKey(r,o);if(s){n[s]=Cs(i),delete n[o];return}const a=t?t2(o):String(o).trim();a!==o&&delete n[o],n[a]=Cs(i),r[a]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return k.forEach(this,(r,i)=>{r!=null&&r!==!1&&(n[i]=t&&k.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` -`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const r=new this(t);return n.forEach(i=>r.set(i)),r}static accessor(t){const r=(this[up]=this[up]={accessors:{}}).accessors,i=this.prototype;function o(s){const a=_i(s);r[a]||(n2(i,s),r[a]=!0)}return k.isArray(t)?t.forEach(o):o(t),this}};Xe.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),k.reduceDescriptors(Xe.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(r){this[n]=r}}}),k.freezeMethods(Xe);function Zl(e,t){const n=this||Ai,r=t||n,i=Xe.from(r.headers);let o=r.data;return k.forEach(e,function(a){o=a.call(n,o,i.normalize(),t?t.status:void 0)}),i.normalize(),o}function dp(e){return!!(e&&e.__CANCEL__)}function Vr(e,t,n){Q.call(this,e??"canceled",Q.ERR_CANCELED,t,n),this.name="CanceledError"}k.inherits(Vr,Q,{__CANCEL__:!0});function hp(e,t,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?e(n):t(new Q("Request failed with status code "+n.status,[Q.ERR_BAD_REQUEST,Q.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function r2(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function i2(e,t){e=e||10;const n=new Array(e),r=new Array(e);let i=0,o=0,s;return t=t!==void 0?t:1e3,function(l){const c=Date.now(),u=r[o];s||(s=c),n[i]=l,r[i]=c;let d=o,h=0;for(;d!==i;)h+=n[d++],d=d%e;if(i=(i+1)%e,i===o&&(o=(o+1)%e),c-s{n=u,i=null,o&&(clearTimeout(o),o=null),e(...c)};return[(...c)=>{const u=Date.now(),d=u-n;d>=r?s(c,u):(i=c,o||(o=setTimeout(()=>{o=null,s(i)},r-d)))},()=>i&&s(i)]}const Ss=(e,t,n=3)=>{let r=0;const i=i2(50,250);return o2(o=>{const s=o.loaded,a=o.lengthComputable?o.total:void 0,l=s-r,c=i(l),u=s<=a;r=s;const d={loaded:s,total:a,progress:a?s/a:void 0,bytes:l,rate:c||void 0,estimated:c&&a&&u?(a-s)/c:void 0,event:o,lengthComputable:a!=null,[t?"download":"upload"]:!0};e(d)},n)},fp=(e,t)=>{const n=e!=null;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},gp=e=>(...t)=>k.asap(()=>e(...t)),s2=ze.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,ze.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(ze.origin),ze.navigator&&/(msie|trident)/i.test(ze.navigator.userAgent)):()=>!0,a2=ze.hasStandardBrowserEnv?{write(e,t,n,r,i,o){const s=[e+"="+encodeURIComponent(t)];k.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),k.isString(r)&&s.push("path="+r),k.isString(i)&&s.push("domain="+i),o===!0&&s.push("secure"),document.cookie=s.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function l2(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function c2(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function pp(e,t,n){let r=!l2(t);return e&&(r||n==!1)?c2(e,t):t}const mp=e=>e instanceof Xe?{...e}:e;function qn(e,t){t=t||{};const n={};function r(c,u,d,h){return k.isPlainObject(c)&&k.isPlainObject(u)?k.merge.call({caseless:h},c,u):k.isPlainObject(u)?k.merge({},u):k.isArray(u)?u.slice():u}function i(c,u,d,h){if(k.isUndefined(u)){if(!k.isUndefined(c))return r(void 0,c,d,h)}else return r(c,u,d,h)}function o(c,u){if(!k.isUndefined(u))return r(void 0,u)}function s(c,u){if(k.isUndefined(u)){if(!k.isUndefined(c))return r(void 0,c)}else return r(void 0,u)}function a(c,u,d){if(d in t)return r(c,u);if(d in e)return r(void 0,c)}const l={url:o,method:o,data:o,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,withXSRFToken:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:a,headers:(c,u,d)=>i(mp(c),mp(u),d,!0)};return k.forEach(Object.keys({...e,...t}),function(u){const d=l[u]||i,h=d(e[u],t[u],u);k.isUndefined(h)&&d!==a||(n[u]=h)}),n}const vp=e=>{const t=qn({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:i,xsrfCookieName:o,headers:s,auth:a}=t;t.headers=s=Xe.from(s),t.url=sp(pp(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),a&&s.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):"")));let l;if(k.isFormData(n)){if(ze.hasStandardBrowserEnv||ze.hasStandardBrowserWebWorkerEnv)s.setContentType(void 0);else if((l=s.getContentType())!==!1){const[c,...u]=l?l.split(";").map(d=>d.trim()).filter(Boolean):[];s.setContentType([c||"multipart/form-data",...u].join("; "))}}if(ze.hasStandardBrowserEnv&&(r&&k.isFunction(r)&&(r=r(t)),r||r!==!1&&s2(t.url))){const c=i&&o&&a2.read(o);c&&s.set(i,c)}return t},u2=typeof XMLHttpRequest<"u"&&function(e){return new Promise(function(n,r){const i=vp(e);let o=i.data;const s=Xe.from(i.headers).normalize();let{responseType:a,onUploadProgress:l,onDownloadProgress:c}=i,u,d,h,m,f;function g(){m&&m(),f&&f(),i.cancelToken&&i.cancelToken.unsubscribe(u),i.signal&&i.signal.removeEventListener("abort",u)}let p=new XMLHttpRequest;p.open(i.method.toUpperCase(),i.url,!0),p.timeout=i.timeout;function v(){if(!p)return;const S=Xe.from("getAllResponseHeaders"in p&&p.getAllResponseHeaders()),w={data:!a||a==="text"||a==="json"?p.responseText:p.response,status:p.status,statusText:p.statusText,headers:S,config:e,request:p};hp(function(_){n(_),g()},function(_){r(_),g()},w),p=null}"onloadend"in p?p.onloadend=v:p.onreadystatechange=function(){!p||p.readyState!==4||p.status===0&&!(p.responseURL&&p.responseURL.indexOf("file:")===0)||setTimeout(v)},p.onabort=function(){p&&(r(new Q("Request aborted",Q.ECONNABORTED,e,p)),p=null)},p.onerror=function(){r(new Q("Network Error",Q.ERR_NETWORK,e,p)),p=null},p.ontimeout=function(){let C=i.timeout?"timeout of "+i.timeout+"ms exceeded":"timeout exceeded";const w=i.transitional||lp;i.timeoutErrorMessage&&(C=i.timeoutErrorMessage),r(new Q(C,w.clarifyTimeoutError?Q.ETIMEDOUT:Q.ECONNABORTED,e,p)),p=null},o===void 0&&s.setContentType(null),"setRequestHeader"in p&&k.forEach(s.toJSON(),function(C,w){p.setRequestHeader(w,C)}),k.isUndefined(i.withCredentials)||(p.withCredentials=!!i.withCredentials),a&&a!=="json"&&(p.responseType=i.responseType),c&&([h,f]=Ss(c,!0),p.addEventListener("progress",h)),l&&p.upload&&([d,m]=Ss(l),p.upload.addEventListener("progress",d),p.upload.addEventListener("loadend",m)),(i.cancelToken||i.signal)&&(u=S=>{p&&(r(!S||S.type?new Vr(null,e,p):S),p.abort(),p=null)},i.cancelToken&&i.cancelToken.subscribe(u),i.signal&&(i.signal.aborted?u():i.signal.addEventListener("abort",u)));const x=r2(i.url);if(x&&ze.protocols.indexOf(x)===-1){r(new Q("Unsupported protocol "+x+":",Q.ERR_BAD_REQUEST,e));return}p.send(o||null)})},d2=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let r=new AbortController,i;const o=function(c){if(!i){i=!0,a();const u=c instanceof Error?c:this.reason;r.abort(u instanceof Q?u:new Vr(u instanceof Error?u.message:u))}};let s=t&&setTimeout(()=>{s=null,o(new Q(`timeout ${t} of ms exceeded`,Q.ETIMEDOUT))},t);const a=()=>{e&&(s&&clearTimeout(s),s=null,e.forEach(c=>{c.unsubscribe?c.unsubscribe(o):c.removeEventListener("abort",o)}),e=null)};e.forEach(c=>c.addEventListener("abort",o));const{signal:l}=r;return l.unsubscribe=()=>k.asap(a),l}},h2=function*(e,t){let n=e.byteLength;if(n{const i=f2(e,t);let o=0,s,a=l=>{s||(s=!0,r&&r(l))};return new ReadableStream({async pull(l){try{const{done:c,value:u}=await i.next();if(c){a(),l.close();return}let d=u.byteLength;if(n){let h=o+=d;n(h)}l.enqueue(new Uint8Array(u))}catch(c){throw a(c),c}},cancel(l){return a(l),i.return()}},{highWaterMark:2})},ws=typeof fetch=="function"&&typeof Request=="function"&&typeof Response=="function",yp=ws&&typeof ReadableStream=="function",p2=ws&&(typeof TextEncoder=="function"?(e=>t=>e.encode(t))(new TextEncoder):async e=>new Uint8Array(await new Response(e).arrayBuffer())),xp=(e,...t)=>{try{return!!e(...t)}catch{return!1}},m2=yp&&xp(()=>{let e=!1;const t=new Request(ze.origin,{body:new ReadableStream,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t}),Cp=64*1024,ec=yp&&xp(()=>k.isReadableStream(new Response("").body)),Es={stream:ec&&(e=>e.body)};ws&&(e=>{["text","arrayBuffer","blob","formData","stream"].forEach(t=>{!Es[t]&&(Es[t]=k.isFunction(e[t])?n=>n[t]():(n,r)=>{throw new Q(`Response type '${t}' is not supported`,Q.ERR_NOT_SUPPORT,r)})})})(new Response);const v2=async e=>{if(e==null)return 0;if(k.isBlob(e))return e.size;if(k.isSpecCompliantForm(e))return(await new Request(ze.origin,{method:"POST",body:e}).arrayBuffer()).byteLength;if(k.isArrayBufferView(e)||k.isArrayBuffer(e))return e.byteLength;if(k.isURLSearchParams(e)&&(e=e+""),k.isString(e))return(await p2(e)).byteLength},b2=async(e,t)=>{const n=k.toFiniteNumber(e.getContentLength());return n??v2(t)},tc={http:MT,xhr:u2,fetch:ws&&(async e=>{let{url:t,method:n,data:r,signal:i,cancelToken:o,timeout:s,onDownloadProgress:a,onUploadProgress:l,responseType:c,headers:u,withCredentials:d="same-origin",fetchOptions:h}=vp(e);c=c?(c+"").toLowerCase():"text";let m=d2([i,o&&o.toAbortSignal()],s),f;const g=m&&m.unsubscribe&&(()=>{m.unsubscribe()});let p;try{if(l&&m2&&n!=="get"&&n!=="head"&&(p=await b2(u,r))!==0){let w=new Request(t,{method:"POST",body:r,duplex:"half"}),P;if(k.isFormData(r)&&(P=w.headers.get("content-type"))&&u.setContentType(P),w.body){const[_,R]=fp(p,Ss(gp(l)));r=bp(w.body,Cp,_,R)}}k.isString(d)||(d=d?"include":"omit");const v="credentials"in Request.prototype;f=new Request(t,{...h,signal:m,method:n.toUpperCase(),headers:u.normalize().toJSON(),body:r,duplex:"half",credentials:v?d:void 0});let x=await fetch(f,h);const S=ec&&(c==="stream"||c==="response");if(ec&&(a||S&&g)){const w={};["status","statusText","headers"].forEach(N=>{w[N]=x[N]});const P=k.toFiniteNumber(x.headers.get("content-length")),[_,R]=a&&fp(P,Ss(gp(a),!0))||[];x=new Response(bp(x.body,Cp,_,()=>{R&&R(),g&&g()}),w)}c=c||"text";let C=await Es[k.findKey(Es,c)||"text"](x,e);return!S&&g&&g(),await new Promise((w,P)=>{hp(w,P,{data:C,headers:Xe.from(x.headers),status:x.status,statusText:x.statusText,config:e,request:f})})}catch(v){throw g&&g(),v&&v.name==="TypeError"&&/Load failed|fetch/i.test(v.message)?Object.assign(new Q("Network Error",Q.ERR_NETWORK,e,f),{cause:v.cause||v}):Q.from(v,v&&v.code,e,f)}})};k.forEach(tc,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const Sp=e=>`- ${e}`,y2=e=>k.isFunction(e)||e===null||e===!1,wp={getAdapter:e=>{e=k.isArray(e)?e:[e];const{length:t}=e;let n,r;const i={};for(let o=0;o`adapter ${a} `+(l===!1?"is not supported by the environment":"is not available in the build"));let s=t?o.length>1?`since : -`+o.map(Sp).join(` -`):" "+Sp(o[0]):"as no adapter specified";throw new Q("There is no suitable adapter to dispatch the request "+s,"ERR_NOT_SUPPORT")}return r},adapters:tc};function nc(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Vr(null,e)}function Ep(e){return nc(e),e.headers=Xe.from(e.headers),e.data=Zl.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),wp.getAdapter(e.adapter||Ai.adapter)(e).then(function(r){return nc(e),r.data=Zl.call(e,e.transformResponse,r),r.headers=Xe.from(r.headers),r},function(r){return dp(r)||(nc(e),r&&r.response&&(r.response.data=Zl.call(e,e.transformResponse,r.response),r.response.headers=Xe.from(r.response.headers))),Promise.reject(r)})}const kp="1.11.0",ks={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{ks[e]=function(r){return typeof r===e||"a"+(t<1?"n ":" ")+e}});const Op={};ks.transitional=function(t,n,r){function i(o,s){return"[Axios v"+kp+"] Transitional option '"+o+"'"+s+(r?". "+r:"")}return(o,s,a)=>{if(t===!1)throw new Q(i(s," has been removed"+(n?" in "+n:"")),Q.ERR_DEPRECATED);return n&&!Op[s]&&(Op[s]=!0,console.warn(i(s," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,s,a):!0}},ks.spelling=function(t){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${t}`),!0)};function x2(e,t,n){if(typeof e!="object")throw new Q("options must be an object",Q.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let i=r.length;for(;i-- >0;){const o=r[i],s=t[o];if(s){const a=e[o],l=a===void 0||s(a,o,e);if(l!==!0)throw new Q("option "+o+" must be "+l,Q.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new Q("Unknown option "+o,Q.ERR_BAD_OPTION)}}const Os={assertOptions:x2,validators:ks},Vt=Os.validators;let Kn=class{constructor(t){this.defaults=t||{},this.interceptors={request:new ap,response:new ap}}async request(t,n){try{return await this._request(t,n)}catch(r){if(r instanceof Error){let i={};Error.captureStackTrace?Error.captureStackTrace(i):i=new Error;const o=i.stack?i.stack.replace(/^.+\n/,""):"";try{r.stack?o&&!String(r.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(r.stack+=` -`+o):r.stack=o}catch{}}throw r}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=qn(this.defaults,n);const{transitional:r,paramsSerializer:i,headers:o}=n;r!==void 0&&Os.assertOptions(r,{silentJSONParsing:Vt.transitional(Vt.boolean),forcedJSONParsing:Vt.transitional(Vt.boolean),clarifyTimeoutError:Vt.transitional(Vt.boolean)},!1),i!=null&&(k.isFunction(i)?n.paramsSerializer={serialize:i}:Os.assertOptions(i,{encode:Vt.function,serialize:Vt.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Os.assertOptions(n,{baseUrl:Vt.spelling("baseURL"),withXsrfToken:Vt.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let s=o&&k.merge(o.common,o[n.method]);o&&k.forEach(["delete","get","head","post","put","patch","common"],f=>{delete o[f]}),n.headers=Xe.concat(s,o);const a=[];let l=!0;this.interceptors.request.forEach(function(g){typeof g.runWhen=="function"&&g.runWhen(n)===!1||(l=l&&g.synchronous,a.unshift(g.fulfilled,g.rejected))});const c=[];this.interceptors.response.forEach(function(g){c.push(g.fulfilled,g.rejected)});let u,d=0,h;if(!l){const f=[Ep.bind(this),void 0];for(f.unshift(...a),f.push(...c),h=f.length,u=Promise.resolve(n);d{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](i);r._listeners=null}),this.promise.then=i=>{let o;const s=new Promise(a=>{r.subscribe(a),o=a}).then(i);return s.cancel=function(){r.unsubscribe(o)},s},t(function(o,s,a){r.reason||(r.reason=new Vr(o,s,a),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=r=>{t.abort(r)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new mb(function(i){t=i}),cancel:t}}};function S2(e){return function(n){return e.apply(null,n)}}function w2(e){return k.isObject(e)&&e.isAxiosError===!0}const rc={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(rc).forEach(([e,t])=>{rc[t]=e});function Ip(e){const t=new Kn(e),n=Ug(Kn.prototype.request,t);return k.extend(n,Kn.prototype,t,{allOwnKeys:!0}),k.extend(n,t,null,{allOwnKeys:!0}),n.create=function(i){return Ip(qn(e,i))},n}const ge=Ip(Ai);ge.Axios=Kn,ge.CanceledError=Vr,ge.CancelToken=C2,ge.isCancel=dp,ge.VERSION=kp,ge.toFormData=xs,ge.AxiosError=Q,ge.Cancel=ge.CanceledError,ge.all=function(t){return Promise.all(t)},ge.spread=S2,ge.isAxiosError=w2,ge.mergeConfig=qn,ge.AxiosHeaders=Xe,ge.formToJSON=e=>cp(k.isHTMLForm(e)?new FormData(e):e),ge.getAdapter=wp.getAdapter,ge.HttpStatusCode=rc,ge.default=ge;const{Axios:E5,AxiosError:k5,CanceledError:O5,isCancel:I5,CancelToken:P5,VERSION:R5,all:T5,Cancel:N5,isAxiosError:A5,spread:_5,toFormData:V5,AxiosHeaders:F5,HttpStatusCode:L5,formToJSON:D5,getAdapter:z5,mergeConfig:M5}=ge;var Is=["light","dark"],ic="(prefers-color-scheme: dark)",E2=typeof window>"u",Pp=O.createContext(void 0),k2=e=>O.useContext(Pp)?e.children:O.createElement(I2,{...e}),O2=["light","dark"],I2=({forcedTheme:e,disableTransitionOnChange:t=!1,enableSystem:n=!0,enableColorScheme:r=!0,storageKey:i="theme",themes:o=O2,defaultTheme:s=n?"system":"light",attribute:a="data-theme",value:l,children:c,nonce:u})=>{let[d,h]=O.useState(()=>Rp(i,s)),[m,f]=O.useState(()=>Rp(i)),g=l?Object.values(l):o,p=O.useCallback(C=>{let w=C;if(!w)return;C==="system"&&n&&(w=Tp());let P=l?l[w]:w,_=t?R2():null,R=document.documentElement;if(a==="class"?(R.classList.remove(...g),P&&R.classList.add(P)):P?R.setAttribute(a,P):R.removeAttribute(a),r){let N=Is.includes(s)?s:null,T=Is.includes(w)?w:N;R.style.colorScheme=T}_==null||_()},[]),v=O.useCallback(C=>{let w=typeof C=="function"?C(C):C;h(w);try{localStorage.setItem(i,w)}catch{}},[e]),x=O.useCallback(C=>{let w=Tp(C);f(w),d==="system"&&n&&!e&&p("system")},[d,e]);O.useEffect(()=>{let C=window.matchMedia(ic);return C.addListener(x),x(C),()=>C.removeListener(x)},[x]),O.useEffect(()=>{let C=w=>{if(w.key!==i)return;let P=w.newValue||s;v(P)};return window.addEventListener("storage",C),()=>window.removeEventListener("storage",C)},[v]),O.useEffect(()=>{p(e??d)},[e,d]);let S=O.useMemo(()=>({theme:d,setTheme:v,forcedTheme:e,resolvedTheme:d==="system"?m:d,themes:n?[...o,"system"]:o,systemTheme:n?m:void 0}),[d,v,e,m,n,o]);return O.createElement(Pp.Provider,{value:S},O.createElement(P2,{forcedTheme:e,disableTransitionOnChange:t,enableSystem:n,enableColorScheme:r,storageKey:i,themes:o,defaultTheme:s,attribute:a,value:l,children:c,attrs:g,nonce:u}),c)},P2=O.memo(({forcedTheme:e,storageKey:t,attribute:n,enableSystem:r,enableColorScheme:i,defaultTheme:o,value:s,attrs:a,nonce:l})=>{let c=o==="system",u=n==="class"?`var d=document.documentElement,c=d.classList;${`c.remove(${a.map(f=>`'${f}'`).join(",")})`};`:`var d=document.documentElement,n='${n}',s='setAttribute';`,d=i?Is.includes(o)&&o?`if(e==='light'||e==='dark'||!e)d.style.colorScheme=e||'${o}'`:"if(e==='light'||e==='dark')d.style.colorScheme=e":"",h=(f,g=!1,p=!0)=>{let v=s?s[f]:f,x=g?f+"|| ''":`'${v}'`,S="";return i&&p&&!g&&Is.includes(f)&&(S+=`d.style.colorScheme = '${f}';`),n==="class"?g||v?S+=`c.add(${x})`:S+="null":v&&(S+=`d[s](n,${x})`),S},m=e?`!function(){${u}${h(e)}}()`:r?`!function(){try{${u}var e=localStorage.getItem('${t}');if('system'===e||(!e&&${c})){var t='${ic}',m=window.matchMedia(t);if(m.media!==t||m.matches){${h("dark")}}else{${h("light")}}}else if(e){${s?`var x=${JSON.stringify(s)};`:""}${h(s?"x[e]":"e",!0)}}${c?"":"else{"+h(o,!1,!1)+"}"}${d}}catch(e){}}()`:`!function(){try{${u}var e=localStorage.getItem('${t}');if(e){${s?`var x=${JSON.stringify(s)};`:""}${h(s?"x[e]":"e",!0)}}else{${h(o,!1,!1)};}${d}}catch(t){}}();`;return O.createElement("script",{nonce:l,dangerouslySetInnerHTML:{__html:m}})}),Rp=(e,t)=>{if(E2)return;let n;try{n=localStorage.getItem(e)||void 0}catch{}return n||t},R2=()=>{let e=document.createElement("style");return e.appendChild(document.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),document.head.appendChild(e),()=>{window.getComputedStyle(document.body),setTimeout(()=>{document.head.removeChild(e)},1)}},Tp=e=>(e||(e=window.matchMedia(ic)),e.matches?"dark":"light");const T2=e=>y.jsx(k2,{attribute:"class",disableTransitionOnChange:!0,...e});/** +)+\\(\\s*min(-device)?-${e}`,"i"),max:new RegExp(`\\(\\s*max(-device)?-${e}`,"i")}),kk=Cf("width"),Ok=Cf("height"),Sf=e=>({isMin:Pf(e.minMax,e.maxMin,e.min),isMax:Pf(e.maxMin,e.minMax,e.max)}),{isMin:Ol,isMax:wf}=Sf(kk),{isMin:Il,isMax:Ef}=Sf(Ok),kf=/print/i,Of=/^print$/i,Ik=/(-?\d*\.?\d+)(ch|em|ex|px|rem)/,Pk=/(\d)/,Ri=Number.MAX_VALUE,Rk={ch:8.8984375,em:16,rem:16,ex:8.296875,px:1};function If(e){const t=Ik.exec(e)||(Ol(e)||Il(e)?Pk.exec(e):null);if(!t)return Ri;if(t[0]==="0")return 0;const n=parseFloat(t[1]),r=t[2];return n*(Rk[r]||1)}function Pf(e,t,n){return r=>e.test(r)||!t.test(r)&&n.test(r)}function Tk(e,t){const n=kf.test(e),r=Of.test(e),i=kf.test(t),o=Of.test(t);return n&&i?!r&&o?1:r&&!o?-1:e.localeCompare(t):n?1:i?-1:null}const Nk=xt((e,t)=>{const n=Tk(e,t);if(n!==null)return n;const r=Ol(e)||Il(e),i=wf(e)||Ef(e),o=Ol(t)||Il(t),s=wf(t)||Ef(t);if(r&&s)return-1;if(i&&o)return 1;const a=If(e),l=If(t);return a===Ri&&l===Ri?e.localeCompare(t):a===Ri?1:l===Ri?-1:a!==l?a>l?i?-1:1:i?1:-1:e.localeCompare(t)});function Rf(e){return e.sort(([t],[n])=>Nk(t,n))}function Tf(e){const t=[],n=[],r={};for(const[s,a]of Object.entries(e))s.startsWith("@media")?t.push([s,a]):s.startsWith("@container")?n.push([s,a]):He(a)?r[s]=Tf(a):r[s]=a;const i=Rf(t),o=Rf(n);return{...r,...Object.fromEntries(i),...Object.fromEntries(o)}}const Nf=/\s*!(important)?/i,Ak=e=>It(e)?Nf.test(e):!1,_k=e=>It(e)?e.replace(Nf,"").trim():e;function Af(e){const{transform:t,conditions:n,normalize:r}=e,i=Lk(e);return xt(function(...s){const a=i(...s),l=r(a),c=Object.create(null);return _t(l,(u,d)=>{const h=Ak(u);if(u==null)return;const[m,...f]=n.sort(d).map(n.resolve);h&&(u=_k(u));let g=t(m,u)??Object.create(null);g=_t(g,p=>It(p)&&h?`${p} !important`:p,{getKey:p=>n.expandAtRule(p)}),Vk(c,f.flat(),g)}),Tf(c)})}function Vk(e,t,n){let r=e;for(const i of t)i&&(r[i]||(r[i]=Object.create(null)),r=r[i]);Rr(r,n)}function Fk(...e){return e.filter(t=>He(t)&&Object.keys(si(t)).length>0)}function Lk(e){function t(n){const r=Fk(...n);return r.length===1?r:r.map(i=>e.normalize(i))}return xt(function(...r){return Rr({},...t(r))})}const _f=e=>({base:{},variants:{},defaultVariants:{},compoundVariants:[],...e});function Dk(e){const{css:t,conditions:n,normalize:r,layers:i}=e;function o(a={}){const{base:l,variants:c,defaultVariants:u,compoundVariants:d}=_f(a),h=Af({conditions:n,normalize:r,transform(C,S){var y;return(y=c[C])==null?void 0:y[S]}}),m=(C={})=>{const S=r({...u,...si(C)});let y={...l};Rr(y,h(S));const k=s(d,S);return i.wrap("recipes",t(y,k))},f=Object.keys(c),g=C=>{const S=of(C,["recipe"]),[y,k]=dr(S,f);return f.includes("colorPalette")||(y.colorPalette=C.colorPalette||u.colorPalette),f.includes("orientation")&&(k.orientation=C.orientation),[y,k]},p=Object.fromEntries(Object.entries(c).map(([C,S])=>[C,Object.keys(S)]));return Object.assign(C=>t(m(C)),{className:a.className,__cva__:!0,variantMap:p,variantKeys:f,raw:m,config:a,splitVariantProps:g,merge(C){return o(zk(e)(this,C))}})}function s(a,l){let c={};return a.forEach(u=>{Object.entries(u).every(([h,m])=>h==="css"?!0:(Array.isArray(m)?m:[m]).some(g=>l[h]===g))&&(c=t(c,u.css))}),c}return o}function zk(e){const{css:t}=e;return function(r,i){const o=_f(i.config),s=Jc(r.variantKeys,Object.keys(i.variants)),a=t(r.base,o.base),l=Object.fromEntries(s.map(h=>[h,t(r.config.variants[h],o.variants[h])])),c=Rr(r.config.defaultVariants,o.defaultVariants),u=[...r.compoundVariants,...o.compoundVariants];return{className:st(r.className,i.className),base:a,variants:l,defaultVariants:c,compoundVariants:u}}}const Mk={reset:"reset",base:"base",tokens:"tokens",recipes:"recipes"},Vf={reset:0,base:1,tokens:2,recipes:3};function $k(e){const t=e.layers??Mk,r=Object.values(t).sort((i,o)=>Vf[i]-Vf[o]);return{names:r,atRule:`@layer ${r.join(", ")};`,wrap(i,o){return e.disableLayers?o:{[`@layer ${t[i]}`]:o}}}}function Bk(e){const{utility:t,normalize:n}=e,{hasShorthand:r,resolveShorthand:i}=t;return function(o){return _t(o,n,{stop:s=>Array.isArray(s),getKey:r?i:void 0})}}function jk(e){const{preflight:t}=e;if(!t)return{};const{scope:n="",level:r="parent"}=He(t)?t:{};let i="";n&&r==="parent"?i=`${n} `:n&&r==="element"&&(i=`&${n}`);const o={"*":{margin:"0px",padding:"0px",font:"inherit",wordWrap:"break-word",WebkitTapHighlightColor:"transparent"},"*, *::before, *::after, *::backdrop":{boxSizing:"border-box",borderWidth:"0px",borderStyle:"solid",borderColor:"var(--global-color-border, currentColor)"},hr:{height:"0px",color:"inherit",borderTopWidth:"1px"},body:{minHeight:"100dvh",position:"relative"},img:{borderStyle:"none"},"img, svg, video, canvas, audio, iframe, embed, object":{display:"block",verticalAlign:"middle"},iframe:{border:"none"},"img, video":{maxWidth:"100%",height:"auto"},"p, h1, h2, h3, h4, h5, h6":{overflowWrap:"break-word"},"ol, ul":{listStyle:"none"},"code, kbd, pre, samp":{fontSize:"1em"},"button, [type='button'], [type='reset'], [type='submit']":{WebkitAppearance:"button",backgroundColor:"transparent",backgroundImage:"none"},"button, input, optgroup, select, textarea":{color:"inherit"},"button, select":{textTransform:"none"},table:{textIndent:"0px",borderColor:"inherit",borderCollapse:"collapse"},"*::placeholder":{opacity:"unset",color:"#9ca3af",userSelect:"none"},textarea:{resize:"vertical"},summary:{display:"list-item"},small:{fontSize:"80%"},"sub, sup":{fontSize:"75%",lineHeight:0,position:"relative",verticalAlign:"baseline"},sub:{bottom:"-0.25em"},sup:{top:"-0.5em"},dialog:{padding:"0px"},a:{color:"inherit",textDecoration:"inherit"},"abbr:where([title])":{textDecoration:"underline dotted"},"b, strong":{fontWeight:"bolder"},"code, kbd, samp, pre":{fontSize:"1em","--font-mono-fallback":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New'",fontFamily:"var(--global-font-mono, var(--font-mono-fallback))"},'input[type="text"], input[type="email"], input[type="search"], input[type="password"]':{WebkitAppearance:"none",MozAppearance:"none"},"input[type='search']":{WebkitAppearance:"textfield",outlineOffset:"-2px"},"::-webkit-search-decoration, ::-webkit-search-cancel-button":{WebkitAppearance:"none"},"::-webkit-file-upload-button":{WebkitAppearance:"button",font:"inherit"},'input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button':{height:"auto"},"input[type='number']":{MozAppearance:"textfield"},":-moz-ui-invalid":{boxShadow:"none"},":-moz-focusring":{outline:"auto"},"[hidden]:where(:not([hidden='until-found']))":{display:"none !important"}},s={[n||"html"]:{lineHeight:1.5,"--font-fallback":"ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",WebkitTextSizeAdjust:"100%",WebkitFontSmoothing:"antialiased",MozOsxFontSmoothing:"grayscale",textRendering:"optimizeLegibility",touchAction:"manipulation",MozTabSize:"4",tabSize:"4",fontFamily:"var(--global-font-body, var(--font-fallback))"}};if(r==="element"){const a=Object.entries(o).reduce((l,[c,u])=>(l[c]={[i]:u},l),{});Object.assign(s,a)}else i?s[i]=o:Object.assign(s,o);return s}function Wk(e){const{conditions:t,isValidProperty:n}=e;return function(i){return _t(i,o=>o,{getKey:(o,s)=>He(s)&&!t.has(o)&&!n(o)?Hk(o).map(a=>"&"+a).join(", "):o})}}function Hk(e){const t=[];let n=0,r="",i=!1;for(let o=0;o{const t=i=>{var o;return{base:((o=e.base)==null?void 0:o[i])??{},variants:{},defaultVariants:e.defaultVariants??{},compoundVariants:e.compoundVariants?Gk(e.compoundVariants,i):[]}},r=(e.slots??[]).map(i=>[i,t(i)]);for(const[i,o]of Object.entries(e.variants??{}))for(const[s,a]of Object.entries(o))r.forEach(([l,c])=>{var u;(u=c.variants)[i]??(u[i]={}),c.variants[i][s]=a[l]??{}});return Object.fromEntries(r)},Gk=(e,t)=>e.filter(n=>n.css[t]).map(n=>({...n,css:n.css[t]}));function qk(e){const{cva:t}=e;return function(r={}){const i=Object.entries(Uk(r)).map(([d,h])=>[d,t(h)]);function o(d){const h=i.map(([m,f])=>[m,f(d)]);return Object.fromEntries(h)}const s=r.variants??{},a=Object.keys(s);function l(d){var g;const h=of(d,["recipe"]),[m,f]=dr(h,a);return a.includes("colorPalette")||(m.colorPalette=d.colorPalette||((g=r.defaultVariants)==null?void 0:g.colorPalette)),a.includes("orientation")&&(f.orientation=d.orientation),[m,f]}const c=Object.fromEntries(Object.entries(s).map(([d,h])=>[d,Object.keys(h)]));let u={};return r.className&&(u=Object.fromEntries(r.slots.map(d=>[d,`${r.className}__${d}`]))),Object.assign(o,{variantMap:c,variantKeys:a,splitVariantProps:l,classNameMap:u})}}const Kk=()=>e=>Array.from(new Set(e)),Xk=/([\0-\x1f\x7f]|^-?\d)|^-$|^-|[^\x80-\uFFFF\w-]/g,Yk=function(e,t){return t?e==="\0"?"�":e==="-"&&e.length===1?"\\-":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16):"\\"+e},Ff=e=>(e+"").replace(Xk,Yk),Lf=(e,t)=>{let n="",r=0,i="char",o="",s="";const a=[];for(;r{let t=0;const n=["("];for(;t{n instanceof Map?t[r]=Object.fromEntries(n):t[r]=n}),t}const zf=/({([^}]*)})/g,Jk=/[{}]/g,Zk=/\w+\.\w+/,Mf=e=>{if(!It(e))return[];const t=e.match(zf);return t?t.map(n=>n.replace(Jk,"")).map(n=>n.trim()):[]},eO=e=>zf.test(e);function $f(e){var n,r,i;if(!((n=e.extensions)!=null&&n.references))return((i=(r=e.extensions)==null?void 0:r.cssVar)==null?void 0:i.ref)??e.value;const t=e.extensions.references??{};return e.value=Object.keys(t).reduce((o,s)=>{const a=t[s];if(a.extensions.conditions)return o;const l=$f(a);return o.replace(`{${s}}`,l)},e.value),delete e.extensions.references,e.value}function Bf(e){return He(e)&&e.reference?e.reference:String(e)}const ds=(e,...t)=>t.map(Bf).join(` ${e} `).replace(/calc/g,""),jf=(...e)=>`calc(${ds("+",...e)})`,Wf=(...e)=>`calc(${ds("-",...e)})`,Pl=(...e)=>`calc(${ds("*",...e)})`,Hf=(...e)=>`calc(${ds("/",...e)})`,Uf=e=>{const t=Bf(e);return t!=null&&!Number.isNaN(parseFloat(t))?String(t).startsWith("-")?String(t).slice(1):`-${t}`:Pl(t,-1)},Vr=Object.assign(e=>({add:(...t)=>Vr(jf(e,...t)),subtract:(...t)=>Vr(Wf(e,...t)),multiply:(...t)=>Vr(Pl(e,...t)),divide:(...t)=>Vr(Hf(e,...t)),negate:()=>Vr(Uf(e)),toString:()=>e.toString()}),{add:jf,subtract:Wf,multiply:Pl,divide:Hf,negate:Uf}),tO={enforce:"pre",transform(e){const{prefix:t,allTokens:n,formatCssVar:r,formatTokenName:i,registerToken:o}=e;n.filter(({extensions:a})=>a.category==="spacing").forEach(a=>{const l=a.path.slice(),c=r(l,t);if(It(a.value)&&a.value==="0rem")return;const u=structuredClone(a);Object.assign(u.extensions,{negative:!0,prop:`-${a.extensions.prop}`,originalPath:l}),u.value=Vr.negate(c.ref);const d=u.path[u.path.length-1];d!=null&&(u.path[u.path.length-1]=`-${d}`),u.path&&(u.name=i(u.path)),o(u)})}},nO=new Set(["spacing","sizes","borderWidths","fontSizes","radii"]),rO=[tO,{enforce:"post",transform(e){const{allTokens:t,registerToken:n,formatTokenName:r}=e,i=t.filter(({extensions:a})=>a.category==="colors"),o=new Map,s=new Map;i.forEach(a=>{const{colorPalette:l}=a.extensions;l&&(l.keys.forEach(c=>{o.set(r(c),c)}),l.roots.forEach(c=>{var h;const u=r(c),d=s.get(u)||[];if(d.push(a),s.set(u,d),a.extensions.default&&c.length===1){const m=(h=l.keys[0])==null?void 0:h.filter(Boolean);if(!m.length)return;const f=c.concat(m);o.set(r(f),[])}}))}),o.forEach(a=>{const l=["colors","colorPalette",...a].filter(Boolean),c=r(l),u=r(l.slice(1));n({name:c,value:c,originalValue:c,path:l,extensions:{condition:"base",originalPath:l,category:"colors",prop:u,virtual:!0}},"pre")})}},{enforce:"post",transform(e){e.allTokens.filter(n=>nO.has(n.extensions.category)&&!n.extensions.negative).forEach(n=>{Object.assign(n.extensions,{pixelValue:yf(n.value)})})}},{enforce:"post",transform(e){e.allTokens=e.allTokens.filter(t=>t.value!=="")}}],iO=[{type:"extensions",enforce:"pre",name:"tokens/css-var",transform(e,t){const{prefix:n,formatCssVar:r}=t,{negative:i,originalPath:o}=e.extensions,s=i?o:e.path;return{cssVar:r(s.filter(Boolean),n)}}},{enforce:"post",type:"value",name:"tokens/conditionals",transform(e,t){const{prefix:n,formatCssVar:r}=t,i=Mf(e.value);return i.length&&i.forEach(o=>{const s=r(o.split("."),n);e.value=e.value.replace(`{${s.ref}}`,s)}),e.value}},{type:"extensions",enforce:"pre",name:"tokens/colors/colorPalette",match(e){return e.extensions.category==="colors"&&!e.extensions.virtual},transform(e,t){let n=e.path.slice();if(n.pop(),n.shift(),n.length===0){const a=[...e.path];a.shift(),n=a}if(n.length===0)return{};const r=n.reduce((a,l,c,u)=>{const d=u.slice(0,c+1);return a.push(d),a},[]),i=n[0],o=t.formatTokenName(n),s=e.path.slice(e.path.indexOf(i)+1).reduce((a,l,c,u)=>(a.push(u.slice(c)),a),[]);return s.length===0&&s.push([""]),{colorPalette:{value:o,roots:r,keys:s}}}}],Gf=e=>He(e)&&Object.prototype.hasOwnProperty.call(e,"value");function oO(e){return e?{breakpoints:sf(e,t=>({value:t})),sizes:Object.fromEntries(Object.entries(e).map(([t,n])=>[`breakpoint-${t}`,{value:n}]))}:{breakpoints:{},sizes:{}}}function sO(e){const{prefix:t="",tokens:n={},semanticTokens:r={},breakpoints:i={}}=e,o=D=>D.join("."),s=(D,L)=>cf(D.join("-"),{prefix:L}),a=[],l=new Map,c=new Map,u=new Map,d=new Map,h=new Map,m=new Map,f=new Map,g=new Map,p=[];function b(D,L){a.push(D),l.set(D.name,D),L&&g.forEach(ne=>{ne.enforce===L&&U(ne,D)})}const C=oO(i),S=si({...n,breakpoints:C.breakpoints,sizes:{...n.sizes,...C.sizes}});function y(){_t(S,(D,L)=>{const ne=L.includes("DEFAULT");L=qf(L);const de=L[0],Ee=o(L),Le=It(D)?{value:D}:D,Jt={value:Le.value,originalValue:Le.value,name:Ee,path:L,extensions:{condition:"base",originalPath:L,category:de,prop:o(L.slice(1))}};ne&&(Jt.extensions.default=!0),b(Jt)},{stop:Gf}),_t(r,(D,L)=>{const ne=L.includes("DEFAULT");L=Kf(qf(L));const de=L[0],Ee=o(L),Le=It(D.value)?{value:{base:D.value}}:D,Jt={value:Le.value.base||"",originalValue:Le.value.base||"",name:Ee,path:L,extensions:{originalPath:L,category:de,conditions:Le.value,condition:"base",prop:o(L.slice(1))}};ne&&(Jt.extensions.default=!0),b(Jt)},{stop:Gf})}function k(D){return l.get(D)}function R(D){const{condition:L}=D.extensions;L&&(c.has(L)||c.set(L,new Set),c.get(L).add(D))}function A(D){const{category:L,prop:ne}=D.extensions;L&&(f.has(L)||f.set(L,new Map),f.get(L).set(ne,D))}function T(D){const{condition:L,negative:ne,virtual:de,cssVar:Ee}=D.extensions;ne||de||!L||!Ee||(u.has(L)||u.set(L,new Map),u.get(L).set(Ee.var,D.value))}function N(D){const{category:L,prop:ne,cssVar:de,negative:Ee}=D.extensions;if(!L)return;m.has(L)||m.set(L,new Map);const Le=Ee?D.extensions.conditions?D.originalValue:D.value:de.ref;m.get(L).set(ne,Le),h.set([L,ne].join("."),Le)}function I(D){const{colorPalette:L,virtual:ne,default:de}=D.extensions;!L||ne||L.roots.forEach(Ee=>{var ub;const Le=o(Ee);d.has(Le)||d.set(Le,new Map);const Jt=lO([...D.path],[...Ee]),Bs=o(Jt),Zr=k(Bs);if(!Zr||!Zr.extensions.cssVar)return;const{var:XA}=Zr.extensions.cssVar;if(d.get(Le).set(XA,D.extensions.cssVar.ref),de&&Ee.length===1){const YA=o(["colors","colorPalette"]),db=k(YA);if(!db)return;const QA=o(D.path),hb=k(QA);if(!hb)return;const fb=(ub=L.keys[0])==null?void 0:ub.filter(Boolean);if(!fb.length)return;const gc=o(Ee.concat(fb));d.has(gc)||d.set(gc,new Map),d.get(gc).set(db.extensions.cssVar.var,hb.extensions.cssVar.ref)}})}let B={};function P(){a.forEach(D=>{R(D),A(D),T(D),N(D),I(D)}),B=Df(m)}const F=(D,L)=>{var Zr;if(!D||typeof D!="string")return{invalid:!0,value:D};const[ne,de]=D.split("/");if(!ne||!de)return{invalid:!0,value:ne};const Ee=L(ne),Le=(Zr=k(`opacity.${de}`))==null?void 0:Zr.value;if(!Le&&isNaN(Number(de)))return{invalid:!0,value:ne};const Jt=Le?Number(Le)*100+"%":`${de}%`,Bs=Ee??ne;return{invalid:!1,color:Bs,value:`color-mix(in srgb, ${Bs} ${Jt}, transparent)`}},X=xt((D,L)=>h.get(D)??L),z=xt(D=>B[D]||null),_=xt(D=>Lf(D,L=>{if(!L)return;if(L.includes("/")){const de=F(L,Ee=>X(Ee));if(de.invalid)throw new Error("Invalid color mix at "+L+": "+de.value);return de.value}const ne=X(L);return ne||(Zk.test(L)?Ff(L):L)})),j={prefix:t,allTokens:a,tokenMap:l,registerToken:b,getByName:k,formatTokenName:o,formatCssVar:s,flatMap:h,cssVarMap:u,categoryMap:f,colorPaletteMap:d,getVar:X,getCategoryValues:z,expandReferenceInValue:_};function W(...D){D.forEach(L=>{g.set(L.name,L)})}function M(...D){p.push(...D)}function U(D,L){if(L.extensions.references||ua(D.match)&&!D.match(L))return;const de=(Ee=>D.transform(Ee,j))(L);switch(!0){case D.type==="extensions":Object.assign(L.extensions,de);break;case D.type==="value":L.value=de;break;default:L[D.type]=de;break}}function G(D){p.forEach(L=>{L.enforce===D&&L.transform(j)})}function re(D){g.forEach(L=>{L.enforce===D&&a.forEach(ne=>{U(L,ne)})})}function gt(){a.forEach(D=>{const L=aO(D);!L||L.length===0||L.forEach(ne=>{b(ne)})})}function Mt(D){return Mf(D).map(ne=>k(ne)).filter(Boolean)}function Qt(){a.forEach(D=>{if(!eO(D.value))return;const L=Mt(D.value);D.extensions.references=L.reduce((ne,de)=>(ne[de.name]=de,ne),{})})}function fc(){a.forEach(D=>{$f(D)})}function KA(){G("pre"),re("pre"),gt(),Qt(),fc(),G("post"),re("post"),P()}return y(),W(...iO),M(...rO),KA(),j}function qf(e){return e[0]==="DEFAULT"?e:e.filter(t=>t!=="DEFAULT")}function Kf(e){return e.filter(t=>t!=="base")}function aO(e){if(!e.extensions.conditions)return;const{conditions:t}=e.extensions,n=[];return _t(t,(r,i)=>{const o=Kf(i);if(!o.length)return;const s=structuredClone(e);s.value=r,s.extensions.condition=o.join(":"),n.push(s)}),n}function lO(e,t){const n=e.findIndex((r,i)=>t.every((o,s)=>e[i+s]===o));return n===-1||(e.splice(n,t.length),e.splice(n,0,"colorPalette")),e}Kk()(["aspectRatios","zIndex","opacity","colors","fonts","fontSizes","fontWeights","lineHeights","letterSpacings","sizes","shadows","spacing","radii","cursor","borders","borderWidths","borderStyles","durations","easings","animations","blurs","gradients","breakpoints","assets"]);function g_(e){return e}function cO(e){return Object.fromEntries(Object.entries(e).map(([t,n])=>[t,n]))}function uO(e){const t=cO(e.config),n=e.tokens,r=new Map,i=new Map;function o(T,N){t[T]=N,s(T,N)}const s=(T,N)=>{const I=g(N);I&&(i.set(T,I),d(T,N))},a=()=>{for(const[T,N]of Object.entries(t))N&&s(T,N)},l=()=>{for(const[T,N]of Object.entries(t)){const{shorthand:I}=N??{};if(!I)continue;(Array.isArray(I)?I:[I]).forEach(P=>r.set(P,T))}},c=()=>{const T=Df(n.colorPaletteMap);o("colorPalette",{values:Object.keys(T),transform:xt(N=>T[N])})},u=new Map,d=(T,N)=>{if(!N)return;const I=g(N,P=>`type:Tokens["${P}"]`);if(typeof I=="object"&&I.type){u.set(T,new Set([`type:${I.type}`]));return}if(I){const P=new Set(Object.keys(I));u.set(T,P)}const B=u.get(T)??new Set;N.property&&u.set(T,B.add(`CssProperties["${N.property}"]`))},h=()=>{for(const[T,N]of Object.entries(t))N&&d(T,N)},m=(T,N)=>{const I=u.get(T)??new Set;u.set(T,new Set([...I,...N]))},f=()=>{const T=new Map;for(const[N,I]of u.entries()){if(I.size===0){T.set(N,["string"]);continue}const B=Array.from(I).map(P=>P.startsWith("CssProperties")?P:P.startsWith("type:")?P.replace("type:",""):JSON.stringify(P));T.set(N,B)}return T},g=(T,N)=>{const{values:I}=T,B=P=>{const F=N==null?void 0:N(P);return F?{[F]:F}:void 0};return It(I)?(B==null?void 0:B(I))??n.getCategoryValues(I)??{}:Array.isArray(I)?I.reduce((P,F)=>(P[F]=F,P),{}):ua(I)?I(N?B:n.getCategoryValues):I},p=xt((T,N)=>({[T]:T.startsWith("--")?n.getVar(N,N):N})),b=Object.assign(n.getVar,{raw:T=>n.getByName(T)}),C=xt((T,N)=>{var X;const I=k(T);It(N)&&!N.includes("_EMO_")&&(N=n.expandReferenceInValue(N));const B=t[I];if(!B)return p(I,N);const P=(X=i.get(I))==null?void 0:X[N];if(!B.transform)return p(T,P??N);const F=z=>UE(z,b);return B.transform(P??N,{raw:N,token:b,utils:{colorMix:F}})});function S(){l(),c(),a(),h()}S();const y=r.size>0,k=xt(T=>r.get(T)??T);return{keys:()=>[...Array.from(r.keys()),...Object.keys(t)],hasShorthand:y,transform:C,shorthands:r,resolveShorthand:k,register:o,getTypes:f,addPropertyType:m}}const qe={};function Xf(...e){const t=af(...e),{theme:n={},utilities:r={},globalCss:i={},cssVarsRoot:o=":where(:root, :host)",cssVarsPrefix:s="chakra",preflight:a}=t,l=$k(t),c=sO({breakpoints:n.breakpoints,tokens:n.tokens,semanticTokens:n.semanticTokens,prefix:s}),u=xk(n.breakpoints??qe),d=Ek({conditions:t.conditions??qe,breakpoints:u}),h=uO({config:r,tokens:c});function m(){const{textStyles:M,layerStyles:U,animationStyles:G}=n,re=si({textStyle:M,layerStyle:U,animationStyle:G});for(const[gt,Mt]of Object.entries(re)){const Qt=hf(Mt??qe,Yf);h.register(gt,{values:Object.keys(Qt),transform(fc){return S(Qt[fc])}})}}m(),h.addPropertyType("animationName",Object.keys(n.keyframes??qe));const f=new Set(["css",...h.keys(),...d.keys()]),g=xt(M=>f.has(M)||pk(M)),p=M=>Array.isArray(M)?M.reduce((U,G,re)=>{const gt=d.breakpoints[re];return G!=null&&(U[gt]=G),U},{}):M,b=Bk({utility:h,normalize:p}),C=Wk({conditions:d,isValidProperty:g}),S=Af({transform:h.transform,conditions:d,normalize:b}),y=Dk({css:S,conditions:d,normalize:b,layers:l}),k=qk({cva:y});function R(){const M={};for(const[U,G]of c.cssVarMap.entries()){const re=Object.fromEntries(G);if(Object.keys(re).length===0)continue;const gt=U==="base"?o:d.resolve(U),Mt=gt.startsWith("@"),Qt=S(C({[gt]:Mt?{[o]:re}:re}));Rr(M,Qt)}return l.wrap("tokens",M)}function A(){const M=Object.fromEntries(Object.entries(n.keyframes??qe).map(([G,re])=>[`@keyframes ${G}`,re])),U=Object.assign({},M,S(C(i)));return l.wrap("base",U)}function T(M){return dr(M,g)}function N(){const M=jk({preflight:a});return l.wrap("reset",M)}const I=dO(c),B=(M,U)=>{var G;return((G=I.get(M))==null?void 0:G.value)||U};B.var=(M,U)=>{var G;return((G=I.get(M))==null?void 0:G.variable)||U};function P(M,U){var G;return((G=n.recipes)==null?void 0:G[M])??U}function F(M,U){var G;return((G=n.slotRecipes)==null?void 0:G[M])??U}function X(M){return Object.hasOwnProperty.call(n.recipes??qe,M)}function z(M){return Object.hasOwnProperty.call(n.slotRecipes??qe,M)}function _(M){return X(M)||z(M)}const j=[N(),A(),R()],W={layerStyles:Rl(n.layerStyles??qe),textStyles:Rl(n.textStyles??qe),animationStyles:Rl(n.animationStyles??qe),tokens:Qf(c,Object.keys(n.tokens??qe),(M,U)=>!M.extensions.conditions&&!U.includes("colorPalette")),semanticTokens:Qf(c,Object.keys(n.semanticTokens??qe),M=>!!M.extensions.conditions),keyframes:Jf(n.keyframes??qe),breakpoints:Jf(n.breakpoints??qe)};return{$$chakra:!0,_config:t,_global:j,breakpoints:u,tokens:c,conditions:d,utility:h,token:B,properties:f,layers:l,isValidProperty:g,splitCssProps:T,normalizeValue:p,getTokenCss:R,getGlobalCss:A,getPreflightCss:N,css:S,cva:y,sva:k,getRecipe:P,getSlotRecipe:F,hasRecipe:_,isRecipe:X,isSlotRecipe:z,query:W}}function dO(e){const t=new Map;return e.allTokens.forEach(n=>{const{cssVar:r,virtual:i,conditions:o}=n.extensions,s=o||i?r.ref:n.value;t.set(n.name,{value:s,variable:r.ref})}),t}const Yf=e=>He(e)&&"value"in e,Rl=e=>({list(){return Object.keys(hf(e,Yf))},search(t){return this.list().filter(n=>n.includes(t))}}),Qf=(e,t,n)=>({categoryKeys:t,list(r){var i;return Array.from(((i=e.categoryMap.get(r))==null?void 0:i.entries())??[]).reduce((o,[s,a])=>(n(a,s)&&o.push(s),o),[])},search(r,i){return this.list(r).filter(o=>o.includes(i))}}),Jf=e=>({list(){return Object.keys(e)},search(t){return this.list().filter(n=>n.includes(t))}}),hO={sm:"480px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},Tl="var(--chakra-empty,/*!*/ /*!*/)",fO=XE({"*":{fontFeatureSettings:'"cv11"',"--ring-inset":Tl,"--ring-offset-width":"0px","--ring-offset-color":"#fff","--ring-color":"rgba(66, 153, 225, 0.6)","--ring-offset-shadow":"0 0 #0000","--ring-shadow":"0 0 #0000",...Object.fromEntries(["brightness","contrast","grayscale","hue-rotate","invert","saturate","sepia","drop-shadow"].map(e=>[`--${e}`,Tl])),...Object.fromEntries(["blur","brightness","contrast","grayscale","hue-rotate","invert","opacity","saturate","sepia"].map(e=>[`--backdrop-${e}`,Tl])),"--global-font-mono":"fonts.mono","--global-font-body":"fonts.body","--global-color-border":"colors.border"},html:{color:"fg",bg:"bg",lineHeight:"1.5",colorPalette:"gray"},"*::placeholder, *[data-placeholder]":{color:"fg.muted/80"},"*::selection":{bg:"colorPalette.emphasized/80"}}),gO=JE({"fill.muted":{value:{background:"colorPalette.muted",color:"colorPalette.fg"}},"fill.subtle":{value:{background:"colorPalette.subtle",color:"colorPalette.fg"}},"fill.surface":{value:{background:"colorPalette.subtle",color:"colorPalette.fg",boxShadow:"0 0 0px 1px var(--shadow-color)",boxShadowColor:"colorPalette.muted"}},"fill.solid":{value:{background:"colorPalette.solid",color:"colorPalette.contrast"}},"outline.subtle":{value:{color:"colorPalette.fg",boxShadow:"inset 0 0 0px 1px var(--shadow-color)",boxShadowColor:"colorPalette.subtle"}},"outline.solid":{value:{borderWidth:"1px",borderColor:"colorPalette.solid",color:"colorPalette.fg"}},"indicator.bottom":{value:{position:"relative","--indicator-color-fallback":"colors.colorPalette.solid",_before:{content:'""',position:"absolute",bottom:"var(--indicator-offset-y, 0)",insetInline:"var(--indicator-offset-x, 0)",height:"var(--indicator-thickness, 2px)",background:"var(--indicator-color, var(--indicator-color-fallback))"}}},"indicator.top":{value:{position:"relative","--indicator-color-fallback":"colors.colorPalette.solid",_before:{content:'""',position:"absolute",top:"var(--indicator-offset-y, 0)",insetInline:"var(--indicator-offset-x, 0)",height:"var(--indicator-thickness, 2px)",background:"var(--indicator-color, var(--indicator-color-fallback))"}}},"indicator.start":{value:{position:"relative","--indicator-color-fallback":"colors.colorPalette.solid",_before:{content:'""',position:"absolute",insetInlineStart:"var(--indicator-offset-x, 0)",insetBlock:"var(--indicator-offset-y, 0)",width:"var(--indicator-thickness, 2px)",background:"var(--indicator-color, var(--indicator-color-fallback))"}}},"indicator.end":{value:{position:"relative","--indicator-color-fallback":"colors.colorPalette.solid",_before:{content:'""',position:"absolute",insetInlineEnd:"var(--indicator-offset-x, 0)",insetBlock:"var(--indicator-offset-y, 0)",width:"var(--indicator-thickness, 2px)",background:"var(--indicator-color, var(--indicator-color-fallback))"}}},disabled:{value:{opacity:"0.5",cursor:"not-allowed"}},none:{value:{}}}),pO=QE({"slide-fade-in":{value:{transformOrigin:"var(--transform-origin)","&[data-placement^=top]":{animationName:"slide-from-bottom, fade-in"},"&[data-placement^=bottom]":{animationName:"slide-from-top, fade-in"},"&[data-placement^=left]":{animationName:"slide-from-right, fade-in"},"&[data-placement^=right]":{animationName:"slide-from-left, fade-in"}}},"slide-fade-out":{value:{transformOrigin:"var(--transform-origin)","&[data-placement^=top]":{animationName:"slide-to-bottom, fade-out"},"&[data-placement^=bottom]":{animationName:"slide-to-top, fade-out"},"&[data-placement^=left]":{animationName:"slide-to-right, fade-out"},"&[data-placement^=right]":{animationName:"slide-to-left, fade-out"}}},"scale-fade-in":{value:{transformOrigin:"var(--transform-origin)",animationName:"scale-in, fade-in"}},"scale-fade-out":{value:{transformOrigin:"var(--transform-origin)",animationName:"scale-out, fade-out"}}}),Nl=Se({className:"chakra-badge",base:{display:"inline-flex",alignItems:"center",borderRadius:"l2",gap:"1",fontWeight:"medium",fontVariantNumeric:"tabular-nums",whiteSpace:"nowrap",userSelect:"none"},variants:{variant:{solid:{bg:"colorPalette.solid",color:"colorPalette.contrast"},subtle:{bg:"colorPalette.subtle",color:"colorPalette.fg"},outline:{color:"colorPalette.fg",shadow:"inset 0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted"},surface:{bg:"colorPalette.subtle",color:"colorPalette.fg",shadow:"inset 0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted"},plain:{color:"colorPalette.fg"}},size:{xs:{textStyle:"2xs",px:"1",minH:"4"},sm:{textStyle:"xs",px:"1.5",minH:"5"},md:{textStyle:"sm",px:"2",minH:"6"},lg:{textStyle:"sm",px:"2.5",minH:"7"}}},defaultVariants:{variant:"subtle",size:"sm"}}),mO=Se({className:"chakra-button",base:{display:"inline-flex",appearance:"none",alignItems:"center",justifyContent:"center",userSelect:"none",position:"relative",borderRadius:"l2",whiteSpace:"nowrap",verticalAlign:"middle",borderWidth:"1px",borderColor:"transparent",cursor:"button",flexShrink:"0",outline:"0",lineHeight:"1.2",isolation:"isolate",fontWeight:"medium",transitionProperty:"common",transitionDuration:"moderate",focusVisibleRing:"outside",_disabled:{layerStyle:"disabled"},_icon:{flexShrink:"0"}},variants:{size:{"2xs":{h:"6",minW:"6",textStyle:"xs",px:"2",gap:"1",_icon:{width:"3.5",height:"3.5"}},xs:{h:"8",minW:"8",textStyle:"xs",px:"2.5",gap:"1",_icon:{width:"4",height:"4"}},sm:{h:"9",minW:"9",px:"3.5",textStyle:"sm",gap:"2",_icon:{width:"4",height:"4"}},md:{h:"10",minW:"10",textStyle:"sm",px:"4",gap:"2",_icon:{width:"5",height:"5"}},lg:{h:"11",minW:"11",textStyle:"md",px:"5",gap:"3",_icon:{width:"5",height:"5"}},xl:{h:"12",minW:"12",textStyle:"md",px:"5",gap:"2.5",_icon:{width:"5",height:"5"}},"2xl":{h:"16",minW:"16",textStyle:"lg",px:"7",gap:"3",_icon:{width:"6",height:"6"}}},variant:{solid:{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"transparent",_hover:{bg:"colorPalette.solid/90"},_expanded:{bg:"colorPalette.solid/90"}},subtle:{bg:"colorPalette.subtle",color:"colorPalette.fg",borderColor:"transparent",_hover:{bg:"colorPalette.muted"},_expanded:{bg:"colorPalette.muted"}},surface:{bg:"colorPalette.subtle",color:"colorPalette.fg",shadow:"0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted",_hover:{bg:"colorPalette.muted"},_expanded:{bg:"colorPalette.muted"}},outline:{borderWidth:"1px",borderColor:"colorPalette.muted",color:"colorPalette.fg",_hover:{bg:"colorPalette.subtle"},_expanded:{bg:"colorPalette.subtle"}},ghost:{bg:"transparent",color:"colorPalette.fg",_hover:{bg:"colorPalette.subtle"},_expanded:{bg:"colorPalette.subtle"}},plain:{color:"colorPalette.fg"}}},defaultVariants:{size:"md",variant:"solid"}}),Ve=Se({className:"chakra-checkmark",base:{display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:"0",color:"white",borderWidth:"1px",borderColor:"transparent",borderRadius:"l1",cursor:"checkbox",focusVisibleRing:"outside",_icon:{boxSize:"full"},_invalid:{colorPalette:"red",borderColor:"border.error"},_disabled:{opacity:"0.5",cursor:"disabled"}},variants:{size:{xs:{boxSize:"3"},sm:{boxSize:"4"},md:{boxSize:"5",p:"0.5"},lg:{boxSize:"6",p:"0.5"}},variant:{solid:{borderColor:"border.emphasized","&:is([data-state=checked], [data-state=indeterminate])":{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"colorPalette.solid"}},outline:{borderColor:"border","&:is([data-state=checked], [data-state=indeterminate])":{color:"colorPalette.fg",borderColor:"colorPalette.solid"}},subtle:{bg:"colorPalette.muted",borderColor:"colorPalette.muted","&:is([data-state=checked], [data-state=indeterminate])":{color:"colorPalette.fg"}},plain:{"&:is([data-state=checked], [data-state=indeterminate])":{color:"colorPalette.fg"}},inverted:{borderColor:"border",color:"colorPalette.fg","&:is([data-state=checked], [data-state=indeterminate])":{borderColor:"colorPalette.solid"}}},filled:{true:{bg:"bg"}}},defaultVariants:{variant:"solid",size:"md"}}),{variants:vO,defaultVariants:bO}=Nl,yO=Se({className:"chakra-code",base:{fontFamily:"mono",alignItems:"center",display:"inline-flex",borderRadius:"l2"},variants:vO,defaultVariants:bO}),Zf=Se({className:"color-swatch",base:{boxSize:"var(--swatch-size)",shadow:"inset 0 0 0 1px rgba(0, 0, 0, 0.1)","--checker-size":"8px","--checker-bg":"colors.bg","--checker-fg":"colors.bg.emphasized",background:"linear-gradient(var(--color), var(--color)), repeating-conic-gradient(var(--checker-fg) 0%, var(--checker-fg) 25%, var(--checker-bg) 0%, var(--checker-bg) 50%) 0% 50% / var(--checker-size) var(--checker-size) !important",display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:"0"},variants:{size:{"2xs":{"--swatch-size":"sizes.3.5"},xs:{"--swatch-size":"sizes.4"},sm:{"--swatch-size":"sizes.4.5"},md:{"--swatch-size":"sizes.5"},lg:{"--swatch-size":"sizes.6"},xl:{"--swatch-size":"sizes.7"},"2xl":{"--swatch-size":"sizes.8"},inherit:{"--swatch-size":"inherit"},full:{"--swatch-size":"100%"}},shape:{square:{borderRadius:"none"},circle:{borderRadius:"full"},rounded:{borderRadius:"l1"}}},defaultVariants:{size:"md",shape:"rounded"}}),xO=Se({className:"chakra-container",base:{position:"relative",maxWidth:"8xl",w:"100%",mx:"auto",px:{base:"4",md:"6",lg:"8"}},variants:{centerContent:{true:{display:"flex",flexDirection:"column",alignItems:"center"}},fluid:{true:{maxWidth:"full"}}}}),CO=Se({className:"chakra-heading",base:{fontFamily:"heading",fontWeight:"semibold"},variants:{size:{xs:{textStyle:"xs"},sm:{textStyle:"sm"},md:{textStyle:"md"},lg:{textStyle:"lg"},xl:{textStyle:"xl"},"2xl":{textStyle:"2xl"},"3xl":{textStyle:"3xl"},"4xl":{textStyle:"4xl"},"5xl":{textStyle:"5xl"},"6xl":{textStyle:"6xl"},"7xl":{textStyle:"7xl"}}},defaultVariants:{size:"xl"}}),SO=Se({className:"chakra-icon",base:{display:"inline-block",lineHeight:"1em",flexShrink:"0",color:"currentcolor",verticalAlign:"middle"},variants:{size:{inherit:{},xs:{boxSize:"3"},sm:{boxSize:"4"},md:{boxSize:"5"},lg:{boxSize:"6"},xl:{boxSize:"7"},"2xl":{boxSize:"8"}}},defaultVariants:{size:"inherit"}}),Ce=Se({className:"chakra-input",base:{width:"100%",minWidth:"0",outline:"0",position:"relative",appearance:"none",textAlign:"start",borderRadius:"l2",_disabled:{layerStyle:"disabled"},height:"var(--input-height)",minW:"var(--input-height)","--focus-color":"colors.colorPalette.focusRing","--error-color":"colors.border.error",_invalid:{focusRingColor:"var(--error-color)",borderColor:"var(--error-color)"}},variants:{size:{"2xs":{textStyle:"xs",px:"2","--input-height":"sizes.7"},xs:{textStyle:"xs",px:"2","--input-height":"sizes.8"},sm:{textStyle:"sm",px:"2.5","--input-height":"sizes.9"},md:{textStyle:"sm",px:"3","--input-height":"sizes.10"},lg:{textStyle:"md",px:"4","--input-height":"sizes.11"},xl:{textStyle:"md",px:"4.5","--input-height":"sizes.12"},"2xl":{textStyle:"lg",px:"5","--input-height":"sizes.16"}},variant:{outline:{bg:"transparent",borderWidth:"1px",borderColor:"border",focusVisibleRing:"inside",focusRingColor:"var(--focus-color)"},subtle:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted",focusVisibleRing:"inside",focusRingColor:"var(--focus-color)"},flushed:{bg:"transparent",borderBottomWidth:"1px",borderBottomColor:"border",borderRadius:"0",px:"0",_focusVisible:{borderColor:"var(--focus-color)",boxShadow:"0px 1px 0px 0px var(--focus-color)",_invalid:{borderColor:"var(--error-color)",boxShadow:"0px 1px 0px 0px var(--error-color)"}}}}},defaultVariants:{size:"md",variant:"outline"}}),wO=Se({className:"chakra-input-addon",base:{flex:"0 0 auto",width:"auto",display:"flex",alignItems:"center",whiteSpace:"nowrap",alignSelf:"stretch",borderRadius:"l2"},variants:{size:Ce.variants.size,variant:{outline:{borderWidth:"1px",borderColor:"border",bg:"bg.muted"},subtle:{borderWidth:"1px",borderColor:"transparent",bg:"bg.emphasized"},flushed:{borderBottom:"1px solid",borderColor:"inherit",borderRadius:"0",px:"0",bg:"transparent"}}},defaultVariants:{size:"md",variant:"outline"}}),EO=Se({className:"chakra-kbd",base:{display:"inline-flex",alignItems:"center",fontWeight:"medium",fontFamily:"mono",flexShrink:"0",whiteSpace:"nowrap",wordSpacing:"-0.5em",userSelect:"none",px:"1",borderRadius:"l2"},variants:{variant:{raised:{bg:"colorPalette.subtle",color:"colorPalette.fg",borderWidth:"1px",borderBottomWidth:"2px",borderColor:"colorPalette.muted"},outline:{borderWidth:"1px",color:"colorPalette.fg"},subtle:{bg:"colorPalette.muted",color:"colorPalette.fg"},plain:{color:"colorPalette.fg"}},size:{sm:{textStyle:"xs",height:"4.5"},md:{textStyle:"sm",height:"5"},lg:{textStyle:"md",height:"6"}}},defaultVariants:{size:"md",variant:"raised"}}),kO=Se({className:"chakra-link",base:{display:"inline-flex",alignItems:"center",outline:"none",gap:"1.5",cursor:"pointer",borderRadius:"l1",focusRing:"outside"},variants:{variant:{underline:{color:"colorPalette.fg",textDecoration:"underline",textUnderlineOffset:"3px",textDecorationColor:"currentColor/20"},plain:{color:"colorPalette.fg",_hover:{textDecoration:"underline",textUnderlineOffset:"3px",textDecorationColor:"currentColor/20"}}}},defaultVariants:{variant:"plain"}}),OO=Se({className:"chakra-mark",base:{bg:"transparent",color:"inherit",whiteSpace:"nowrap"},variants:{variant:{subtle:{bg:"colorPalette.subtle",color:"inherit"},solid:{bg:"colorPalette.solid",color:"colorPalette.contrast"},text:{fontWeight:"medium"},plain:{}}}}),Fe=Se({className:"chakra-radiomark",base:{display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:0,verticalAlign:"top",color:"white",borderWidth:"1px",borderColor:"transparent",borderRadius:"full",cursor:"radio",_focusVisible:{outline:"2px solid",outlineColor:"colorPalette.focusRing",outlineOffset:"2px"},_invalid:{colorPalette:"red",borderColor:"red.500"},_disabled:{opacity:"0.5",cursor:"disabled"},"& .dot":{height:"100%",width:"100%",borderRadius:"full",bg:"currentColor",scale:"0.4"}},variants:{variant:{solid:{borderWidth:"1px",borderColor:"border.emphasized",_checked:{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"colorPalette.solid"}},subtle:{borderWidth:"1px",bg:"colorPalette.muted",borderColor:"colorPalette.muted",color:"transparent",_checked:{color:"colorPalette.fg"}},outline:{borderWidth:"1px",borderColor:"inherit",_checked:{color:"colorPalette.fg",borderColor:"colorPalette.solid"},"& .dot":{scale:"0.6"}},inverted:{bg:"bg",borderWidth:"1px",borderColor:"inherit",_checked:{color:"colorPalette.solid",borderColor:"currentcolor"}}},size:{xs:{boxSize:"3"},sm:{boxSize:"4"},md:{boxSize:"5"},lg:{boxSize:"6"}},filled:{true:{bg:"bg"}}},defaultVariants:{variant:"solid",size:"md"}}),IO=Se({className:"chakra-separator",base:{display:"block",borderColor:"border"},variants:{variant:{solid:{borderStyle:"solid"},dashed:{borderStyle:"dashed"},dotted:{borderStyle:"dotted"}},orientation:{vertical:{borderInlineStartWidth:"var(--separator-thickness)"},horizontal:{borderTopWidth:"var(--separator-thickness)"}},size:{xs:{"--separator-thickness":"0.5px"},sm:{"--separator-thickness":"1px"},md:{"--separator-thickness":"2px"},lg:{"--separator-thickness":"3px"}}},defaultVariants:{size:"sm",variant:"solid",orientation:"horizontal"}}),PO=Se({className:"chakra-skeleton",base:{},variants:{loading:{true:{borderRadius:"l2",boxShadow:"none",backgroundClip:"padding-box",cursor:"default",color:"transparent",pointerEvents:"none",userSelect:"none",flexShrink:"0","&::before, &::after, *":{visibility:"hidden"}},false:{background:"unset",animation:"fade-in var(--fade-duration, 0.1s) ease-out !important"}},variant:{pulse:{background:"bg.emphasized",animation:"pulse",animationDuration:"var(--duration, 1.2s)"},shine:{"--animate-from":"200%","--animate-to":"-200%","--start-color":"colors.bg.muted","--end-color":"colors.bg.emphasized",backgroundImage:"linear-gradient(270deg,var(--start-color),var(--end-color),var(--end-color),var(--start-color))",backgroundSize:"400% 100%",animation:"bg-position var(--duration, 5s) ease-in-out infinite"},none:{animation:"none"}}},defaultVariants:{variant:"pulse",loading:!0}}),RO=Se({className:"chakra-skip-nav",base:{display:"inline-flex",bg:"bg.panel",padding:"2.5",borderRadius:"l2",fontWeight:"semibold",focusVisibleRing:"outside",textStyle:"sm",userSelect:"none",border:"0",height:"1px",width:"1px",margin:"-1px",outline:"0",overflow:"hidden",position:"absolute",clip:"rect(0 0 0 0)",_focusVisible:{clip:"auto",width:"auto",height:"auto",position:"fixed",top:"6",insetStart:"6"}}}),TO=Se({className:"chakra-spinner",base:{display:"inline-block",borderColor:"currentColor",borderStyle:"solid",borderWidth:"2px",borderRadius:"full",width:"var(--spinner-size)",height:"var(--spinner-size)",animation:"spin",animationDuration:"slowest","--spinner-track-color":"transparent",borderBottomColor:"var(--spinner-track-color)",borderInlineStartColor:"var(--spinner-track-color)"},variants:{size:{inherit:{"--spinner-size":"1em"},xs:{"--spinner-size":"sizes.3"},sm:{"--spinner-size":"sizes.4"},md:{"--spinner-size":"sizes.5"},lg:{"--spinner-size":"sizes.8"},xl:{"--spinner-size":"sizes.10"}}},defaultVariants:{size:"md"}}),NO=Se({className:"chakra-textarea",base:{width:"100%",minWidth:"0",outline:"0",position:"relative",appearance:"none",textAlign:"start",borderRadius:"l2",_disabled:{layerStyle:"disabled"},"--focus-color":"colors.colorPalette.focusRing","--error-color":"colors.border.error",_invalid:{focusRingColor:"var(--error-color)",borderColor:"var(--error-color)"}},variants:{size:{xs:{textStyle:"xs",px:"2",py:"1.5",scrollPaddingBottom:"1.5"},sm:{textStyle:"sm",px:"2.5",py:"2",scrollPaddingBottom:"2"},md:{textStyle:"sm",px:"3",py:"2",scrollPaddingBottom:"2"},lg:{textStyle:"md",px:"4",py:"3",scrollPaddingBottom:"3"},xl:{textStyle:"md",px:"4.5",py:"3.5",scrollPaddingBottom:"3.5"}},variant:{outline:{bg:"transparent",borderWidth:"1px",borderColor:"border",focusVisibleRing:"inside"},subtle:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted",focusVisibleRing:"inside"},flushed:{bg:"transparent",borderBottomWidth:"1px",borderBottomColor:"border",borderRadius:"0",px:"0",_focusVisible:{borderColor:"var(--focus-color)",boxShadow:"0px 1px 0px 0px var(--focus-color)"}}}},defaultVariants:{size:"md",variant:"outline"}}),AO={badge:Nl,button:mO,code:yO,container:xO,heading:CO,input:Ce,inputAddon:wO,kbd:EO,link:kO,mark:OO,separator:IO,skeleton:PO,skipNavLink:RO,spinner:TO,textarea:NO,icon:SO,checkmark:Ve,radiomark:Fe,colorSwatch:Zf},_O=Cl.colors({bg:{DEFAULT:{value:{_light:"{colors.white}",_dark:"{colors.black}"}},subtle:{value:{_light:"{colors.gray.50}",_dark:"{colors.gray.950}"}},muted:{value:{_light:"{colors.gray.100}",_dark:"{colors.gray.900}"}},emphasized:{value:{_light:"{colors.gray.200}",_dark:"{colors.gray.800}"}},inverted:{value:{_light:"{colors.black}",_dark:"{colors.white}"}},panel:{value:{_light:"{colors.white}",_dark:"{colors.gray.950}"}},error:{value:{_light:"{colors.red.50}",_dark:"{colors.red.950}"}},warning:{value:{_light:"{colors.orange.50}",_dark:"{colors.orange.950}"}},success:{value:{_light:"{colors.green.50}",_dark:"{colors.green.950}"}},info:{value:{_light:"{colors.blue.50}",_dark:"{colors.blue.950}"}}},fg:{DEFAULT:{value:{_light:"{colors.black}",_dark:"{colors.gray.50}"}},muted:{value:{_light:"{colors.gray.600}",_dark:"{colors.gray.400}"}},subtle:{value:{_light:"{colors.gray.400}",_dark:"{colors.gray.500}"}},inverted:{value:{_light:"{colors.gray.50}",_dark:"{colors.black}"}},error:{value:{_light:"{colors.red.500}",_dark:"{colors.red.400}"}},warning:{value:{_light:"{colors.orange.600}",_dark:"{colors.orange.300}"}},success:{value:{_light:"{colors.green.600}",_dark:"{colors.green.300}"}},info:{value:{_light:"{colors.blue.600}",_dark:"{colors.blue.300}"}}},border:{DEFAULT:{value:{_light:"{colors.gray.200}",_dark:"{colors.gray.800}"}},muted:{value:{_light:"{colors.gray.100}",_dark:"{colors.gray.900}"}},subtle:{value:{_light:"{colors.gray.50}",_dark:"{colors.gray.950}"}},emphasized:{value:{_light:"{colors.gray.300}",_dark:"{colors.gray.700}"}},inverted:{value:{_light:"{colors.gray.800}",_dark:"{colors.gray.200}"}},error:{value:{_light:"{colors.red.500}",_dark:"{colors.red.400}"}},warning:{value:{_light:"{colors.orange.500}",_dark:"{colors.orange.400}"}},success:{value:{_light:"{colors.green.500}",_dark:"{colors.green.400}"}},info:{value:{_light:"{colors.blue.500}",_dark:"{colors.blue.400}"}}},gray:{contrast:{value:{_light:"{colors.white}",_dark:"{colors.black}"}},fg:{value:{_light:"{colors.gray.800}",_dark:"{colors.gray.200}"}},subtle:{value:{_light:"{colors.gray.100}",_dark:"{colors.gray.900}"}},muted:{value:{_light:"{colors.gray.200}",_dark:"{colors.gray.800}"}},emphasized:{value:{_light:"{colors.gray.300}",_dark:"{colors.gray.700}"}},solid:{value:{_light:"{colors.gray.900}",_dark:"{colors.white}"}},focusRing:{value:{_light:"{colors.gray.400}",_dark:"{colors.gray.400}"}}},red:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.red.700}",_dark:"{colors.red.300}"}},subtle:{value:{_light:"{colors.red.100}",_dark:"{colors.red.900}"}},muted:{value:{_light:"{colors.red.200}",_dark:"{colors.red.800}"}},emphasized:{value:{_light:"{colors.red.300}",_dark:"{colors.red.700}"}},solid:{value:{_light:"{colors.red.600}",_dark:"{colors.red.600}"}},focusRing:{value:{_light:"{colors.red.500}",_dark:"{colors.red.500}"}}},orange:{contrast:{value:{_light:"white",_dark:"black"}},fg:{value:{_light:"{colors.orange.700}",_dark:"{colors.orange.300}"}},subtle:{value:{_light:"{colors.orange.100}",_dark:"{colors.orange.900}"}},muted:{value:{_light:"{colors.orange.200}",_dark:"{colors.orange.800}"}},emphasized:{value:{_light:"{colors.orange.300}",_dark:"{colors.orange.700}"}},solid:{value:{_light:"{colors.orange.600}",_dark:"{colors.orange.500}"}},focusRing:{value:{_light:"{colors.orange.500}",_dark:"{colors.orange.500}"}}},green:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.green.700}",_dark:"{colors.green.300}"}},subtle:{value:{_light:"{colors.green.100}",_dark:"{colors.green.900}"}},muted:{value:{_light:"{colors.green.200}",_dark:"{colors.green.800}"}},emphasized:{value:{_light:"{colors.green.300}",_dark:"{colors.green.700}"}},solid:{value:{_light:"{colors.green.600}",_dark:"{colors.green.600}"}},focusRing:{value:{_light:"{colors.green.500}",_dark:"{colors.green.500}"}}},blue:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.blue.700}",_dark:"{colors.blue.300}"}},subtle:{value:{_light:"{colors.blue.100}",_dark:"{colors.blue.900}"}},muted:{value:{_light:"{colors.blue.200}",_dark:"{colors.blue.800}"}},emphasized:{value:{_light:"{colors.blue.300}",_dark:"{colors.blue.700}"}},solid:{value:{_light:"{colors.blue.600}",_dark:"{colors.blue.600}"}},focusRing:{value:{_light:"{colors.blue.500}",_dark:"{colors.blue.500}"}}},yellow:{contrast:{value:{_light:"black",_dark:"black"}},fg:{value:{_light:"{colors.yellow.800}",_dark:"{colors.yellow.300}"}},subtle:{value:{_light:"{colors.yellow.100}",_dark:"{colors.yellow.900}"}},muted:{value:{_light:"{colors.yellow.200}",_dark:"{colors.yellow.800}"}},emphasized:{value:{_light:"{colors.yellow.300}",_dark:"{colors.yellow.700}"}},solid:{value:{_light:"{colors.yellow.300}",_dark:"{colors.yellow.300}"}},focusRing:{value:{_light:"{colors.yellow.500}",_dark:"{colors.yellow.500}"}}},teal:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.teal.700}",_dark:"{colors.teal.300}"}},subtle:{value:{_light:"{colors.teal.100}",_dark:"{colors.teal.900}"}},muted:{value:{_light:"{colors.teal.200}",_dark:"{colors.teal.800}"}},emphasized:{value:{_light:"{colors.teal.300}",_dark:"{colors.teal.700}"}},solid:{value:{_light:"{colors.teal.600}",_dark:"{colors.teal.600}"}},focusRing:{value:{_light:"{colors.teal.500}",_dark:"{colors.teal.500}"}}},purple:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.purple.700}",_dark:"{colors.purple.300}"}},subtle:{value:{_light:"{colors.purple.100}",_dark:"{colors.purple.900}"}},muted:{value:{_light:"{colors.purple.200}",_dark:"{colors.purple.800}"}},emphasized:{value:{_light:"{colors.purple.300}",_dark:"{colors.purple.700}"}},solid:{value:{_light:"{colors.purple.600}",_dark:"{colors.purple.600}"}},focusRing:{value:{_light:"{colors.purple.500}",_dark:"{colors.purple.500}"}}},pink:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.pink.700}",_dark:"{colors.pink.300}"}},subtle:{value:{_light:"{colors.pink.100}",_dark:"{colors.pink.900}"}},muted:{value:{_light:"{colors.pink.200}",_dark:"{colors.pink.800}"}},emphasized:{value:{_light:"{colors.pink.300}",_dark:"{colors.pink.700}"}},solid:{value:{_light:"{colors.pink.600}",_dark:"{colors.pink.600}"}},focusRing:{value:{_light:"{colors.pink.500}",_dark:"{colors.pink.500}"}}},cyan:{contrast:{value:{_light:"white",_dark:"white"}},fg:{value:{_light:"{colors.cyan.700}",_dark:"{colors.cyan.300}"}},subtle:{value:{_light:"{colors.cyan.100}",_dark:"{colors.cyan.900}"}},muted:{value:{_light:"{colors.cyan.200}",_dark:"{colors.cyan.800}"}},emphasized:{value:{_light:"{colors.cyan.300}",_dark:"{colors.cyan.700}"}},solid:{value:{_light:"{colors.cyan.600}",_dark:"{colors.cyan.600}"}},focusRing:{value:{_light:"{colors.cyan.500}",_dark:"{colors.cyan.500}"}}}}),VO=Cl.radii({l1:{value:"{radii.xs}"},l2:{value:"{radii.sm}"},l3:{value:"{radii.md}"}}),FO=Cl.shadows({xs:{value:{_light:"0px 1px 2px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/20}",_dark:"0px 1px 1px {black/64}, 0px 0px 1px inset {colors.gray.300/20}"}},sm:{value:{_light:"0px 2px 4px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 2px 4px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},md:{value:{_light:"0px 4px 8px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 4px 8px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},lg:{value:{_light:"0px 8px 16px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 8px 16px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},xl:{value:{_light:"0px 16px 24px {colors.gray.900/10}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 16px 24px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},"2xl":{value:{_light:"0px 24px 40px {colors.gray.900/16}, 0px 0px 1px {colors.gray.900/30}",_dark:"0px 24px 40px {black/64}, 0px 0px 1px inset {colors.gray.300/30}"}},inner:{value:{_light:"inset 0 2px 4px 0 {black/5}",_dark:"inset 0 2px 4px 0 black"}},inset:{value:{_light:"inset 0 0 0 1px {black/5}",_dark:"inset 0 0 0 1px {colors.gray.300/5}"}}}),LO=Rd.extendWith("itemBody"),DO=K("action-bar").parts("positioner","content","separator","selectionTrigger","closeTrigger"),zO=K("alert").parts("title","description","root","indicator","content"),MO=K("breadcrumb").parts("link","currentLink","item","list","root","ellipsis","separator"),$O=K("blockquote").parts("root","icon","content","caption"),BO=K("card").parts("root","header","body","footer","title","description"),jO=K("checkbox-card",["root","control","label","description","addon","indicator","content"]),WO=K("data-list").parts("root","item","itemLabel","itemValue"),HO=tl.extendWith("header","body","footer","backdrop"),UO=tl.extendWith("header","body","footer","backdrop"),GO=mh.extendWith("textarea"),qO=K("empty-state",["root","content","indicator","title","description"]),KO=vh.extendWith("requiredIndicator"),XO=yh.extendWith("content"),YO=xh.extendWith("itemContent","dropzoneContent","fileText"),QO=K("list").parts("root","item","indicator"),JO=Ih.extendWith("itemCommand"),ZO=K("select").parts("root","field","indicator"),eI=Hh.extendWith("header","body","footer"),eg=gl.extendWith("itemAddon","itemIndicator"),tI=eg.extendWith("itemContent","itemDescription"),nI=Gh.extendWith("itemIndicator"),rI=Xh.extendWith("indicatorGroup"),iI=dw.extendWith("indicatorGroup","empty"),oI=Zh.extendWith("markerIndicator"),sI=K("stat").parts("root","label","helpText","valueText","valueUnit","indicator"),aI=K("status").parts("root","indicator"),lI=K("steps",["root","list","item","trigger","indicator","separator","content","title","description","nextTrigger","prevTrigger","progress"]),cI=ef.extendWith("indicator"),uI=K("table").parts("root","header","body","row","columnHeader","cell","footer","caption"),dI=K("toast").parts("root","title","description","indicator","closeTrigger","actionTrigger"),hI=K("tabs").parts("root","trigger","list","content","contentGroup","indicator"),fI=K("tag").parts("root","label","closeTrigger","startElement","endElement"),gI=K("timeline").parts("root","item","content","separator","indicator","connector","title","description"),pI=PS.extendWith("channelText"),mI=K("code-block",["root","content","title","header","footer","control","overlay","code","codeText","copyTrigger","copyIndicator","collapseTrigger","collapseIndicator","collapseText"]);zd.extendWith("valueText");const vI=Mw,bI=Y({className:"chakra-accordion",slots:LO.keys(),base:{root:{width:"full","--accordion-radius":"radii.l2"},item:{overflowAnchor:"none"},itemTrigger:{display:"flex",alignItems:"center",textAlign:"start",width:"full",outline:"0",gap:"3",fontWeight:"medium",borderRadius:"var(--accordion-radius)",_focusVisible:{outline:"2px solid",outlineColor:"colorPalette.focusRing"},_disabled:{layerStyle:"disabled"}},itemBody:{pt:"var(--accordion-padding-y)",pb:"calc(var(--accordion-padding-y) * 2)"},itemContent:{overflow:"hidden",borderRadius:"var(--accordion-radius)",_open:{animationName:"expand-height, fade-in",animationDuration:"moderate"},_closed:{animationName:"collapse-height, fade-out",animationDuration:"moderate"}},itemIndicator:{transition:"rotate 0.2s",transformOrigin:"center",color:"fg.subtle",_open:{rotate:"180deg"},_icon:{width:"1.2em",height:"1.2em"}}},variants:{variant:{outline:{item:{borderBottomWidth:"1px"}},subtle:{itemTrigger:{px:"var(--accordion-padding-x)"},itemContent:{px:"var(--accordion-padding-x)"},item:{borderRadius:"var(--accordion-radius)",_open:{bg:"colorPalette.subtle"}}},enclosed:{root:{borderWidth:"1px",borderRadius:"var(--accordion-radius)",divideY:"1px",overflow:"hidden"},itemTrigger:{px:"var(--accordion-padding-x)"},itemContent:{px:"var(--accordion-padding-x)"},item:{_open:{bg:"bg.subtle"}}},plain:{}},size:{sm:{root:{"--accordion-padding-x":"spacing.3","--accordion-padding-y":"spacing.2"},itemTrigger:{textStyle:"sm",py:"var(--accordion-padding-y)"}},md:{root:{"--accordion-padding-x":"spacing.4","--accordion-padding-y":"spacing.2"},itemTrigger:{textStyle:"md",py:"var(--accordion-padding-y)"}},lg:{root:{"--accordion-padding-x":"spacing.4.5","--accordion-padding-y":"spacing.2.5"},itemTrigger:{textStyle:"lg",py:"var(--accordion-padding-y)"}}}},defaultVariants:{size:"md",variant:"outline"}}),yI=Y({className:"chakra-action-bar",slots:DO.keys(),base:{positioner:{position:"fixed",display:"flex",justifyContent:"center",pointerEvents:"none",insetInline:"0",top:"unset",bottom:"calc(env(safe-area-inset-bottom) + 20px)"},content:{bg:"bg.panel",shadow:"md",display:"flex",alignItems:"center",gap:"3",borderRadius:"l3",py:"2.5",px:"3",pointerEvents:"auto",translate:"calc(-1 * var(--scrollbar-width) / 2) 0px",_open:{animationName:"slide-from-bottom, fade-in",animationDuration:"moderate"},_closed:{animationName:"slide-to-bottom, fade-out",animationDuration:"faster"}},separator:{width:"1px",height:"5",bg:"border"},selectionTrigger:{display:"inline-flex",alignItems:"center",gap:"2",alignSelf:"stretch",textStyle:"sm",px:"4",py:"1",borderRadius:"l2",borderWidth:"1px",borderStyle:"dashed"}}}),xI=Y({slots:zO.keys(),className:"chakra-alert",base:{root:{width:"full",display:"flex",alignItems:"flex-start",position:"relative",borderRadius:"l3"},title:{fontWeight:"medium"},description:{display:"inline"},indicator:{display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:"0",width:"1em",height:"1em",_icon:{boxSize:"full"}},content:{display:"flex",flex:"1",gap:"1"}},variants:{status:{info:{root:{colorPalette:"blue"}},warning:{root:{colorPalette:"orange"}},success:{root:{colorPalette:"green"}},error:{root:{colorPalette:"red"}},neutral:{root:{colorPalette:"gray"}}},inline:{true:{content:{display:"inline-flex",flexDirection:"row",alignItems:"center"}},false:{content:{display:"flex",flexDirection:"column"}}},variant:{subtle:{root:{bg:"colorPalette.subtle",color:"colorPalette.fg"}},surface:{root:{bg:"colorPalette.subtle",color:"colorPalette.fg",shadow:"inset 0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted"},indicator:{color:"colorPalette.fg"}},outline:{root:{color:"colorPalette.fg",shadow:"inset 0 0 0px 1px var(--shadow-color)",shadowColor:"colorPalette.muted"},indicator:{color:"colorPalette.fg"}},solid:{root:{bg:"colorPalette.solid",color:"colorPalette.contrast"},indicator:{color:"colorPalette.contrast"}}},size:{sm:{root:{gap:"2",px:"3",py:"3",textStyle:"xs"},indicator:{textStyle:"lg"}},md:{root:{gap:"3",px:"4",py:"4",textStyle:"sm"},indicator:{textStyle:"xl"}},lg:{root:{gap:"3",px:"4",py:"4",textStyle:"md"},indicator:{textStyle:"2xl"}}}},defaultVariants:{status:"info",variant:"subtle",size:"md",inline:!1}}),CI=Y({slots:Ad.keys(),className:"chakra-avatar",base:{root:{display:"inline-flex",alignItems:"center",justifyContent:"center",fontWeight:"medium",position:"relative",verticalAlign:"top",flexShrink:"0",userSelect:"none",width:"var(--avatar-size)",height:"var(--avatar-size)",fontSize:"var(--avatar-font-size)",borderRadius:"var(--avatar-radius)","&[data-group-item]":{borderWidth:"2px",borderColor:"bg"}},image:{width:"100%",height:"100%",objectFit:"cover",borderRadius:"var(--avatar-radius)"},fallback:{lineHeight:"1",textTransform:"uppercase",fontWeight:"medium",fontSize:"var(--avatar-font-size)",borderRadius:"var(--avatar-radius)"}},variants:{size:{full:{root:{"--avatar-size":"100%","--avatar-font-size":"100%"}},"2xs":{root:{"--avatar-font-size":"fontSizes.2xs","--avatar-size":"sizes.6"}},xs:{root:{"--avatar-font-size":"fontSizes.xs","--avatar-size":"sizes.8"}},sm:{root:{"--avatar-font-size":"fontSizes.sm","--avatar-size":"sizes.9"}},md:{root:{"--avatar-font-size":"fontSizes.md","--avatar-size":"sizes.10"}},lg:{root:{"--avatar-font-size":"fontSizes.md","--avatar-size":"sizes.11"}},xl:{root:{"--avatar-font-size":"fontSizes.lg","--avatar-size":"sizes.12"}},"2xl":{root:{"--avatar-font-size":"fontSizes.xl","--avatar-size":"sizes.16"}}},variant:{solid:{root:{bg:"colorPalette.solid",color:"colorPalette.contrast"}},subtle:{root:{bg:"colorPalette.muted",color:"colorPalette.fg"}},outline:{root:{color:"colorPalette.fg",borderWidth:"1px",borderColor:"colorPalette.muted"}}},shape:{square:{},rounded:{root:{"--avatar-radius":"radii.l3"}},full:{root:{"--avatar-radius":"radii.full"}}},borderless:{true:{root:{"&[data-group-item]":{borderWidth:"0px"}}}}},defaultVariants:{size:"md",shape:"full",variant:"subtle"}}),SI=Y({className:"chakra-blockquote",slots:$O.keys(),base:{root:{position:"relative",display:"flex",flexDirection:"column",gap:"2"},caption:{textStyle:"sm",color:"fg.muted"},icon:{boxSize:"5"}},variants:{justify:{start:{root:{alignItems:"flex-start",textAlign:"start"}},center:{root:{alignItems:"center",textAlign:"center"}},end:{root:{alignItems:"flex-end",textAlign:"end"}}},variant:{subtle:{root:{paddingX:"5",borderStartWidth:"4px",borderStartColor:"colorPalette.muted"},icon:{color:"colorPalette.fg"}},solid:{root:{paddingX:"5",borderStartWidth:"4px",borderStartColor:"colorPalette.solid"},icon:{color:"colorPalette.solid"}},plain:{root:{paddingX:"5"},icon:{color:"colorPalette.solid"}}}},defaultVariants:{variant:"subtle",justify:"start"}}),wI=Y({className:"chakra-breadcrumb",slots:MO.keys(),base:{list:{display:"flex",alignItems:"center",wordBreak:"break-word",color:"fg.muted",listStyle:"none"},link:{outline:"0",textDecoration:"none",borderRadius:"l1",focusRing:"outside",display:"inline-flex",alignItems:"center",gap:"2"},item:{display:"inline-flex",alignItems:"center"},separator:{color:"fg.muted",opacity:"0.8",_icon:{boxSize:"1em"},_rtl:{rotate:"180deg"}},ellipsis:{display:"inline-flex",alignItems:"center",justifyContent:"center",_icon:{boxSize:"1em"}}},variants:{variant:{underline:{link:{color:"colorPalette.fg",textDecoration:"underline",textUnderlineOffset:"0.2em",textDecorationColor:"colorPalette.muted"},currentLink:{color:"colorPalette.fg"}},plain:{link:{color:"fg.muted",_hover:{color:"fg"}},currentLink:{color:"fg"}}},size:{sm:{list:{gap:"1",textStyle:"xs"}},md:{list:{gap:"1.5",textStyle:"sm"}},lg:{list:{gap:"2",textStyle:"md"}}}},defaultVariants:{variant:"plain",size:"md"}}),EI=Y({className:"chakra-card",slots:BO.keys(),base:{root:{display:"flex",flexDirection:"column",position:"relative",minWidth:"0",wordWrap:"break-word",borderRadius:"l3",color:"fg",textAlign:"start"},title:{fontWeight:"semibold"},description:{color:"fg.muted",fontSize:"sm"},header:{paddingInline:"var(--card-padding)",paddingTop:"var(--card-padding)",display:"flex",flexDirection:"column",gap:"1.5"},body:{padding:"var(--card-padding)",flex:"1",display:"flex",flexDirection:"column"},footer:{display:"flex",alignItems:"center",gap:"2",paddingInline:"var(--card-padding)",paddingBottom:"var(--card-padding)"}},variants:{size:{sm:{root:{"--card-padding":"spacing.4"},title:{textStyle:"md"}},md:{root:{"--card-padding":"spacing.6"},title:{textStyle:"lg"}},lg:{root:{"--card-padding":"spacing.7"},title:{textStyle:"xl"}}},variant:{elevated:{root:{bg:"bg.panel",boxShadow:"md"}},outline:{root:{bg:"bg.panel",borderWidth:"1px",borderColor:"border"}},subtle:{root:{bg:"bg.muted"}}}},defaultVariants:{variant:"outline",size:"md"}}),kI=Y({slots:OS.keys(),className:"chakra-checkbox",base:{root:{display:"inline-flex",gap:"2",alignItems:"center",verticalAlign:"top",position:"relative"},control:Ve.base,label:{fontWeight:"medium",userSelect:"none",_disabled:{opacity:"0.5"}}},variants:{size:{xs:{root:{gap:"1.5"},label:{textStyle:"xs"},control:(pm=(gm=Ve.variants)==null?void 0:gm.size)==null?void 0:pm.xs},sm:{root:{gap:"2"},label:{textStyle:"sm"},control:(vm=(mm=Ve.variants)==null?void 0:mm.size)==null?void 0:vm.sm},md:{root:{gap:"2.5"},label:{textStyle:"sm"},control:(ym=(bm=Ve.variants)==null?void 0:bm.size)==null?void 0:ym.md},lg:{root:{gap:"3"},label:{textStyle:"md"},control:(Cm=(xm=Ve.variants)==null?void 0:xm.size)==null?void 0:Cm.lg}},variant:{outline:{control:(wm=(Sm=Ve.variants)==null?void 0:Sm.variant)==null?void 0:wm.outline},solid:{control:(km=(Em=Ve.variants)==null?void 0:Em.variant)==null?void 0:km.solid},subtle:{control:(Im=(Om=Ve.variants)==null?void 0:Om.variant)==null?void 0:Im.subtle}}},defaultVariants:{variant:"solid",size:"md"}}),OI=Y({slots:jO.keys(),className:"chakra-checkbox-card",base:{root:{display:"flex",flexDirection:"column",userSelect:"none",position:"relative",borderRadius:"l2",flex:"1",focusVisibleRing:"outside",_disabled:{opacity:"0.8"},_invalid:{outline:"2px solid",outlineColor:"border.error"}},control:{display:"inline-flex",flex:"1",position:"relative",borderRadius:"inherit",justifyContent:"var(--checkbox-card-justify)",alignItems:"var(--checkbox-card-align)"},label:{fontWeight:"medium",display:"flex",alignItems:"center",gap:"2",flex:"1",_disabled:{opacity:"0.5"}},description:{opacity:"0.64",textStyle:"sm",_disabled:{opacity:"0.5"}},addon:{_disabled:{opacity:"0.5"}},indicator:Ve.base,content:{display:"flex",flexDirection:"column",flex:"1",gap:"1",justifyContent:"var(--checkbox-card-justify)",alignItems:"var(--checkbox-card-align)"}},variants:{size:{sm:{root:{textStyle:"sm"},control:{padding:"3",gap:"1.5"},addon:{px:"3",py:"1.5",borderTopWidth:"1px"},indicator:(Pm=Ve.variants)==null?void 0:Pm.size.sm},md:{root:{textStyle:"sm"},control:{padding:"4",gap:"2.5"},addon:{px:"4",py:"2",borderTopWidth:"1px"},indicator:(Rm=Ve.variants)==null?void 0:Rm.size.md},lg:{root:{textStyle:"md"},control:{padding:"4",gap:"3.5"},addon:{px:"4",py:"2",borderTopWidth:"1px"},indicator:(Tm=Ve.variants)==null?void 0:Tm.size.lg}},variant:{surface:{root:{borderWidth:"1px",borderColor:"border",_checked:{bg:"colorPalette.subtle",color:"colorPalette.fg",borderColor:"colorPalette.muted"},_disabled:{bg:"bg.muted"}},indicator:(Nm=Ve.variants)==null?void 0:Nm.variant.solid},subtle:{root:{bg:"bg.muted"},control:{_checked:{bg:"colorPalette.muted",color:"colorPalette.fg"}},indicator:(Am=Ve.variants)==null?void 0:Am.variant.plain},outline:{root:{borderWidth:"1px",borderColor:"border",_checked:{boxShadow:"0 0 0 1px var(--shadow-color)",boxShadowColor:"colorPalette.solid",borderColor:"colorPalette.solid"}},indicator:(_m=Ve.variants)==null?void 0:_m.variant.solid},solid:{root:{borderWidth:"1px",_checked:{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"colorPalette.solid"}},indicator:(Vm=Ve.variants)==null?void 0:Vm.variant.inverted}},justify:{start:{root:{"--checkbox-card-justify":"flex-start"}},end:{root:{"--checkbox-card-justify":"flex-end"}},center:{root:{"--checkbox-card-justify":"center"}}},align:{start:{root:{"--checkbox-card-align":"flex-start"},content:{textAlign:"start"}},end:{root:{"--checkbox-card-align":"flex-end"},content:{textAlign:"end"}},center:{root:{"--checkbox-card-align":"center"},content:{textAlign:"center"}}},orientation:{vertical:{control:{flexDirection:"column"}},horizontal:{control:{flexDirection:"row"}}}},defaultVariants:{size:"md",variant:"outline",align:"start",orientation:"horizontal"}}),II=Y({slots:mI.keys(),className:"code-block",base:{root:{colorPalette:"gray",rounded:"var(--code-block-radius)",overflow:"hidden",bg:"bg",color:"fg",borderWidth:"1px","--code-block-max-height":"320px","--code-block-bg":"colors.bg","--code-block-fg":"colors.fg","--code-block-obscured-opacity":"0.5","--code-block-obscured-blur":"1px","--code-block-line-number-width":"sizes.3","--code-block-line-number-margin":"spacing.4","--code-block-highlight-bg":"{colors.teal.focusRing/20}","--code-block-highlight-border":"colors.teal.focusRing","--code-block-highlight-added-bg":"{colors.green.focusRing/20}","--code-block-highlight-added-border":"colors.green.focusRing","--code-block-highlight-removed-bg":"{colors.red.focusRing/20}","--code-block-highlight-removed-border":"colors.red.focusRing"},header:{display:"flex",alignItems:"center",gap:"2",position:"relative",px:"var(--code-block-padding)",minH:"var(--code-block-header-height)",mb:"calc(var(--code-block-padding) / 2 * -1)"},title:{display:"inline-flex",alignItems:"center",gap:"1.5",flex:"1",color:"fg.muted"},control:{gap:"1.5",display:"inline-flex",alignItems:"center"},footer:{display:"flex",alignItems:"center",justifyContent:"center",gap:"2",px:"var(--code-block-padding)",minH:"var(--code-block-header-height)"},content:{position:"relative",colorScheme:"dark",overflowX:"auto",overflowY:"hidden",borderBottomRadius:"var(--code-block-radius)",maxHeight:"var(--code-block-max-height)","& ::selection":{bg:"blue.500/40"},_expanded:{maxHeight:"unset"}},overlay:{"--bg":"{colors.black/50}",display:"flex",alignItems:"flex-end",justifyContent:"center",padding:"4",bgImage:"linear-gradient(0deg,var(--bg) 25%,transparent 100%)",color:"white",minH:"5rem",pos:"absolute",bottom:"0",insetInline:"0",zIndex:"1",fontWeight:"medium",_expanded:{display:"none"}},code:{fontFamily:"mono",lineHeight:"tall",whiteSpace:"pre",counterReset:"line 0"},codeText:{px:"var(--code-block-padding)",py:"var(--code-block-padding)",position:"relative",display:"block",width:"100%","&[data-has-focused]":{"& [data-line]:not([data-focused])":{transitionProperty:"opacity, filter",transitionDuration:"moderate",transitionTimingFunction:"ease-in-out",opacity:"var(--code-block-obscured-opacity)",filter:"blur(var(--code-block-obscured-blur))"},"&:hover":{"--code-block-obscured-opacity":"1","--code-block-obscured-blur":"0px"}},"&[data-has-line-numbers][data-plaintext]":{paddingInlineStart:"calc(var(--code-block-line-number-width) + var(--code-block-line-number-margin) + var(--code-block-padding))"},"& [data-line]":{position:"relative","--highlight-bg":"var(--code-block-highlight-bg)","--highlight-border":"var(--code-block-highlight-border)","&[data-highlight], &[data-diff]":{display:"inline-block",width:"full","&:after":{content:"''",display:"block",position:"absolute",insetStart:"calc(var(--code-block-padding) * -1)",insetEnd:"0px",width:"calc(100% + var(--code-block-padding) * 2)",height:"100%",bg:"var(--highlight-bg)",borderStartWidth:"2px",borderStartColor:"var(--highlight-border)"}},"&[data-diff='added']":{"--highlight-bg":"var(--code-block-highlight-added-bg)","--highlight-border":"var(--code-block-highlight-added-border)"},"&[data-diff='removed']":{"--highlight-bg":"var(--code-block-highlight-removed-bg)","--highlight-border":"var(--code-block-highlight-removed-border)"}},"&[data-word-wrap]":{"&[data-plaintext], & [data-line]":{whiteSpace:"pre-wrap",wordBreak:"break-all"}},"&[data-has-line-numbers]":{"--content":"counter(line)","& [data-line]:before":{content:"var(--content)",counterIncrement:"line",width:"var(--code-block-line-number-width)",marginRight:"var(--code-block-line-number-margin)",display:"inline-block",textAlign:"end",userSelect:"none",whiteSpace:"nowrap",opacity:.4},"& [data-diff='added']:before":{content:"'+'"},"& [data-diff='removed']:before":{content:"'-'"}}}},variants:{size:{sm:{root:{"--code-block-padding":"spacing.4","--code-block-radius":"radii.md","--code-block-header-height":"sizes.8"},title:{textStyle:"xs"},code:{fontSize:"xs"}},md:{root:{"--code-block-padding":"spacing.4","--code-block-radius":"radii.lg","--code-block-header-height":"sizes.10"},title:{textStyle:"xs"},code:{fontSize:"sm"}},lg:{root:{"--code-block-padding":"spacing.5","--code-block-radius":"radii.xl","--code-block-header-height":"sizes.12"},title:{textStyle:"sm"},code:{fontSize:"sm"}}}},defaultVariants:{size:"md"}}),PI=Y({slots:Bu.keys(),className:"chakra-collapsible",base:{content:{overflow:"hidden",_open:{animationName:"expand-height, fade-in",animationDuration:"moderate"},_closed:{animationName:"collapse-height, fade-out",animationDuration:"moderate"}}}}),RI=Y({className:"colorPicker",slots:pI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5"},label:{color:"fg",fontWeight:"medium",textStyle:"sm",_disabled:{opacity:"0.5"}},valueText:{textAlign:"start"},control:{display:"flex",alignItems:"center",flexDirection:"row",gap:"2",position:"relative"},swatchTrigger:{display:"flex",alignItems:"center",justifyContent:"center"},trigger:{display:"flex",alignItems:"center",justifyContent:"center",flexDirection:"row",flexShrink:"0",gap:"2",textStyle:"sm",minH:"var(--input-height)",minW:"var(--input-height)",px:"1",rounded:"l2",_disabled:{opacity:"0.5"},"--focus-color":"colors.colorPalette.focusRing","&:focus-visible":{borderColor:"var(--focus-color)",outline:"1px solid var(--focus-color)"},"&[data-fit-content]":{"--input-height":"unset",px:"0",border:"0"}},content:{display:"flex",flexDirection:"column",bg:"bg.panel",borderRadius:"l3",boxShadow:"lg",width:"64",p:"4",gap:"3",zIndex:"dropdown",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"faster"}},area:{height:"180px",borderRadius:"l2",overflow:"hidden"},areaThumb:{borderRadius:"full",height:"var(--thumb-size)",width:"var(--thumb-size)",borderWidth:"2px",borderColor:"white",shadow:"sm",focusVisibleRing:"mixed",focusRingColor:"white"},areaBackground:{height:"full"},channelSlider:{borderRadius:"l2",flex:"1"},channelSliderTrack:{height:"var(--slider-height)",borderRadius:"inherit",boxShadow:"inset 0 0 0 1px rgba(0,0,0,0.1)"},channelText:{textStyle:"xs",color:"fg.muted",fontWeight:"medium",textTransform:"capitalize"},swatchGroup:{display:"flex",flexDirection:"row",flexWrap:"wrap",gap:"2"},swatch:{...Zf.base,borderRadius:"l1"},swatchIndicator:{color:"white",rounded:"full"},channelSliderThumb:{borderRadius:"full",height:"var(--thumb-size)",width:"var(--thumb-size)",borderWidth:"2px",borderColor:"white",shadow:"sm",transform:"translate(-50%, -50%)",focusVisibleRing:"outside",focusRingOffset:"1px"},channelInput:{...Ce.base,"&::-webkit-inner-spin-button, &::-webkit-outer-spin-button":{WebkitAppearance:"none",margin:0}},formatSelect:{textStyle:"xs",textTransform:"uppercase",borderWidth:"1px",minH:"6",focusRing:"inside",rounded:"l2"},transparencyGrid:{borderRadius:"l2"},view:{display:"flex",flexDirection:"column",gap:"2"}},variants:{size:{"2xs":{channelInput:(Lm=(Fm=Ce.variants)==null?void 0:Fm.size)==null?void 0:Lm["2xs"],swatch:{"--swatch-size":"sizes.4.5"},trigger:{"--input-height":"sizes.7"},area:{"--thumb-size":"sizes.3"},channelSlider:{"--slider-height":"sizes.3","--thumb-size":"sizes.3"}},xs:{channelInput:(zm=(Dm=Ce.variants)==null?void 0:Dm.size)==null?void 0:zm.xs,swatch:{"--swatch-size":"sizes.5"},trigger:{"--input-height":"sizes.8"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},sm:{channelInput:($m=(Mm=Ce.variants)==null?void 0:Mm.size)==null?void 0:$m.sm,swatch:{"--swatch-size":"sizes.6"},trigger:{"--input-height":"sizes.9"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},md:{channelInput:(jm=(Bm=Ce.variants)==null?void 0:Bm.size)==null?void 0:jm.md,swatch:{"--swatch-size":"sizes.7"},trigger:{"--input-height":"sizes.10"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},lg:{channelInput:(Hm=(Wm=Ce.variants)==null?void 0:Wm.size)==null?void 0:Hm.lg,swatch:{"--swatch-size":"sizes.7"},trigger:{"--input-height":"sizes.11"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},xl:{channelInput:(Gm=(Um=Ce.variants)==null?void 0:Um.size)==null?void 0:Gm.xl,swatch:{"--swatch-size":"sizes.8"},trigger:{"--input-height":"sizes.12"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}},"2xl":{channelInput:(Km=(qm=Ce.variants)==null?void 0:qm.size)==null?void 0:Km["2xl"],swatch:{"--swatch-size":"sizes.10"},trigger:{"--input-height":"sizes.16"},area:{"--thumb-size":"sizes.3.5"},channelSlider:{"--slider-height":"sizes.3.5","--thumb-size":"sizes.3.5"}}},variant:{outline:{channelInput:(Ym=(Xm=Ce.variants)==null?void 0:Xm.variant)==null?void 0:Ym.outline,trigger:{borderWidth:"1px"}},subtle:{channelInput:(Jm=(Qm=Ce.variants)==null?void 0:Qm.variant)==null?void 0:Jm.subtle,trigger:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted"}}}},defaultVariants:{size:"md",variant:"outline"}}),TI=Y({className:"chakra-combobox",slots:iI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5",width:"full"},label:{fontWeight:"medium",userSelect:"none",textStyle:"sm",_disabled:{layerStyle:"disabled"}},input:{display:"flex",alignItems:"center",justifyContent:"space-between",background:"bg.panel",width:"full",minH:"var(--combobox-input-height)",px:"var(--combobox-input-padding-x)","--input-height":"var(--combobox-input-height)",borderRadius:"l2",outline:0,userSelect:"none",textAlign:"start",_placeholderShown:{color:"fg.muted"},_disabled:{layerStyle:"disabled"},"--focus-color":"colors.colorPalette.focusRing","--error-color":"colors.border.error",_invalid:{focusRingColor:"var(--error-color)",borderColor:"var(--error-color)"}},trigger:{display:"inline-flex",alignItems:"center",justifyContent:"center","--input-height":"var(--combobox-input-height)"},clearTrigger:{color:"fg.muted",pointerEvents:"auto",focusVisibleRing:"inside",focusRingWidth:"2px",rounded:"l1"},control:{pos:"relative"},indicatorGroup:{display:"flex",alignItems:"center",justifyContent:"center",gap:"1",pos:"absolute",insetEnd:"0",top:"0",bottom:"0",px:"var(--combobox-input-padding-x)",_icon:{boxSize:"var(--combobox-indicator-size)"},"[data-disabled] &":{opacity:.5}},content:{background:"bg.panel",display:"flex",flexDirection:"column",zIndex:"dropdown",borderRadius:"l2",outline:0,maxH:"96",overflowY:"auto",boxShadow:"md",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"0s"},"&[data-empty]:not(:has([data-scope=combobox][data-part=empty]))":{opacity:0}},item:{position:"relative",userSelect:"none",display:"flex",alignItems:"center",gap:"2",py:"var(--combobox-item-padding-y)",px:"var(--combobox-item-padding-x)",cursor:"option",justifyContent:"space-between",flex:"1",textAlign:"start",borderRadius:"l1",_highlighted:{bg:"bg.emphasized/60"},_disabled:{pointerEvents:"none",opacity:"0.5"},_icon:{boxSize:"var(--combobox-indicator-size)"}},empty:{py:"var(--combobox-item-padding-y)",px:"var(--combobox-item-padding-x)"},itemText:{flex:"1"},itemGroup:{pb:"var(--combobox-item-padding-y)",_last:{pb:"0"}},itemGroupLabel:{fontWeight:"medium",py:"var(--combobox-item-padding-y)",px:"var(--combobox-item-padding-x)"}},variants:{variant:{outline:{input:{bg:"transparent",borderWidth:"1px",borderColor:"border",focusVisibleRing:"inside"}},subtle:{input:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted",focusVisibleRing:"inside"}},flushed:{input:{bg:"transparent",borderBottomWidth:"1px",borderBottomColor:"border",borderRadius:"0",px:"0",_focusVisible:{borderColor:"var(--focus-color)",boxShadow:"0px 1px 0px 0px var(--focus-color)"}},indicatorGroup:{px:"0"}}},size:{xs:{root:{"--combobox-input-height":"sizes.8","--combobox-input-padding-x":"spacing.2","--combobox-indicator-size":"sizes.3.5"},input:{textStyle:"xs"},content:{"--combobox-item-padding-x":"spacing.1.5","--combobox-item-padding-y":"spacing.1","--combobox-indicator-size":"sizes.3.5",p:"1",textStyle:"xs"},trigger:{textStyle:"xs",gap:"1"}},sm:{root:{"--combobox-input-height":"sizes.9","--combobox-input-padding-x":"spacing.2.5","--combobox-indicator-size":"sizes.4"},input:{textStyle:"sm"},content:{"--combobox-item-padding-x":"spacing.2","--combobox-item-padding-y":"spacing.1.5","--combobox-indicator-size":"sizes.4",p:"1",textStyle:"sm"},trigger:{textStyle:"sm",gap:"1"}},md:{root:{"--combobox-input-height":"sizes.10","--combobox-input-padding-x":"spacing.3","--combobox-indicator-size":"sizes.4"},input:{textStyle:"sm"},content:{"--combobox-item-padding-x":"spacing.2","--combobox-item-padding-y":"spacing.1.5","--combobox-indicator-size":"sizes.4",p:"1",textStyle:"sm"},itemIndicator:{display:"flex",alignItems:"center",justifyContent:"center"},trigger:{textStyle:"sm",gap:"2"}},lg:{root:{"--combobox-input-height":"sizes.12","--combobox-input-padding-x":"spacing.4","--combobox-indicator-size":"sizes.5"},input:{textStyle:"md"},content:{"--combobox-item-padding-y":"spacing.2","--combobox-item-padding-x":"spacing.3","--combobox-indicator-size":"sizes.5",p:"1.5",textStyle:"md"},trigger:{textStyle:"md",py:"3",gap:"2"}}}},defaultVariants:{size:"md",variant:"outline"}}),NI=Y({slots:WO.keys(),className:"chakra-data-list",base:{itemLabel:{display:"flex",alignItems:"center",gap:"1"},itemValue:{display:"flex",minWidth:"0",flex:"1"}},variants:{orientation:{horizontal:{root:{display:"flex",flexDirection:"column"},item:{display:"inline-flex",alignItems:"center",gap:"4"},itemLabel:{minWidth:"120px"}},vertical:{root:{display:"flex",flexDirection:"column"},item:{display:"flex",flexDirection:"column",gap:"1"}}},size:{sm:{root:{gap:"3"},item:{textStyle:"xs"}},md:{root:{gap:"4"},item:{textStyle:"sm"}},lg:{root:{gap:"5"},item:{textStyle:"md"}}},variant:{subtle:{itemLabel:{color:"fg.muted"}},bold:{itemLabel:{fontWeight:"medium"},itemValue:{color:"fg.muted"}}}},defaultVariants:{size:"md",orientation:"vertical",variant:"subtle"}}),AI=Y({slots:HO.keys(),className:"chakra-dialog",base:{backdrop:{bg:"blackAlpha.500",pos:"fixed",left:0,top:0,w:"100dvw",h:"100dvh",zIndex:"var(--z-index)",_open:{animationName:"fade-in",animationDuration:"slow"},_closed:{animationName:"fade-out",animationDuration:"moderate"}},positioner:{display:"flex",width:"100dvw",height:"100dvh",position:"fixed",left:0,top:0,"--dialog-z-index":"zIndex.modal",zIndex:"calc(var(--dialog-z-index) + var(--layer-index, 0))",justifyContent:"center",overscrollBehaviorY:"none"},content:{display:"flex",flexDirection:"column",position:"relative",width:"100%",outline:0,borderRadius:"l3",textStyle:"sm",my:"var(--dialog-margin, var(--dialog-base-margin))","--dialog-z-index":"zIndex.modal",zIndex:"calc(var(--dialog-z-index) + var(--layer-index, 0))",bg:"bg.panel",boxShadow:"lg",_open:{animationDuration:"moderate"},_closed:{animationDuration:"faster"}},header:{display:"flex",gap:"2",flex:0,px:"6",pt:"6",pb:"4"},body:{flex:"1",px:"6",pt:"2",pb:"6"},footer:{display:"flex",alignItems:"center",justifyContent:"flex-end",gap:"3",px:"6",pt:"2",pb:"4"},title:{textStyle:"lg",fontWeight:"semibold"},description:{color:"fg.muted"},closeTrigger:{pos:"absolute",top:"2",insetEnd:"2"}},variants:{placement:{center:{positioner:{alignItems:"center"},content:{"--dialog-base-margin":"auto",mx:"auto"}},top:{positioner:{alignItems:"flex-start"},content:{"--dialog-base-margin":"spacing.16",mx:"auto"}},bottom:{positioner:{alignItems:"flex-end"},content:{"--dialog-base-margin":"spacing.16",mx:"auto"}}},scrollBehavior:{inside:{positioner:{overflow:"hidden"},content:{maxH:"calc(100% - 7.5rem)"},body:{overflow:"auto"}},outside:{positioner:{overflow:"auto",pointerEvents:"auto"}}},size:{xs:{content:{maxW:"sm"}},sm:{content:{maxW:"md"}},md:{content:{maxW:"lg"}},lg:{content:{maxW:"2xl"}},xl:{content:{maxW:"4xl"}},cover:{positioner:{padding:"10"},content:{width:"100%",height:"100%","--dialog-margin":"0"}},full:{content:{maxW:"100dvw",minH:"100dvh","--dialog-margin":"0",borderRadius:"0"}}},motionPreset:{scale:{content:{_open:{animationName:"scale-in, fade-in"},_closed:{animationName:"scale-out, fade-out"}}},"slide-in-bottom":{content:{_open:{animationName:"slide-from-bottom, fade-in"},_closed:{animationName:"slide-to-bottom, fade-out"}}},"slide-in-top":{content:{_open:{animationName:"slide-from-top, fade-in"},_closed:{animationName:"slide-to-top, fade-out"}}},"slide-in-left":{content:{_open:{animationName:"slide-from-left, fade-in"},_closed:{animationName:"slide-to-left, fade-out"}}},"slide-in-right":{content:{_open:{animationName:"slide-from-right, fade-in"},_closed:{animationName:"slide-to-right, fade-out"}}},none:{}}},defaultVariants:{size:"md",scrollBehavior:"outside",placement:"top",motionPreset:"scale"}}),_I=Y({slots:UO.keys(),className:"chakra-drawer",base:{backdrop:{bg:"blackAlpha.500",pos:"fixed",insetInlineStart:0,top:0,w:"100vw",h:"100dvh",zIndex:"overlay",_open:{animationName:"fade-in",animationDuration:"slow"},_closed:{animationName:"fade-out",animationDuration:"moderate"}},positioner:{display:"flex",width:"100vw",height:"100dvh",position:"fixed",insetInlineStart:0,top:0,zIndex:"modal",overscrollBehaviorY:"none"},content:{display:"flex",flexDirection:"column",position:"relative",width:"100%",outline:0,zIndex:"modal",textStyle:"sm",maxH:"100dvh",color:"inherit",bg:"bg.panel",boxShadow:"lg",_open:{animationDuration:"slowest",animationTimingFunction:"ease-in-smooth"},_closed:{animationDuration:"slower",animationTimingFunction:"ease-in-smooth"}},header:{display:"flex",alignItems:"center",gap:"2",flex:0,px:"6",pt:"6",pb:"4"},body:{px:"6",py:"2",flex:"1",overflow:"auto"},footer:{display:"flex",alignItems:"center",justifyContent:"flex-end",gap:"3",px:"6",pt:"2",pb:"4"},title:{flex:"1",textStyle:"lg",fontWeight:"semibold"},description:{color:"fg.muted"},closeTrigger:{pos:"absolute",top:"3",insetEnd:"2"}},variants:{size:{xs:{content:{maxW:"xs"}},sm:{content:{maxW:"md"}},md:{content:{maxW:"lg"}},lg:{content:{maxW:"2xl"}},xl:{content:{maxW:"4xl"}},full:{content:{maxW:"100vw",h:"100dvh"}}},placement:{start:{positioner:{justifyContent:"flex-start",alignItems:"stretch"},content:{_open:{animationName:{base:"slide-from-left-full, fade-in",_rtl:"slide-from-right-full, fade-in"}},_closed:{animationName:{base:"slide-to-left-full, fade-out",_rtl:"slide-to-right-full, fade-out"}}}},end:{positioner:{justifyContent:"flex-end",alignItems:"stretch"},content:{_open:{animationName:{base:"slide-from-right-full, fade-in",_rtl:"slide-from-left-full, fade-in"}},_closed:{animationName:{base:"slide-to-right-full, fade-out",_rtl:"slide-to-left-full, fade-out"}}}},top:{positioner:{justifyContent:"stretch",alignItems:"flex-start"},content:{maxW:"100%",_open:{animationName:"slide-from-top-full, fade-in"},_closed:{animationName:"slide-to-top-full, fade-out"}}},bottom:{positioner:{justifyContent:"stretch",alignItems:"flex-end"},content:{maxW:"100%",_open:{animationName:"slide-from-bottom-full, fade-in"},_closed:{animationName:"slide-to-bottom-full, fade-out"}}}},contained:{true:{positioner:{padding:"4"},content:{borderRadius:"l3"}}}},defaultVariants:{size:"xs",placement:"end"}}),tg=Tr({fontSize:"inherit",fontWeight:"inherit",textAlign:"inherit",bg:"transparent",borderRadius:"l2"}),VI=Y({slots:GO.keys(),className:"chakra-editable",base:{root:{display:"inline-flex",alignItems:"center",position:"relative",gap:"1.5",width:"full"},preview:{...tg,py:"1",px:"1",display:"inline-flex",alignItems:"center",transitionProperty:"common",transitionDuration:"moderate",cursor:"text",_hover:{bg:"bg.muted"},_disabled:{userSelect:"none"}},input:{...tg,outline:"0",py:"1",px:"1",transitionProperty:"common",transitionDuration:"normal",width:"full",focusVisibleRing:"inside",focusRingWidth:"2px",_placeholder:{opacity:.6}},control:{display:"inline-flex",alignItems:"center",gap:"1.5"}},variants:{size:{sm:{root:{textStyle:"sm"},preview:{minH:"8"},input:{minH:"8"}},md:{root:{textStyle:"sm"},preview:{minH:"9"},input:{minH:"9"}},lg:{root:{textStyle:"md"},preview:{minH:"10"},input:{minH:"10"}}}},defaultVariants:{size:"md"}}),FI=Y({slots:qO.keys(),className:"chakra-empty-state",base:{root:{width:"full"},content:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},indicator:{display:"flex",alignItems:"center",justifyContent:"center",color:"fg.subtle",_icon:{boxSize:"1em"}},title:{fontWeight:"semibold"},description:{textStyle:"sm",color:"fg.muted"}},variants:{size:{sm:{root:{px:"4",py:"6"},title:{textStyle:"md"},content:{gap:"4"},indicator:{textStyle:"2xl"}},md:{root:{px:"8",py:"12"},title:{textStyle:"lg"},content:{gap:"6"},indicator:{textStyle:"4xl"}},lg:{root:{px:"12",py:"16"},title:{textStyle:"xl"},content:{gap:"8"},indicator:{textStyle:"6xl"}}}},defaultVariants:{size:"md"}}),LI=Y({className:"chakra-field",slots:KO.keys(),base:{requiredIndicator:{color:"fg.error",lineHeight:"1"},root:{display:"flex",width:"100%",position:"relative",gap:"1.5"},label:{display:"flex",alignItems:"center",textAlign:"start",textStyle:"sm",fontWeight:"medium",gap:"1",userSelect:"none",_disabled:{opacity:"0.5"}},errorText:{display:"inline-flex",alignItems:"center",fontWeight:"medium",gap:"1",color:"fg.error",textStyle:"xs"},helperText:{color:"fg.muted",textStyle:"xs"}},variants:{orientation:{vertical:{root:{flexDirection:"column",alignItems:"flex-start"}},horizontal:{root:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},label:{flex:"0 0 var(--field-label-width, 80px)"}}}},defaultVariants:{orientation:"vertical"}}),DI=Y({className:"fieldset",slots:XO.keys(),base:{root:{display:"flex",flexDirection:"column",width:"full"},content:{display:"flex",flexDirection:"column",width:"full"},legend:{color:"fg",fontWeight:"medium",_disabled:{opacity:"0.5"}},helperText:{color:"fg.muted",textStyle:"sm"},errorText:{display:"inline-flex",alignItems:"center",color:"fg.error",gap:"2",fontWeight:"medium",textStyle:"sm"}},variants:{size:{sm:{root:{spaceY:"2"},content:{gap:"1.5"},legend:{textStyle:"sm"}},md:{root:{spaceY:"4"},content:{gap:"4"},legend:{textStyle:"sm"}},lg:{root:{spaceY:"6"},content:{gap:"4"},legend:{textStyle:"md"}}}},defaultVariants:{size:"md"}}),zI=Y({className:"chakra-file-upload",slots:YO.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"4",width:"100%",alignItems:"flex-start"},label:{fontWeight:"medium",textStyle:"sm"},dropzone:{background:"bg",borderRadius:"l3",borderWidth:"2px",borderStyle:"dashed",display:"flex",alignItems:"center",flexDirection:"column",gap:"4",justifyContent:"center",minHeight:"2xs",px:"3",py:"2",transition:"backgrounds",focusVisibleRing:"outside",_hover:{bg:"bg.subtle"},_dragging:{bg:"colorPalette.subtle",borderStyle:"solid",borderColor:"colorPalette.solid"}},dropzoneContent:{display:"flex",flexDirection:"column",alignItems:"center",textAlign:"center",gap:"1",textStyle:"sm"},item:{pos:"relative",textStyle:"sm",animationName:"fade-in",animationDuration:"moderate",background:"bg",borderRadius:"l2",borderWidth:"1px",width:"100%",display:"flex",alignItems:"center",gap:"3",p:"4"},itemGroup:{width:"100%",display:"flex",flexDirection:"column",gap:"3",_empty:{display:"none"}},itemName:{color:"fg",fontWeight:"medium",lineClamp:"1"},itemContent:{display:"flex",flexDirection:"column",gap:"0.5",flex:"1"},itemSizeText:{color:"fg.muted",textStyle:"xs"},itemDeleteTrigger:{display:"flex",alignItems:"center",justifyContent:"center",alignSelf:"flex-start",boxSize:"5",p:"2px",color:"fg.muted",cursor:"button"},itemPreview:{color:"fg.muted",_icon:{boxSize:"4.5"}}},defaultVariants:{}}),MI=Y({className:"chakra-hover-card",slots:Ch.keys(),base:{content:{position:"relative",display:"flex",flexDirection:"column",textStyle:"sm","--hovercard-bg":"colors.bg.panel",bg:"var(--hovercard-bg)",boxShadow:"lg",maxWidth:"80",borderRadius:"l3",zIndex:"popover",transformOrigin:"var(--transform-origin)",outline:"0",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"faster"}},arrow:{"--arrow-size":"sizes.3","--arrow-background":"var(--hovercard-bg)"},arrowTip:{borderTopWidth:"0.5px",borderInlineStartWidth:"0.5px"}},variants:{size:{xs:{content:{padding:"3"}},sm:{content:{padding:"4"}},md:{content:{padding:"5"}},lg:{content:{padding:"6"}}}},defaultVariants:{size:"md"}}),$I=Y({className:"chakra-list",slots:QO.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"var(--list-gap)","& :where(ul, ol)":{marginTop:"var(--list-gap)"}},item:{whiteSpace:"normal",display:"list-item"},indicator:{marginEnd:"2",minHeight:"1lh",flexShrink:0,display:"inline-block",verticalAlign:"middle"}},variants:{variant:{marker:{root:{listStyle:"revert"},item:{_marker:{color:"fg.subtle"}}},plain:{item:{alignItems:"flex-start",display:"inline-flex"}}},align:{center:{item:{alignItems:"center"}},start:{item:{alignItems:"flex-start"}},end:{item:{alignItems:"flex-end"}}}},defaultVariants:{variant:"marker"}}),BI=Y({className:"chakra-listbox",slots:vI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5",width:"full"},content:{display:"flex",maxH:"96",p:"1",gap:"1",textStyle:"sm",outline:"none",scrollPadding:"1",_horizontal:{flexDirection:"row",overflowX:"auto"},_vertical:{flexDirection:"column",overflowY:"auto"},"--listbox-item-padding-x":"spacing.2","--listbox-item-padding-y":"spacing.1.5"},item:{position:"relative",userSelect:"none",display:"flex",alignItems:"center",gap:"2",cursor:"pointer",justifyContent:"space-between",flex:"1",textAlign:"start",borderRadius:"l1",py:"var(--listbox-item-padding-y)",px:"var(--listbox-item-padding-x)",_highlighted:{outline:"2px solid",outlineColor:"border.emphasized"},_disabled:{pointerEvents:"none",opacity:"0.5"}},empty:{py:"var(--listbox-item-padding-y)",px:"var(--listbox-item-padding-x)"},itemText:{flex:"1"},itemGroup:{mt:"1.5",_first:{mt:"0"}},itemGroupLabel:{py:"1.5",px:"2",fontWeight:"medium"},label:{fontWeight:"medium",userSelect:"none",textStyle:"sm",_disabled:{layerStyle:"disabled"}},valueText:{lineClamp:"1",maxW:"80%"},itemIndicator:{display:"flex",alignItems:"center",justifyContent:"center",_icon:{boxSize:"4"}}},variants:{variant:{subtle:{content:{bg:"bg.panel",borderWidth:"1px",borderRadius:"l2"},item:{_hover:{bg:"bg.emphasized/60"},_selected:{bg:"bg.muted"}}},solid:{content:{bg:"bg.panel",borderWidth:"1px",borderRadius:"l2"},item:{_selected:{bg:"colorPalette.solid",color:"colorPalette.contrast"}}},plain:{}}},defaultVariants:{variant:"subtle"}}),jI=Y({className:"chakra-menu",slots:JO.keys(),base:{content:{outline:0,bg:"bg.panel",boxShadow:"lg",color:"fg",maxHeight:"var(--available-height)","--menu-z-index":"zIndex.dropdown",zIndex:"calc(var(--menu-z-index) + var(--layer-index, 0))",borderRadius:"l2",overflow:"hidden",overflowY:"auto",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"faster"}},item:{textDecoration:"none",color:"fg",userSelect:"none",borderRadius:"l1",width:"100%",display:"flex",cursor:"menuitem",alignItems:"center",textAlign:"start",position:"relative",flex:"0 0 auto",outline:0,_disabled:{layerStyle:"disabled"},"&[data-type]":{ps:"8"}},itemText:{flex:"1"},itemIndicator:{position:"absolute",insetStart:"2",transform:"translateY(-50%)",top:"50%"},itemGroupLabel:{px:"2",py:"1.5",fontWeight:"semibold",textStyle:"sm"},indicator:{display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:"0"},itemCommand:{opacity:"0.6",textStyle:"xs",ms:"auto",ps:"4",letterSpacing:"widest",fontFamily:"inherit"},separator:{height:"1px",bg:"bg.muted",my:"1",mx:"-1"}},variants:{variant:{subtle:{item:{_highlighted:{bg:"bg.emphasized/60"}}},solid:{item:{_highlighted:{bg:"colorPalette.solid",color:"colorPalette.contrast"}}}},size:{sm:{content:{minW:"8rem",padding:"1",scrollPadding:"1"},item:{gap:"1",textStyle:"xs",py:"1",px:"1.5"}},md:{content:{minW:"8rem",padding:"1.5",scrollPadding:"1.5"},item:{gap:"2",textStyle:"sm",py:"1.5",px:"2"}}}},defaultVariants:{size:"md",variant:"subtle"}}),hs=Y({className:"chakra-select",slots:rI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5",width:"full"},trigger:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"full",minH:"var(--select-trigger-height)","--input-height":"var(--select-trigger-height)",px:"var(--select-trigger-padding-x)",borderRadius:"l2",userSelect:"none",textAlign:"start",focusVisibleRing:"inside",_placeholderShown:{color:"fg.muted/80"},_disabled:{layerStyle:"disabled"},_invalid:{borderColor:"border.error"}},indicatorGroup:{display:"flex",alignItems:"center",gap:"1",pos:"absolute",insetEnd:"0",top:"0",bottom:"0",px:"var(--select-trigger-padding-x)",pointerEvents:"none"},indicator:{display:"flex",alignItems:"center",justifyContent:"center",color:{base:"fg.muted",_disabled:"fg.subtle",_invalid:"fg.error"}},content:{background:"bg.panel",display:"flex",flexDirection:"column",zIndex:"dropdown",borderRadius:"l2",outline:0,maxH:"96",overflowY:"auto",boxShadow:"md",_open:{animationStyle:"slide-fade-in",animationDuration:"fast"},_closed:{animationStyle:"slide-fade-out",animationDuration:"fastest"}},item:{position:"relative",userSelect:"none",display:"flex",alignItems:"center",gap:"2",cursor:"option",justifyContent:"space-between",flex:"1",textAlign:"start",borderRadius:"l1",_highlighted:{bg:"bg.emphasized/60"},_disabled:{pointerEvents:"none",opacity:"0.5"},_icon:{width:"4",height:"4"}},control:{pos:"relative"},itemText:{flex:"1"},itemGroup:{_first:{mt:"0"}},itemGroupLabel:{py:"1",fontWeight:"medium"},label:{fontWeight:"medium",userSelect:"none",textStyle:"sm",_disabled:{layerStyle:"disabled"}},valueText:{lineClamp:"1",maxW:"80%"},clearTrigger:{color:"fg.muted",pointerEvents:"auto",focusVisibleRing:"inside",focusRingWidth:"2px",rounded:"l1"}},variants:{variant:{outline:{trigger:{bg:"transparent",borderWidth:"1px",borderColor:"border",_expanded:{borderColor:"border.emphasized"}}},subtle:{trigger:{borderWidth:"1px",borderColor:"transparent",bg:"bg.muted"}}},size:{xs:{root:{"--select-trigger-height":"sizes.8","--select-trigger-padding-x":"spacing.2"},content:{p:"1",gap:"1",textStyle:"xs"},trigger:{textStyle:"xs",gap:"1"},item:{py:"1",px:"2"},itemGroupLabel:{py:"1",px:"2"},indicator:{_icon:{width:"3.5",height:"3.5"}}},sm:{root:{"--select-trigger-height":"sizes.9","--select-trigger-padding-x":"spacing.2.5"},content:{p:"1",textStyle:"sm"},trigger:{textStyle:"sm",gap:"1"},indicator:{_icon:{width:"4",height:"4"}},item:{py:"1",px:"1.5"},itemGroup:{mt:"1"},itemGroupLabel:{py:"1",px:"1.5"}},md:{root:{"--select-trigger-height":"sizes.10","--select-trigger-padding-x":"spacing.3"},content:{p:"1",textStyle:"sm"},itemGroup:{mt:"1.5"},item:{py:"1.5",px:"2"},itemIndicator:{display:"flex",alignItems:"center",justifyContent:"center"},itemGroupLabel:{py:"1.5",px:"2"},trigger:{textStyle:"sm",gap:"2"},indicator:{_icon:{width:"4",height:"4"}}},lg:{root:{"--select-trigger-height":"sizes.12","--select-trigger-padding-x":"spacing.4"},content:{p:"1.5",textStyle:"md"},itemGroup:{mt:"2"},item:{py:"2",px:"3"},itemGroupLabel:{py:"2",px:"3"},trigger:{textStyle:"md",py:"3",gap:"2"},indicator:{_icon:{width:"5",height:"5"}}}}},defaultVariants:{size:"md",variant:"outline"}}),WI=Y({className:"chakra-native-select",slots:ZO.keys(),base:{root:{height:"fit-content",display:"flex",width:"100%",position:"relative"},field:{width:"100%",minWidth:"0",outline:"0",appearance:"none",borderRadius:"l2","--error-color":"colors.border.error","--input-height":"var(--select-field-height)",height:"var(--select-field-height)",_disabled:{layerStyle:"disabled"},_invalid:{focusRingColor:"var(--error-color)",borderColor:"var(--error-color)"},focusVisibleRing:"inside",lineHeight:"normal","& > option, & > optgroup":{bg:"bg"}},indicator:{position:"absolute",display:"inline-flex",alignItems:"center",justifyContent:"center",pointerEvents:"none",top:"50%",transform:"translateY(-50%)",height:"100%",color:"fg.muted",_disabled:{opacity:"0.5"},_invalid:{color:"fg.error"},_icon:{width:"1em",height:"1em"}}},variants:{variant:{outline:{field:(Zm=hs.variants)==null?void 0:Zm.variant.outline.trigger},subtle:{field:(ev=hs.variants)==null?void 0:ev.variant.subtle.trigger},plain:{field:{bg:"transparent",color:"fg",focusRingWidth:"2px"}}},size:{xs:{root:{"--select-field-height":"sizes.8"},field:{textStyle:"xs",ps:"2",pe:"6"},indicator:{textStyle:"sm",insetEnd:"1.5"}},sm:{root:{"--select-field-height":"sizes.9"},field:{textStyle:"sm",ps:"2.5",pe:"8"},indicator:{textStyle:"md",insetEnd:"2"}},md:{root:{"--select-field-height":"sizes.10"},field:{textStyle:"sm",ps:"3",pe:"8"},indicator:{textStyle:"lg",insetEnd:"2"}},lg:{root:{"--select-field-height":"sizes.11"},field:{textStyle:"md",ps:"4",pe:"8"},indicator:{textStyle:"xl",insetEnd:"3"}},xl:{root:{"--select-field-height":"sizes.12"},field:{textStyle:"md",ps:"4.5",pe:"10"},indicator:{textStyle:"xl",insetEnd:"3"}}}},defaultVariants:hs.defaultVariants});function Al(e,t){const n={};for(const r in e){const i=t(r,e[r]);n[i[0]]=i[1]}return n}const ng=Tr({display:"flex",justifyContent:"center",alignItems:"center",flex:"1",userSelect:"none",cursor:"button",lineHeight:"1",color:"fg.muted","--stepper-base-radius":"radii.l1","--stepper-radius":"calc(var(--stepper-base-radius) + 1px)",_icon:{boxSize:"1em"},_disabled:{opacity:"0.5"},_hover:{bg:"bg.muted"},_active:{bg:"bg.emphasized"}}),HI=Y({className:"chakra-number-input",slots:zh.keys(),base:{root:{position:"relative",zIndex:"0",isolation:"isolate"},input:{...Ce.base,verticalAlign:"top",pe:"calc(var(--stepper-width) + 0.5rem)"},control:{display:"flex",flexDirection:"column",position:"absolute",top:"0",insetEnd:"0px",margin:"1px",width:"var(--stepper-width)",height:"calc(100% - 2px)",zIndex:"1",borderStartWidth:"1px",divideY:"1px"},incrementTrigger:{...ng,borderTopEndRadius:"var(--stepper-radius)"},decrementTrigger:{...ng,borderBottomEndRadius:"var(--stepper-radius)"},valueText:{fontWeight:"medium",fontFeatureSettings:"pnum",fontVariantNumeric:"proportional-nums"}},variants:{size:{xs:{input:Ce.variants.size.xs,control:{fontSize:"2xs","--stepper-width":"sizes.4"}},sm:{input:Ce.variants.size.sm,control:{fontSize:"xs","--stepper-width":"sizes.5"}},md:{input:Ce.variants.size.md,control:{fontSize:"sm","--stepper-width":"sizes.6"}},lg:{input:Ce.variants.size.lg,control:{fontSize:"sm","--stepper-width":"sizes.6"}}},variant:Al(Ce.variants.variant,(e,t)=>[e,{input:t}])},defaultVariants:{size:"md",variant:"outline"}}),{variants:rg,defaultVariants:UI}=Ce,GI=Y({className:"chakra-pin-input",slots:Wh.keys(),base:{input:{...Ce.base,textAlign:"center",width:"var(--input-height)"},control:{display:"inline-flex",gap:"2",isolation:"isolate"}},variants:{size:Al(rg.size,(e,t)=>[e,{input:{...t,px:"1"}}]),variant:Al(rg.variant,(e,t)=>[e,{input:t}]),attached:{true:{control:{gap:"0",spaceX:"-1px"},input:{_notFirst:{borderStartRadius:"0"},_notLast:{borderEndRadius:"0"},_focusVisible:{zIndex:"1"}}}}},defaultVariants:UI}),qI=Y({className:"chakra-popover",slots:eI.keys(),base:{content:{position:"relative",display:"flex",flexDirection:"column",textStyle:"sm","--popover-bg":"colors.bg.panel",bg:"var(--popover-bg)",boxShadow:"lg","--popover-size":"sizes.xs","--popover-mobile-size":"calc(100dvw - 1rem)",width:{base:"min(var(--popover-mobile-size), var(--popover-size))",sm:"var(--popover-size)"},borderRadius:"l3","--popover-z-index":"zIndex.popover",zIndex:"calc(var(--popover-z-index) + var(--layer-index, 0))",outline:"0",transformOrigin:"var(--transform-origin)",maxHeight:"var(--available-height)",_open:{animationStyle:"scale-fade-in",animationDuration:"fast"},_closed:{animationStyle:"scale-fade-out",animationDuration:"faster"}},header:{paddingInline:"var(--popover-padding)",paddingTop:"var(--popover-padding)"},body:{padding:"var(--popover-padding)",flex:"1"},footer:{display:"flex",alignItems:"center",paddingInline:"var(--popover-padding)",paddingBottom:"var(--popover-padding)"},arrow:{"--arrow-size":"sizes.3","--arrow-background":"var(--popover-bg)"},arrowTip:{borderTopWidth:"1px",borderInlineStartWidth:"1px"}},variants:{size:{xs:{content:{"--popover-padding":"spacing.3"}},sm:{content:{"--popover-padding":"spacing.4"}},md:{content:{"--popover-padding":"spacing.5"}},lg:{content:{"--popover-padding":"spacing.6"}}}},defaultVariants:{size:"md"}}),KI=Y({slots:fl.keys(),className:"chakra-progress",base:{root:{textStyle:"sm",position:"relative"},track:{overflow:"hidden",position:"relative"},range:{display:"flex",alignItems:"center",justifyContent:"center",transitionProperty:"width, height",transitionDuration:"slow",height:"100%",bgColor:"var(--track-color)",_indeterminate:{"--animate-from-x":"-40%","--animate-to-x":"100%",position:"absolute",willChange:"left",minWidth:"50%",animation:"position 1s ease infinite normal none running",backgroundImage:"linear-gradient(to right, transparent 0%, var(--track-color) 50%, transparent 100%)"}},label:{display:"inline-flex",fontWeight:"medium",alignItems:"center",gap:"1"},valueText:{textStyle:"xs",lineHeight:"1",fontWeight:"medium"}},variants:{variant:{outline:{track:{shadow:"inset",bgColor:"bg.muted"},range:{bgColor:"colorPalette.solid"}},subtle:{track:{bgColor:"colorPalette.muted"},range:{bgColor:"colorPalette.solid/72"}}},shape:{square:{},rounded:{track:{borderRadius:"l1"}},full:{track:{borderRadius:"full"}}},striped:{true:{range:{backgroundImage:"linear-gradient(45deg, var(--stripe-color) 25%, transparent 25%, transparent 50%, var(--stripe-color) 50%, var(--stripe-color) 75%, transparent 75%, transparent)",backgroundSize:"var(--stripe-size) var(--stripe-size)","--stripe-size":"1rem","--stripe-color":{_light:"rgba(255, 255, 255, 0.3)",_dark:"rgba(0, 0, 0, 0.3)"}}}},animated:{true:{range:{"--animate-from":"var(--stripe-size)",animation:"bg-position 1s linear infinite"}}},size:{xs:{track:{h:"1.5"}},sm:{track:{h:"2"}},md:{track:{h:"2.5"}},lg:{track:{h:"3"}},xl:{track:{h:"4"}}}},defaultVariants:{variant:"outline",size:"md",shape:"rounded"}}),XI=Y({className:"chakra-progress-circle",slots:fl.keys(),base:{root:{display:"inline-flex",textStyle:"sm",position:"relative"},circle:{_indeterminate:{animation:"spin 2s linear infinite"}},circleTrack:{"--track-color":"colors.colorPalette.muted",stroke:"var(--track-color)"},circleRange:{stroke:"colorPalette.solid",transitionProperty:"stroke-dashoffset, stroke-dasharray",transitionDuration:"0.6s",_indeterminate:{animation:"circular-progress 1.5s linear infinite"}},label:{display:"inline-flex"},valueText:{lineHeight:"1",fontWeight:"medium",letterSpacing:"tight",fontVariantNumeric:"tabular-nums"}},variants:{size:{xs:{circle:{"--size":"24px","--thickness":"4px"},valueText:{textStyle:"2xs"}},sm:{circle:{"--size":"32px","--thickness":"5px"},valueText:{textStyle:"2xs"}},md:{circle:{"--size":"40px","--thickness":"6px"},valueText:{textStyle:"xs"}},lg:{circle:{"--size":"48px","--thickness":"7px"},valueText:{textStyle:"sm"}},xl:{circle:{"--size":"64px","--thickness":"8px"},valueText:{textStyle:"sm"}}}},defaultVariants:{size:"md"}}),YI=Y({slots:Uh.keys(),className:"chakra-qr-code",base:{root:{position:"relative",width:"fit-content","--qr-code-overlay-size":"calc(var(--qr-code-size) / 3)"},frame:{width:"var(--qr-code-size)",height:"var(--qr-code-size)",fill:"currentColor"},overlay:{display:"flex",alignItems:"center",justifyContent:"center",width:"var(--qr-code-overlay-size)",height:"var(--qr-code-overlay-size)",padding:"1",bg:"bg",rounded:"l1"}},variants:{size:{"2xs":{root:{"--qr-code-size":"40px"}},xs:{root:{"--qr-code-size":"64px"}},sm:{root:{"--qr-code-size":"80px"}},md:{root:{"--qr-code-size":"120px"}},lg:{root:{"--qr-code-size":"160px"}},xl:{root:{"--qr-code-size":"200px"}},"2xl":{root:{"--qr-code-size":"240px"}},full:{root:{"--qr-code-size":"100%"}}}},defaultVariants:{size:"md"}}),QI=Y({className:"chakra-radio-card",slots:tI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1.5",isolation:"isolate"},item:{flex:"1",display:"flex",flexDirection:"column",userSelect:"none",position:"relative",borderRadius:"l2",_focus:{bg:"colorPalette.muted/20"},_disabled:{opacity:"0.8",borderColor:"border.disabled"},_checked:{zIndex:"1"}},label:{display:"inline-flex",fontWeight:"medium",textStyle:"sm",_disabled:{opacity:"0.5"}},itemText:{fontWeight:"medium",flex:"1"},itemDescription:{opacity:"0.64",textStyle:"sm"},itemControl:{display:"inline-flex",flex:"1",pos:"relative",rounded:"inherit",justifyContent:"var(--radio-card-justify)",alignItems:"var(--radio-card-align)",_disabled:{bg:"bg.muted"}},itemIndicator:Fe.base,itemAddon:{roundedBottom:"inherit",_disabled:{color:"fg.muted"}},itemContent:{display:"flex",flexDirection:"column",flex:"1",gap:"1",justifyContent:"var(--radio-card-justify)",alignItems:"var(--radio-card-align)"}},variants:{size:{sm:{item:{textStyle:"sm"},itemControl:{padding:"3",gap:"1.5"},itemAddon:{px:"3",py:"1.5",borderTopWidth:"1px"},itemIndicator:(tv=Fe.variants)==null?void 0:tv.size.sm},md:{item:{textStyle:"sm"},itemControl:{padding:"4",gap:"2.5"},itemAddon:{px:"4",py:"2",borderTopWidth:"1px"},itemIndicator:(nv=Fe.variants)==null?void 0:nv.size.md},lg:{item:{textStyle:"md"},itemControl:{padding:"4",gap:"3.5"},itemAddon:{px:"4",py:"2",borderTopWidth:"1px"},itemIndicator:(rv=Fe.variants)==null?void 0:rv.size.lg}},variant:{surface:{item:{borderWidth:"1px",_checked:{bg:"colorPalette.subtle",color:"colorPalette.fg",borderColor:"colorPalette.muted"}},itemIndicator:(iv=Fe.variants)==null?void 0:iv.variant.solid},subtle:{item:{bg:"bg.muted"},itemControl:{_checked:{bg:"colorPalette.muted",color:"colorPalette.fg"}},itemIndicator:(ov=Fe.variants)==null?void 0:ov.variant.outline},outline:{item:{borderWidth:"1px",_checked:{boxShadow:"0 0 0 1px var(--shadow-color)",boxShadowColor:"colorPalette.solid",borderColor:"colorPalette.solid"}},itemIndicator:(sv=Fe.variants)==null?void 0:sv.variant.solid},solid:{item:{borderWidth:"1px",_checked:{bg:"colorPalette.solid",color:"colorPalette.contrast",borderColor:"colorPalette.solid"}},itemIndicator:(av=Fe.variants)==null?void 0:av.variant.inverted}},justify:{start:{item:{"--radio-card-justify":"flex-start"}},end:{item:{"--radio-card-justify":"flex-end"}},center:{item:{"--radio-card-justify":"center"}}},align:{start:{item:{"--radio-card-align":"flex-start"},itemControl:{textAlign:"start"}},end:{item:{"--radio-card-align":"flex-end"},itemControl:{textAlign:"end"}},center:{item:{"--radio-card-align":"center"},itemControl:{textAlign:"center"}}},orientation:{vertical:{itemControl:{flexDirection:"column"}},horizontal:{itemControl:{flexDirection:"row"}}}},defaultVariants:{size:"md",variant:"outline",align:"start",orientation:"horizontal"}}),JI=Y({className:"chakra-radio-group",slots:eg.keys(),base:{item:{display:"inline-flex",alignItems:"center",position:"relative",fontWeight:"medium",_disabled:{cursor:"disabled"}},itemControl:Fe.base,label:{userSelect:"none",textStyle:"sm",_disabled:{opacity:"0.5"}}},variants:{variant:{outline:{itemControl:(cv=(lv=Fe.variants)==null?void 0:lv.variant)==null?void 0:cv.outline},subtle:{itemControl:(dv=(uv=Fe.variants)==null?void 0:uv.variant)==null?void 0:dv.subtle},solid:{itemControl:(fv=(hv=Fe.variants)==null?void 0:hv.variant)==null?void 0:fv.solid}},size:{xs:{item:{textStyle:"xs",gap:"1.5"},itemControl:(pv=(gv=Fe.variants)==null?void 0:gv.size)==null?void 0:pv.xs},sm:{item:{textStyle:"sm",gap:"2"},itemControl:(vv=(mv=Fe.variants)==null?void 0:mv.size)==null?void 0:vv.sm},md:{item:{textStyle:"sm",gap:"2.5"},itemControl:(yv=(bv=Fe.variants)==null?void 0:bv.size)==null?void 0:yv.md},lg:{item:{textStyle:"md",gap:"3"},itemControl:(Cv=(xv=Fe.variants)==null?void 0:xv.size)==null?void 0:Cv.lg}}},defaultVariants:{size:"md",variant:"solid"}}),ZI=Y({className:"chakra-rating-group",slots:nI.keys(),base:{root:{display:"inline-flex"},control:{display:"inline-flex",alignItems:"center"},item:{display:"inline-flex",alignItems:"center",justifyContent:"center",userSelect:"none"},itemIndicator:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:"1em",height:"1em",position:"relative","--clip-path":{base:"inset(0 50% 0 0)",_rtl:"inset(0 0 0 50%)"},_icon:{stroke:"currentColor",width:"100%",height:"100%",display:"inline-block",flexShrink:0,position:"absolute",left:0,top:0},"& [data-bg]":{color:"bg.emphasized"},"& [data-fg]":{color:"transparent"},"&[data-highlighted]:not([data-half])":{"& [data-fg]":{color:"colorPalette.solid"}},"&[data-half]":{"& [data-fg]":{color:"colorPalette.solid",clipPath:"var(--clip-path)"}}}},variants:{size:{xs:{item:{textStyle:"sm"}},sm:{item:{textStyle:"md"}},md:{item:{textStyle:"xl"}},lg:{item:{textStyle:"2xl"}}}},defaultVariants:{size:"md"}}),eP=Y({className:"chakra-scroll-area",slots:qh.keys(),base:{root:{display:"flex",flexDirection:"column",width:"100%",height:"100%",position:"relative",overflow:"hidden","--scrollbar-margin":"2px","--scrollbar-click-area":"calc(var(--scrollbar-size) + calc(var(--scrollbar-margin) * 2))"},viewport:{display:"flex",flexDirection:"column",height:"100%",width:"100%",borderRadius:"inherit",WebkitOverflowScrolling:"touch",scrollbarWidth:"none","&::-webkit-scrollbar":{display:"none"}},content:{minWidth:"100%"},scrollbar:{display:"flex",userSelect:"none",touchAction:"none",borderRadius:"full",colorPalette:"gray",transition:"opacity 150ms 300ms",position:"relative",margin:"var(--scrollbar-margin)","&:not([data-overflow-x], [data-overflow-y])":{display:"none"},bg:"{colors.colorPalette.solid/10}","--thumb-bg":"{colors.colorPalette.solid/25}","&:is(:hover, :active)":{"--thumb-bg":"{colors.colorPalette.solid/50}"},_before:{content:'""',position:"absolute"},_vertical:{width:"var(--scrollbar-size)",flexDirection:"column","&::before":{width:"var(--scrollbar-click-area)",height:"100%",insetInlineStart:"calc(var(--scrollbar-margin) * -1)"}},_horizontal:{height:"var(--scrollbar-size)",flexDirection:"row","&::before":{height:"var(--scrollbar-click-area)",width:"100%",top:"calc(var(--scrollbar-margin) * -1)"}}},thumb:{borderRadius:"inherit",bg:"var(--thumb-bg)",transition:"backgrounds",_vertical:{width:"full"},_horizontal:{height:"full"}},corner:{bg:"bg.muted",margin:"var(--scrollbar-margin)",opacity:0,transition:"opacity 150ms 300ms","&[data-hover]":{transitionDelay:"0ms",opacity:1}}},variants:{variant:{hover:{scrollbar:{opacity:"0","&[data-hover], &[data-scrolling]":{opacity:"1",transitionDuration:"faster",transitionDelay:"0ms"}}},always:{scrollbar:{opacity:"1"}}},size:{xs:{root:{"--scrollbar-size":"sizes.1"}},sm:{root:{"--scrollbar-size":"sizes.1.5"}},md:{root:{"--scrollbar-size":"sizes.2"}},lg:{root:{"--scrollbar-size":"sizes.3"}}}},defaultVariants:{size:"md",variant:"hover"}}),tP=Y({className:"chakra-segment-group",slots:Kh.keys(),base:{root:{"--segment-radius":"radii.l2",borderRadius:"l2",display:"inline-flex",boxShadow:"inset",minW:"max-content",textAlign:"center",position:"relative",isolation:"isolate",bg:"bg.muted",_vertical:{flexDirection:"column"}},item:{display:"flex",alignItems:"center",justifyContent:"center",userSelect:"none",fontSize:"sm",position:"relative",color:"fg",borderRadius:"var(--segment-radius)",_disabled:{opacity:"0.5"},"&:has(input:focus-visible)":{focusRing:"outside"},_before:{content:'""',position:"absolute",bg:"border",transition:"opacity 0.2s"},_horizontal:{_before:{insetInlineStart:0,insetBlock:"1.5",width:"1px"}},_vertical:{_before:{insetBlockStart:0,insetInline:"1.5",height:"1px"}},"& + &[data-state=checked], &[data-state=checked] + &, &:first-of-type":{_before:{opacity:"0"}},"&[data-state=checked][data-ssr]":{shadow:"sm",bg:"bg",borderRadius:"var(--segment-radius)"}},indicator:{shadow:"sm",pos:"absolute",bg:{_light:"bg",_dark:"bg.emphasized"},width:"var(--width)",height:"var(--height)",top:"var(--top)",left:"var(--left)",zIndex:-1,borderRadius:"var(--segment-radius)"}},variants:{size:{xs:{item:{textStyle:"xs",px:"3",gap:"1",height:"6"}},sm:{item:{textStyle:"sm",px:"4",gap:"2",height:"8"}},md:{item:{textStyle:"sm",px:"4",gap:"2",height:"10"}},lg:{item:{textStyle:"md",px:"4.5",gap:"3",height:"11"}}}},defaultVariants:{size:"md"}}),nP=Y({className:"chakra-slider",slots:oI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1",textStyle:"sm",position:"relative",isolation:"isolate",touchAction:"none"},label:{fontWeight:"medium",textStyle:"sm"},control:{display:"inline-flex",alignItems:"center",position:"relative"},track:{overflow:"hidden",borderRadius:"full",flex:"1"},range:{width:"inherit",height:"inherit",_disabled:{bg:"border.emphasized!"}},markerGroup:{position:"absolute!",zIndex:"1"},marker:{"--marker-bg":{base:"white",_underValue:"colors.bg"},display:"flex",alignItems:"center",gap:"calc(var(--slider-thumb-size) / 2)",color:"fg.muted",textStyle:"xs"},markerIndicator:{width:"var(--slider-marker-size)",height:"var(--slider-marker-size)",borderRadius:"full",bg:"var(--marker-bg)"},thumb:{width:"var(--slider-thumb-size)",height:"var(--slider-thumb-size)",display:"flex",alignItems:"center",justifyContent:"center",outline:0,zIndex:"2",borderRadius:"full",_focusVisible:{ring:"2px",ringColor:"colorPalette.focusRing",ringOffset:"2px",ringOffsetColor:"bg"}}},variants:{size:{sm:{root:{"--slider-thumb-size":"sizes.4","--slider-track-size":"sizes.1.5","--slider-marker-center":"6px","--slider-marker-size":"sizes.1","--slider-marker-inset":"3px"}},md:{root:{"--slider-thumb-size":"sizes.5","--slider-track-size":"sizes.2","--slider-marker-center":"8px","--slider-marker-size":"sizes.1","--slider-marker-inset":"4px"}},lg:{root:{"--slider-thumb-size":"sizes.6","--slider-track-size":"sizes.2.5","--slider-marker-center":"9px","--slider-marker-size":"sizes.1.5","--slider-marker-inset":"5px"}}},variant:{outline:{track:{shadow:"inset",bg:"bg.emphasized/72"},range:{bg:"colorPalette.solid"},thumb:{borderWidth:"2px",borderColor:"colorPalette.solid",bg:"bg",_disabled:{bg:"border.emphasized",borderColor:"border.emphasized"}}},solid:{track:{bg:"colorPalette.subtle",_disabled:{bg:"bg.muted"}},range:{bg:"colorPalette.solid"},thumb:{bg:"colorPalette.solid",_disabled:{bg:"border.emphasized"}}}},orientation:{vertical:{root:{display:"inline-flex"},control:{flexDirection:"column",height:"100%",minWidth:"var(--slider-thumb-size)","&[data-has-mark-label], &:has(.chakra-slider__marker-label)":{marginEnd:"4"}},track:{width:"var(--slider-track-size)"},thumb:{left:"50%",translate:"-50% 0"},markerGroup:{insetStart:"var(--slider-marker-center)",insetBlock:"var(--slider-marker-inset)"},marker:{flexDirection:"row"}},horizontal:{control:{flexDirection:"row",width:"100%",minHeight:"var(--slider-thumb-size)","&[data-has-mark-label], &:has(.chakra-slider__marker-label)":{marginBottom:"4"}},track:{height:"var(--slider-track-size)"},thumb:{top:"50%",translate:"0 -50%"},markerGroup:{top:"var(--slider-marker-center)",insetInline:"var(--slider-marker-inset)"},marker:{flexDirection:"column"}}}},defaultVariants:{size:"md",variant:"outline",orientation:"horizontal"}}),rP=Y({className:"chakra-stat",slots:sI.keys(),base:{root:{display:"flex",flexDirection:"column",gap:"1",position:"relative",flex:"1"},label:{display:"inline-flex",gap:"1.5",alignItems:"center",color:"fg.muted",textStyle:"sm"},helpText:{color:"fg.muted",textStyle:"xs"},valueUnit:{color:"fg.muted",textStyle:"xs",fontWeight:"initial",letterSpacing:"initial"},valueText:{verticalAlign:"baseline",fontWeight:"semibold",letterSpacing:"tight",fontFeatureSettings:"pnum",fontVariantNumeric:"proportional-nums",display:"inline-flex",gap:"1"},indicator:{display:"inline-flex",alignItems:"center",justifyContent:"center",marginEnd:1,"& :where(svg)":{w:"1em",h:"1em"},"&[data-type=up]":{color:"fg.success"},"&[data-type=down]":{color:"fg.error"}}},variants:{size:{sm:{valueText:{textStyle:"xl"}},md:{valueText:{textStyle:"2xl"}},lg:{valueText:{textStyle:"3xl"}}}},defaultVariants:{size:"md"}}),iP=Y({className:"chakra-status",slots:aI.keys(),base:{root:{display:"inline-flex",alignItems:"center",gap:"2"},indicator:{width:"0.64em",height:"0.64em",flexShrink:0,borderRadius:"full",forcedColorAdjust:"none",bg:"colorPalette.solid"}},variants:{size:{sm:{root:{textStyle:"xs"}},md:{root:{textStyle:"sm"}},lg:{root:{textStyle:"md"}}}},defaultVariants:{size:"md"}}),oP=Y({className:"chakra-steps",slots:lI.keys(),base:{root:{display:"flex",width:"full"},list:{display:"flex",justifyContent:"space-between","--steps-gutter":"spacing.3","--steps-thickness":"2px"},title:{fontWeight:"medium",color:"fg"},description:{color:"fg.muted"},separator:{bg:"border",flex:"1"},indicator:{display:"flex",justifyContent:"center",alignItems:"center",flexShrink:"0",borderRadius:"full",fontWeight:"medium",width:"var(--steps-size)",height:"var(--steps-size)",_icon:{flexShrink:"0",width:"var(--steps-icon-size)",height:"var(--steps-icon-size)"}},item:{position:"relative",display:"flex",gap:"3",flex:"1 0 0","&:last-of-type":{flex:"initial","& [data-part=separator]":{display:"none"}}},trigger:{display:"flex",alignItems:"center",gap:"3",textAlign:"start",focusVisibleRing:"outside",borderRadius:"l2"},content:{focusVisibleRing:"outside"}},variants:{orientation:{vertical:{root:{flexDirection:"row",height:"100%"},list:{flexDirection:"column",alignItems:"flex-start"},separator:{position:"absolute",width:"var(--steps-thickness)",height:"100%",maxHeight:"calc(100% - var(--steps-size) - var(--steps-gutter) * 2)",top:"calc(var(--steps-size) + var(--steps-gutter))",insetStart:"calc(var(--steps-size) / 2 - 1px)"},item:{alignItems:"flex-start"}},horizontal:{root:{flexDirection:"column",width:"100%"},list:{flexDirection:"row",alignItems:"center"},separator:{width:"100%",height:"var(--steps-thickness)",marginX:"var(--steps-gutter)"},item:{alignItems:"center"}}},variant:{solid:{indicator:{_incomplete:{borderWidth:"var(--steps-thickness)"},_current:{bg:"colorPalette.muted",borderWidth:"var(--steps-thickness)",borderColor:"colorPalette.solid",color:"colorPalette.fg"},_complete:{bg:"colorPalette.solid",borderColor:"colorPalette.solid",color:"colorPalette.contrast"}},separator:{_complete:{bg:"colorPalette.solid"}}},subtle:{indicator:{_incomplete:{bg:"bg.muted"},_current:{bg:"colorPalette.muted",color:"colorPalette.fg"},_complete:{bg:"colorPalette.emphasized",color:"colorPalette.fg"}},separator:{_complete:{bg:"colorPalette.emphasized"}}}},size:{xs:{root:{gap:"2.5"},list:{"--steps-size":"sizes.6","--steps-icon-size":"sizes.3.5",textStyle:"xs"},title:{textStyle:"sm"}},sm:{root:{gap:"3"},list:{"--steps-size":"sizes.8","--steps-icon-size":"sizes.4",textStyle:"xs"},title:{textStyle:"sm"}},md:{root:{gap:"4"},list:{"--steps-size":"sizes.10","--steps-icon-size":"sizes.4",textStyle:"sm"},title:{textStyle:"sm"}},lg:{root:{gap:"6"},list:{"--steps-size":"sizes.11","--steps-icon-size":"sizes.5",textStyle:"md"},title:{textStyle:"md"}}}},defaultVariants:{size:"md",variant:"solid",orientation:"horizontal"}}),sP=Y({slots:cI.keys(),className:"chakra-switch",base:{root:{display:"inline-flex",gap:"2.5",alignItems:"center",position:"relative",verticalAlign:"middle","--switch-diff":"calc(var(--switch-width) - var(--switch-height))","--switch-x":{base:"var(--switch-diff)",_rtl:"calc(var(--switch-diff) * -1)"}},label:{lineHeight:"1",userSelect:"none",fontSize:"sm",fontWeight:"medium",_disabled:{opacity:"0.5"}},indicator:{position:"absolute",height:"var(--switch-height)",width:"var(--switch-height)",fontSize:"var(--switch-indicator-font-size)",fontWeight:"medium",flexShrink:0,userSelect:"none",display:"grid",placeContent:"center",transition:"inset-inline-start 0.12s ease",insetInlineStart:"calc(var(--switch-x) - 2px)",_checked:{insetInlineStart:"2px"}},control:{display:"inline-flex",gap:"0.5rem",flexShrink:0,justifyContent:"flex-start",cursor:"switch",borderRadius:"full",position:"relative",width:"var(--switch-width)",height:"var(--switch-height)",transition:"backgrounds",_disabled:{opacity:"0.5",cursor:"not-allowed"},_invalid:{outline:"2px solid",outlineColor:"border.error",outlineOffset:"2px"}},thumb:{display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,transitionProperty:"translate",transitionDuration:"fast",borderRadius:"inherit",_checked:{translate:"var(--switch-x) 0"}}},variants:{variant:{solid:{control:{borderRadius:"full",bg:"bg.emphasized",focusVisibleRing:"outside",_checked:{bg:"colorPalette.solid"}},thumb:{bg:"white",width:"var(--switch-height)",height:"var(--switch-height)",scale:"0.8",boxShadow:"sm",_checked:{bg:"colorPalette.contrast"}}},raised:{control:{borderRadius:"full",height:"calc(var(--switch-height) / 2)",bg:"bg.muted",boxShadow:"inset",_checked:{bg:"colorPalette.solid/60"}},thumb:{width:"var(--switch-height)",height:"var(--switch-height)",position:"relative",top:"calc(var(--switch-height) * -0.25)",bg:"white",boxShadow:"xs",focusVisibleRing:"outside",_checked:{bg:"colorPalette.solid"}}}},size:{xs:{root:{"--switch-width":"sizes.6","--switch-height":"sizes.3","--switch-indicator-font-size":"fontSizes.xs"}},sm:{root:{"--switch-width":"sizes.8","--switch-height":"sizes.4","--switch-indicator-font-size":"fontSizes.xs"}},md:{root:{"--switch-width":"sizes.10","--switch-height":"sizes.5","--switch-indicator-font-size":"fontSizes.sm"}},lg:{root:{"--switch-width":"sizes.12","--switch-height":"sizes.6","--switch-indicator-font-size":"fontSizes.md"}}}},defaultVariants:{variant:"solid",size:"md"}}),aP=Y({className:"chakra-table",slots:uI.keys(),base:{root:{fontVariantNumeric:"lining-nums tabular-nums",borderCollapse:"collapse",width:"full",textAlign:"start",verticalAlign:"top"},row:{_selected:{bg:"colorPalette.subtle"}},cell:{textAlign:"start",alignItems:"center"},columnHeader:{fontWeight:"medium",textAlign:"start",color:"fg"},caption:{fontWeight:"medium",textStyle:"xs"},footer:{fontWeight:"medium"}},variants:{interactive:{true:{body:{"& tr":{_hover:{bg:"colorPalette.subtle"}}}}},stickyHeader:{true:{header:{"& :where(tr)":{top:"var(--table-sticky-offset, 0)",position:"sticky",zIndex:1}}}},striped:{true:{row:{"&:nth-of-type(odd) td":{bg:"bg.muted"}}}},showColumnBorder:{true:{columnHeader:{"&:not(:last-of-type)":{borderInlineEndWidth:"1px"}},cell:{"&:not(:last-of-type)":{borderInlineEndWidth:"1px"}}}},variant:{line:{columnHeader:{borderBottomWidth:"1px"},cell:{borderBottomWidth:"1px"},row:{bg:"bg"}},outline:{root:{boxShadow:"0 0 0 1px {colors.border}",overflow:"hidden"},columnHeader:{borderBottomWidth:"1px"},header:{bg:"bg.muted"},row:{"&:not(:last-of-type)":{borderBottomWidth:"1px"}},footer:{borderTopWidth:"1px"}}},size:{sm:{root:{textStyle:"sm"},columnHeader:{px:"2",py:"2"},cell:{px:"2",py:"2"}},md:{root:{textStyle:"sm"},columnHeader:{px:"3",py:"3"},cell:{px:"3",py:"3"}},lg:{root:{textStyle:"md"},columnHeader:{px:"4",py:"3"},cell:{px:"4",py:"3"}}}},defaultVariants:{variant:"line",size:"md"}}),lP=Y({slots:hI.keys(),className:"chakra-tabs",base:{root:{"--tabs-trigger-radius":"radii.l2",position:"relative",_horizontal:{display:"block"},_vertical:{display:"flex"}},list:{display:"inline-flex",position:"relative",isolation:"isolate","--tabs-indicator-shadow":"shadows.xs","--tabs-indicator-bg":"colors.bg",minH:"var(--tabs-height)",_horizontal:{flexDirection:"row"},_vertical:{flexDirection:"column"}},trigger:{outline:"0",minW:"var(--tabs-height)",height:"var(--tabs-height)",display:"flex",alignItems:"center",fontWeight:"medium",position:"relative",cursor:"button",gap:"2",_focusVisible:{zIndex:1,outline:"2px solid",outlineColor:"colorPalette.focusRing"},_disabled:{cursor:"not-allowed",opacity:.5}},content:{focusVisibleRing:"inside",_horizontal:{width:"100%",pt:"var(--tabs-content-padding)"},_vertical:{height:"100%",ps:"var(--tabs-content-padding)"}},indicator:{width:"var(--width)",height:"var(--height)",borderRadius:"var(--tabs-indicator-radius)",bg:"var(--tabs-indicator-bg)",shadow:"var(--tabs-indicator-shadow)",zIndex:-1}},variants:{fitted:{true:{list:{display:"flex"},trigger:{flex:1,textAlign:"center",justifyContent:"center"}}},justify:{start:{list:{justifyContent:"flex-start"}},center:{list:{justifyContent:"center"}},end:{list:{justifyContent:"flex-end"}}},size:{sm:{root:{"--tabs-height":"sizes.9","--tabs-content-padding":"spacing.3"},trigger:{py:"1",px:"3",textStyle:"sm"}},md:{root:{"--tabs-height":"sizes.10","--tabs-content-padding":"spacing.4"},trigger:{py:"2",px:"4",textStyle:"sm"}},lg:{root:{"--tabs-height":"sizes.11","--tabs-content-padding":"spacing.4.5"},trigger:{py:"2",px:"4.5",textStyle:"md"}}},variant:{line:{list:{display:"flex",borderColor:"border",_horizontal:{borderBottomWidth:"1px"},_vertical:{borderEndWidth:"1px"}},trigger:{color:"fg.muted",_disabled:{_active:{bg:"initial"}},_selected:{color:"fg",_horizontal:{layerStyle:"indicator.bottom","--indicator-offset-y":"-1px","--indicator-color":"colors.colorPalette.solid"},_vertical:{layerStyle:"indicator.end","--indicator-offset-x":"-1px"}}}},subtle:{trigger:{borderRadius:"var(--tabs-trigger-radius)",color:"fg.muted",_selected:{bg:"colorPalette.subtle",color:"colorPalette.fg"}}},enclosed:{list:{bg:"bg.muted",padding:"1",borderRadius:"l3",minH:"calc(var(--tabs-height) - 4px)"},trigger:{justifyContent:"center",color:"fg.muted",borderRadius:"var(--tabs-trigger-radius)",_selected:{bg:"bg",color:"colorPalette.fg",shadow:"xs"}}},outline:{list:{"--line-thickness":"1px","--line-offset":"calc(var(--line-thickness) * -1)",borderColor:"border",display:"flex",_horizontal:{_before:{content:'""',position:"absolute",bottom:"0px",width:"100%",borderBottomWidth:"var(--line-thickness)",borderBottomColor:"border"}},_vertical:{_before:{content:'""',position:"absolute",insetInline:"var(--line-offset)",height:"calc(100% - calc(var(--line-thickness) * 2))",borderEndWidth:"var(--line-thickness)",borderEndColor:"border"}}},trigger:{color:"fg.muted",borderWidth:"1px",borderColor:"transparent",_selected:{bg:"currentBg",color:"colorPalette.fg"},_horizontal:{borderTopRadius:"var(--tabs-trigger-radius)",marginBottom:"var(--line-offset)",marginEnd:{_notLast:"var(--line-offset)"},_selected:{borderColor:"border",borderBottomColor:"transparent"}},_vertical:{borderStartRadius:"var(--tabs-trigger-radius)",marginEnd:"var(--line-offset)",marginBottom:{_notLast:"var(--line-offset)"},_selected:{borderColor:"border",borderEndColor:"transparent"}}}},plain:{trigger:{color:"fg.muted",_selected:{color:"colorPalette.fg"},borderRadius:"var(--tabs-trigger-radius)","&[data-selected][data-ssr]":{bg:"var(--tabs-indicator-bg)",shadow:"var(--tabs-indicator-shadow)",borderRadius:"var(--tabs-indicator-radius)"}}}}},defaultVariants:{size:"md",variant:"line"}}),ut=(Sv=Nl.variants)==null?void 0:Sv.variant,cP=Y({slots:fI.keys(),className:"chakra-tag",base:{root:{display:"inline-flex",alignItems:"center",verticalAlign:"top",maxWidth:"100%",userSelect:"none",borderRadius:"l2",focusVisibleRing:"outside"},label:{lineClamp:"1"},closeTrigger:{display:"flex",alignItems:"center",justifyContent:"center",outline:"0",borderRadius:"l1",color:"currentColor",focusVisibleRing:"inside",focusRingWidth:"2px"},startElement:{flexShrink:0,boxSize:"var(--tag-element-size)",ms:"var(--tag-element-offset)","&:has([data-scope=avatar])":{boxSize:"var(--tag-avatar-size)",ms:"calc(var(--tag-element-offset) * 1.5)"},_icon:{boxSize:"100%"}},endElement:{flexShrink:0,boxSize:"var(--tag-element-size)",me:"var(--tag-element-offset)",_icon:{boxSize:"100%"},"&:has(button)":{ms:"calc(var(--tag-element-offset) * -1)"}}},variants:{size:{sm:{root:{px:"1.5",minH:"4.5",gap:"1","--tag-avatar-size":"spacing.3","--tag-element-size":"spacing.3","--tag-element-offset":"-2px"},label:{textStyle:"xs"}},md:{root:{px:"1.5",minH:"5",gap:"1","--tag-avatar-size":"spacing.3.5","--tag-element-size":"spacing.3.5","--tag-element-offset":"-2px"},label:{textStyle:"xs"}},lg:{root:{px:"2",minH:"6",gap:"1.5","--tag-avatar-size":"spacing.4.5","--tag-element-size":"spacing.4","--tag-element-offset":"-3px"},label:{textStyle:"sm"}},xl:{root:{px:"2.5",minH:"8",gap:"1.5","--tag-avatar-size":"spacing.6","--tag-element-size":"spacing.4.5","--tag-element-offset":"-4px"},label:{textStyle:"sm"}}},variant:{subtle:{root:ut==null?void 0:ut.subtle},solid:{root:ut==null?void 0:ut.solid},outline:{root:ut==null?void 0:ut.outline},surface:{root:ut==null?void 0:ut.surface}}},defaultVariants:{size:"md",variant:"surface"}}),uP=Y({slots:gI.keys(),className:"chakra-timeline",base:{root:{display:"flex",flexDirection:"column",width:"full","--timeline-thickness":"1px","--timeline-gutter":"4px"},item:{display:"flex",position:"relative",alignItems:"flex-start",flexShrink:0,gap:"4",_last:{"& :where(.chakra-timeline__separator)":{display:"none"}}},separator:{position:"absolute",borderStartWidth:"var(--timeline-thickness)",ms:"calc(-1 * var(--timeline-thickness) / 2)",insetInlineStart:"calc(var(--timeline-indicator-size) / 2)",insetBlock:"0",borderColor:"border"},indicator:{outline:"2px solid {colors.bg}",position:"relative",flexShrink:"0",boxSize:"var(--timeline-indicator-size)",fontSize:"var(--timeline-font-size)",display:"flex",alignItems:"center",justifyContent:"center",borderRadius:"full",fontWeight:"medium"},connector:{alignSelf:"stretch",position:"relative"},content:{pb:"6",display:"flex",flexDirection:"column",width:"full",gap:"2"},title:{display:"flex",fontWeight:"medium",flexWrap:"wrap",gap:"1.5",alignItems:"center",mt:"var(--timeline-margin)"},description:{color:"fg.muted",textStyle:"xs"}},variants:{variant:{subtle:{indicator:{bg:"colorPalette.muted"}},solid:{indicator:{bg:"colorPalette.solid",color:"colorPalette.contrast"}},outline:{indicator:{bg:"currentBg",borderWidth:"1px",borderColor:"colorPalette.muted"}},plain:{}},size:{sm:{root:{"--timeline-indicator-size":"sizes.4","--timeline-font-size":"fontSizes.2xs"},title:{textStyle:"xs"}},md:{root:{"--timeline-indicator-size":"sizes.5","--timeline-font-size":"fontSizes.xs"},title:{textStyle:"sm"}},lg:{root:{"--timeline-indicator-size":"sizes.6","--timeline-font-size":"fontSizes.xs"},title:{mt:"0.5",textStyle:"sm"}},xl:{root:{"--timeline-indicator-size":"sizes.8","--timeline-font-size":"fontSizes.sm"},title:{mt:"1.5",textStyle:"sm"}}}},defaultVariants:{size:"md",variant:"solid"}}),dP=Y({slots:dI.keys(),className:"chakra-toast",base:{root:{width:"full",display:"flex",alignItems:"flex-start",position:"relative",gap:"3",py:"4",ps:"4",pe:"6",borderRadius:"l2",translate:"var(--x) var(--y)",scale:"var(--scale)",zIndex:"var(--z-index)",height:"var(--height)",opacity:"var(--opacity)",willChange:"translate, opacity, scale",transition:"translate 400ms, scale 400ms, opacity 400ms, height 400ms, box-shadow 200ms",transitionTimingFunction:"cubic-bezier(0.21, 1.02, 0.73, 1)",_closed:{transition:"translate 400ms, scale 400ms, opacity 200ms",transitionTimingFunction:"cubic-bezier(0.06, 0.71, 0.55, 1)"},bg:"bg.panel",color:"fg",boxShadow:"xl","--toast-trigger-bg":"colors.bg.muted","&[data-type=warning]":{bg:"orange.solid",color:"orange.contrast","--toast-trigger-bg":"{white/10}","--toast-border-color":"{white/40}"},"&[data-type=success]":{bg:"green.solid",color:"green.contrast","--toast-trigger-bg":"{white/10}","--toast-border-color":"{white/40}"},"&[data-type=error]":{bg:"red.solid",color:"red.contrast","--toast-trigger-bg":"{white/10}","--toast-border-color":"{white/40}"}},title:{fontWeight:"medium",textStyle:"sm",marginEnd:"2"},description:{display:"inline",textStyle:"sm",opacity:"0.8"},indicator:{flexShrink:"0",boxSize:"5"},actionTrigger:{textStyle:"sm",fontWeight:"medium",height:"8",px:"3",borderRadius:"l2",alignSelf:"center",borderWidth:"1px",borderColor:"var(--toast-border-color, inherit)",transition:"background 200ms",_hover:{bg:"var(--toast-trigger-bg)"}},closeTrigger:{position:"absolute",top:"1",insetEnd:"1",padding:"1",display:"inline-flex",alignItems:"center",justifyContent:"center",color:"{currentColor/60}",borderRadius:"l2",textStyle:"md",transition:"background 200ms",_icon:{boxSize:"1em"}}}}),hP=Y({slots:tf.keys(),className:"chakra-tooltip",base:{content:{"--tooltip-bg":"colors.bg.inverted",bg:"var(--tooltip-bg)",color:"fg.inverted",px:"2.5",py:"1",borderRadius:"l2",fontWeight:"medium",textStyle:"xs",boxShadow:"md",maxW:"xs",zIndex:"tooltip",transformOrigin:"var(--transform-origin)",_open:{animationStyle:"scale-fade-in",animationDuration:"fast"},_closed:{animationStyle:"scale-fade-out",animationDuration:"fast"}},arrow:{"--arrow-size":"sizes.2","--arrow-background":"var(--tooltip-bg)"},arrowTip:{borderTopWidth:"1px",borderInlineStartWidth:"1px",borderColor:"var(--tooltip-bg)"}}}),ig=Tr({display:"flex",alignItems:"center",gap:"var(--tree-item-gap)",rounded:"l2",userSelect:"none",position:"relative","--tree-depth":"calc(var(--depth) - 1)","--tree-indentation-offset":"calc(var(--tree-indentation) * var(--tree-depth))","--tree-icon-offset":"calc(var(--tree-icon-size) * var(--tree-depth) * 0.5)","--tree-offset":"calc(var(--tree-padding-inline) + var(--tree-indentation-offset) + var(--tree-icon-offset))",ps:"var(--tree-offset)",pe:"var(--tree-padding-inline)",py:"var(--tree-padding-block)",focusVisibleRing:"inside",focusRingColor:"border.emphasized",focusRingWidth:"2px","&:hover, &:focus-visible":{bg:"bg.muted"},_disabled:{layerStyle:"disabled"}}),og=Tr({flex:"1"}),sg=Tr({_selected:{bg:"colorPalette.subtle",color:"colorPalette.fg"}}),ag=Tr({_selected:{layerStyle:"fill.solid"}}),fP=Y({slots:Eh.keys(),className:"chakra-tree-view",base:{root:{width:"full",display:"flex",flexDirection:"column",gap:"2"},tree:{display:"flex",flexDirection:"column","--tree-item-gap":"spacing.2",_icon:{boxSize:"var(--tree-icon-size)"}},label:{fontWeight:"medium",textStyle:"sm"},branch:{position:"relative"},branchContent:{position:"relative"},branchIndentGuide:{height:"100%",width:"1px",bg:"border",position:"absolute","--tree-depth":"calc(var(--depth) - 1)","--tree-indentation-offset":"calc(var(--tree-indentation) * var(--tree-depth))","--tree-offset":"calc(var(--tree-padding-inline) + var(--tree-indentation-offset))","--tree-icon-offset":"calc(var(--tree-icon-size) * 0.5 * var(--depth))",insetInlineStart:"calc(var(--tree-offset) + var(--tree-icon-offset))",zIndex:"1"},branchIndicator:{color:"fg.muted",transformOrigin:"center",transitionDuration:"normal",transitionProperty:"transform",transitionTimingFunction:"default",_open:{transform:"rotate(90deg)"}},branchTrigger:{display:"inline-flex",alignItems:"center",justifyContent:"center"},branchControl:ig,item:ig,itemText:og,branchText:og,nodeCheckbox:{display:"inline-flex"}},variants:{size:{md:{tree:{textStyle:"sm","--tree-indentation":"spacing.4","--tree-padding-inline":"spacing.3","--tree-padding-block":"spacing.1.5","--tree-icon-size":"spacing.4"}},sm:{tree:{textStyle:"sm","--tree-indentation":"spacing.4","--tree-padding-inline":"spacing.3","--tree-padding-block":"spacing.1","--tree-icon-size":"spacing.3"}},xs:{tree:{textStyle:"xs","--tree-indentation":"spacing.4","--tree-padding-inline":"spacing.2","--tree-padding-block":"spacing.1","--tree-icon-size":"spacing.3"}}},variant:{subtle:{branchControl:sg,item:sg},solid:{branchControl:ag,item:ag}},animateContent:{true:{branchContent:{_open:{animationName:"expand-height, fade-in",animationDuration:"moderate"},_closed:{animationName:"collapse-height, fade-out",animationDuration:"moderate"}}}}},defaultVariants:{size:"md",variant:"subtle"}}),gP={accordion:bI,actionBar:yI,alert:xI,avatar:CI,blockquote:SI,breadcrumb:wI,card:EI,checkbox:kI,checkboxCard:OI,codeBlock:II,collapsible:PI,dataList:NI,dialog:AI,drawer:_I,editable:VI,emptyState:FI,field:LI,fieldset:DI,fileUpload:zI,hoverCard:MI,list:$I,listbox:BI,menu:jI,nativeSelect:WI,numberInput:HI,pinInput:GI,popover:qI,progress:KI,progressCircle:XI,radioCard:QI,radioGroup:JI,ratingGroup:ZI,scrollArea:eP,segmentGroup:tP,select:hs,combobox:TI,slider:nP,stat:rP,steps:oP,switch:sP,table:aP,tabs:lP,tag:cP,toast:dP,tooltip:hP,status:iP,timeline:uP,colorPicker:RI,qrCode:YI,treeView:fP},pP=YE({"2xs":{value:{fontSize:"2xs",lineHeight:"0.75rem"}},xs:{value:{fontSize:"xs",lineHeight:"1rem"}},sm:{value:{fontSize:"sm",lineHeight:"1.25rem"}},md:{value:{fontSize:"md",lineHeight:"1.5rem"}},lg:{value:{fontSize:"lg",lineHeight:"1.75rem"}},xl:{value:{fontSize:"xl",lineHeight:"1.875rem"}},"2xl":{value:{fontSize:"2xl",lineHeight:"2rem"}},"3xl":{value:{fontSize:"3xl",lineHeight:"2.375rem"}},"4xl":{value:{fontSize:"4xl",lineHeight:"2.75rem",letterSpacing:"-0.025em"}},"5xl":{value:{fontSize:"5xl",lineHeight:"3.75rem",letterSpacing:"-0.025em"}},"6xl":{value:{fontSize:"6xl",lineHeight:"4.5rem",letterSpacing:"-0.025em"}},"7xl":{value:{fontSize:"7xl",lineHeight:"5.75rem",letterSpacing:"-0.025em"}},none:{value:{}},label:{value:{fontSize:"sm",lineHeight:"1.25rem",fontWeight:"medium"}}}),mP=xe.animations({spin:{value:"spin 1s linear infinite"},ping:{value:"ping 1s cubic-bezier(0, 0, 0.2, 1) infinite"},pulse:{value:"pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"},bounce:{value:"bounce 1s infinite"}}),vP=xe.aspectRatios({square:{value:"1 / 1"},landscape:{value:"4 / 3"},portrait:{value:"3 / 4"},wide:{value:"16 / 9"},ultrawide:{value:"18 / 5"},golden:{value:"1.618 / 1"}}),bP=xe.blurs({none:{value:" "},sm:{value:"4px"},md:{value:"8px"},lg:{value:"12px"},xl:{value:"16px"},"2xl":{value:"24px"},"3xl":{value:"40px"},"4xl":{value:"64px"}}),yP=xe.borders({xs:{value:"0.5px solid"},sm:{value:"1px solid"},md:{value:"2px solid"},lg:{value:"4px solid"},xl:{value:"8px solid"}}),xP=xe.colors({transparent:{value:"transparent"},current:{value:"currentColor"},black:{value:"#09090B"},white:{value:"#FFFFFF"},whiteAlpha:{50:{value:"rgba(255, 255, 255, 0.04)"},100:{value:"rgba(255, 255, 255, 0.06)"},200:{value:"rgba(255, 255, 255, 0.08)"},300:{value:"rgba(255, 255, 255, 0.16)"},400:{value:"rgba(255, 255, 255, 0.24)"},500:{value:"rgba(255, 255, 255, 0.36)"},600:{value:"rgba(255, 255, 255, 0.48)"},700:{value:"rgba(255, 255, 255, 0.64)"},800:{value:"rgba(255, 255, 255, 0.80)"},900:{value:"rgba(255, 255, 255, 0.92)"},950:{value:"rgba(255, 255, 255, 0.95)"}},blackAlpha:{50:{value:"rgba(0, 0, 0, 0.04)"},100:{value:"rgba(0, 0, 0, 0.06)"},200:{value:"rgba(0, 0, 0, 0.08)"},300:{value:"rgba(0, 0, 0, 0.16)"},400:{value:"rgba(0, 0, 0, 0.24)"},500:{value:"rgba(0, 0, 0, 0.36)"},600:{value:"rgba(0, 0, 0, 0.48)"},700:{value:"rgba(0, 0, 0, 0.64)"},800:{value:"rgba(0, 0, 0, 0.80)"},900:{value:"rgba(0, 0, 0, 0.92)"},950:{value:"rgba(0, 0, 0, 0.95)"}},gray:{50:{value:"#fafafa"},100:{value:"#f4f4f5"},200:{value:"#e4e4e7"},300:{value:"#d4d4d8"},400:{value:"#a1a1aa"},500:{value:"#71717a"},600:{value:"#52525b"},700:{value:"#3f3f46"},800:{value:"#27272a"},900:{value:"#18181b"},950:{value:"#111111"}},red:{50:{value:"#fef2f2"},100:{value:"#fee2e2"},200:{value:"#fecaca"},300:{value:"#fca5a5"},400:{value:"#f87171"},500:{value:"#ef4444"},600:{value:"#dc2626"},700:{value:"#991919"},800:{value:"#511111"},900:{value:"#300c0c"},950:{value:"#1f0808"}},orange:{50:{value:"#fff7ed"},100:{value:"#ffedd5"},200:{value:"#fed7aa"},300:{value:"#fdba74"},400:{value:"#fb923c"},500:{value:"#f97316"},600:{value:"#ea580c"},700:{value:"#92310a"},800:{value:"#6c2710"},900:{value:"#3b1106"},950:{value:"#220a04"}},yellow:{50:{value:"#fefce8"},100:{value:"#fef9c3"},200:{value:"#fef08a"},300:{value:"#fde047"},400:{value:"#facc15"},500:{value:"#eab308"},600:{value:"#ca8a04"},700:{value:"#845209"},800:{value:"#713f12"},900:{value:"#422006"},950:{value:"#281304"}},green:{50:{value:"#f0fdf4"},100:{value:"#dcfce7"},200:{value:"#bbf7d0"},300:{value:"#86efac"},400:{value:"#4ade80"},500:{value:"#22c55e"},600:{value:"#16a34a"},700:{value:"#116932"},800:{value:"#124a28"},900:{value:"#042713"},950:{value:"#03190c"}},teal:{50:{value:"#f0fdfa"},100:{value:"#ccfbf1"},200:{value:"#99f6e4"},300:{value:"#5eead4"},400:{value:"#2dd4bf"},500:{value:"#14b8a6"},600:{value:"#0d9488"},700:{value:"#0c5d56"},800:{value:"#114240"},900:{value:"#032726"},950:{value:"#021716"}},blue:{50:{value:"#eff6ff"},100:{value:"#dbeafe"},200:{value:"#bfdbfe"},300:{value:"#a3cfff"},400:{value:"#60a5fa"},500:{value:"#3b82f6"},600:{value:"#2563eb"},700:{value:"#173da6"},800:{value:"#1a3478"},900:{value:"#14204a"},950:{value:"#0c142e"}},cyan:{50:{value:"#ecfeff"},100:{value:"#cffafe"},200:{value:"#a5f3fc"},300:{value:"#67e8f9"},400:{value:"#22d3ee"},500:{value:"#06b6d4"},600:{value:"#0891b2"},700:{value:"#0c5c72"},800:{value:"#134152"},900:{value:"#072a38"},950:{value:"#051b24"}},purple:{50:{value:"#faf5ff"},100:{value:"#f3e8ff"},200:{value:"#e9d5ff"},300:{value:"#d8b4fe"},400:{value:"#c084fc"},500:{value:"#a855f7"},600:{value:"#9333ea"},700:{value:"#641ba3"},800:{value:"#4a1772"},900:{value:"#2f0553"},950:{value:"#1a032e"}},pink:{50:{value:"#fdf2f8"},100:{value:"#fce7f3"},200:{value:"#fbcfe8"},300:{value:"#f9a8d4"},400:{value:"#f472b6"},500:{value:"#ec4899"},600:{value:"#db2777"},700:{value:"#a41752"},800:{value:"#6d0e34"},900:{value:"#45061f"},950:{value:"#2c0514"}}}),CP=xe.cursor({button:{value:"pointer"},checkbox:{value:"default"},disabled:{value:"not-allowed"},menuitem:{value:"default"},option:{value:"default"},radio:{value:"default"},slider:{value:"default"},switch:{value:"pointer"}}),SP=xe.durations({fastest:{value:"50ms"},faster:{value:"100ms"},fast:{value:"150ms"},moderate:{value:"200ms"},slow:{value:"300ms"},slower:{value:"400ms"},slowest:{value:"500ms"}}),wP=xe.easings({"ease-in":{value:"cubic-bezier(0.42, 0, 1, 1)"},"ease-out":{value:"cubic-bezier(0, 0, 0.58, 1)"},"ease-in-out":{value:"cubic-bezier(0.42, 0, 0.58, 1)"},"ease-in-smooth":{value:"cubic-bezier(0.32, 0.72, 0, 1)"}}),EP=xe.fontSizes({"2xs":{value:"0.625rem"},xs:{value:"0.75rem"},sm:{value:"0.875rem"},md:{value:"1rem"},lg:{value:"1.125rem"},xl:{value:"1.25rem"},"2xl":{value:"1.5rem"},"3xl":{value:"1.875rem"},"4xl":{value:"2.25rem"},"5xl":{value:"3rem"},"6xl":{value:"3.75rem"},"7xl":{value:"4.5rem"},"8xl":{value:"6rem"},"9xl":{value:"8rem"}}),kP=xe.fontWeights({thin:{value:"100"},extralight:{value:"200"},light:{value:"300"},normal:{value:"400"},medium:{value:"500"},semibold:{value:"600"},bold:{value:"700"},extrabold:{value:"800"},black:{value:"900"}}),lg='-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',OP=xe.fonts({heading:{value:`Inter, ${lg}`},body:{value:`Inter, ${lg}`},mono:{value:'SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace'}}),IP=KE({spin:{"0%":{transform:"rotate(0deg)"},"100%":{transform:"rotate(360deg)"}},pulse:{"50%":{opacity:"0.5"}},ping:{"75%, 100%":{transform:"scale(2)",opacity:"0"}},bounce:{"0%, 100%":{transform:"translateY(-25%)",animationTimingFunction:"cubic-bezier(0.8,0,1,1)"},"50%":{transform:"none",animationTimingFunction:"cubic-bezier(0,0,0.2,1)"}},"bg-position":{from:{backgroundPosition:"var(--animate-from, 1rem) 0"},to:{backgroundPosition:"var(--animate-to, 0) 0"}},position:{from:{insetInlineStart:"var(--animate-from-x)",insetBlockStart:"var(--animate-from-y)"},to:{insetInlineStart:"var(--animate-to-x)",insetBlockStart:"var(--animate-to-y)"}},"circular-progress":{"0%":{strokeDasharray:"1, 400",strokeDashoffset:"0"},"50%":{strokeDasharray:"400, 400",strokeDashoffset:"-100%"},"100%":{strokeDasharray:"400, 400",strokeDashoffset:"-260%"}},"expand-height":{from:{height:"0"},to:{height:"var(--height)"}},"collapse-height":{from:{height:"var(--height)"},to:{height:"0"}},"expand-width":{from:{width:"0"},to:{width:"var(--width)"}},"collapse-width":{from:{height:"var(--width)"},to:{height:"0"}},"fade-in":{from:{opacity:0},to:{opacity:1}},"fade-out":{from:{opacity:1},to:{opacity:0}},"slide-from-left-full":{from:{translate:"-100% 0"},to:{translate:"0 0"}},"slide-from-right-full":{from:{translate:"100% 0"},to:{translate:"0 0"}},"slide-from-top-full":{from:{translate:"0 -100%"},to:{translate:"0 0"}},"slide-from-bottom-full":{from:{translate:"0 100%"},to:{translate:"0 0"}},"slide-to-left-full":{from:{translate:"0 0"},to:{translate:"-100% 0"}},"slide-to-right-full":{from:{translate:"0 0"},to:{translate:"100% 0"}},"slide-to-top-full":{from:{translate:"0 0"},to:{translate:"0 -100%"}},"slide-to-bottom-full":{from:{translate:"0 0"},to:{translate:"0 100%"}},"slide-from-top":{"0%":{translate:"0 -0.5rem"},to:{translate:"0"}},"slide-from-bottom":{"0%":{translate:"0 0.5rem"},to:{translate:"0"}},"slide-from-left":{"0%":{translate:"-0.5rem 0"},to:{translate:"0"}},"slide-from-right":{"0%":{translate:"0.5rem 0"},to:{translate:"0"}},"slide-to-top":{"0%":{translate:"0"},to:{translate:"0 -0.5rem"}},"slide-to-bottom":{"0%":{translate:"0"},to:{translate:"0 0.5rem"}},"slide-to-left":{"0%":{translate:"0"},to:{translate:"-0.5rem 0"}},"slide-to-right":{"0%":{translate:"0"},to:{translate:"0.5rem 0"}},"scale-in":{from:{scale:"0.95"},to:{scale:"1"}},"scale-out":{from:{scale:"1"},to:{scale:"0.95"}}}),PP=xe.letterSpacings({tighter:{value:"-0.05em"},tight:{value:"-0.025em"},wide:{value:"0.025em"},wider:{value:"0.05em"},widest:{value:"0.1em"}}),RP=xe.lineHeights({shorter:{value:1.25},short:{value:1.375},moderate:{value:1.5},tall:{value:1.625},taller:{value:2}}),TP=xe.radii({none:{value:"0"},"2xs":{value:"0.0625rem"},xs:{value:"0.125rem"},sm:{value:"0.25rem"},md:{value:"0.375rem"},lg:{value:"0.5rem"},xl:{value:"0.75rem"},"2xl":{value:"1rem"},"3xl":{value:"1.5rem"},"4xl":{value:"2rem"},full:{value:"9999px"}}),cg=xe.spacing({.5:{value:"0.125rem"},1:{value:"0.25rem"},1.5:{value:"0.375rem"},2:{value:"0.5rem"},2.5:{value:"0.625rem"},3:{value:"0.75rem"},3.5:{value:"0.875rem"},4:{value:"1rem"},4.5:{value:"1.125rem"},5:{value:"1.25rem"},6:{value:"1.5rem"},7:{value:"1.75rem"},8:{value:"2rem"},9:{value:"2.25rem"},10:{value:"2.5rem"},11:{value:"2.75rem"},12:{value:"3rem"},14:{value:"3.5rem"},16:{value:"4rem"},20:{value:"5rem"},24:{value:"6rem"},28:{value:"7rem"},32:{value:"8rem"},36:{value:"9rem"},40:{value:"10rem"},44:{value:"11rem"},48:{value:"12rem"},52:{value:"13rem"},56:{value:"14rem"},60:{value:"15rem"},64:{value:"16rem"},72:{value:"18rem"},80:{value:"20rem"},96:{value:"24rem"}}),NP=xe.sizes({"3xs":{value:"14rem"},"2xs":{value:"16rem"},xs:{value:"20rem"},sm:{value:"24rem"},md:{value:"28rem"},lg:{value:"32rem"},xl:{value:"36rem"},"2xl":{value:"42rem"},"3xl":{value:"48rem"},"4xl":{value:"56rem"},"5xl":{value:"64rem"},"6xl":{value:"72rem"},"7xl":{value:"80rem"},"8xl":{value:"90rem"}}),AP=xe.sizes({max:{value:"max-content"},min:{value:"min-content"},fit:{value:"fit-content"},prose:{value:"60ch"},full:{value:"100%"},dvh:{value:"100dvh"},svh:{value:"100svh"},lvh:{value:"100lvh"},dvw:{value:"100dvw"},svw:{value:"100svw"},lvw:{value:"100lvw"},vw:{value:"100vw"},vh:{value:"100vh"}}),_P=xe.sizes({"1/2":{value:"50%"},"1/3":{value:"33.333333%"},"2/3":{value:"66.666667%"},"1/4":{value:"25%"},"3/4":{value:"75%"},"1/5":{value:"20%"},"2/5":{value:"40%"},"3/5":{value:"60%"},"4/5":{value:"80%"},"1/6":{value:"16.666667%"},"2/6":{value:"33.333333%"},"3/6":{value:"50%"},"4/6":{value:"66.666667%"},"5/6":{value:"83.333333%"},"1/12":{value:"8.333333%"},"2/12":{value:"16.666667%"},"3/12":{value:"25%"},"4/12":{value:"33.333333%"},"5/12":{value:"41.666667%"},"6/12":{value:"50%"},"7/12":{value:"58.333333%"},"8/12":{value:"66.666667%"},"9/12":{value:"75%"},"10/12":{value:"83.333333%"},"11/12":{value:"91.666667%"}}),VP=xe.sizes({...NP,...cg,..._P,...AP}),FP=xe.zIndex({hide:{value:-1},base:{value:0},docked:{value:10},dropdown:{value:1e3},sticky:{value:1100},banner:{value:1200},overlay:{value:1300},modal:{value:1400},popover:{value:1500},skipNav:{value:1600},toast:{value:1700},tooltip:{value:1800},max:{value:2147483647}}),LP=Sl({preflight:!0,cssVarsPrefix:"chakra",cssVarsRoot:":where(html, .chakra-theme)",globalCss:fO,theme:{breakpoints:hO,keyframes:IP,tokens:{aspectRatios:vP,animations:mP,blurs:bP,borders:yP,colors:xP,durations:SP,easings:wP,fonts:OP,fontSizes:EP,fontWeights:kP,letterSpacings:PP,lineHeights:RP,radii:TP,spacing:cg,sizes:VP,zIndex:FP,cursor:CP},semanticTokens:{colors:_O,shadows:FO,radii:VO},recipes:AO,slotRecipes:gP,textStyles:pP,layerStyles:gO,animationStyles:pO}}),dt=af(sk,LP);Xf(dt);function DP(e){const{key:t,recipe:n}=e,r=ho();return E.useMemo(()=>{const i=n||(t!=null?r.getSlotRecipe(t):{});return r.sva(structuredClone(i))},[t,n,r])}const zP=e=>e.charAt(0).toUpperCase()+e.slice(1),_l=e=>{const{key:t,recipe:n}=e,r=zP(t||n.className||"Component"),[i,o]=ur({name:`${r}StylesContext`,errorMessage:`use${r}Styles returned is 'undefined'. Seems you forgot to wrap the components in "<${r}.Root />" `}),[s,a]=ur({name:`${r}ClassNameContext`,errorMessage:`use${r}ClassNames returned is 'undefined'. Seems you forgot to wrap the components in "<${r}.Root />" `,strict:!1}),[l,c]=ur({strict:!1,name:`${r}PropsContext`,providerName:`${r}PropsContext`,defaultValue:{}});function u(f){const{unstyled:g,...p}=f,b=DP({key:t,recipe:p.recipe||n}),[C,S]=E.useMemo(()=>b.splitVariantProps(p),[p,b]);return{styles:E.useMemo(()=>g?Wy:b(C),[g,C,b]),classNames:b.classNameMap,props:S}}function d(f,g={}){const{defaultProps:p}=g,b=C=>{const S=c(),y=E.useMemo(()=>oi(p,S,C),[S,C]),{styles:k,classNames:R,props:A}=u(y);return x.jsx(i,{value:k,children:x.jsx(s,{value:R,children:x.jsx(f,{...A})})})};return b.displayName=f.displayName||f.name,b}return{StylesProvider:i,ClassNamesProvider:s,PropsProvider:l,usePropsContext:c,useRecipeResult:u,withProvider:(f,g,p)=>{const{defaultProps:b,...C}=p??{},S=Oe(f,{},C),y=E.forwardRef((k,R)=>{var X;const A=c(),T=E.useMemo(()=>oi(b??{},A,k),[A,k]),{styles:N,props:I,classNames:B}=u(T),P=B[g],F=x.jsx(i,{value:N,children:x.jsx(s,{value:B,children:x.jsx(S,{ref:R,...I,css:[N[g],T.css],className:st(T.className,P)})})});return((X=p==null?void 0:p.wrapElement)==null?void 0:X.call(p,F,T))??F});return y.displayName=f.displayName||f.name,y},withContext:(f,g,p)=>{const b=Oe(f,{},p),C=E.forwardRef((S,y)=>{const{unstyled:k,...R}=S,A=o(),T=a(),N=T==null?void 0:T[g];return x.jsx(b,{...R,css:[!k&&g?A[g]:void 0,S.css],ref:y,className:st(S.className,N)})});return C.displayName=f.displayName||f.name,C},withRootProvider:d,useStyles:o,useClassNames:a}},ug=Oe("div",{base:{position:"absolute",display:"flex",alignItems:"center",justifyContent:"center"},variants:{axis:{horizontal:{insetStart:"50%",translate:"-50%",_rtl:{translate:"50%"}},vertical:{top:"50%",translate:"0 -50%"},both:{insetStart:"50%",top:"50%",translate:"-50% -50%",_rtl:{translate:"50% -50%"}}}},defaultVariants:{axis:"both"}});ug.displayName="AbsoluteCenter";const MP=e=>x.jsx(Oe.svg,{stroke:"currentColor",fill:"currentColor",strokeWidth:"0",viewBox:"0 0 24 24",...e,children:x.jsx("path",{d:"M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11.0026 16L6.75999 11.7574L8.17421 10.3431L11.0026 13.1716L16.6595 7.51472L18.0737 8.92893L11.0026 16Z"})}),dg=e=>x.jsx(Oe.svg,{stroke:"currentColor",fill:"currentColor",strokeWidth:"0",viewBox:"0 0 24 24",...e,children:x.jsx("path",{d:"M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z"})}),hg=e=>x.jsx(Oe.svg,{viewBox:"0 0 24 24",fill:"currentColor",stroke:"currentColor",strokeWidth:"0",...e,children:x.jsx("path",{d:"M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 7H13V9H11V7ZM11 11H13V17H11V11Z"})}),$P=e=>x.jsx(Oe.svg,{viewBox:"0 0 24 24",fill:"currentColor",...e,children:x.jsx("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.29289 17.2929C4.90237 17.6834 4.90237 18.3166 5.29289 18.7071C5.68342 19.0976 6.31658 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711Z"})}),[BP,jP]=ur({name:"AlertStatusContext",hookName:"useAlertStatusContext",providerName:""}),{withProvider:WP,withContext:Vl,useStyles:HP}=_l({key:"alert"}),UP=WP("div","root",{forwardAsChild:!0,wrapElement(e,t){return x.jsx(BP,{value:{status:t.status||"info"},children:e})}}),fg=Vl("div","title"),GP=Vl("div","description"),qP=Vl("div","content"),KP={info:hg,warning:dg,success:MP,error:dg,neutral:hg},XP=E.forwardRef(function(t,n){const r=jP(),i=HP(),o=typeof r.status=="string"?KP[r.status]:E.Fragment,{children:s=x.jsx(o,{}),...a}=t;return x.jsx(Oe.span,{ref:n,...a,css:[i.indicator,t.css],children:s})}),YP=e=>e?"":void 0,{withContext:QP}=ai({key:"badge"}),gg=QP("span"),{withContext:JP}=ai({key:"spinner"}),ZP=JP("span"),eR=O.forwardRef(function(t,n){const{spinner:r=x.jsx(ZP,{size:"inherit",borderWidth:"0.125em",color:"inherit"}),spinnerPlacement:i="start",children:o,text:s,visible:a=!0,...l}=t;return a?s?x.jsxs(Vo,{ref:n,display:"contents",...l,children:[i==="start"&&r,s,i==="end"&&r]}):r?x.jsxs(Vo,{ref:n,display:"contents",...l,children:[x.jsx(ug,{display:"inline-flex",children:r}),x.jsx(Vo,{visibility:"hidden",display:"contents",children:o})]}):x.jsx(Vo,{ref:n,display:"contents",...l,children:o}):o}),{useRecipeResult:tR,usePropsContext:nR}=ai({key:"button"}),Fl=E.forwardRef(function(t,n){const r=nR(),i=E.useMemo(()=>oi(r,t),[r,t]),o=tR(i),{loading:s,loadingText:a,children:l,spinner:c,spinnerPlacement:u,...d}=o.props;return x.jsx(Oe.button,{type:"button",ref:n,...d,"data-loading":YP(s),disabled:s||d.disabled,className:st(o.className,i.className),css:[o.styles,i.css],children:!i.asChild&&s?x.jsx(eR,{spinner:c,text:a,spinnerPlacement:u,children:l}):l})}),fs=E.forwardRef(function(t,n){return x.jsx(Fl,{px:"0",py:"0",_icon:{fontSize:"1.2em"},ref:n,...t})}),rR=O.forwardRef(function(t,n){return x.jsx(fs,{variant:"ghost","aria-label":"Close",ref:n,...t,children:t.children??x.jsx($P,{})})}),pg=Oe("div",{base:{display:"flex",alignItems:"center",justifyContent:"center"},variants:{inline:{true:{display:"inline-flex"}}}});pg.displayName="Center";function iR(e){const{gap:t,direction:n}=e,r={column:{marginY:t,marginX:0,borderInlineStartWidth:0,borderTopWidth:"1px"},"column-reverse":{marginY:t,marginX:0,borderInlineStartWidth:0,borderTopWidth:"1px"},row:{marginX:t,marginY:0,borderInlineStartWidth:"1px",borderTopWidth:0},"row-reverse":{marginX:t,marginY:0,borderInlineStartWidth:"1px",borderTopWidth:0}};return{"&":sf(n,i=>r[i])}}function oR(e){return E.Children.toArray(e).filter(t=>E.isValidElement(t))}const mg=E.forwardRef(function(t,n){const{direction:r="column",align:i,justify:o,gap:s="0.5rem",wrap:a,children:l,separator:c,className:u,...d}=t,h=E.useMemo(()=>iR({gap:s,direction:r}),[s,r]),m=E.useMemo(()=>E.isValidElement(c)?oR(l).map((f,g,p)=>{const b=typeof f.key<"u"?f.key:g,C=c,S=E.cloneElement(C,{css:[h,C.props.css]});return x.jsxs(E.Fragment,{children:[f,g===p.length-1?null:S]},b)}):l,[l,c,h]);return x.jsx(Oe.div,{ref:n,display:"flex",alignItems:i,justifyContent:o,flexDirection:r,flexWrap:a,gap:c?void 0:s,className:st("chakra-stack",u),...d,children:m})}),{withRootProvider:vg,withContext:Vt}=_l({key:"dialog"});vg(Nw,{defaultProps:{unmountOnExit:!0,lazyMount:!0}});const sR=vg(Tw,{defaultProps:{unmountOnExit:!0,lazyMount:!0}});Vt(ph,"trigger",{forwardAsChild:!0});const aR=Vt(ah,"positioner",{forwardAsChild:!0}),lR=Vt(oh,"content",{forwardAsChild:!0});Vt(sh,"description",{forwardAsChild:!0});const cR=Vt(gh,"title",{forwardAsChild:!0}),uR=Vt(ih,"closeTrigger",{forwardAsChild:!0}),dR=E.forwardRef(function(t,n){const r=cn();return x.jsx(Oe.button,{...t,ref:n,onClick:()=>r.setOpen(!1)})}),hR=Vt(rh,"backdrop",{forwardAsChild:!0}),fR=Vt("div","body"),gR=Vt("div","footer"),pR=Vt("div","header"),Ll=E.forwardRef(function(t,n){const{direction:r,align:i,justify:o,wrap:s,basis:a,grow:l,shrink:c,inline:u,...d}=t;return x.jsx(Oe.div,{ref:n,...d,css:{display:u?"inline-flex":"flex",flexDirection:r,alignItems:i,justifyContent:o,flexWrap:s,flexBasis:a,flexGrow:l,flexShrink:c,...t.css}})}),mR=E.forwardRef(function(t,n){return x.jsx(mg,{align:"center",...t,direction:"row",ref:n})}),vR=E.forwardRef(function(t,n){return x.jsx(mg,{align:"center",...t,direction:"column",ref:n})}),{StylesProvider:bR,ClassNamesProvider:yR,useRecipeResult:xR,withContext:Ut}=_l({key:"table"}),bg=E.forwardRef(function({native:t,...n},r){const{styles:i,props:o,classNames:s}=xR(n),a=E.useMemo(()=>t?{...i.root,"& thead":i.header,"& tbody":i.body,"& tfoot":i.footer,"& thead th":i.columnHeader,"& tr":i.row,"& td":i.cell,"& caption":i.caption}:i.root,[i,t]);return x.jsx(yR,{value:s,children:x.jsx(bR,{value:i,children:x.jsx(Oe.table,{ref:r,...o,css:[a,n.css],className:st(s==null?void 0:s.root,n.className)})})})}),gs=Ut("tr","row");Oe("div",{base:{display:"block",whiteSpace:"nowrap",WebkitOverflowScrolling:"touch",overflow:"auto",maxWidth:"100%"}});const yg=Ut("thead","header");Ut("tfoot","footer");const Te=Ut("th","columnHeader"),Ne=Ut("td","cell");Ut("caption","caption",{defaultProps:{captionSide:"bottom"}});const xg=Ut("tbody","body");Ut("colgroup"),Ut("col");const{withContext:CR}=ai({key:"textarea"}),SR=CR(bh);var Fr=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(e){return this.listeners.add(e),this.onSubscribe(),()=>{this.listeners.delete(e),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}},wR={setTimeout:(e,t)=>setTimeout(e,t),clearTimeout:e=>clearTimeout(e),setInterval:(e,t)=>setInterval(e,t),clearInterval:e=>clearInterval(e)},ER=(wv=class{constructor(){H(this,vn,wR);H(this,hc,!1)}setTimeoutProvider(e){$(this,vn,e)}setTimeout(e,t){return v(this,vn).setTimeout(e,t)}clearTimeout(e){v(this,vn).clearTimeout(e)}setInterval(e,t){return v(this,vn).setInterval(e,t)}clearInterval(e){v(this,vn).clearInterval(e)}},vn=new WeakMap,hc=new WeakMap,wv),Un=new ER;function kR(e){setTimeout(e,0)}var Gn=typeof window>"u"||"Deno"in globalThis;function $e(){}function OR(e,t){return typeof e=="function"?e(t):e}function Dl(e){return typeof e=="number"&&e>=0&&e!==1/0}function Cg(e,t){return Math.max(e+(t||0)-Date.now(),0)}function hn(e,t){return typeof e=="function"?e(t):e}function ht(e,t){return typeof e=="function"?e(t):e}function Sg(e,t){const{type:n="all",exact:r,fetchStatus:i,predicate:o,queryKey:s,stale:a}=e;if(s){if(r){if(t.queryHash!==zl(s,t.options))return!1}else if(!Ti(t.queryKey,s))return!1}if(n!=="all"){const l=t.isActive();if(n==="active"&&!l||n==="inactive"&&l)return!1}return!(typeof a=="boolean"&&t.isStale()!==a||i&&i!==t.state.fetchStatus||o&&!o(t))}function wg(e,t){const{exact:n,status:r,predicate:i,mutationKey:o}=e;if(o){if(!t.options.mutationKey)return!1;if(n){if(qn(t.options.mutationKey)!==qn(o))return!1}else if(!Ti(t.options.mutationKey,o))return!1}return!(r&&t.state.status!==r||i&&!i(t))}function zl(e,t){return((t==null?void 0:t.queryKeyHashFn)||qn)(e)}function qn(e){return JSON.stringify(e,(t,n)=>Ml(n)?Object.keys(n).sort().reduce((r,i)=>(r[i]=n[i],r),{}):n)}function Ti(e,t){return e===t?!0:typeof e!=typeof t?!1:e&&t&&typeof e=="object"&&typeof t=="object"?Object.keys(t).every(n=>Ti(e[n],t[n])):!1}var IR=Object.prototype.hasOwnProperty;function Eg(e,t){if(e===t)return e;const n=kg(e)&&kg(t);if(!n&&!(Ml(e)&&Ml(t)))return t;const i=(n?e:Object.keys(e)).length,o=n?t:Object.keys(t),s=o.length,a=n?new Array(s):{};let l=0;for(let c=0;c{Un.setTimeout(t,e)})}function $l(e,t,n){return typeof n.structuralSharing=="function"?n.structuralSharing(e,t):n.structuralSharing!==!1?Eg(e,t):t}function RR(e,t,n=0){const r=[...e,t];return n&&r.length>n?r.slice(1):r}function TR(e,t,n=0){const r=[t,...e];return n&&r.length>n?r.slice(0,-1):r}var Bl=Symbol();function Ig(e,t){return!e.queryFn&&(t!=null&&t.initialPromise)?()=>t.initialPromise:!e.queryFn||e.queryFn===Bl?()=>Promise.reject(new Error(`Missing queryFn: '${e.queryHash}'`)):e.queryFn}function Pg(e,t){return typeof e=="function"?e(...t):!!e}var NR=(Ev=class extends Fr{constructor(){super();H(this,Jn);H(this,bn);H(this,Br);$(this,Br,t=>{if(!Gn&&window.addEventListener){const n=()=>t();return window.addEventListener("visibilitychange",n,!1),()=>{window.removeEventListener("visibilitychange",n)}}})}onSubscribe(){v(this,bn)||this.setEventListener(v(this,Br))}onUnsubscribe(){var t;this.hasListeners()||((t=v(this,bn))==null||t.call(this),$(this,bn,void 0))}setEventListener(t){var n;$(this,Br,t),(n=v(this,bn))==null||n.call(this),$(this,bn,t(r=>{typeof r=="boolean"?this.setFocused(r):this.onFocus()}))}setFocused(t){v(this,Jn)!==t&&($(this,Jn,t),this.onFocus())}onFocus(){const t=this.isFocused();this.listeners.forEach(n=>{n(t)})}isFocused(){var t;return typeof v(this,Jn)=="boolean"?v(this,Jn):((t=globalThis.document)==null?void 0:t.visibilityState)!=="hidden"}},Jn=new WeakMap,bn=new WeakMap,Br=new WeakMap,Ev),jl=new NR;function Wl(){let e,t;const n=new Promise((i,o)=>{e=i,t=o});n.status="pending",n.catch(()=>{});function r(i){Object.assign(n,i),delete n.resolve,delete n.reject}return n.resolve=i=>{r({status:"fulfilled",value:i}),e(i)},n.reject=i=>{r({status:"rejected",reason:i}),t(i)},n}var AR=kR;function _R(){let e=[],t=0,n=a=>{a()},r=a=>{a()},i=AR;const o=a=>{t?e.push(a):i(()=>{n(a)})},s=()=>{const a=e;e=[],a.length&&i(()=>{r(()=>{a.forEach(l=>{n(l)})})})};return{batch:a=>{let l;t++;try{l=a()}finally{t--,t||s()}return l},batchCalls:a=>(...l)=>{o(()=>{a(...l)})},schedule:o,setNotifyFunction:a=>{n=a},setBatchNotifyFunction:a=>{r=a},setScheduler:a=>{i=a}}}var we=_R(),VR=(kv=class extends Fr{constructor(){super();H(this,jr,!0);H(this,yn);H(this,Wr);$(this,Wr,t=>{if(!Gn&&window.addEventListener){const n=()=>t(!0),r=()=>t(!1);return window.addEventListener("online",n,!1),window.addEventListener("offline",r,!1),()=>{window.removeEventListener("online",n),window.removeEventListener("offline",r)}}})}onSubscribe(){v(this,yn)||this.setEventListener(v(this,Wr))}onUnsubscribe(){var t;this.hasListeners()||((t=v(this,yn))==null||t.call(this),$(this,yn,void 0))}setEventListener(t){var n;$(this,Wr,t),(n=v(this,yn))==null||n.call(this),$(this,yn,t(this.setOnline.bind(this)))}setOnline(t){v(this,jr)!==t&&($(this,jr,t),this.listeners.forEach(r=>{r(t)}))}isOnline(){return v(this,jr)}},jr=new WeakMap,yn=new WeakMap,Wr=new WeakMap,kv),ms=new VR;function FR(e){return Math.min(1e3*2**e,3e4)}function Rg(e){return(e??"online")==="online"?ms.isOnline():!0}var Hl=class extends Error{constructor(e){super("CancelledError"),this.revert=e==null?void 0:e.revert,this.silent=e==null?void 0:e.silent}};function Tg(e){let t=!1,n=0,r;const i=Wl(),o=()=>i.status!=="pending",s=g=>{var p;if(!o()){const b=new Hl(g);h(b),(p=e.onCancel)==null||p.call(e,b)}},a=()=>{t=!0},l=()=>{t=!1},c=()=>jl.isFocused()&&(e.networkMode==="always"||ms.isOnline())&&e.canRun(),u=()=>Rg(e.networkMode)&&e.canRun(),d=g=>{o()||(r==null||r(),i.resolve(g))},h=g=>{o()||(r==null||r(),i.reject(g))},m=()=>new Promise(g=>{var p;r=b=>{(o()||c())&&g(b)},(p=e.onPause)==null||p.call(e)}).then(()=>{var g;r=void 0,o()||(g=e.onContinue)==null||g.call(e)}),f=()=>{if(o())return;let g;const p=n===0?e.initialPromise:void 0;try{g=p??e.fn()}catch(b){g=Promise.reject(b)}Promise.resolve(g).then(d).catch(b=>{var R;if(o())return;const C=e.retry??(Gn?0:3),S=e.retryDelay??FR,y=typeof S=="function"?S(n,b):S,k=C===!0||typeof C=="number"&&nc()?void 0:m()).then(()=>{t?h(b):f()})})};return{promise:i,status:()=>i.status,cancel:s,continue:()=>(r==null||r(),i),cancelRetry:a,continueRetry:l,canStart:u,start:()=>(u()?f():m().then(f),i)}}var Ng=(Ov=class{constructor(){H(this,Zn)}destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),Dl(this.gcTime)&&$(this,Zn,Un.setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(e){this.gcTime=Math.max(this.gcTime||0,e??(Gn?1/0:5*60*1e3))}clearGcTimeout(){v(this,Zn)&&(Un.clearTimeout(v(this,Zn)),$(this,Zn,void 0))}},Zn=new WeakMap,Ov),LR=(Iv=class extends Ng{constructor(t){super();H(this,St);H(this,er);H(this,Hr);H(this,ft);H(this,tr);H(this,Ae);H(this,$i);H(this,nr);$(this,nr,!1),$(this,$i,t.defaultOptions),this.setOptions(t.options),this.observers=[],$(this,tr,t.client),$(this,ft,v(this,tr).getQueryCache()),this.queryKey=t.queryKey,this.queryHash=t.queryHash,$(this,er,_g(this.options)),this.state=t.state??v(this,er),this.scheduleGc()}get meta(){return this.options.meta}get promise(){var t;return(t=v(this,Ae))==null?void 0:t.promise}setOptions(t){if(this.options={...v(this,$i),...t},this.updateGcTime(this.options.gcTime),this.state&&this.state.data===void 0){const n=_g(this.options);n.data!==void 0&&(this.setData(n.data,{updatedAt:n.dataUpdatedAt,manual:!0}),$(this,er,n))}}optionalRemove(){!this.observers.length&&this.state.fetchStatus==="idle"&&v(this,ft).remove(this)}setData(t,n){const r=$l(this.state.data,t,this.options);return J(this,St,Zt).call(this,{data:r,type:"success",dataUpdatedAt:n==null?void 0:n.updatedAt,manual:n==null?void 0:n.manual}),r}setState(t,n){J(this,St,Zt).call(this,{type:"setState",state:t,setStateOptions:n})}cancel(t){var r,i;const n=(r=v(this,Ae))==null?void 0:r.promise;return(i=v(this,Ae))==null||i.cancel(t),n?n.then($e).catch($e):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}reset(){this.destroy(),this.setState(v(this,er))}isActive(){return this.observers.some(t=>ht(t.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===Bl||this.state.dataUpdateCount+this.state.errorUpdateCount===0}isStatic(){return this.getObserversCount()>0?this.observers.some(t=>hn(t.options.staleTime,this)==="static"):!1}isStale(){return this.getObserversCount()>0?this.observers.some(t=>t.getCurrentResult().isStale):this.state.data===void 0||this.state.isInvalidated}isStaleByTime(t=0){return this.state.data===void 0?!0:t==="static"?!1:this.state.isInvalidated?!0:!Cg(this.state.dataUpdatedAt,t)}onFocus(){var n;const t=this.observers.find(r=>r.shouldFetchOnWindowFocus());t==null||t.refetch({cancelRefetch:!1}),(n=v(this,Ae))==null||n.continue()}onOnline(){var n;const t=this.observers.find(r=>r.shouldFetchOnReconnect());t==null||t.refetch({cancelRefetch:!1}),(n=v(this,Ae))==null||n.continue()}addObserver(t){this.observers.includes(t)||(this.observers.push(t),this.clearGcTimeout(),v(this,ft).notify({type:"observerAdded",query:this,observer:t}))}removeObserver(t){this.observers.includes(t)&&(this.observers=this.observers.filter(n=>n!==t),this.observers.length||(v(this,Ae)&&(v(this,nr)?v(this,Ae).cancel({revert:!0}):v(this,Ae).cancelRetry()),this.scheduleGc()),v(this,ft).notify({type:"observerRemoved",query:this,observer:t}))}getObserversCount(){return this.observers.length}invalidate(){this.state.isInvalidated||J(this,St,Zt).call(this,{type:"invalidate"})}async fetch(t,n){var l,c,u,d,h,m,f,g,p,b,C,S;if(this.state.fetchStatus!=="idle"&&((l=v(this,Ae))==null?void 0:l.status())!=="rejected"){if(this.state.data!==void 0&&(n!=null&&n.cancelRefetch))this.cancel({silent:!0});else if(v(this,Ae))return v(this,Ae).continueRetry(),v(this,Ae).promise}if(t&&this.setOptions(t),!this.options.queryFn){const y=this.observers.find(k=>k.options.queryFn);y&&this.setOptions(y.options)}const r=new AbortController,i=y=>{Object.defineProperty(y,"signal",{enumerable:!0,get:()=>($(this,nr,!0),r.signal)})},o=()=>{const y=Ig(this.options,n),R=(()=>{const A={client:v(this,tr),queryKey:this.queryKey,meta:this.meta};return i(A),A})();return $(this,nr,!1),this.options.persister?this.options.persister(y,R,this):y(R)},a=(()=>{const y={fetchOptions:n,options:this.options,queryKey:this.queryKey,client:v(this,tr),state:this.state,fetchFn:o};return i(y),y})();(c=this.options.behavior)==null||c.onFetch(a,this),$(this,Hr,this.state),(this.state.fetchStatus==="idle"||this.state.fetchMeta!==((u=a.fetchOptions)==null?void 0:u.meta))&&J(this,St,Zt).call(this,{type:"fetch",meta:(d=a.fetchOptions)==null?void 0:d.meta}),$(this,Ae,Tg({initialPromise:n==null?void 0:n.initialPromise,fn:a.fetchFn,onCancel:y=>{y instanceof Hl&&y.revert&&this.setState({...v(this,Hr),fetchStatus:"idle"}),r.abort()},onFail:(y,k)=>{J(this,St,Zt).call(this,{type:"failed",failureCount:y,error:k})},onPause:()=>{J(this,St,Zt).call(this,{type:"pause"})},onContinue:()=>{J(this,St,Zt).call(this,{type:"continue"})},retry:a.options.retry,retryDelay:a.options.retryDelay,networkMode:a.options.networkMode,canRun:()=>!0}));try{const y=await v(this,Ae).start();if(y===void 0)throw new Error(`${this.queryHash} data is undefined`);return this.setData(y),(m=(h=v(this,ft).config).onSuccess)==null||m.call(h,y,this),(g=(f=v(this,ft).config).onSettled)==null||g.call(f,y,this.state.error,this),y}catch(y){if(y instanceof Hl){if(y.silent)return v(this,Ae).promise;if(y.revert){if(this.state.data===void 0)throw y;return this.state.data}}throw J(this,St,Zt).call(this,{type:"error",error:y}),(b=(p=v(this,ft).config).onError)==null||b.call(p,y,this),(S=(C=v(this,ft).config).onSettled)==null||S.call(C,this.state.data,y,this),y}finally{this.scheduleGc()}}},er=new WeakMap,Hr=new WeakMap,ft=new WeakMap,tr=new WeakMap,Ae=new WeakMap,$i=new WeakMap,nr=new WeakMap,St=new WeakSet,Zt=function(t){const n=r=>{switch(t.type){case"failed":return{...r,fetchFailureCount:t.failureCount,fetchFailureReason:t.error};case"pause":return{...r,fetchStatus:"paused"};case"continue":return{...r,fetchStatus:"fetching"};case"fetch":return{...r,...Ag(r.data,this.options),fetchMeta:t.meta??null};case"success":const i={...r,data:t.data,dataUpdateCount:r.dataUpdateCount+1,dataUpdatedAt:t.dataUpdatedAt??Date.now(),error:null,isInvalidated:!1,status:"success",...!t.manual&&{fetchStatus:"idle",fetchFailureCount:0,fetchFailureReason:null}};return $(this,Hr,t.manual?i:void 0),i;case"error":const o=t.error;return{...r,error:o,errorUpdateCount:r.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:r.fetchFailureCount+1,fetchFailureReason:o,fetchStatus:"idle",status:"error"};case"invalidate":return{...r,isInvalidated:!0};case"setState":return{...r,...t.state}}};this.state=n(this.state),we.batch(()=>{this.observers.forEach(r=>{r.onQueryUpdate()}),v(this,ft).notify({query:this,type:"updated",action:t})})},Iv);function Ag(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:Rg(t.networkMode)?"fetching":"paused",...e===void 0&&{error:null,status:"pending"}}}function _g(e){const t=typeof e.initialData=="function"?e.initialData():e.initialData,n=t!==void 0,r=n?typeof e.initialDataUpdatedAt=="function"?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:n?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:n?"success":"pending",fetchStatus:"idle"}}var DR=(Pv=class extends Fr{constructor(t,n){super();H(this,se);H(this,Ye);H(this,ee);H(this,Bi);H(this,Be);H(this,rr);H(this,Ur);H(this,Gt);H(this,xn);H(this,ji);H(this,Gr);H(this,qr);H(this,ir);H(this,or);H(this,Cn);H(this,Kr,new Set);this.options=n,$(this,Ye,t),$(this,xn,null),$(this,Gt,Wl()),this.bindMethods(),this.setOptions(n)}bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(v(this,ee).addObserver(this),Vg(v(this,ee),this.options)?J(this,se,Ui).call(this):this.updateResult(),J(this,se,yc).call(this))}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return Ul(v(this,ee),this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return Ul(v(this,ee),this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,J(this,se,xc).call(this),J(this,se,Cc).call(this),v(this,ee).removeObserver(this)}setOptions(t){const n=this.options,r=v(this,ee);if(this.options=v(this,Ye).defaultQueryOptions(t),this.options.enabled!==void 0&&typeof this.options.enabled!="boolean"&&typeof this.options.enabled!="function"&&typeof ht(this.options.enabled,v(this,ee))!="boolean")throw new Error("Expected enabled to be a boolean or a callback that returns a boolean");J(this,se,Sc).call(this),v(this,ee).setOptions(this.options),n._defaulted&&!ps(this.options,n)&&v(this,Ye).getQueryCache().notify({type:"observerOptionsUpdated",query:v(this,ee),observer:this});const i=this.hasListeners();i&&Fg(v(this,ee),r,this.options,n)&&J(this,se,Ui).call(this),this.updateResult(),i&&(v(this,ee)!==r||ht(this.options.enabled,v(this,ee))!==ht(n.enabled,v(this,ee))||hn(this.options.staleTime,v(this,ee))!==hn(n.staleTime,v(this,ee)))&&J(this,se,mc).call(this);const o=J(this,se,vc).call(this);i&&(v(this,ee)!==r||ht(this.options.enabled,v(this,ee))!==ht(n.enabled,v(this,ee))||o!==v(this,Cn))&&J(this,se,bc).call(this,o)}getOptimisticResult(t){const n=v(this,Ye).getQueryCache().build(v(this,Ye),t),r=this.createResult(n,t);return MR(this,r)&&($(this,Be,r),$(this,Ur,this.options),$(this,rr,v(this,ee).state)),r}getCurrentResult(){return v(this,Be)}trackResult(t,n){return new Proxy(t,{get:(r,i)=>(this.trackProp(i),n==null||n(i),i==="promise"&&!this.options.experimental_prefetchInRender&&v(this,Gt).status==="pending"&&v(this,Gt).reject(new Error("experimental_prefetchInRender feature flag is not enabled")),Reflect.get(r,i))})}trackProp(t){v(this,Kr).add(t)}getCurrentQuery(){return v(this,ee)}refetch({...t}={}){return this.fetch({...t})}fetchOptimistic(t){const n=v(this,Ye).defaultQueryOptions(t),r=v(this,Ye).getQueryCache().build(v(this,Ye),n);return r.fetch().then(()=>this.createResult(r,n))}fetch(t){return J(this,se,Ui).call(this,{...t,cancelRefetch:t.cancelRefetch??!0}).then(()=>(this.updateResult(),v(this,Be)))}createResult(t,n){var N;const r=v(this,ee),i=this.options,o=v(this,Be),s=v(this,rr),a=v(this,Ur),c=t!==r?t.state:v(this,Bi),{state:u}=t;let d={...u},h=!1,m;if(n._optimisticResults){const I=this.hasListeners(),B=!I&&Vg(t,n),P=I&&Fg(t,r,n,i);(B||P)&&(d={...d,...Ag(u.data,t.options)}),n._optimisticResults==="isRestoring"&&(d.fetchStatus="idle")}let{error:f,errorUpdatedAt:g,status:p}=d;m=d.data;let b=!1;if(n.placeholderData!==void 0&&m===void 0&&p==="pending"){let I;o!=null&&o.isPlaceholderData&&n.placeholderData===(a==null?void 0:a.placeholderData)?(I=o.data,b=!0):I=typeof n.placeholderData=="function"?n.placeholderData((N=v(this,qr))==null?void 0:N.state.data,v(this,qr)):n.placeholderData,I!==void 0&&(p="success",m=$l(o==null?void 0:o.data,I,n),h=!0)}if(n.select&&m!==void 0&&!b)if(o&&m===(s==null?void 0:s.data)&&n.select===v(this,ji))m=v(this,Gr);else try{$(this,ji,n.select),m=n.select(m),m=$l(o==null?void 0:o.data,m,n),$(this,Gr,m),$(this,xn,null)}catch(I){$(this,xn,I)}v(this,xn)&&(f=v(this,xn),m=v(this,Gr),g=Date.now(),p="error");const C=d.fetchStatus==="fetching",S=p==="pending",y=p==="error",k=S&&C,R=m!==void 0,T={status:p,fetchStatus:d.fetchStatus,isPending:S,isSuccess:p==="success",isError:y,isInitialLoading:k,isLoading:k,data:m,dataUpdatedAt:d.dataUpdatedAt,error:f,errorUpdatedAt:g,failureCount:d.fetchFailureCount,failureReason:d.fetchFailureReason,errorUpdateCount:d.errorUpdateCount,isFetched:d.dataUpdateCount>0||d.errorUpdateCount>0,isFetchedAfterMount:d.dataUpdateCount>c.dataUpdateCount||d.errorUpdateCount>c.errorUpdateCount,isFetching:C,isRefetching:C&&!S,isLoadingError:y&&!R,isPaused:d.fetchStatus==="paused",isPlaceholderData:h,isRefetchError:y&&R,isStale:Gl(t,n),refetch:this.refetch,promise:v(this,Gt),isEnabled:ht(n.enabled,t)!==!1};if(this.options.experimental_prefetchInRender){const I=F=>{T.status==="error"?F.reject(T.error):T.data!==void 0&&F.resolve(T.data)},B=()=>{const F=$(this,Gt,T.promise=Wl());I(F)},P=v(this,Gt);switch(P.status){case"pending":t.queryHash===r.queryHash&&I(P);break;case"fulfilled":(T.status==="error"||T.data!==P.value)&&B();break;case"rejected":(T.status!=="error"||T.error!==P.reason)&&B();break}}return T}updateResult(){const t=v(this,Be),n=this.createResult(v(this,ee),this.options);if($(this,rr,v(this,ee).state),$(this,Ur,this.options),v(this,rr).data!==void 0&&$(this,qr,v(this,ee)),ps(n,t))return;$(this,Be,n);const r=()=>{if(!t)return!0;const{notifyOnChangeProps:i}=this.options,o=typeof i=="function"?i():i;if(o==="all"||!o&&!v(this,Kr).size)return!0;const s=new Set(o??v(this,Kr));return this.options.throwOnError&&s.add("error"),Object.keys(v(this,Be)).some(a=>{const l=a;return v(this,Be)[l]!==t[l]&&s.has(l)})};J(this,se,vb).call(this,{listeners:r()})}onQueryUpdate(){this.updateResult(),this.hasListeners()&&J(this,se,yc).call(this)}},Ye=new WeakMap,ee=new WeakMap,Bi=new WeakMap,Be=new WeakMap,rr=new WeakMap,Ur=new WeakMap,Gt=new WeakMap,xn=new WeakMap,ji=new WeakMap,Gr=new WeakMap,qr=new WeakMap,ir=new WeakMap,or=new WeakMap,Cn=new WeakMap,Kr=new WeakMap,se=new WeakSet,Ui=function(t){J(this,se,Sc).call(this);let n=v(this,ee).fetch(this.options,t);return t!=null&&t.throwOnError||(n=n.catch($e)),n},mc=function(){J(this,se,xc).call(this);const t=hn(this.options.staleTime,v(this,ee));if(Gn||v(this,Be).isStale||!Dl(t))return;const r=Cg(v(this,Be).dataUpdatedAt,t)+1;$(this,ir,Un.setTimeout(()=>{v(this,Be).isStale||this.updateResult()},r))},vc=function(){return(typeof this.options.refetchInterval=="function"?this.options.refetchInterval(v(this,ee)):this.options.refetchInterval)??!1},bc=function(t){J(this,se,Cc).call(this),$(this,Cn,t),!(Gn||ht(this.options.enabled,v(this,ee))===!1||!Dl(v(this,Cn))||v(this,Cn)===0)&&$(this,or,Un.setInterval(()=>{(this.options.refetchIntervalInBackground||jl.isFocused())&&J(this,se,Ui).call(this)},v(this,Cn)))},yc=function(){J(this,se,mc).call(this),J(this,se,bc).call(this,J(this,se,vc).call(this))},xc=function(){v(this,ir)&&(Un.clearTimeout(v(this,ir)),$(this,ir,void 0))},Cc=function(){v(this,or)&&(Un.clearInterval(v(this,or)),$(this,or,void 0))},Sc=function(){const t=v(this,Ye).getQueryCache().build(v(this,Ye),this.options);if(t===v(this,ee))return;const n=v(this,ee);$(this,ee,t),$(this,Bi,t.state),this.hasListeners()&&(n==null||n.removeObserver(this),t.addObserver(this))},vb=function(t){we.batch(()=>{t.listeners&&this.listeners.forEach(n=>{n(v(this,Be))}),v(this,Ye).getQueryCache().notify({query:v(this,ee),type:"observerResultsUpdated"})})},Pv);function zR(e,t){return ht(t.enabled,e)!==!1&&e.state.data===void 0&&!(e.state.status==="error"&&t.retryOnMount===!1)}function Vg(e,t){return zR(e,t)||e.state.data!==void 0&&Ul(e,t,t.refetchOnMount)}function Ul(e,t,n){if(ht(t.enabled,e)!==!1&&hn(t.staleTime,e)!=="static"){const r=typeof n=="function"?n(e):n;return r==="always"||r!==!1&&Gl(e,t)}return!1}function Fg(e,t,n,r){return(e!==t||ht(r.enabled,e)===!1)&&(!n.suspense||e.state.status!=="error")&&Gl(e,n)}function Gl(e,t){return ht(t.enabled,e)!==!1&&e.isStaleByTime(hn(t.staleTime,e))}function MR(e,t){return!ps(e.getCurrentResult(),t)}function Lg(e){return{onFetch:(t,n)=>{var u,d,h,m,f;const r=t.options,i=(h=(d=(u=t.fetchOptions)==null?void 0:u.meta)==null?void 0:d.fetchMore)==null?void 0:h.direction,o=((m=t.state.data)==null?void 0:m.pages)||[],s=((f=t.state.data)==null?void 0:f.pageParams)||[];let a={pages:[],pageParams:[]},l=0;const c=async()=>{let g=!1;const p=S=>{Object.defineProperty(S,"signal",{enumerable:!0,get:()=>(t.signal.aborted?g=!0:t.signal.addEventListener("abort",()=>{g=!0}),t.signal)})},b=Ig(t.options,t.fetchOptions),C=async(S,y,k)=>{if(g)return Promise.reject();if(y==null&&S.pages.length)return Promise.resolve(S);const A=(()=>{const B={client:t.client,queryKey:t.queryKey,pageParam:y,direction:k?"backward":"forward",meta:t.options.meta};return p(B),B})(),T=await b(A),{maxPages:N}=t.options,I=k?TR:RR;return{pages:I(S.pages,T,N),pageParams:I(S.pageParams,y,N)}};if(i&&o.length){const S=i==="backward",y=S?$R:Dg,k={pages:o,pageParams:s},R=y(r,k);a=await C(k,R,S)}else{const S=e??o.length;do{const y=l===0?s[0]??r.initialPageParam:Dg(r,a);if(l>0&&y==null)break;a=await C(a,y),l++}while(l{var g,p;return(p=(g=t.options).persister)==null?void 0:p.call(g,c,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n)}:t.fetchFn=c}}}function Dg(e,{pages:t,pageParams:n}){const r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function $R(e,{pages:t,pageParams:n}){var r;return t.length>0?(r=e.getPreviousPageParam)==null?void 0:r.call(e,t[0],t,n[0],n):void 0}var BR=(Rv=class extends Ng{constructor(t){super();H(this,Dt);H(this,Wi);H(this,Lt);H(this,je);H(this,sr);$(this,Wi,t.client),this.mutationId=t.mutationId,$(this,je,t.mutationCache),$(this,Lt,[]),this.state=t.state||zg(),this.setOptions(t.options),this.scheduleGc()}setOptions(t){this.options=t,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(t){v(this,Lt).includes(t)||(v(this,Lt).push(t),this.clearGcTimeout(),v(this,je).notify({type:"observerAdded",mutation:this,observer:t}))}removeObserver(t){$(this,Lt,v(this,Lt).filter(n=>n!==t)),this.scheduleGc(),v(this,je).notify({type:"observerRemoved",mutation:this,observer:t})}optionalRemove(){v(this,Lt).length||(this.state.status==="pending"?this.scheduleGc():v(this,je).remove(this))}continue(){var t;return((t=v(this,sr))==null?void 0:t.continue())??this.execute(this.state.variables)}async execute(t){var s,a,l,c,u,d,h,m,f,g,p,b,C,S,y,k,R,A,T,N;const n=()=>{J(this,Dt,On).call(this,{type:"continue"})},r={client:v(this,Wi),meta:this.options.meta,mutationKey:this.options.mutationKey};$(this,sr,Tg({fn:()=>this.options.mutationFn?this.options.mutationFn(t,r):Promise.reject(new Error("No mutationFn found")),onFail:(I,B)=>{J(this,Dt,On).call(this,{type:"failed",failureCount:I,error:B})},onPause:()=>{J(this,Dt,On).call(this,{type:"pause"})},onContinue:n,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>v(this,je).canRun(this)}));const i=this.state.status==="pending",o=!v(this,sr).canStart();try{if(i)n();else{J(this,Dt,On).call(this,{type:"pending",variables:t,isPaused:o}),await((a=(s=v(this,je).config).onMutate)==null?void 0:a.call(s,t,this,r));const B=await((c=(l=this.options).onMutate)==null?void 0:c.call(l,t,r));B!==this.state.context&&J(this,Dt,On).call(this,{type:"pending",context:B,variables:t,isPaused:o})}const I=await v(this,sr).start();return await((d=(u=v(this,je).config).onSuccess)==null?void 0:d.call(u,I,t,this.state.context,this,r)),await((m=(h=this.options).onSuccess)==null?void 0:m.call(h,I,t,this.state.context,r)),await((g=(f=v(this,je).config).onSettled)==null?void 0:g.call(f,I,null,this.state.variables,this.state.context,this,r)),await((b=(p=this.options).onSettled)==null?void 0:b.call(p,I,null,t,this.state.context,r)),J(this,Dt,On).call(this,{type:"success",data:I}),I}catch(I){try{throw await((S=(C=v(this,je).config).onError)==null?void 0:S.call(C,I,t,this.state.context,this,r)),await((k=(y=this.options).onError)==null?void 0:k.call(y,I,t,this.state.context,r)),await((A=(R=v(this,je).config).onSettled)==null?void 0:A.call(R,void 0,I,this.state.variables,this.state.context,this,r)),await((N=(T=this.options).onSettled)==null?void 0:N.call(T,void 0,I,t,this.state.context,r)),I}finally{J(this,Dt,On).call(this,{type:"error",error:I})}}finally{v(this,je).runNext(this)}}},Wi=new WeakMap,Lt=new WeakMap,je=new WeakMap,sr=new WeakMap,Dt=new WeakSet,On=function(t){const n=r=>{switch(t.type){case"failed":return{...r,failureCount:t.failureCount,failureReason:t.error};case"pause":return{...r,isPaused:!0};case"continue":return{...r,isPaused:!1};case"pending":return{...r,context:t.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:t.isPaused,status:"pending",variables:t.variables,submittedAt:Date.now()};case"success":return{...r,data:t.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...r,data:void 0,error:t.error,failureCount:r.failureCount+1,failureReason:t.error,isPaused:!1,status:"error"}}};this.state=n(this.state),we.batch(()=>{v(this,Lt).forEach(r=>{r.onMutationUpdate(t)}),v(this,je).notify({mutation:this,type:"updated",action:t})})},Rv);function zg(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}var jR=(Tv=class extends Fr{constructor(t={}){super();H(this,qt);H(this,wt);H(this,Hi);this.config=t,$(this,qt,new Set),$(this,wt,new Map),$(this,Hi,0)}build(t,n,r){const i=new BR({client:t,mutationCache:this,mutationId:++js(this,Hi)._,options:t.defaultMutationOptions(n),state:r});return this.add(i),i}add(t){v(this,qt).add(t);const n=vs(t);if(typeof n=="string"){const r=v(this,wt).get(n);r?r.push(t):v(this,wt).set(n,[t])}this.notify({type:"added",mutation:t})}remove(t){if(v(this,qt).delete(t)){const n=vs(t);if(typeof n=="string"){const r=v(this,wt).get(n);if(r)if(r.length>1){const i=r.indexOf(t);i!==-1&&r.splice(i,1)}else r[0]===t&&v(this,wt).delete(n)}}this.notify({type:"removed",mutation:t})}canRun(t){const n=vs(t);if(typeof n=="string"){const r=v(this,wt).get(n),i=r==null?void 0:r.find(o=>o.state.status==="pending");return!i||i===t}else return!0}runNext(t){var r;const n=vs(t);if(typeof n=="string"){const i=(r=v(this,wt).get(n))==null?void 0:r.find(o=>o!==t&&o.state.isPaused);return(i==null?void 0:i.continue())??Promise.resolve()}else return Promise.resolve()}clear(){we.batch(()=>{v(this,qt).forEach(t=>{this.notify({type:"removed",mutation:t})}),v(this,qt).clear(),v(this,wt).clear()})}getAll(){return Array.from(v(this,qt))}find(t){const n={exact:!0,...t};return this.getAll().find(r=>wg(n,r))}findAll(t={}){return this.getAll().filter(n=>wg(t,n))}notify(t){we.batch(()=>{this.listeners.forEach(n=>{n(t)})})}resumePausedMutations(){const t=this.getAll().filter(n=>n.state.isPaused);return we.batch(()=>Promise.all(t.map(n=>n.continue().catch($e))))}},qt=new WeakMap,wt=new WeakMap,Hi=new WeakMap,Tv);function vs(e){var t;return(t=e.options.scope)==null?void 0:t.id}var WR=(Nv=class extends Fr{constructor(t,n){super();H(this,Yt);H(this,Kt);H(this,Sn);H(this,Qe);H(this,Xt);$(this,Kt,t),this.setOptions(n),this.bindMethods(),J(this,Yt,Gs).call(this)}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(t){var r;const n=this.options;this.options=v(this,Kt).defaultMutationOptions(t),ps(this.options,n)||v(this,Kt).getMutationCache().notify({type:"observerOptionsUpdated",mutation:v(this,Qe),observer:this}),n!=null&&n.mutationKey&&this.options.mutationKey&&qn(n.mutationKey)!==qn(this.options.mutationKey)?this.reset():((r=v(this,Qe))==null?void 0:r.state.status)==="pending"&&v(this,Qe).setOptions(this.options)}onUnsubscribe(){var t;this.hasListeners()||(t=v(this,Qe))==null||t.removeObserver(this)}onMutationUpdate(t){J(this,Yt,Gs).call(this),J(this,Yt,wc).call(this,t)}getCurrentResult(){return v(this,Sn)}reset(){var t;(t=v(this,Qe))==null||t.removeObserver(this),$(this,Qe,void 0),J(this,Yt,Gs).call(this),J(this,Yt,wc).call(this)}mutate(t,n){var r;return $(this,Xt,n),(r=v(this,Qe))==null||r.removeObserver(this),$(this,Qe,v(this,Kt).getMutationCache().build(v(this,Kt),this.options)),v(this,Qe).addObserver(this),v(this,Qe).execute(t)}},Kt=new WeakMap,Sn=new WeakMap,Qe=new WeakMap,Xt=new WeakMap,Yt=new WeakSet,Gs=function(){var n;const t=((n=v(this,Qe))==null?void 0:n.state)??zg();$(this,Sn,{...t,isPending:t.status==="pending",isSuccess:t.status==="success",isError:t.status==="error",isIdle:t.status==="idle",mutate:this.mutate,reset:this.reset})},wc=function(t){we.batch(()=>{var n,r,i,o,s,a,l,c;if(v(this,Xt)&&this.hasListeners()){const u=v(this,Sn).variables,d=v(this,Sn).context,h={client:v(this,Kt),meta:this.options.meta,mutationKey:this.options.mutationKey};(t==null?void 0:t.type)==="success"?((r=(n=v(this,Xt)).onSuccess)==null||r.call(n,t.data,u,d,h),(o=(i=v(this,Xt)).onSettled)==null||o.call(i,t.data,null,u,d,h)):(t==null?void 0:t.type)==="error"&&((a=(s=v(this,Xt)).onError)==null||a.call(s,t.error,u,d,h),(c=(l=v(this,Xt)).onSettled)==null||c.call(l,void 0,t.error,u,d,h))}this.listeners.forEach(u=>{u(v(this,Sn))})})},Nv),HR=(Av=class extends Fr{constructor(t={}){super();H(this,zt);this.config=t,$(this,zt,new Map)}build(t,n,r){const i=n.queryKey,o=n.queryHash??zl(i,n);let s=this.get(o);return s||(s=new LR({client:t,queryKey:i,queryHash:o,options:t.defaultQueryOptions(n),state:r,defaultOptions:t.getQueryDefaults(i)}),this.add(s)),s}add(t){v(this,zt).has(t.queryHash)||(v(this,zt).set(t.queryHash,t),this.notify({type:"added",query:t}))}remove(t){const n=v(this,zt).get(t.queryHash);n&&(t.destroy(),n===t&&v(this,zt).delete(t.queryHash),this.notify({type:"removed",query:t}))}clear(){we.batch(()=>{this.getAll().forEach(t=>{this.remove(t)})})}get(t){return v(this,zt).get(t)}getAll(){return[...v(this,zt).values()]}find(t){const n={exact:!0,...t};return this.getAll().find(r=>Sg(n,r))}findAll(t={}){const n=this.getAll();return Object.keys(t).length>0?n.filter(r=>Sg(t,r)):n}notify(t){we.batch(()=>{this.listeners.forEach(n=>{n(t)})})}onFocus(){we.batch(()=>{this.getAll().forEach(t=>{t.onFocus()})})}onOnline(){we.batch(()=>{this.getAll().forEach(t=>{t.onOnline()})})}},zt=new WeakMap,Av),UR=(_v=class{constructor(e={}){H(this,me);H(this,wn);H(this,En);H(this,Xr);H(this,Yr);H(this,kn);H(this,Qr);H(this,Jr);$(this,me,e.queryCache||new HR),$(this,wn,e.mutationCache||new jR),$(this,En,e.defaultOptions||{}),$(this,Xr,new Map),$(this,Yr,new Map),$(this,kn,0)}mount(){js(this,kn)._++,v(this,kn)===1&&($(this,Qr,jl.subscribe(async e=>{e&&(await this.resumePausedMutations(),v(this,me).onFocus())})),$(this,Jr,ms.subscribe(async e=>{e&&(await this.resumePausedMutations(),v(this,me).onOnline())})))}unmount(){var e,t;js(this,kn)._--,v(this,kn)===0&&((e=v(this,Qr))==null||e.call(this),$(this,Qr,void 0),(t=v(this,Jr))==null||t.call(this),$(this,Jr,void 0))}isFetching(e){return v(this,me).findAll({...e,fetchStatus:"fetching"}).length}isMutating(e){return v(this,wn).findAll({...e,status:"pending"}).length}getQueryData(e){var n;const t=this.defaultQueryOptions({queryKey:e});return(n=v(this,me).get(t.queryHash))==null?void 0:n.state.data}ensureQueryData(e){const t=this.defaultQueryOptions(e),n=v(this,me).build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(hn(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return v(this,me).findAll(e).map(({queryKey:t,state:n})=>{const r=n.data;return[t,r]})}setQueryData(e,t,n){const r=this.defaultQueryOptions({queryKey:e}),i=v(this,me).get(r.queryHash),o=i==null?void 0:i.state.data,s=OR(t,o);if(s!==void 0)return v(this,me).build(this,r).setData(s,{...n,manual:!0})}setQueriesData(e,t,n){return we.batch(()=>v(this,me).findAll(e).map(({queryKey:r})=>[r,this.setQueryData(r,t,n)]))}getQueryState(e){var n;const t=this.defaultQueryOptions({queryKey:e});return(n=v(this,me).get(t.queryHash))==null?void 0:n.state}removeQueries(e){const t=v(this,me);we.batch(()=>{t.findAll(e).forEach(n=>{t.remove(n)})})}resetQueries(e,t){const n=v(this,me);return we.batch(()=>(n.findAll(e).forEach(r=>{r.reset()}),this.refetchQueries({type:"active",...e},t)))}cancelQueries(e,t={}){const n={revert:!0,...t},r=we.batch(()=>v(this,me).findAll(e).map(i=>i.cancel(n)));return Promise.all(r).then($e).catch($e)}invalidateQueries(e,t={}){return we.batch(()=>(v(this,me).findAll(e).forEach(n=>{n.invalidate()}),(e==null?void 0:e.refetchType)==="none"?Promise.resolve():this.refetchQueries({...e,type:(e==null?void 0:e.refetchType)??(e==null?void 0:e.type)??"active"},t)))}refetchQueries(e,t={}){const n={...t,cancelRefetch:t.cancelRefetch??!0},r=we.batch(()=>v(this,me).findAll(e).filter(i=>!i.isDisabled()&&!i.isStatic()).map(i=>{let o=i.fetch(void 0,n);return n.throwOnError||(o=o.catch($e)),i.state.fetchStatus==="paused"?Promise.resolve():o}));return Promise.all(r).then($e)}fetchQuery(e){const t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);const n=v(this,me).build(this,t);return n.isStaleByTime(hn(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then($e).catch($e)}fetchInfiniteQuery(e){return e.behavior=Lg(e.pages),this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then($e).catch($e)}ensureInfiniteQueryData(e){return e.behavior=Lg(e.pages),this.ensureQueryData(e)}resumePausedMutations(){return ms.isOnline()?v(this,wn).resumePausedMutations():Promise.resolve()}getQueryCache(){return v(this,me)}getMutationCache(){return v(this,wn)}getDefaultOptions(){return v(this,En)}setDefaultOptions(e){$(this,En,e)}setQueryDefaults(e,t){v(this,Xr).set(qn(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){const t=[...v(this,Xr).values()],n={};return t.forEach(r=>{Ti(e,r.queryKey)&&Object.assign(n,r.defaultOptions)}),n}setMutationDefaults(e,t){v(this,Yr).set(qn(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){const t=[...v(this,Yr).values()],n={};return t.forEach(r=>{Ti(e,r.mutationKey)&&Object.assign(n,r.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;const t={...v(this,En).queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||(t.queryHash=zl(t.queryKey,t)),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!=="always"),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode="offlineFirst"),t.queryFn===Bl&&(t.enabled=!1),t}defaultMutationOptions(e){return e!=null&&e._defaulted?e:{...v(this,En).mutations,...(e==null?void 0:e.mutationKey)&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){v(this,me).clear(),v(this,wn).clear()}},me=new WeakMap,wn=new WeakMap,En=new WeakMap,Xr=new WeakMap,Yr=new WeakMap,kn=new WeakMap,Qr=new WeakMap,Jr=new WeakMap,_v),Mg=O.createContext(void 0),$g=e=>{const t=O.useContext(Mg);if(!t)throw new Error("No QueryClient set, use QueryClientProvider to set one");return t},GR=({client:e,children:t})=>(O.useEffect(()=>(e.mount(),()=>{e.unmount()}),[e]),x.jsx(Mg.Provider,{value:e,children:t})),Bg=O.createContext(!1),qR=()=>O.useContext(Bg);Bg.Provider;function KR(){let e=!1;return{clearReset:()=>{e=!1},reset:()=>{e=!0},isReset:()=>e}}var XR=O.createContext(KR()),YR=()=>O.useContext(XR),QR=(e,t)=>{(e.suspense||e.throwOnError||e.experimental_prefetchInRender)&&(t.isReset()||(e.retryOnMount=!1))},JR=e=>{O.useEffect(()=>{e.clearReset()},[e])},ZR=({result:e,errorResetBoundary:t,throwOnError:n,query:r,suspense:i})=>e.isError&&!t.isReset()&&!e.isFetching&&r&&(i&&e.data===void 0||Pg(n,[e.error,r])),eT=e=>{if(e.suspense){const n=i=>i==="static"?i:Math.max(i??1e3,1e3),r=e.staleTime;e.staleTime=typeof r=="function"?(...i)=>n(r(...i)):n(r),typeof e.gcTime=="number"&&(e.gcTime=Math.max(e.gcTime,1e3))}},tT=(e,t)=>e.isLoading&&e.isFetching&&!t,nT=(e,t)=>(e==null?void 0:e.suspense)&&t.isPending,jg=(e,t,n)=>t.fetchOptimistic(e).catch(()=>{n.clearReset()});function rT(e,t,n){var d,h,m,f,g;const r=qR(),i=YR(),o=$g(),s=o.defaultQueryOptions(e);(h=(d=o.getDefaultOptions().queries)==null?void 0:d._experimental_beforeQuery)==null||h.call(d,s),s._optimisticResults=r?"isRestoring":"optimistic",eT(s),QR(s,i),JR(i);const a=!o.getQueryCache().get(s.queryHash),[l]=O.useState(()=>new t(o,s)),c=l.getOptimisticResult(s),u=!r&&e.subscribed!==!1;if(O.useSyncExternalStore(O.useCallback(p=>{const b=u?l.subscribe(we.batchCalls(p)):$e;return l.updateResult(),b},[l,u]),()=>l.getCurrentResult(),()=>l.getCurrentResult()),O.useEffect(()=>{l.setOptions(s)},[s,l]),nT(s,c))throw jg(s,l,i);if(ZR({result:c,errorResetBoundary:i,throwOnError:s.throwOnError,query:o.getQueryCache().get(s.queryHash),suspense:s.suspense}))throw c.error;if((f=(m=o.getDefaultOptions().queries)==null?void 0:m._experimental_afterQuery)==null||f.call(m,s,c),s.experimental_prefetchInRender&&!Gn&&tT(c,r)){const p=a?jg(s,l,i):(g=o.getQueryCache().get(s.queryHash))==null?void 0:g.promise;p==null||p.catch($e).finally(()=>{l.updateResult()})}return s.notifyOnChangeProps?c:l.trackResult(c)}function Wg(e,t){return rT(e,DR)}function Hg(e,t){const n=$g(),[r]=O.useState(()=>new WR(n,e));O.useEffect(()=>{r.setOptions(e)},[r,e]);const i=O.useSyncExternalStore(O.useCallback(s=>r.subscribe(we.batchCalls(s)),[r]),()=>r.getCurrentResult(),()=>r.getCurrentResult()),o=O.useCallback((s,a)=>{r.mutate(s,a).catch($e)},[r]);if(i.error&&Pg(r.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:o,mutateAsync:i.mutate}}function Ug(e,t){return function(){return e.apply(t,arguments)}}const{toString:iT}=Object.prototype,{getPrototypeOf:ql}=Object,{iterator:bs,toStringTag:Gg}=Symbol,ys=(e=>t=>{const n=iT.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),Ct=e=>(e=e.toLowerCase(),t=>ys(t)===e),xs=e=>t=>typeof t===e,{isArray:Lr}=Array,Dr=xs("undefined");function Ni(e){return e!==null&&!Dr(e)&&e.constructor!==null&&!Dr(e.constructor)&&Ke(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const qg=Ct("ArrayBuffer");function oT(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&qg(e.buffer),t}const sT=xs("string"),Ke=xs("function"),Kg=xs("number"),Ai=e=>e!==null&&typeof e=="object",aT=e=>e===!0||e===!1,Cs=e=>{if(ys(e)!=="object")return!1;const t=ql(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Gg in e)&&!(bs in e)},lT=e=>{if(!Ai(e)||Ni(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},cT=Ct("Date"),uT=Ct("File"),dT=Ct("Blob"),hT=Ct("FileList"),fT=e=>Ai(e)&&Ke(e.pipe),gT=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||Ke(e.append)&&((t=ys(e))==="formdata"||t==="object"&&Ke(e.toString)&&e.toString()==="[object FormData]"))},pT=Ct("URLSearchParams"),[mT,vT,bT,yT]=["ReadableStream","Request","Response","Headers"].map(Ct),xT=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function _i(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let r,i;if(typeof e!="object"&&(e=[e]),Lr(e))for(r=0,i=e.length;r0;)if(i=n[r],t===i.toLowerCase())return i;return null}const Kn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:globalThis,Yg=e=>!Dr(e)&&e!==Kn;function Kl(){const{caseless:e,skipUndefined:t}=Yg(this)&&this||{},n={},r=(i,o)=>{const s=e&&Xg(n,o)||o;Cs(n[s])&&Cs(i)?n[s]=Kl(n[s],i):Cs(i)?n[s]=Kl({},i):Lr(i)?n[s]=i.slice():(!t||!Dr(i))&&(n[s]=i)};for(let i=0,o=arguments.length;i(_i(t,(i,o)=>{n&&Ke(i)?e[o]=Ug(i,n):e[o]=i},{allOwnKeys:r}),e),ST=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),wT=(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},ET=(e,t,n,r)=>{let i,o,s;const a={};if(t=t||{},e==null)return t;do{for(i=Object.getOwnPropertyNames(e),o=i.length;o-- >0;)s=i[o],(!r||r(s,e,t))&&!a[s]&&(t[s]=e[s],a[s]=!0);e=n!==!1&&ql(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kT=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return r!==-1&&r===n},OT=e=>{if(!e)return null;if(Lr(e))return e;let t=e.length;if(!Kg(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},IT=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&ql(Uint8Array)),PT=(e,t)=>{const r=(e&&e[bs]).call(e);let i;for(;(i=r.next())&&!i.done;){const o=i.value;t.call(e,o[0],o[1])}},RT=(e,t)=>{let n;const r=[];for(;(n=e.exec(t))!==null;)r.push(n);return r},TT=Ct("HTMLFormElement"),NT=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,i){return r.toUpperCase()+i}),Qg=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),AT=Ct("RegExp"),Jg=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};_i(n,(i,o)=>{let s;(s=t(i,o,e))!==!1&&(r[o]=s||i)}),Object.defineProperties(e,r)},_T=e=>{Jg(e,(t,n)=>{if(Ke(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const r=e[n];if(Ke(r)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},VT=(e,t)=>{const n={},r=i=>{i.forEach(o=>{n[o]=!0})};return Lr(e)?r(e):r(String(e).split(t)),n},FT=()=>{},LT=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function DT(e){return!!(e&&Ke(e.append)&&e[Gg]==="FormData"&&e[bs])}const zT=e=>{const t=new Array(10),n=(r,i)=>{if(Ai(r)){if(t.indexOf(r)>=0)return;if(Ni(r))return r;if(!("toJSON"in r)){t[i]=r;const o=Lr(r)?[]:{};return _i(r,(s,a)=>{const l=n(s,i+1);!Dr(l)&&(o[a]=l)}),t[i]=void 0,o}}return r};return n(e,0)},MT=Ct("AsyncFunction"),$T=e=>e&&(Ai(e)||Ke(e))&&Ke(e.then)&&Ke(e.catch),Zg=((e,t)=>e?setImmediate:t?((n,r)=>(Kn.addEventListener("message",({source:i,data:o})=>{i===Kn&&o===n&&r.length&&r.shift()()},!1),i=>{r.push(i),Kn.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",Ke(Kn.postMessage)),BT=typeof queueMicrotask<"u"?queueMicrotask.bind(Kn):typeof process<"u"&&process.nextTick||Zg,w={isArray:Lr,isArrayBuffer:qg,isBuffer:Ni,isFormData:gT,isArrayBufferView:oT,isString:sT,isNumber:Kg,isBoolean:aT,isObject:Ai,isPlainObject:Cs,isEmptyObject:lT,isReadableStream:mT,isRequest:vT,isResponse:bT,isHeaders:yT,isUndefined:Dr,isDate:cT,isFile:uT,isBlob:dT,isRegExp:AT,isFunction:Ke,isStream:fT,isURLSearchParams:pT,isTypedArray:IT,isFileList:hT,forEach:_i,merge:Kl,extend:CT,trim:xT,stripBOM:ST,inherits:wT,toFlatObject:ET,kindOf:ys,kindOfTest:Ct,endsWith:kT,toArray:OT,forEachEntry:PT,matchAll:RT,isHTMLForm:TT,hasOwnProperty:Qg,hasOwnProp:Qg,reduceDescriptors:Jg,freezeMethods:_T,toObjectSet:VT,toCamelCase:NT,noop:FT,toFiniteNumber:LT,findKey:Xg,global:Kn,isContextDefined:Yg,isSpecCompliantForm:DT,toJSONObject:zT,isAsyncFn:MT,isThenable:$T,setImmediate:Zg,asap:BT,isIterable:e=>e!=null&&Ke(e[bs])};function Q(e,t,n,r,i){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),i&&(this.response=i,this.status=i.status?i.status:null)}w.inherits(Q,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:w.toJSONObject(this.config),code:this.code,status:this.status}}});const ep=Q.prototype,tp={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{tp[e]={value:e}}),Object.defineProperties(Q,tp),Object.defineProperty(ep,"isAxiosError",{value:!0}),Q.from=(e,t,n,r,i,o)=>{const s=Object.create(ep);w.toFlatObject(e,s,function(u){return u!==Error.prototype},c=>c!=="isAxiosError");const a=e&&e.message?e.message:"Error",l=t==null&&e?e.code:t;return Q.call(s,a,l,n,r,i),e&&s.cause==null&&Object.defineProperty(s,"cause",{value:e,configurable:!0}),s.name=e&&e.name||"Error",o&&Object.assign(s,o),s};const jT=null;function Xl(e){return w.isPlainObject(e)||w.isArray(e)}function np(e){return w.endsWith(e,"[]")?e.slice(0,-2):e}function rp(e,t,n){return e?e.concat(t).map(function(i,o){return i=np(i),!n&&o?"["+i+"]":i}).join(n?".":""):t}function WT(e){return w.isArray(e)&&!e.some(Xl)}const HT=w.toFlatObject(w,{},null,function(t){return/^is[A-Z]/.test(t)});function Ss(e,t,n){if(!w.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=w.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(g,p){return!w.isUndefined(p[g])});const r=n.metaTokens,i=n.visitor||u,o=n.dots,s=n.indexes,l=(n.Blob||typeof Blob<"u"&&Blob)&&w.isSpecCompliantForm(t);if(!w.isFunction(i))throw new TypeError("visitor must be a function");function c(f){if(f===null)return"";if(w.isDate(f))return f.toISOString();if(w.isBoolean(f))return f.toString();if(!l&&w.isBlob(f))throw new Q("Blob is not supported. Use a Buffer instead.");return w.isArrayBuffer(f)||w.isTypedArray(f)?l&&typeof Blob=="function"?new Blob([f]):Buffer.from(f):f}function u(f,g,p){let b=f;if(f&&!p&&typeof f=="object"){if(w.endsWith(g,"{}"))g=r?g:g.slice(0,-2),f=JSON.stringify(f);else if(w.isArray(f)&&WT(f)||(w.isFileList(f)||w.endsWith(g,"[]"))&&(b=w.toArray(f)))return g=np(g),b.forEach(function(S,y){!(w.isUndefined(S)||S===null)&&t.append(s===!0?rp([g],y,o):s===null?g:g+"[]",c(S))}),!1}return Xl(f)?!0:(t.append(rp(p,g,o),c(f)),!1)}const d=[],h=Object.assign(HT,{defaultVisitor:u,convertValue:c,isVisitable:Xl});function m(f,g){if(!w.isUndefined(f)){if(d.indexOf(f)!==-1)throw Error("Circular reference detected in "+g.join("."));d.push(f),w.forEach(f,function(b,C){(!(w.isUndefined(b)||b===null)&&i.call(t,b,w.isString(C)?C.trim():C,g,h))===!0&&m(b,g?g.concat(C):[C])}),d.pop()}}if(!w.isObject(e))throw new TypeError("data must be an object");return m(e),t}function ip(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(r){return t[r]})}function Yl(e,t){this._pairs=[],e&&Ss(e,this,t)}const op=Yl.prototype;op.append=function(t,n){this._pairs.push([t,n])},op.toString=function(t){const n=t?function(r){return t.call(this,r,ip)}:ip;return this._pairs.map(function(i){return n(i[0])+"="+n(i[1])},"").join("&")};function UT(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function sp(e,t,n){if(!t)return e;const r=n&&n.encode||UT;w.isFunction(n)&&(n={serialize:n});const i=n&&n.serialize;let o;if(i?o=i(t,n):o=w.isURLSearchParams(t)?t.toString():new Yl(t,n).toString(r),o){const s=e.indexOf("#");s!==-1&&(e=e.slice(0,s)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class ap{constructor(){this.handlers=[]}use(t,n,r){return this.handlers.push({fulfilled:t,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){w.forEach(this.handlers,function(r){r!==null&&t(r)})}}const lp={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},GT={isBrowser:!0,classes:{URLSearchParams:typeof URLSearchParams<"u"?URLSearchParams:Yl,FormData:typeof FormData<"u"?FormData:null,Blob:typeof Blob<"u"?Blob:null},protocols:["http","https","file","blob","url","data"]},Ql=typeof window<"u"&&typeof document<"u",Jl=typeof navigator=="object"&&navigator||void 0,qT=Ql&&(!Jl||["ReactNative","NativeScript","NS"].indexOf(Jl.product)<0),KT=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",XT=Ql&&window.location.href||"http://localhost",ze={...Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Ql,hasStandardBrowserEnv:qT,hasStandardBrowserWebWorkerEnv:KT,navigator:Jl,origin:XT},Symbol.toStringTag,{value:"Module"})),...GT};function YT(e,t){return Ss(e,new ze.classes.URLSearchParams,{visitor:function(n,r,i,o){return ze.isNode&&w.isBuffer(n)?(this.append(r,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)},...t})}function QT(e){return w.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function JT(e){const t={},n=Object.keys(e);let r;const i=n.length;let o;for(r=0;r=n.length;return s=!s&&w.isArray(i)?i.length:s,l?(w.hasOwnProp(i,s)?i[s]=[i[s],r]:i[s]=r,!a):((!i[s]||!w.isObject(i[s]))&&(i[s]=[]),t(n,r,i[s],o)&&w.isArray(i[s])&&(i[s]=JT(i[s])),!a)}if(w.isFormData(e)&&w.isFunction(e.entries)){const n={};return w.forEachEntry(e,(r,i)=>{t(QT(r),i,n,0)}),n}return null}function ZT(e,t,n){if(w.isString(e))try{return(t||JSON.parse)(e),w.trim(e)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(e)}const Vi={transitional:lp,adapter:["xhr","http","fetch"],transformRequest:[function(t,n){const r=n.getContentType()||"",i=r.indexOf("application/json")>-1,o=w.isObject(t);if(o&&w.isHTMLForm(t)&&(t=new FormData(t)),w.isFormData(t))return i?JSON.stringify(cp(t)):t;if(w.isArrayBuffer(t)||w.isBuffer(t)||w.isStream(t)||w.isFile(t)||w.isBlob(t)||w.isReadableStream(t))return t;if(w.isArrayBufferView(t))return t.buffer;if(w.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let a;if(o){if(r.indexOf("application/x-www-form-urlencoded")>-1)return YT(t,this.formSerializer).toString();if((a=w.isFileList(t))||r.indexOf("multipart/form-data")>-1){const l=this.env&&this.env.FormData;return Ss(a?{"files[]":t}:t,l&&new l,this.formSerializer)}}return o||i?(n.setContentType("application/json",!1),ZT(t)):t}],transformResponse:[function(t){const n=this.transitional||Vi.transitional,r=n&&n.forcedJSONParsing,i=this.responseType==="json";if(w.isResponse(t)||w.isReadableStream(t))return t;if(t&&w.isString(t)&&(r&&!this.responseType||i)){const s=!(n&&n.silentJSONParsing)&&i;try{return JSON.parse(t,this.parseReviver)}catch(a){if(s)throw a.name==="SyntaxError"?Q.from(a,Q.ERR_BAD_RESPONSE,this,null,this.response):a}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:ze.classes.FormData,Blob:ze.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};w.forEach(["delete","get","head","post","put","patch"],e=>{Vi.headers[e]={}});const e2=w.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),t2=e=>{const t={};let n,r,i;return e&&e.split(` +`).forEach(function(s){i=s.indexOf(":"),n=s.substring(0,i).trim().toLowerCase(),r=s.substring(i+1).trim(),!(!n||t[n]&&e2[n])&&(n==="set-cookie"?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)}),t},up=Symbol("internals");function Fi(e){return e&&String(e).trim().toLowerCase()}function ws(e){return e===!1||e==null?e:w.isArray(e)?e.map(ws):String(e)}function n2(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}const r2=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Zl(e,t,n,r,i){if(w.isFunction(r))return r.call(this,t,n);if(i&&(t=n),!!w.isString(t)){if(w.isString(r))return t.indexOf(r)!==-1;if(w.isRegExp(r))return r.test(t)}}function i2(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,r)=>n.toUpperCase()+r)}function o2(e,t){const n=w.toCamelCase(" "+t);["get","set","has"].forEach(r=>{Object.defineProperty(e,r+n,{value:function(i,o,s){return this[r].call(this,t,i,o,s)},configurable:!0})})}let Xe=class{constructor(t){t&&this.set(t)}set(t,n,r){const i=this;function o(a,l,c){const u=Fi(l);if(!u)throw new Error("header name must be a non-empty string");const d=w.findKey(i,u);(!d||i[d]===void 0||c===!0||c===void 0&&i[d]!==!1)&&(i[d||l]=ws(a))}const s=(a,l)=>w.forEach(a,(c,u)=>o(c,u,l));if(w.isPlainObject(t)||t instanceof this.constructor)s(t,n);else if(w.isString(t)&&(t=t.trim())&&!r2(t))s(t2(t),n);else if(w.isObject(t)&&w.isIterable(t)){let a={},l,c;for(const u of t){if(!w.isArray(u))throw TypeError("Object iterator must return a key-value pair");a[c=u[0]]=(l=a[c])?w.isArray(l)?[...l,u[1]]:[l,u[1]]:u[1]}s(a,n)}else t!=null&&o(n,t,r);return this}get(t,n){if(t=Fi(t),t){const r=w.findKey(this,t);if(r){const i=this[r];if(!n)return i;if(n===!0)return n2(i);if(w.isFunction(n))return n.call(this,i,r);if(w.isRegExp(n))return n.exec(i);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=Fi(t),t){const r=w.findKey(this,t);return!!(r&&this[r]!==void 0&&(!n||Zl(this,this[r],r,n)))}return!1}delete(t,n){const r=this;let i=!1;function o(s){if(s=Fi(s),s){const a=w.findKey(r,s);a&&(!n||Zl(r,r[a],a,n))&&(delete r[a],i=!0)}}return w.isArray(t)?t.forEach(o):o(t),i}clear(t){const n=Object.keys(this);let r=n.length,i=!1;for(;r--;){const o=n[r];(!t||Zl(this,this[o],o,t,!0))&&(delete this[o],i=!0)}return i}normalize(t){const n=this,r={};return w.forEach(this,(i,o)=>{const s=w.findKey(r,o);if(s){n[s]=ws(i),delete n[o];return}const a=t?i2(o):String(o).trim();a!==o&&delete n[o],n[a]=ws(i),r[a]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return w.forEach(this,(r,i)=>{r!=null&&r!==!1&&(n[i]=t&&w.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` +`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const r=new this(t);return n.forEach(i=>r.set(i)),r}static accessor(t){const r=(this[up]=this[up]={accessors:{}}).accessors,i=this.prototype;function o(s){const a=Fi(s);r[a]||(o2(i,s),r[a]=!0)}return w.isArray(t)?t.forEach(o):o(t),this}};Xe.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),w.reduceDescriptors(Xe.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(r){this[n]=r}}}),w.freezeMethods(Xe);function ec(e,t){const n=this||Vi,r=t||n,i=Xe.from(r.headers);let o=r.data;return w.forEach(e,function(a){o=a.call(n,o,i.normalize(),t?t.status:void 0)}),i.normalize(),o}function dp(e){return!!(e&&e.__CANCEL__)}function zr(e,t,n){Q.call(this,e??"canceled",Q.ERR_CANCELED,t,n),this.name="CanceledError"}w.inherits(zr,Q,{__CANCEL__:!0});function hp(e,t,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?e(n):t(new Q("Request failed with status code "+n.status,[Q.ERR_BAD_REQUEST,Q.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function s2(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function a2(e,t){e=e||10;const n=new Array(e),r=new Array(e);let i=0,o=0,s;return t=t!==void 0?t:1e3,function(l){const c=Date.now(),u=r[o];s||(s=c),n[i]=l,r[i]=c;let d=o,h=0;for(;d!==i;)h+=n[d++],d=d%e;if(i=(i+1)%e,i===o&&(o=(o+1)%e),c-s{n=u,i=null,o&&(clearTimeout(o),o=null),e(...c)};return[(...c)=>{const u=Date.now(),d=u-n;d>=r?s(c,u):(i=c,o||(o=setTimeout(()=>{o=null,s(i)},r-d)))},()=>i&&s(i)]}const Es=(e,t,n=3)=>{let r=0;const i=a2(50,250);return l2(o=>{const s=o.loaded,a=o.lengthComputable?o.total:void 0,l=s-r,c=i(l),u=s<=a;r=s;const d={loaded:s,total:a,progress:a?s/a:void 0,bytes:l,rate:c||void 0,estimated:c&&a&&u?(a-s)/c:void 0,event:o,lengthComputable:a!=null,[t?"download":"upload"]:!0};e(d)},n)},fp=(e,t)=>{const n=e!=null;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},gp=e=>(...t)=>w.asap(()=>e(...t)),c2=ze.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,ze.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(ze.origin),ze.navigator&&/(msie|trident)/i.test(ze.navigator.userAgent)):()=>!0,u2=ze.hasStandardBrowserEnv?{write(e,t,n,r,i,o){const s=[e+"="+encodeURIComponent(t)];w.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),w.isString(r)&&s.push("path="+r),w.isString(i)&&s.push("domain="+i),o===!0&&s.push("secure"),document.cookie=s.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function d2(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function h2(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function pp(e,t,n){let r=!d2(t);return e&&(r||n==!1)?h2(e,t):t}const mp=e=>e instanceof Xe?{...e}:e;function Xn(e,t){t=t||{};const n={};function r(c,u,d,h){return w.isPlainObject(c)&&w.isPlainObject(u)?w.merge.call({caseless:h},c,u):w.isPlainObject(u)?w.merge({},u):w.isArray(u)?u.slice():u}function i(c,u,d,h){if(w.isUndefined(u)){if(!w.isUndefined(c))return r(void 0,c,d,h)}else return r(c,u,d,h)}function o(c,u){if(!w.isUndefined(u))return r(void 0,u)}function s(c,u){if(w.isUndefined(u)){if(!w.isUndefined(c))return r(void 0,c)}else return r(void 0,u)}function a(c,u,d){if(d in t)return r(c,u);if(d in e)return r(void 0,c)}const l={url:o,method:o,data:o,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,withXSRFToken:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:a,headers:(c,u,d)=>i(mp(c),mp(u),d,!0)};return w.forEach(Object.keys({...e,...t}),function(u){const d=l[u]||i,h=d(e[u],t[u],u);w.isUndefined(h)&&d!==a||(n[u]=h)}),n}const vp=e=>{const t=Xn({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:i,xsrfCookieName:o,headers:s,auth:a}=t;if(t.headers=s=Xe.from(s),t.url=sp(pp(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),a&&s.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):""))),w.isFormData(n)){if(ze.hasStandardBrowserEnv||ze.hasStandardBrowserWebWorkerEnv)s.setContentType(void 0);else if(w.isFunction(n.getHeaders)){const l=n.getHeaders(),c=["content-type","content-length"];Object.entries(l).forEach(([u,d])=>{c.includes(u.toLowerCase())&&s.set(u,d)})}}if(ze.hasStandardBrowserEnv&&(r&&w.isFunction(r)&&(r=r(t)),r||r!==!1&&c2(t.url))){const l=i&&o&&u2.read(o);l&&s.set(i,l)}return t},f2=typeof XMLHttpRequest<"u"&&function(e){return new Promise(function(n,r){const i=vp(e);let o=i.data;const s=Xe.from(i.headers).normalize();let{responseType:a,onUploadProgress:l,onDownloadProgress:c}=i,u,d,h,m,f;function g(){m&&m(),f&&f(),i.cancelToken&&i.cancelToken.unsubscribe(u),i.signal&&i.signal.removeEventListener("abort",u)}let p=new XMLHttpRequest;p.open(i.method.toUpperCase(),i.url,!0),p.timeout=i.timeout;function b(){if(!p)return;const S=Xe.from("getAllResponseHeaders"in p&&p.getAllResponseHeaders()),k={data:!a||a==="text"||a==="json"?p.responseText:p.response,status:p.status,statusText:p.statusText,headers:S,config:e,request:p};hp(function(A){n(A),g()},function(A){r(A),g()},k),p=null}"onloadend"in p?p.onloadend=b:p.onreadystatechange=function(){!p||p.readyState!==4||p.status===0&&!(p.responseURL&&p.responseURL.indexOf("file:")===0)||setTimeout(b)},p.onabort=function(){p&&(r(new Q("Request aborted",Q.ECONNABORTED,e,p)),p=null)},p.onerror=function(y){const k=y&&y.message?y.message:"Network Error",R=new Q(k,Q.ERR_NETWORK,e,p);R.event=y||null,r(R),p=null},p.ontimeout=function(){let y=i.timeout?"timeout of "+i.timeout+"ms exceeded":"timeout exceeded";const k=i.transitional||lp;i.timeoutErrorMessage&&(y=i.timeoutErrorMessage),r(new Q(y,k.clarifyTimeoutError?Q.ETIMEDOUT:Q.ECONNABORTED,e,p)),p=null},o===void 0&&s.setContentType(null),"setRequestHeader"in p&&w.forEach(s.toJSON(),function(y,k){p.setRequestHeader(k,y)}),w.isUndefined(i.withCredentials)||(p.withCredentials=!!i.withCredentials),a&&a!=="json"&&(p.responseType=i.responseType),c&&([h,f]=Es(c,!0),p.addEventListener("progress",h)),l&&p.upload&&([d,m]=Es(l),p.upload.addEventListener("progress",d),p.upload.addEventListener("loadend",m)),(i.cancelToken||i.signal)&&(u=S=>{p&&(r(!S||S.type?new zr(null,e,p):S),p.abort(),p=null)},i.cancelToken&&i.cancelToken.subscribe(u),i.signal&&(i.signal.aborted?u():i.signal.addEventListener("abort",u)));const C=s2(i.url);if(C&&ze.protocols.indexOf(C)===-1){r(new Q("Unsupported protocol "+C+":",Q.ERR_BAD_REQUEST,e));return}p.send(o||null)})},g2=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let r=new AbortController,i;const o=function(c){if(!i){i=!0,a();const u=c instanceof Error?c:this.reason;r.abort(u instanceof Q?u:new zr(u instanceof Error?u.message:u))}};let s=t&&setTimeout(()=>{s=null,o(new Q(`timeout ${t} of ms exceeded`,Q.ETIMEDOUT))},t);const a=()=>{e&&(s&&clearTimeout(s),s=null,e.forEach(c=>{c.unsubscribe?c.unsubscribe(o):c.removeEventListener("abort",o)}),e=null)};e.forEach(c=>c.addEventListener("abort",o));const{signal:l}=r;return l.unsubscribe=()=>w.asap(a),l}},p2=function*(e,t){let n=e.byteLength;if(n{const i=m2(e,t);let o=0,s,a=l=>{s||(s=!0,r&&r(l))};return new ReadableStream({async pull(l){try{const{done:c,value:u}=await i.next();if(c){a(),l.close();return}let d=u.byteLength;if(n){let h=o+=d;n(h)}l.enqueue(new Uint8Array(u))}catch(c){throw a(c),c}},cancel(l){return a(l),i.return()}},{highWaterMark:2})},yp=64*1024,{isFunction:ks}=w,b2=(({Request:e,Response:t})=>({Request:e,Response:t}))(w.global),{ReadableStream:xp,TextEncoder:Cp}=w.global,Sp=(e,...t)=>{try{return!!e(...t)}catch{return!1}},y2=e=>{e=w.merge.call({skipUndefined:!0},b2,e);const{fetch:t,Request:n,Response:r}=e,i=t?ks(t):typeof fetch=="function",o=ks(n),s=ks(r);if(!i)return!1;const a=i&&ks(xp),l=i&&(typeof Cp=="function"?(f=>g=>f.encode(g))(new Cp):async f=>new Uint8Array(await new n(f).arrayBuffer())),c=o&&a&&Sp(()=>{let f=!1;const g=new n(ze.origin,{body:new xp,method:"POST",get duplex(){return f=!0,"half"}}).headers.has("Content-Type");return f&&!g}),u=s&&a&&Sp(()=>w.isReadableStream(new r("").body)),d={stream:u&&(f=>f.body)};i&&["text","arrayBuffer","blob","formData","stream"].forEach(f=>{!d[f]&&(d[f]=(g,p)=>{let b=g&&g[f];if(b)return b.call(g);throw new Q(`Response type '${f}' is not supported`,Q.ERR_NOT_SUPPORT,p)})});const h=async f=>{if(f==null)return 0;if(w.isBlob(f))return f.size;if(w.isSpecCompliantForm(f))return(await new n(ze.origin,{method:"POST",body:f}).arrayBuffer()).byteLength;if(w.isArrayBufferView(f)||w.isArrayBuffer(f))return f.byteLength;if(w.isURLSearchParams(f)&&(f=f+""),w.isString(f))return(await l(f)).byteLength},m=async(f,g)=>{const p=w.toFiniteNumber(f.getContentLength());return p??h(g)};return async f=>{let{url:g,method:p,data:b,signal:C,cancelToken:S,timeout:y,onDownloadProgress:k,onUploadProgress:R,responseType:A,headers:T,withCredentials:N="same-origin",fetchOptions:I}=vp(f),B=t||fetch;A=A?(A+"").toLowerCase():"text";let P=g2([C,S&&S.toAbortSignal()],y),F=null;const X=P&&P.unsubscribe&&(()=>{P.unsubscribe()});let z;try{if(R&&c&&p!=="get"&&p!=="head"&&(z=await m(T,b))!==0){let G=new n(g,{method:"POST",body:b,duplex:"half"}),re;if(w.isFormData(b)&&(re=G.headers.get("content-type"))&&T.setContentType(re),G.body){const[gt,Mt]=fp(z,Es(gp(R)));b=bp(G.body,yp,gt,Mt)}}w.isString(N)||(N=N?"include":"omit");const _=o&&"credentials"in n.prototype,j={...I,signal:P,method:p.toUpperCase(),headers:T.normalize().toJSON(),body:b,duplex:"half",credentials:_?N:void 0};F=o&&new n(g,j);let W=await(o?B(F,I):B(g,j));const M=u&&(A==="stream"||A==="response");if(u&&(k||M&&X)){const G={};["status","statusText","headers"].forEach(Qt=>{G[Qt]=W[Qt]});const re=w.toFiniteNumber(W.headers.get("content-length")),[gt,Mt]=k&&fp(re,Es(gp(k),!0))||[];W=new r(bp(W.body,yp,gt,()=>{Mt&&Mt(),X&&X()}),G)}A=A||"text";let U=await d[w.findKey(d,A)||"text"](W,f);return!M&&X&&X(),await new Promise((G,re)=>{hp(G,re,{data:U,headers:Xe.from(W.headers),status:W.status,statusText:W.statusText,config:f,request:F})})}catch(_){throw X&&X(),_&&_.name==="TypeError"&&/Load failed|fetch/i.test(_.message)?Object.assign(new Q("Network Error",Q.ERR_NETWORK,f,F),{cause:_.cause||_}):Q.from(_,_&&_.code,f,F)}}},x2=new Map,wp=e=>{let t=e?e.env:{};const{fetch:n,Request:r,Response:i}=t,o=[r,i,n];let s=o.length,a=s,l,c,u=x2;for(;a--;)l=o[a],c=u.get(l),c===void 0&&u.set(l,c=a?new Map:y2(t)),u=c;return c};wp();const tc={http:jT,xhr:f2,fetch:{get:wp}};w.forEach(tc,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const Ep=e=>`- ${e}`,C2=e=>w.isFunction(e)||e===null||e===!1,kp={getAdapter:(e,t)=>{e=w.isArray(e)?e:[e];const{length:n}=e;let r,i;const o={};for(let s=0;s`adapter ${l} `+(c===!1?"is not supported by the environment":"is not available in the build"));let a=n?s.length>1?`since : +`+s.map(Ep).join(` +`):" "+Ep(s[0]):"as no adapter specified";throw new Q("There is no suitable adapter to dispatch the request "+a,"ERR_NOT_SUPPORT")}return i},adapters:tc};function nc(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new zr(null,e)}function Op(e){return nc(e),e.headers=Xe.from(e.headers),e.data=ec.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),kp.getAdapter(e.adapter||Vi.adapter,e)(e).then(function(r){return nc(e),r.data=ec.call(e,e.transformResponse,r),r.headers=Xe.from(r.headers),r},function(r){return dp(r)||(nc(e),r&&r.response&&(r.response.data=ec.call(e,e.transformResponse,r.response),r.response.headers=Xe.from(r.response.headers))),Promise.reject(r)})}const Ip="1.12.2",Os={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{Os[e]=function(r){return typeof r===e||"a"+(t<1?"n ":" ")+e}});const Pp={};Os.transitional=function(t,n,r){function i(o,s){return"[Axios v"+Ip+"] Transitional option '"+o+"'"+s+(r?". "+r:"")}return(o,s,a)=>{if(t===!1)throw new Q(i(s," has been removed"+(n?" in "+n:"")),Q.ERR_DEPRECATED);return n&&!Pp[s]&&(Pp[s]=!0,console.warn(i(s," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,s,a):!0}},Os.spelling=function(t){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${t}`),!0)};function S2(e,t,n){if(typeof e!="object")throw new Q("options must be an object",Q.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let i=r.length;for(;i-- >0;){const o=r[i],s=t[o];if(s){const a=e[o],l=a===void 0||s(a,o,e);if(l!==!0)throw new Q("option "+o+" must be "+l,Q.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new Q("Unknown option "+o,Q.ERR_BAD_OPTION)}}const Is={assertOptions:S2,validators:Os},Ft=Is.validators;let Yn=class{constructor(t){this.defaults=t||{},this.interceptors={request:new ap,response:new ap}}async request(t,n){try{return await this._request(t,n)}catch(r){if(r instanceof Error){let i={};Error.captureStackTrace?Error.captureStackTrace(i):i=new Error;const o=i.stack?i.stack.replace(/^.+\n/,""):"";try{r.stack?o&&!String(r.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(r.stack+=` +`+o):r.stack=o}catch{}}throw r}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=Xn(this.defaults,n);const{transitional:r,paramsSerializer:i,headers:o}=n;r!==void 0&&Is.assertOptions(r,{silentJSONParsing:Ft.transitional(Ft.boolean),forcedJSONParsing:Ft.transitional(Ft.boolean),clarifyTimeoutError:Ft.transitional(Ft.boolean)},!1),i!=null&&(w.isFunction(i)?n.paramsSerializer={serialize:i}:Is.assertOptions(i,{encode:Ft.function,serialize:Ft.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Is.assertOptions(n,{baseUrl:Ft.spelling("baseURL"),withXsrfToken:Ft.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let s=o&&w.merge(o.common,o[n.method]);o&&w.forEach(["delete","get","head","post","put","patch","common"],f=>{delete o[f]}),n.headers=Xe.concat(s,o);const a=[];let l=!0;this.interceptors.request.forEach(function(g){typeof g.runWhen=="function"&&g.runWhen(n)===!1||(l=l&&g.synchronous,a.unshift(g.fulfilled,g.rejected))});const c=[];this.interceptors.response.forEach(function(g){c.push(g.fulfilled,g.rejected)});let u,d=0,h;if(!l){const f=[Op.bind(this),void 0];for(f.unshift(...a),f.push(...c),h=f.length,u=Promise.resolve(n);d{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](i);r._listeners=null}),this.promise.then=i=>{let o;const s=new Promise(a=>{r.subscribe(a),o=a}).then(i);return s.cancel=function(){r.unsubscribe(o)},s},t(function(o,s,a){r.reason||(r.reason=new zr(o,s,a),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=r=>{t.abort(r)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new bb(function(i){t=i}),cancel:t}}};function E2(e){return function(n){return e.apply(null,n)}}function k2(e){return w.isObject(e)&&e.isAxiosError===!0}const rc={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(rc).forEach(([e,t])=>{rc[t]=e});function Rp(e){const t=new Yn(e),n=Ug(Yn.prototype.request,t);return w.extend(n,Yn.prototype,t,{allOwnKeys:!0}),w.extend(n,t,null,{allOwnKeys:!0}),n.create=function(i){return Rp(Xn(e,i))},n}const ge=Rp(Vi);ge.Axios=Yn,ge.CanceledError=zr,ge.CancelToken=w2,ge.isCancel=dp,ge.VERSION=Ip,ge.toFormData=Ss,ge.AxiosError=Q,ge.Cancel=ge.CanceledError,ge.all=function(t){return Promise.all(t)},ge.spread=E2,ge.isAxiosError=k2,ge.mergeConfig=Xn,ge.AxiosHeaders=Xe,ge.formToJSON=e=>cp(w.isHTMLForm(e)?new FormData(e):e),ge.getAdapter=kp.getAdapter,ge.HttpStatusCode=rc,ge.default=ge;const{Axios:k_,AxiosError:O_,CanceledError:I_,isCancel:P_,CancelToken:R_,VERSION:T_,all:N_,Cancel:A_,isAxiosError:__,spread:V_,toFormData:F_,AxiosHeaders:L_,HttpStatusCode:D_,formToJSON:z_,getAdapter:M_,mergeConfig:$_}=ge;var Ps=["light","dark"],ic="(prefers-color-scheme: dark)",O2=typeof window>"u",Tp=O.createContext(void 0),I2=e=>O.useContext(Tp)?e.children:O.createElement(R2,{...e}),P2=["light","dark"],R2=({forcedTheme:e,disableTransitionOnChange:t=!1,enableSystem:n=!0,enableColorScheme:r=!0,storageKey:i="theme",themes:o=P2,defaultTheme:s=n?"system":"light",attribute:a="data-theme",value:l,children:c,nonce:u})=>{let[d,h]=O.useState(()=>Np(i,s)),[m,f]=O.useState(()=>Np(i)),g=l?Object.values(l):o,p=O.useCallback(y=>{let k=y;if(!k)return;y==="system"&&n&&(k=Ap());let R=l?l[k]:k,A=t?N2():null,T=document.documentElement;if(a==="class"?(T.classList.remove(...g),R&&T.classList.add(R)):R?T.setAttribute(a,R):T.removeAttribute(a),r){let N=Ps.includes(s)?s:null,I=Ps.includes(k)?k:N;T.style.colorScheme=I}A==null||A()},[]),b=O.useCallback(y=>{let k=typeof y=="function"?y(y):y;h(k);try{localStorage.setItem(i,k)}catch{}},[e]),C=O.useCallback(y=>{let k=Ap(y);f(k),d==="system"&&n&&!e&&p("system")},[d,e]);O.useEffect(()=>{let y=window.matchMedia(ic);return y.addListener(C),C(y),()=>y.removeListener(C)},[C]),O.useEffect(()=>{let y=k=>{if(k.key!==i)return;let R=k.newValue||s;b(R)};return window.addEventListener("storage",y),()=>window.removeEventListener("storage",y)},[b]),O.useEffect(()=>{p(e??d)},[e,d]);let S=O.useMemo(()=>({theme:d,setTheme:b,forcedTheme:e,resolvedTheme:d==="system"?m:d,themes:n?[...o,"system"]:o,systemTheme:n?m:void 0}),[d,b,e,m,n,o]);return O.createElement(Tp.Provider,{value:S},O.createElement(T2,{forcedTheme:e,disableTransitionOnChange:t,enableSystem:n,enableColorScheme:r,storageKey:i,themes:o,defaultTheme:s,attribute:a,value:l,children:c,attrs:g,nonce:u}),c)},T2=O.memo(({forcedTheme:e,storageKey:t,attribute:n,enableSystem:r,enableColorScheme:i,defaultTheme:o,value:s,attrs:a,nonce:l})=>{let c=o==="system",u=n==="class"?`var d=document.documentElement,c=d.classList;${`c.remove(${a.map(f=>`'${f}'`).join(",")})`};`:`var d=document.documentElement,n='${n}',s='setAttribute';`,d=i?Ps.includes(o)&&o?`if(e==='light'||e==='dark'||!e)d.style.colorScheme=e||'${o}'`:"if(e==='light'||e==='dark')d.style.colorScheme=e":"",h=(f,g=!1,p=!0)=>{let b=s?s[f]:f,C=g?f+"|| ''":`'${b}'`,S="";return i&&p&&!g&&Ps.includes(f)&&(S+=`d.style.colorScheme = '${f}';`),n==="class"?g||b?S+=`c.add(${C})`:S+="null":b&&(S+=`d[s](n,${C})`),S},m=e?`!function(){${u}${h(e)}}()`:r?`!function(){try{${u}var e=localStorage.getItem('${t}');if('system'===e||(!e&&${c})){var t='${ic}',m=window.matchMedia(t);if(m.media!==t||m.matches){${h("dark")}}else{${h("light")}}}else if(e){${s?`var x=${JSON.stringify(s)};`:""}${h(s?"x[e]":"e",!0)}}${c?"":"else{"+h(o,!1,!1)+"}"}${d}}catch(e){}}()`:`!function(){try{${u}var e=localStorage.getItem('${t}');if(e){${s?`var x=${JSON.stringify(s)};`:""}${h(s?"x[e]":"e",!0)}}else{${h(o,!1,!1)};}${d}}catch(t){}}();`;return O.createElement("script",{nonce:l,dangerouslySetInnerHTML:{__html:m}})}),Np=(e,t)=>{if(O2)return;let n;try{n=localStorage.getItem(e)||void 0}catch{}return n||t},N2=()=>{let e=document.createElement("style");return e.appendChild(document.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),document.head.appendChild(e),()=>{window.getComputedStyle(document.body),setTimeout(()=>{document.head.removeChild(e)},1)}},Ap=e=>(e||(e=window.matchMedia(ic)),e.matches?"dark":"light");const A2=e=>x.jsx(I2,{attribute:"class",disableTransitionOnChange:!0,...e});/** * @remix-run/router v1.23.0 * * Copyright (c) Remix Software Inc. @@ -35,7 +35,7 @@ * LICENSE.md file in the root directory of this source tree. * * @license MIT - */function Vi(){return Vi=Object.assign?Object.assign.bind():function(e){for(var t=1;t"u")throw new Error(t)}function Ap(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function A2(){return Math.random().toString(36).substr(2,8)}function _p(e,t){return{usr:e.state,key:e.key,idx:t}}function oc(e,t,n,r){return n===void 0&&(n=null),Vi({pathname:typeof e=="string"?e:e.pathname,search:"",hash:""},typeof t=="string"?Fr(t):t,{state:n,key:t&&t.key||r||A2()})}function Ps(e){let{pathname:t="/",search:n="",hash:r=""}=e;return n&&n!=="?"&&(t+=n.charAt(0)==="?"?n:"?"+n),r&&r!=="#"&&(t+=r.charAt(0)==="#"?r:"#"+r),t}function Fr(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function _2(e,t,n,r){r===void 0&&(r={});let{window:i=document.defaultView,v5Compat:o=!1}=r,s=i.history,a=cn.Pop,l=null,c=u();c==null&&(c=0,s.replaceState(Vi({},s.state,{idx:c}),""));function u(){return(s.state||{idx:null}).idx}function d(){a=cn.Pop;let p=u(),v=p==null?null:p-c;c=p,l&&l({action:a,location:g.location,delta:v})}function h(p,v){a=cn.Push;let x=oc(g.location,p,v);c=u()+1;let S=_p(x,c),C=g.createHref(x);try{s.pushState(S,"",C)}catch(w){if(w instanceof DOMException&&w.name==="DataCloneError")throw w;i.location.assign(C)}o&&l&&l({action:a,location:g.location,delta:1})}function m(p,v){a=cn.Replace;let x=oc(g.location,p,v);c=u();let S=_p(x,c),C=g.createHref(x);s.replaceState(S,"",C),o&&l&&l({action:a,location:g.location,delta:0})}function f(p){let v=i.location.origin!=="null"?i.location.origin:i.location.href,x=typeof p=="string"?p:Ps(p);return x=x.replace(/ $/,"%20"),pe(v,"No window.location.(origin|href) available to create URL for href: "+x),new URL(x,v)}let g={get action(){return a},get location(){return e(i,s)},listen(p){if(l)throw new Error("A history only accepts one active listener");return i.addEventListener(Np,d),l=p,()=>{i.removeEventListener(Np,d),l=null}},createHref(p){return t(i,p)},createURL:f,encodeLocation(p){let v=f(p);return{pathname:v.pathname,search:v.search,hash:v.hash}},push:h,replace:m,go(p){return s.go(p)}};return g}var Vp;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(Vp||(Vp={}));function V2(e,t,n){return n===void 0&&(n="/"),F2(e,t,n)}function F2(e,t,n,r){let i=typeof t=="string"?Fr(t):t,o=Lr(i.pathname||"/",n);if(o==null)return null;let s=Fp(e);L2(s);let a=null;for(let l=0;a==null&&l{let l={relativePath:a===void 0?o.path||"":a,caseSensitive:o.caseSensitive===!0,childrenIndex:s,route:o};l.relativePath.startsWith("/")&&(pe(l.relativePath.startsWith(r),'Absolute route path "'+l.relativePath+'" nested under path '+('"'+r+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),l.relativePath=l.relativePath.slice(r.length));let c=un([r,l.relativePath]),u=n.concat(l);o.children&&o.children.length>0&&(pe(o.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+c+'".')),Fp(o.children,t,u,c)),!(o.path==null&&!o.index)&&t.push({path:c,score:W2(c,o.index),routesMeta:u})};return e.forEach((o,s)=>{var a;if(o.path===""||!((a=o.path)!=null&&a.includes("?")))i(o,s);else for(let l of Lp(o.path))i(o,s,l)}),t}function Lp(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,i=n.endsWith("?"),o=n.replace(/\?$/,"");if(r.length===0)return i?[o,""]:[o];let s=Lp(r.join("/")),a=[];return a.push(...s.map(l=>l===""?o:[o,l].join("/"))),i&&a.push(...s),a.map(l=>e.startsWith("/")&&l===""?"/":l)}function L2(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:H2(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}const D2=/^:[\w-]+$/,z2=3,M2=2,$2=1,B2=10,j2=-2,Dp=e=>e==="*";function W2(e,t){let n=e.split("/"),r=n.length;return n.some(Dp)&&(r+=j2),t&&(r+=M2),n.filter(i=>!Dp(i)).reduce((i,o)=>i+(D2.test(o)?z2:o===""?$2:B2),r)}function H2(e,t){return e.length===t.length&&e.slice(0,-1).every((r,i)=>r===t[i])?e[e.length-1]-t[t.length-1]:0}function U2(e,t,n){let{routesMeta:r}=e,i={},o="/",s=[];for(let a=0;a{let{paramName:h,isOptional:m}=u;if(h==="*"){let g=a[d]||"";s=o.slice(0,o.length-g.length).replace(/(.)\/+$/,"$1")}const f=a[d];return m&&!f?c[h]=void 0:c[h]=(f||"").replace(/%2F/g,"/"),c},{}),pathname:o,pathnameBase:s,pattern:e}}function G2(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!0),Ap(e==="*"||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were '+('"'+e.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+e.replace(/\*$/,"/*")+'".'));let r=[],i="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(s,a,l)=>(r.push({paramName:a,isOptional:l!=null}),l?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(r.push({paramName:"*"}),i+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?i+="\\/*$":e!==""&&e!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,t?void 0:"i"),r]}function q2(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return Ap(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+t+").")),e}}function Lr(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}function K2(e,t){t===void 0&&(t="/");let{pathname:n,search:r="",hash:i=""}=typeof e=="string"?Fr(e):e;return{pathname:n?n.startsWith("/")?n:X2(n,t):t,search:J2(r),hash:Z2(i)}}function X2(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(i=>{i===".."?n.length>1&&n.pop():i!=="."&&n.push(i)}),n.length>1?n.join("/"):"/"}function ac(e,t,n,r){return"Cannot include a '"+e+"' character in a manually specified "+("`to."+t+"` field ["+JSON.stringify(r)+"]. Please separate it out to the ")+("`to."+n+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}function Y2(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function zp(e,t){let n=Y2(e);return t?n.map((r,i)=>i===n.length-1?r.pathname:r.pathnameBase):n.map(r=>r.pathnameBase)}function Mp(e,t,n,r){r===void 0&&(r=!1);let i;typeof e=="string"?i=Fr(e):(i=Vi({},e),pe(!i.pathname||!i.pathname.includes("?"),ac("?","pathname","search",i)),pe(!i.pathname||!i.pathname.includes("#"),ac("#","pathname","hash",i)),pe(!i.search||!i.search.includes("#"),ac("#","search","hash",i)));let o=e===""||i.pathname==="",s=o?"/":i.pathname,a;if(s==null)a=n;else{let d=t.length-1;if(!r&&s.startsWith("..")){let h=s.split("/");for(;h[0]==="..";)h.shift(),d-=1;i.pathname=h.join("/")}a=d>=0?t[d]:"/"}let l=K2(i,a),c=s&&s!=="/"&&s.endsWith("/"),u=(o||s===".")&&n.endsWith("/");return!l.pathname.endsWith("/")&&(c||u)&&(l.pathname+="/"),l}const un=e=>e.join("/").replace(/\/\/+/g,"/"),Q2=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),J2=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,Z2=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;function eN(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}const $p=["post","put","patch","delete"];new Set($p);const tN=["get",...$p];new Set(tN);/** + */function Li(){return Li=Object.assign?Object.assign.bind():function(e){for(var t=1;t"u")throw new Error(t)}function Vp(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function V2(){return Math.random().toString(36).substr(2,8)}function Fp(e,t){return{usr:e.state,key:e.key,idx:t}}function oc(e,t,n,r){return n===void 0&&(n=null),Li({pathname:typeof e=="string"?e:e.pathname,search:"",hash:""},typeof t=="string"?Mr(t):t,{state:n,key:t&&t.key||r||V2()})}function Rs(e){let{pathname:t="/",search:n="",hash:r=""}=e;return n&&n!=="?"&&(t+=n.charAt(0)==="?"?n:"?"+n),r&&r!=="#"&&(t+=r.charAt(0)==="#"?r:"#"+r),t}function Mr(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function F2(e,t,n,r){r===void 0&&(r={});let{window:i=document.defaultView,v5Compat:o=!1}=r,s=i.history,a=fn.Pop,l=null,c=u();c==null&&(c=0,s.replaceState(Li({},s.state,{idx:c}),""));function u(){return(s.state||{idx:null}).idx}function d(){a=fn.Pop;let p=u(),b=p==null?null:p-c;c=p,l&&l({action:a,location:g.location,delta:b})}function h(p,b){a=fn.Push;let C=oc(g.location,p,b);c=u()+1;let S=Fp(C,c),y=g.createHref(C);try{s.pushState(S,"",y)}catch(k){if(k instanceof DOMException&&k.name==="DataCloneError")throw k;i.location.assign(y)}o&&l&&l({action:a,location:g.location,delta:1})}function m(p,b){a=fn.Replace;let C=oc(g.location,p,b);c=u();let S=Fp(C,c),y=g.createHref(C);s.replaceState(S,"",y),o&&l&&l({action:a,location:g.location,delta:0})}function f(p){let b=i.location.origin!=="null"?i.location.origin:i.location.href,C=typeof p=="string"?p:Rs(p);return C=C.replace(/ $/,"%20"),pe(b,"No window.location.(origin|href) available to create URL for href: "+C),new URL(C,b)}let g={get action(){return a},get location(){return e(i,s)},listen(p){if(l)throw new Error("A history only accepts one active listener");return i.addEventListener(_p,d),l=p,()=>{i.removeEventListener(_p,d),l=null}},createHref(p){return t(i,p)},createURL:f,encodeLocation(p){let b=f(p);return{pathname:b.pathname,search:b.search,hash:b.hash}},push:h,replace:m,go(p){return s.go(p)}};return g}var Lp;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(Lp||(Lp={}));function L2(e,t,n){return n===void 0&&(n="/"),D2(e,t,n)}function D2(e,t,n,r){let i=typeof t=="string"?Mr(t):t,o=$r(i.pathname||"/",n);if(o==null)return null;let s=Dp(e);z2(s);let a=null;for(let l=0;a==null&&l{let l={relativePath:a===void 0?o.path||"":a,caseSensitive:o.caseSensitive===!0,childrenIndex:s,route:o};l.relativePath.startsWith("/")&&(pe(l.relativePath.startsWith(r),'Absolute route path "'+l.relativePath+'" nested under path '+('"'+r+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),l.relativePath=l.relativePath.slice(r.length));let c=gn([r,l.relativePath]),u=n.concat(l);o.children&&o.children.length>0&&(pe(o.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+c+'".')),Dp(o.children,t,u,c)),!(o.path==null&&!o.index)&&t.push({path:c,score:U2(c,o.index),routesMeta:u})};return e.forEach((o,s)=>{var a;if(o.path===""||!((a=o.path)!=null&&a.includes("?")))i(o,s);else for(let l of zp(o.path))i(o,s,l)}),t}function zp(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,i=n.endsWith("?"),o=n.replace(/\?$/,"");if(r.length===0)return i?[o,""]:[o];let s=zp(r.join("/")),a=[];return a.push(...s.map(l=>l===""?o:[o,l].join("/"))),i&&a.push(...s),a.map(l=>e.startsWith("/")&&l===""?"/":l)}function z2(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:G2(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}const M2=/^:[\w-]+$/,$2=3,B2=2,j2=1,W2=10,H2=-2,Mp=e=>e==="*";function U2(e,t){let n=e.split("/"),r=n.length;return n.some(Mp)&&(r+=H2),t&&(r+=B2),n.filter(i=>!Mp(i)).reduce((i,o)=>i+(M2.test(o)?$2:o===""?j2:W2),r)}function G2(e,t){return e.length===t.length&&e.slice(0,-1).every((r,i)=>r===t[i])?e[e.length-1]-t[t.length-1]:0}function q2(e,t,n){let{routesMeta:r}=e,i={},o="/",s=[];for(let a=0;a{let{paramName:h,isOptional:m}=u;if(h==="*"){let g=a[d]||"";s=o.slice(0,o.length-g.length).replace(/(.)\/+$/,"$1")}const f=a[d];return m&&!f?c[h]=void 0:c[h]=(f||"").replace(/%2F/g,"/"),c},{}),pathname:o,pathnameBase:s,pattern:e}}function K2(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!0),Vp(e==="*"||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were '+('"'+e.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+e.replace(/\*$/,"/*")+'".'));let r=[],i="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(s,a,l)=>(r.push({paramName:a,isOptional:l!=null}),l?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(r.push({paramName:"*"}),i+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?i+="\\/*$":e!==""&&e!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,t?void 0:"i"),r]}function X2(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return Vp(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+t+").")),e}}function $r(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}function Y2(e,t){t===void 0&&(t="/");let{pathname:n,search:r="",hash:i=""}=typeof e=="string"?Mr(e):e;return{pathname:n?n.startsWith("/")?n:Q2(n,t):t,search:eN(r),hash:tN(i)}}function Q2(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(i=>{i===".."?n.length>1&&n.pop():i!=="."&&n.push(i)}),n.length>1?n.join("/"):"/"}function ac(e,t,n,r){return"Cannot include a '"+e+"' character in a manually specified "+("`to."+t+"` field ["+JSON.stringify(r)+"]. Please separate it out to the ")+("`to."+n+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}function J2(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function $p(e,t){let n=J2(e);return t?n.map((r,i)=>i===n.length-1?r.pathname:r.pathnameBase):n.map(r=>r.pathnameBase)}function Bp(e,t,n,r){r===void 0&&(r=!1);let i;typeof e=="string"?i=Mr(e):(i=Li({},e),pe(!i.pathname||!i.pathname.includes("?"),ac("?","pathname","search",i)),pe(!i.pathname||!i.pathname.includes("#"),ac("#","pathname","hash",i)),pe(!i.search||!i.search.includes("#"),ac("#","search","hash",i)));let o=e===""||i.pathname==="",s=o?"/":i.pathname,a;if(s==null)a=n;else{let d=t.length-1;if(!r&&s.startsWith("..")){let h=s.split("/");for(;h[0]==="..";)h.shift(),d-=1;i.pathname=h.join("/")}a=d>=0?t[d]:"/"}let l=Y2(i,a),c=s&&s!=="/"&&s.endsWith("/"),u=(o||s===".")&&n.endsWith("/");return!l.pathname.endsWith("/")&&(c||u)&&(l.pathname+="/"),l}const gn=e=>e.join("/").replace(/\/\/+/g,"/"),Z2=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),eN=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,tN=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;function nN(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}const jp=["post","put","patch","delete"];new Set(jp);const rN=["get",...jp];new Set(rN);/** * React Router v6.30.1 * * Copyright (c) Remix Software Inc. @@ -44,7 +44,7 @@ * LICENSE.md file in the root directory of this source tree. * * @license MIT - */function Fi(){return Fi=Object.assign?Object.assign.bind():function(e){for(var t=1;t{a.current=!0}),O.useCallback(function(c,u){if(u===void 0&&(u={}),!a.current)return;if(typeof c=="number"){r.go(c);return}let d=Mp(c,JSON.parse(s),o,u.relative==="path");e==null&&t!=="/"&&(d.pathname=d.pathname==="/"?t:un([t,d.pathname])),(u.replace?r.replace:r.push)(d,u.state,u)},[t,r,s,o,e])}function Ns(e,t){let{relative:n}=t===void 0?{}:t,{future:r}=O.useContext(dn),{matches:i}=O.useContext(Xn),{pathname:o}=Di(),s=JSON.stringify(zp(i,r.v7_relativeSplatPath));return O.useMemo(()=>Mp(e,JSON.parse(s),o,n==="path"),[e,s,o,n])}function oN(e,t){return sN(e,t)}function sN(e,t,n,r){Li()||pe(!1);let{navigator:i}=O.useContext(dn),{matches:o}=O.useContext(Xn),s=o[o.length-1],a=s?s.params:{};s&&s.pathname;let l=s?s.pathnameBase:"/";s&&s.route;let c=Di(),u;if(t){var d;let p=typeof t=="string"?Fr(t):t;l==="/"||(d=p.pathname)!=null&&d.startsWith(l)||pe(!1),u=p}else u=c;let h=u.pathname||"/",m=h;if(l!=="/"){let p=l.replace(/^\//,"").split("/");m="/"+h.replace(/^\//,"").split("/").slice(p.length).join("/")}let f=V2(e,{pathname:m}),g=dN(f&&f.map(p=>Object.assign({},p,{params:Object.assign({},a,p.params),pathname:un([l,i.encodeLocation?i.encodeLocation(p.pathname).pathname:p.pathname]),pathnameBase:p.pathnameBase==="/"?l:un([l,i.encodeLocation?i.encodeLocation(p.pathnameBase).pathname:p.pathnameBase])})),o,n,r);return t&&g?O.createElement(Ts.Provider,{value:{location:Fi({pathname:"/",search:"",hash:"",state:null,key:"default"},u),navigationType:cn.Pop}},g):g}function aN(){let e=pN(),t=eN(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,i={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return O.createElement(O.Fragment,null,O.createElement("h2",null,"Unexpected Application Error!"),O.createElement("h3",{style:{fontStyle:"italic"}},t),n?O.createElement("pre",{style:i},n):null,null)}const lN=O.createElement(aN,null);class cN extends O.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,n){return n.location!==t.location||n.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:n.error,location:n.location,revalidation:t.revalidation||n.revalidation}}componentDidCatch(t,n){console.error("React Router caught the following error during render",t,n)}render(){return this.state.error!==void 0?O.createElement(Xn.Provider,{value:this.props.routeContext},O.createElement(jp.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function uN(e){let{routeContext:t,match:n,children:r}=e,i=O.useContext(Rs);return i&&i.static&&i.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(i.staticContext._deepestRenderedBoundaryId=n.route.id),O.createElement(Xn.Provider,{value:t},r)}function dN(e,t,n,r){var i;if(t===void 0&&(t=[]),n===void 0&&(n=null),r===void 0&&(r=null),e==null){var o;if(!n)return null;if(n.errors)e=n.matches;else if((o=r)!=null&&o.v7_partialHydration&&t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let s=e,a=(i=n)==null?void 0:i.errors;if(a!=null){let u=s.findIndex(d=>d.route.id&&(a==null?void 0:a[d.route.id])!==void 0);u>=0||pe(!1),s=s.slice(0,Math.min(s.length,u+1))}let l=!1,c=-1;if(n&&r&&r.v7_partialHydration)for(let u=0;u=0?s=s.slice(0,c+1):s=[s[0]];break}}}return s.reduceRight((u,d,h)=>{let m,f=!1,g=null,p=null;n&&(m=a&&d.route.id?a[d.route.id]:void 0,g=d.route.errorElement||lN,l&&(c<0&&h===0?(vN("route-fallback"),f=!0,p=null):c===h&&(f=!0,p=d.route.hydrateFallbackElement||null)));let v=t.concat(s.slice(0,h+1)),x=()=>{let S;return m?S=g:f?S=p:d.route.Component?S=O.createElement(d.route.Component,null):d.route.element?S=d.route.element:S=u,O.createElement(uN,{match:d,routeContext:{outlet:u,matches:v,isDataRoute:n!=null},children:S})};return n&&(d.route.ErrorBoundary||d.route.errorElement||h===0)?O.createElement(cN,{location:n.location,revalidation:n.revalidation,component:g,error:m,children:x(),routeContext:{outlet:null,matches:v,isDataRoute:!0}}):x()},null)}var Hp=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(Hp||{}),Up=function(e){return e.UseBlocker="useBlocker",e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e.UseRouteId="useRouteId",e}(Up||{});function hN(e){let t=O.useContext(Rs);return t||pe(!1),t}function fN(e){let t=O.useContext(Bp);return t||pe(!1),t}function gN(e){let t=O.useContext(Xn);return t||pe(!1),t}function Gp(e){let t=gN(),n=t.matches[t.matches.length-1];return n.route.id||pe(!1),n.route.id}function pN(){var e;let t=O.useContext(jp),n=fN(),r=Gp();return t!==void 0?t:(e=n.errors)==null?void 0:e[r]}function mN(){let{router:e}=hN(Hp.UseNavigateStable),t=Gp(Up.UseNavigateStable),n=O.useRef(!1);return Wp(()=>{n.current=!0}),O.useCallback(function(i,o){o===void 0&&(o={}),n.current&&(typeof i=="number"?e.navigate(i):e.navigate(i,Fi({fromRouteId:t},o)))},[e,t])}const qp={};function vN(e,t,n){qp[e]||(qp[e]=!0)}function bN(e,t){e==null||e.v7_startTransition,e==null||e.v7_relativeSplatPath}function lc(e){pe(!1)}function yN(e){let{basename:t="/",children:n=null,location:r,navigationType:i=cn.Pop,navigator:o,static:s=!1,future:a}=e;Li()&&pe(!1);let l=t.replace(/^\/*/,"/"),c=O.useMemo(()=>({basename:l,navigator:o,static:s,future:Fi({v7_relativeSplatPath:!1},a)}),[l,a,o,s]);typeof r=="string"&&(r=Fr(r));let{pathname:u="/",search:d="",hash:h="",state:m=null,key:f="default"}=r,g=O.useMemo(()=>{let p=Lr(u,l);return p==null?null:{location:{pathname:p,search:d,hash:h,state:m,key:f},navigationType:i}},[l,u,d,h,m,f,i]);return g==null?null:O.createElement(dn.Provider,{value:c},O.createElement(Ts.Provider,{children:n,value:g}))}function xN(e){let{children:t,location:n}=e;return oN(cc(t),n)}new Promise(()=>{});function cc(e,t){t===void 0&&(t=[]);let n=[];return O.Children.forEach(e,(r,i)=>{if(!O.isValidElement(r))return;let o=[...t,i];if(r.type===O.Fragment){n.push.apply(n,cc(r.props.children,o));return}r.type!==lc&&pe(!1),!r.props.index||!r.props.children||pe(!1);let s={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,loader:r.props.loader,action:r.props.action,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(s.children=cc(r.props.children,o)),n.push(s)}),n}/** + */function Di(){return Di=Object.assign?Object.assign.bind():function(e){for(var t=1;t{a.current=!0}),O.useCallback(function(c,u){if(u===void 0&&(u={}),!a.current)return;if(typeof c=="number"){r.go(c);return}let d=Bp(c,JSON.parse(s),o,u.relative==="path");e==null&&t!=="/"&&(d.pathname=d.pathname==="/"?t:gn([t,d.pathname])),(u.replace?r.replace:r.push)(d,u.state,u)},[t,r,s,o,e])}function As(e,t){let{relative:n}=t===void 0?{}:t,{future:r}=O.useContext(pn),{matches:i}=O.useContext(Qn),{pathname:o}=Mi(),s=JSON.stringify($p(i,r.v7_relativeSplatPath));return O.useMemo(()=>Bp(e,JSON.parse(s),o,n==="path"),[e,s,o,n])}function aN(e,t){return lN(e,t)}function lN(e,t,n,r){zi()||pe(!1);let{navigator:i}=O.useContext(pn),{matches:o}=O.useContext(Qn),s=o[o.length-1],a=s?s.params:{};s&&s.pathname;let l=s?s.pathnameBase:"/";s&&s.route;let c=Mi(),u;if(t){var d;let p=typeof t=="string"?Mr(t):t;l==="/"||(d=p.pathname)!=null&&d.startsWith(l)||pe(!1),u=p}else u=c;let h=u.pathname||"/",m=h;if(l!=="/"){let p=l.replace(/^\//,"").split("/");m="/"+h.replace(/^\//,"").split("/").slice(p.length).join("/")}let f=L2(e,{pathname:m}),g=fN(f&&f.map(p=>Object.assign({},p,{params:Object.assign({},a,p.params),pathname:gn([l,i.encodeLocation?i.encodeLocation(p.pathname).pathname:p.pathname]),pathnameBase:p.pathnameBase==="/"?l:gn([l,i.encodeLocation?i.encodeLocation(p.pathnameBase).pathname:p.pathnameBase])})),o,n,r);return t&&g?O.createElement(Ns.Provider,{value:{location:Di({pathname:"/",search:"",hash:"",state:null,key:"default"},u),navigationType:fn.Pop}},g):g}function cN(){let e=vN(),t=nN(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,i={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return O.createElement(O.Fragment,null,O.createElement("h2",null,"Unexpected Application Error!"),O.createElement("h3",{style:{fontStyle:"italic"}},t),n?O.createElement("pre",{style:i},n):null,null)}const uN=O.createElement(cN,null);class dN extends O.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,n){return n.location!==t.location||n.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:n.error,location:n.location,revalidation:t.revalidation||n.revalidation}}componentDidCatch(t,n){console.error("React Router caught the following error during render",t,n)}render(){return this.state.error!==void 0?O.createElement(Qn.Provider,{value:this.props.routeContext},O.createElement(Hp.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function hN(e){let{routeContext:t,match:n,children:r}=e,i=O.useContext(Ts);return i&&i.static&&i.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(i.staticContext._deepestRenderedBoundaryId=n.route.id),O.createElement(Qn.Provider,{value:t},r)}function fN(e,t,n,r){var i;if(t===void 0&&(t=[]),n===void 0&&(n=null),r===void 0&&(r=null),e==null){var o;if(!n)return null;if(n.errors)e=n.matches;else if((o=r)!=null&&o.v7_partialHydration&&t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let s=e,a=(i=n)==null?void 0:i.errors;if(a!=null){let u=s.findIndex(d=>d.route.id&&(a==null?void 0:a[d.route.id])!==void 0);u>=0||pe(!1),s=s.slice(0,Math.min(s.length,u+1))}let l=!1,c=-1;if(n&&r&&r.v7_partialHydration)for(let u=0;u=0?s=s.slice(0,c+1):s=[s[0]];break}}}return s.reduceRight((u,d,h)=>{let m,f=!1,g=null,p=null;n&&(m=a&&d.route.id?a[d.route.id]:void 0,g=d.route.errorElement||uN,l&&(c<0&&h===0?(yN("route-fallback"),f=!0,p=null):c===h&&(f=!0,p=d.route.hydrateFallbackElement||null)));let b=t.concat(s.slice(0,h+1)),C=()=>{let S;return m?S=g:f?S=p:d.route.Component?S=O.createElement(d.route.Component,null):d.route.element?S=d.route.element:S=u,O.createElement(hN,{match:d,routeContext:{outlet:u,matches:b,isDataRoute:n!=null},children:S})};return n&&(d.route.ErrorBoundary||d.route.errorElement||h===0)?O.createElement(dN,{location:n.location,revalidation:n.revalidation,component:g,error:m,children:C(),routeContext:{outlet:null,matches:b,isDataRoute:!0}}):C()},null)}var Gp=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(Gp||{}),qp=function(e){return e.UseBlocker="useBlocker",e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e.UseRouteId="useRouteId",e}(qp||{});function gN(e){let t=O.useContext(Ts);return t||pe(!1),t}function pN(e){let t=O.useContext(Wp);return t||pe(!1),t}function mN(e){let t=O.useContext(Qn);return t||pe(!1),t}function Kp(e){let t=mN(),n=t.matches[t.matches.length-1];return n.route.id||pe(!1),n.route.id}function vN(){var e;let t=O.useContext(Hp),n=pN(),r=Kp();return t!==void 0?t:(e=n.errors)==null?void 0:e[r]}function bN(){let{router:e}=gN(Gp.UseNavigateStable),t=Kp(qp.UseNavigateStable),n=O.useRef(!1);return Up(()=>{n.current=!0}),O.useCallback(function(i,o){o===void 0&&(o={}),n.current&&(typeof i=="number"?e.navigate(i):e.navigate(i,Di({fromRouteId:t},o)))},[e,t])}const Xp={};function yN(e,t,n){Xp[e]||(Xp[e]=!0)}function xN(e,t){e==null||e.v7_startTransition,e==null||e.v7_relativeSplatPath}function lc(e){pe(!1)}function CN(e){let{basename:t="/",children:n=null,location:r,navigationType:i=fn.Pop,navigator:o,static:s=!1,future:a}=e;zi()&&pe(!1);let l=t.replace(/^\/*/,"/"),c=O.useMemo(()=>({basename:l,navigator:o,static:s,future:Di({v7_relativeSplatPath:!1},a)}),[l,a,o,s]);typeof r=="string"&&(r=Mr(r));let{pathname:u="/",search:d="",hash:h="",state:m=null,key:f="default"}=r,g=O.useMemo(()=>{let p=$r(u,l);return p==null?null:{location:{pathname:p,search:d,hash:h,state:m,key:f},navigationType:i}},[l,u,d,h,m,f,i]);return g==null?null:O.createElement(pn.Provider,{value:c},O.createElement(Ns.Provider,{children:n,value:g}))}function SN(e){let{children:t,location:n}=e;return aN(cc(t),n)}new Promise(()=>{});function cc(e,t){t===void 0&&(t=[]);let n=[];return O.Children.forEach(e,(r,i)=>{if(!O.isValidElement(r))return;let o=[...t,i];if(r.type===O.Fragment){n.push.apply(n,cc(r.props.children,o));return}r.type!==lc&&pe(!1),!r.props.index||!r.props.children||pe(!1);let s={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,loader:r.props.loader,action:r.props.action,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(s.children=cc(r.props.children,o)),n.push(s)}),n}/** * React Router DOM v6.30.1 * * Copyright (c) Remix Software Inc. @@ -53,7 +53,7 @@ * LICENSE.md file in the root directory of this source tree. * * @license MIT - */function As(){return As=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&(n[i]=e[i]);return n}function CN(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function SN(e,t){return e.button===0&&(!t||t==="_self")&&!CN(e)}const wN=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],EN=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],kN="6";try{window.__reactRouterVersion=kN}catch{}const ON=O.createContext({isTransitioning:!1}),Xp=O["startTransition"];function IN(e){let{basename:t,children:n,future:r,window:i}=e,o=O.useRef();o.current==null&&(o.current=N2({window:i,v5Compat:!0}));let s=o.current,[a,l]=O.useState({action:s.action,location:s.location}),{v7_startTransition:c}=r||{},u=O.useCallback(d=>{c&&Xp?Xp(()=>l(d)):l(d)},[l,c]);return O.useLayoutEffect(()=>s.listen(u),[s,u]),O.useEffect(()=>bN(r),[r]),O.createElement(yN,{basename:t,children:n,location:a.location,navigationType:a.action,navigator:s,future:r})}const PN=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",RN=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,TN=O.forwardRef(function(t,n){let{onClick:r,relative:i,reloadDocument:o,replace:s,state:a,target:l,to:c,preventScrollReset:u,viewTransition:d}=t,h=Kp(t,wN),{basename:m}=O.useContext(dn),f,g=!1;if(typeof c=="string"&&RN.test(c)&&(f=c,PN))try{let S=new URL(window.location.href),C=c.startsWith("//")?new URL(S.protocol+c):new URL(c),w=Lr(C.pathname,m);C.origin===S.origin&&w!=null?c=w+C.search+C.hash:g=!0}catch{}let p=nN(c,{relative:i}),v=_N(c,{replace:s,state:a,target:l,preventScrollReset:u,relative:i,viewTransition:d});function x(S){r&&r(S),S.defaultPrevented||v(S)}return O.createElement("a",As({},h,{href:f||p,onClick:g||o?r:x,ref:n,target:l}))}),NN=O.forwardRef(function(t,n){let{"aria-current":r="page",caseSensitive:i=!1,className:o="",end:s=!1,style:a,to:l,viewTransition:c,children:u}=t,d=Kp(t,EN),h=Ns(l,{relative:d.relative}),m=Di(),f=O.useContext(Bp),{navigator:g,basename:p}=O.useContext(dn),v=f!=null&&VN(h)&&c===!0,x=g.encodeLocation?g.encodeLocation(h).pathname:h.pathname,S=m.pathname,C=f&&f.navigation&&f.navigation.location?f.navigation.location.pathname:null;i||(S=S.toLowerCase(),C=C?C.toLowerCase():null,x=x.toLowerCase()),C&&p&&(C=Lr(C,p)||C);const w=x!=="/"&&x.endsWith("/")?x.length-1:x.length;let P=S===x||!s&&S.startsWith(x)&&S.charAt(w)==="/",_=C!=null&&(C===x||!s&&C.startsWith(x)&&C.charAt(x.length)==="/"),R={isActive:P,isPending:_,isTransitioning:v},N=P?r:void 0,T;typeof o=="function"?T=o(R):T=[o,P?"active":null,_?"pending":null,v?"transitioning":null].filter(Boolean).join(" ");let j=typeof a=="function"?a(R):a;return O.createElement(TN,As({},d,{"aria-current":N,className:T,ref:n,style:j,to:l,viewTransition:c}),typeof u=="function"?u(R):u)});var uc;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(uc||(uc={}));var Yp;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(Yp||(Yp={}));function AN(e){let t=O.useContext(Rs);return t||pe(!1),t}function _N(e,t){let{target:n,replace:r,state:i,preventScrollReset:o,relative:s,viewTransition:a}=t===void 0?{}:t,l=rN(),c=Di(),u=Ns(e,{relative:s});return O.useCallback(d=>{if(SN(d,n)){d.preventDefault();let h=r!==void 0?r:Ps(c)===Ps(u);l(e,{replace:h,state:i,preventScrollReset:o,relative:s,viewTransition:a})}},[c,l,u,r,i,n,e,o,s,a])}function VN(e,t){t===void 0&&(t={});let n=O.useContext(ON);n==null&&pe(!1);let{basename:r}=AN(uc.useViewTransitionState),i=Ns(e,{relative:t.relative});if(!n.isTransitioning)return!1;let o=Lr(n.currentLocation.pathname,r)||n.currentLocation.pathname,s=Lr(n.nextLocation.pathname,r)||n.nextLocation.pathname;return sc(i.pathname,s)!=null||sc(i.pathname,o)!=null}const FN="UiServiceWorker",LN=e=>[FN],DN="UiServiceJobs",zN=e=>[DN];class Qp{constructor(){Je(this,"_fns");this._fns=[]}eject(t){const n=this._fns.indexOf(t);n!==-1&&(this._fns=[...this._fns.slice(0,n),...this._fns.slice(n+1)])}use(t){this._fns=[...this._fns,t]}}const _s={BASE:"",CREDENTIALS:"include",ENCODE_PATH:void 0,HEADERS:void 0,PASSWORD:void 0,TOKEN:void 0,USERNAME:void 0,VERSION:"0.1.0",WITH_CREDENTIALS:!1,interceptors:{request:new Qp,response:new Qp}};class Jp extends Error{constructor(n,r,i){super(i);Je(this,"url");Je(this,"status");Je(this,"statusText");Je(this,"body");Je(this,"request");this.name="ApiError",this.url=r.url,this.status=r.status,this.statusText=r.statusText,this.body=r.body,this.request=n}}class MN extends Error{constructor(t){super(t),this.name="CancelError"}get isCancelled(){return!0}}class $N{constructor(t){Je(this,"_isResolved");Je(this,"_isRejected");Je(this,"_isCancelled");Je(this,"cancelHandlers");Je(this,"promise");Je(this,"_resolve");Je(this,"_reject");this._isResolved=!1,this._isRejected=!1,this._isCancelled=!1,this.cancelHandlers=[],this.promise=new Promise((n,r)=>{this._resolve=n,this._reject=r;const i=a=>{this._isResolved||this._isRejected||this._isCancelled||(this._isResolved=!0,this._resolve&&this._resolve(a))},o=a=>{this._isResolved||this._isRejected||this._isCancelled||(this._isRejected=!0,this._reject&&this._reject(a))},s=a=>{this._isResolved||this._isRejected||this._isCancelled||this.cancelHandlers.push(a)};return Object.defineProperty(s,"isResolved",{get:()=>this._isResolved}),Object.defineProperty(s,"isRejected",{get:()=>this._isRejected}),Object.defineProperty(s,"isCancelled",{get:()=>this._isCancelled}),t(i,o,s)})}get[Symbol.toStringTag](){return"Cancellable Promise"}then(t,n){return this.promise.then(t,n)}catch(t){return this.promise.catch(t)}finally(t){return this.promise.finally(t)}cancel(){if(!(this._isResolved||this._isRejected||this._isCancelled)){if(this._isCancelled=!0,this.cancelHandlers.length)try{for(const t of this.cancelHandlers)t()}catch(t){console.warn("Cancellation threw an error",t);return}this.cancelHandlers.length=0,this._reject&&this._reject(new MN("Request aborted"))}}get isCancelled(){return this._isCancelled}}const Vs=e=>typeof e=="string",dc=e=>Vs(e)&&e!=="",Zp=e=>e instanceof Blob,BN=e=>e instanceof FormData,em=e=>e>=200&&e<300,jN=e=>{try{return btoa(e)}catch{return Buffer.from(e).toString("base64")}},WN=e=>{const t=[],n=(i,o)=>{t.push(`${encodeURIComponent(i)}=${encodeURIComponent(String(o))}`)},r=(i,o)=>{o!=null&&(o instanceof Date?n(i,o.toISOString()):Array.isArray(o)?o.forEach(s=>r(i,s)):typeof o=="object"?Object.entries(o).forEach(([s,a])=>r(`${i}[${s}]`,a)):n(i,o))};return Object.entries(e).forEach(([i,o])=>r(i,o)),t.length?`?${t.join("&")}`:""},HN=(e,t)=>{const n=encodeURI,r=t.url.replace("{api-version}",e.VERSION).replace(/{(.*?)}/g,(o,s)=>{var a;return(a=t.path)!=null&&a.hasOwnProperty(s)?n(String(t.path[s])):o}),i=e.BASE+r;return t.query?i+WN(t.query):i},UN=e=>{if(e.formData){const t=new FormData,n=(r,i)=>{Vs(i)||Zp(i)?t.append(r,i):t.append(r,JSON.stringify(i))};return Object.entries(e.formData).filter(([,r])=>r!=null).forEach(([r,i])=>{Array.isArray(i)?i.forEach(o=>n(r,o)):n(r,i)}),t}},Fs=async(e,t)=>t,GN=async(e,t)=>{const[n,r,i,o]=await Promise.all([Fs(t,e.TOKEN),Fs(t,e.USERNAME),Fs(t,e.PASSWORD),Fs(t,e.HEADERS)]),s=Object.entries({Accept:"application/json",...o,...t.headers}).filter(([,a])=>a!=null).reduce((a,[l,c])=>({...a,[l]:String(c)}),{});if(dc(n)&&(s.Authorization=`Bearer ${n}`),dc(r)&&dc(i)){const a=jN(`${r}:${i}`);s.Authorization=`Basic ${a}`}return t.body!==void 0?t.mediaType?s["Content-Type"]=t.mediaType:Zp(t.body)?s["Content-Type"]=t.body.type||"application/octet-stream":Vs(t.body)?s["Content-Type"]="text/plain":BN(t.body)||(s["Content-Type"]="application/json"):t.formData!==void 0&&t.mediaType&&(s["Content-Type"]=t.mediaType),s},qN=e=>{if(e.body)return e.body},KN=async(e,t,n,r,i,o,s,a)=>{const l=new AbortController;let c={data:r??i,headers:o,method:t.method,signal:l.signal,url:n,withCredentials:e.WITH_CREDENTIALS};s(()=>l.abort());for(const u of e.interceptors.request._fns)c=await u(c);try{return await a.request(c)}catch(u){const d=u;if(d.response)return d.response;throw u}},XN=(e,t)=>{if(t){const n=e.headers[t];if(Vs(n))return n}},YN=e=>{if(e.status!==204)return e.data},QN=(e,t)=>{const r={400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Payload Too Large",414:"URI Too Long",415:"Unsupported Media Type",416:"Range Not Satisfiable",417:"Expectation Failed",418:"Im a teapot",421:"Misdirected Request",422:"Unprocessable Content",423:"Locked",424:"Failed Dependency",425:"Too Early",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",451:"Unavailable For Legal Reasons",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",508:"Loop Detected",510:"Not Extended",511:"Network Authentication Required",...e.errors}[t.status];if(r)throw new Jp(e,t,r);if(!t.ok){const i=t.status??"unknown",o=t.statusText??"unknown",s=(()=>{try{return JSON.stringify(t.body,null,2)}catch{return}})();throw new Jp(e,t,`Generic Error: status: ${i}; status text: ${o}; body: ${s}`)}},Ls=(e,t,n=ge)=>new $N(async(r,i,o)=>{try{const s=HN(e,t),a=UN(t),l=qN(t),c=await GN(e,t);if(!o.isCancelled){let u=await KN(e,t,s,l,a,c,o,n);for(const g of e.interceptors.response._fns)u=await g(u);const d=YN(u),h=XN(u,t.responseHeader);let m=d;t.responseTransformer&&em(u.status)&&(m=await t.responseTransformer(d));const f={url:s,ok:em(u.status),status:u.status,statusText:u.statusText,body:h??m};QN(t,f),r(f.body)}}catch(s){i(s)}});class Ds{static worker(){return Ls(_s,{method:"GET",url:"/edge_worker/ui/worker"})}static jobs(){return Ls(_s,{method:"GET",url:"/edge_worker/ui/jobs"})}static requestWorkerMaintenance(t){return Ls(_s,{method:"POST",url:"/edge_worker/ui/worker/{worker_name}/maintenance",path:{worker_name:t.workerName},body:t.requestBody,mediaType:"application/json",errors:{422:"Validation Error"}})}static exitWorkerMaintenance(t){return Ls(_s,{method:"DELETE",url:"/edge_worker/ui/worker/{worker_name}/maintenance",path:{worker_name:t.workerName},errors:{422:"Validation Error"}})}}const JN=(e,t)=>Wg({queryKey:LN(),queryFn:()=>Ds.worker(),...t}),ZN=(e,t)=>Wg({queryKey:zN(),queryFn:()=>Ds.jobs(),...t}),eA=e=>Hg({mutationFn:({requestBody:t,workerName:n})=>Ds.requestWorkerMaintenance({requestBody:t,workerName:n}),...e}),tA=e=>Hg({mutationFn:({workerName:t})=>Ds.exitWorkerMaintenance({workerName:t}),...e});var tm={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},nm=E.createContext&&E.createContext(tm),nA=["attr","size","title"];function rA(e,t){if(e==null)return{};var n=iA(e,t),r,i;if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}function iA(e,t){if(e==null)return{};var n={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}function zs(){return zs=Object.assign?Object.assign.bind():function(e){for(var t=1;tE.createElement(t.tag,Ms({key:n},t.attr),im(t.child)))}function be(e){return t=>E.createElement(lA,zs({attr:Ms({},e.attr)},t),im(e.child))}function lA(e){var t=n=>{var{attr:r,size:i,title:o}=e,s=rA(e,nA),a=i||n.size||"1em",l;return n.className&&(l=n.className),e.className&&(l=(l?l+" ":"")+e.className),E.createElement("svg",zs({stroke:"currentColor",fill:"currentColor",strokeWidth:"0"},n.attr,r,s,{className:l,style:Ms(Ms({color:e.color||n.color},n.style),e.style),height:a,width:a,xmlns:"http://www.w3.org/2000/svg"}),o&&E.createElement("title",null,o),e.children)};return nm!==void 0?E.createElement(nm.Consumer,null,n=>t(n)):t(tm)}function cA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M11 10v4h4"},child:[]},{tag:"path",attr:{d:"m11 14 1.535-1.605a5 5 0 0 1 8 1.5"},child:[]},{tag:"path",attr:{d:"M16 2v4"},child:[]},{tag:"path",attr:{d:"m21 18-1.535 1.605a5 5 0 0 1-8-1.5"},child:[]},{tag:"path",attr:{d:"M21 22v-4h-4"},child:[]},{tag:"path",attr:{d:"M21 8.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h4.3"},child:[]},{tag:"path",attr:{d:"M3 10h4"},child:[]},{tag:"path",attr:{d:"M8 2v4"},child:[]}]})(e)}function uA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M20 6 9 17l-5-5"},child:[]}]})(e)}function om(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M10.1 2.182a10 10 0 0 1 3.8 0"},child:[]},{tag:"path",attr:{d:"M13.9 21.818a10 10 0 0 1-3.8 0"},child:[]},{tag:"path",attr:{d:"M17.609 3.721a10 10 0 0 1 2.69 2.7"},child:[]},{tag:"path",attr:{d:"M2.182 13.9a10 10 0 0 1 0-3.8"},child:[]},{tag:"path",attr:{d:"M20.279 17.609a10 10 0 0 1-2.7 2.69"},child:[]},{tag:"path",attr:{d:"M21.818 10.1a10 10 0 0 1 0 3.8"},child:[]},{tag:"path",attr:{d:"M3.721 6.391a10 10 0 0 1 2.7-2.69"},child:[]},{tag:"path",attr:{d:"M6.391 20.279a10 10 0 0 1-2.69-2.7"},child:[]}]})(e)}function dA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M12 2a10 10 0 0 1 7.38 16.75"},child:[]},{tag:"path",attr:{d:"m16 12-4-4-4 4"},child:[]},{tag:"path",attr:{d:"M12 16V8"},child:[]},{tag:"path",attr:{d:"M2.5 8.875a10 10 0 0 0-.5 3"},child:[]},{tag:"path",attr:{d:"M2.83 16a10 10 0 0 0 2.43 3.4"},child:[]},{tag:"path",attr:{d:"M4.636 5.235a10 10 0 0 1 .891-.857"},child:[]},{tag:"path",attr:{d:"M8.644 21.42a10 10 0 0 0 7.631-.38"},child:[]}]})(e)}function hA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"m15 14 5-5-5-5"},child:[]},{tag:"path",attr:{d:"M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13"},child:[]}]})(e)}function fA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M18 6 6 18"},child:[]},{tag:"path",attr:{d:"m6 6 12 12"},child:[]}]})(e)}const gA=E.forwardRef((e,t)=>y.jsx(ds,{"aria-label":"Close",ref:t,variant:"ghost",...e,children:e.children??y.jsx(fA,{})})),pA=E.forwardRef((e,t)=>{const{children:n,closable:r,endElement:i,icon:o,onClose:s,startElement:a,title:l,...c}=e;return y.jsxs(jP,{ref:t,...c,alignItems:"center",children:[a??y.jsx(GP,{children:o}),n?y.jsxs(HP,{children:[y.jsx(fg,{children:l}),y.jsx(WP,{children:n})]}):y.jsx(fg,{flex:"1",children:l}),i,r?y.jsx(gA,{alignSelf:"flex-start",insetEnd:"-2",onClick:s,pos:"relative",size:"sm",top:"-2"}):void 0]})});/*! + */function _s(){return _s=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&(n[i]=e[i]);return n}function wN(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function EN(e,t){return e.button===0&&(!t||t==="_self")&&!wN(e)}const kN=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],ON=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],IN="6";try{window.__reactRouterVersion=IN}catch{}const PN=O.createContext({isTransitioning:!1}),Qp=O["startTransition"];function RN(e){let{basename:t,children:n,future:r,window:i}=e,o=O.useRef();o.current==null&&(o.current=_2({window:i,v5Compat:!0}));let s=o.current,[a,l]=O.useState({action:s.action,location:s.location}),{v7_startTransition:c}=r||{},u=O.useCallback(d=>{c&&Qp?Qp(()=>l(d)):l(d)},[l,c]);return O.useLayoutEffect(()=>s.listen(u),[s,u]),O.useEffect(()=>xN(r),[r]),O.createElement(CN,{basename:t,children:n,location:a.location,navigationType:a.action,navigator:s,future:r})}const TN=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",NN=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,AN=O.forwardRef(function(t,n){let{onClick:r,relative:i,reloadDocument:o,replace:s,state:a,target:l,to:c,preventScrollReset:u,viewTransition:d}=t,h=Yp(t,kN),{basename:m}=O.useContext(pn),f,g=!1;if(typeof c=="string"&&NN.test(c)&&(f=c,TN))try{let S=new URL(window.location.href),y=c.startsWith("//")?new URL(S.protocol+c):new URL(c),k=$r(y.pathname,m);y.origin===S.origin&&k!=null?c=k+y.search+y.hash:g=!0}catch{}let p=iN(c,{relative:i}),b=FN(c,{replace:s,state:a,target:l,preventScrollReset:u,relative:i,viewTransition:d});function C(S){r&&r(S),S.defaultPrevented||b(S)}return O.createElement("a",_s({},h,{href:f||p,onClick:g||o?r:C,ref:n,target:l}))}),_N=O.forwardRef(function(t,n){let{"aria-current":r="page",caseSensitive:i=!1,className:o="",end:s=!1,style:a,to:l,viewTransition:c,children:u}=t,d=Yp(t,ON),h=As(l,{relative:d.relative}),m=Mi(),f=O.useContext(Wp),{navigator:g,basename:p}=O.useContext(pn),b=f!=null&&LN(h)&&c===!0,C=g.encodeLocation?g.encodeLocation(h).pathname:h.pathname,S=m.pathname,y=f&&f.navigation&&f.navigation.location?f.navigation.location.pathname:null;i||(S=S.toLowerCase(),y=y?y.toLowerCase():null,C=C.toLowerCase()),y&&p&&(y=$r(y,p)||y);const k=C!=="/"&&C.endsWith("/")?C.length-1:C.length;let R=S===C||!s&&S.startsWith(C)&&S.charAt(k)==="/",A=y!=null&&(y===C||!s&&y.startsWith(C)&&y.charAt(C.length)==="/"),T={isActive:R,isPending:A,isTransitioning:b},N=R?r:void 0,I;typeof o=="function"?I=o(T):I=[o,R?"active":null,A?"pending":null,b?"transitioning":null].filter(Boolean).join(" ");let B=typeof a=="function"?a(T):a;return O.createElement(AN,_s({},d,{"aria-current":N,className:I,ref:n,style:B,to:l,viewTransition:c}),typeof u=="function"?u(T):u)});var uc;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(uc||(uc={}));var Jp;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(Jp||(Jp={}));function VN(e){let t=O.useContext(Ts);return t||pe(!1),t}function FN(e,t){let{target:n,replace:r,state:i,preventScrollReset:o,relative:s,viewTransition:a}=t===void 0?{}:t,l=oN(),c=Mi(),u=As(e,{relative:s});return O.useCallback(d=>{if(EN(d,n)){d.preventDefault();let h=r!==void 0?r:Rs(c)===Rs(u);l(e,{replace:h,state:i,preventScrollReset:o,relative:s,viewTransition:a})}},[c,l,u,r,i,n,e,o,s,a])}function LN(e,t){t===void 0&&(t={});let n=O.useContext(PN);n==null&&pe(!1);let{basename:r}=VN(uc.useViewTransitionState),i=As(e,{relative:t.relative});if(!n.isTransitioning)return!1;let o=$r(n.currentLocation.pathname,r)||n.currentLocation.pathname,s=$r(n.nextLocation.pathname,r)||n.nextLocation.pathname;return sc(i.pathname,s)!=null||sc(i.pathname,o)!=null}const DN="UiServiceWorker",zN=e=>[DN],MN="UiServiceJobs",$N=e=>[MN];class Zp{constructor(){Je(this,"_fns");this._fns=[]}eject(t){const n=this._fns.indexOf(t);n!==-1&&(this._fns=[...this._fns.slice(0,n),...this._fns.slice(n+1)])}use(t){this._fns=[...this._fns,t]}}const Vs={BASE:"",CREDENTIALS:"include",ENCODE_PATH:void 0,HEADERS:void 0,PASSWORD:void 0,TOKEN:void 0,USERNAME:void 0,VERSION:"0.1.0",WITH_CREDENTIALS:!1,interceptors:{request:new Zp,response:new Zp}};class em extends Error{constructor(n,r,i){super(i);Je(this,"url");Je(this,"status");Je(this,"statusText");Je(this,"body");Je(this,"request");this.name="ApiError",this.url=r.url,this.status=r.status,this.statusText=r.statusText,this.body=r.body,this.request=n}}class BN extends Error{constructor(t){super(t),this.name="CancelError"}get isCancelled(){return!0}}class jN{constructor(t){Je(this,"_isResolved");Je(this,"_isRejected");Je(this,"_isCancelled");Je(this,"cancelHandlers");Je(this,"promise");Je(this,"_resolve");Je(this,"_reject");this._isResolved=!1,this._isRejected=!1,this._isCancelled=!1,this.cancelHandlers=[],this.promise=new Promise((n,r)=>{this._resolve=n,this._reject=r;const i=a=>{this._isResolved||this._isRejected||this._isCancelled||(this._isResolved=!0,this._resolve&&this._resolve(a))},o=a=>{this._isResolved||this._isRejected||this._isCancelled||(this._isRejected=!0,this._reject&&this._reject(a))},s=a=>{this._isResolved||this._isRejected||this._isCancelled||this.cancelHandlers.push(a)};return Object.defineProperty(s,"isResolved",{get:()=>this._isResolved}),Object.defineProperty(s,"isRejected",{get:()=>this._isRejected}),Object.defineProperty(s,"isCancelled",{get:()=>this._isCancelled}),t(i,o,s)})}get[Symbol.toStringTag](){return"Cancellable Promise"}then(t,n){return this.promise.then(t,n)}catch(t){return this.promise.catch(t)}finally(t){return this.promise.finally(t)}cancel(){if(!(this._isResolved||this._isRejected||this._isCancelled)){if(this._isCancelled=!0,this.cancelHandlers.length)try{for(const t of this.cancelHandlers)t()}catch(t){console.warn("Cancellation threw an error",t);return}this.cancelHandlers.length=0,this._reject&&this._reject(new BN("Request aborted"))}}get isCancelled(){return this._isCancelled}}const Fs=e=>typeof e=="string",dc=e=>Fs(e)&&e!=="",tm=e=>e instanceof Blob,WN=e=>e instanceof FormData,nm=e=>e>=200&&e<300,HN=e=>{try{return btoa(e)}catch{return Buffer.from(e).toString("base64")}},UN=e=>{const t=[],n=(i,o)=>{t.push(`${encodeURIComponent(i)}=${encodeURIComponent(String(o))}`)},r=(i,o)=>{o!=null&&(o instanceof Date?n(i,o.toISOString()):Array.isArray(o)?o.forEach(s=>r(i,s)):typeof o=="object"?Object.entries(o).forEach(([s,a])=>r(`${i}[${s}]`,a)):n(i,o))};return Object.entries(e).forEach(([i,o])=>r(i,o)),t.length?`?${t.join("&")}`:""},GN=(e,t)=>{const n=encodeURI,r=t.url.replace("{api-version}",e.VERSION).replace(/{(.*?)}/g,(o,s)=>{var a;return(a=t.path)!=null&&a.hasOwnProperty(s)?n(String(t.path[s])):o}),i=e.BASE+r;return t.query?i+UN(t.query):i},qN=e=>{if(e.formData){const t=new FormData,n=(r,i)=>{Fs(i)||tm(i)?t.append(r,i):t.append(r,JSON.stringify(i))};return Object.entries(e.formData).filter(([,r])=>r!=null).forEach(([r,i])=>{Array.isArray(i)?i.forEach(o=>n(r,o)):n(r,i)}),t}},Ls=async(e,t)=>t,KN=async(e,t)=>{const[n,r,i,o]=await Promise.all([Ls(t,e.TOKEN),Ls(t,e.USERNAME),Ls(t,e.PASSWORD),Ls(t,e.HEADERS)]),s=Object.entries({Accept:"application/json",...o,...t.headers}).filter(([,a])=>a!=null).reduce((a,[l,c])=>({...a,[l]:String(c)}),{});if(dc(n)&&(s.Authorization=`Bearer ${n}`),dc(r)&&dc(i)){const a=HN(`${r}:${i}`);s.Authorization=`Basic ${a}`}return t.body!==void 0?t.mediaType?s["Content-Type"]=t.mediaType:tm(t.body)?s["Content-Type"]=t.body.type||"application/octet-stream":Fs(t.body)?s["Content-Type"]="text/plain":WN(t.body)||(s["Content-Type"]="application/json"):t.formData!==void 0&&t.mediaType&&(s["Content-Type"]=t.mediaType),s},XN=e=>{if(e.body)return e.body},YN=async(e,t,n,r,i,o,s,a)=>{const l=new AbortController;let c={data:r??i,headers:o,method:t.method,signal:l.signal,url:n,withCredentials:e.WITH_CREDENTIALS};s(()=>l.abort());for(const u of e.interceptors.request._fns)c=await u(c);try{return await a.request(c)}catch(u){const d=u;if(d.response)return d.response;throw u}},QN=(e,t)=>{if(t){const n=e.headers[t];if(Fs(n))return n}},JN=e=>{if(e.status!==204)return e.data},ZN=(e,t)=>{const r={400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Payload Too Large",414:"URI Too Long",415:"Unsupported Media Type",416:"Range Not Satisfiable",417:"Expectation Failed",418:"Im a teapot",421:"Misdirected Request",422:"Unprocessable Content",423:"Locked",424:"Failed Dependency",425:"Too Early",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",451:"Unavailable For Legal Reasons",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",508:"Loop Detected",510:"Not Extended",511:"Network Authentication Required",...e.errors}[t.status];if(r)throw new em(e,t,r);if(!t.ok){const i=t.status??"unknown",o=t.statusText??"unknown",s=(()=>{try{return JSON.stringify(t.body,null,2)}catch{return}})();throw new em(e,t,`Generic Error: status: ${i}; status text: ${o}; body: ${s}`)}},Ds=(e,t,n=ge)=>new jN(async(r,i,o)=>{try{const s=GN(e,t),a=qN(t),l=XN(t),c=await KN(e,t);if(!o.isCancelled){let u=await YN(e,t,s,l,a,c,o,n);for(const g of e.interceptors.response._fns)u=await g(u);const d=JN(u),h=QN(u,t.responseHeader);let m=d;t.responseTransformer&&nm(u.status)&&(m=await t.responseTransformer(d));const f={url:s,ok:nm(u.status),status:u.status,statusText:u.statusText,body:h??m};ZN(t,f),r(f.body)}}catch(s){i(s)}});class zs{static worker(){return Ds(Vs,{method:"GET",url:"/edge_worker/ui/worker"})}static jobs(){return Ds(Vs,{method:"GET",url:"/edge_worker/ui/jobs"})}static requestWorkerMaintenance(t){return Ds(Vs,{method:"POST",url:"/edge_worker/ui/worker/{worker_name}/maintenance",path:{worker_name:t.workerName},body:t.requestBody,mediaType:"application/json",errors:{422:"Validation Error"}})}static exitWorkerMaintenance(t){return Ds(Vs,{method:"DELETE",url:"/edge_worker/ui/worker/{worker_name}/maintenance",path:{worker_name:t.workerName},errors:{422:"Validation Error"}})}}const eA=(e,t)=>Wg({queryKey:zN(),queryFn:()=>zs.worker(),...t}),tA=(e,t)=>Wg({queryKey:$N(),queryFn:()=>zs.jobs(),...t}),nA=e=>Hg({mutationFn:({requestBody:t,workerName:n})=>zs.requestWorkerMaintenance({requestBody:t,workerName:n}),...e}),rA=e=>Hg({mutationFn:({workerName:t})=>zs.exitWorkerMaintenance({workerName:t}),...e});var rm={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},im=E.createContext&&E.createContext(rm),iA=["attr","size","title"];function oA(e,t){if(e==null)return{};var n=sA(e,t),r,i;if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}function sA(e,t){if(e==null)return{};var n={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}function Ms(){return Ms=Object.assign?Object.assign.bind():function(e){for(var t=1;tE.createElement(t.tag,$s({key:n},t.attr),sm(t.child)))}function be(e){return t=>E.createElement(uA,Ms({attr:$s({},e.attr)},t),sm(e.child))}function uA(e){var t=n=>{var{attr:r,size:i,title:o}=e,s=oA(e,iA),a=i||n.size||"1em",l;return n.className&&(l=n.className),e.className&&(l=(l?l+" ":"")+e.className),E.createElement("svg",Ms({stroke:"currentColor",fill:"currentColor",strokeWidth:"0"},n.attr,r,s,{className:l,style:$s($s({color:e.color||n.color},n.style),e.style),height:a,width:a,xmlns:"http://www.w3.org/2000/svg"}),o&&E.createElement("title",null,o),e.children)};return im!==void 0?E.createElement(im.Consumer,null,n=>t(n)):t(rm)}function dA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M11 10v4h4"},child:[]},{tag:"path",attr:{d:"m11 14 1.535-1.605a5 5 0 0 1 8 1.5"},child:[]},{tag:"path",attr:{d:"M16 2v4"},child:[]},{tag:"path",attr:{d:"m21 18-1.535 1.605a5 5 0 0 1-8-1.5"},child:[]},{tag:"path",attr:{d:"M21 22v-4h-4"},child:[]},{tag:"path",attr:{d:"M21 8.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h4.3"},child:[]},{tag:"path",attr:{d:"M3 10h4"},child:[]},{tag:"path",attr:{d:"M8 2v4"},child:[]}]})(e)}function hA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M20 6 9 17l-5-5"},child:[]}]})(e)}function am(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M10.1 2.182a10 10 0 0 1 3.8 0"},child:[]},{tag:"path",attr:{d:"M13.9 21.818a10 10 0 0 1-3.8 0"},child:[]},{tag:"path",attr:{d:"M17.609 3.721a10 10 0 0 1 2.69 2.7"},child:[]},{tag:"path",attr:{d:"M2.182 13.9a10 10 0 0 1 0-3.8"},child:[]},{tag:"path",attr:{d:"M20.279 17.609a10 10 0 0 1-2.7 2.69"},child:[]},{tag:"path",attr:{d:"M21.818 10.1a10 10 0 0 1 0 3.8"},child:[]},{tag:"path",attr:{d:"M3.721 6.391a10 10 0 0 1 2.7-2.69"},child:[]},{tag:"path",attr:{d:"M6.391 20.279a10 10 0 0 1-2.69-2.7"},child:[]}]})(e)}function fA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M12 2a10 10 0 0 1 7.38 16.75"},child:[]},{tag:"path",attr:{d:"m16 12-4-4-4 4"},child:[]},{tag:"path",attr:{d:"M12 16V8"},child:[]},{tag:"path",attr:{d:"M2.5 8.875a10 10 0 0 0-.5 3"},child:[]},{tag:"path",attr:{d:"M2.83 16a10 10 0 0 0 2.43 3.4"},child:[]},{tag:"path",attr:{d:"M4.636 5.235a10 10 0 0 1 .891-.857"},child:[]},{tag:"path",attr:{d:"M8.644 21.42a10 10 0 0 0 7.631-.38"},child:[]}]})(e)}function gA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"m15 14 5-5-5-5"},child:[]},{tag:"path",attr:{d:"M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13"},child:[]}]})(e)}function pA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M18 6 6 18"},child:[]},{tag:"path",attr:{d:"m6 6 12 12"},child:[]}]})(e)}const mA=E.forwardRef((e,t)=>x.jsx(fs,{"aria-label":"Close",ref:t,variant:"ghost",...e,children:e.children??x.jsx(pA,{})})),vA=E.forwardRef((e,t)=>{const{children:n,closable:r,endElement:i,icon:o,onClose:s,startElement:a,title:l,...c}=e;return x.jsxs(UP,{ref:t,...c,alignItems:"center",children:[a??x.jsx(XP,{children:o}),n?x.jsxs(qP,{children:[x.jsx(fg,{children:l}),x.jsx(GP,{children:n})]}):x.jsx(fg,{flex:"1",children:l}),i,r?x.jsx(mA,{alignSelf:"flex-start",insetEnd:"-2",onClick:s,pos:"relative",size:"sm",top:"-2"}):void 0]})});/*! * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -70,7 +70,7 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */const mA=zE({pauseOnPageIdle:!0,placement:"bottom-end"}),sm=({error:e})=>{var i;const t=e;if(!t)return;const n=(i=t.body)==null?void 0:i.detail;let r;return n!==void 0&&(typeof n=="string"?r=n:Array.isArray(n)?r=n.map(o=>`${o.loc.join(".")} ${o.msg}`):r=Object.keys(n).map(o=>`${o}: ${n[o]}`)),y.jsx(pA,{status:"error",children:y.jsxs(fR,{align:"start",flexDirection:"column",gap:2,mt:-1,children:[t.status," ",t.message,r===t.message?void 0:y.jsx(Wx,{whiteSpace:"preserve",wordBreak:"break-all",children:r})]})})};function am(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"polyline",attr:{points:"22 12 18 12 15 21 9 3 6 12 2 12"},child:[]}]})(e)}function vA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"line",attr:{x1:"7",y1:"7",x2:"17",y2:"17"},child:[]},{tag:"polyline",attr:{points:"17 7 17 17 7 17"},child:[]}]})(e)}function bA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"rect",attr:{x:"3",y:"4",width:"18",height:"18",rx:"2",ry:"2"},child:[]},{tag:"line",attr:{x1:"16",y1:"2",x2:"16",y2:"6"},child:[]},{tag:"line",attr:{x1:"8",y1:"2",x2:"8",y2:"6"},child:[]},{tag:"line",attr:{x1:"3",y1:"10",x2:"21",y2:"10"},child:[]}]})(e)}function yA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"polyline",attr:{points:"17 1 21 5 17 9"},child:[]},{tag:"path",attr:{d:"M3 11V9a4 4 0 0 1 4-4h14"},child:[]},{tag:"polyline",attr:{points:"7 23 3 19 7 15"},child:[]},{tag:"path",attr:{d:"M21 13v2a4 4 0 0 1-4 4H3"},child:[]}]})(e)}function xA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"polygon",attr:{points:"5 4 15 12 5 20 5 4"},child:[]},{tag:"line",attr:{x1:"19",y1:"5",x2:"19",y2:"19"},child:[]}]})(e)}function CA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"circle",attr:{cx:"12",cy:"12",r:"10"},child:[]},{tag:"line",attr:{x1:"4.93",y1:"4.93",x2:"19.07",y2:"19.07"},child:[]}]})(e)}function lm(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"circle",attr:{cx:"12",cy:"12",r:"7"},child:[]},{tag:"polyline",attr:{points:"12 9 12 12 13.5 13.5"},child:[]},{tag:"path",attr:{d:"M16.51 17.35l-.35 3.83a2 2 0 0 1-2 1.82H9.83a2 2 0 0 1-2-1.82l-.35-3.83m.01-10.7l.35-3.83A2 2 0 0 1 9.83 1h4.35a2 2 0 0 1 2 1.82l.35 3.83"},child:[]}]})(e)}function SA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"line",attr:{x1:"18",y1:"6",x2:"6",y2:"18"},child:[]},{tag:"line",attr:{x1:"6",y1:"6",x2:"18",y2:"18"},child:[]}]})(e)}function wA(e){return be({attr:{viewBox:"0 0 256 256",fill:"currentColor"},child:[{tag:"path",attr:{d:"M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm104,56H40a8,8,0,0,0,0,16h96a8,8,0,0,0,0-16Zm0,64H40a8,8,0,0,0,0,16h96a8,8,0,0,0,0-16Zm112-24a8,8,0,0,1-3.76,6.78l-64,40A8,8,0,0,1,168,200V120a8,8,0,0,1,12.24-6.78l64,40A8,8,0,0,1,248,160Zm-23.09,0L184,134.43v51.14Z"},child:[]}]})(e)}const EA=({state:e,...t})=>{switch(e){case"deferred":return y.jsx(lm,{...t});case"failed":return y.jsx(SA,{...t});case"queued":return y.jsx(wA,{...t});case"removed":return y.jsx(CA,{...t});case"restarting":return y.jsx(yA,{...t});case"running":return y.jsx(am,{...t});case"scheduled":return y.jsx(bA,{...t});case"skipped":return y.jsx(xA,{...t});case"success":return y.jsx(uA,{...t});case"up_for_reschedule":return y.jsx(cA,{...t});case"up_for_retry":return y.jsx(hA,{...t});case"upstream_failed":return y.jsx(dA,{...t});default:return y.jsx(om,{...t})}},kA=O.forwardRef(({children:e,state:t,...n},r)=>y.jsxs(gg,{borderRadius:"full",colorPalette:t===null?"none":t,fontSize:"sm",px:e===void 0?1:2,py:1,ref:r,variant:"solid",...n,children:[t===void 0?void 0:y.jsx(EA,{state:t}),e]}));/*! + */const bA=BE({pauseOnPageIdle:!0,placement:"bottom-end"}),lm=({error:e})=>{var i;const t=e;if(!t)return;const n=(i=t.body)==null?void 0:i.detail;let r;return n!==void 0&&(typeof n=="string"?r=n:Array.isArray(n)?r=n.map(o=>`${o.loc.join(".")} ${o.msg}`):r=Object.keys(n).map(o=>`${o}: ${n[o]}`)),x.jsx(vA,{status:"error",children:x.jsxs(mR,{align:"start",flexDirection:"column",gap:2,mt:-1,children:[t.status," ",t.message,r===t.message?void 0:x.jsx(Gx,{whiteSpace:"preserve",wordBreak:"break-all",children:r})]})})};function cm(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"polyline",attr:{points:"22 12 18 12 15 21 9 3 6 12 2 12"},child:[]}]})(e)}function yA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"line",attr:{x1:"7",y1:"7",x2:"17",y2:"17"},child:[]},{tag:"polyline",attr:{points:"17 7 17 17 7 17"},child:[]}]})(e)}function xA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"rect",attr:{x:"3",y:"4",width:"18",height:"18",rx:"2",ry:"2"},child:[]},{tag:"line",attr:{x1:"16",y1:"2",x2:"16",y2:"6"},child:[]},{tag:"line",attr:{x1:"8",y1:"2",x2:"8",y2:"6"},child:[]},{tag:"line",attr:{x1:"3",y1:"10",x2:"21",y2:"10"},child:[]}]})(e)}function CA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"polyline",attr:{points:"17 1 21 5 17 9"},child:[]},{tag:"path",attr:{d:"M3 11V9a4 4 0 0 1 4-4h14"},child:[]},{tag:"polyline",attr:{points:"7 23 3 19 7 15"},child:[]},{tag:"path",attr:{d:"M21 13v2a4 4 0 0 1-4 4H3"},child:[]}]})(e)}function SA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"polygon",attr:{points:"5 4 15 12 5 20 5 4"},child:[]},{tag:"line",attr:{x1:"19",y1:"5",x2:"19",y2:"19"},child:[]}]})(e)}function wA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"circle",attr:{cx:"12",cy:"12",r:"10"},child:[]},{tag:"line",attr:{x1:"4.93",y1:"4.93",x2:"19.07",y2:"19.07"},child:[]}]})(e)}function um(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"circle",attr:{cx:"12",cy:"12",r:"7"},child:[]},{tag:"polyline",attr:{points:"12 9 12 12 13.5 13.5"},child:[]},{tag:"path",attr:{d:"M16.51 17.35l-.35 3.83a2 2 0 0 1-2 1.82H9.83a2 2 0 0 1-2-1.82l-.35-3.83m.01-10.7l.35-3.83A2 2 0 0 1 9.83 1h4.35a2 2 0 0 1 2 1.82l.35 3.83"},child:[]}]})(e)}function EA(e){return be({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"line",attr:{x1:"18",y1:"6",x2:"6",y2:"18"},child:[]},{tag:"line",attr:{x1:"6",y1:"6",x2:"18",y2:"18"},child:[]}]})(e)}function kA(e){return be({attr:{viewBox:"0 0 256 256",fill:"currentColor"},child:[{tag:"path",attr:{d:"M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm104,56H40a8,8,0,0,0,0,16h96a8,8,0,0,0,0-16Zm0,64H40a8,8,0,0,0,0,16h96a8,8,0,0,0,0-16Zm112-24a8,8,0,0,1-3.76,6.78l-64,40A8,8,0,0,1,168,200V120a8,8,0,0,1,12.24-6.78l64,40A8,8,0,0,1,248,160Zm-23.09,0L184,134.43v51.14Z"},child:[]}]})(e)}const OA=({state:e,...t})=>{switch(e){case"deferred":return x.jsx(um,{...t});case"failed":return x.jsx(EA,{...t});case"queued":return x.jsx(kA,{...t});case"removed":return x.jsx(wA,{...t});case"restarting":return x.jsx(CA,{...t});case"running":return x.jsx(cm,{...t});case"scheduled":return x.jsx(xA,{...t});case"skipped":return x.jsx(SA,{...t});case"success":return x.jsx(hA,{...t});case"up_for_reschedule":return x.jsx(dA,{...t});case"up_for_retry":return x.jsx(gA,{...t});case"upstream_failed":return x.jsx(fA,{...t});default:return x.jsx(am,{...t})}},IA=O.forwardRef(({children:e,state:t,...n},r)=>x.jsxs(gg,{borderRadius:"full",colorPalette:t===null?"none":t,fontSize:"sm",px:e===void 0?1:2,py:1,ref:r,variant:"solid",...n,children:[t===void 0?void 0:x.jsx(OA,{state:t}),e]}));/*! * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -87,7 +87,7 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */const cm=5e3;/*! + */const dm=5e3;/*! * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -104,7 +104,7 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */const OA=e=>{const[t,n]=E.useState(0);return E.useEffect(()=>{if(!e.current)return;const r=new ResizeObserver(i=>{for(const o of i)n(o.contentRect.width)});return r.observe(e.current),()=>{r.disconnect()}},[e]),t};/*! + */const PA=e=>{const[t,n]=E.useState(0);return E.useEffect(()=>{if(!e.current)return;const r=new ResizeObserver(i=>{for(const o of i)n(o.contentRect.width)});return r.observe(e.current),()=>{r.disconnect()}},[e]),t};/*! * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -121,7 +121,7 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */const um="token",IA=()=>{const e=document.cookie.split(";");for(const t of e){const[n,r]=t.split("=");if((n==null?void 0:n.trim())==="_token"&&r!==void 0)return localStorage.setItem(um,r),document.cookie="_token=; expires=Sat, 01 Jan 2000 00:00:00 UTC; path=/;",r}},PA=e=>{const t=localStorage.getItem(um)??IA();return t!==void 0&&(e.headers.Authorization=`Bearer ${t}`),e},RA=()=>{const{data:e,error:t}=ZN(void 0,{enabled:!0,refetchInterval:cm});return e?y.jsx(zt,{p:2,children:y.jsxs(bg,{size:"sm",interactive:!0,stickyHeader:!0,striped:!0,children:[y.jsx(yg,{children:y.jsxs(hs,{children:[y.jsx(Te,{children:"Dag ID"}),y.jsx(Te,{children:"Run ID"}),y.jsx(Te,{children:"Task ID"}),y.jsx(Te,{children:"Map Index"}),y.jsx(Te,{children:"Try Number"}),y.jsx(Te,{children:"State"}),y.jsx(Te,{children:"Queue"}),y.jsx(Te,{children:"Queued DTTM"}),y.jsx(Te,{children:"Edge Worker"}),y.jsx(Te,{children:"Last Update"})]})}),y.jsx(xg,{children:e.jobs.map(n=>y.jsxs(hs,{children:[y.jsx(Ne,{children:n.dag_id}),y.jsx(Ne,{children:n.run_id}),y.jsx(Ne,{children:n.task_id}),y.jsx(Ne,{children:n.map_index}),y.jsx(Ne,{children:n.try_number}),y.jsx(Ne,{children:y.jsx(kA,{state:n.state,children:n.state})}),y.jsx(Ne,{children:n.queue}),y.jsx(Ne,{children:n.queued_dttm}),y.jsx(Ne,{children:n.edge_worker}),y.jsx(Ne,{children:n.last_update})]},`${n.dag_id}.${n.run_id}.${n.task_id}.${n.map_index}.${n.try_number}`))})]})}):t?y.jsxs(zt,{p:2,children:[y.jsx("p",{children:"Unable to load data:"}),y.jsx(sm,{error:t})]}):y.jsx(zt,{p:2,children:"Loading..."})};function dm(e){return be({attr:{fill:"none",viewBox:"0 0 24 24",strokeWidth:"1.5",stroke:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{strokeLinecap:"round",strokeLinejoin:"round",d:"M11.42 15.17 17.25 21A2.652 2.652 0 0 0 21 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 1 1-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 0 0 4.486-6.336l-3.276 3.277a3.004 3.004 0 0 1-2.25-2.25l3.276-3.276a4.5 4.5 0 0 0-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L2.25 3.75l1.5-1.5L7.5 4.5v1.409l4.26 4.26m-1.745 1.437 1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008Z"},child:[]}]})(e)}function TA(e){return be({attr:{fill:"none",viewBox:"0 0 24 24",strokeWidth:"1.5",stroke:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{strokeLinecap:"round",strokeLinejoin:"round",d:"M21.75 6.75a4.5 4.5 0 0 1-4.884 4.484c-1.076-.091-2.264.071-2.95.904l-7.152 8.684a2.548 2.548 0 1 1-3.586-3.586l8.684-7.152c.833-.686.995-1.874.904-2.95a4.5 4.5 0 0 1 6.336-4.486l-3.276 3.276a3.004 3.004 0 0 0 2.25 2.25l3.276-3.276c.256.565.398 1.192.398 1.852Z"},child:[]},{tag:"path",attr:{strokeLinecap:"round",strokeLinejoin:"round",d:"M4.867 19.125h.008v.008h-.008v-.008Z"},child:[]}]})(e)}const NA=({onEnterMaintenance:e,workerName:t})=>{const{onClose:n,onOpen:r,open:i}=Hx(),[o,s]=E.useState(""),a=eA({onError:c=>{e({description:`Unable to set worker ${t} to maintenance mode: ${c}`,title:"Setting Maintenance Mode failed",type:"error"})},onSuccess:()=>{e({description:`Worker ${t} was requested to be in maintenance mode.`,title:"Maintenance Mode activated",type:"success"})}}),l=()=>{a.mutate({requestBody:{maintenance_comment:o},workerName:t})};return y.jsxs(y.Fragment,{children:[y.jsx(ds,{size:"sm",variant:"ghost","aria-label":"Enter Maintenance",title:"Enter Maintenance",onClick:r,children:y.jsx(dm,{})}),y.jsx(rR,{onOpenChange:n,open:i,size:"md",children:y.jsxs(wE,{children:[y.jsx(cR,{}),y.jsx(iR,{children:y.jsxs(oR,{children:[y.jsx(hR,{children:y.jsxs(sR,{children:["Set maintenance for worker ",t]})}),y.jsx(uR,{children:y.jsx(yR,{placeholder:"Enter maintenance comment (required)",value:o,onChange:c=>s(c.target.value),required:!0,maxLength:1024,size:"sm"})}),y.jsxs(dR,{children:[y.jsx(lR,{asChild:!0,children:y.jsx(Vl,{variant:"outline",children:"Cancel"})}),y.jsx(Vl,{onClick:l,disabled:!o.trim(),children:"Confirm Maintenance"})]}),y.jsx(aR,{asChild:!0,children:y.jsx(eR,{size:"sm"})})]})})]})})]})};function AA(e){return be({attr:{viewBox:"0 0 512 512"},child:[{tag:"path",attr:{d:"M215.469 332.802l29.863 29.864L352 256 245.332 149.333l-29.863 29.865 55.469 55.469H64v42.666h205.864l-54.395 55.469zM405.334 64H106.666C83.198 64 64 83.198 64 106.666V192h42.666v-85.333h298.668v298.668H106.666V320H64v85.334C64 428.802 83.198 448 106.666 448h298.668C428.802 448 448 428.802 448 405.334V106.666C448 83.198 428.802 64 405.334 64z"},child:[]}]})(e)}const _A=({onExitMaintenance:e,workerName:t})=>{const n=tA({onError:i=>{e({description:`Unable to exit ${t} from maintenance mode: ${i}`,title:"Exit Maintenance Mode failed",type:"error"})},onSuccess:()=>{e({description:`Worker ${t} was requested to exit maintenance mode.`,title:"Maintenance Mode deactivated",type:"success"})}}),r=()=>{n.mutate({workerName:t})};return y.jsx(ds,{size:"sm",variant:"ghost",onClick:()=>r(),"aria-label":"Exit Maintenance",title:"Exit Maintenance",children:y.jsx(AA,{})})},VA=({onOperations:e,worker:t})=>{const n=t.worker_name,r=t.state,i=o=>{mA.create(o),e()};return r==="idle"||r==="running"?y.jsx(Fl,{justifyContent:"end",children:y.jsx(NA,{onEnterMaintenance:i,workerName:n})}):r==="maintenance pending"||r==="maintenance mode"||r==="maintenance request"||r==="offline maintenance"?y.jsxs(gR,{gap:2,align:"stretch",children:[y.jsx(zt,{fontSize:"sm",whiteSpace:"pre-wrap",children:t.maintenance_comments||"No comment"}),y.jsx(Fl,{justifyContent:"end",children:y.jsx(_A,{onExitMaintenance:i,workerName:n})})]}):null};function FA(e){return be({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{d:"m22 3.41-.12-1.26-1.2.4a13.84 13.84 0 0 1-6.41.64 11.87 11.87 0 0 0-6.68.9A7.23 7.23 0 0 0 3.3 9.5a9 9 0 0 0 .39 4.58 16.6 16.6 0 0 1 1.18-2.2 9.85 9.85 0 0 1 4.07-3.43 11.16 11.16 0 0 1 5.06-1A12.08 12.08 0 0 0 9.34 9.2a9.48 9.48 0 0 0-1.86 1.53 11.38 11.38 0 0 0-1.39 1.91 16.39 16.39 0 0 0-1.57 4.54A26.42 26.42 0 0 0 4 22h2a30.69 30.69 0 0 1 .59-4.32 9.25 9.25 0 0 0 4.52 1.11 11 11 0 0 0 4.28-.87C23 14.67 22 3.86 22 3.41z"},child:[]}]})(e)}function LA(e){return be({attr:{viewBox:"0 0 512 512"},child:[{tag:"path",attr:{fill:"none",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"32",d:"M93.72 183.25C49.49 198.05 16 233.1 16 288c0 66 54 112 120 112h184.37m147.45-22.26C485.24 363.3 496 341.61 496 312c0-59.82-53-85.76-96-88-8.89-89.54-71-144-144-144-26.16 0-48.79 6.93-67.6 18.14"},child:[]},{tag:"path",attr:{fill:"none",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"32",d:"M448 448 64 64"},child:[]}]})(e)}function DA(e){return be({attr:{viewBox:"0 0 24 24",fill:"currentColor"},child:[{tag:"path",attr:{d:"M12.0001 18C12.7144 18 13.3704 18.2497 13.8856 18.6665L12.0001 21L10.1145 18.6665C10.6297 18.2497 11.2857 18 12.0001 18ZM2.80766 1.39343L20.4853 19.0711L19.0711 20.4853L13.8913 15.3042C13.2967 15.1069 12.6609 15 12.0001 15C10.5719 15 9.26024 15.499 8.22998 16.3322L6.97363 14.7759C8.24961 13.7442 9.84925 13.0969 11.5964 13.01L9.00025 10.414C7.55273 10.8234 6.22651 11.5217 5.0878 12.4426L3.83099 10.8868C4.89946 10.0226 6.10763 9.32438 7.41633 8.83118L5.13168 6.5451C3.98878 7.08913 2.92058 7.76472 1.94666 8.55228L0.689453 6.99674C1.60358 6.25747 2.59156 5.60589 3.64058 5.05479L1.39345 2.80765L2.80766 1.39343ZM14.5004 10.2854L12.2165 8.00243L12 8C15.0947 8 17.9369 9.08141 20.1693 10.8869L18.9123 12.4426C17.6438 11.4167 16.1427 10.6672 14.5004 10.2854ZM12.0001 3.00003C16.2849 3.00003 20.22 4.49719 23.3109 6.99691L22.0534 8.55228C19.3061 6.33062 15.8085 5.00003 12.0001 5.00003C11.122 5.00003 10.2604 5.07077 9.42075 5.20685L7.72455 3.51088C9.09498 3.17702 10.5268 3.00003 12.0001 3.00003Z"},child:[]}]})(e)}const zA=({state:e,...t})=>{switch(e){case"starting":return y.jsx(lm,{...t});case"running":return y.jsx(am,{...t});case"idle":return y.jsx(FA,{...t});case"shutdown request":case"terminating":return y.jsx(vA,{...t});case"offline":return y.jsx(LA,{...t});case"unknown":return y.jsx(DA,{...t});case"maintenance request":case"maintenance pending":case"maintenance exit":return y.jsx(TA,{...t});case"maintenance mode":case"offline maintenance":return y.jsx(dm,{...t});default:return y.jsx(om,{...t})}},MA=e=>{switch(e){case"starting":case"maintenance request":case"maintenance exit":return"yellow";case"running":return"green";case"idle":return"teal";case"shutdown request":case"terminating":return"purple";case"offline":case"offline maintenance":return"black";case"unknown":return"red";case"maintenance mode":case"maintenance pending":return"orange";default:return"gray"}},$A=O.forwardRef(({children:e,state:t,...n},r)=>y.jsxs(gg,{borderRadius:"full",colorPalette:MA(t),fontSize:"sm",px:e===void 0?1:2,py:1,ref:r,variant:"solid",...n,children:[t===void 0?void 0:y.jsx(zA,{state:t}),e]})),BA=()=>{const{data:e,error:t,refetch:n}=JN(void 0,{enabled:!0,refetchInterval:cm});return e?y.jsx(zt,{p:2,children:y.jsxs(bg,{size:"sm",interactive:!0,stickyHeader:!0,striped:!0,children:[y.jsx(yg,{children:y.jsxs(hs,{children:[y.jsx(Te,{children:"Worker Name"}),y.jsx(Te,{children:"State"}),y.jsx(Te,{children:"Queues"}),y.jsx(Te,{children:"First Online"}),y.jsx(Te,{children:"Last Heartbeat"}),y.jsx(Te,{children:"Active Jobs"}),y.jsx(Te,{children:"System Information"}),y.jsx(Te,{children:"Operations"})]})}),y.jsx(xg,{children:e.workers.map(r=>y.jsxs(hs,{children:[y.jsx(Ne,{children:r.worker_name}),y.jsx(Ne,{children:y.jsx($A,{state:r.state,children:r.state})}),y.jsx(Ne,{children:r.queues?y.jsx("ul",{children:r.queues.map(i=>y.jsx("li",{children:i},i))}):"(default)"}),y.jsx(Ne,{children:r.first_online}),y.jsx(Ne,{children:r.last_heartbeat}),y.jsx(Ne,{children:r.jobs_active}),y.jsx(Ne,{children:r.sysinfo?y.jsx("ul",{children:Object.entries(r.sysinfo).map(([i,o])=>y.jsxs("li",{children:[i,": ",o]},i))}):"N/A"}),y.jsx(Ne,{children:y.jsx(VA,{worker:r,onOperations:n})})]},r.worker_name))})]})}):t?y.jsxs(zt,{p:2,children:[y.jsx("p",{children:"Unable to load data:"}),y.jsx(sm,{error:t})]}):y.jsx(zt,{p:2,children:"Loading..."})},jA=({tabs:e})=>{const t=E.useRef(null),n=OA(t);return y.jsx(Fl,{alignItems:"center",borderBottomWidth:1,mb:2,ref:t,children:e.map(({icon:r,label:i,value:o})=>y.jsx(NN,{end:!0,title:i,to:{pathname:o},children:({isActive:s})=>y.jsx(pg,{borderBottomColor:"border.info",borderBottomWidth:s?3:0,color:s?"fg":"fg.muted",fontWeight:"bold",height:"40px",mb:"-2px",pb:s?0:"3px",px:4,transition:"all 0.2s ease",children:n>600||!r?i:r})},o))})},WA=()=>{const e=[{label:"Edge Worker",value:"plugin/edge_worker"},{label:"Edge Jobs",value:"plugin/edge_jobs"}];return y.jsx(zt,{p:2,children:y.jsxs(IN,{children:[y.jsx(jA,{tabs:e}),y.jsxs(xN,{children:[y.jsx(lc,{path:"plugin/edge_worker",element:y.jsx(BA,{})}),y.jsx(lc,{path:"plugin/edge_jobs",element:y.jsx(RA,{})})]})]})})};/*! + */const hm="token",RA=()=>{const e=document.cookie.split(";");for(const t of e){const[n,r]=t.split("=");if((n==null?void 0:n.trim())==="_token"&&r!==void 0)return localStorage.setItem(hm,r),document.cookie="_token=; expires=Sat, 01 Jan 2000 00:00:00 UTC; path=/;",r}},TA=e=>{const t=localStorage.getItem(hm)??RA();return t!==void 0&&(e.headers.Authorization=`Bearer ${t}`),e},NA=()=>{const{data:e,error:t}=tA(void 0,{enabled:!0,refetchInterval:dm});return e?x.jsx($t,{p:2,children:x.jsxs(bg,{size:"sm",interactive:!0,stickyHeader:!0,striped:!0,children:[x.jsx(yg,{children:x.jsxs(gs,{children:[x.jsx(Te,{children:"Dag ID"}),x.jsx(Te,{children:"Run ID"}),x.jsx(Te,{children:"Task ID"}),x.jsx(Te,{children:"Map Index"}),x.jsx(Te,{children:"Try Number"}),x.jsx(Te,{children:"State"}),x.jsx(Te,{children:"Queue"}),x.jsx(Te,{children:"Queued DTTM"}),x.jsx(Te,{children:"Edge Worker"}),x.jsx(Te,{children:"Last Update"})]})}),x.jsx(xg,{children:e.jobs.map(n=>x.jsxs(gs,{children:[x.jsx(Ne,{children:n.dag_id}),x.jsx(Ne,{children:n.run_id}),x.jsx(Ne,{children:n.task_id}),x.jsx(Ne,{children:n.map_index}),x.jsx(Ne,{children:n.try_number}),x.jsx(Ne,{children:x.jsx(IA,{state:n.state,children:n.state})}),x.jsx(Ne,{children:n.queue}),x.jsx(Ne,{children:n.queued_dttm}),x.jsx(Ne,{children:n.edge_worker}),x.jsx(Ne,{children:n.last_update})]},`${n.dag_id}.${n.run_id}.${n.task_id}.${n.map_index}.${n.try_number}`))})]})}):t?x.jsxs($t,{p:2,children:[x.jsx("p",{children:"Unable to load data:"}),x.jsx(lm,{error:t})]}):x.jsx($t,{p:2,children:"Loading..."})};function fm(e){return be({attr:{fill:"none",viewBox:"0 0 24 24",strokeWidth:"1.5",stroke:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{strokeLinecap:"round",strokeLinejoin:"round",d:"M11.42 15.17 17.25 21A2.652 2.652 0 0 0 21 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 1 1-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 0 0 4.486-6.336l-3.276 3.277a3.004 3.004 0 0 1-2.25-2.25l3.276-3.276a4.5 4.5 0 0 0-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L2.25 3.75l1.5-1.5L7.5 4.5v1.409l4.26 4.26m-1.745 1.437 1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008Z"},child:[]}]})(e)}function AA(e){return be({attr:{fill:"none",viewBox:"0 0 24 24",strokeWidth:"1.5",stroke:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{strokeLinecap:"round",strokeLinejoin:"round",d:"M21.75 6.75a4.5 4.5 0 0 1-4.884 4.484c-1.076-.091-2.264.071-2.95.904l-7.152 8.684a2.548 2.548 0 1 1-3.586-3.586l8.684-7.152c.833-.686.995-1.874.904-2.95a4.5 4.5 0 0 1 6.336-4.486l-3.276 3.276a3.004 3.004 0 0 0 2.25 2.25l3.276-3.276c.256.565.398 1.192.398 1.852Z"},child:[]},{tag:"path",attr:{strokeLinecap:"round",strokeLinejoin:"round",d:"M4.867 19.125h.008v.008h-.008v-.008Z"},child:[]}]})(e)}const _A=({onEnterMaintenance:e,workerName:t})=>{const{onClose:n,onOpen:r,open:i}=qx(),[o,s]=E.useState(""),a=nA({onError:c=>{e({description:`Unable to set worker ${t} to maintenance mode: ${c}`,title:"Setting Maintenance Mode failed",type:"error"})},onSuccess:()=>{e({description:`Worker ${t} was requested to be in maintenance mode.`,title:"Maintenance Mode activated",type:"success"})}}),l=()=>{a.mutate({requestBody:{maintenance_comment:o},workerName:t})};return x.jsxs(x.Fragment,{children:[x.jsx(fs,{size:"sm",variant:"ghost","aria-label":"Enter Maintenance",title:"Enter Maintenance",onClick:r,children:x.jsx(fm,{})}),x.jsx(sR,{onOpenChange:n,open:i,size:"md",children:x.jsxs(OE,{children:[x.jsx(hR,{}),x.jsx(aR,{children:x.jsxs(lR,{children:[x.jsx(pR,{children:x.jsxs(cR,{children:["Set maintenance for worker ",t]})}),x.jsx(fR,{children:x.jsx(SR,{placeholder:"Enter maintenance comment (required)",value:o,onChange:c=>s(c.target.value),required:!0,maxLength:1024,size:"sm"})}),x.jsxs(gR,{children:[x.jsx(dR,{asChild:!0,children:x.jsx(Fl,{variant:"outline",children:"Cancel"})}),x.jsx(Fl,{onClick:l,disabled:!o.trim(),children:"Confirm Maintenance"})]}),x.jsx(uR,{asChild:!0,children:x.jsx(rR,{size:"sm"})})]})})]})})]})};function VA(e){return be({attr:{viewBox:"0 0 512 512"},child:[{tag:"path",attr:{d:"M215.469 332.802l29.863 29.864L352 256 245.332 149.333l-29.863 29.865 55.469 55.469H64v42.666h205.864l-54.395 55.469zM405.334 64H106.666C83.198 64 64 83.198 64 106.666V192h42.666v-85.333h298.668v298.668H106.666V320H64v85.334C64 428.802 83.198 448 106.666 448h298.668C428.802 448 448 428.802 448 405.334V106.666C448 83.198 428.802 64 405.334 64z"},child:[]}]})(e)}const FA=({onExitMaintenance:e,workerName:t})=>{const n=rA({onError:i=>{e({description:`Unable to exit ${t} from maintenance mode: ${i}`,title:"Exit Maintenance Mode failed",type:"error"})},onSuccess:()=>{e({description:`Worker ${t} was requested to exit maintenance mode.`,title:"Maintenance Mode deactivated",type:"success"})}}),r=()=>{n.mutate({workerName:t})};return x.jsx(fs,{size:"sm",variant:"ghost",onClick:()=>r(),"aria-label":"Exit Maintenance",title:"Exit Maintenance",children:x.jsx(VA,{})})},LA=({onOperations:e,worker:t})=>{const n=t.worker_name,r=t.state,i=o=>{bA.create(o),e()};return r==="idle"||r==="running"?x.jsx(Ll,{justifyContent:"end",children:x.jsx(_A,{onEnterMaintenance:i,workerName:n})}):r==="maintenance pending"||r==="maintenance mode"||r==="maintenance request"||r==="offline maintenance"?x.jsxs(vR,{gap:2,align:"stretch",children:[x.jsx($t,{fontSize:"sm",whiteSpace:"pre-wrap",children:t.maintenance_comments||"No comment"}),x.jsx(Ll,{justifyContent:"end",children:x.jsx(FA,{onExitMaintenance:i,workerName:n})})]}):null};function DA(e){return be({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{d:"m22 3.41-.12-1.26-1.2.4a13.84 13.84 0 0 1-6.41.64 11.87 11.87 0 0 0-6.68.9A7.23 7.23 0 0 0 3.3 9.5a9 9 0 0 0 .39 4.58 16.6 16.6 0 0 1 1.18-2.2 9.85 9.85 0 0 1 4.07-3.43 11.16 11.16 0 0 1 5.06-1A12.08 12.08 0 0 0 9.34 9.2a9.48 9.48 0 0 0-1.86 1.53 11.38 11.38 0 0 0-1.39 1.91 16.39 16.39 0 0 0-1.57 4.54A26.42 26.42 0 0 0 4 22h2a30.69 30.69 0 0 1 .59-4.32 9.25 9.25 0 0 0 4.52 1.11 11 11 0 0 0 4.28-.87C23 14.67 22 3.86 22 3.41z"},child:[]}]})(e)}function zA(e){return be({attr:{viewBox:"0 0 512 512"},child:[{tag:"path",attr:{fill:"none",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"32",d:"M93.72 183.25C49.49 198.05 16 233.1 16 288c0 66 54 112 120 112h184.37m147.45-22.26C485.24 363.3 496 341.61 496 312c0-59.82-53-85.76-96-88-8.89-89.54-71-144-144-144-26.16 0-48.79 6.93-67.6 18.14"},child:[]},{tag:"path",attr:{fill:"none",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"32",d:"M448 448 64 64"},child:[]}]})(e)}function MA(e){return be({attr:{viewBox:"0 0 24 24",fill:"currentColor"},child:[{tag:"path",attr:{d:"M12.0001 18C12.7144 18 13.3704 18.2497 13.8856 18.6665L12.0001 21L10.1145 18.6665C10.6297 18.2497 11.2857 18 12.0001 18ZM2.80766 1.39343L20.4853 19.0711L19.0711 20.4853L13.8913 15.3042C13.2967 15.1069 12.6609 15 12.0001 15C10.5719 15 9.26024 15.499 8.22998 16.3322L6.97363 14.7759C8.24961 13.7442 9.84925 13.0969 11.5964 13.01L9.00025 10.414C7.55273 10.8234 6.22651 11.5217 5.0878 12.4426L3.83099 10.8868C4.89946 10.0226 6.10763 9.32438 7.41633 8.83118L5.13168 6.5451C3.98878 7.08913 2.92058 7.76472 1.94666 8.55228L0.689453 6.99674C1.60358 6.25747 2.59156 5.60589 3.64058 5.05479L1.39345 2.80765L2.80766 1.39343ZM14.5004 10.2854L12.2165 8.00243L12 8C15.0947 8 17.9369 9.08141 20.1693 10.8869L18.9123 12.4426C17.6438 11.4167 16.1427 10.6672 14.5004 10.2854ZM12.0001 3.00003C16.2849 3.00003 20.22 4.49719 23.3109 6.99691L22.0534 8.55228C19.3061 6.33062 15.8085 5.00003 12.0001 5.00003C11.122 5.00003 10.2604 5.07077 9.42075 5.20685L7.72455 3.51088C9.09498 3.17702 10.5268 3.00003 12.0001 3.00003Z"},child:[]}]})(e)}const $A=({state:e,...t})=>{switch(e){case"starting":return x.jsx(um,{...t});case"running":return x.jsx(cm,{...t});case"idle":return x.jsx(DA,{...t});case"shutdown request":case"terminating":return x.jsx(yA,{...t});case"offline":return x.jsx(zA,{...t});case"unknown":return x.jsx(MA,{...t});case"maintenance request":case"maintenance pending":case"maintenance exit":return x.jsx(AA,{...t});case"maintenance mode":case"offline maintenance":return x.jsx(fm,{...t});default:return x.jsx(am,{...t})}},BA=e=>{switch(e){case"starting":case"maintenance request":case"maintenance exit":return"yellow";case"running":return"green";case"idle":return"teal";case"shutdown request":case"terminating":return"purple";case"offline":case"offline maintenance":return"black";case"unknown":return"red";case"maintenance mode":case"maintenance pending":return"orange";default:return"gray"}},jA=O.forwardRef(({children:e,state:t,...n},r)=>x.jsxs(gg,{borderRadius:"full",colorPalette:BA(t),fontSize:"sm",px:e===void 0?1:2,py:1,ref:r,variant:"solid",...n,children:[t===void 0?void 0:x.jsx($A,{state:t}),e]})),WA=()=>{const{data:e,error:t,refetch:n}=eA(void 0,{enabled:!0,refetchInterval:dm});return e?x.jsx($t,{p:2,children:x.jsxs(bg,{size:"sm",interactive:!0,stickyHeader:!0,striped:!0,children:[x.jsx(yg,{children:x.jsxs(gs,{children:[x.jsx(Te,{children:"Worker Name"}),x.jsx(Te,{children:"State"}),x.jsx(Te,{children:"Queues"}),x.jsx(Te,{children:"First Online"}),x.jsx(Te,{children:"Last Heartbeat"}),x.jsx(Te,{children:"Active Jobs"}),x.jsx(Te,{children:"System Information"}),x.jsx(Te,{children:"Operations"})]})}),x.jsx(xg,{children:e.workers.map(r=>x.jsxs(gs,{children:[x.jsx(Ne,{children:r.worker_name}),x.jsx(Ne,{children:x.jsx(jA,{state:r.state,children:r.state})}),x.jsx(Ne,{children:r.queues?x.jsx("ul",{children:r.queues.map(i=>x.jsx("li",{children:i},i))}):"(default)"}),x.jsx(Ne,{children:r.first_online}),x.jsx(Ne,{children:r.last_heartbeat}),x.jsx(Ne,{children:r.jobs_active}),x.jsx(Ne,{children:r.sysinfo?x.jsx("ul",{children:Object.entries(r.sysinfo).map(([i,o])=>x.jsxs("li",{children:[i,": ",o]},i))}):"N/A"}),x.jsx(Ne,{children:x.jsx(LA,{worker:r,onOperations:n})})]},r.worker_name))})]})}):t?x.jsxs($t,{p:2,children:[x.jsx("p",{children:"Unable to load data:"}),x.jsx(lm,{error:t})]}):x.jsx($t,{p:2,children:"Loading..."})},HA=({tabs:e})=>{const t=E.useRef(null),n=PA(t);return x.jsx(Ll,{alignItems:"center",borderBottomWidth:1,mb:2,ref:t,children:e.map(({icon:r,label:i,value:o})=>x.jsx(_N,{end:!0,title:i,to:{pathname:o},children:({isActive:s})=>x.jsx(pg,{borderBottomColor:"border.info",borderBottomWidth:s?3:0,color:s?"fg":"fg.muted",fontWeight:"bold",height:"40px",mb:"-2px",pb:s?0:"3px",px:4,transition:"all 0.2s ease",children:n>600||!r?i:r})},o))})},UA=()=>{const e=[{label:"Edge Worker",value:"plugin/edge_worker"},{label:"Edge Jobs",value:"plugin/edge_jobs"}];return x.jsx($t,{p:2,children:x.jsxs(RN,{children:[x.jsx(HA,{tabs:e}),x.jsxs(SN,{children:[x.jsx(lc,{path:"plugin/edge_worker",element:x.jsx(WA,{})}),x.jsx(lc,{path:"plugin/edge_jobs",element:x.jsx(NA,{})})]})]})})};/*! * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -138,4 +138,4 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */const hn=(e,t="white")=>({solid:{value:`{colors.${e}.600}`},contrast:{value:{_light:"white",_dark:t}},fg:{value:{_light:`{colors.${e}.800}`,_dark:`{colors.${e}.200}`}},muted:{value:{_light:`{colors.${e}.200}`,_dark:`{colors.${e}.800}`}},subtle:{value:{_light:`{colors.${e}.100}`,_dark:`{colors.${e}.900}`}},emphasized:{value:{_light:`{colors.${e}.300}`,_dark:`{colors.${e}.700}`}},focusRing:{value:{_light:`{colors.${e}.800}`,_dark:`{colors.${e}.200}`}}}),HA=Cl({theme:{tokens:{colors:{success:{50:{value:"#E0FFE0"},100:{value:"#C2FFC2"},200:{value:"#80FF80"},300:{value:"#42FF42"},400:{value:"#00FF00"},500:{value:"#00C200"},600:{value:"#008000"},700:{value:"#006100"},800:{value:"#004200"},900:{value:"#001F00"},950:{value:"#000F00"}},failed:((Vv=(_v=(Av=dt.theme)==null?void 0:Av.tokens)==null?void 0:_v.colors)==null?void 0:Vv.red)??{},queued:{50:{value:"#F5F5F5"},100:{value:"#EBEBEB"},200:{value:"#D4D4D4"},300:{value:"#BFBFBF"},400:{value:"#ABABAB"},500:{value:"#969696"},600:{value:"#808080"},700:{value:"#616161"},800:{value:"#404040"},900:{value:"#212121"},950:{value:"#0F0F0F"}},skipped:((Dv=(Lv=(Fv=dt.theme)==null?void 0:Fv.tokens)==null?void 0:Lv.colors)==null?void 0:Dv.pink)??{},up_for_reschedule:(($v=(Mv=(zv=dt.theme)==null?void 0:zv.tokens)==null?void 0:Mv.colors)==null?void 0:$v.cyan)??{},up_for_retry:((Wv=(jv=(Bv=dt.theme)==null?void 0:Bv.tokens)==null?void 0:jv.colors)==null?void 0:Wv.yellow)??{},upstream_failed:((Gv=(Uv=(Hv=dt.theme)==null?void 0:Hv.tokens)==null?void 0:Uv.colors)==null?void 0:Gv.orange)??{},running:{50:{value:"#EFFBEF"},100:{value:"#DEF7DE"},200:{value:"#B9EEB9"},300:{value:"#98E698"},400:{value:"#78DE78"},500:{value:"#53D553"},600:{value:"#32CD32"},700:{value:"#269C26"},800:{value:"#196719"},900:{value:"#0D350D"},950:{value:"#061906"}},restarting:{50:{value:"#F6EBFF"},100:{value:"#EDD6FF"},200:{value:"#D9A8FF"},300:{value:"#C880FF"},400:{value:"#B657FF"},500:{value:"#A229FF"},600:{value:"#8F00FF"},700:{value:"#6E00C2"},800:{value:"#480080"},900:{value:"#260042"},950:{value:"#11001F"}},deferred:{50:{value:"#F6F3FC"},100:{value:"#EDE7F9"},200:{value:"#DACEF3"},300:{value:"#C8B6ED"},400:{value:"#B9A1E7"},500:{value:"#A689E1"},600:{value:"#9370DB"},700:{value:"#6432C8"},800:{value:"#412182"},900:{value:"#211041"},950:{value:"#100821"}},scheduled:{50:{value:"#FBF8F4"},100:{value:"#F8F3ED"},200:{value:"#F1E7DA"},300:{value:"#E8D9C4"},400:{value:"#E1CDB2"},500:{value:"#DAC1A0"},600:{value:"#D2B48C"},700:{value:"#B9894B"},800:{value:"#7D5C31"},900:{value:"#3E2E18"},950:{value:"#21180D"}},none:{50:{value:"#F7FBFD"},100:{value:"#F3F9FB"},200:{value:"#E4F2F7"},300:{value:"#D8ECF3"},400:{value:"#C8E5EE"},500:{value:"#BDDFEB"},600:{value:"#ADD8E6"},700:{value:"#5FB2CE"},800:{value:"#30819C"},900:{value:"#18414E"},950:{value:"#0C2027"}},removed:{50:{value:"#FCFCFC"},100:{value:"#F7F7F7"},200:{value:"#F0F0F0"},300:{value:"#E8E8E8"},400:{value:"#E0E0E0"},500:{value:"#DBDBDB"},600:{value:"#D3D3D3"},700:{value:"#9E9E9E"},800:{value:"#696969"},900:{value:"#363636"},950:{value:"#1A1A1A"}}}},semanticTokens:{colors:{success:hn("success"),failed:((Xv=(Kv=(qv=dt.theme)==null?void 0:qv.semanticTokens)==null?void 0:Kv.colors)==null?void 0:Xv.red)??{},queued:hn("queued"),skipped:((Jv=(Qv=(Yv=dt.theme)==null?void 0:Yv.semanticTokens)==null?void 0:Qv.colors)==null?void 0:Jv.pink)??{},up_for_reschedule:((tb=(eb=(Zv=dt.theme)==null?void 0:Zv.semanticTokens)==null?void 0:eb.colors)==null?void 0:tb.cyan)??{},up_for_retry:((ib=(rb=(nb=dt.theme)==null?void 0:nb.semanticTokens)==null?void 0:rb.colors)==null?void 0:ib.yellow)??{},upstream_failed:((ab=(sb=(ob=dt.theme)==null?void 0:ob.semanticTokens)==null?void 0:sb.colors)==null?void 0:ab.orange)??{},running:hn("running"),restarting:hn("restarting"),deferred:hn("deferred"),scheduled:hn("scheduled"),none:hn("none","black"),removed:hn("removed","black")}}}}),UA=Xf(dt,HA);return()=>{ge.interceptors.request.use(PA);const e=new jR({defaultOptions:{queries:{staleTime:1/0}}});return y.jsx(Py,{value:UA,children:y.jsx(WR,{client:e,children:y.jsx(T2,{children:y.jsx(WA,{})})})})}}); + */const mn=(e,t="white")=>({solid:{value:`{colors.${e}.600}`},contrast:{value:{_light:"white",_dark:t}},fg:{value:{_light:`{colors.${e}.800}`,_dark:`{colors.${e}.200}`}},muted:{value:{_light:`{colors.${e}.200}`,_dark:`{colors.${e}.800}`}},subtle:{value:{_light:`{colors.${e}.100}`,_dark:`{colors.${e}.900}`}},emphasized:{value:{_light:`{colors.${e}.300}`,_dark:`{colors.${e}.700}`}},focusRing:{value:{_light:`{colors.${e}.800}`,_dark:`{colors.${e}.200}`}}}),GA=Sl({theme:{tokens:{colors:{success:{50:{value:"#E0FFE0"},100:{value:"#C2FFC2"},200:{value:"#80FF80"},300:{value:"#42FF42"},400:{value:"#00FF00"},500:{value:"#00C200"},600:{value:"#008000"},700:{value:"#006100"},800:{value:"#004200"},900:{value:"#001F00"},950:{value:"#000F00"}},failed:((Lv=(Fv=(Vv=dt.theme)==null?void 0:Vv.tokens)==null?void 0:Fv.colors)==null?void 0:Lv.red)??{},queued:{50:{value:"#F5F5F5"},100:{value:"#EBEBEB"},200:{value:"#D4D4D4"},300:{value:"#BFBFBF"},400:{value:"#ABABAB"},500:{value:"#969696"},600:{value:"#808080"},700:{value:"#616161"},800:{value:"#404040"},900:{value:"#212121"},950:{value:"#0F0F0F"}},skipped:((Mv=(zv=(Dv=dt.theme)==null?void 0:Dv.tokens)==null?void 0:zv.colors)==null?void 0:Mv.pink)??{},up_for_reschedule:((jv=(Bv=($v=dt.theme)==null?void 0:$v.tokens)==null?void 0:Bv.colors)==null?void 0:jv.cyan)??{},up_for_retry:((Uv=(Hv=(Wv=dt.theme)==null?void 0:Wv.tokens)==null?void 0:Hv.colors)==null?void 0:Uv.yellow)??{},upstream_failed:((Kv=(qv=(Gv=dt.theme)==null?void 0:Gv.tokens)==null?void 0:qv.colors)==null?void 0:Kv.orange)??{},running:{50:{value:"#EFFBEF"},100:{value:"#DEF7DE"},200:{value:"#B9EEB9"},300:{value:"#98E698"},400:{value:"#78DE78"},500:{value:"#53D553"},600:{value:"#32CD32"},700:{value:"#269C26"},800:{value:"#196719"},900:{value:"#0D350D"},950:{value:"#061906"}},restarting:{50:{value:"#F6EBFF"},100:{value:"#EDD6FF"},200:{value:"#D9A8FF"},300:{value:"#C880FF"},400:{value:"#B657FF"},500:{value:"#A229FF"},600:{value:"#8F00FF"},700:{value:"#6E00C2"},800:{value:"#480080"},900:{value:"#260042"},950:{value:"#11001F"}},deferred:{50:{value:"#F6F3FC"},100:{value:"#EDE7F9"},200:{value:"#DACEF3"},300:{value:"#C8B6ED"},400:{value:"#B9A1E7"},500:{value:"#A689E1"},600:{value:"#9370DB"},700:{value:"#6432C8"},800:{value:"#412182"},900:{value:"#211041"},950:{value:"#100821"}},scheduled:{50:{value:"#FBF8F4"},100:{value:"#F8F3ED"},200:{value:"#F1E7DA"},300:{value:"#E8D9C4"},400:{value:"#E1CDB2"},500:{value:"#DAC1A0"},600:{value:"#D2B48C"},700:{value:"#B9894B"},800:{value:"#7D5C31"},900:{value:"#3E2E18"},950:{value:"#21180D"}},none:{50:{value:"#F7FBFD"},100:{value:"#F3F9FB"},200:{value:"#E4F2F7"},300:{value:"#D8ECF3"},400:{value:"#C8E5EE"},500:{value:"#BDDFEB"},600:{value:"#ADD8E6"},700:{value:"#5FB2CE"},800:{value:"#30819C"},900:{value:"#18414E"},950:{value:"#0C2027"}},removed:{50:{value:"#FCFCFC"},100:{value:"#F7F7F7"},200:{value:"#F0F0F0"},300:{value:"#E8E8E8"},400:{value:"#E0E0E0"},500:{value:"#DBDBDB"},600:{value:"#D3D3D3"},700:{value:"#9E9E9E"},800:{value:"#696969"},900:{value:"#363636"},950:{value:"#1A1A1A"}}}},semanticTokens:{colors:{success:mn("success"),failed:((Qv=(Yv=(Xv=dt.theme)==null?void 0:Xv.semanticTokens)==null?void 0:Yv.colors)==null?void 0:Qv.red)??{},queued:mn("queued"),skipped:((eb=(Zv=(Jv=dt.theme)==null?void 0:Jv.semanticTokens)==null?void 0:Zv.colors)==null?void 0:eb.pink)??{},up_for_reschedule:((rb=(nb=(tb=dt.theme)==null?void 0:tb.semanticTokens)==null?void 0:nb.colors)==null?void 0:rb.cyan)??{},up_for_retry:((sb=(ob=(ib=dt.theme)==null?void 0:ib.semanticTokens)==null?void 0:ob.colors)==null?void 0:sb.yellow)??{},upstream_failed:((cb=(lb=(ab=dt.theme)==null?void 0:ab.semanticTokens)==null?void 0:lb.colors)==null?void 0:cb.orange)??{},running:mn("running"),restarting:mn("restarting"),deferred:mn("deferred"),scheduled:mn("scheduled"),none:mn("none","black"),removed:mn("removed","black")}}}}),qA=Xf(dt,GA);return()=>{ge.interceptors.request.use(TA);const e=new UR({defaultOptions:{queries:{staleTime:1/0}}});return x.jsx(Ty,{value:qA,children:x.jsx(GR,{client:e,children:x.jsx(A2,{children:x.jsx(UA,{})})})})}}); diff --git a/providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/requests/services.gen.ts b/providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/requests/services.gen.ts index 728a1ae550722..f05a060eca4d1 100644 --- a/providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/requests/services.gen.ts +++ b/providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/requests/services.gen.ts @@ -47,7 +47,7 @@ export class JobsService { * @param data.mapIndex For dynamically mapped tasks the mapping number, -1 if the task is not mapped. * @param data.state State of the assigned task under execution. * @param data.authorization JWT Authorization Token - * @returns null Successful Response + * @returns unknown Successful Response * @throws ApiError */ public static state(data: StateData): CancelablePromise { @@ -122,7 +122,7 @@ export class LogsService { * @param data.mapIndex For dynamically mapped tasks the mapping number, -1 if the task is not mapped. * @param data.authorization JWT Authorization Token * @param data.requestBody - * @returns null Successful Response + * @returns unknown Successful Response * @throws ApiError */ public static pushLogs(data: PushLogsData): CancelablePromise { @@ -218,7 +218,7 @@ export class WorkerService { * @param data.workerName Hostname or instance name of the worker * @param data.authorization JWT Authorization Token * @param data.requestBody - * @returns null Successful Response + * @returns unknown Successful Response * @throws ApiError */ public static updateQueues(data: UpdateQueuesData): CancelablePromise { @@ -292,7 +292,7 @@ export class UiService { * @param data The data for the request. * @param data.workerName * @param data.requestBody - * @returns null Successful Response + * @returns unknown Successful Response * @throws ApiError */ public static requestWorkerMaintenance(data: RequestWorkerMaintenanceData): CancelablePromise { @@ -315,7 +315,7 @@ export class UiService { * Exit a worker from maintenance mode. * @param data The data for the request. * @param data.workerName - * @returns null Successful Response + * @returns unknown Successful Response * @throws ApiError */ public static exitWorkerMaintenance(data: ExitWorkerMaintenanceData): CancelablePromise { diff --git a/providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/requests/types.gen.ts b/providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/requests/types.gen.ts index 61bf7663a9abd..0990dd418eb7e 100644 --- a/providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/requests/types.gen.ts +++ b/providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/requests/types.gen.ts @@ -359,7 +359,7 @@ export type StateData = { tryNumber: number; }; -export type StateResponse = null; +export type StateResponse = unknown; export type LogfilePathData = { /** @@ -418,7 +418,7 @@ export type PushLogsData = { tryNumber: number; }; -export type PushLogsResponse = null; +export type PushLogsResponse = unknown; export type RegisterData = { /** @@ -460,7 +460,7 @@ export type UpdateQueuesData = { workerName: string; }; -export type UpdateQueuesResponse = null; +export type UpdateQueuesResponse = unknown; export type HealthResponse = { [key: string]: (string); @@ -475,13 +475,13 @@ export type RequestWorkerMaintenanceData = { workerName: string; }; -export type RequestWorkerMaintenanceResponse = null; +export type RequestWorkerMaintenanceResponse = unknown; export type ExitWorkerMaintenanceData = { workerName: string; }; -export type ExitWorkerMaintenanceResponse = null; +export type ExitWorkerMaintenanceResponse = unknown; export type $OpenApiTs = { '/edge_worker/v1/jobs/fetch/{worker_name}': { @@ -514,7 +514,7 @@ export type $OpenApiTs = { /** * Successful Response */ - 200: null; + 200: unknown; /** * Bad Request */ @@ -560,7 +560,7 @@ export type $OpenApiTs = { /** * Successful Response */ - 200: null; + 200: unknown; /** * Bad Request */ @@ -627,7 +627,7 @@ export type $OpenApiTs = { /** * Successful Response */ - 200: null; + 200: unknown; /** * Bad Request */ @@ -682,7 +682,7 @@ export type $OpenApiTs = { /** * Successful Response */ - 200: null; + 200: unknown; /** * Validation Error */ @@ -695,7 +695,7 @@ export type $OpenApiTs = { /** * Successful Response */ - 200: null; + 200: unknown; /** * Validation Error */ diff --git a/providers/edge3/www-hash.txt b/providers/edge3/www-hash.txt index e77d9fccb1452..fd8d498bd3271 100644 --- a/providers/edge3/www-hash.txt +++ b/providers/edge3/www-hash.txt @@ -1 +1 @@ -d3d458dbc15ae801bb6bf8f128e38a1a65fd81e3ecc8c87dd30a79acc9a4041a +b73fb2eb4057b872cc47ac6d26eda7c9b3d806cb7cca4da826ba2a07656af7ad diff --git a/providers/fab/pyproject.toml b/providers/fab/pyproject.toml index 608963d0b1111..b9c074af2d6ba 100644 --- a/providers/fab/pyproject.toml +++ b/providers/fab/pyproject.toml @@ -80,6 +80,10 @@ dependencies = [ "jmespath>=0.7.0; python_version < '3.13'", "werkzeug>=2.2,<4; python_version < '3.13'", "wtforms>=3.0,<4; python_version < '3.13'", + + # https://github.com/dpgaspar/Flask-AppBuilder/blob/release/4.6.3/setup.py#L54C8-L54C26 + # with an exclusion to account for https://github.com/alisaifee/flask-limiter/issues/479 + "flask_limiter>3,<4,!=3.13", ] # The optional dependencies should be modified in place in the generated file diff --git a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py index 2fa5c0c5b4b1f..488d57b66c4e8 100644 --- a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py +++ b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py @@ -112,6 +112,7 @@ RESOURCE_ASSET_ALIAS, ) from airflow.sdk import DAG + from airflow.serialization.serialized_objects import SerializedDAG else: from airflow.providers.common.compat.security.permissions import ( RESOURCE_ASSET, @@ -122,13 +123,13 @@ from airflow.models.dagbag import DBDagBag from airflow.utils.session import create_session - def _iter_dags() -> Iterable[DAG]: + def _iter_dags() -> Iterable[DAG | SerializedDAG]: with create_session() as session: yield from DBDagBag().iter_all_latest_version_dags(session=session) else: from airflow.models.dagbag import DagBag - def _iter_dags() -> Iterable[DAG]: + def _iter_dags() -> Iterable[DAG | SerializedDAG]: dagbag = DagBag(read_dags_from_db=True) # type: ignore[call-arg] dagbag.collect_dags_from_db() # type: ignore[attr-defined] return dagbag.dags.values() diff --git a/providers/fab/src/airflow/providers/fab/version_compat.py b/providers/fab/src/airflow/providers/fab/version_compat.py index 423a778376e98..e1d9559cc311b 100644 --- a/providers/fab/src/airflow/providers/fab/version_compat.py +++ b/providers/fab/src/airflow/providers/fab/version_compat.py @@ -33,3 +33,4 @@ def get_base_airflow_version_tuple() -> tuple[int, int, int]: AIRFLOW_V_3_1_PLUS = get_base_airflow_version_tuple() >= (3, 1, 0) +AIRFLOW_V_3_1_1_PLUS = get_base_airflow_version_tuple() >= (3, 1, 1) diff --git a/providers/fab/src/airflow/providers/fab/www/static/dist/743.fc7a7c6ef9d09365976e.js b/providers/fab/src/airflow/providers/fab/www/static/dist/743.935ed3d26e56ed8f63d3.js similarity index 99% rename from providers/fab/src/airflow/providers/fab/www/static/dist/743.fc7a7c6ef9d09365976e.js rename to providers/fab/src/airflow/providers/fab/www/static/dist/743.935ed3d26e56ed8f63d3.js index 06235eb8787e8..abbe8cb876efb 100644 --- a/providers/fab/src/airflow/providers/fab/www/static/dist/743.fc7a7c6ef9d09365976e.js +++ b/providers/fab/src/airflow/providers/fab/www/static/dist/743.935ed3d26e56ed8f63d3.js @@ -1,2 +1,2 @@ -/*! For license information please see 743.fc7a7c6ef9d09365976e.js.LICENSE.txt */ +/*! For license information please see 743.935ed3d26e56ed8f63d3.js.LICENSE.txt */ (self.webpackChunkAirflow=self.webpackChunkAirflow||[]).push([[743],{93:function(M,z,b){(M=b.nmd(M)).exports=function(){"use strict";var z,p;function O(){return z.apply(null,arguments)}function A(M){z=M}function c(M){return M instanceof Array||"[object Array]"===Object.prototype.toString.call(M)}function o(M){return null!=M&&"[object Object]"===Object.prototype.toString.call(M)}function q(M,z){return Object.prototype.hasOwnProperty.call(M,z)}function W(M){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(M).length;var z;for(z in M)if(q(M,z))return!1;return!0}function d(M){return void 0===M}function a(M){return"number"==typeof M||"[object Number]"===Object.prototype.toString.call(M)}function n(M){return M instanceof Date||"[object Date]"===Object.prototype.toString.call(M)}function e(M,z){var b,p=[],O=M.length;for(b=0;b>>0;for(z=0;z0)for(b=0;b=0?b?"+":"":"-")+Math.pow(10,Math.max(0,O)).toString().substr(1)+p}var k=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,v=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,P={},U={};function H(M,z,b,p){var O=p;"string"==typeof p&&(O=function(){return this[p]()}),M&&(U[M]=O),z&&(U[z[0]]=function(){return w(O.apply(this,arguments),z[1],z[2])}),b&&(U[b]=function(){return this.localeData().ordinal(O.apply(this,arguments),M)})}function x(M){return M.match(/\[[\s\S]/)?M.replace(/^\[|\]$/g,""):M.replace(/\\/g,"")}function I(M){var z,b,p=M.match(k);for(z=0,b=p.length;z=0&&v.test(M);)M=M.replace(v,p),v.lastIndex=0,b-=1;return M}var j={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"};function F(M){var z=this._longDateFormat[M],b=this._longDateFormat[M.toUpperCase()];return z||!b?z:(this._longDateFormat[M]=b.match(k).map(function(M){return"MMMM"===M||"MM"===M||"DD"===M||"dddd"===M?M.slice(1):M}).join(""),this._longDateFormat[M])}var K="Invalid date";function V(){return this._invalidDate}var Q="%d",J=/\d{1,2}/;function Z(M){return this._ordinal.replace("%d",M)}var $={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function MM(M,z,b,p){var O=this._relativeTime[b];return S(O)?O(M,z,b,p):O.replace(/%d/i,M)}function zM(M,z){var b=this._relativeTime[M>0?"future":"past"];return S(b)?b(z):b.replace(/%s/i,z)}var bM={D:"date",dates:"date",date:"date",d:"day",days:"day",day:"day",e:"weekday",weekdays:"weekday",weekday:"weekday",E:"isoWeekday",isoweekdays:"isoWeekday",isoweekday:"isoWeekday",DDD:"dayOfYear",dayofyears:"dayOfYear",dayofyear:"dayOfYear",h:"hour",hours:"hour",hour:"hour",ms:"millisecond",milliseconds:"millisecond",millisecond:"millisecond",m:"minute",minutes:"minute",minute:"minute",M:"month",months:"month",month:"month",Q:"quarter",quarters:"quarter",quarter:"quarter",s:"second",seconds:"second",second:"second",gg:"weekYear",weekyears:"weekYear",weekyear:"weekYear",GG:"isoWeekYear",isoweekyears:"isoWeekYear",isoweekyear:"isoWeekYear",w:"week",weeks:"week",week:"week",W:"isoWeek",isoweeks:"isoWeek",isoweek:"isoWeek",y:"year",years:"year",year:"year"};function pM(M){return"string"==typeof M?bM[M]||bM[M.toLowerCase()]:void 0}function OM(M){var z,b,p={};for(b in M)q(M,b)&&(z=pM(b))&&(p[z]=M[b]);return p}var AM={date:9,day:11,weekday:11,isoWeekday:11,dayOfYear:4,hour:13,millisecond:16,minute:14,month:8,quarter:7,second:15,weekYear:1,isoWeekYear:1,week:5,isoWeek:5,year:1};function cM(M){var z,b=[];for(z in M)q(M,z)&&b.push({unit:z,priority:AM[z]});return b.sort(function(M,z){return M.priority-z.priority}),b}var oM,qM=/\d/,WM=/\d\d/,dM=/\d{3}/,aM=/\d{4}/,nM=/[+-]?\d{6}/,eM=/\d\d?/,RM=/\d\d\d\d?/,iM=/\d\d\d\d\d\d?/,rM=/\d{1,3}/,LM=/\d{1,4}/,fM=/[+-]?\d{1,6}/,tM=/\d+/,uM=/[+-]?\d+/,sM=/Z|[+-]\d\d:?\d\d/gi,NM=/Z|[+-]\d\d(?::?\d\d)?/gi,BM=/[+-]?\d+(\.\d{1,3})?/,XM=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,lM=/^[1-9]\d?/,hM=/^([1-9]\d|\d)/;function TM(M,z,b){oM[M]=S(z)?z:function(M,p){return M&&b?b:z}}function mM(M,z){return q(oM,M)?oM[M](z._strict,z._locale):new RegExp(gM(M))}function gM(M){return SM(M.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(M,z,b,p,O){return z||b||p||O}))}function SM(M){return M.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function _M(M){return M<0?Math.ceil(M)||0:Math.floor(M)}function EM(M){var z=+M,b=0;return 0!==z&&isFinite(z)&&(b=_M(z)),b}oM={};var CM={};function yM(M,z){var b,p,O=z;for("string"==typeof M&&(M=[M]),a(z)&&(O=function(M,b){b[z]=EM(M)}),p=M.length,b=0;b68?1900:2e3)};var KM,VM=JM("FullYear",!0);function QM(){return kM(this.year())}function JM(M,z){return function(b){return null!=b?($M(this,M,b),O.updateOffset(this,z),this):ZM(this,M)}}function ZM(M,z){if(!M.isValid())return NaN;var b=M._d,p=M._isUTC;switch(z){case"Milliseconds":return p?b.getUTCMilliseconds():b.getMilliseconds();case"Seconds":return p?b.getUTCSeconds():b.getSeconds();case"Minutes":return p?b.getUTCMinutes():b.getMinutes();case"Hours":return p?b.getUTCHours():b.getHours();case"Date":return p?b.getUTCDate():b.getDate();case"Day":return p?b.getUTCDay():b.getDay();case"Month":return p?b.getUTCMonth():b.getMonth();case"FullYear":return p?b.getUTCFullYear():b.getFullYear();default:return NaN}}function $M(M,z,b){var p,O,A,c,o;if(M.isValid()&&!isNaN(b)){switch(p=M._d,O=M._isUTC,z){case"Milliseconds":return void(O?p.setUTCMilliseconds(b):p.setMilliseconds(b));case"Seconds":return void(O?p.setUTCSeconds(b):p.setSeconds(b));case"Minutes":return void(O?p.setUTCMinutes(b):p.setMinutes(b));case"Hours":return void(O?p.setUTCHours(b):p.setHours(b));case"Date":return void(O?p.setUTCDate(b):p.setDate(b));case"FullYear":break;default:return}A=b,c=M.month(),o=29!==(o=M.date())||1!==c||kM(A)?o:28,O?p.setUTCFullYear(A,c,o):p.setFullYear(A,c,o)}}function Mz(M){return S(this[M=pM(M)])?this[M]():this}function zz(M,z){if("object"==typeof M){var b,p=cM(M=OM(M)),O=p.length;for(b=0;b=0?(o=new Date(M+400,z,b,p,O,A,c),isFinite(o.getFullYear())&&o.setFullYear(M)):o=new Date(M,z,b,p,O,A,c),o}function uz(M){var z,b;return M<100&&M>=0?((b=Array.prototype.slice.call(arguments))[0]=M+400,z=new Date(Date.UTC.apply(null,b)),isFinite(z.getUTCFullYear())&&z.setUTCFullYear(M)):z=new Date(Date.UTC.apply(null,arguments)),z}function sz(M,z,b){var p=7+z-b;return-(7+uz(M,0,p).getUTCDay()-z)%7+p-1}function Nz(M,z,b,p,O){var A,c,o=1+7*(z-1)+(7+b-p)%7+sz(M,p,O);return o<=0?c=FM(A=M-1)+o:o>FM(M)?(A=M+1,c=o-FM(M)):(A=M,c=o),{year:A,dayOfYear:c}}function Bz(M,z,b){var p,O,A=sz(M.year(),z,b),c=Math.floor((M.dayOfYear()-A-1)/7)+1;return c<1?p=c+Xz(O=M.year()-1,z,b):c>Xz(M.year(),z,b)?(p=c-Xz(M.year(),z,b),O=M.year()+1):(O=M.year(),p=c),{week:p,year:O}}function Xz(M,z,b){var p=sz(M,z,b),O=sz(M+1,z,b);return(FM(M)-p+O)/7}function lz(M){return Bz(M,this._week.dow,this._week.doy).week}H("w",["ww",2],"wo","week"),H("W",["WW",2],"Wo","isoWeek"),TM("w",eM,lM),TM("ww",eM,WM),TM("W",eM,lM),TM("WW",eM,WM),DM(["w","ww","W","WW"],function(M,z,b,p){z[p.substr(0,1)]=EM(M)});var hz={dow:0,doy:6};function Tz(){return this._week.dow}function mz(){return this._week.doy}function gz(M){var z=this.localeData().week(this);return null==M?z:this.add(7*(M-z),"d")}function Sz(M){var z=Bz(this,1,4).week;return null==M?z:this.add(7*(M-z),"d")}function _z(M,z){return"string"!=typeof M?M:isNaN(M)?"number"==typeof(M=z.weekdaysParse(M))?M:null:parseInt(M,10)}function Ez(M,z){return"string"==typeof M?z.weekdaysParse(M)%7||7:isNaN(M)?null:M}function Cz(M,z){return M.slice(z,7).concat(M.slice(0,z))}H("d",0,"do","day"),H("dd",0,0,function(M){return this.localeData().weekdaysMin(this,M)}),H("ddd",0,0,function(M){return this.localeData().weekdaysShort(this,M)}),H("dddd",0,0,function(M){return this.localeData().weekdays(this,M)}),H("e",0,0,"weekday"),H("E",0,0,"isoWeekday"),TM("d",eM),TM("e",eM),TM("E",eM),TM("dd",function(M,z){return z.weekdaysMinRegex(M)}),TM("ddd",function(M,z){return z.weekdaysShortRegex(M)}),TM("dddd",function(M,z){return z.weekdaysRegex(M)}),DM(["dd","ddd","dddd"],function(M,z,b,p){var O=b._locale.weekdaysParse(M,p,b._strict);null!=O?z.d=O:L(b).invalidWeekday=M}),DM(["d","e","E"],function(M,z,b,p){z[p]=EM(M)});var yz="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Dz="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),wz="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),kz=XM,vz=XM,Pz=XM;function Uz(M,z){var b=c(this._weekdays)?this._weekdays:this._weekdays[M&&!0!==M&&this._weekdays.isFormat.test(z)?"format":"standalone"];return!0===M?Cz(b,this._week.dow):M?b[M.day()]:b}function Hz(M){return!0===M?Cz(this._weekdaysShort,this._week.dow):M?this._weekdaysShort[M.day()]:this._weekdaysShort}function xz(M){return!0===M?Cz(this._weekdaysMin,this._week.dow):M?this._weekdaysMin[M.day()]:this._weekdaysMin}function Iz(M,z,b){var p,O,A,c=M.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],p=0;p<7;++p)A=i([2e3,1]).day(p),this._minWeekdaysParse[p]=this.weekdaysMin(A,"").toLocaleLowerCase(),this._shortWeekdaysParse[p]=this.weekdaysShort(A,"").toLocaleLowerCase(),this._weekdaysParse[p]=this.weekdays(A,"").toLocaleLowerCase();return b?"dddd"===z?-1!==(O=KM.call(this._weekdaysParse,c))?O:null:"ddd"===z?-1!==(O=KM.call(this._shortWeekdaysParse,c))?O:null:-1!==(O=KM.call(this._minWeekdaysParse,c))?O:null:"dddd"===z?-1!==(O=KM.call(this._weekdaysParse,c))||-1!==(O=KM.call(this._shortWeekdaysParse,c))||-1!==(O=KM.call(this._minWeekdaysParse,c))?O:null:"ddd"===z?-1!==(O=KM.call(this._shortWeekdaysParse,c))||-1!==(O=KM.call(this._weekdaysParse,c))||-1!==(O=KM.call(this._minWeekdaysParse,c))?O:null:-1!==(O=KM.call(this._minWeekdaysParse,c))||-1!==(O=KM.call(this._weekdaysParse,c))||-1!==(O=KM.call(this._shortWeekdaysParse,c))?O:null}function Yz(M,z,b){var p,O,A;if(this._weekdaysParseExact)return Iz.call(this,M,z,b);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),p=0;p<7;p++){if(O=i([2e3,1]).day(p),b&&!this._fullWeekdaysParse[p]&&(this._fullWeekdaysParse[p]=new RegExp("^"+this.weekdays(O,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[p]=new RegExp("^"+this.weekdaysShort(O,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[p]=new RegExp("^"+this.weekdaysMin(O,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[p]||(A="^"+this.weekdays(O,"")+"|^"+this.weekdaysShort(O,"")+"|^"+this.weekdaysMin(O,""),this._weekdaysParse[p]=new RegExp(A.replace(".",""),"i")),b&&"dddd"===z&&this._fullWeekdaysParse[p].test(M))return p;if(b&&"ddd"===z&&this._shortWeekdaysParse[p].test(M))return p;if(b&&"dd"===z&&this._minWeekdaysParse[p].test(M))return p;if(!b&&this._weekdaysParse[p].test(M))return p}}function Gz(M){if(!this.isValid())return null!=M?this:NaN;var z=ZM(this,"Day");return null!=M?(M=_z(M,this.localeData()),this.add(M-z,"d")):z}function jz(M){if(!this.isValid())return null!=M?this:NaN;var z=(this.day()+7-this.localeData()._week.dow)%7;return null==M?z:this.add(M-z,"d")}function Fz(M){if(!this.isValid())return null!=M?this:NaN;if(null!=M){var z=Ez(M,this.localeData());return this.day(this.day()%7?z:z-7)}return this.day()||7}function Kz(M){return this._weekdaysParseExact?(q(this,"_weekdaysRegex")||Jz.call(this),M?this._weekdaysStrictRegex:this._weekdaysRegex):(q(this,"_weekdaysRegex")||(this._weekdaysRegex=kz),this._weekdaysStrictRegex&&M?this._weekdaysStrictRegex:this._weekdaysRegex)}function Vz(M){return this._weekdaysParseExact?(q(this,"_weekdaysRegex")||Jz.call(this),M?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(q(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=vz),this._weekdaysShortStrictRegex&&M?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Qz(M){return this._weekdaysParseExact?(q(this,"_weekdaysRegex")||Jz.call(this),M?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(q(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Pz),this._weekdaysMinStrictRegex&&M?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Jz(){function M(M,z){return z.length-M.length}var z,b,p,O,A,c=[],o=[],q=[],W=[];for(z=0;z<7;z++)b=i([2e3,1]).day(z),p=SM(this.weekdaysMin(b,"")),O=SM(this.weekdaysShort(b,"")),A=SM(this.weekdays(b,"")),c.push(p),o.push(O),q.push(A),W.push(p),W.push(O),W.push(A);c.sort(M),o.sort(M),q.sort(M),W.sort(M),this._weekdaysRegex=new RegExp("^("+W.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+q.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+c.join("|")+")","i")}function Zz(){return this.hours()%12||12}function $z(){return this.hours()||24}function Mb(M,z){H(M,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),z)})}function zb(M,z){return z._meridiemParse}function bb(M){return"p"===(M+"").toLowerCase().charAt(0)}H("H",["HH",2],0,"hour"),H("h",["hh",2],0,Zz),H("k",["kk",2],0,$z),H("hmm",0,0,function(){return""+Zz.apply(this)+w(this.minutes(),2)}),H("hmmss",0,0,function(){return""+Zz.apply(this)+w(this.minutes(),2)+w(this.seconds(),2)}),H("Hmm",0,0,function(){return""+this.hours()+w(this.minutes(),2)}),H("Hmmss",0,0,function(){return""+this.hours()+w(this.minutes(),2)+w(this.seconds(),2)}),Mb("a",!0),Mb("A",!1),TM("a",zb),TM("A",zb),TM("H",eM,hM),TM("h",eM,lM),TM("k",eM,lM),TM("HH",eM,WM),TM("hh",eM,WM),TM("kk",eM,WM),TM("hmm",RM),TM("hmmss",iM),TM("Hmm",RM),TM("Hmmss",iM),yM(["H","HH"],HM),yM(["k","kk"],function(M,z,b){var p=EM(M);z[HM]=24===p?0:p}),yM(["a","A"],function(M,z,b){b._isPm=b._locale.isPM(M),b._meridiem=M}),yM(["h","hh"],function(M,z,b){z[HM]=EM(M),L(b).bigHour=!0}),yM("hmm",function(M,z,b){var p=M.length-2;z[HM]=EM(M.substr(0,p)),z[xM]=EM(M.substr(p)),L(b).bigHour=!0}),yM("hmmss",function(M,z,b){var p=M.length-4,O=M.length-2;z[HM]=EM(M.substr(0,p)),z[xM]=EM(M.substr(p,2)),z[IM]=EM(M.substr(O)),L(b).bigHour=!0}),yM("Hmm",function(M,z,b){var p=M.length-2;z[HM]=EM(M.substr(0,p)),z[xM]=EM(M.substr(p))}),yM("Hmmss",function(M,z,b){var p=M.length-4,O=M.length-2;z[HM]=EM(M.substr(0,p)),z[xM]=EM(M.substr(p,2)),z[IM]=EM(M.substr(O))});var pb=/[ap]\.?m?\.?/i,Ob=JM("Hours",!0);function Ab(M,z,b){return M>11?b?"pm":"PM":b?"am":"AM"}var cb,ob={calendar:y,longDateFormat:j,invalidDate:K,ordinal:Q,dayOfMonthOrdinalParse:J,relativeTime:$,months:Oz,monthsShort:Az,week:hz,weekdays:yz,weekdaysMin:wz,weekdaysShort:Dz,meridiemParse:pb},qb={},Wb={};function db(M,z){var b,p=Math.min(M.length,z.length);for(b=0;b0;){if(p=Rb(O.slice(0,z).join("-")))return p;if(b&&b.length>=z&&db(O,b)>=z-1)break;z--}A++}return cb}function eb(M){return!(!M||!M.match("^[^/\\\\]*$"))}function Rb(z){var p=null;if(void 0===qb[z]&&M&&M.exports&&eb(z))try{p=cb._abbr,b(137)("./"+z),ib(p)}catch(M){qb[z]=null}return qb[z]}function ib(M,z){var b;return M&&((b=d(z)?fb(M):rb(M,z))?cb=b:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+M+" not found. Did you forget to load it?")),cb._abbr}function rb(M,z){if(null!==z){var b,p=ob;if(z.abbr=M,null!=qb[M])g("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),p=qb[M]._config;else if(null!=z.parentLocale)if(null!=qb[z.parentLocale])p=qb[z.parentLocale]._config;else{if(null==(b=Rb(z.parentLocale)))return Wb[z.parentLocale]||(Wb[z.parentLocale]=[]),Wb[z.parentLocale].push({name:M,config:z}),null;p=b._config}return qb[M]=new C(E(p,z)),Wb[M]&&Wb[M].forEach(function(M){rb(M.name,M.config)}),ib(M),qb[M]}return delete qb[M],null}function Lb(M,z){if(null!=z){var b,p,O=ob;null!=qb[M]&&null!=qb[M].parentLocale?qb[M].set(E(qb[M]._config,z)):(null!=(p=Rb(M))&&(O=p._config),z=E(O,z),null==p&&(z.abbr=M),(b=new C(z)).parentLocale=qb[M],qb[M]=b),ib(M)}else null!=qb[M]&&(null!=qb[M].parentLocale?(qb[M]=qb[M].parentLocale,M===ib()&&ib(M)):null!=qb[M]&&delete qb[M]);return qb[M]}function fb(M){var z;if(M&&M._locale&&M._locale._abbr&&(M=M._locale._abbr),!M)return cb;if(!c(M)){if(z=Rb(M))return z;M=[M]}return nb(M)}function tb(){return T(qb)}function ub(M){var z,b=M._a;return b&&-2===L(M).overflow&&(z=b[PM]<0||b[PM]>11?PM:b[UM]<1||b[UM]>pz(b[vM],b[PM])?UM:b[HM]<0||b[HM]>24||24===b[HM]&&(0!==b[xM]||0!==b[IM]||0!==b[YM])?HM:b[xM]<0||b[xM]>59?xM:b[IM]<0||b[IM]>59?IM:b[YM]<0||b[YM]>999?YM:-1,L(M)._overflowDayOfYear&&(zUM)&&(z=UM),L(M)._overflowWeeks&&-1===z&&(z=GM),L(M)._overflowWeekday&&-1===z&&(z=jM),L(M).overflow=z),M}var sb=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Nb=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Bb=/Z|[+-]\d\d(?::?\d\d)?/,Xb=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,!1],["YYYY",/\d{4}/,!1]],lb=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],hb=/^\/?Date\((-?\d+)/i,Tb=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,mb={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function gb(M){var z,b,p,O,A,c,o=M._i,q=sb.exec(o)||Nb.exec(o),W=Xb.length,d=lb.length;if(q){for(L(M).iso=!0,z=0,b=W;zFM(A)||0===M._dayOfYear)&&(L(M)._overflowDayOfYear=!0),b=uz(A,0,M._dayOfYear),M._a[PM]=b.getUTCMonth(),M._a[UM]=b.getUTCDate()),z=0;z<3&&null==M._a[z];++z)M._a[z]=c[z]=p[z];for(;z<7;z++)M._a[z]=c[z]=null==M._a[z]?2===z?1:0:M._a[z];24===M._a[HM]&&0===M._a[xM]&&0===M._a[IM]&&0===M._a[YM]&&(M._nextDay=!0,M._a[HM]=0),M._d=(M._useUTC?uz:tz).apply(null,c),O=M._useUTC?M._d.getUTCDay():M._d.getDay(),null!=M._tzm&&M._d.setUTCMinutes(M._d.getUTCMinutes()-M._tzm),M._nextDay&&(M._a[HM]=24),M._w&&void 0!==M._w.d&&M._w.d!==O&&(L(M).weekdayMismatch=!0)}}function Ub(M){var z,b,p,O,A,c,o,q,W;null!=(z=M._w).GG||null!=z.W||null!=z.E?(A=1,c=4,b=kb(z.GG,M._a[vM],Bz(Vb(),1,4).year),p=kb(z.W,1),((O=kb(z.E,1))<1||O>7)&&(q=!0)):(A=M._locale._week.dow,c=M._locale._week.doy,W=Bz(Vb(),A,c),b=kb(z.gg,M._a[vM],W.year),p=kb(z.w,W.week),null!=z.d?((O=z.d)<0||O>6)&&(q=!0):null!=z.e?(O=z.e+A,(z.e<0||z.e>6)&&(q=!0)):O=A),p<1||p>Xz(b,A,c)?L(M)._overflowWeeks=!0:null!=q?L(M)._overflowWeekday=!0:(o=Nz(b,p,O,A,c),M._a[vM]=o.year,M._dayOfYear=o.dayOfYear)}function Hb(M){if(M._f!==O.ISO_8601)if(M._f!==O.RFC_2822){M._a=[],L(M).empty=!0;var z,b,p,A,c,o,q,W=""+M._i,d=W.length,a=0;for(q=(p=G(M._f,M._locale).match(k)||[]).length,z=0;z0&&L(M).unusedInput.push(c),W=W.slice(W.indexOf(b)+b.length),a+=b.length),U[A]?(b?L(M).empty=!1:L(M).unusedTokens.push(A),wM(A,b,M)):M._strict&&!b&&L(M).unusedTokens.push(A);L(M).charsLeftOver=d-a,W.length>0&&L(M).unusedInput.push(W),M._a[HM]<=12&&!0===L(M).bigHour&&M._a[HM]>0&&(L(M).bigHour=void 0),L(M).parsedDateParts=M._a.slice(0),L(M).meridiem=M._meridiem,M._a[HM]=xb(M._locale,M._a[HM],M._meridiem),null!==(o=L(M).era)&&(M._a[vM]=M._locale.erasConvertYear(o,M._a[vM])),Pb(M),ub(M)}else Db(M);else gb(M)}function xb(M,z,b){var p;return null==b?z:null!=M.meridiemHour?M.meridiemHour(z,b):null!=M.isPM?((p=M.isPM(b))&&z<12&&(z+=12),p||12!==z||(z=0),z):z}function Ib(M){var z,b,p,O,A,c,o=!1,q=M._f.length;if(0===q)return L(M).invalidFormat=!0,void(M._d=new Date(NaN));for(O=0;Othis?this:M:t()});function Zb(M,z){var b,p;if(1===z.length&&c(z[0])&&(z=z[0]),!z.length)return Vb();for(b=z[0],p=1;pthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Np(){if(!d(this._isDSTShifted))return this._isDSTShifted;var M,z={};return N(z,this),(z=jb(z))._a?(M=z._isUTC?i(z._a):Vb(z._a),this._isDSTShifted=this.isValid()&&Wp(z._a,M.toArray())>0):this._isDSTShifted=!1,this._isDSTShifted}function Bp(){return!!this.isValid()&&!this._isUTC}function Xp(){return!!this.isValid()&&this._isUTC}function lp(){return!!this.isValid()&&this._isUTC&&0===this._offset}O.updateOffset=function(){};var hp=/^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,Tp=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function mp(M,z){var b,p,O,A=M,c=null;return op(M)?A={ms:M._milliseconds,d:M._days,M:M._months}:a(M)||!isNaN(+M)?(A={},z?A[z]=+M:A.milliseconds=+M):(c=hp.exec(M))?(b="-"===c[1]?-1:1,A={y:0,d:EM(c[UM])*b,h:EM(c[HM])*b,m:EM(c[xM])*b,s:EM(c[IM])*b,ms:EM(qp(1e3*c[YM]))*b}):(c=Tp.exec(M))?(b="-"===c[1]?-1:1,A={y:gp(c[2],b),M:gp(c[3],b),w:gp(c[4],b),d:gp(c[5],b),h:gp(c[6],b),m:gp(c[7],b),s:gp(c[8],b)}):null==A?A={}:"object"==typeof A&&("from"in A||"to"in A)&&(O=_p(Vb(A.from),Vb(A.to)),(A={}).ms=O.milliseconds,A.M=O.months),p=new cp(A),op(M)&&q(M,"_locale")&&(p._locale=M._locale),op(M)&&q(M,"_isValid")&&(p._isValid=M._isValid),p}function gp(M,z){var b=M&&parseFloat(M.replace(",","."));return(isNaN(b)?0:b)*z}function Sp(M,z){var b={};return b.months=z.month()-M.month()+12*(z.year()-M.year()),M.clone().add(b.months,"M").isAfter(z)&&--b.months,b.milliseconds=+z-+M.clone().add(b.months,"M"),b}function _p(M,z){var b;return M.isValid()&&z.isValid()?(z=ep(z,M),M.isBefore(z)?b=Sp(M,z):((b=Sp(z,M)).milliseconds=-b.milliseconds,b.months=-b.months),b):{milliseconds:0,months:0}}function Ep(M,z){return function(b,p){var O;return null===p||isNaN(+p)||(g(z,"moment()."+z+"(period, number) is deprecated. Please use moment()."+z+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),O=b,b=p,p=O),Cp(this,mp(b,p),M),this}}function Cp(M,z,b,p){var A=z._milliseconds,c=qp(z._days),o=qp(z._months);M.isValid()&&(p=null==p||p,o&&ez(M,ZM(M,"Month")+o*b),c&&$M(M,"Date",ZM(M,"Date")+c*b),A&&M._d.setTime(M._d.valueOf()+A*b),p&&O.updateOffset(M,c||o))}mp.fn=cp.prototype,mp.invalid=Ap;var yp=Ep(1,"add"),Dp=Ep(-1,"subtract");function wp(M){return"string"==typeof M||M instanceof String}function kp(M){return X(M)||n(M)||wp(M)||a(M)||Pp(M)||vp(M)||null==M}function vp(M){var z,b,p=o(M)&&!W(M),O=!1,A=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"],c=A.length;for(z=0;zb.valueOf():b.valueOf()9999?Y(b,z?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):S(Date.prototype.toISOString)?z?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",Y(b,"Z")):Y(b,z?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")}function MO(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var M,z,b,p,O="moment",A="";return this.isLocal()||(O=0===this.utcOffset()?"moment.utc":"moment.parseZone",A="Z"),M="["+O+'("]',z=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",b="-MM-DD[T]HH:mm:ss.SSS",p=A+'[")]',this.format(M+z+b+p)}function zO(M){M||(M=this.isUtc()?O.defaultFormatUtc:O.defaultFormat);var z=Y(this,M);return this.localeData().postformat(z)}function bO(M,z){return this.isValid()&&(X(M)&&M.isValid()||Vb(M).isValid())?mp({to:this,from:M}).locale(this.locale()).humanize(!z):this.localeData().invalidDate()}function pO(M){return this.from(Vb(),M)}function OO(M,z){return this.isValid()&&(X(M)&&M.isValid()||Vb(M).isValid())?mp({from:this,to:M}).locale(this.locale()).humanize(!z):this.localeData().invalidDate()}function AO(M){return this.to(Vb(),M)}function cO(M){var z;return void 0===M?this._locale._abbr:(null!=(z=fb(M))&&(this._locale=z),this)}O.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",O.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var oO=h("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(M){return void 0===M?this.localeData():this.locale(M)});function qO(){return this._locale}var WO=1e3,dO=60*WO,aO=60*dO,nO=3506328*aO;function eO(M,z){return(M%z+z)%z}function RO(M,z,b){return M<100&&M>=0?new Date(M+400,z,b)-nO:new Date(M,z,b).valueOf()}function iO(M,z,b){return M<100&&M>=0?Date.UTC(M+400,z,b)-nO:Date.UTC(M,z,b)}function rO(M){var z,b;if(void 0===(M=pM(M))||"millisecond"===M||!this.isValid())return this;switch(b=this._isUTC?iO:RO,M){case"year":z=b(this.year(),0,1);break;case"quarter":z=b(this.year(),this.month()-this.month()%3,1);break;case"month":z=b(this.year(),this.month(),1);break;case"week":z=b(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":z=b(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":z=b(this.year(),this.month(),this.date());break;case"hour":z=this._d.valueOf(),z-=eO(z+(this._isUTC?0:this.utcOffset()*dO),aO);break;case"minute":z=this._d.valueOf(),z-=eO(z,dO);break;case"second":z=this._d.valueOf(),z-=eO(z,WO)}return this._d.setTime(z),O.updateOffset(this,!0),this}function LO(M){var z,b;if(void 0===(M=pM(M))||"millisecond"===M||!this.isValid())return this;switch(b=this._isUTC?iO:RO,M){case"year":z=b(this.year()+1,0,1)-1;break;case"quarter":z=b(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":z=b(this.year(),this.month()+1,1)-1;break;case"week":z=b(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":z=b(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":z=b(this.year(),this.month(),this.date()+1)-1;break;case"hour":z=this._d.valueOf(),z+=aO-eO(z+(this._isUTC?0:this.utcOffset()*dO),aO)-1;break;case"minute":z=this._d.valueOf(),z+=dO-eO(z,dO)-1;break;case"second":z=this._d.valueOf(),z+=WO-eO(z,WO)-1}return this._d.setTime(z),O.updateOffset(this,!0),this}function fO(){return this._d.valueOf()-6e4*(this._offset||0)}function tO(){return Math.floor(this.valueOf()/1e3)}function uO(){return new Date(this.valueOf())}function sO(){var M=this;return[M.year(),M.month(),M.date(),M.hour(),M.minute(),M.second(),M.millisecond()]}function NO(){var M=this;return{years:M.year(),months:M.month(),date:M.date(),hours:M.hours(),minutes:M.minutes(),seconds:M.seconds(),milliseconds:M.milliseconds()}}function BO(){return this.isValid()?this.toISOString():null}function XO(){return f(this)}function lO(){return R({},L(this))}function hO(){return L(this).overflow}function TO(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function mO(M,z){var b,p,A,c=this._eras||fb("en")._eras;for(b=0,p=c.length;b=0)return q[p]}function SO(M,z){var b=M.since<=M.until?1:-1;return void 0===z?O(M.since).year():O(M.since).year()+(z-M.offset)*b}function _O(){var M,z,b,p=this.localeData().eras();for(M=0,z=p.length;M(A=Xz(M,p,O))&&(z=A),JO.call(this,M,z,b,p,O))}function JO(M,z,b,p,O){var A=Nz(M,z,b,p,O),c=uz(A.year,0,A.dayOfYear);return this.year(c.getUTCFullYear()),this.month(c.getUTCMonth()),this.date(c.getUTCDate()),this}function ZO(M){return null==M?Math.ceil((this.month()+1)/3):this.month(3*(M-1)+this.month()%3)}H("N",0,0,"eraAbbr"),H("NN",0,0,"eraAbbr"),H("NNN",0,0,"eraAbbr"),H("NNNN",0,0,"eraName"),H("NNNNN",0,0,"eraNarrow"),H("y",["y",1],"yo","eraYear"),H("y",["yy",2],0,"eraYear"),H("y",["yyy",3],0,"eraYear"),H("y",["yyyy",4],0,"eraYear"),TM("N",vO),TM("NN",vO),TM("NNN",vO),TM("NNNN",PO),TM("NNNNN",UO),yM(["N","NN","NNN","NNNN","NNNNN"],function(M,z,b,p){var O=b._locale.erasParse(M,p,b._strict);O?L(b).era=O:L(b).invalidEra=M}),TM("y",tM),TM("yy",tM),TM("yyy",tM),TM("yyyy",tM),TM("yo",HO),yM(["y","yy","yyy","yyyy"],vM),yM(["yo"],function(M,z,b,p){var O;b._locale._eraYearOrdinalRegex&&(O=M.match(b._locale._eraYearOrdinalRegex)),b._locale.eraYearOrdinalParse?z[vM]=b._locale.eraYearOrdinalParse(M,O):z[vM]=parseInt(M,10)}),H(0,["gg",2],0,function(){return this.weekYear()%100}),H(0,["GG",2],0,function(){return this.isoWeekYear()%100}),IO("gggg","weekYear"),IO("ggggg","weekYear"),IO("GGGG","isoWeekYear"),IO("GGGGG","isoWeekYear"),TM("G",uM),TM("g",uM),TM("GG",eM,WM),TM("gg",eM,WM),TM("GGGG",LM,aM),TM("gggg",LM,aM),TM("GGGGG",fM,nM),TM("ggggg",fM,nM),DM(["gggg","ggggg","GGGG","GGGGG"],function(M,z,b,p){z[p.substr(0,2)]=EM(M)}),DM(["gg","GG"],function(M,z,b,p){z[p]=O.parseTwoDigitYear(M)}),H("Q",0,"Qo","quarter"),TM("Q",qM),yM("Q",function(M,z){z[PM]=3*(EM(M)-1)}),H("D",["DD",2],"Do","date"),TM("D",eM,lM),TM("DD",eM,WM),TM("Do",function(M,z){return M?z._dayOfMonthOrdinalParse||z._ordinalParse:z._dayOfMonthOrdinalParseLenient}),yM(["D","DD"],UM),yM("Do",function(M,z){z[UM]=EM(M.match(eM)[0])});var $O=JM("Date",!0);function MA(M){var z=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==M?z:this.add(M-z,"d")}H("DDD",["DDDD",3],"DDDo","dayOfYear"),TM("DDD",rM),TM("DDDD",dM),yM(["DDD","DDDD"],function(M,z,b){b._dayOfYear=EM(M)}),H("m",["mm",2],0,"minute"),TM("m",eM,hM),TM("mm",eM,WM),yM(["m","mm"],xM);var zA=JM("Minutes",!1);H("s",["ss",2],0,"second"),TM("s",eM,hM),TM("ss",eM,WM),yM(["s","ss"],IM);var bA,pA,OA=JM("Seconds",!1);for(H("S",0,0,function(){return~~(this.millisecond()/100)}),H(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),H(0,["SSS",3],0,"millisecond"),H(0,["SSSS",4],0,function(){return 10*this.millisecond()}),H(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),H(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),H(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),H(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),H(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),TM("S",rM,qM),TM("SS",rM,WM),TM("SSS",rM,dM),bA="SSSS";bA.length<=9;bA+="S")TM(bA,tM);function AA(M,z){z[YM]=EM(1e3*("0."+M))}for(bA="S";bA.length<=9;bA+="S")yM(bA,AA);function cA(){return this._isUTC?"UTC":""}function oA(){return this._isUTC?"Coordinated Universal Time":""}pA=JM("Milliseconds",!1),H("z",0,0,"zoneAbbr"),H("zz",0,0,"zoneName");var qA=B.prototype;function WA(M){return Vb(1e3*M)}function dA(){return Vb.apply(null,arguments).parseZone()}function aA(M){return M}qA.add=yp,qA.calendar=xp,qA.clone=Ip,qA.diff=Qp,qA.endOf=LO,qA.format=zO,qA.from=bO,qA.fromNow=pO,qA.to=OO,qA.toNow=AO,qA.get=Mz,qA.invalidAt=hO,qA.isAfter=Yp,qA.isBefore=Gp,qA.isBetween=jp,qA.isSame=Fp,qA.isSameOrAfter=Kp,qA.isSameOrBefore=Vp,qA.isValid=XO,qA.lang=oO,qA.locale=cO,qA.localeData=qO,qA.max=Jb,qA.min=Qb,qA.parsingFlags=lO,qA.set=zz,qA.startOf=rO,qA.subtract=Dp,qA.toArray=sO,qA.toObject=NO,qA.toDate=uO,qA.toISOString=$p,qA.inspect=MO,"undefined"!=typeof Symbol&&null!=Symbol.for&&(qA[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"}),qA.toJSON=BO,qA.toString=Zp,qA.unix=tO,qA.valueOf=fO,qA.creationData=TO,qA.eraName=_O,qA.eraNarrow=EO,qA.eraAbbr=CO,qA.eraYear=yO,qA.year=VM,qA.isLeapYear=QM,qA.weekYear=YO,qA.isoWeekYear=GO,qA.quarter=qA.quarters=ZO,qA.month=Rz,qA.daysInMonth=iz,qA.week=qA.weeks=gz,qA.isoWeek=qA.isoWeeks=Sz,qA.weeksInYear=KO,qA.weeksInWeekYear=VO,qA.isoWeeksInYear=jO,qA.isoWeeksInISOWeekYear=FO,qA.date=$O,qA.day=qA.days=Gz,qA.weekday=jz,qA.isoWeekday=Fz,qA.dayOfYear=MA,qA.hour=qA.hours=Ob,qA.minute=qA.minutes=zA,qA.second=qA.seconds=OA,qA.millisecond=qA.milliseconds=pA,qA.utcOffset=ip,qA.utc=Lp,qA.local=fp,qA.parseZone=tp,qA.hasAlignedHourOffset=up,qA.isDST=sp,qA.isLocal=Bp,qA.isUtcOffset=Xp,qA.isUtc=lp,qA.isUTC=lp,qA.zoneAbbr=cA,qA.zoneName=oA,qA.dates=h("dates accessor is deprecated. Use date instead.",$O),qA.months=h("months accessor is deprecated. Use month instead",Rz),qA.years=h("years accessor is deprecated. Use year instead",VM),qA.zone=h("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",rp),qA.isDSTShifted=h("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Np);var nA=C.prototype;function eA(M,z,b,p){var O=fb(),A=i().set(p,z);return O[b](A,M)}function RA(M,z,b){if(a(M)&&(z=M,M=void 0),M=M||"",null!=z)return eA(M,z,b,"month");var p,O=[];for(p=0;p<12;p++)O[p]=eA(M,p,b,"month");return O}function iA(M,z,b,p){"boolean"==typeof M?(a(z)&&(b=z,z=void 0),z=z||""):(b=z=M,M=!1,a(z)&&(b=z,z=void 0),z=z||"");var O,A=fb(),c=M?A._week.dow:0,o=[];if(null!=b)return eA(z,(b+c)%7,p,"day");for(O=0;O<7;O++)o[O]=eA(z,(O+c)%7,p,"day");return o}function rA(M,z){return RA(M,z,"months")}function LA(M,z){return RA(M,z,"monthsShort")}function fA(M,z,b){return iA(M,z,b,"weekdays")}function tA(M,z,b){return iA(M,z,b,"weekdaysShort")}function uA(M,z,b){return iA(M,z,b,"weekdaysMin")}nA.calendar=D,nA.longDateFormat=F,nA.invalidDate=V,nA.ordinal=Z,nA.preparse=aA,nA.postformat=aA,nA.relativeTime=MM,nA.pastFuture=zM,nA.set=_,nA.eras=mO,nA.erasParse=gO,nA.erasConvertYear=SO,nA.erasAbbrRegex=wO,nA.erasNameRegex=DO,nA.erasNarrowRegex=kO,nA.months=Wz,nA.monthsShort=dz,nA.monthsParse=nz,nA.monthsRegex=Lz,nA.monthsShortRegex=rz,nA.week=lz,nA.firstDayOfYear=mz,nA.firstDayOfWeek=Tz,nA.weekdays=Uz,nA.weekdaysMin=xz,nA.weekdaysShort=Hz,nA.weekdaysParse=Yz,nA.weekdaysRegex=Kz,nA.weekdaysShortRegex=Vz,nA.weekdaysMinRegex=Qz,nA.isPM=bb,nA.meridiem=Ab,ib("en",{eras:[{since:"0001-01-01",until:1/0,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(M){var z=M%10;return M+(1===EM(M%100/10)?"th":1===z?"st":2===z?"nd":3===z?"rd":"th")}}),O.lang=h("moment.lang is deprecated. Use moment.locale instead.",ib),O.langData=h("moment.langData is deprecated. Use moment.localeData instead.",fb);var sA=Math.abs;function NA(){var M=this._data;return this._milliseconds=sA(this._milliseconds),this._days=sA(this._days),this._months=sA(this._months),M.milliseconds=sA(M.milliseconds),M.seconds=sA(M.seconds),M.minutes=sA(M.minutes),M.hours=sA(M.hours),M.months=sA(M.months),M.years=sA(M.years),this}function BA(M,z,b,p){var O=mp(z,b);return M._milliseconds+=p*O._milliseconds,M._days+=p*O._days,M._months+=p*O._months,M._bubble()}function XA(M,z){return BA(this,M,z,1)}function lA(M,z){return BA(this,M,z,-1)}function hA(M){return M<0?Math.floor(M):Math.ceil(M)}function TA(){var M,z,b,p,O,A=this._milliseconds,c=this._days,o=this._months,q=this._data;return A>=0&&c>=0&&o>=0||A<=0&&c<=0&&o<=0||(A+=864e5*hA(gA(o)+c),c=0,o=0),q.milliseconds=A%1e3,M=_M(A/1e3),q.seconds=M%60,z=_M(M/60),q.minutes=z%60,b=_M(z/60),q.hours=b%24,c+=_M(b/24),o+=O=_M(mA(c)),c-=hA(gA(O)),p=_M(o/12),o%=12,q.days=c,q.months=o,q.years=p,this}function mA(M){return 4800*M/146097}function gA(M){return 146097*M/4800}function SA(M){if(!this.isValid())return NaN;var z,b,p=this._milliseconds;if("month"===(M=pM(M))||"quarter"===M||"year"===M)switch(z=this._days+p/864e5,b=this._months+mA(z),M){case"month":return b;case"quarter":return b/3;case"year":return b/12}else switch(z=this._days+Math.round(gA(this._months)),M){case"week":return z/7+p/6048e5;case"day":return z+p/864e5;case"hour":return 24*z+p/36e5;case"minute":return 1440*z+p/6e4;case"second":return 86400*z+p/1e3;case"millisecond":return Math.floor(864e5*z)+p;default:throw new Error("Unknown unit "+M)}}function _A(M){return function(){return this.as(M)}}var EA=_A("ms"),CA=_A("s"),yA=_A("m"),DA=_A("h"),wA=_A("d"),kA=_A("w"),vA=_A("M"),PA=_A("Q"),UA=_A("y"),HA=EA;function xA(){return mp(this)}function IA(M){return M=pM(M),this.isValid()?this[M+"s"]():NaN}function YA(M){return function(){return this.isValid()?this._data[M]:NaN}}var GA=YA("milliseconds"),jA=YA("seconds"),FA=YA("minutes"),KA=YA("hours"),VA=YA("days"),QA=YA("months"),JA=YA("years");function ZA(){return _M(this.days()/7)}var $A=Math.round,Mc={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function zc(M,z,b,p,O){return O.relativeTime(z||1,!!b,M,p)}function bc(M,z,b,p){var O=mp(M).abs(),A=$A(O.as("s")),c=$A(O.as("m")),o=$A(O.as("h")),q=$A(O.as("d")),W=$A(O.as("M")),d=$A(O.as("w")),a=$A(O.as("y")),n=A<=b.ss&&["s",A]||A0,n[4]=p,zc.apply(null,n)}function pc(M){return void 0===M?$A:"function"==typeof M&&($A=M,!0)}function Oc(M,z){return void 0!==Mc[M]&&(void 0===z?Mc[M]:(Mc[M]=z,"s"===M&&(Mc.ss=z-1),!0))}function Ac(M,z){if(!this.isValid())return this.localeData().invalidDate();var b,p,O=!1,A=Mc;return"object"==typeof M&&(z=M,M=!1),"boolean"==typeof M&&(O=M),"object"==typeof z&&(A=Object.assign({},Mc,z),null!=z.s&&null==z.ss&&(A.ss=z.s-1)),p=bc(this,!O,A,b=this.localeData()),O&&(p=b.pastFuture(+this,p)),b.postformat(p)}var cc=Math.abs;function oc(M){return(M>0)-(M<0)||+M}function qc(){if(!this.isValid())return this.localeData().invalidDate();var M,z,b,p,O,A,c,o,q=cc(this._milliseconds)/1e3,W=cc(this._days),d=cc(this._months),a=this.asSeconds();return a?(M=_M(q/60),z=_M(M/60),q%=60,M%=60,b=_M(d/12),d%=12,p=q?q.toFixed(3).replace(/\.?0+$/,""):"",O=a<0?"-":"",A=oc(this._months)!==oc(a)?"-":"",c=oc(this._days)!==oc(a)?"-":"",o=oc(this._milliseconds)!==oc(a)?"-":"",O+"P"+(b?A+b+"Y":"")+(d?A+d+"M":"")+(W?c+W+"D":"")+(z||M||q?"T":"")+(z?o+z+"H":"")+(M?o+M+"M":"")+(q?o+p+"S":"")):"P0D"}var Wc=cp.prototype;return Wc.isValid=Op,Wc.abs=NA,Wc.add=XA,Wc.subtract=lA,Wc.as=SA,Wc.asMilliseconds=EA,Wc.asSeconds=CA,Wc.asMinutes=yA,Wc.asHours=DA,Wc.asDays=wA,Wc.asWeeks=kA,Wc.asMonths=vA,Wc.asQuarters=PA,Wc.asYears=UA,Wc.valueOf=HA,Wc._bubble=TA,Wc.clone=xA,Wc.get=IA,Wc.milliseconds=GA,Wc.seconds=jA,Wc.minutes=FA,Wc.hours=KA,Wc.days=VA,Wc.weeks=ZA,Wc.months=QA,Wc.years=JA,Wc.humanize=Ac,Wc.toISOString=qc,Wc.toString=qc,Wc.toJSON=qc,Wc.locale=cO,Wc.localeData=qO,Wc.toIsoString=h("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",qc),Wc.lang=oO,H("X",0,0,"unix"),H("x",0,0,"valueOf"),TM("x",uM),TM("X",BM),yM("X",function(M,z,b){b._d=new Date(1e3*parseFloat(M))}),yM("x",function(M,z,b){b._d=new Date(EM(M))}),O.version="2.30.1",A(Vb),O.fn=qA,O.min=$b,O.max=Mp,O.now=zp,O.utc=i,O.unix=WA,O.months=rA,O.isDate=n,O.locale=ib,O.invalid=t,O.duration=mp,O.isMoment=X,O.weekdays=fA,O.parseZone=dA,O.localeData=fb,O.isDuration=op,O.monthsShort=LA,O.weekdaysMin=uA,O.defineLocale=rb,O.updateLocale=Lb,O.locales=tb,O.weekdaysShort=tA,O.normalizeUnits=pM,O.relativeTimeRounding=pc,O.relativeTimeThreshold=Oc,O.calendarFormat=Hp,O.prototype=qA,O.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},O}()},639:function(M,z,b){var p,O,A;!function(c,o){"use strict";M.exports?M.exports=o(b(93)):(O=[b(93)],void 0===(A="function"==typeof(p=o)?p.apply(z,O):p)||(M.exports=A))}(0,function(M){"use strict";void 0===M.version&&M.default&&(M=M.default);var z,b={},p={},O={},A={},c={};M&&"string"==typeof M.version||g("Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/");var o=M.version.split("."),q=+o[0],W=+o[1];function d(M){return M>96?M-87:M>64?M-29:M-48}function a(M){var z=0,b=M.split("."),p=b[0],O=b[1]||"",A=1,c=0,o=1;for(45===M.charCodeAt(0)&&(z=1,o=-1);z3){var z=A[X(M)];if(z)return z;g("Moment Timezone found "+M+" from the Intl api, but did not have that data loaded.")}}catch(M){}var b,p,O,c=function(){var M,z,b,p,O=(new Date).getFullYear()-2,A=new L(new Date(O,0,1)),c=A.offset,o=[A];for(p=1;p<48;p++)(b=new Date(O,p,1).getTimezoneOffset())!==c&&(M=t(A,z=new L(new Date(O,p,1))),o.push(M),o.push(new L(new Date(M.at+6e4))),A=z,c=b);for(p=0;p<4;p++)o.push(new L(new Date(O+p,0,1))),o.push(new L(new Date(O+p,6,1)));return o}(),o=c.length,q=N(c),W=[];for(p=0;p0?W[0].zone.name:void 0}function X(M){return(M||"").toLowerCase().replace(/\//g,"_")}function l(M){var z,p,O,c;for("string"==typeof M&&(M=[M]),z=0;z= 2.6.0. You are using Moment.js "+M.version+". See momentjs.com"),i.prototype={_set:function(M){this.name=M.name,this.abbrs=M.abbrs,this.untils=M.untils,this.offsets=M.offsets,this.population=M.population},_index:function(M){var z;if((z=function(M,z){var b,p=z.length;if(M1&&z[p-1]===1/0&&M>=z[p-2])return p-1;if(M>=z[p-1])return-1;for(var O=0,A=p-1;A-O>1;)z[b=Math.floor((O+A)/2)]<=M?O=b:A=b;return A}(+M,this.untils))>=0)return z},countries:function(){var M=this.name;return Object.keys(O).filter(function(z){return-1!==O[z].zones.indexOf(M)})},parse:function(M){var z,b,p,O,A=+M,c=this.offsets,o=this.untils,q=o.length-1;for(O=0;Op&&S.moveInvalidForward&&(z=p),A0&&(this._z=null),_.apply(this,arguments)}),M.tz.setDefault=function(z){return(q<2||2===q&&W<9)&&g("Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js "+M.version+"."),M.defaultZone=z?h(z):null,M};var D=M.momentProperties;return"[object Array]"===Object.prototype.toString.call(D)?(D.push("_z"),D.push("_a")):D&&(D._z=null),M})},681:M=>{"use strict";M.exports=JSON.parse('{"version":"2025b","zones":["Africa/Abidjan|LMT GMT|g.8 0|01|-2ldXH.Q|48e5","Africa/Nairobi|LMT +0230 EAT +0245|-2r.g -2u -30 -2J|012132|-2ua2r.g N6nV.g 3Fbu h1cu dzbJ|47e5","Africa/Algiers|LMT PMT WET WEST CET CEST|-c.c -9.l 0 -10 -10 -20|01232323232323232454542423234542324|-3bQ0c.c MDA2.P cNb9.l HA0 19A0 1iM0 11c0 1oo0 Wo0 1rc0 QM0 1EM0 UM0 DA0 Imo0 rd0 De0 9Xz0 1fb0 1ap0 16K0 2yo0 mEp0 hwL0 jxA0 11A0 dDd0 17b0 11B0 1cN0 2Dy0 1cN0 1fB0 1cL0|26e5","Africa/Lagos|LMT GMT +0030 WAT|-d.z 0 -u -10|01023|-2B40d.z 7iod.z dnXK.p dLzH.z|17e6","Africa/Bissau|LMT -01 GMT|12.k 10 0|012|-2ldX0 2xoo0|39e4","Africa/Maputo|LMT CAT|-2a.i -20|01|-2sw2a.i|26e5","Africa/Cairo|LMT EET EEST|-25.9 -20 -30|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2MBC5.9 1AQM5.9 vb0 1ip0 11z0 1iN0 1nz0 12p0 1pz0 10N0 1pz0 16p0 1jz0 s3d0 Vz0 1oN0 11b0 1oO0 10N0 1pz0 10N0 1pb0 10N0 1pb0 10N0 1pb0 10N0 1pz0 10N0 1pb0 10N0 1pb0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1WL0 rd0 1Rz0 wp0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1qL0 Xd0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1ny0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 WL0 1qN0 Rb0 1wp0 On0 1zd0 Lz0 1EN0 Fb0 c10 8n0 8Nd0 gL0 e10 mn0 kSp0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0|15e6","Africa/Casablanca|LMT +00 +01|u.k 0 -10|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-2gMnt.E 130Lt.E rb0 Dd0 dVb0 b6p0 TX0 EoB0 LL0 gnd0 rz0 43d0 AL0 1Nd0 XX0 1Cp0 pz0 dEp0 4mn0 SyN0 AL0 1Nd0 wn0 1FB0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0|32e5","Africa/Ceuta|LMT WET WEST CET CEST|l.g 0 -10 -10 -20|0121212121212121212121343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-2M0M0 GdX0 11z0 drd0 18p0 3HX0 17d0 1fz0 1a10 1io0 1a00 1y7o0 LL0 gnd0 rz0 43d0 AL0 1Nd0 XX0 1Cp0 pz0 dEp0 4VB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|85e3","Africa/El_Aaiun|LMT -01 +00 +01|Q.M 10 0 -10|012323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323|-1rDz7.c 1GVA7.c 6L0 AL0 1Nd0 XX0 1Cp0 pz0 1cBB0 AL0 1Nd0 wn0 1FB0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0|20e4","Africa/Johannesburg|LMT SAST SAST SAST|-1Q -1u -20 -30|0123232|-39EpQ qTcm 1Ajdu 1cL0 1cN0 1cL0|84e5","Africa/Juba|LMT CAT CAST EAT|-26.s -20 -30 -30|012121212121212121212121212121212131|-1yW26.s 1zK06.s 16L0 1iN0 17b0 1jd0 17b0 1ip0 17z0 1i10 17X0 1hB0 18n0 1hd0 19b0 1gp0 19z0 1iN0 17b0 1ip0 17z0 1i10 18n0 1hd0 18L0 1gN0 19b0 1gp0 19z0 1iN0 17z0 1i10 17X0 yGd0 PeX0|","Africa/Khartoum|LMT CAT CAST EAT|-2a.8 -20 -30 -30|012121212121212121212121212121212131|-1yW2a.8 1zK0a.8 16L0 1iN0 17b0 1jd0 17b0 1ip0 17z0 1i10 17X0 1hB0 18n0 1hd0 19b0 1gp0 19z0 1iN0 17b0 1ip0 17z0 1i10 18n0 1hd0 18L0 1gN0 19b0 1gp0 19z0 1iN0 17z0 1i10 17X0 yGd0 HjL0|51e5","Africa/Monrovia|LMT MMT MMT GMT|H.8 H.8 I.u 0|0123|-3ygng.Q 1usM0 28G01.m|11e5","Africa/Ndjamena|LMT WAT WAST|-10.c -10 -20|0121|-2le10.c 2J3c0.c Wn0|13e5","Africa/Sao_Tome|LMT LMT GMT WAT|-q.U A.J 0 -10|01232|-3tooq.U 18aoq.U 4i6N0 2q00|","Africa/Tripoli|LMT CET CEST EET|-Q.I -10 -20 -20|012121213121212121212121213123123|-21JcQ.I 1hnBQ.I vx0 4iP0 xx0 4eN0 Bb0 7ip0 U0n0 A10 1db0 1cN0 1db0 1dd0 1db0 1eN0 1bb0 1e10 1cL0 1c10 1db0 1dd0 1db0 1cN0 1db0 1q10 fAn0 1ep0 1db0 AKq0 TA0 1o00|11e5","Africa/Tunis|LMT PMT CET CEST|-E.I -9.l -10 -20|01232323232323232323232323232323232|-3zO0E.I 1cBAv.n 18pa9.l 1qM0 DA0 3Tc0 11B0 1ze0 WM0 7z0 3d0 14L0 1cN0 1f90 1ar0 16J0 1gXB0 WM0 1rA0 11c0 nwo0 Ko0 1cM0 1cM0 1rA0 10M0 zuM0 10N0 1aN0 1qM0 WM0 1qM0 11A0 1o00|20e5","Africa/Windhoek|LMT +0130 SAST SAST CAT WAT|-18.o -1u -20 -30 -20 -10|012324545454545454545454545454545454545454545454545454|-39Ep8.o qTbC.o 1Ajdu 1cL0 1SqL0 9Io0 16P0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|32e4","America/Adak|LMT LMT NST NWT NPT BST BDT AHST HST HDT|-cd.m bK.C b0 a0 a0 b0 a0 a0 a0 90|01234256565656565656565656565656565678989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898|-48Pzs.L 1jVzf.p 1EX1d.m 8wW0 iB0 Qlb0 52O0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cm0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|326","America/Anchorage|LMT LMT AST AWT APT AHST AHDT YST AKST AKDT|-e0.o 9X.A a0 90 90 a0 90 90 90 80|01234256565656565656565656565656565678989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898|-48Pzs.L 1jVxs.n 1EX20.o 8wX0 iA0 Qlb0 52O0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cm0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|30e4","America/Puerto_Rico|LMT AST AWT APT|4o.p 40 30 30|01231|-2Qi7z.z 1IUbz.z 7XT0 iu0|24e5","America/Araguaina|LMT -03 -02|3c.M 30 20|0121212121212121212121212121212121212121212121212121|-2glwL.c HdKL.c 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 dMN0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 ny10 Lz0|14e4","America/Argentina/Buenos_Aires|LMT CMT -04 -03 -02|3R.M 4g.M 40 30 20|012323232323232323232323232323232323232323234343434343434343|-331U6.c 125cn pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 A4p0 uL0 1qN0 WL0|","America/Argentina/Catamarca|LMT CMT -04 -03 -02|4n.8 4g.M 40 30 20|012323232323232323232323232323232323232323234343434243432343|-331TA.Q 125bR.E pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 rlB0 7B0 8zb0 uL0|","America/Argentina/Cordoba|LMT CMT -04 -03 -02|4g.M 4g.M 40 30 20|012323232323232323232323232323232323232323234343434243434343|-331TH.c 125c0 pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 A4p0 uL0 1qN0 WL0|","America/Argentina/Jujuy|LMT CMT -04 -03 -02|4l.c 4g.M 40 30 20|0123232323232323232323232323232323232323232343434232434343|-331TC.M 125bT.A pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1ze0 TX0 1ld0 WK0 1wp0 TX0 A4p0 uL0|","America/Argentina/La_Rioja|LMT CMT -04 -03 -02|4r.o 4g.M 40 30 20|0123232323232323232323232323232323232323232343434342343432343|-331Tw.A 125bN.o pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Qn0 qO0 16n0 Rb0 1wp0 TX0 rlB0 7B0 8zb0 uL0|","America/Argentina/Mendoza|LMT CMT -04 -03 -02|4z.g 4g.M 40 30 20|012323232323232323232323232323232323232323234343423232432343|-331To.I 125bF.w pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1u20 SL0 1vd0 Tb0 1wp0 TW0 ri10 Op0 7TX0 uL0|","America/Argentina/Rio_Gallegos|LMT CMT -04 -03 -02|4A.Q 4g.M 40 30 20|012323232323232323232323232323232323232323234343434343432343|-331Tn.8 125bD.U pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 rlB0 7B0 8zb0 uL0|","America/Argentina/Salta|LMT CMT -04 -03 -02|4l.E 4g.M 40 30 20|0123232323232323232323232323232323232323232343434342434343|-331TC.k 125bT.8 pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 A4p0 uL0|","America/Argentina/San_Juan|LMT CMT -04 -03 -02|4y.4 4g.M 40 30 20|0123232323232323232323232323232323232323232343434342343432343|-331Tp.U 125bG.I pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Qn0 qO0 16n0 Rb0 1wp0 TX0 rld0 m10 8lb0 uL0|","America/Argentina/San_Luis|LMT CMT -04 -03 -02|4p.o 4g.M 40 30 20|0123232323232323232323232323232323232323232343434232323432323|-331Ty.A 125bP.o pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 XX0 1q20 SL0 AN0 vDb0 m10 8lb0 8L0 jd0 1qN0 WL0 1qN0|","America/Argentina/Tucuman|LMT CMT -04 -03 -02|4k.Q 4g.M 40 30 20|01232323232323232323232323232323232323232323434343424343234343|-331TD.8 125bT.U pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 rlB0 4N0 8BX0 uL0 1qN0 WL0|","America/Argentina/Ushuaia|LMT CMT -04 -03 -02|4x.c 4g.M 40 30 20|012323232323232323232323232323232323232323234343434343432343|-331Tq.M 125bH.A pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 rkN0 8p0 8zb0 uL0|","America/Asuncion|LMT AMT -04 -03|3O.E 3O.E 40 30|01232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323|-3eLw9.k 1FGo0 1DKM9.k 3CL0 3Dd0 10L0 1pB0 10n0 1pB0 10n0 1pB0 1cL0 1dd0 1db0 1dd0 1cL0 1dd0 1cL0 1dd0 1cL0 1dd0 1db0 1dd0 1cL0 1dd0 1cL0 1dd0 1cL0 1dd0 1db0 1dd0 1cL0 1lB0 14n0 1dd0 1cL0 1fd0 WL0 1rd0 1aL0 1dB0 Xz0 1qp0 Xb0 1qN0 10L0 1rB0 TX0 1tB0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 WN0 1qL0 11B0 1nX0 1ip0 WL0 1qN0 WL0 1qN0 WL0 1tB0 TX0 1tB0 TX0 1tB0 19X0 1a10 1fz0 1a10 1fz0 1cN0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0|28e5","America/Panama|LMT CMT EST|5i.8 5j.A 50|012|-3eLuF.Q Iy01.s|15e5","America/Bahia_Banderas|LMT MST CST MDT CDT|71 70 60 60 50|01213121313131313131313131313131313142424242424242424242424242|-1UQF0 deo0 8lz0 16p0 11z0 1dd0 otX0 2bmP0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nW0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|84e3","America/Bahia|LMT -03 -02|2y.4 30 20|01212121212121212121212121212121212121212121212121212121212121|-2glxp.U HdLp.U 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 l5B0 Rb0|27e5","America/Barbados|LMT AST ADT -0330|3W.t 40 30 3u|0121213121212121|-2m4k1.v 1eAN1.v RB0 1Bz0 Op0 1rb0 11d0 1jJc0 IL0 1ip0 17b0 1ip0 17b0 1ld0 13b0|28e4","America/Belem|LMT -03 -02|3d.U 30 20|012121212121212121212121212121|-2glwK.4 HdKK.4 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0|20e5","America/Belize|LMT CST -0530 CWT CPT CDT|5Q.M 60 5u 50 50 50|012121212121212121212121212121212121212121212121213412121212121212121212121212121212121212121215151|-2kBu7.c fPA7.c Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Rbu Rcu 7Bt0 Ni0 4nd0 Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1zcu Onu e9Au qn0 lxB0 mn0|57e3","America/Boa_Vista|LMT -04 -03|42.E 40 30|0121212121212121212121212121212121|-2glvV.k HdKV.k 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 smp0 WL0 1tB0 2L0|62e2","America/Bogota|LMT BMT -05 -04|4U.g 4U.g 50 40|01232|-3sTv3.I 1eIo0 38yo3.I 1PX0|90e5","America/Boise|LMT PST PDT MST MWT MPT MDT|7I.N 80 70 70 60 60 60|01212134536363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363|-3tFE0 1nEe0 1nX0 11B0 1nX0 8C10 JCL0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 Dd0 1Kn0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e4","America/Cambridge_Bay|-00 MST MWT MPT MDT CST CDT EST|0 70 60 60 60 60 50 50|012314141414141414141414141414141414141414141414141414141414567541414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141|-21Jc0 RO90 8x20 ix0 14HB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11A0 1nX0 2K0 WQ0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e2","America/Campo_Grande|LMT -04 -03|3C.s 40 30|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2glwl.w HdLl.w 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 1C10 Lz0 1Ip0 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|77e4","America/Cancun|LMT CST EST CDT EDT|5L.4 60 50 50 40|01213132431313131313131313131313131313131312|-1UQG0 2q3C0 2tx0 wgP0 1lb0 14p0 1lb0 14o0 Lz0 xB0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 Dd0|63e4","America/Caracas|LMT CMT -0430 -04|4r.I 4r.E 4u 40|012323|-3eLvw.g ROnX.U 28KM2.k 1IwOu kqo0|29e5","America/Cayenne|LMT -04 -03|3t.k 40 30|012|-2mrwu.E 2gWou.E|58e3","America/Chicago|LMT CST CDT EST CWT CPT|5O.A 60 50 50 50 50|012121212121212121212121212121212121213121212121214512121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3tFG0 1nEe0 1nX0 11B0 1nX0 1wp0 TX0 WN0 1qL0 1cN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 11B0 1Hz0 14p0 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 RB0 8x30 iw0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|92e5","America/Chihuahua|LMT MST CST MDT CDT|74.k 70 60 60 50|0121312424231313131313131313131313131313131313131313131313132|-1UQF0 deo0 8lz0 16p0 11z0 1dd0 2zQN0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|81e4","America/Ciudad_Juarez|LMT MST CST MDT CDT|75.U 70 60 60 50|01213124242313131313131313131313131313131313131313131313131321313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131|-1UQF0 deo0 8lz0 16p0 11z0 1dd0 2zQN0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1wn0 cm0 EP0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Costa_Rica|LMT SJMT CST CDT|5A.d 5A.d 60 50|01232323232|-3eLun.L 1fyo0 2lu0n.L Db0 1Kp0 Db0 pRB0 15b0 1kp0 mL0|12e5","America/Coyhaique|LMT SMT -05 -04 -03|4M.g 4G.J 50 40 30|012131323232323232323434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-3eLvb.I MJbS.t fJAh.f 5knG.J 1Vzh.f jRAG.J 1pbh.f 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 nHX0 op0 blz0 ko0 Qeo0 WL0 1zd0 On0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0|","America/Phoenix|LMT MST MDT MWT|7s.i 70 60 60|012121313121|-3tFF0 1nEe0 1nX0 11B0 1nX0 SgN0 4Al1 Ap0 1db0 SWqX 1cL0|42e5","America/Cuiaba|LMT -04 -03|3I.k 40 30|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2glwf.E HdLf.E 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 4a10 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|54e4","America/Danmarkshavn|LMT -03 -02 GMT|1e.E 30 20 0|01212121212121212121212121212121213|-2a5WJ.k 2z5fJ.k 19U0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 DC0|8","America/Dawson_Creek|LMT PST PDT PWT PPT MST|80.U 80 70 70 70 70|01213412121212121212121212121212121212121212121212121212125|-3tofX.4 1nspX.4 1in0 UGp0 8x10 iy0 3NB0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 ML0|12e3","America/Dawson|LMT YST YDT YWT YPT YDDT PST PDT MST|9h.E 90 80 80 80 70 80 70 70|0121213415167676767676767676767676767676767676767676767676767676767676767676767676767676767678|-2MSeG.k GWpG.k 1in0 1o10 13V0 Ser0 8x00 iz0 LCL0 1fA0 jrA0 fNd0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1z90|13e2","America/Denver|LMT MST MDT MWT MPT|6X.U 70 60 60 60|012121212134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3tFF0 1nEe0 1nX0 11B0 1nX0 11B0 1qL0 WN0 mn0 Ord0 8x20 ix0 LCN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e5","America/Detroit|LMT CST EST EWT EPT EDT|5w.b 60 50 40 40 40|0123425252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252|-2Cgir.N peqr.N 156L0 8x40 iv0 6fd0 11z0 JxX1 SMX 1cN0 1cL0 aW10 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e5","America/Edmonton|LMT MST MDT MWT MPT|7x.Q 70 60 60 60|0121212121212134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2yd4q.8 shdq.8 1in0 17d0 hz0 2dB0 1fz0 1a10 11z0 1qN0 WL0 1qN0 11z0 IGN0 8x20 ix0 3NB0 11z0 XQp0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|10e5","America/Eirunepe|LMT -05 -04|4D.s 50 40|0121212121212121212121212121212121|-2glvk.w HdLk.w 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 dPB0 On0 yTd0 d5X0|31e3","America/El_Salvador|LMT CST CDT|5U.M 60 50|012121|-1XiG3.c 2Fvc3.c WL0 1qN0 WL0|11e5","America/Tijuana|LMT MST PST PDT PWT PPT|7M.4 70 80 70 70 70|012123245232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-1UQF0 4Q00 8mp0 8lz0 SN0 1cL0 pHB0 83r0 AU0 5MN0 1Rz0 38N0 Wn0 1qP0 11z0 1o10 11z0 3NA0 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 BUp0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|20e5","America/Fort_Nelson|LMT PST PDT PWT PPT MST|8a.L 80 70 70 70 70|012134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121215|-3tofN.d 1nspN.d 1in0 UGp0 8x10 iy0 3NB0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0|39e2","America/Fort_Wayne|LMT CST CDT CWT CPT EST EDT|5I.C 60 50 50 50 50 40|0121212134121212121212121212151565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFG0 1nEe0 1nX0 11B0 1nX0 QI10 Db0 RB0 8x30 iw0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 5Tz0 1o10 qLb0 1cL0 1cN0 1cL0 1qhd0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Fortaleza|LMT -03 -02|2y 30 20|0121212121212121212121212121212121212121|-2glxq HdLq 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 5z0 2mN0 On0|34e5","America/Glace_Bay|LMT AST ADT AWT APT|3X.M 40 30 30 30|012134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2IsI0.c CwO0.c 1in0 UGp0 8x50 iu0 iq10 11z0 Jg10 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|19e3","America/Godthab|LMT -03 -02 -01|3q.U 30 20 10|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212123232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-2a5Ux.4 2z5dx.4 19U0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 2so0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|17e3","America/Goose_Bay|LMT NST NDT NST NDT NWT NPT AST ADT ADDT|41.E 3u.Q 2u.Q 3u 2u 2u 2u 40 30 20|0121343434343434356343434343434343434343434343434343434343437878787878787878787878787878787878787878787879787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787|-3tojW.k 1nspt.c 1in0 DXb0 2HbX.8 WL0 1qN0 WL0 1qN0 WL0 1tB0 TX0 1tB0 WL0 1qN0 WL0 1qN0 7UHu itu 1tB0 WL0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1tB0 WL0 1ld0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 S10 g0u 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14n1 1lb0 14p0 1nW0 11C0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|76e2","America/Grand_Turk|LMT KMT EST EDT AST|4I.w 57.a 50 40 40|01232323232323232323232323232323232323232323232323232323232323232323232323243232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-3eLvf.s RK0m.C 2HHBQ.O 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 7jA0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e2","America/Guatemala|LMT CST CDT|62.4 60 50|0121212121|-24KhV.U 2efXV.U An0 mtd0 Nz0 ifB0 17b0 zDB0 11z0|13e5","America/Guayaquil|LMT QMT -05 -04|5j.k 5e 50 40|01232|-3eLuE.E 1DNzS.E 2uILK rz0|27e5","America/Guyana|LMT -04 -0345 -03|3Q.D 40 3J 30|01231|-2mf87.l 8Hc7.l 2r7bJ Ey0f|80e4","America/Halifax|LMT AST ADT AWT APT|4e.o 40 30 30 30|0121212121212121212121212121212121212121212121212134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2IsHJ.A xzzJ.A 1db0 3I30 1in0 3HX0 IL0 1E10 ML0 1yN0 Pb0 1Bd0 Mn0 1Bd0 Rz0 1w10 Xb0 1w10 LX0 1w10 Xb0 1w10 Lz0 1C10 Jz0 1E10 OL0 1yN0 Un0 1qp0 Xb0 1qp0 11X0 1w10 Lz0 1HB0 LX0 1C10 FX0 1w10 Xb0 1qp0 Xb0 1BB0 LX0 1td0 Xb0 1qp0 Xb0 Rf0 8x50 iu0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 3Qp0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 3Qp0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 6i10 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|39e4","America/Havana|LMT HMT CST CDT|5t.s 5t.A 50 40|0123232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-3eLuu.w 1qx00.8 72zu.o ML0 sld0 An0 1Nd0 Db0 1Nd0 An0 6Ep0 An0 1Nd0 An0 JDd0 Mn0 1Ap0 On0 1fd0 11X0 1qN0 WL0 1wp0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 14n0 1ld0 14L0 1kN0 15b0 1kp0 1cL0 1cN0 1fz0 1a10 1fz0 1fB0 11z0 14p0 1nX0 11B0 1nX0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 14n0 1ld0 14n0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 1a10 1in0 1a10 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 17c0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 11A0 6i00 Rc0 1wo0 U00 1tA0 Rc0 1wo0 U00 1wo0 U00 1zc0 U00 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0|21e5","America/Hermosillo|LMT MST CST MDT|7n.Q 70 60 60|01213121313131|-1UQF0 deo0 8lz0 16p0 11z0 1dd0 otX0 2bmP0 1lb0 14p0 1lb0 14p0 1lb0|64e4","America/Indiana/Knox|LMT CST CDT CWT CPT EST|5K.u 60 50 50 50 50|01212134121212121212121212121212121212151212121212121212121212121212121212121212121212121252121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3tFG0 1nEe0 1nX0 11B0 1nX0 SgN0 8x30 iw0 3NB0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 11z0 1o10 11z0 1o10 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 3Cn0 8wp0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 z8o0 1o00 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Marengo|LMT CST CDT CWT CPT EST EDT|5J.n 60 50 50 50 50 40|01212134121212121212121215656565656525656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFG0 1nEe0 1nX0 11B0 1nX0 SgN0 8x30 iw0 dyN0 11z0 6fd0 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 jrz0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1VA0 LA0 1BX0 1e6p0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Petersburg|LMT CST CDT CWT CPT EST EDT|5N.7 60 50 50 50 50 40|012121341212121212121212121215121212121212121212121252125656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFG0 1nEe0 1nX0 11B0 1nX0 SgN0 8x30 iw0 njX0 WN0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 3Fb0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 19co0 1o00 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Tell_City|LMT CST CDT CWT CPT EST EDT|5L.3 60 50 50 50 50 40|012121341212121212121212121512165652121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3tFG0 1nEe0 1nX0 11B0 1nX0 SgN0 8x30 iw0 njX0 WN0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 8wn0 1cN0 1cL0 1cN0 1cK0 1cN0 1cL0 1qhd0 1o00 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Vevay|LMT CST CDT CWT CPT EST EDT|5E.g 60 50 50 50 50 40|0121213415656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFG0 1nEe0 1nX0 11B0 1nX0 SgN0 8x30 iw0 kPB0 Awn0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1lnd0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Vincennes|LMT CST CDT CWT CPT EST EDT|5O.7 60 50 50 50 50 40|012121341212121212121212121212121565652125656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFG0 1nEe0 1nX0 11B0 1nX0 SgN0 8x30 iw0 1o10 11z0 g0p0 11z0 1o10 11z0 1qL0 WN0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 caL0 1cL0 1cN0 1cL0 1qhd0 1o00 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Winamac|LMT CST CDT CWT CPT EST EDT|5K.p 60 50 50 50 50 40|012121341212121212121212121212121212121565652165656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFG0 1nEe0 1nX0 11B0 1nX0 SgN0 8x30 iw0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 jrz0 1cL0 1cN0 1cL0 1qhd0 1o00 Rd0 1za0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Inuvik|-00 PST PDT MDT MST|0 80 70 60 70|01212121212121213434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-FnA0 L3K0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cK0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|35e2","America/Iqaluit|-00 EWT EPT EST EDT CST CDT|0 40 40 50 40 60 50|0123434343434343434343434343434343434343434343434343434343456343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-16K00 7nX0 iv0 14HB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11C0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|67e2","America/Jamaica|LMT KMT EST EDT|57.a 57.a 50 40|01232323232323232323232|-3eLuQ.O RK00 2uM1Q.O 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0|94e4","America/Juneau|LMT LMT PST PWT PPT PDT YDT YST AKST AKDT|-f2.j 8V.F 80 70 70 70 80 90 90 80|0123425252525252525252525252625252578989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898|-48Pzs.L 1jVwq.s 1EX12.j 8x10 iy0 Vo10 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cM0 1cM0 1cL0 1cN0 1fz0 1a10 1fz0 co0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|33e3","America/Kentucky/Louisville|LMT CST CDT CWT CPT EST EDT|5H.2 60 50 50 50 50 40|01212121213412121212121212121212121212565656565656525656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFG0 1nEe0 1nX0 11B0 1nX0 3Fd0 Nb0 LPd0 11z0 RB0 8x30 iw0 1nX1 e0X 9vd0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 xz0 gso0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1VA0 LA0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Kentucky/Monticello|LMT CST CDT CWT CPT EST EDT|5D.o 60 50 50 50 50 40|01212134121212121212121212121212121212121212121212121212121212121212121212565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFG0 1nEe0 1nX0 11B0 1nX0 SgN0 8x30 iw0 SWp0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/La_Paz|LMT CMT BST -04|4w.A 4w.A 3w.A 40|0123|-3eLvr.o 1FIo0 13b0|19e5","America/Lima|LMT LMT -05 -04|58.c 58.A 50 40|01232323232323232|-3eLuP.M JcM0.o 1bDzP.o zX0 1aN0 1cL0 1cN0 1cL0 1PrB0 zX0 1O10 zX0 6Gp0 zX0 98p0 zX0|11e6","America/Los_Angeles|LMT PST PDT PWT PPT|7Q.W 80 70 70 70|0121213412121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3tFE0 1nEe0 1nX0 11B0 1nX0 SgN0 8x10 iy0 5Wp1 1VaX 3dA0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e6","America/Maceio|LMT -03 -02|2m.Q 30 20|012121212121212121212121212121212121212121|-2glxB.8 HdLB.8 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 dMN0 Lz0 8Q10 WL0 1tB0 5z0 2mN0 On0|93e4","America/Managua|LMT MMT CST EST CDT|5J.8 5J.c 60 50 50|01232424232324242|-3eLue.Q 1Mhc0.4 1yAMe.M 4mn0 9Up0 Dz0 1K10 Dz0 s3F0 1KH0 DB0 9In0 k8p0 19X0 1o30 11y0|22e5","America/Manaus|LMT -04 -03|40.4 40 30|01212121212121212121212121212121|-2glvX.U HdKX.U 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 dPB0 On0|19e5","America/Martinique|LMT FFMT AST ADT|44.k 44.k 40 30|01232|-3eLvT.E PTA0 2LPbT.E 19X0|39e4","America/Matamoros|LMT CST CDT|6u 60 50|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1UQG0 2FjC0 1nX0 i6p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|45e4","America/Mazatlan|LMT MST CST MDT|75.E 70 60 60|01213121313131313131313131313131313131313131313131313131313131|-1UQF0 deo0 8lz0 16p0 11z0 1dd0 otX0 2bmP0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|44e4","America/Menominee|LMT CST CDT CWT CPT EST|5O.r 60 50 50 50 50|012121341212152121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3pdG9.x 1jce9.x 1nX0 11B0 1nX0 SgN0 8x30 iw0 1o10 11z0 LCN0 1fz0 6410 9Jb0 1cM0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|85e2","America/Merida|LMT CST EST CDT|5W.s 60 50 50|0121313131313131313131313131313131313131313131313131313131|-1UQG0 2q3C0 24n0 wG10 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|11e5","America/Metlakatla|LMT LMT PST PWT PPT PDT AKST AKDT|-fd.G 8K.i 80 70 70 70 90 80|0123425252525252525252525252525252526767672676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676|-48Pzs.L 1jVwf.5 1EX1d.G 8x10 iy0 Vo10 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1hU10 Rd0 1zb0 Op0 1zb0 Op0 1zb0 uM0 jB0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2","America/Mexico_City|LMT MST CST MDT CDT CWT|6A.A 70 60 60 50 50|012131242425242424242424242424242424242424242424242424242424242424242|-1UQF0 deo0 8lz0 16p0 11z0 1dd0 gEn0 TX0 3xd0 Jb0 6zB0 SL0 e5d0 17b0 1Pff0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|20e6","America/Miquelon|LMT AST -03 -02|3I.E 40 30 20|012323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-2mxUf.k 2LHcf.k gQ10 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|61e2","America/Moncton|LMT EST AST ADT AWT APT|4j.8 50 40 30 30 30|0123232323232323232323245232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-3txvE.Q J4ME.Q CwN0 1in0 zAo0 An0 1Nd0 An0 1Nd0 An0 1Nd0 An0 1Nd0 An0 1Nd0 An0 1K10 Lz0 1zB0 NX0 1u10 Wn0 S20 8x50 iu0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 3Cp0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14n1 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 ReX 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|64e3","America/Monterrey|LMT MST CST MDT CDT|6F.g 70 60 60 50|012131242424242424242424242424242424242424242424242424242424242|-1UQG0 dep0 8lz0 16p0 11z0 1dd0 2gmp0 1nX0 i6p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|41e5","America/Montevideo|LMT MMT -04 -03 -0330 -0230 -02 -0130|3I.P 3I.P 40 30 3u 2u 20 1u|012343434343434343434343435353636353636375363636363636363636363636363636363636363636363|-2tRUf.9 sVc0 8jcf.9 1db0 1dcu 1cLu 1dcu 1cLu ircu 11zu 1o0u 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 1qMu WLu 1fAu 1cLu 1o0u 11zu NAu 3jXu zXu Dq0u 19Xu pcu jz0 cm10 19X0 6tB0 1fbu 3o0u jX0 4vB0 xz0 3Cp0 mmu 1a10 IMu Db0 4c10 uL0 1Nd0 An0 1SN0 uL0 mp0 28L0 iPB0 un0 1SN0 xz0 1zd0 Lz0 1zd0 Rb0 1zd0 On0 1wp0 Rb0 s8p0 1fB0 1ip0 11z0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 14n0 1ld0 14n0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 11z0|17e5","America/Toronto|LMT EST EDT EWT EPT|5h.w 50 40 40 40|012121212121212121212121212121212121212121212123412121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-32B6G.s UFdG.s 1in0 11Wu 1nzu 1fD0 WJ0 1wr0 Nb0 1Ap0 On0 1zd0 On0 1wp0 TX0 1tB0 TX0 1tB0 TX0 1tB0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 4kM0 8x40 iv0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1qL0 11B0 1nX0 11B0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|65e5","America/New_York|LMT EST EDT EWT EPT|4U.2 50 40 40 40|012121212121212121212121212121212121212121212121213412121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3tFH0 1nEe0 1nX0 11B0 1nX0 11B0 1qL0 1a10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 RB0 8x40 iv0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e6","America/Nome|LMT LMT NST NWT NPT BST BDT YST AKST AKDT|-cW.m b1.C b0 a0 a0 b0 a0 90 90 80|01234256565656565656565656565656565678989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898|-48Pzs.L 1jVyu.p 1EX1W.m 8wW0 iB0 Qlb0 52O0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cl0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|38e2","America/Noronha|LMT -02 -01|29.E 20 10|0121212121212121212121212121212121212121|-2glxO.k HdKO.k 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 2L0 2pB0 On0|30e2","America/North_Dakota/Beulah|LMT MST MDT MWT MPT CST CDT|6L.7 70 60 60 60 60 50|0121213412121212121212121212121212121212121212121212121212121212121212121212121212121212121212125656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFF0 1nEe0 1nX0 11B0 1nX0 SgN0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/North_Dakota/Center|LMT MST MDT MWT MPT CST CDT|6J.c 70 60 60 60 60 50|0121213412121212121212121212121212121212121212121212121212125656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFF0 1nEe0 1nX0 11B0 1nX0 SgN0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14o0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/North_Dakota/New_Salem|LMT MST MDT MWT MPT CST CDT|6J.D 70 60 60 60 60 50|0121213412121212121212121212121212121212121212121212121212121212121212121212121212565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tFF0 1nEe0 1nX0 11B0 1nX0 SgN0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14o0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Ojinaga|LMT MST CST MDT CDT|6V.E 70 60 60 50|0121312424231313131313131313131313131313131313131313131313132424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242|-1UQF0 deo0 8lz0 16p0 11z0 1dd0 2zQN0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1wn0 Rc0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e3","America/Paramaribo|LMT PMT PMT -0330 -03|3E.E 3E.Q 3E.A 3u 30|01234|-2nDUj.k Wqo0.c qanX.I 1yVXN.o|24e4","America/Port-au-Prince|LMT PPMT EST EDT|4N.k 4N 50 40|012323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-3eLva.E 15RLX.E 2FnMb 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14q0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 i6n0 1nX0 11B0 1nX0 d430 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 3iN0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5","America/Rio_Branco|LMT -05 -04|4v.c 50 40|01212121212121212121212121212121|-2glvs.M HdLs.M 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 NBd0 d5X0|31e4","America/Porto_Velho|LMT -04 -03|4f.A 40 30|012121212121212121212121212121|-2glvI.o HdKI.o 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0|37e4","America/Punta_Arenas|LMT SMT -05 -04 -03|4H.E 4G.J 50 40 30|01213132323232323232343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-3eLvg.k MJbX.5 fJAh.f 5knG.J 1Vzh.f jRAG.J 1pbh.f 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 nHX0 op0 blz0 ko0 Qeo0 WL0 1zd0 On0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0|","America/Winnipeg|LMT CST CDT CWT CPT|6s.A 60 50 50 50|0121212134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3kLtv.o 1a3bv.o WL0 3ND0 1in0 Jap0 Rb0 aCN0 8x30 iw0 1tB0 11z0 1ip0 11z0 1o10 11z0 1o10 11z0 1rd0 10L0 1op0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 1cL0 1cN0 11z0 6i10 WL0 6i10 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|66e4","America/Rankin_Inlet|-00 CST CDT EST|0 60 50 50|01212121212121212121212121212121212121212121212121212121212321212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-vDc0 Bjk0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e2","America/Recife|LMT -03 -02|2j.A 30 20|0121212121212121212121212121212121212121|-2glxE.o HdLE.o 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 2L0 2pB0 On0|33e5","America/Regina|LMT MST MDT MWT MPT CST|6W.A 70 60 60 60 60|012121212121212121212121341212121212121212121212121215|-2AD51.o uHe1.o 1in0 s2L0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 66N0 1cL0 1cN0 19X0 1fB0 1cL0 1fB0 1cL0 1cN0 1cL0 M30 8x20 ix0 1ip0 1cL0 1ip0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 3NB0 1cL0 1cN0|19e4","America/Resolute|-00 CST CDT EST|0 60 50 50|01212121212121212121212121212121212121212121212121212121212321212121212321212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-SnA0 103I0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|229","America/Santarem|LMT -04 -03|3C.M 40 30|0121212121212121212121212121212|-2glwl.c HdLl.c 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 NBd0|21e4","America/Santiago|LMT SMT -05 -04 -03|4G.J 4G.J 50 40 30|0121313232323232323432343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-3eLvh.f MJc0 fJAh.f 5knG.J 1Vzh.f jRAG.J 1pbh.f 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 nHX0 op0 9Bz0 hX0 1q10 ko0 Qeo0 WL0 1zd0 On0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0|62e5","America/Santo_Domingo|LMT SDMT EST EDT -0430 AST|4D.A 4E 50 40 4u 40|012324242424242525|-3eLvk.o 1Jic0.o 1lJMk Mn0 6sp0 Lbu 1Cou yLu 1RAu wLu 1QMu xzu 1Q0u xXu 1PAu 13jB0 e00|29e5","America/Sao_Paulo|LMT -03 -02|36.s 30 20|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2glwR.w HdKR.w 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 pTd0 PX0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 1C10 Lz0 1Ip0 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|20e6","America/Scoresbysund|LMT -02 -01 +00|1r.Q 20 10 0|012132323232323232323232323232323232323232323232323232323232323232323232323232323232323232121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2a5Ww.8 2z5ew.8 1a00 1cK0 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 2pA0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|452","America/Sitka|LMT LMT PST PWT PPT PDT YST AKST AKDT|-eW.L 91.d 80 70 70 70 90 90 80|0123425252525252525252525252525252567878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787|-48Pzs.L 1jVwu 1EX0W.L 8x10 iy0 Vo10 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 co0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|90e2","America/St_Johns|LMT NST NDT NST NDT NWT NPT NDDT|3u.Q 3u.Q 2u.Q 3u 2u 2u 2u 1u|012121212121212121212121212121212121213434343434343435634343434343434343434343434343434343434343434343434343434343434343434343434343434343437343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-3tokt.8 1l020 14L0 1nB0 1in0 1gm0 Dz0 1JB0 1cL0 1cN0 1cL0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1fB0 1cL0 1cN0 1cL0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1fB0 1cL0 1fB0 19X0 1fB0 19X0 10O0 eKX.8 19X0 1iq0 WL0 1qN0 WL0 1qN0 WL0 1tB0 TX0 1tB0 WL0 1qN0 WL0 1qN0 7UHu itu 1tB0 WL0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1tB0 WL0 1ld0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14n1 1lb0 14p0 1nW0 11C0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4","America/Swift_Current|LMT MST MDT MWT MPT CST|7b.k 70 60 60 60 60|012134121212121212121215|-2AD4M.E uHdM.E 1in0 UGp0 8x20 ix0 1o10 17b0 1ip0 11z0 1o10 11z0 1o10 11z0 isN0 1cL0 3Cp0 1cL0 1cN0 11z0 1qN0 WL0 pMp0|16e3","America/Tegucigalpa|LMT CST CDT|5M.Q 60 50|01212121|-1WGGb.8 2ETcb.8 WL0 1qN0 WL0 GRd0 AL0|11e5","America/Thule|LMT AST ADT|4z.8 40 30|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2a5To.Q 31NBo.Q 1cL0 1cN0 1cL0 1fB0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|656","America/Vancouver|LMT PST PDT PWT PPT|8c.s 80 70 70 70|01213412121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3tofL.w 1nspL.w 1in0 UGp0 8x10 iy0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5","America/Whitehorse|LMT YST YDT YWT YPT YDDT PST PDT MST|90.c 90 80 80 80 70 80 70 70|0121213415167676767676767676767676767676767676767676767676767676767676767676767676767676767678|-2MSeX.M GWpX.M 1in0 1o10 13V0 Ser0 8x00 iz0 LCL0 1fA0 LA0 ytd0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1z90|23e3","America/Yakutat|LMT LMT YST YWT YPT YDT AKST AKDT|-eF.5 9i.T 90 80 80 80 90 80|0123425252525252525252525252525252526767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676|-48Pzs.L 1jVwL.G 1EX1F.5 8x00 iz0 Vo10 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cn0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|642","Antarctica/Casey|-00 +08 +11|0 -80 -b0|012121212121212121|-2q00 1DjS0 T90 40P0 KL0 blz0 3m10 1o30 14k0 1kr0 12l0 1o01 14kX 1lf1 14kX 1lf1 13bX|10","Antarctica/Davis|-00 +07 +05|0 -70 -50|01012121|-vyo0 iXt0 alj0 1D7v0 VB0 3Wn0 KN0|70","Pacific/Port_Moresby|LMT PMMT +10|-9M.E -9M.w -a0|012|-3D8VM.E AvA0.8|25e4","Antarctica/Macquarie|-00 AEST AEDT|0 -a0 -b0|0121012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-2OPc0 Fb40 1a00 4SK0 1ayy0 Lvs0 1cM0 1o00 Rc0 1wo0 Rc0 1wo0 U00 1wo0 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 3Co0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|1","Antarctica/Mawson|-00 +06 +05|0 -60 -50|012|-CEo0 2fyk0|60","Pacific/Auckland|LMT NZMT NZST NZST NZDT|-bD.4 -bu -cu -c0 -d0|012131313131313131313131313134343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-46jLD.4 2nEO9.4 Lz0 1tB0 11zu 1o0u 11zu 1o0u 11zu 1o0u 14nu 1lcu 14nu 1lcu 1lbu 11Au 1nXu 11Au 1nXu 11Au 1nXu 11Au 1nXu 11Au 1qLu WMu 1qLu 11Au 1n1bu IM0 1C00 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1qM0 14o0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1io0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00|14e5","Antarctica/Palmer|-00 -03 -04 -02|0 30 40 20|0121212121213121212121212121212121212121212121212121212121212121212121212121212121|-cao0 nD0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 jsN0 14N0 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0|40","Antarctica/Rothera|-00 -03|0 30|01|gOo0|130","Asia/Riyadh|LMT +03|-36.Q -30|01|-TvD6.Q|57e5","Antarctica/Troll|-00 +00 +02|0 0 -20|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|1puo0 hd0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|40","Antarctica/Vostok|-00 +07 +05|0 -70 -50|01012|-tjA0 1rWh0 1Nj0 1aTv0|25","Europe/Berlin|LMT CET CEST CEMT|-R.s -10 -20 -30|012121212121212321212321212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-36RcR.s UbWR.s 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 1cM0 kL0 Nc0 m10 WM0 1ao0 1cp0 dX0 jz0 Dd0 1io0 17c0 1fA0 1a00 1ehA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|41e5","Asia/Almaty|LMT +05 +06 +07|-57.M -50 -60 -70|0123232323232323232323212323232323232323232323232321|-1Pc57.M eUo7.M 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 L4m0|15e5","Asia/Amman|LMT EET EEST +03|-2n.I -20 -30 -30|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212123|-1yW2n.I 1HiMn.I KL0 1oN0 11b0 1oN0 11b0 1pd0 1dz0 1cp0 11b0 1op0 11b0 fO10 1db0 1e10 1cL0 1cN0 1cL0 1cN0 1fz0 1pd0 10n0 1ld0 14n0 1hB0 15b0 1ip0 19X0 1cN0 1cL0 1cN0 17b0 1ld0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1So0 y00 1fc0 1dc0 1co0 1dc0 1cM0 1cM0 1cM0 1o00 11A0 1lc0 17c0 1cM0 1cM0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 4bX0 Dd0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 LA0 1C00|25e5","Asia/Anadyr|LMT +12 +13 +14 +11|-bN.U -c0 -d0 -e0 -b0|01232121212121212121214121212121212121212121212121212121212141|-1PcbN.U eUnN.U 23CL0 1db0 2q10 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|13e3","Asia/Aqtau|LMT +04 +05 +06|-3l.4 -40 -50 -60|012323232323232323232123232312121212121212121212|-1Pc3l.4 eUnl.4 24PX0 2pX0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|15e4","Asia/Aqtobe|LMT +04 +05 +06|-3M.E -40 -50 -60|0123232323232323232321232323232323232323232323232|-1Pc3M.E eUnM.E 23CL0 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0|27e4","Asia/Ashgabat|LMT +04 +05 +06|-3R.w -40 -50 -60|0123232323232323232323212|-1Pc3R.w eUnR.w 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0|41e4","Asia/Atyrau|LMT +03 +05 +06 +04|-3r.I -30 -50 -60 -40|01232323232323232323242323232323232324242424242|-1Pc3r.I eUor.I 24PW0 2pX0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 2sp0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|","Asia/Baghdad|LMT BMT +03 +04|-2V.E -2V.A -30 -40|0123232323232323232323232323232323232323232323232323232|-3eLCV.E 18ao0.4 2ACnV.A 11b0 1cp0 1dz0 1dd0 1db0 1cN0 1cp0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1de0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0|66e5","Asia/Qatar|LMT +04 +03|-3q.8 -40 -30|012|-21Jfq.8 27BXq.8|96e4","Asia/Baku|LMT +03 +04 +05|-3j.o -30 -40 -50|01232323232323232323232123232323232323232323232323232323232323232|-1Pc3j.o 1jUoj.o WCL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cM0 9Je0 1o00 11z0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|27e5","Asia/Bangkok|LMT BMT +07|-6G.4 -6G.4 -70|012|-3D8SG.4 1C000|15e6","Asia/Barnaul|LMT +06 +07 +08|-5z -60 -70 -80|0123232323232323232323212323232321212121212121212121212121212121212|-21S5z pCnz 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 p90 LE0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|","Asia/Beirut|LMT EET EEST|-2m -20 -30|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3D8Om 1BWom 1on0 1410 1db0 19B0 1in0 1ip0 WL0 1lQp0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 q6N0 En0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1op0 11b0 dA10 17b0 1iN0 17b0 1iN0 17b0 1iN0 17b0 1vB0 SL0 1mp0 13z0 1iN0 17b0 1iN0 17b0 1jd0 12n0 1a10 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0|22e5","Asia/Bishkek|LMT +05 +06 +07|-4W.o -50 -60 -70|012323232323232323232321212121212121212121212121212|-1Pc4W.o eUnW.o 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2e00 1tX0 17b0 1ip0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1cPu 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0|87e4","Asia/Brunei|LMT +0730 +08 +0820 +09|-7l.k -7u -80 -8k -90|0123232323232323242|-1KITl.k gDbP.k 6ynu AnE 1O0k AnE 1NAk AnE 1NAk AnE 1NAk AnE 1O0k AnE 1NAk AnE pAk 8Fz0|42e4","Asia/Kolkata|LMT HMT MMT IST +0630|-5R.s -5R.k -5l.a -5u -6u|01234343|-4Fg5R.s BKo0.8 1rDcw.a 1r2LP.a 1un0 HB0 7zX0|15e6","Asia/Chita|LMT +08 +09 +10|-7x.Q -80 -90 -a0|012323232323232323232321232323232323232323232323232323232323232312|-21Q7x.Q pAnx.Q 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3re0|33e4","Asia/Ulaanbaatar|LMT +07 +08 +09|-77.w -70 -80 -90|012323232323232323232323232323232323232323232323232|-2APH7.w 2Uko7.w cKn0 1db0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 kEp0 1cJ0 1cP0 1cJ0|12e5","Asia/Shanghai|LMT CST CDT|-85.H -80 -90|012121212121212121212121212121|-2M0U5.H Iuo5.H 18n0 OjB0 Rz0 11d0 1wL0 A10 8HX0 1G10 Tz0 1ip0 1jX0 1cN0 11b0 1oN0 aL0 1tU30 Rb0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0|23e6","Asia/Colombo|LMT MMT +0530 +06 +0630|-5j.o -5j.w -5u -60 -6u|012342432|-3D8Rj.o 13inX.Q 1rFbN.w 1zzu 7Apu 23dz0 11zu n3cu|22e5","Asia/Dhaka|LMT HMT +0630 +0530 +06 +07|-61.E -5R.k -6u -5u -60 -70|01232454|-3eLG1.E 26008.k 1unn.k HB0 m6n0 2kxbu 1i00|16e6","Asia/Damascus|LMT EET EEST +03|-2p.c -20 -30 -30|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212123|-21Jep.c Hep.c 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1xRB0 11X0 1oN0 10L0 1pB0 11b0 1oN0 10L0 1mp0 13X0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 Nb0 1AN0 Nb0 bcp0 19X0 1gp0 19X0 3ld0 1xX0 Vd0 1Bz0 Sp0 1vX0 10p0 1dz0 1cN0 1cL0 1db0 1db0 1g10 1an0 1ap0 1db0 1fd0 1db0 1cN0 1db0 1dd0 1db0 1cp0 1dz0 1c10 1dX0 1cN0 1db0 1dd0 1db0 1cN0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1db0 1cN0 1db0 1cN0 19z0 1fB0 1qL0 11B0 1on0 Wp0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0|26e5","Asia/Dili|LMT +08 +09|-8m.k -80 -90|01212|-2le80 1dnX0 1nfA0 Xld0|19e4","Asia/Dubai|LMT +04|-3F.c -40|01|-21JfF.c|39e5","Asia/Dushanbe|LMT +05 +06 +07|-4z.c -50 -60 -70|012323232323232323232321|-1Pc4z.c eUnz.c 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2hB0|76e4","Asia/Famagusta|LMT EET EEST +03|-2f.M -20 -30 -30|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212312121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1Vc2f.M 2a3cf.M 1cL0 1qp0 Xz0 19B0 19X0 1fB0 1db0 1cp0 1cL0 1fB0 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1o30 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 15U0 2Ks0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|","Asia/Gaza|LMT EET EEST IST IDT|-2h.Q -20 -30 -20 -30|0121212121212121212121212121212121234343434343434343434343434343431212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2MBCh.Q 1Azeh.Q MM0 iM0 4JA0 10o0 1pA0 10M0 1pA0 16o0 1jA0 16o0 1jA0 pBa0 Vz0 1oN0 11b0 1oO0 10N0 1pz0 10N0 1pb0 10N0 1pb0 10N0 1pb0 10N0 1pz0 10N0 1pb0 10N0 1pb0 11d0 1oL0 dW0 hfB0 Db0 1fB0 Rb0 bXB0 gM0 8Q00 IM0 1wo0 TX0 1HB0 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 M10 C00 17c0 1io0 17c0 1io0 17c0 1o00 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 17c0 1io0 18N0 1bz0 19z0 1gp0 1610 1iL0 11z0 1o10 14o0 1lA1 SKX 1xd1 MKX 1AN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nA0 1210 1qL0 WN0 1qL0 WN0 1qL0 11c0 1on0 11B0 1o00 11A0 1qo0 XA0 1qp0 1cN0 1cL0 1a10 1fz0 17d0 1in0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1lb0 14p0 1in0 17d0 1cL0 1cN0 19X0 1fB0 14n0 jB0 2L0 11B0 WL0 gN0 8n0 11B0 TX0 gN0 bb0 11B0 On0 jB0 dX0 11B0 Lz0 gN0 mn0 WN0 IL0 gN0 pb0 WN0 Db0 jB0 rX0 11B0 xz0 gN0 xz0 11B0 rX0 jB0 An0 11B0 pb0 gN0 IL0 WN0 mn0 gN0 Lz0 WN0 gL0 jB0 On0 11B0 bb0 gN0 TX0 11B0 5z0 jB0 WL0 11B0 2L0 jB0 11z0 1ip0 19X0 1cN0 1cL0 17d0 1in0 14p0 1lb0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1nX0 14p0 1in0 17d0 1fz0 1a10 19X0 1fB0 17b0 gN0 2L0 WN0 14n0 gN0 5z0 WN0 WL0 jB0 8n0 11B0 Rb0 gN0 dX0 11B0 Lz0 jB0 gL0 11B0 IL0 jB0 mn0 WN0 FX0 gN0 rX0 WN0 An0 jB0 uL0 11B0 uL0 gN0 An0 11B0 rX0 gN0 Db0 11B0 mn0 jB0 FX0 11B0 jz0 gN0 On0 WN0 dX0 jB0 Rb0 WN0 bb0 jB0 TX0 11B0 5z0 gN0 11z0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0|18e5","Asia/Hebron|LMT EET EEST IST IDT|-2k.n -20 -30 -20 -30|012121212121212121212121212121212123434343434343434343434343434343121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2MBCk.n 1Azek.n MM0 iM0 4JA0 10o0 1pA0 10M0 1pA0 16o0 1jA0 16o0 1jA0 pBa0 Vz0 1oN0 11b0 1oO0 10N0 1pz0 10N0 1pb0 10N0 1pb0 10N0 1pb0 10N0 1pz0 10N0 1pb0 10N0 1pb0 11d0 1oL0 dW0 hfB0 Db0 1fB0 Rb0 bXB0 gM0 8Q00 IM0 1wo0 TX0 1HB0 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 M10 C00 17c0 1io0 17c0 1io0 17c0 1o00 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 17c0 1io0 18N0 1bz0 19z0 1gp0 1610 1iL0 12L0 1mN0 14o0 1lc0 Tb0 1xd1 MKX bB0 cn0 1cN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nA0 1210 1qL0 WN0 1qL0 WN0 1qL0 11c0 1on0 11B0 1o00 11A0 1qo0 XA0 1qp0 1cN0 1cL0 1a10 1fz0 17d0 1in0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1lb0 14p0 1in0 17d0 1cL0 1cN0 19X0 1fB0 14n0 jB0 2L0 11B0 WL0 gN0 8n0 11B0 TX0 gN0 bb0 11B0 On0 jB0 dX0 11B0 Lz0 gN0 mn0 WN0 IL0 gN0 pb0 WN0 Db0 jB0 rX0 11B0 xz0 gN0 xz0 11B0 rX0 jB0 An0 11B0 pb0 gN0 IL0 WN0 mn0 gN0 Lz0 WN0 gL0 jB0 On0 11B0 bb0 gN0 TX0 11B0 5z0 jB0 WL0 11B0 2L0 jB0 11z0 1ip0 19X0 1cN0 1cL0 17d0 1in0 14p0 1lb0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1nX0 14p0 1in0 17d0 1fz0 1a10 19X0 1fB0 17b0 gN0 2L0 WN0 14n0 gN0 5z0 WN0 WL0 jB0 8n0 11B0 Rb0 gN0 dX0 11B0 Lz0 jB0 gL0 11B0 IL0 jB0 mn0 WN0 FX0 gN0 rX0 WN0 An0 jB0 uL0 11B0 uL0 gN0 An0 11B0 rX0 gN0 Db0 11B0 mn0 jB0 FX0 11B0 jz0 gN0 On0 WN0 dX0 jB0 Rb0 WN0 bb0 jB0 TX0 11B0 5z0 gN0 11z0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0|25e4","Asia/Ho_Chi_Minh|LMT PLMT +07 +08 +09|-76.u -76.u -70 -80 -90|0123423232|-2yC76.u bK00 1h7b6.u 5lz0 18o0 3Oq0 k5c0 aVX0 BAM0|90e5","Asia/Hong_Kong|LMT HKT HKST HKWT JST|-7A.G -80 -90 -8u -90|0123412121212121212121212121212121212121212121212121212121212121212121|-2CFH0 1taO0 Hc0 xUu 9tBu 11z0 1tDu Rc0 1wo0 11A0 1cM0 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1nX0 U10 1tz0 U10 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1wn0 Rd0 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 17d0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1cL0 6fd0 14n0|73e5","Asia/Hovd|LMT +06 +07 +08|-66.A -60 -70 -80|012323232323232323232323232323232323232323232323232|-2APG6.A 2Uko6.A cKn0 1db0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 kEp0 1cJ0 1cP0 1cJ0|81e3","Asia/Irkutsk|LMT IMT +07 +08 +09|-6V.5 -6V.5 -70 -80 -90|012343434343434343434343234343434343434343434343434343434343434343|-3D8SV.5 1Bxc0 pjXV.5 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|60e4","Europe/Istanbul|LMT IMT EET EEST +03 +04|-1T.Q -1U.U -20 -30 -30 -40|01232323232323232323232323232323232323232323232345423232323232323232323232323232323232323232323232323232323232323234|-3D8NT.Q 1ePXW.U dzzU.U 11b0 8tB0 1on0 1410 1db0 19B0 1in0 3Rd0 Un0 1oN0 11b0 zSN0 CL0 mp0 1Vz0 1gN0 8yn0 1yp0 ML0 1kp0 17b0 1ip0 17b0 1fB0 19X0 1ip0 19X0 1ip0 17b0 qdB0 38L0 1jd0 Tz0 l6O0 11A0 WN0 1qL0 TB0 1tX0 U10 1tz0 11B0 1in0 17d0 z90 cne0 pb0 2Cp0 1800 14o0 1dc0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1a00 1fA0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WO0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 Xc0 1qo0 WM0 1qM0 11A0 1o00 1200 1nA0 11A0 1tA0 U00 15w0|13e6","Asia/Jakarta|LMT BMT +0720 +0730 +09 +08 WIB|-77.c -77.c -7k -7u -90 -80 -70|012343536|-49jH7.c 2hiLL.c luM0 mPzO 8vWu 6kpu 4PXu xhcu|31e6","Asia/Jayapura|LMT +09 +0930 WIT|-9m.M -90 -9u -90|0123|-1uu9m.M sMMm.M L4nu|26e4","Asia/Jerusalem|LMT JMT IST IDT IDDT|-2k.S -2k.E -20 -30 -40|012323232323232432323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-3D8Ok.S 1wvA0.e SyOk.E MM0 iM0 4JA0 10o0 1pA0 10M0 1pA0 16o0 1jA0 16o0 1jA0 3LA0 Eo0 oo0 1co0 1dA0 16o0 10M0 1jc0 1tA0 14o0 1cM0 1a00 11A0 1Nc0 Ao0 1Nc0 Ao0 1Ko0 LA0 1o00 WM0 EQK0 Db0 1fB0 Rb0 bXB0 gM0 8Q00 IM0 1wo0 TX0 1HB0 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 1hB0 1dX0 1ep0 1aL0 1eN0 17X0 1nf0 11z0 1tB0 19W0 1e10 17b0 1ep0 1gL0 18N0 1fz0 1eN0 17b0 1gq0 1gn0 19d0 1dz0 1c10 17X0 1hB0 1gn0 19d0 1dz0 1c10 17X0 1kp0 1dz0 1c10 1aL0 1eN0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0|81e4","Asia/Kabul|LMT +04 +0430|-4A.M -40 -4u|012|-3eLEA.M 2dTcA.M|46e5","Asia/Kamchatka|LMT +11 +12 +13|-ay.A -b0 -c0 -d0|012323232323232323232321232323232323232323232323232323232323212|-1SLKy.A ivXy.A 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|18e4","Asia/Karachi|LMT +0530 +0630 +05 PKT PKST|-4s.c -5u -6u -50 -50 -60|012134545454|-2xoss.c 1qOKW.c 7zX0 eup0 LqMu 1fy00 1cL0 dK10 11b0 1610 1jX0|24e6","Asia/Urumqi|LMT +06|-5O.k -60|01|-1GgtO.k|32e5","Asia/Kathmandu|LMT +0530 +0545|-5F.g -5u -5J|012|-21JhF.g 2EGMb.g|12e5","Asia/Khandyga|LMT +08 +09 +10 +11|-92.d -80 -90 -a0 -b0|0123232323232323232323212323232323232323232323232343434343434343432|-21Q92.d pAp2.d 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 qK0 yN0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 17V0 7zD0|66e2","Asia/Krasnoyarsk|LMT +06 +07 +08|-6b.q -60 -70 -80|01232323232323232323232123232323232323232323232323232323232323232|-21Hib.q prAb.q 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|10e5","Asia/Kuala_Lumpur|LMT SMT +07 +0720 +0730 +09 +08|-6T.p -6T.p -70 -7k -7u -90 -80|01234546|-2M0ST.p aIM0 17anT.p l5XE 17bO 8Fyu 1so10|71e5","Asia/Macau|LMT CST +09 +10 CDT|-7y.a -80 -90 -a0 -90|012323214141414141414141414141414141414141414141414141414141414141414141|-2CFHy.a 1uqKy.a PX0 1kn0 15B0 11b0 4Qq0 1oM0 11c0 1ko0 1u00 11A0 1cM0 11c0 1o00 11A0 1o00 11A0 1oo0 1400 1o00 11A0 1o00 U00 1tA0 U00 1wo0 Rc0 1wru U10 1tz0 U10 1tz0 U10 1tz0 U10 1wn0 Rd0 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 17d0 1cK0 1cO0 1cK0 1cO0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1cL0 6fd0 14n0|57e4","Asia/Magadan|LMT +10 +11 +12|-a3.c -a0 -b0 -c0|012323232323232323232321232323232323232323232323232323232323232312|-1Pca3.c eUo3.c 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3Cq0|95e3","Asia/Makassar|LMT MMT +08 +09 WITA|-7V.A -7V.A -80 -90 -80|01234|-21JjV.A vfc0 myLV.A 8ML0|15e5","Asia/Manila|LMT LMT PST PDT JST|fU.8 -83.Q -80 -90 -90|012323432323232|-54m83.Q 2d8A3.Q 1urM0 un0 bW10 nb0 7qo0 1MM0 klB0 lz0 TwN0 1bb0 uNB0 rz0|24e6","Asia/Nicosia|LMT EET EEST|-2d.s -20 -30|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1Vc2d.s 2a3cd.s 1cL0 1qp0 Xz0 19B0 19X0 1fB0 1db0 1cp0 1cL0 1fB0 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1o30 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|32e4","Asia/Novokuznetsk|LMT +06 +07 +08|-5M.M -60 -70 -80|012323232323232323232321232323232323232323232323232323232323212|-1PctM.M eULM.M 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|55e4","Asia/Novosibirsk|LMT +06 +07 +08|-5v.E -60 -70 -80|0123232323232323232323212323212121212121212121212121212121212121212|-21Qnv.E pAFv.E 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 ml0 Os0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 4eN0|15e5","Asia/Omsk|LMT +05 +06 +07|-4R.u -50 -60 -70|01232323232323232323232123232323232323232323232323232323232323232|-224sR.u pMLR.u 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|12e5","Asia/Oral|LMT +03 +05 +06 +04|-3p.o -30 -50 -60 -40|01232323232323232424242424242424242424242424242|-1Pc3p.o eUop.o 23CK0 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 1cM0 IM0 1EM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|27e4","Asia/Pontianak|LMT PMT +0730 +09 +08 WITA WIB|-7h.k -7h.k -7u -90 -80 -80 -70|012324256|-2ua7h.k XE00 munL.k 8Rau 6kpu 4PXu xhcu Wqnu|23e4","Asia/Pyongyang|LMT KST JST KST|-8n -8u -90 -90|012313|-2um8n 97XR 1lTzu 2Onc0 6BA0|29e5","Asia/Qostanay|LMT +04 +05 +06|-4e.s -40 -50 -60|0123232323232323232321232323232323232323232323232|-1Pc4e.s eUoe.s 23CL0 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 Mv90|","Asia/Qyzylorda|LMT +04 +05 +06|-4l.Q -40 -50 -60|01232323232323232323232323232323232323232323232|-1Pc4l.Q eUol.Q 23CL0 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 3ao0 1EM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 zQl0|73e4","Asia/Rangoon|LMT RMT +0630 +09|-6o.L -6o.L -6u -90|01232|-3D8So.L 1BnA0 SmnS.L 7j9u|48e5","Asia/Sakhalin|LMT +09 +11 +12 +10|-9u.M -90 -b0 -c0 -a0|01232323232323232323232423232323232424242424242424242424242424242|-2AGVu.M 1BoMu.M 1qFa0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 2pB0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|58e4","Asia/Samarkand|LMT +04 +05 +06|-4r.R -40 -50 -60|01232323232323232323232|-1Pc4r.R eUor.R 23CL0 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|36e4","Asia/Seoul|LMT KST JST KST KDT KDT|-8r.Q -8u -90 -90 -a0 -9u|012343434343151515151515134343|-2um8r.Q 97XV.Q 1m1zu 6CM0 Fz0 1kN0 14n0 1kN0 14L0 1zd0 On0 69B0 2I0u OL0 1FB0 Rb0 1qN0 TX0 1tB0 TX0 1tB0 TX0 1tB0 TX0 2ap0 12FBu 11A0 1o00 11A0|23e6","Asia/Srednekolymsk|LMT +10 +11 +12|-ae.Q -a0 -b0 -c0|01232323232323232323232123232323232323232323232323232323232323232|-1Pcae.Q eUoe.Q 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|35e2","Asia/Taipei|LMT CST JST CDT|-86 -80 -90 -90|012131313131313131313131313131313131313131|-30bk6 1FDc6 joM0 1yo0 Tz0 1ip0 1jX0 1cN0 11b0 1oN0 11b0 1oN0 11b0 1oN0 11b0 10N0 1BX0 10p0 1pz0 10p0 1pz0 10p0 1db0 1dd0 1db0 1cN0 1db0 1cN0 1db0 1cN0 1db0 1BB0 ML0 1Bd0 ML0 uq10 1db0 1cN0 1db0 97B0 AL0|74e5","Asia/Tashkent|LMT +05 +06 +07|-4B.b -50 -60 -70|012323232323232323232321|-1Pc4B.b eUnB.b 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0|23e5","Asia/Tbilisi|LMT TBMT +03 +04 +05|-2X.b -2X.b -30 -40 -50|01234343434343434343434323232343434343434343434323|-3D8OX.b 1LUM0 1jUnX.b WCL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cK0 1cL0 1cN0 1cL0 1cN0 2pz0 1cL0 1fB0 3Nz0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 An0 Os0 WM0|11e5","Asia/Tehran|LMT TMT +0330 +0430 +04 +05|-3p.I -3p.I -3u -4u -40 -50|012345423232323232323232323232323232323232323232323232323232323232323232|-2btDp.I Llc0 1FHaT.I 1pc0 120u Rc0 Dc0 1iMu JX0 1dB0 1en0 pNB0 UL0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 64p0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0|14e6","Asia/Thimphu|LMT +0530 +06|-5W.A -5u -60|012|-Su5W.A 1BGMs.A|79e3","Asia/Tokyo|LMT JST JDT|-9i.X -90 -a0|0121212121|-3jE90 2qSo0 Rc0 1lc0 14o0 1zc0 Oo0 1zc0 Oo0|38e6","Asia/Tomsk|LMT +06 +07 +08|-5D.P -60 -70 -80|0123232323232323232323212323232323232323232323212121212121212121212|-21NhD.P pxzD.P 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 co0 1bB0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3Qp0|10e5","Asia/Ust-Nera|LMT +08 +09 +12 +11 +10|-9w.S -80 -90 -c0 -b0 -a0|012343434343434343434345434343434343434343434343434343434343434345|-21Q9w.S pApw.S 23CL0 1d90 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 17V0 7zD0|65e2","Asia/Vladivostok|LMT +09 +10 +11|-8L.v -90 -a0 -b0|01232323232323232323232123232323232323232323232323232323232323232|-1SJIL.v itXL.v 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|60e4","Asia/Yakutsk|LMT +08 +09 +10|-8C.W -80 -90 -a0|01232323232323232323232123232323232323232323232323232323232323232|-21Q8C.W pAoC.W 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|28e4","Asia/Yekaterinburg|LMT PMT +04 +05 +06|-42.x -3J.5 -40 -50 -60|012343434343434343434343234343434343434343434343434343434343434343|-2ag42.x 7mQh.s qBvJ.5 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|14e5","Asia/Yerevan|LMT +03 +04 +05|-2W -30 -40 -50|0123232323232323232323212121212323232323232323232323232323232|-1Pc2W 1jUnW WCL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 4RX0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|13e5","Atlantic/Azores|LMT HMT -02 -01 +00 WET WEST|1G.E 1S.w 20 10 0 0 -10|012323232323232323232323232323232323232323232343234323432343232323232323232323232323232323232323232323434343434343434343434356434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-3tomh.k 18aoh.k aPX0 Sp0 M00 1vb0 SN0 1vb0 SN0 1vb0 Td0 1vb0 SN0 1vb0 6600 18o0 3I00 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 3I00 17c0 1cM0 1cM0 3Fc0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 1uo0 1c00 1dc0 1400 gL0 IM0 s10 U00 dX0 Rc0 pd0 Rc0 gL0 Oo0 pd0 Rc0 gL0 Oo0 pd0 14o0 1cM0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 CT90 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 Ap0 An0 wo0 Eo0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|25e4","Atlantic/Bermuda|LMT BMT BST AST ADT|4j.i 4j.i 3j.i 40 30|0121213434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-3eLvE.G 16mo0 1bb0 1i10 11X0 ru30 thbE.G 1PX0 11B0 1tz0 Rd0 1zb0 Op0 1zb0 3I10 Lz0 1EN0 FX0 1HB0 FX0 1Kp0 Db0 1Kp0 Db0 1Kp0 FX0 93d0 11z0 GAp0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|65e3","Atlantic/Canary|LMT -01 WET WEST|11.A 10 0 -10|01232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-1UtaW.o XPAW.o 1lAK0 1a10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|54e4","Atlantic/Cape_Verde|LMT -02 -01|1y.4 20 10|01212|-2ldW0 1eEo0 7zX0 1djf0|50e4","Atlantic/Faroe|LMT WET WEST|r.4 0 -10|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2uSnw.U 2Wgow.U 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|49e3","Atlantic/Madeira|LMT FMT -01 +00 +01 WET WEST|17.A 17.A 10 0 -10 0 -10|01232323232323232323232323232323232323232323234323432343234323232323232323232323232323232323232323232356565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-3tomQ.o 18anQ.o aPX0 Sp0 M00 1vb0 SN0 1vb0 SN0 1vb0 Td0 1vb0 SN0 1vb0 6600 18o0 3I00 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 3I00 17c0 1cM0 1cM0 3Fc0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 1uo0 1c00 1dc0 1400 gL0 IM0 s10 U00 dX0 Rc0 pd0 Rc0 gL0 Oo0 pd0 Rc0 gL0 Oo0 pd0 14o0 1cM0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 BJ90 1a00 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|27e4","Atlantic/South_Georgia|LMT -02|2q.8 20|01|-3eLxx.Q|30","Atlantic/Stanley|LMT SMT -04 -03 -02|3P.o 3P.o 40 30 20|0123232323232323434323232323232323232323232323232323232323232323232323|-3eLw8.A S200 12bA8.A 19X0 1fB0 19X0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 Cn0 1Cc10 WL0 1qL0 U10 1tz0 2mN0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1tz0 U10 1tz0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1tz0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qN0 U10 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1wn0 U10 1tz0 U10 1tz0 U10|21e2","Australia/Sydney|LMT AEST AEDT|-a4.Q -a0 -b0|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-32oW4.Q RlC4.Q xc0 10jc0 yM0 1cM0 1cM0 1fA0 1a00 17c00 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 14o0 1o00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 11A0 1o00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|40e5","Australia/Adelaide|LMT ACST ACST ACDT|-9e.k -90 -9u -au|012323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323|-32oVe.k ak0e.k H1Bu xc0 10jc0 yM0 1cM0 1cM0 1fA0 1a00 17c00 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 Oo0 1zc0 WM0 1qM0 Rc0 1zc0 U00 1tA0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|11e5","Australia/Brisbane|LMT AEST AEDT|-ac.8 -a0 -b0|012121212121212121|-32Bmc.8 Ry2c.8 xc0 10jc0 yM0 1cM0 1cM0 1fA0 1a00 17c00 LA0 H1A0 Oo0 1zc0 Oo0 1zc0 Oo0|20e5","Australia/Broken_Hill|LMT AEST ACST ACST ACDT|-9p.M -a0 -90 -9u -au|0123434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-32oVp.M 3Lzp.M 6wp0 H1Bu xc0 10jc0 yM0 1cM0 1cM0 1fA0 1a00 17c00 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 14o0 1o00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|18e3","Australia/Hobart|LMT AEST AEDT|-9N.g -a0 -b0|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-3109N.g Pk1N.g 1a00 1qM0 Oo0 1zc0 Oo0 TAo0 yM0 1cM0 1cM0 1fA0 1a00 VfA0 1cM0 1o00 Rc0 1wo0 Rc0 1wo0 U00 1wo0 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|21e4","Australia/Darwin|LMT ACST ACST ACDT|-8H.k -90 -9u -au|01232323232|-32oUH.k ajXH.k H1Bu xc0 10jc0 yM0 1cM0 1cM0 1fA0 1a00|12e4","Australia/Eucla|LMT +0845 +0945|-8z.s -8J -9J|01212121212121212121|-30nIz.s PkpO.s xc0 10jc0 yM0 1cM0 1cM0 1gSo0 Oo0 l5A0 Oo0 iJA0 G00 zU00 IM0 1qM0 11A0 1o00 11A0|368","Australia/Lord_Howe|LMT AEST +1030 +1130 +11|-aA.k -a0 -au -bu -b0|01232323232424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424|-32oWA.k 3tzAA.k 1zdu Rb0 1zd0 On0 1zd0 On0 1zd0 On0 1zd0 TXu 1qMu WLu 1tAu WLu 1tAu TXu 1tAu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu 11zu 1o0u 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 11Au 1nXu 1qMu 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 1qMu 11zu 1o0u WLu 1qMu 14nu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu|347","Australia/Lindeman|LMT AEST AEDT|-9T.U -a0 -b0|0121212121212121212121|-32BlT.U Ry1T.U xc0 10jc0 yM0 1cM0 1cM0 1fA0 1a00 17c00 LA0 H1A0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0|10","Australia/Melbourne|LMT AEST AEDT|-9D.Q -a0 -b0|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-32oVD.Q RlBD.Q xc0 10jc0 yM0 1cM0 1cM0 1fA0 1a00 17c00 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1qM0 11A0 1tA0 U00 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 11A0 1o00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|39e5","Australia/Perth|LMT AWST AWDT|-7H.o -80 -90|01212121212121212121|-30nHH.o PkpH.o xc0 10jc0 yM0 1cM0 1cM0 1gSo0 Oo0 l5A0 Oo0 iJA0 G00 zU00 IM0 1qM0 11A0 1o00 11A0|18e5","Europe/Brussels|LMT BMT WET CET CEST WEST|-h.u -h.u 0 -10 -20 -10|012343434325252525252525252525252525252525252525252525434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-3D8Mh.u u1Ah.u SO00 3zX0 11c0 1iO0 11A0 1o00 11A0 my0 Ic0 1qM0 Rc0 1EM0 UM0 1u00 10o0 1io0 1io0 17c0 1a00 1fA0 1cM0 1cM0 1io0 17c0 1fA0 1a00 1io0 1a30 1io0 17c0 1fA0 1a00 1io0 17c0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 y00 5Wn0 WM0 1fA0 1cM0 16M0 1iM0 16M0 1C00 Uo0 1eeo0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|21e5","Pacific/Easter|LMT EMT -07 -06 -05|7h.s 7h.s 70 60 50|0123232323232323232323232323234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-3eLsG.w 1HRc0 1s4IG.w WL0 1zd0 On0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 2pA0 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0|30e2","Europe/Athens|LMT AMT EET EEST CEST CET|-1y.Q -1y.Q -20 -30 -20 -10|0123234545232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-30SNy.Q OMM1 CNbx.Q mn0 kU10 9b0 3Es0 Xa0 1fb0 1dd0 k3X0 Nz0 SCp0 1vc0 SO0 1cM0 1a00 1ao0 1fc0 1a10 1fG0 1cg0 1dX0 1bX0 1cQ0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|35e5","Europe/Dublin|LMT DMT IST GMT BST IST|p.l p.l -y.D 0 -10 -10|012343434343435353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353|-3BHby.D 1ra20 Rc0 1fzy.D 14M0 1fc0 1g00 1co0 1dc0 1co0 1oo0 1400 1dc0 19A0 1io0 1io0 WM0 1o00 14o0 1o00 17c0 1io0 17c0 1fA0 1a00 1lc0 17c0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1cM0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1io0 1qM0 Dc0 g600 14o0 1wo0 17c0 1io0 11A0 1o00 17c0 1fA0 1a00 1fA0 1cM0 1fA0 1a00 17c0 1fA0 1a00 1io0 17c0 1lc0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1a00 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1tA0 IM0 90o0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|12e5","Etc/GMT-0|GMT|0|0||","Etc/GMT-1|+01|-10|0||","Etc/GMT-10|+10|-a0|0||","Etc/GMT-11|+11|-b0|0||","Etc/GMT-12|+12|-c0|0||","Etc/GMT-13|+13|-d0|0||","Etc/GMT-14|+14|-e0|0||","Etc/GMT-2|+02|-20|0||","Etc/GMT-3|+03|-30|0||","Etc/GMT-4|+04|-40|0||","Etc/GMT-5|+05|-50|0||","Etc/GMT-6|+06|-60|0||","Etc/GMT-7|+07|-70|0||","Etc/GMT-8|+08|-80|0||","Etc/GMT-9|+09|-90|0||","Etc/GMT+1|-01|10|0||","Etc/GMT+10|-10|a0|0||","Etc/GMT+11|-11|b0|0||","Etc/GMT+12|-12|c0|0||","Etc/GMT+2|-02|20|0||","Etc/GMT+3|-03|30|0||","Etc/GMT+4|-04|40|0||","Etc/GMT+5|-05|50|0||","Etc/GMT+6|-06|60|0||","Etc/GMT+7|-07|70|0||","Etc/GMT+8|-08|80|0||","Etc/GMT+9|-09|90|0||","Etc/UTC|UTC|0|0||","Europe/Andorra|LMT WET CET CEST|-6.4 0 -10 -20|0123232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-2M0M6.4 1Pnc6.4 1xIN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|79e3","Europe/Astrakhan|LMT +03 +04 +05|-3c.c -30 -40 -50|012323232323232323212121212121212121212121212121212121212121212|-1Pcrc.c eUMc.c 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|10e5","Europe/London|LMT GMT BST BDST|1.f 0 -10 -20|01212121212121212121212121212121212121212121212121232323232321212321212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-4VgnW.J 2KHdW.J Rc0 1fA0 14M0 1fc0 1g00 1co0 1dc0 1co0 1oo0 1400 1dc0 19A0 1io0 1io0 WM0 1o00 14o0 1o00 17c0 1io0 17c0 1fA0 1a00 1lc0 17c0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1cM0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1io0 1qM0 Dc0 2Rz0 Dc0 1zc0 Oo0 1zc0 Rc0 1wo0 17c0 1iM0 FA0 xB0 1fA0 1a00 14o0 bb0 LA0 xB0 Rc0 1wo0 11A0 1o00 17c0 1fA0 1a00 1fA0 1cM0 1fA0 1a00 17c0 1fA0 1a00 1io0 17c0 1lc0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1a00 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1tA0 IM0 90o0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|10e6","Europe/Belgrade|LMT CET CEST|-1m -10 -20|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3topm 2juLm 3IP0 WM0 1fA0 1cM0 1cM0 1rc0 Qo0 1vmo0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|12e5","Europe/Prague|LMT PMT CET CEST GMT|-V.I -V.I -10 -20 0|0123232323232323232423232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-4QbAV.I 1FDc0 XPaV.I 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 1cM0 1cM0 1qM0 11c0 mp0 xA0 mn0 17c0 1io0 17c0 1fc0 1ao0 1bNc0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|13e5","Europe/Bucharest|LMT BMT EET EEST|-1I.o -1I.o -20 -30|01232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-3awpI.o 1AU00 20LI.o RA0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1Axc0 On0 1fA0 1a10 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cK0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cL0 1cN0 1cL0 1fB0 1nX0 11E0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|19e5","Europe/Budapest|LMT CET CEST|-1g.k -10 -20|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-3cK1g.k 124Lg.k 11d0 1iO0 11A0 1o00 11A0 1oo0 11c0 1lc0 17c0 O1V0 3Nf0 WM0 1fA0 1cM0 1cM0 1oJ0 1dd0 1020 1fX0 1cp0 1cM0 1cM0 1cM0 1fA0 1a00 bhy0 Rb0 1wr0 Rc0 1C00 LA0 1C00 LA0 SNW0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cO0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|17e5","Europe/Zurich|LMT BMT CET CEST|-y.8 -t.K -10 -20|0123232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-4HyMy.8 1Dw04.m 1SfAt.K 11A0 1o00 11A0 1xG10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|38e4","Europe/Chisinau|LMT CMT BMT EET EEST CEST CET MSK MSD|-1T.k -1T -1I.o -20 -30 -20 -10 -30 -40|0123434343434343434345656578787878787878787878434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-3D8NT.k 1wNA0.k wGMa.A 20LI.o RA0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 27A0 2en0 39g0 WM0 1fA0 1cM0 V90 1t7z0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 gL0 WO0 1cM0 1cM0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1nX0 11D0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|67e4","Europe/Gibraltar|LMT GMT BST BDST CET CEST|l.o 0 -10 -20 -10 -20|0121212121212121212121212121212121212121212121212123232323232121232121212121212121212145454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-3BHbC.A 1ra1C.A Rc0 1fA0 14M0 1fc0 1g00 1co0 1dc0 1co0 1oo0 1400 1dc0 19A0 1io0 1io0 WM0 1o00 14o0 1o00 17c0 1io0 17c0 1fA0 1a00 1lc0 17c0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1cM0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1io0 1qM0 Dc0 2Rz0 Dc0 1zc0 Oo0 1zc0 Rc0 1wo0 17c0 1iM0 FA0 xB0 1fA0 1a00 14o0 bb0 LA0 xB0 Rc0 1wo0 11A0 1o00 17c0 1fA0 1a00 1fA0 1cM0 1fA0 1a00 17c0 1fA0 1a00 1io0 17c0 1lc0 17c0 1fA0 10Jz0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|30e3","Europe/Helsinki|LMT HMT EET EEST|-1D.N -1D.N -20 -30|01232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-3H0ND.N 1Iu00 OULD.N 1dA0 1xGq0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|12e5","Europe/Kaliningrad|LMT CET CEST EET EEST MSK MSD +03|-1m -10 -20 -20 -30 -30 -40 -30|012121212121212343565656565656565654343434343434343434343434343434343434343434373|-36Rdm UbXm 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 1cM0 390 7A0 1en0 12N0 1pbb0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|44e4","Europe/Kiev|LMT KMT EET MSK CEST CET MSD EEST|-22.4 -22.4 -20 -30 -20 -10 -40 -30|01234545363636363636363636367272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272|-3D8O2.4 1LUM0 eUo2.4 rnz0 2Hg0 WM0 1fA0 da0 1v4m0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 Db0 3220 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o10 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|34e5","Europe/Kirov|LMT +03 +04 +05 MSD MSK MSK|-3i.M -30 -40 -50 -40 -30 -40|0123232323232323232454524545454545454545454545454545454545454565|-22WM0 qH90 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 2pz0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|48e4","Europe/Lisbon|LMT WET WEST WEMT CET CEST|A.J 0 -10 -20 -10 -20|012121212121212121212121212121212121212121212321232123212321212121212121212121212121212121212121212124121212121212121212121212121212124545454212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2le00 aPX0 Sp0 M00 1vb0 SN0 1vb0 SN0 1vb0 Td0 1vb0 SN0 1vb0 6600 18o0 3I00 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 3I00 17c0 1cM0 1cM0 3Fc0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 1uo0 1c00 1dc0 1400 gL0 IM0 s10 U00 dX0 Rc0 pd0 Rc0 gL0 Oo0 pd0 Rc0 gL0 Oo0 pd0 14o0 1cM0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 oiK0 1cM0 1cM0 1fB0 1cM0 1cM0 1cM0 1fA0 1a00 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|27e5","Europe/Madrid|LMT WET WEST WEMT CET CEST|e.I 0 -10 -20 -10 -20|0121212121212121212321454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-2M0M0 G5z0 19B0 1cL0 1dd0 b1z0 18p0 3HX0 17d0 1fz0 1a10 1io0 1a00 1in0 17d0 iIn0 Hd0 1cL0 bb0 1200 2s20 14n0 5aL0 Mp0 1vz0 17d0 1in0 17d0 1in0 17d0 1in0 17d0 6hX0 11B0 XHX0 1a10 1fz0 1a10 19X0 1cN0 1fz0 1a10 1fC0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|62e5","Europe/Malta|LMT CET CEST|-W.4 -10 -20|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-35rcW.4 SXzW.4 Lz0 1cN0 1db0 1410 1on0 Wp0 1qL0 17d0 1cL0 M3B0 5M20 WM0 1fA0 1co0 17c0 1iM0 16m0 1de0 1lc0 14m0 1lc0 WO0 1qM0 GTW0 On0 1C10 LA0 1C00 LA0 1EM0 LA0 1C00 LA0 1zc0 Oo0 1C00 Oo0 1co0 1cM0 1lA0 Xc0 1qq0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1iN0 19z0 1fB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|42e4","Europe/Minsk|LMT MMT EET MSK CEST CET MSD EEST +03|-1O.g -1O -20 -30 -20 -10 -40 -30 -30|012345454363636363636363636372727272727272727272727272727272727272728|-3D8NO.g 1LUM0.g eUnO qNX0 3gQ0 WM0 1fA0 1cM0 Al0 1tsn0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 3Fc0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0|19e5","Europe/Paris|LMT PMT WET WEST CEST CET WEMT|-9.l -9.l 0 -10 -20 -10 -20|01232323232323232323232323232323232323232323232323234545463654545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545|-3bQ09.l MDA0 cNb9.l HA0 19A0 1iM0 11c0 1oo0 Wo0 1rc0 QM0 1EM0 UM0 1u00 10o0 1io0 1wo0 Rc0 1a00 1fA0 1cM0 1cM0 1io0 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 1fA0 1a00 1io0 17c0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Df0 Ik0 5M30 WM0 1fA0 1cM0 Vx0 hB0 1aq0 16M0 1ekn0 1cL0 1fC0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|11e6","Europe/Moscow|LMT MMT MMT MST MDST MSD MSK +05 EET EEST MSK|-2u.h -2u.h -2v.j -3v.j -4v.j -40 -30 -50 -20 -30 -40|01232434565756865656565656565656565698656565656565656565656565656565656565656a6|-3D8Ou.h 1sQM0 2pyW.W 1bA0 11X0 GN0 1Hb0 c4v.j ik0 3DA0 dz0 15A0 c10 2q10 iM10 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|16e6","Europe/Riga|LMT RMT LST EET MSK CEST CET MSD EEST|-1A.y -1A.y -2A.y -20 -30 -20 -10 -40 -30|0121213456565647474747474747474838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383|-3D8NA.y 1xde0 11A0 1iM0 ko0 gWm0 yDXA.y 2bX0 3fE0 WM0 1fA0 1cM0 1cM0 4m0 1sLy0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 1o00 11A0 1o00 11A0 1qM0 3oo0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|64e4","Europe/Rome|LMT RMT CET CEST|-N.U -N.U -10 -20|012323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-4aU0N.U 15snN.U T000 Lz0 1cN0 1db0 1410 1on0 Wp0 1qL0 17d0 1cL0 M3B0 5M20 WM0 1fA0 1cM0 16M0 1iM0 16m0 1de0 1lc0 14m0 1lc0 WO0 1qM0 GTW0 On0 1C10 LA0 1C00 LA0 1EM0 LA0 1C00 LA0 1zc0 Oo0 1C00 Oo0 1C00 LA0 1zc0 Oo0 1C00 LA0 1C00 LA0 1zc0 Oo0 1C00 Oo0 1zc0 Oo0 1fC0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|39e5","Europe/Samara|LMT +03 +04 +05|-3k.k -30 -40 -50|0123232323232323232121232323232323232323232323232323232323212|-22WM0 qH90 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 2y10 14m0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|12e5","Europe/Saratov|LMT +03 +04 +05|-34.i -30 -40 -50|012323232323232321212121212121212121212121212121212121212121212|-22WM0 qH90 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1cM0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 5810|","Europe/Simferopol|LMT SMT EET MSK CEST CET MSD EEST MSK|-2g.o -2g -20 -30 -20 -10 -40 -30 -40|0123454543636363636363636363272727636363727272727272727272727272727272727283|-3D8Og.o 1LUM0.o eUog rEn0 2qs0 WM0 1fA0 1cM0 3V0 1u0L0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1Q00 4eN0 1cM0 1cM0 1cM0 1cM0 dV0 WO0 1cM0 1cM0 1fy0 1o30 11B0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11z0 1nW0|33e4","Europe/Sofia|LMT IMT EET CET CEST EEST|-1x.g -1U.U -20 -10 -20 -30|0123434325252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252|-3D8Nx.g AiLA.k 1UFeU.U WM0 1fA0 1cM0 1cM0 1cN0 1mKH0 1dd0 1fb0 1ap0 1fb0 1a20 1fy0 1a30 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1nX0 11E0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|12e5","Europe/Tallinn|LMT TMT CET CEST EET MSK MSD EEST|-1D -1D -10 -20 -20 -30 -40 -30|0123214532323565656565656565657474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474747474|-3D8ND 1wI00 teD 11A0 1Ta0 4rXl KSLD 2FX0 2Jg0 WM0 1fA0 1cM0 18J0 1sTX0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o10 11A0 1qM0 5QM0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|41e4","Europe/Tirane|LMT CET CEST|-1j.k -10 -20|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2glBj.k 14pcj.k 5LC0 WM0 4M0 1fCK0 10n0 1op0 11z0 1pd0 11z0 1qN0 WL0 1qp0 Xb0 1qp0 Xb0 1qp0 11z0 1lB0 11z0 1qN0 11z0 1iN0 16n0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|42e4","Europe/Ulyanovsk|LMT +03 +04 +05 +02|-3d.A -30 -40 -50 -20|01232323232323232321214121212121212121212121212121212121212121212|-22WM0 qH90 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|13e5","Europe/Vienna|LMT CET CEST|-15.l -10 -20|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-36Rd5.l UbX5.l 11d0 1iO0 11A0 1o00 11A0 3KM0 14o0 LA00 6i00 WM0 1fA0 1cM0 1cM0 1cM0 400 2qM0 1ao0 1co0 1cM0 1io0 17c0 1gHa0 19X0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|18e5","Europe/Vilnius|LMT WMT KMT CET EET MSK CEST MSD EEST|-1F.g -1o -1z.A -10 -20 -30 -20 -40 -30|0123435636365757575757575757584848484848484848463648484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484848484|-3D8NF.g 1u5Ah.g 6ILM.o 1Ooz.A zz0 Mfd0 29W0 3is0 WM0 1fA0 1cM0 LV0 1tgL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11B0 1o00 11A0 1qM0 8io0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|54e4","Europe/Volgograd|LMT +03 +04 +05 MSD MSK MSK|-2V.E -30 -40 -50 -40 -30 -40|012323232323232324545452454545454545454545454545454545454545456525|-21IqV.E psLV.E 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1fA0 1cM0 2pz0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 9Jd0 5gn0|10e5","Europe/Warsaw|LMT WMT CET CEST EET EEST|-1o -1o -10 -20 -20 -30|0123232345423232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-3D8No 1qDA0 1LXo 11d0 1iO0 11A0 1o00 11A0 1on0 11A0 6zy0 HWP0 5IM0 WM0 1fA0 1cM0 1dz0 1mL0 1en0 15B0 1aq0 1nA0 11A0 1io0 17c0 1fA0 1a00 iDX0 LA0 1cM0 1cM0 1C00 Oo0 1cM0 1cM0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1C00 LA0 uso0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|17e5","Pacific/Honolulu|LMT HST HDT HWT HPT HST|av.q au 9u 9u 9u a0|01213415|-3061s.y 1uMdW.y 8x0 lef0 8wWu iAu 46p0|37e4","Indian/Chagos|LMT +05 +06|-4N.E -50 -60|012|-2xosN.E 3AGLN.E|30e2","Indian/Maldives|LMT MMT +05|-4S -4S -50|012|-3D8QS 3eLA0|35e4","Indian/Mauritius|LMT +04 +05|-3O -40 -50|012121|-2xorO 34unO 14L0 12kr0 11z0|15e4","Pacific/Kwajalein|LMT +11 +10 +09 -12 +12|-b9.k -b0 -a0 -90 c0 -c0|0123145|-2M0X9.k 1rDA9.k akp0 6Up0 12ry0 Wan0|14e3","Pacific/Chatham|LMT +1215 +1245 +1345|-cd.M -cf -cJ -dJ|0123232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323|-46jMd.M 37RbW.M 1adef IM0 1C00 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1qM0 14o0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1io0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00|600","Pacific/Apia|LMT LMT -1130 -11 -10 +14 +13|-cx.4 bq.U bu b0 a0 -e0 -d0|012343456565656565656565656|-38Fox.4 J1A0 1yW03.4 2rRbu 1ff0 1a00 CI0 AQ0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0|37e3","Pacific/Bougainville|LMT PMMT +10 +09 +11|-am.g -9M.w -a0 -90 -b0|012324|-3D8Wm.g AvAx.I 1TCLM.w 7CN0 2MQp0|18e4","Pacific/Efate|LMT +11 +12|-bd.g -b0 -c0|012121212121212121212121|-2l9nd.g 2uNXd.g Dc0 n610 1cL0 1cN0 1cL0 1fB0 19X0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 Lz0 1Nd0 An0|66e3","Pacific/Enderbury|-00 -12 -11 +13|0 c0 b0 -d0|0123|-1iIo0 1GsA0 B7X0|1","Pacific/Fakaofo|LMT -11 +13|bo.U b0 -d0|012|-2M0Az.4 4ufXz.4|483","Pacific/Fiji|LMT +12 +13|-bT.I -c0 -d0|012121212121212121212121212121|-2bUzT.I 3m8NT.I LA0 1EM0 IM0 nJc0 LA0 1o00 Rc0 1wo0 Ao0 1Nc0 Ao0 1Q00 xz0 1SN0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 20o0 pc0 2hc0 bc0|88e4","Pacific/Tarawa|LMT +12|-bw.4 -c0|01|-2M0Xw.4|29e3","Pacific/Galapagos|LMT -05 -06|5W.o 50 60|01212|-1yVS1.A 2dTz1.A gNd0 rz0|25e3","Pacific/Gambier|LMT -09|8X.M 90|01|-2jof0.c|125","Pacific/Guadalcanal|LMT +11|-aD.M -b0|01|-2joyD.M|11e4","Pacific/Guam|LMT LMT GST +09 GDT ChST|el -9D -a0 -90 -b0 -a0|0123242424242424242425|-54m9D 2glc0 1DFbD 6pB0 AhB0 3QL0 g2p0 3p91 WOX rX0 1zd0 Rb0 1wp0 Rb0 5xd0 rX0 5sN0 zb1 1C0X On0 ULb0|17e4","Pacific/Kiritimati|LMT -1040 -10 +14|at.k aE a0 -e0|0123|-2M0Bu.E 3bIMa.E B7Xk|51e2","Pacific/Kosrae|LMT LMT +11 +09 +10 +12|d8.4 -aP.U -b0 -90 -a0 -c0|0123243252|-54maP.U 2glc0 xsnP.U axC0 HBy0 akp0 axd0 WOK0 1bdz0|66e2","Pacific/Marquesas|LMT -0930|9i 9u|01|-2joeG|86e2","Pacific/Pago_Pago|LMT LMT SST|-cB.c bm.M b0|012|-38FoB.c J1A0|37e2","Pacific/Nauru|LMT +1130 +09 +12|-b7.E -bu -90 -c0|01213|-1Xdn7.E QCnB.E 7mqu 1lnbu|10e3","Pacific/Niue|LMT -1120 -11|bj.E bk b0|012|-FScE.k suo0.k|12e2","Pacific/Norfolk|LMT +1112 +1130 +1230 +11 +12|-bb.Q -bc -bu -cu -b0 -c0|0123245454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545|-2M0Xb.Q 21ILX.Q W01G Oo0 1COo0 9Jcu 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|25e4","Pacific/Noumea|LMT +11 +12|-b5.M -b0 -c0|01212121|-2l9n5.M 2EqM5.M xX0 1PB0 yn0 HeP0 Ao0|98e3","Pacific/Palau|LMT LMT +09|f2.4 -8V.U -90|012|-54m8V.U 2glc0|21e3","Pacific/Pitcairn|LMT -0830 -08|8E.k 8u 80|012|-2M0Dj.E 3UVXN.E|56","Pacific/Rarotonga|LMT LMT -1030 -0930 -10|-dk.U aD.4 au 9u a0|01234343434343434343434343434|-2Otpk.U 28zc0 13tbO.U IL0 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu Onu|13e3","Pacific/Tahiti|LMT -10|9W.g a0|01|-2joe1.I|18e4","Pacific/Tongatapu|LMT +1220 +13 +14|-cj.c -ck -d0 -e0|01232323232|-XbMj.c BgLX.c 1yndk 15A0 1wo0 xz0 1Q10 xz0 zWN0 s00|75e3"],"links":["Africa/Abidjan|Africa/Accra","Africa/Abidjan|Africa/Bamako","Africa/Abidjan|Africa/Banjul","Africa/Abidjan|Africa/Conakry","Africa/Abidjan|Africa/Dakar","Africa/Abidjan|Africa/Freetown","Africa/Abidjan|Africa/Lome","Africa/Abidjan|Africa/Nouakchott","Africa/Abidjan|Africa/Ouagadougou","Africa/Abidjan|Africa/Timbuktu","Africa/Abidjan|Atlantic/Reykjavik","Africa/Abidjan|Atlantic/St_Helena","Africa/Abidjan|Iceland","Africa/Cairo|Egypt","Africa/Johannesburg|Africa/Maseru","Africa/Johannesburg|Africa/Mbabane","Africa/Lagos|Africa/Bangui","Africa/Lagos|Africa/Brazzaville","Africa/Lagos|Africa/Douala","Africa/Lagos|Africa/Kinshasa","Africa/Lagos|Africa/Libreville","Africa/Lagos|Africa/Luanda","Africa/Lagos|Africa/Malabo","Africa/Lagos|Africa/Niamey","Africa/Lagos|Africa/Porto-Novo","Africa/Maputo|Africa/Blantyre","Africa/Maputo|Africa/Bujumbura","Africa/Maputo|Africa/Gaborone","Africa/Maputo|Africa/Harare","Africa/Maputo|Africa/Kigali","Africa/Maputo|Africa/Lubumbashi","Africa/Maputo|Africa/Lusaka","Africa/Nairobi|Africa/Addis_Ababa","Africa/Nairobi|Africa/Asmara","Africa/Nairobi|Africa/Asmera","Africa/Nairobi|Africa/Dar_es_Salaam","Africa/Nairobi|Africa/Djibouti","Africa/Nairobi|Africa/Kampala","Africa/Nairobi|Africa/Mogadishu","Africa/Nairobi|Indian/Antananarivo","Africa/Nairobi|Indian/Comoro","Africa/Nairobi|Indian/Mayotte","Africa/Tripoli|Libya","America/Adak|America/Atka","America/Adak|US/Aleutian","America/Anchorage|US/Alaska","America/Argentina/Buenos_Aires|America/Buenos_Aires","America/Argentina/Catamarca|America/Argentina/ComodRivadavia","America/Argentina/Catamarca|America/Catamarca","America/Argentina/Cordoba|America/Cordoba","America/Argentina/Cordoba|America/Rosario","America/Argentina/Jujuy|America/Jujuy","America/Argentina/Mendoza|America/Mendoza","America/Chicago|CST6CDT","America/Chicago|US/Central","America/Denver|America/Shiprock","America/Denver|MST7MDT","America/Denver|Navajo","America/Denver|US/Mountain","America/Detroit|US/Michigan","America/Edmonton|America/Yellowknife","America/Edmonton|Canada/Mountain","America/Fort_Wayne|America/Indiana/Indianapolis","America/Fort_Wayne|America/Indianapolis","America/Fort_Wayne|US/East-Indiana","America/Godthab|America/Nuuk","America/Halifax|Canada/Atlantic","America/Havana|Cuba","America/Indiana/Knox|America/Knox_IN","America/Indiana/Knox|US/Indiana-Starke","America/Iqaluit|America/Pangnirtung","America/Jamaica|Jamaica","America/Kentucky/Louisville|America/Louisville","America/Los_Angeles|PST8PDT","America/Los_Angeles|US/Pacific","America/Manaus|Brazil/West","America/Mazatlan|Mexico/BajaSur","America/Mexico_City|Mexico/General","America/New_York|EST5EDT","America/New_York|US/Eastern","America/Noronha|Brazil/DeNoronha","America/Panama|America/Atikokan","America/Panama|America/Cayman","America/Panama|America/Coral_Harbour","America/Panama|EST","America/Phoenix|America/Creston","America/Phoenix|MST","America/Phoenix|US/Arizona","America/Puerto_Rico|America/Anguilla","America/Puerto_Rico|America/Antigua","America/Puerto_Rico|America/Aruba","America/Puerto_Rico|America/Blanc-Sablon","America/Puerto_Rico|America/Curacao","America/Puerto_Rico|America/Dominica","America/Puerto_Rico|America/Grenada","America/Puerto_Rico|America/Guadeloupe","America/Puerto_Rico|America/Kralendijk","America/Puerto_Rico|America/Lower_Princes","America/Puerto_Rico|America/Marigot","America/Puerto_Rico|America/Montserrat","America/Puerto_Rico|America/Port_of_Spain","America/Puerto_Rico|America/St_Barthelemy","America/Puerto_Rico|America/St_Kitts","America/Puerto_Rico|America/St_Lucia","America/Puerto_Rico|America/St_Thomas","America/Puerto_Rico|America/St_Vincent","America/Puerto_Rico|America/Tortola","America/Puerto_Rico|America/Virgin","America/Regina|Canada/Saskatchewan","America/Rio_Branco|America/Porto_Acre","America/Rio_Branco|Brazil/Acre","America/Santiago|Chile/Continental","America/Sao_Paulo|Brazil/East","America/St_Johns|Canada/Newfoundland","America/Tijuana|America/Ensenada","America/Tijuana|America/Santa_Isabel","America/Tijuana|Mexico/BajaNorte","America/Toronto|America/Montreal","America/Toronto|America/Nassau","America/Toronto|America/Nipigon","America/Toronto|America/Thunder_Bay","America/Toronto|Canada/Eastern","America/Vancouver|Canada/Pacific","America/Whitehorse|Canada/Yukon","America/Winnipeg|America/Rainy_River","America/Winnipeg|Canada/Central","Asia/Ashgabat|Asia/Ashkhabad","Asia/Bangkok|Asia/Phnom_Penh","Asia/Bangkok|Asia/Vientiane","Asia/Bangkok|Indian/Christmas","Asia/Brunei|Asia/Kuching","Asia/Dhaka|Asia/Dacca","Asia/Dubai|Asia/Muscat","Asia/Dubai|Indian/Mahe","Asia/Dubai|Indian/Reunion","Asia/Ho_Chi_Minh|Asia/Saigon","Asia/Hong_Kong|Hongkong","Asia/Jerusalem|Asia/Tel_Aviv","Asia/Jerusalem|Israel","Asia/Kathmandu|Asia/Katmandu","Asia/Kolkata|Asia/Calcutta","Asia/Kuala_Lumpur|Asia/Singapore","Asia/Kuala_Lumpur|Singapore","Asia/Macau|Asia/Macao","Asia/Makassar|Asia/Ujung_Pandang","Asia/Nicosia|Europe/Nicosia","Asia/Qatar|Asia/Bahrain","Asia/Rangoon|Asia/Yangon","Asia/Rangoon|Indian/Cocos","Asia/Riyadh|Antarctica/Syowa","Asia/Riyadh|Asia/Aden","Asia/Riyadh|Asia/Kuwait","Asia/Seoul|ROK","Asia/Shanghai|Asia/Chongqing","Asia/Shanghai|Asia/Chungking","Asia/Shanghai|Asia/Harbin","Asia/Shanghai|PRC","Asia/Taipei|ROC","Asia/Tehran|Iran","Asia/Thimphu|Asia/Thimbu","Asia/Tokyo|Japan","Asia/Ulaanbaatar|Asia/Choibalsan","Asia/Ulaanbaatar|Asia/Ulan_Bator","Asia/Urumqi|Asia/Kashgar","Atlantic/Faroe|Atlantic/Faeroe","Australia/Adelaide|Australia/South","Australia/Brisbane|Australia/Queensland","Australia/Broken_Hill|Australia/Yancowinna","Australia/Darwin|Australia/North","Australia/Hobart|Australia/Currie","Australia/Hobart|Australia/Tasmania","Australia/Lord_Howe|Australia/LHI","Australia/Melbourne|Australia/Victoria","Australia/Perth|Australia/West","Australia/Sydney|Australia/ACT","Australia/Sydney|Australia/Canberra","Australia/Sydney|Australia/NSW","Etc/GMT-0|Etc/GMT","Etc/GMT-0|Etc/GMT+0","Etc/GMT-0|Etc/GMT0","Etc/GMT-0|Etc/Greenwich","Etc/GMT-0|GMT","Etc/GMT-0|GMT+0","Etc/GMT-0|GMT-0","Etc/GMT-0|GMT0","Etc/GMT-0|Greenwich","Etc/UTC|Etc/UCT","Etc/UTC|Etc/Universal","Etc/UTC|Etc/Zulu","Etc/UTC|UCT","Etc/UTC|UTC","Etc/UTC|Universal","Etc/UTC|Zulu","Europe/Athens|EET","Europe/Belgrade|Europe/Ljubljana","Europe/Belgrade|Europe/Podgorica","Europe/Belgrade|Europe/Sarajevo","Europe/Belgrade|Europe/Skopje","Europe/Belgrade|Europe/Zagreb","Europe/Berlin|Arctic/Longyearbyen","Europe/Berlin|Atlantic/Jan_Mayen","Europe/Berlin|Europe/Copenhagen","Europe/Berlin|Europe/Oslo","Europe/Berlin|Europe/Stockholm","Europe/Brussels|CET","Europe/Brussels|Europe/Amsterdam","Europe/Brussels|Europe/Luxembourg","Europe/Brussels|MET","Europe/Chisinau|Europe/Tiraspol","Europe/Dublin|Eire","Europe/Helsinki|Europe/Mariehamn","Europe/Istanbul|Asia/Istanbul","Europe/Istanbul|Turkey","Europe/Kiev|Europe/Kyiv","Europe/Kiev|Europe/Uzhgorod","Europe/Kiev|Europe/Zaporozhye","Europe/Lisbon|Portugal","Europe/Lisbon|WET","Europe/London|Europe/Belfast","Europe/London|Europe/Guernsey","Europe/London|Europe/Isle_of_Man","Europe/London|Europe/Jersey","Europe/London|GB","Europe/London|GB-Eire","Europe/Moscow|W-SU","Europe/Paris|Europe/Monaco","Europe/Prague|Europe/Bratislava","Europe/Rome|Europe/San_Marino","Europe/Rome|Europe/Vatican","Europe/Warsaw|Poland","Europe/Zurich|Europe/Busingen","Europe/Zurich|Europe/Vaduz","Indian/Maldives|Indian/Kerguelen","Pacific/Auckland|Antarctica/McMurdo","Pacific/Auckland|Antarctica/South_Pole","Pacific/Auckland|NZ","Pacific/Chatham|NZ-CHAT","Pacific/Easter|Chile/EasterIsland","Pacific/Enderbury|Pacific/Kanton","Pacific/Guadalcanal|Pacific/Pohnpei","Pacific/Guadalcanal|Pacific/Ponape","Pacific/Guam|Pacific/Saipan","Pacific/Honolulu|HST","Pacific/Honolulu|Pacific/Johnston","Pacific/Honolulu|US/Hawaii","Pacific/Kwajalein|Kwajalein","Pacific/Pago_Pago|Pacific/Midway","Pacific/Pago_Pago|Pacific/Samoa","Pacific/Pago_Pago|US/Samoa","Pacific/Port_Moresby|Antarctica/DumontDUrville","Pacific/Port_Moresby|Pacific/Chuuk","Pacific/Port_Moresby|Pacific/Truk","Pacific/Port_Moresby|Pacific/Yap","Pacific/Tarawa|Pacific/Funafuti","Pacific/Tarawa|Pacific/Majuro","Pacific/Tarawa|Pacific/Wake","Pacific/Tarawa|Pacific/Wallis"],"countries":["AD|Europe/Andorra","AE|Asia/Dubai","AF|Asia/Kabul","AG|America/Puerto_Rico America/Antigua","AI|America/Puerto_Rico America/Anguilla","AL|Europe/Tirane","AM|Asia/Yerevan","AO|Africa/Lagos Africa/Luanda","AQ|Antarctica/Casey Antarctica/Davis Antarctica/Mawson Antarctica/Palmer Antarctica/Rothera Antarctica/Troll Antarctica/Vostok Pacific/Auckland Pacific/Port_Moresby Asia/Riyadh Asia/Singapore Antarctica/McMurdo Antarctica/DumontDUrville Antarctica/Syowa","AR|America/Argentina/Buenos_Aires America/Argentina/Cordoba America/Argentina/Salta America/Argentina/Jujuy America/Argentina/Tucuman America/Argentina/Catamarca America/Argentina/La_Rioja America/Argentina/San_Juan America/Argentina/Mendoza America/Argentina/San_Luis America/Argentina/Rio_Gallegos America/Argentina/Ushuaia","AS|Pacific/Pago_Pago","AT|Europe/Vienna","AU|Australia/Lord_Howe Antarctica/Macquarie Australia/Hobart Australia/Melbourne Australia/Sydney Australia/Broken_Hill Australia/Brisbane Australia/Lindeman Australia/Adelaide Australia/Darwin Australia/Perth Australia/Eucla Asia/Tokyo","AW|America/Puerto_Rico America/Aruba","AX|Europe/Helsinki Europe/Mariehamn","AZ|Asia/Baku","BA|Europe/Belgrade Europe/Sarajevo","BB|America/Barbados","BD|Asia/Dhaka","BE|Europe/Brussels","BF|Africa/Abidjan Africa/Ouagadougou","BG|Europe/Sofia","BH|Asia/Qatar Asia/Bahrain","BI|Africa/Maputo Africa/Bujumbura","BJ|Africa/Lagos Africa/Porto-Novo","BL|America/Puerto_Rico America/St_Barthelemy","BM|Atlantic/Bermuda","BN|Asia/Kuching Asia/Brunei","BO|America/La_Paz","BQ|America/Puerto_Rico America/Kralendijk","BR|America/Noronha America/Belem America/Fortaleza America/Recife America/Araguaina America/Maceio America/Bahia America/Sao_Paulo America/Campo_Grande America/Cuiaba America/Santarem America/Porto_Velho America/Boa_Vista America/Manaus America/Eirunepe America/Rio_Branco","BS|America/Toronto America/Nassau","BT|Asia/Thimphu","BW|Africa/Maputo Africa/Gaborone","BY|Europe/Minsk","BZ|America/Belize","CA|America/St_Johns America/Halifax America/Glace_Bay America/Moncton America/Goose_Bay America/Toronto America/Iqaluit America/Winnipeg America/Resolute America/Rankin_Inlet America/Regina America/Swift_Current America/Edmonton America/Cambridge_Bay America/Inuvik America/Dawson_Creek America/Fort_Nelson America/Whitehorse America/Dawson America/Vancouver America/Panama America/Puerto_Rico America/Phoenix America/Blanc-Sablon America/Atikokan America/Creston","CC|Asia/Yangon Indian/Cocos","CD|Africa/Maputo Africa/Lagos Africa/Kinshasa Africa/Lubumbashi","CF|Africa/Lagos Africa/Bangui","CG|Africa/Lagos Africa/Brazzaville","CH|Europe/Zurich","CI|Africa/Abidjan","CK|Pacific/Rarotonga","CL|America/Santiago America/Coyhaique America/Punta_Arenas Pacific/Easter","CM|Africa/Lagos Africa/Douala","CN|Asia/Shanghai Asia/Urumqi","CO|America/Bogota","CR|America/Costa_Rica","CU|America/Havana","CV|Atlantic/Cape_Verde","CW|America/Puerto_Rico America/Curacao","CX|Asia/Bangkok Indian/Christmas","CY|Asia/Nicosia Asia/Famagusta","CZ|Europe/Prague","DE|Europe/Zurich Europe/Berlin Europe/Busingen","DJ|Africa/Nairobi Africa/Djibouti","DK|Europe/Berlin Europe/Copenhagen","DM|America/Puerto_Rico America/Dominica","DO|America/Santo_Domingo","DZ|Africa/Algiers","EC|America/Guayaquil Pacific/Galapagos","EE|Europe/Tallinn","EG|Africa/Cairo","EH|Africa/El_Aaiun","ER|Africa/Nairobi Africa/Asmara","ES|Europe/Madrid Africa/Ceuta Atlantic/Canary","ET|Africa/Nairobi Africa/Addis_Ababa","FI|Europe/Helsinki","FJ|Pacific/Fiji","FK|Atlantic/Stanley","FM|Pacific/Kosrae Pacific/Port_Moresby Pacific/Guadalcanal Pacific/Chuuk Pacific/Pohnpei","FO|Atlantic/Faroe","FR|Europe/Paris","GA|Africa/Lagos Africa/Libreville","GB|Europe/London","GD|America/Puerto_Rico America/Grenada","GE|Asia/Tbilisi","GF|America/Cayenne","GG|Europe/London Europe/Guernsey","GH|Africa/Abidjan Africa/Accra","GI|Europe/Gibraltar","GL|America/Nuuk America/Danmarkshavn America/Scoresbysund America/Thule","GM|Africa/Abidjan Africa/Banjul","GN|Africa/Abidjan Africa/Conakry","GP|America/Puerto_Rico America/Guadeloupe","GQ|Africa/Lagos Africa/Malabo","GR|Europe/Athens","GS|Atlantic/South_Georgia","GT|America/Guatemala","GU|Pacific/Guam","GW|Africa/Bissau","GY|America/Guyana","HK|Asia/Hong_Kong","HN|America/Tegucigalpa","HR|Europe/Belgrade Europe/Zagreb","HT|America/Port-au-Prince","HU|Europe/Budapest","ID|Asia/Jakarta Asia/Pontianak Asia/Makassar Asia/Jayapura","IE|Europe/Dublin","IL|Asia/Jerusalem","IM|Europe/London Europe/Isle_of_Man","IN|Asia/Kolkata","IO|Indian/Chagos","IQ|Asia/Baghdad","IR|Asia/Tehran","IS|Africa/Abidjan Atlantic/Reykjavik","IT|Europe/Rome","JE|Europe/London Europe/Jersey","JM|America/Jamaica","JO|Asia/Amman","JP|Asia/Tokyo","KE|Africa/Nairobi","KG|Asia/Bishkek","KH|Asia/Bangkok Asia/Phnom_Penh","KI|Pacific/Tarawa Pacific/Kanton Pacific/Kiritimati","KM|Africa/Nairobi Indian/Comoro","KN|America/Puerto_Rico America/St_Kitts","KP|Asia/Pyongyang","KR|Asia/Seoul","KW|Asia/Riyadh Asia/Kuwait","KY|America/Panama America/Cayman","KZ|Asia/Almaty Asia/Qyzylorda Asia/Qostanay Asia/Aqtobe Asia/Aqtau Asia/Atyrau Asia/Oral","LA|Asia/Bangkok Asia/Vientiane","LB|Asia/Beirut","LC|America/Puerto_Rico America/St_Lucia","LI|Europe/Zurich Europe/Vaduz","LK|Asia/Colombo","LR|Africa/Monrovia","LS|Africa/Johannesburg Africa/Maseru","LT|Europe/Vilnius","LU|Europe/Brussels Europe/Luxembourg","LV|Europe/Riga","LY|Africa/Tripoli","MA|Africa/Casablanca","MC|Europe/Paris Europe/Monaco","MD|Europe/Chisinau","ME|Europe/Belgrade Europe/Podgorica","MF|America/Puerto_Rico America/Marigot","MG|Africa/Nairobi Indian/Antananarivo","MH|Pacific/Tarawa Pacific/Kwajalein Pacific/Majuro","MK|Europe/Belgrade Europe/Skopje","ML|Africa/Abidjan Africa/Bamako","MM|Asia/Yangon","MN|Asia/Ulaanbaatar Asia/Hovd","MO|Asia/Macau","MP|Pacific/Guam Pacific/Saipan","MQ|America/Martinique","MR|Africa/Abidjan Africa/Nouakchott","MS|America/Puerto_Rico America/Montserrat","MT|Europe/Malta","MU|Indian/Mauritius","MV|Indian/Maldives","MW|Africa/Maputo Africa/Blantyre","MX|America/Mexico_City America/Cancun America/Merida America/Monterrey America/Matamoros America/Chihuahua America/Ciudad_Juarez America/Ojinaga America/Mazatlan America/Bahia_Banderas America/Hermosillo America/Tijuana","MY|Asia/Kuching Asia/Singapore Asia/Kuala_Lumpur","MZ|Africa/Maputo","NA|Africa/Windhoek","NC|Pacific/Noumea","NE|Africa/Lagos Africa/Niamey","NF|Pacific/Norfolk","NG|Africa/Lagos","NI|America/Managua","NL|Europe/Brussels Europe/Amsterdam","NO|Europe/Berlin Europe/Oslo","NP|Asia/Kathmandu","NR|Pacific/Nauru","NU|Pacific/Niue","NZ|Pacific/Auckland Pacific/Chatham","OM|Asia/Dubai Asia/Muscat","PA|America/Panama","PE|America/Lima","PF|Pacific/Tahiti Pacific/Marquesas Pacific/Gambier","PG|Pacific/Port_Moresby Pacific/Bougainville","PH|Asia/Manila","PK|Asia/Karachi","PL|Europe/Warsaw","PM|America/Miquelon","PN|Pacific/Pitcairn","PR|America/Puerto_Rico","PS|Asia/Gaza Asia/Hebron","PT|Europe/Lisbon Atlantic/Madeira Atlantic/Azores","PW|Pacific/Palau","PY|America/Asuncion","QA|Asia/Qatar","RE|Asia/Dubai Indian/Reunion","RO|Europe/Bucharest","RS|Europe/Belgrade","RU|Europe/Kaliningrad Europe/Moscow Europe/Simferopol Europe/Kirov Europe/Volgograd Europe/Astrakhan Europe/Saratov Europe/Ulyanovsk Europe/Samara Asia/Yekaterinburg Asia/Omsk Asia/Novosibirsk Asia/Barnaul Asia/Tomsk Asia/Novokuznetsk Asia/Krasnoyarsk Asia/Irkutsk Asia/Chita Asia/Yakutsk Asia/Khandyga Asia/Vladivostok Asia/Ust-Nera Asia/Magadan Asia/Sakhalin Asia/Srednekolymsk Asia/Kamchatka Asia/Anadyr","RW|Africa/Maputo Africa/Kigali","SA|Asia/Riyadh","SB|Pacific/Guadalcanal","SC|Asia/Dubai Indian/Mahe","SD|Africa/Khartoum","SE|Europe/Berlin Europe/Stockholm","SG|Asia/Singapore","SH|Africa/Abidjan Atlantic/St_Helena","SI|Europe/Belgrade Europe/Ljubljana","SJ|Europe/Berlin Arctic/Longyearbyen","SK|Europe/Prague Europe/Bratislava","SL|Africa/Abidjan Africa/Freetown","SM|Europe/Rome Europe/San_Marino","SN|Africa/Abidjan Africa/Dakar","SO|Africa/Nairobi Africa/Mogadishu","SR|America/Paramaribo","SS|Africa/Juba","ST|Africa/Sao_Tome","SV|America/El_Salvador","SX|America/Puerto_Rico America/Lower_Princes","SY|Asia/Damascus","SZ|Africa/Johannesburg Africa/Mbabane","TC|America/Grand_Turk","TD|Africa/Ndjamena","TF|Asia/Dubai Indian/Maldives Indian/Kerguelen","TG|Africa/Abidjan Africa/Lome","TH|Asia/Bangkok","TJ|Asia/Dushanbe","TK|Pacific/Fakaofo","TL|Asia/Dili","TM|Asia/Ashgabat","TN|Africa/Tunis","TO|Pacific/Tongatapu","TR|Europe/Istanbul","TT|America/Puerto_Rico America/Port_of_Spain","TV|Pacific/Tarawa Pacific/Funafuti","TW|Asia/Taipei","TZ|Africa/Nairobi Africa/Dar_es_Salaam","UA|Europe/Simferopol Europe/Kyiv","UG|Africa/Nairobi Africa/Kampala","UM|Pacific/Pago_Pago Pacific/Tarawa Pacific/Midway Pacific/Wake","US|America/New_York America/Detroit America/Kentucky/Louisville America/Kentucky/Monticello America/Indiana/Indianapolis America/Indiana/Vincennes America/Indiana/Winamac America/Indiana/Marengo America/Indiana/Petersburg America/Indiana/Vevay America/Chicago America/Indiana/Tell_City America/Indiana/Knox America/Menominee America/North_Dakota/Center America/North_Dakota/New_Salem America/North_Dakota/Beulah America/Denver America/Boise America/Phoenix America/Los_Angeles America/Anchorage America/Juneau America/Sitka America/Metlakatla America/Yakutat America/Nome America/Adak Pacific/Honolulu","UY|America/Montevideo","UZ|Asia/Samarkand Asia/Tashkent","VA|Europe/Rome Europe/Vatican","VC|America/Puerto_Rico America/St_Vincent","VE|America/Caracas","VG|America/Puerto_Rico America/Tortola","VI|America/Puerto_Rico America/St_Thomas","VN|Asia/Bangkok Asia/Ho_Chi_Minh","VU|Pacific/Efate","WF|Pacific/Tarawa Pacific/Wallis","WS|Pacific/Apia","YE|Asia/Riyadh Asia/Aden","YT|Africa/Nairobi Indian/Mayotte","ZA|Africa/Johannesburg","ZM|Africa/Maputo Africa/Lusaka","ZW|Africa/Maputo Africa/Harare"]}')},743:(M,z,b)=>{(M.exports=b(639)).tz.load(b(681))}}]); \ No newline at end of file diff --git a/providers/fab/src/airflow/providers/fab/www/static/dist/743.fc7a7c6ef9d09365976e.js.LICENSE.txt b/providers/fab/src/airflow/providers/fab/www/static/dist/743.935ed3d26e56ed8f63d3.js.LICENSE.txt similarity index 100% rename from providers/fab/src/airflow/providers/fab/www/static/dist/743.fc7a7c6ef9d09365976e.js.LICENSE.txt rename to providers/fab/src/airflow/providers/fab/www/static/dist/743.935ed3d26e56ed8f63d3.js.LICENSE.txt diff --git a/providers/fab/src/airflow/providers/fab/www/static/dist/airflowDefaultTheme.ff5a35f322070b094aa2.css b/providers/fab/src/airflow/providers/fab/www/static/dist/airflowDefaultTheme.ff5a35f322070b094aa2.css index 0e29eda7dac79..dc37b46e63f68 100644 --- a/providers/fab/src/airflow/providers/fab/www/static/dist/airflowDefaultTheme.ff5a35f322070b094aa2.css +++ b/providers/fab/src/airflow/providers/fab/www/static/dist/airflowDefaultTheme.ff5a35f322070b094aa2.css @@ -30,4 +30,4 @@ /*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}html[data-color-scheme=dark]{filter:invert(100%) hue-rotate(180deg) saturate(90%) contrast(85%)}#dark_icon,#light_icon{display:none}html[data-color-scheme=dark] #dark_icon{display:block}html[data-color-scheme=dark] #light_icon,html[data-color-scheme=light] #dark_icon{display:none}html[data-color-scheme=light] #light_icon{display:block}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:initial}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:initial}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:initial;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:none;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} -/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{background:#0000!important;box-shadow:none!important;color:#000!important;text-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#cbcbcb!important}.label{border:1px solid #51504f}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #f0f0f0!important}}*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:12px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{color:#51504f;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a,a code{color:#365f84;text-decoration:none}a:focus,a:hover{color:#017cee;text-decoration:none}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;height:auto;max-width:100%}.img-rounded{border-radius:6px}.img-thumbnail{background-color:#fafafa;border:1px solid #ddd;border-radius:4px;display:inline-block;height:auto;line-height:1.428571429;max-width:100%;padding:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{border:0;border-top:2px solid #f0f0f0;margin-bottom:15px;margin-top:15px}.sr-only{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{height:auto;margin:0;overflow:visible;position:static;width:auto;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{color:inherit;font-family:inherit;font-weight:500;line-height:1.1}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{color:#777;font-weight:400;line-height:1}.h1,.h2,.h3,h1,h2,h3{margin-bottom:10px;margin-top:20px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-bottom:10px;margin-top:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{font-size:16px;font-weight:300;line-height:1.4;margin-bottom:20px}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#cbcbcb}.text-primary{color:#017cee}a.text-primary:hover{color:#002e33}.text-success{color:#1b8e49}a.text-success:hover{color:#366f4c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#e43921}a.text-danger:hover{color:#843534}.bg-primary{background-color:#017cee;color:#fff}a.bg-primary:hover{background-color:#002e33}.bg-success{background-color:#bfebd1}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{border-bottom:1px solid #eee;margin:40px 0 20px;padding-bottom:9px}ol,ul{margin-bottom:10px;margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-inline,.list-unstyled{list-style:none;padding-left:0}.list-inline{margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-bottom:20px;margin-top:0}dd,dt{line-height:1.428571429}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{clear:left;float:left;overflow:hidden;text-align:right;text-overflow:ellipsis;white-space:nowrap;width:160px}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{border-bottom:1px dotted #777;cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{border-left:5px solid #eee;font-size:17.5px;margin:0 0 20px;padding:10px 20px}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{color:#777;display:block;font-size:80%;line-height:1.428571429}blockquote .small:before,blockquote footer:before,blockquote small:before{content:"\2014 \00A0"}.blockquote-reverse,blockquote.pull-right{border-left:0;border-right:5px solid #eee;padding-left:0;padding-right:15px;text-align:right}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:""}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:"\00A0 \2014"}address{font-style:normal;line-height:1.428571429;margin-bottom:20px}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Courier New,monospace}code{background-color:#e2e2e2;border-radius:4px;color:#51504f}code,kbd{font-size:90%;padding:2px 4px}kbd{background-color:#51504f;border-radius:3px;box-shadow:inset 0 -1px 0 #00000040;color:#fff}kbd kbd{box-shadow:none;font-size:100%;font-weight:700;padding:0}pre{display:block;font-size:13px;line-height:1.428571429;margin:0 0 10px;padding:9.5px;word-break:break-all;word-wrap:break-word;background-color:#f0f0f0;border:0;border-radius:4px;color:#51504f}pre code{background-color:initial;border-radius:0;color:inherit;font-size:inherit;padding:0;white-space:pre-wrap}.pre-scrollable{max-height:340px;overflow-y:auto}.container{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:15px;padding-right:15px;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666666666666%}.col-xs-10{width:83.33333333333334%}.col-xs-9{width:75%}.col-xs-8{width:66.66666666666666%}.col-xs-7{width:58.333333333333336%}.col-xs-6{width:50%}.col-xs-5{width:41.66666666666667%}.col-xs-4{width:33.33333333333333%}.col-xs-3{width:25%}.col-xs-2{width:16.666666666666664%}.col-xs-1{width:8.333333333333332%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666666666666%}.col-xs-pull-10{right:83.33333333333334%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666666666666%}.col-xs-pull-7{right:58.333333333333336%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666666666667%}.col-xs-pull-4{right:33.33333333333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.666666666666664%}.col-xs-pull-1{right:8.333333333333332%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666666666666%}.col-xs-push-10{left:83.33333333333334%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666666666666%}.col-xs-push-7{left:58.333333333333336%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666666666667%}.col-xs-push-4{left:33.33333333333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.666666666666664%}.col-xs-push-1{left:8.333333333333332%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666666666666%}.col-xs-offset-10{margin-left:83.33333333333334%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666666666666%}.col-xs-offset-7{margin-left:58.333333333333336%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666666666667%}.col-xs-offset-4{margin-left:33.33333333333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.666666666666664%}.col-xs-offset-1{margin-left:8.333333333333332%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}table{background-color:initial}caption{color:#777;padding-bottom:8px;padding-top:8px}caption,th{text-align:left}.table{margin-bottom:20px;max-width:100%;width:100%}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{border-top:1px solid #ddd;line-height:1.428571429;padding:8px;vertical-align:middle}.table>thead>tr>th{background-color:#f0f0f0;border-bottom:1px solid #fff;vertical-align:bottom;white-space:nowrap}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>tbody+tbody,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table .table{background-color:#f0f0f0}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #f0f0f0}.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>th{border:0}.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td,.table-bordered>thead>tr>td{border:0;border-top:1px solid #f0f0f0}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#fff}.table-striped>tbody>tr:nth-child(2n){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{display:table-column;float:none;position:static}table td[class*=col-],table th[class*=col-]{display:table-cell;float:none;position:static}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#bfebd1}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow:visible}@media screen and (max-width:767px){.table-responsive{border:1px solid #ddd;margin-bottom:15px;width:100%}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{margin:0;min-width:0}fieldset,legend{border:0;padding:0}legend{border-bottom:1px solid #e5e5e5;color:#51504f;display:block;font-size:21px;line-height:inherit;margin-bottom:20px;width:100%}label{display:inline-block;font-weight:700;margin-bottom:5px;max-width:100%}input[type=checkbox],input[type=radio]{line-height:normal;margin:4px 0 0;margin-top:1px\9}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{padding-top:7px}.form-control,output{color:#555;display:block;font-size:14px;line-height:1.428571429}.form-control{background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);height:34px;padding:6px 12px;-webkit-transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-o-transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}.form-control:focus{border-color:#66afe9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px #66afe999;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px #66afe999;outline:0}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;color:#cbcbcb;cursor:not-allowed;opacity:1}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=datetime-local],input[type=month],input[type=time]{line-height:34px}input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{display:block;margin-bottom:10px;margin-top:10px;position:relative}.checkbox label,.radio label{cursor:pointer;font-weight:400;margin-bottom:0;min-height:20px;padding-left:20px}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{margin-left:-20px;margin-top:4px\9;position:absolute}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{cursor:pointer;display:inline-block;font-weight:400;margin-bottom:0;padding-left:20px;vertical-align:middle}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-left:10px;margin-top:0}.checkbox-inline.disabled,.checkbox.disabled label,.radio-inline.disabled,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio label,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.form-control-static{margin-bottom:0;padding-bottom:7px;padding-top:7px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{border-radius:3px;font-size:12px;height:30px;line-height:1.5;padding:5px 10px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{border-radius:3px;font-size:12px;height:30px;line-height:1.5;padding:5px 10px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.input-lg{border-radius:6px;font-size:18px;height:46px;line-height:1.33;padding:10px 16px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{border-radius:6px;font-size:18px;height:46px;line-height:1.33;padding:10px 16px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{display:block;height:34px;line-height:34px;pointer-events:none;position:absolute;right:0;text-align:center;top:0;width:34px;z-index:2}.input-lg+.form-control-feedback{height:46px;line-height:46px;width:46px}.input-sm+.form-control-feedback{height:30px;line-height:30px;width:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#1b8e49}.has-success .form-control{border-color:#1b8e49;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#366f4c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{background-color:#bfebd1;border-color:#1b8e49;color:#1b8e49}.has-success .form-control-feedback{color:#1b8e49}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{background-color:#fcf8e3;border-color:#8a6d3b;color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#e43921}.has-error .form-control{border-color:#e43921;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{background-color:#f2dede;border-color:#e43921;color:#e43921}.has-error .form-control-feedback{color:#e43921}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{color:#737373;display:block;margin-bottom:10px;margin-top:5px}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;vertical-align:middle;width:auto}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-bottom:0;margin-top:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{margin-left:0;position:relative}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{margin-bottom:0;margin-top:0;padding-top:7px}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{margin-bottom:0;padding-top:7px;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{background:#fff;border:1px solid #017cee;border-radius:4px;color:#017cee;cursor:pointer;display:inline-block;font-size:14px;font-weight:400;line-height:1.428571429;margin-bottom:0;padding:6px 12px;text-align:center;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;white-space:nowrap}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{background-color:#c0defb;color:#017cee;text-decoration:none}.btn.active,.btn:active{background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125);outline:0}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed;opacity:.5;pointer-events:none}.btn-icon-only{padding:6px}.btn-default{background-color:#fff;border-color:#ccc;color:#365f84}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{background-color:#f0f0f0;border-color:#adadad;color:#017cee}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{background-color:#51504f;color:#fff}.btn-primary{background-color:#017cee;border-color:#017cee;color:#fff}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{background-color:#0cb6ff;border-color:#0cb6ff;color:#fff}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#017cee;border-color:#00454c}.btn-primary .badge{background-color:#fff;color:#017cee}.btn-primary.active .badge,.btn-primary.focus .badge,.btn-primary:active .badge,.btn-primary:focus .badge,.btn-primary:hover .badge,.open>.dropdown-toggle.btn-primary .badge{color:#0cb6ff}.btn-success{background-color:#00ad46;border-color:#38a047;color:#fff}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{background-color:#328d3e;border-color:#287333;color:#fff}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#00ad46;border-color:#00ad46}.btn-success .badge{background-color:#fff;color:#00ad46}.btn-info{background-color:#00d1c1;border-color:#00b8a9;color:#fff}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{background-color:#009e92;border-color:#007a71;color:#fff}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#00d1c1;border-color:#00b8a9}.btn-info .badge{background-color:#fff;color:#00d1c1}.btn-warning{background-color:#ffb400;border-color:#e6a200;color:#fff}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{background-color:#cc9000;border-color:#a87700;color:#fff}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#ffb400;border-color:#e6a200}.btn-warning .badge{background-color:#fff;color:#ffb400}.btn-danger{background-color:#ff5a5f;border-color:#ff4146;color:#fff}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{background-color:#ff272e;border-color:#ff030b;color:#fff}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#ff5a5f;border-color:#ff4146}.btn-danger .badge{background-color:#fff;color:#ff5a5f}.btn-link{border-radius:0;color:#017cee;font-weight:400}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:initial;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:#0000}.btn-link:focus,.btn-link:hover{background-color:initial;color:#004c54;text-decoration:underline}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{border-radius:6px;font-size:18px;line-height:1.33;padding:10px 16px}.btn-group-lg>.btn.btn-icon-only,.btn-lg.btn-icon-only{padding:10px}.btn-group-sm>.btn,.btn-sm{border-radius:3px;font-size:12px;line-height:1.5;padding:5px 10px}.btn-group-sm>.btn.btn-icon-only,.btn-sm.btn-icon-only{padding:5px}.btn-group-xs>.btn,.btn-xs{border-radius:3px;font-size:12px;line-height:1.5;padding:1px 5px}.btn-group-xs>.btn.btn-icon-only,.btn-xs.btn-icon-only{padding:1px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{height:0;overflow:hidden;position:relative;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-timing-function:ease;transition-timing-function:ease}.caret{border-left:4px solid #0000;border-right:4px solid #0000;border-top:4px solid;display:inline-block;height:0;margin-left:2px;vertical-align:middle;width:0}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{background-clip:padding-box;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);display:none;float:left;font-size:14px;left:0;list-style:none;margin:2px 0 0;min-width:160px;padding:5px 0;position:absolute;text-align:left;top:100%;z-index:1000}.dropdown-menu.pull-right{left:auto;right:0}.dropdown-menu .divider{background-color:#e5e5e5;height:1px;margin:9px 0;overflow:hidden}.dropdown-menu>li>a,.dropdown-menu>li>form>button{clear:both;color:#51504f;display:block;font-weight:400;line-height:1.428571429;max-width:100%;padding:3px 20px;text-align:left;white-space:nowrap;width:100%}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover,.dropdown-menu>li>form>button:focus,.dropdown-menu>li>form>button:hover{background-color:#f5f5f5;color:#262626;text-decoration:none}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#017cee;color:#fff;outline:0;text-decoration:none}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{background-color:initial;background-image:none;cursor:not-allowed;text-decoration:none}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{color:#777;display:block;font-size:12px;line-height:1.428571429;padding:3px 20px;white-space:nowrap}.dropdown-backdrop{bottom:0;left:0;position:fixed;right:0;top:0;z-index:990}.pull-right>.dropdown-menu{left:auto;right:0}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-bottom:4px solid;border-top:0;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{bottom:100%;margin-bottom:2px;top:auto}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{display:inline-block;position:relative;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{float:left;position:relative}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;max-width:100%;width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-left:0;margin-top:-1px}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-bottom-left-radius:0;border-bottom-right-radius:0;border-top-right-radius:4px}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-left-radius:0;border-top-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{border-collapse:initial;display:table;table-layout:fixed;width:100%}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{border-collapse:initial;display:table;position:relative}.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}.input-group .form-control{float:left;margin-bottom:0;position:relative;width:100%;z-index:2}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{border-radius:6px;font-size:18px;height:46px;line-height:1.33;padding:10px 16px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{border-radius:3px;font-size:12px;height:30px;line-height:1.5;padding:5px 10px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{vertical-align:middle;white-space:nowrap;width:1%}.input-group-addon{background-color:#eee;border:1px solid #ccc;border-radius:4px;color:#555;font-size:14px;font-weight:400;line-height:1;padding:6px 12px;text-align:center}.input-group-addon.input-sm{border-radius:3px;font-size:12px;padding:5px 10px}.input-group-addon.input-lg{border-radius:6px;font-size:18px;padding:10px 16px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{font-size:0;white-space:nowrap}.input-group-btn,.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{list-style:none;margin-bottom:0;padding-left:0}.nav>li,.nav>li>a{display:block;position:relative}.nav>li>a{padding:10px 15px}.nav>li:focus-within>a,.nav>li>a:focus,.nav>li>a:hover{background-color:#eee;text-decoration:none}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{background-color:initial;color:#777;cursor:not-allowed;text-decoration:none}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#017cee}.nav .nav-divider{background-color:#e5e5e5;height:1px;margin:9px 0;overflow:hidden}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{border:1px solid #0000;border-radius:4px 4px 0 0;line-height:1.428571429;margin-right:2px}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{background-color:#fafafa;border:1px solid;border-color:#ddd #ddd #0000;color:#555;cursor:default}.nav-tabs.nav-justified{border-bottom:0;width:100%}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{border-radius:4px;margin-bottom:5px;margin-right:0;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{left:auto;top:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fafafa}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px;color:#365f84}.nav-pills>li>a:focus,.nav-pills>li>a:hover{background-color:#c0defb;color:#365f84}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{background-color:#365f84;color:#fff}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-left:0;margin-top:2px}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{left:auto;top:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{border-radius:4px;margin-right:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fafafa}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:-1px}.navbar{background-color:#fff;border:0;box-shadow:0 0 16px #1d201940;margin:0;min-height:50px;position:relative}@media (min-width:768px){.navbar{border-radius:4px}.navbar-header{float:left}}.navbar-collapse{border-top:1px solid #0000;box-shadow:inset 0 1px 0 #ffffff1a;overflow-x:visible;padding-left:15px;padding-right:15px;-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:visible}@media (min-width:768px){.navbar-collapse{border-top:0;box-shadow:none;width:auto}.navbar-collapse.collapse{display:block!important;height:auto!important;overflow:visible!important;padding-bottom:0;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:none}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-left:0;margin-right:0}}.navbar-static-top{border-width:0 0 1px;z-index:1000}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{left:0;position:fixed;right:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{border-width:0 0 1px;top:0}.navbar-fixed-bottom{border-width:1px 0 0;bottom:0;margin-bottom:0}.navbar-brand{float:left;height:50px;padding:10px 15px}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{background-color:initial;background-image:none;border:1px solid #0000;border-radius:4px;float:right;margin-bottom:8px;margin-right:15px;margin-top:8px;padding:9px 10px;position:relative}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{background:currentColor;border-radius:1px;display:block;height:2px;width:22px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{line-height:20px;padding-bottom:10px;padding-top:10px}@media (max-width:767px){.navbar-nav .dropdown:focus-within>.dropdown-menu,.navbar-nav .dropdown:hover>.dropdown-menu{background-color:initial;border:0;box-shadow:none;float:none;margin-top:0;position:static;width:auto}.navbar-nav .dropdown:focus-within>.dropdown-menu .dropdown-header,.navbar-nav .dropdown:focus-within>.dropdown-menu>li>a,.navbar-nav .dropdown:focus-within>.dropdown-menu>li>form>button,.navbar-nav .dropdown:hover>.dropdown-menu .dropdown-header,.navbar-nav .dropdown:hover>.dropdown-menu>li>a,.navbar-nav .dropdown:hover>.dropdown-menu>li>form>button{padding:5px 15px 5px 25px}.navbar-nav .dropdown:focus-within>.dropdown-menu>li>a,.navbar-nav .dropdown:focus-within>.dropdown-menu>li>form>button,.navbar-nav .dropdown:hover>.dropdown-menu>li>a,.navbar-nav .dropdown:hover>.dropdown-menu>li>form>button{line-height:20px}.navbar-nav .dropdown:focus-within>.dropdown-menu>li>a:focus,.navbar-nav .dropdown:focus-within>.dropdown-menu>li>a:hover,.navbar-nav .dropdown:hover>.dropdown-menu>li>a:focus,.navbar-nav .dropdown:hover>.dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-bottom:20px;padding-top:20px}}.navbar-form{border-bottom:1px solid #0000;border-top:1px solid #0000;-webkit-box-shadow:inset 0 1px 0 #ffffff1a,0 1px 0 #ffffff1a;box-shadow:inset 0 1px 0 #ffffff1a,0 1px 0 #ffffff1a;margin:8px -15px;padding:10px 15px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;vertical-align:middle;width:auto}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-bottom:0;margin-top:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{margin-left:0;position:relative}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{border:0;-webkit-box-shadow:none;box-shadow:none;margin-left:0;margin-right:0;padding-bottom:0;padding-top:0;width:auto}}.navbar-nav>li>.dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-radius:4px 4px 0 0}.navbar-btn{margin-bottom:8px;margin-top:8px}.navbar-btn.btn-sm{margin-bottom:10px;margin-top:10px}.navbar-btn.btn-xs{margin-bottom:14px;margin-top:14px}.navbar-text{margin-bottom:15px;margin-top:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#ffb400;border-color:#de9d00}.navbar-default .navbar-brand{color:#007a87}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{background-color:initial;color:#004c54}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#007a87}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{background-color:initial;color:#51504f}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{background-color:#de9d00;color:#555}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{background-color:initial;color:#ccc}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#de9d00}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{background-color:#de9d00;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#007a87}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{background-color:initial;color:#51504f}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{background-color:#de9d00;color:#555}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{background-color:initial;color:#ccc}}.navbar-default .navbar-link{color:#007a87}.navbar-default .navbar-link:hover{color:#51504f}.navbar-default .btn-link{color:#007a87}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#51504f}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#007a87;border-color:#004c54}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.navbar-inverse,.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a,ee.dropdown-menu>.active>a:focus{background-image:none}.navbar-inverse .navbar-brand{color:#ddd}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{background-color:initial;color:#fff}.navbar-inverse .navbar-text{color:#ffb400}.navbar-inverse .navbar-nav>li>a{color:#ddd}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{background-color:initial;color:#fff}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{background-color:#004c54;color:#fff}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{background-color:initial;color:#444}.navbar-inverse .navbar-toggle{border-color:#51504f}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#51504f}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#005a63}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{background-color:#004c54;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#004c54}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#004c54}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#ddd}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{background-color:initial;color:#fff}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{background-color:#004c54;color:#fff}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{background-color:initial;color:#444}}.navbar-inverse .navbar-link{color:#ddd}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#ddd}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{background-color:#f5f5f5;border-radius:4px;list-style:none;margin-bottom:20px;padding:8px 15px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{color:#ccc;content:"/\00a0";padding:0 5px}.breadcrumb>.active{color:#777}.pagination{border-radius:4px;display:inline-block;margin:20px 0;padding-left:0}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{background-color:#fff;border:1px solid #ddd;color:#017cee;float:left;line-height:1.428571429;margin-left:-1px;padding:6px 12px;position:relative;text-decoration:none}.pagination>li:first-child>a,.pagination>li:first-child>span{border-bottom-left-radius:4px;border-top-left-radius:4px;margin-left:0}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{background-color:#eee;border-color:#ddd;color:#0cb6ff}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{background-color:##017cee;border-color:##017cee;color:#fff;cursor:default;z-index:2}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{background-color:#fff;border-color:#ddd;color:#777;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{font-size:18px;padding:10px 16px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{font-size:12px;padding:5px 10px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{list-style:none;margin:20px 0;padding-left:0;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{background-color:#fff;border:1px solid #ddd;border-radius:15px;display:inline-block;padding:5px 14px}.pager li>a:focus,.pager li>a:hover{background-color:#eee;text-decoration:none}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{background-color:#fff;color:#777;cursor:not-allowed}.label{border-radius:.25em;color:#51504f;display:inline;font-size:75%;font-weight:700;line-height:1;padding:.2em .6em .3em;text-align:center;vertical-align:initial;white-space:nowrap}a.label:focus,a.label:hover{color:#51504f;cursor:pointer;text-decoration:none}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#e2e2e2}.label-default[href]:focus,.label-default[href]:hover{background-color:#cbcbcb}.label-primary{background-color:#c0defb;color:#365f84}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#0cb6ff;color:#365f84}.label-success{background-color:#bfebd1;color:#366f4c}.label-success[href]:focus,.label-success[href]:hover{background-color:#04d659;color:#366f4c}.label-info{background-color:#bff1f4;color:#36787b}.label-info[href]:focus,.label-info[href]:hover{background-color:#11e1ee;color:#36787b}.label-warning{background-color:#ffb400}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#cc9000}.label-danger{background-color:#f8cec8;color:#824840}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#ff7557;color:#824840}.badge{background-color:#777;border-radius:10px;color:#fff;display:inline-block;font-size:12px;font-weight:700;line-height:1;min-width:10px;padding:3px 7px;text-align:center;vertical-align:initial;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{padding:1px 5px;top:0}a.badge:focus,a.badge:hover{color:#fff;cursor:pointer;text-decoration:none}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{background-color:#fff;color:#017cee}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{background-color:#eee;margin-bottom:30px;padding:30px 15px}.jumbotron,.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{font-size:21px;font-weight:200;margin-bottom:15px}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{background-color:#fafafa;border:1px solid #ddd;border-radius:4px;display:block;line-height:1.428571429;margin-bottom:20px;padding:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-left:auto;margin-right:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#017cee}.thumbnail .caption{color:#51504f;padding:9px}.alert{border:0;border-radius:4px;margin-bottom:16px;padding:16px}.alert h4{color:inherit;margin-top:0}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{color:inherit;position:relative;right:-21px;top:-2px}.alert-success{background-color:#bfebd1;color:#1b8e49}.alert-success hr{border-top-color:#bfebd1}.alert-success .alert-link{color:#366f4c}.alert-info{background-color:#bff1f4;color:#36787b}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;color:#e43921}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}.alert-message{background-color:#d9edf7;color:#31708f}.alert-message hr{border-top-color:#a6e1ec}.alert-message .alert-link{color:#245269}.alert-error{background-color:#f2dede;color:#e43921}.alert-error hr{border-top-color:#e4b9c0}.alert-error .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}.progress{background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px #0000001a;box-shadow:inset 0 1px 2px #0000001a;height:20px;margin-bottom:20px;overflow:hidden}.progress-bar{background-color:#017cee;-webkit-box-shadow:inset 0 -1px 0 #00000026;box-shadow:inset 0 -1px 0 #00000026;color:#fff;float:left;font-size:12px;height:100%;line-height:20px;text-align:center;-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease;width:0}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#00ad46}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000)}.progress-bar-info{background-color:#00d1c1}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000)}.progress-bar-warning{background-color:#ffb400}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000)}.progress-bar-danger{background-color:#ff5a5f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-bottom:5px;margin-top:0}.media-list{list-style:none;padding-left:0}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{background-color:#fff;border:1px solid #ddd;display:block;margin-bottom:-1px;padding:10px 15px;position:relative}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;margin-bottom:0}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#51504f}a.list-group-item:focus,a.list-group-item:hover{background-color:#f5f5f5;color:#555;text-decoration:none}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{background-color:#eee;color:#777;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{background-color:#017cee;border-color:#017cee;color:#fff;z-index:2}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#33ebff}.list-group-item-success{background-color:#bfebd1;color:#1b8e49}a.list-group-item-success{color:#1b8e49}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{background-color:#d0e9c6;color:#1b8e49}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{background-color:#1b8e49;border-color:#1b8e49;color:#fff}.list-group-item-info{background-color:#d9edf7;color:#31708f}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{background-color:#c4e3f3;color:#31708f}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{background-color:#31708f;border-color:#31708f;color:#fff}.list-group-item-warning{background-color:#fcf8e3;color:#8a6d3b}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{background-color:#faf2cc;color:#8a6d3b}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{background-color:#8a6d3b;border-color:#8a6d3b;color:#fff}.list-group-item-danger{background-color:#f2dede;color:#e43921}a.list-group-item-danger{color:#e43921}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{background-color:#ebcccc;color:#e43921}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{background-color:#e43921;border-color:#e43921;color:#fff}.list-group-item-heading{margin-bottom:5px;margin-top:0}.list-group-item-text{line-height:1.3;margin-bottom:0}.panel{background-color:#fff;border:2px solid #0000;border-radius:4px;box-shadow:none;margin-bottom:20px}.panel-body{padding:15px}.panel-heading{border-bottom:1px solid #0000;border-top-left-radius:2px;border-top-right-radius:2px;padding:10px 15px}.panel-heading>.dropdown .dropdown-toggle,.panel-title{color:inherit}.panel-title{font-size:16px;margin-bottom:0;margin-top:0}.panel-title>a{color:inherit}.panel-footer{background-color:#f5f5f5;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top:1px solid #ddd;padding:10px 15px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-radius:0;border-width:1px 0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px}.list-group+.panel-footer,.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-left:15px;padding-right:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{border-radius:4px;margin-bottom:0}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{background-color:#f5f5f5;border-color:#ddd;color:#51504f}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{background-color:#51504f;color:#f5f5f5}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#e2e2e2}.panel-primary>.panel-heading{background-color:#e2e2e2;border-color:#e2e2e2;color:#51504f}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#e2e2e2}.panel-primary>.panel-heading .badge{color:#e2e2e2}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#e2e2e2}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{background-color:#bfebd1;border-color:#d6e9c6;color:#1b8e49}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{background-color:#1b8e49;color:#bfebd1}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{background-color:#31708f;color:#d9edf7}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{background-color:#8a6d3b;color:#fcf8e3}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{background-color:#f2dede;border-color:#ebccd1;color:#e43921}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{background-color:#e43921;color:#f2dede}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.well{background-color:#f5f5f5;border:0;border-radius:4px;box-shadow:none;margin-bottom:20px;min-height:20px;padding:19px}.well blockquote{border-color:#00000026}.well-lg{border-radius:6px;padding:24px}.well-sm{padding:9px}.close{color:currentColor;float:right;font-size:21px;font-weight:700;line-height:1;opacity:.4}.close:focus,.close:hover{color:currentColor;cursor:pointer;opacity:.8;text-decoration:none}button.close{-webkit-appearance:none;background:#0000;border:0;cursor:pointer;padding:0}.modal,.modal-open{overflow:hidden}.modal{bottom:0;display:none;left:0;position:fixed;right:0;top:0;z-index:1040;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translateY(-25%);-ms-transform:translateY(-25%);-o-transform:translateY(-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0);-ms-transform:translate(0);-o-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{margin:10px;position:relative;width:auto}.modal-content{background-clip:padding-box;background-color:#fff;border:0;border-radius:6px;-webkit-box-shadow:0 3px 9px #00000080;box-shadow:0 3px 9px #00000080;outline:0;position:relative;z-index:5}.modal-backdrop{background-color:#000;left:0;position:fixed;right:0;top:0;z-index:2}.modal-backdrop.fade{opacity:0}.modal-backdrop.in{opacity:.5}.modal-header{border-bottom:1px solid #e5e5e5;min-height:16.428571429px;padding:15px}.modal-header .close{margin-top:-2px}.modal-title{line-height:1.428571429;margin:0}.modal-body{padding:15px;position:relative}.modal-footer{border-top:1px solid #e5e5e5;padding:15px;text-align:right}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{height:50px;overflow:auto;position:absolute;top:-9999px;width:50px}@media (min-width:768px){.modal-dialog{margin:30px auto;width:600px}.modal-content{-webkit-box-shadow:0 5px 15px #00000080;box-shadow:0 5px 15px #00000080}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{display:block;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:1070}.tooltip.in{opacity:1}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{background-color:#51504f;border-radius:4px;color:#fff;font-size:13px;max-width:500px;padding:3px 8px;text-align:left;text-decoration:none}.tooltip-arrow{border-color:#0000;border-style:solid;height:0;position:absolute;width:0}.tooltip.top .tooltip-arrow{border-top-color:#51504f;border-width:5px 5px 0;bottom:0;left:50%;margin-left:-5px}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{border-top-color:#51504f;border-width:5px 5px 0;bottom:0;margin-bottom:-5px}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{border-right-color:#51504f;border-width:5px 5px 5px 0;left:0;margin-top:-5px;top:50%}.tooltip.left .tooltip-arrow{border-left-color:#51504f;border-width:5px 0 5px 5px;margin-top:-5px;right:0;top:50%}.tooltip.bottom .tooltip-arrow{border-bottom-color:#51504f;border-width:0 5px 5px;left:50%;margin-left:-5px;top:0}.tooltip.bottom-left .tooltip-arrow{border-bottom-color:#51504f;border-width:0 5px 5px;margin-top:-5px;right:5px;top:0}.tooltip.bottom-right .tooltip-arrow{border-bottom-color:#51504f;border-width:0 5px 5px;left:5px;margin-top:-5px;top:0}.popover{background-clip:padding-box;background-color:#fff;border:1px solid #0003;border-radius:6px;-webkit-box-shadow:0 5px 10px #0003;box-shadow:0 5px 10px #0003;display:none;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;left:0;line-height:1.428571429;max-width:276px;padding:1px;position:absolute;text-align:left;top:0;white-space:normal;z-index:1060}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0;font-size:14px;margin:0;padding:8px 14px}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{border-color:#0000;border-style:solid;display:block;height:0;position:absolute;width:0}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{border-bottom-width:0;border-top-color:#00000040;bottom:-11px;left:50%;margin-left:-11px}.popover.top>.arrow:after{border-bottom-width:0;border-top-color:#fff;bottom:1px;content:" ";margin-left:-10px}.popover.right>.arrow{border-left-width:0;border-right-color:#00000040;left:-11px;margin-top:-11px;top:50%}.popover.right>.arrow:after{border-left-width:0;border-right-color:#fff;bottom:-10px;content:" ";left:1px}.popover.bottom>.arrow{border-bottom-color:#00000040;border-top-width:0;left:50%;margin-left:-11px;top:-11px}.popover.bottom>.arrow:after{border-bottom-color:#fff;border-top-width:0;content:" ";margin-left:-10px;top:1px}.popover.left>.arrow{border-left-color:#00000040;border-right-width:0;margin-top:-11px;right:-11px;top:50%}.popover.left>.arrow:after{border-left-color:#fff;border-right-width:0;bottom:-10px;content:" ";right:1px}.carousel,.carousel-inner{position:relative}.carousel-inner{overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:left .6s ease-in-out;-o-transition:left .6s ease-in-out;transition:left .6s ease-in-out}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@supports (transform:translate3d){.carousel-inner>.item{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;-moz-perspective:1000;perspective:1000;-webkit-transition:-webkit-transform .6s ease-in-out;-moz-transition:-moz-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translateZ(0);transform:translateZ(0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{bottom:0;color:#fff;font-size:20px;left:0;opacity:.5;position:absolute;text-align:center;text-shadow:0 1px 2px #0009;top:0;width:15%}.carousel-control.left{background-image:-webkit-linear-gradient(left,#00000080,#0000);background-image:-o-linear-gradient(left,#00000080 0,#0000 100%);background-image:linear-gradient(90deg,#00000080 0,#0000);background-repeat:repeat-x}.carousel-control.right{background-image:-webkit-linear-gradient(left,#0000,#00000080);background-image:-o-linear-gradient(left,#0000 0,#00000080 100%);background-image:linear-gradient(90deg,#0000 0,#00000080);background-repeat:repeat-x;left:auto;right:0}.carousel-control:focus,.carousel-control:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{display:inline-block;position:absolute;top:50%;z-index:5}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px;right:50%}.carousel-control .icon-next,.carousel-control .icon-prev{font-family:serif;height:20px;line-height:1;margin-top:-10px;width:20px}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{bottom:10px;left:50%;list-style:none;margin-left:-30%;padding-left:0;position:absolute;text-align:center;width:60%;z-index:15}.carousel-indicators li{background-color:#000\9;background-color:#0000;border:1px solid #fff;border-radius:10px;cursor:pointer;display:inline-block;height:10px;margin:1px;text-indent:-999px;width:10px}.carousel-indicators .active{background-color:#fff;height:12px;margin:0;width:12px}.carousel-caption{bottom:20px;color:#fff;left:15%;padding-bottom:20px;padding-top:20px;position:absolute;right:15%;text-align:center;text-shadow:0 1px 2px #0009;z-index:10}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{font-size:30px;height:30px;margin-top:-15px;width:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{left:20%;padding-bottom:30px;right:20%}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{content:" ";display:table}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}.visible-xs-block{display:block!important}.visible-xs-inline{display:inline!important}.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}.visible-sm-block{display:block!important}.visible-sm-inline{display:inline!important}.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}.visible-md-block{display:block!important}.visible-md-inline{display:inline!important}.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}.visible-lg-block{display:block!important}.visible-lg-inline{display:inline!important}.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}.hidden-print{display:none!important}} \ No newline at end of file +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{background:#0000!important;box-shadow:none!important;color:#000!important;text-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#cbcbcb!important}.label{border:1px solid #51504f}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #f0f0f0!important}}*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:12px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{color:#51504f;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a,a code{color:#365f84;text-decoration:none}a:focus,a:hover{color:#017cee;text-decoration:none}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;height:auto;max-width:100%}.img-rounded{border-radius:6px}.img-thumbnail{background-color:#fafafa;border:1px solid #ddd;border-radius:4px;display:inline-block;height:auto;line-height:1.428571429;max-width:100%;padding:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{border:0;border-top:2px solid #f0f0f0;margin-bottom:15px;margin-top:15px}.sr-only{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{height:auto;margin:0;overflow:visible;position:static;width:auto;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{color:inherit;font-family:inherit;font-weight:500;line-height:1.1}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{color:#777;font-weight:400;line-height:1}.h1,.h2,.h3,h1,h2,h3{margin-bottom:10px;margin-top:20px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-bottom:10px;margin-top:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{font-size:16px;font-weight:300;line-height:1.4;margin-bottom:20px}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#cbcbcb}.text-primary{color:#017cee}a.text-primary:hover{color:#002e33}.text-success{color:#1b8e49}a.text-success:hover{color:#366f4c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#e43921}a.text-danger:hover{color:#843534}.bg-primary{background-color:#017cee;color:#fff}a.bg-primary:hover{background-color:#002e33}.bg-success{background-color:#bfebd1}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{border-bottom:1px solid #eee;margin:40px 0 20px;padding-bottom:9px}ol,ul{margin-bottom:10px;margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-inline,.list-unstyled{list-style:none;padding-left:0}.list-inline{margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-bottom:20px;margin-top:0}dd,dt{line-height:1.428571429}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{clear:left;float:left;overflow:hidden;text-align:right;text-overflow:ellipsis;white-space:nowrap;width:160px}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{border-bottom:1px dotted #777;cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{border-left:5px solid #eee;font-size:17.5px;margin:0 0 20px;padding:10px 20px}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{color:#777;display:block;font-size:80%;line-height:1.428571429}blockquote .small:before,blockquote footer:before,blockquote small:before{content:"\2014 \00A0"}.blockquote-reverse,blockquote.pull-right{border-left:0;border-right:5px solid #eee;padding-left:0;padding-right:15px;text-align:right}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:""}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:"\00A0 \2014"}address{font-style:normal;line-height:1.428571429;margin-bottom:20px}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Courier New,monospace}code{background-color:#e2e2e2;border-radius:4px;color:#51504f}code,kbd{font-size:90%;padding:2px 4px}kbd{background-color:#51504f;border-radius:3px;box-shadow:inset 0 -1px 0 #00000040;color:#fff}kbd kbd{box-shadow:none;font-size:100%;font-weight:700;padding:0}pre{display:block;font-size:13px;line-height:1.428571429;margin:0 0 10px;padding:9.5px;word-break:break-all;word-wrap:break-word;background-color:#f0f0f0;border:0;border-radius:4px;color:#51504f}pre code{background-color:initial;border-radius:0;color:inherit;font-size:inherit;padding:0;white-space:pre-wrap}.pre-scrollable{max-height:340px;overflow-y:auto}.container{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:15px;padding-right:15px;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666666666666%}.col-xs-10{width:83.33333333333334%}.col-xs-9{width:75%}.col-xs-8{width:66.66666666666666%}.col-xs-7{width:58.333333333333336%}.col-xs-6{width:50%}.col-xs-5{width:41.66666666666667%}.col-xs-4{width:33.33333333333333%}.col-xs-3{width:25%}.col-xs-2{width:16.666666666666664%}.col-xs-1{width:8.333333333333332%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666666666666%}.col-xs-pull-10{right:83.33333333333334%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666666666666%}.col-xs-pull-7{right:58.333333333333336%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666666666667%}.col-xs-pull-4{right:33.33333333333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.666666666666664%}.col-xs-pull-1{right:8.333333333333332%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666666666666%}.col-xs-push-10{left:83.33333333333334%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666666666666%}.col-xs-push-7{left:58.333333333333336%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666666666667%}.col-xs-push-4{left:33.33333333333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.666666666666664%}.col-xs-push-1{left:8.333333333333332%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666666666666%}.col-xs-offset-10{margin-left:83.33333333333334%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666666666666%}.col-xs-offset-7{margin-left:58.333333333333336%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666666666667%}.col-xs-offset-4{margin-left:33.33333333333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.666666666666664%}.col-xs-offset-1{margin-left:8.333333333333332%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}table{background-color:initial}caption{color:#777;padding-bottom:8px;padding-top:8px}caption,th{text-align:left}.table{margin-bottom:20px;max-width:100%;width:100%}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{border-top:1px solid #ddd;line-height:1.428571429;padding:8px;vertical-align:middle}.table>thead>tr>th{background-color:#f0f0f0;border-bottom:1px solid #fff;vertical-align:bottom;white-space:nowrap}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>tbody+tbody,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table .table{background-color:#f0f0f0}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #f0f0f0}.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>th{border:0}.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td,.table-bordered>thead>tr>td{border:0;border-top:1px solid #f0f0f0}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#fff}.table-striped>tbody>tr:nth-child(2n){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{display:table-column;float:none;position:static}table td[class*=col-],table th[class*=col-]{display:table-cell;float:none;position:static}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#bfebd1}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow:visible}@media screen and (max-width:767px){.table-responsive{border:1px solid #ddd;margin-bottom:15px;width:100%}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{margin:0;min-width:0}fieldset,legend{border:0;padding:0}legend{border-bottom:1px solid #e5e5e5;color:#51504f;display:block;font-size:21px;line-height:inherit;margin-bottom:20px;width:100%}label{display:inline-block;font-weight:700;margin-bottom:5px;max-width:100%}input[type=checkbox],input[type=radio]{line-height:normal;margin:4px 0 0;margin-top:1px\9}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{padding-top:7px}.form-control,output{color:#555;display:block;font-size:14px;line-height:1.428571429}.form-control{background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);height:34px;padding:6px 12px;-webkit-transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-o-transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}.form-control:focus{border-color:#66afe9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px #66afe999;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px #66afe999;outline:0}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;color:#cbcbcb;cursor:not-allowed;opacity:1}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=datetime-local],input[type=month],input[type=time]{line-height:34px}input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{display:block;margin-bottom:10px;margin-top:10px;position:relative}.checkbox label,.radio label{cursor:pointer;font-weight:400;margin-bottom:0;min-height:20px;padding-left:20px}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{margin-left:-20px;margin-top:4px\9;position:absolute}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{cursor:pointer;display:inline-block;font-weight:400;margin-bottom:0;padding-left:20px;vertical-align:middle}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-left:10px;margin-top:0}.checkbox-inline.disabled,.checkbox.disabled label,.radio-inline.disabled,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio label,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.form-control-static{margin-bottom:0;padding-bottom:7px;padding-top:7px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{border-radius:3px;font-size:12px;height:30px;line-height:1.5;padding:5px 10px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{border-radius:3px;font-size:12px;height:30px;line-height:1.5;padding:5px 10px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.input-lg{border-radius:6px;font-size:18px;height:46px;line-height:1.33;padding:10px 16px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{border-radius:6px;font-size:18px;height:46px;line-height:1.33;padding:10px 16px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{display:block;height:34px;line-height:34px;pointer-events:none;position:absolute;right:0;text-align:center;top:0;width:34px;z-index:2}.input-lg+.form-control-feedback{height:46px;line-height:46px;width:46px}.input-sm+.form-control-feedback{height:30px;line-height:30px;width:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#1b8e49}.has-success .form-control{border-color:#1b8e49;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#366f4c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{background-color:#bfebd1;border-color:#1b8e49;color:#1b8e49}.has-success .form-control-feedback{color:#1b8e49}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{background-color:#fcf8e3;border-color:#8a6d3b;color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#e43921}.has-error .form-control{border-color:#e43921;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{background-color:#f2dede;border-color:#e43921;color:#e43921}.has-error .form-control-feedback{color:#e43921}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{color:#737373;display:block;margin-bottom:10px;margin-top:5px}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;vertical-align:middle;width:auto}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-bottom:0;margin-top:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{margin-left:0;position:relative}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{margin-bottom:0;margin-top:0;padding-top:7px}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{margin-bottom:0;padding-top:7px;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{background:#fff;border:1px solid #017cee;border-radius:4px;color:#017cee;cursor:pointer;display:inline-block;font-size:14px;font-weight:400;line-height:1.428571429;margin-bottom:0;padding:6px 12px;text-align:center;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;white-space:nowrap}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{background-color:#c0defb;color:#017cee;text-decoration:none}.btn.active,.btn:active{background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125);outline:0}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed;opacity:.5;pointer-events:none}.btn-icon-only{padding:6px}.btn-default{background-color:#fff;border-color:#ccc;color:#365f84}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{background-color:#f0f0f0;border-color:#adadad;color:#017cee}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{background-color:#51504f;color:#fff}.btn-primary{background-color:#017cee;border-color:#017cee;color:#fff}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{background-color:#0cb6ff;border-color:#0cb6ff;color:#fff}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#017cee;border-color:#00454c}.btn-primary .badge{background-color:#fff;color:#017cee}.btn-primary.active .badge,.btn-primary.focus .badge,.btn-primary:active .badge,.btn-primary:focus .badge,.btn-primary:hover .badge,.open>.dropdown-toggle.btn-primary .badge{color:#0cb6ff}.btn-success{background-color:#00ad46;border-color:#38a047;color:#fff}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{background-color:#328d3e;border-color:#287333;color:#fff}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#00ad46;border-color:#00ad46}.btn-success .badge{background-color:#fff;color:#00ad46}.btn-info{background-color:#00d1c1;border-color:#00b8a9;color:#fff}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{background-color:#009e92;border-color:#007a71;color:#fff}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#00d1c1;border-color:#00b8a9}.btn-info .badge{background-color:#fff;color:#00d1c1}.btn-warning{background-color:#ffb400;border-color:#e6a200;color:#fff}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{background-color:#cc9000;border-color:#a87700;color:#fff}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#ffb400;border-color:#e6a200}.btn-warning .badge{background-color:#fff;color:#ffb400}.btn-danger{background-color:#ff5a5f;border-color:#ff4146;color:#fff}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{background-color:#ff272e;border-color:#ff030b;color:#fff}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#ff5a5f;border-color:#ff4146}.btn-danger .badge{background-color:#fff;color:#ff5a5f}.btn-link{border-radius:0;color:#017cee;font-weight:400}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:initial;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:#0000}.btn-link:focus,.btn-link:hover{background-color:initial;color:#004c54;text-decoration:underline}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{border-radius:6px;font-size:18px;line-height:1.33;padding:10px 16px}.btn-group-lg>.btn.btn-icon-only,.btn-lg.btn-icon-only{padding:10px}.btn-group-sm>.btn,.btn-sm{border-radius:3px;font-size:12px;line-height:1.5;padding:5px 10px}.btn-group-sm>.btn.btn-icon-only,.btn-sm.btn-icon-only{padding:5px}.btn-group-xs>.btn,.btn-xs{border-radius:3px;font-size:12px;line-height:1.5;padding:1px 5px}.btn-group-xs>.btn.btn-icon-only,.btn-xs.btn-icon-only{padding:1px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{height:0;overflow:hidden;position:relative;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-timing-function:ease;transition-timing-function:ease}.caret{border-left:4px solid #0000;border-right:4px solid #0000;border-top:4px solid;display:inline-block;height:0;margin-left:2px;vertical-align:middle;width:0}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{background-clip:padding-box;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);display:none;float:left;font-size:14px;left:0;list-style:none;margin:2px 0 0;min-width:160px;padding:5px 0;position:absolute;text-align:left;top:100%;z-index:1000}.dropdown-menu.pull-right{left:auto;right:0}.dropdown-menu .divider{background-color:#e5e5e5;height:1px;margin:9px 0;overflow:hidden}.dropdown-menu>li>a,.dropdown-menu>li>form>button{clear:both;color:#51504f;display:block;font-weight:400;line-height:1.428571429;max-width:100%;padding:3px 20px;text-align:left;white-space:nowrap;width:100%}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover,.dropdown-menu>li>form>button:focus,.dropdown-menu>li>form>button:hover{background-color:#f5f5f5;color:#262626;text-decoration:none}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#017cee;color:#fff;outline:0;text-decoration:none}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{background-color:initial;background-image:none;cursor:not-allowed;text-decoration:none}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{color:#777;display:block;font-size:12px;line-height:1.428571429;padding:3px 20px;white-space:nowrap}.dropdown-backdrop{bottom:0;left:0;position:fixed;right:0;top:0;z-index:990}.pull-right>.dropdown-menu{left:auto;right:0}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-bottom:4px solid;border-top:0;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{bottom:100%;margin-bottom:2px;top:auto}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{display:inline-block;position:relative;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{float:left;position:relative}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;max-width:100%;width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-left:0;margin-top:-1px}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-bottom-left-radius:0;border-bottom-right-radius:0;border-top-right-radius:4px}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-left-radius:0;border-top-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{border-collapse:initial;display:table;table-layout:fixed;width:100%}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{border-collapse:initial;display:table;position:relative}.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}.input-group .form-control{float:left;margin-bottom:0;position:relative;width:100%;z-index:2}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{border-radius:6px;font-size:18px;height:46px;line-height:1.33;padding:10px 16px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{border-radius:3px;font-size:12px;height:30px;line-height:1.5;padding:5px 10px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{vertical-align:middle;white-space:nowrap;width:1%}.input-group-addon{background-color:#eee;border:1px solid #ccc;border-radius:4px;color:#555;font-size:14px;font-weight:400;line-height:1;padding:6px 12px;text-align:center}.input-group-addon.input-sm{border-radius:3px;font-size:12px;padding:5px 10px}.input-group-addon.input-lg{border-radius:6px;font-size:18px;padding:10px 16px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{font-size:0;white-space:nowrap}.input-group-btn,.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{list-style:none;margin-bottom:0;padding-left:0}.nav>li,.nav>li>a{display:block;position:relative}.nav>li>a{padding:10px 15px}.nav>li:focus-within>a,.nav>li>a:focus,.nav>li>a:hover{background-color:#eee;text-decoration:none}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{background-color:initial;color:#777;cursor:not-allowed;text-decoration:none}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#017cee}.nav .nav-divider{background-color:#e5e5e5;height:1px;margin:9px 0;overflow:hidden}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{border:1px solid #0000;border-radius:4px 4px 0 0;line-height:1.428571429;margin-right:2px}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{background-color:#fafafa;border:1px solid;border-color:#ddd #ddd #0000;color:#555;cursor:default}.nav-tabs.nav-justified{border-bottom:0;width:100%}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{border-radius:4px;margin-bottom:5px;margin-right:0;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{left:auto;top:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fafafa}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px;color:#365f84}.nav-pills>li>a:focus,.nav-pills>li>a:hover{background-color:#c0defb;color:#365f84}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{background-color:#365f84;color:#fff}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-left:0;margin-top:2px}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{left:auto;top:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{border-radius:4px;margin-right:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fafafa}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:-1px}.navbar{background-color:#fff;border:0;box-shadow:0 0 16px #1d201940;margin:0;min-height:50px;position:relative}@media (min-width:768px){.navbar{border-radius:4px}.navbar-header{float:left}}.navbar-collapse{border-top:1px solid #0000;box-shadow:inset 0 1px 0 #ffffff1a;overflow-x:visible;padding-left:15px;padding-right:15px;-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:visible}@media (min-width:768px){.navbar-collapse{border-top:0;box-shadow:none;width:auto}.navbar-collapse.collapse{display:block!important;height:auto!important;overflow:visible!important;padding-bottom:0;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:none}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-left:0;margin-right:0}}.navbar-static-top{border-width:0 0 1px;z-index:1000}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{left:0;position:fixed;right:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{border-width:0 0 1px;top:0}.navbar-fixed-bottom{border-width:1px 0 0;bottom:0;margin-bottom:0}.navbar-brand{float:left;height:50px;padding:10px 15px}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{background-color:initial;background-image:none;border:1px solid #0000;border-radius:4px;float:right;margin-bottom:8px;margin-right:15px;margin-top:8px;padding:9px 10px;position:relative}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{background:currentColor;border-radius:1px;display:block;height:2px;width:22px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{line-height:20px;padding-bottom:10px;padding-top:10px}@media (max-width:767px){.navbar-nav .dropdown:focus-within>.dropdown-menu,.navbar-nav .dropdown:hover>.dropdown-menu{background-color:initial;border:0;box-shadow:none;float:none;margin-top:0;position:static;width:auto}.navbar-nav .dropdown:focus-within>.dropdown-menu .dropdown-header,.navbar-nav .dropdown:focus-within>.dropdown-menu>li>a,.navbar-nav .dropdown:focus-within>.dropdown-menu>li>form>button,.navbar-nav .dropdown:hover>.dropdown-menu .dropdown-header,.navbar-nav .dropdown:hover>.dropdown-menu>li>a,.navbar-nav .dropdown:hover>.dropdown-menu>li>form>button{padding:5px 15px 5px 25px}.navbar-nav .dropdown:focus-within>.dropdown-menu>li>a,.navbar-nav .dropdown:focus-within>.dropdown-menu>li>form>button,.navbar-nav .dropdown:hover>.dropdown-menu>li>a,.navbar-nav .dropdown:hover>.dropdown-menu>li>form>button{line-height:20px}.navbar-nav .dropdown:focus-within>.dropdown-menu>li>a:focus,.navbar-nav .dropdown:focus-within>.dropdown-menu>li>a:hover,.navbar-nav .dropdown:hover>.dropdown-menu>li>a:focus,.navbar-nav .dropdown:hover>.dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-bottom:20px;padding-top:20px}}.navbar-form{border-bottom:1px solid #0000;border-top:1px solid #0000;-webkit-box-shadow:inset 0 1px 0 #ffffff1a,0 1px 0 #ffffff1a;box-shadow:inset 0 1px 0 #ffffff1a,0 1px 0 #ffffff1a;margin:8px -15px;padding:10px 15px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;vertical-align:middle;width:auto}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-bottom:0;margin-top:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{margin-left:0;position:relative}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{border:0;-webkit-box-shadow:none;box-shadow:none;margin-left:0;margin-right:0;padding-bottom:0;padding-top:0;width:auto}}.navbar-nav>li>.dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-radius:4px 4px 0 0}.navbar-btn{margin-bottom:8px;margin-top:8px}.navbar-btn.btn-sm{margin-bottom:10px;margin-top:10px}.navbar-btn.btn-xs{margin-bottom:14px;margin-top:14px}.navbar-text{margin-bottom:15px;margin-top:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#ffb400;border-color:#de9d00}.navbar-default .navbar-brand{color:#007a87}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{background-color:initial;color:#004c54}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#007a87}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{background-color:initial;color:#51504f}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{background-color:#de9d00;color:#555}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{background-color:initial;color:#ccc}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#de9d00}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{background-color:#de9d00;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#007a87}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{background-color:initial;color:#51504f}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{background-color:#de9d00;color:#555}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{background-color:initial;color:#ccc}}.navbar-default .navbar-link{color:#007a87}.navbar-default .navbar-link:hover{color:#51504f}.navbar-default .btn-link{color:#007a87}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#51504f}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#007a87;border-color:#004c54}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.navbar-inverse,.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a,ee.dropdown-menu>.active>a:focus{background-image:none}.navbar-inverse .navbar-brand{color:#ddd}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{background-color:initial;color:#fff}.navbar-inverse .navbar-text{color:#ffb400}.navbar-inverse .navbar-nav>li>a{color:#ddd}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{background-color:initial;color:#fff}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{background-color:#004c54;color:#fff}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{background-color:initial;color:#444}.navbar-inverse .navbar-toggle{border-color:#51504f}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#51504f}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#005a63}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{background-color:#004c54;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#004c54}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#004c54}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#ddd}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{background-color:initial;color:#fff}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{background-color:#004c54;color:#fff}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{background-color:initial;color:#444}}.navbar-inverse .navbar-link{color:#ddd}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#ddd}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{background-color:#f5f5f5;border-radius:4px;list-style:none;margin-bottom:20px;padding:8px 15px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{color:#ccc;content:"/\00a0";padding:0 5px}.breadcrumb>.active{color:#777}.pagination{border-radius:4px;display:inline-block;margin:20px 0;padding-left:0}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{background-color:#fff;border:1px solid #ddd;color:#017cee;float:left;line-height:1.428571429;margin-left:-1px;padding:6px 12px;position:relative;text-decoration:none}.pagination>li:first-child>a,.pagination>li:first-child>span{border-bottom-left-radius:4px;border-top-left-radius:4px;margin-left:0}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{background-color:#eee;border-color:#ddd;color:#0cb6ff}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{background-color:##017cee;border-color:##017cee;color:#fff;cursor:default;z-index:2}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{background-color:#fff;border-color:#ddd;color:#777;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{font-size:18px;padding:10px 16px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{font-size:12px;padding:5px 10px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{list-style:none;margin:20px 0;padding-left:0;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{background-color:#fff;border:1px solid #ddd;border-radius:15px;display:inline-block;padding:5px 14px}.pager li>a:focus,.pager li>a:hover{background-color:#eee;text-decoration:none}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{background-color:#fff;color:#777;cursor:not-allowed}.label{border-radius:.25em;color:#51504f;display:inline;font-size:75%;font-weight:700;line-height:1;padding:.2em .6em .3em;text-align:center;vertical-align:initial;white-space:nowrap}a.label:focus,a.label:hover{color:#51504f;cursor:pointer;text-decoration:none}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#e2e2e2}.label-default[href]:focus,.label-default[href]:hover{background-color:#cbcbcb}.label-primary{background-color:#c0defb;color:#365f84}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#0cb6ff;color:#365f84}.label-success{background-color:#bfebd1;color:#366f4c}.label-success[href]:focus,.label-success[href]:hover{background-color:#04d659;color:#366f4c}.label-info{background-color:#bff1f4;color:#36787b}.label-info[href]:focus,.label-info[href]:hover{background-color:#11e1ee;color:#36787b}.label-warning{background-color:#ffb400}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#cc9000}.label-danger{background-color:#f8cec8;color:#824840}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#ff7557;color:#824840}.badge{background-color:#777;border-radius:10px;color:#fff;display:inline-block;font-size:12px;font-weight:700;line-height:1;min-width:10px;padding:3px 7px;text-align:center;vertical-align:initial;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{padding:1px 5px;top:0}a.badge:focus,a.badge:hover{color:#fff;cursor:pointer;text-decoration:none}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{background-color:#fff;color:#017cee}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{background-color:#eee;margin-bottom:30px;padding:30px 15px}.jumbotron,.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{font-size:21px;font-weight:200;margin-bottom:15px}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{background-color:#fafafa;border:1px solid #ddd;border-radius:4px;display:block;line-height:1.428571429;margin-bottom:20px;padding:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-left:auto;margin-right:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#017cee}.thumbnail .caption{color:#51504f;padding:9px}.alert{border:0;border-radius:4px;margin-bottom:16px;padding:16px}.alert h4{color:inherit;margin-top:0}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{color:inherit;position:relative;right:-21px;top:-2px}.alert-success{background-color:#bfebd1;color:#1b8e49}.alert-success hr{border-top-color:#bfebd1}.alert-success .alert-link{color:#366f4c}.alert-info{background-color:#bff1f4;color:#36787b}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;color:#e43921}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}.alert-message{background-color:#d9edf7;color:#31708f}.alert-message hr{border-top-color:#a6e1ec}.alert-message .alert-link{color:#245269}.alert-error{background-color:#f2dede;color:#e43921}.alert-error hr{border-top-color:#e4b9c0}.alert-error .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}.progress{background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px #0000001a;box-shadow:inset 0 1px 2px #0000001a;height:20px;margin-bottom:20px;overflow:hidden}.progress-bar{background-color:#017cee;-webkit-box-shadow:inset 0 -1px 0 #00000026;box-shadow:inset 0 -1px 0 #00000026;color:#fff;float:left;font-size:12px;height:100%;line-height:20px;text-align:center;-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease;width:0}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#00ad46}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000)}.progress-bar-info{background-color:#00d1c1}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000)}.progress-bar-warning{background-color:#ffb400}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000)}.progress-bar-danger{background-color:#ff5a5f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-image:-o-linear-gradient(45deg,#ffffff26 25%,#0000 25%,#0000 50%,#ffffff26 50%,#ffffff26 75%,#0000 75%,#0000);background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-bottom:5px;margin-top:0}.media-list{list-style:none;padding-left:0}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{background-color:#fff;border:1px solid #ddd;display:block;margin-bottom:-1px;padding:10px 15px;position:relative}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;margin-bottom:0}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#51504f}a.list-group-item:focus,a.list-group-item:hover{background-color:#f5f5f5;color:#555;text-decoration:none}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{background-color:#eee;color:#777;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{background-color:#017cee;border-color:#017cee;color:#fff;z-index:2}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#33ebff}.list-group-item-success{background-color:#bfebd1;color:#1b8e49}a.list-group-item-success{color:#1b8e49}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{background-color:#d0e9c6;color:#1b8e49}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{background-color:#1b8e49;border-color:#1b8e49;color:#fff}.list-group-item-info{background-color:#d9edf7;color:#31708f}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{background-color:#c4e3f3;color:#31708f}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{background-color:#31708f;border-color:#31708f;color:#fff}.list-group-item-warning{background-color:#fcf8e3;color:#8a6d3b}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{background-color:#faf2cc;color:#8a6d3b}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{background-color:#8a6d3b;border-color:#8a6d3b;color:#fff}.list-group-item-danger{background-color:#f2dede;color:#e43921}a.list-group-item-danger{color:#e43921}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{background-color:#ebcccc;color:#e43921}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{background-color:#e43921;border-color:#e43921;color:#fff}.list-group-item-heading{margin-bottom:5px;margin-top:0}.list-group-item-text{line-height:1.3;margin-bottom:0}.panel{background-color:#fff;border:2px solid #0000;border-radius:4px;box-shadow:none;margin-bottom:20px}.panel-body{padding:15px}.panel-heading{border-bottom:1px solid #0000;border-top-left-radius:2px;border-top-right-radius:2px;padding:10px 15px}.panel-heading>.dropdown .dropdown-toggle,.panel-title{color:inherit}.panel-title{font-size:16px;margin-bottom:0;margin-top:0}.panel-title>a{color:inherit}.panel-footer{background-color:#f5f5f5;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top:1px solid #ddd;padding:10px 15px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-radius:0;border-width:1px 0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px}.list-group+.panel-footer,.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-left:15px;padding-right:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{border-radius:4px;margin-bottom:0}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{background-color:#f5f5f5;border-color:#ddd;color:#51504f}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{background-color:#51504f;color:#f5f5f5}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#e2e2e2}.panel-primary>.panel-heading{background-color:#e2e2e2;border-color:#e2e2e2;color:#51504f}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#e2e2e2}.panel-primary>.panel-heading .badge{color:#e2e2e2}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#e2e2e2}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{background-color:#bfebd1;border-color:#d6e9c6;color:#1b8e49}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{background-color:#1b8e49;color:#bfebd1}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{background-color:#31708f;color:#d9edf7}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{background-color:#8a6d3b;color:#fcf8e3}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{background-color:#f2dede;border-color:#ebccd1;color:#e43921}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{background-color:#e43921;color:#f2dede}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.well{background-color:#f5f5f5;border:0;border-radius:4px;box-shadow:none;margin-bottom:20px;min-height:20px;padding:19px}.well blockquote{border-color:#00000026}.well-lg{border-radius:6px;padding:24px}.well-sm{padding:9px}.close{color:currentColor;float:right;font-size:21px;font-weight:700;line-height:1;opacity:.4}.close:focus,.close:hover{color:currentColor;cursor:pointer;opacity:.8;text-decoration:none}button.close{-webkit-appearance:none;background:#0000;border:0;cursor:pointer;padding:0}.modal,.modal-open{overflow:hidden}.modal{bottom:0;display:none;left:0;position:fixed;right:0;top:0;z-index:1040;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translateY(-25%);-ms-transform:translateY(-25%);-o-transform:translateY(-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0);-ms-transform:translate(0);-o-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{margin:10px;position:relative;width:auto}.modal-content{background-clip:padding-box;background-color:#fff;border:0;border-radius:6px;-webkit-box-shadow:0 3px 9px #00000080;box-shadow:0 3px 9px #00000080;outline:0;position:relative;z-index:5}.modal-backdrop{background-color:#000;left:0;position:fixed;right:0;top:0;z-index:2}.modal-backdrop.fade{opacity:0}.modal-backdrop.in{opacity:.5}.modal-header{border-bottom:1px solid #e5e5e5;min-height:16.428571429px;padding:15px}.modal-header .close{margin-top:-2px}.modal-title{line-height:1.428571429;margin:0}.modal-body{padding:15px;position:relative}.modal-footer{border-top:1px solid #e5e5e5;padding:15px;text-align:right}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{height:50px;overflow:auto;position:absolute;top:-9999px;width:50px}@media (min-width:768px){.modal-dialog{margin:30px auto;width:600px}.modal-content{-webkit-box-shadow:0 5px 15px #00000080;box-shadow:0 5px 15px #00000080}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{display:block;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:1070}.tooltip.in{opacity:1}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{background-color:#51504f;border-radius:4px;color:#fff;font-size:13px;max-width:500px;padding:3px 8px;text-align:left;text-decoration:none}.tooltip-arrow{border-color:#0000;border-style:solid;height:0;position:absolute;width:0}.tooltip.top .tooltip-arrow{border-top-color:#51504f;border-width:5px 5px 0;bottom:0;left:50%;margin-left:-5px}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{border-top-color:#51504f;border-width:5px 5px 0;bottom:0;margin-bottom:-5px}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{border-right-color:#51504f;border-width:5px 5px 5px 0;left:0;margin-top:-5px;top:50%}.tooltip.left .tooltip-arrow{border-left-color:#51504f;border-width:5px 0 5px 5px;margin-top:-5px;right:0;top:50%}.tooltip.bottom .tooltip-arrow{border-bottom-color:#51504f;border-width:0 5px 5px;left:50%;margin-left:-5px;top:0}.tooltip.bottom-left .tooltip-arrow{border-bottom-color:#51504f;border-width:0 5px 5px;margin-top:-5px;right:5px;top:0}.tooltip.bottom-right .tooltip-arrow{border-bottom-color:#51504f;border-width:0 5px 5px;left:5px;margin-top:-5px;top:0}.popover{background-clip:padding-box;background-color:#fff;border:1px solid #0003;border-radius:6px;-webkit-box-shadow:0 5px 10px #0003;box-shadow:0 5px 10px #0003;display:none;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;left:0;line-height:1.428571429;max-width:276px;padding:1px;position:absolute;text-align:left;top:0;white-space:normal;z-index:1060}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0;font-size:14px;margin:0;padding:8px 14px}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{border-color:#0000;border-style:solid;display:block;height:0;position:absolute;width:0}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{border-bottom-width:0;border-top-color:#00000040;bottom:-11px;left:50%;margin-left:-11px}.popover.top>.arrow:after{border-bottom-width:0;border-top-color:#fff;bottom:1px;content:" ";margin-left:-10px}.popover.right>.arrow{border-left-width:0;border-right-color:#00000040;left:-11px;margin-top:-11px;top:50%}.popover.right>.arrow:after{border-left-width:0;border-right-color:#fff;bottom:-10px;content:" ";left:1px}.popover.bottom>.arrow{border-bottom-color:#00000040;border-top-width:0;left:50%;margin-left:-11px;top:-11px}.popover.bottom>.arrow:after{border-bottom-color:#fff;border-top-width:0;content:" ";margin-left:-10px;top:1px}.popover.left>.arrow{border-left-color:#00000040;border-right-width:0;margin-top:-11px;right:-11px;top:50%}.popover.left>.arrow:after{border-left-color:#fff;border-right-width:0;bottom:-10px;content:" ";right:1px}.carousel,.carousel-inner{position:relative}.carousel-inner{overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:left .6s ease-in-out;-o-transition:left .6s ease-in-out;transition:left .6s ease-in-out}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@supports (transform:translate3d){.carousel-inner>.item{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;-moz-perspective:1000;perspective:1000;-webkit-transition:-webkit-transform .6s ease-in-out;-moz-transition:-moz-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translateZ(0);transform:translateZ(0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{bottom:0;color:#fff;font-size:20px;left:0;opacity:.5;position:absolute;text-align:center;text-shadow:0 1px 2px #0009;top:0;width:15%}.carousel-control.left{background-image:-webkit-linear-gradient(left,#00000080,#0000);background-image:-o-linear-gradient(left,#00000080 0,#0000 100%);background-image:linear-gradient(90deg,#00000080 0,#0000);background-repeat:repeat-x}.carousel-control.right{background-image:-webkit-linear-gradient(left,#0000,#00000080);background-image:-o-linear-gradient(left,#0000 0,#00000080 100%);background-image:linear-gradient(90deg,#0000 0,#00000080);background-repeat:repeat-x;left:auto;right:0}.carousel-control:focus,.carousel-control:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{display:inline-block;position:absolute;top:50%;z-index:5}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px;right:50%}.carousel-control .icon-next,.carousel-control .icon-prev{font-family:serif;height:20px;line-height:1;margin-top:-10px;width:20px}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{bottom:10px;left:50%;list-style:none;margin-left:-30%;padding-left:0;position:absolute;text-align:center;width:60%;z-index:15}.carousel-indicators li{background-color:#000\9;background-color:#0000;border:1px solid #fff;border-radius:10px;cursor:pointer;display:inline-block;height:10px;margin:1px;text-indent:-999px;width:10px}.carousel-indicators .active{background-color:#fff;height:12px;margin:0;width:12px}.carousel-caption{bottom:20px;color:#fff;left:15%;padding-bottom:20px;padding-top:20px;position:absolute;right:15%;text-align:center;text-shadow:0 1px 2px #0009;z-index:10}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{font-size:30px;height:30px;margin-top:-15px;width:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{left:20%;padding-bottom:30px;right:20%}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{content:" ";display:table}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}.visible-xs-block{display:block!important}.visible-xs-inline{display:inline!important}.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}.visible-sm-block{display:block!important}.visible-sm-inline{display:inline!important}.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}.visible-md-block{display:block!important}.visible-md-inline{display:inline!important}.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}.visible-lg-block{display:block!important}.visible-lg-inline{display:inline!important}.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}.hidden-print{display:none!important}} \ No newline at end of file diff --git a/providers/fab/src/airflow/providers/fab/www/static/dist/manifest.json b/providers/fab/src/airflow/providers/fab/www/static/dist/manifest.json index 049ccd78ca61c..144d1e2c3b650 100644 --- a/providers/fab/src/airflow/providers/fab/www/static/dist/manifest.json +++ b/providers/fab/src/airflow/providers/fab/www/static/dist/manifest.json @@ -10,8 +10,8 @@ "materialIcons.css": "materialIcons.3e67dd6fbfcc4f3b5105.css", "materialIcons.js": "materialIcons.3e67dd6fbfcc4f3b5105.js", "moment.js": "moment.9baee5ec3d7639a10897.js", - "runtime.js": "runtime.ad800fc1845ad5c6ddeb.js", - "743.js": "743.fc7a7c6ef9d09365976e.js", + "runtime.js": "runtime.6ad9da077ea169d60db9.js", + "743.js": "743.935ed3d26e56ed8f63d3.js", "jquery-ui.min.js": "jquery-ui.min.js", "jquery-ui.min.css": "jquery-ui.min.css", "oss-licenses.json": "oss-licenses.json", diff --git a/providers/fab/src/airflow/providers/fab/www/static/dist/materialIcons.3e67dd6fbfcc4f3b5105.css b/providers/fab/src/airflow/providers/fab/www/static/dist/materialIcons.3e67dd6fbfcc4f3b5105.css index c10472d9cd0bc..e4b7e396d3c27 100644 --- a/providers/fab/src/airflow/providers/fab/www/static/dist/materialIcons.3e67dd6fbfcc4f3b5105.css +++ b/providers/fab/src/airflow/providers/fab/www/static/dist/materialIcons.3e67dd6fbfcc4f3b5105.css @@ -15,4 +15,4 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */@font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url(data:font/woff2;base64,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) format("woff2")}.material-icons{display:inline-block;font-family:Material Icons;font-size:20px;font-style:normal;font-weight:400;letter-spacing:normal;line-height:1;text-transform:none;word-wrap:normal;direction:ltr;position:relative;top:-.05em;vertical-align:middle;white-space:nowrap;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:"liga"}.material-icons.md-18{font-size:18px}.material-icons.md-24{font-size:24px}.material-icons.md-36{font-size:36px}.material-icons.md-48{font-size:48px}.dropdown-menu>li>a>.material-icons,.dropdown-menu>li>form>button>.material-icons{margin-right:6px}.custom-icon{position:relative;top:-.1em;vertical-align:middle;fill:currentColor;stroke-width:0} \ No newline at end of file + */@font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url(data:font/woff2;base64,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) format("woff2")}.material-icons{display:inline-block;font-family:Material Icons;font-size:20px;font-style:normal;font-weight:400;letter-spacing:normal;line-height:1;text-transform:none;word-wrap:normal;direction:ltr;position:relative;top:-.05em;vertical-align:middle;white-space:nowrap;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:"liga"}.material-icons.md-18{font-size:18px}.material-icons.md-24{font-size:24px}.material-icons.md-36{font-size:36px}.material-icons.md-48{font-size:48px}.dropdown-menu>li>a>.material-icons,.dropdown-menu>li>form>button>.material-icons{margin-right:6px}.custom-icon{fill:currentColor;position:relative;stroke-width:0;top:-.1em;vertical-align:middle} \ No newline at end of file diff --git a/providers/fab/src/airflow/providers/fab/www/static/dist/runtime.6ad9da077ea169d60db9.js b/providers/fab/src/airflow/providers/fab/www/static/dist/runtime.6ad9da077ea169d60db9.js new file mode 100644 index 0000000000000..04f13d7aa8fb3 --- /dev/null +++ b/providers/fab/src/airflow/providers/fab/www/static/dist/runtime.6ad9da077ea169d60db9.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,r={},o={};function t(e){var n=o[e];if(void 0!==n)return n.exports;var l=o[e]={id:e,loaded:!1,exports:{}};return r[e].call(l.exports,l,l.exports,t),l.loaded=!0,l.exports}t.m=r,e=[],t.O=(r,o,n,l)=>{if(!o){var i=1/0;for(p=0;p=l)&&Object.keys(t.O).every(e=>t.O[e](o[f]))?o.splice(f--,1):(a=!1,l0&&e[p-1][2]>l;p--)e[p]=e[p-1];e[p]=[o,n,l]},t.d=(e,r)=>{for(var o in r)t.o(r,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},t.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e={121:0};t.O.j=r=>0===e[r];var r=(r,o)=>{var n,l,[i,a,f]=o,d=0;if(i.some(r=>0!==e[r])){for(n in a)t.o(a,n)&&(t.m[n]=a[n]);if(f)var p=f(t)}for(r&&r(o);d{"use strict";var e,r={},o={};function t(e){var n=o[e];if(void 0!==n)return n.exports;var l=o[e]={id:e,loaded:!1,exports:{}};return r[e].call(l.exports,l,l.exports,t),l.loaded=!0,l.exports}t.m=r,e=[],t.O=(r,o,n,l)=>{if(!o){var i=1/0;for(p=0;p=l)&&Object.keys(t.O).every(e=>t.O[e](o[f]))?o.splice(f--,1):(a=!1,l0&&e[p-1][2]>l;p--)e[p]=e[p-1];e[p]=[o,n,l]},t.d=(e,r)=>{for(var o in r)t.o(r,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},t.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e={121:0};t.O.j=r=>0===e[r];var r=(r,o)=>{var n,l,i=o[0],a=o[1],f=o[2],d=0;if(i.some(r=>0!==e[r])){for(n in a)t.o(a,n)&&(t.m[n]=a[n]);if(f)var p=f(t)}for(r&&r(o);d=6.1.2", "gcloud-aio-storage>=9.0.0", "gcsfs>=2023.10.0", - "google-ads>=26.0.0", + "google-ads>=26.0.0,!=28.0.0.post2", "google-analytics-admin>=0.9.0", # Google-api-core 2.16.0 back-compat issue: # - https://github.com/googleapis/python-api-core/issues/576 diff --git a/providers/google/src/airflow/providers/google/cloud/utils/bigquery_get_data.py b/providers/google/src/airflow/providers/google/cloud/utils/bigquery_get_data.py index 6e1df55286dd0..6218f3df51614 100644 --- a/providers/google/src/airflow/providers/google/cloud/utils/bigquery_get_data.py +++ b/providers/google/src/airflow/providers/google/cloud/utils/bigquery_get_data.py @@ -23,9 +23,9 @@ if TYPE_CHECKING: from collections.abc import Iterator - from logging import Logger from airflow.providers.google.cloud.hooks.bigquery import BigQueryHook + from airflow.sdk.types import Logger def bigquery_get_data( diff --git a/providers/keycloak/src/airflow/providers/keycloak/auth_manager/routes/login.py b/providers/keycloak/src/airflow/providers/keycloak/auth_manager/routes/login.py index 99d42dce36ccc..e8681188b361e 100644 --- a/providers/keycloak/src/airflow/providers/keycloak/auth_manager/routes/login.py +++ b/providers/keycloak/src/airflow/providers/keycloak/auth_manager/routes/login.py @@ -30,6 +30,7 @@ from airflow.configuration import conf from airflow.providers.keycloak.auth_manager.keycloak_auth_manager import KeycloakAuthManager from airflow.providers.keycloak.auth_manager.user import KeycloakAuthManagerUser +from airflow.providers.keycloak.version_compat import AIRFLOW_V_3_1_1_PLUS log = logging.getLogger(__name__) login_router = AirflowRouter(tags=["KeycloakAuthManagerLogin"]) @@ -70,7 +71,12 @@ def login_callback(request: Request): response = RedirectResponse(url=conf.get("api", "base_url", fallback="/"), status_code=303) secure = bool(conf.get("api", "ssl_cert", fallback="")) - response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure) + # In Airflow 3.1.1 authentication changes, front-end no longer handle the token + # See https://github.com/apache/airflow/pull/55506 + if AIRFLOW_V_3_1_1_PLUS: + response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure, httponly=True) + else: + response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure) return response diff --git a/providers/keycloak/src/airflow/providers/keycloak/version_compat.py b/providers/keycloak/src/airflow/providers/keycloak/version_compat.py new file mode 100644 index 0000000000000..384af03bd1ed5 --- /dev/null +++ b/providers/keycloak/src/airflow/providers/keycloak/version_compat.py @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# NOTE! THIS FILE IS COPIED MANUALLY IN OTHER PROVIDERS DELIBERATELY TO AVOID ADDING UNNECESSARY +# DEPENDENCIES BETWEEN PROVIDERS. IF YOU WANT TO ADD CONDITIONAL CODE IN YOUR PROVIDER THAT DEPENDS +# ON AIRFLOW VERSION, PLEASE COPY THIS FILE TO THE ROOT PACKAGE OF YOUR PROVIDER AND IMPORT +# THOSE CONSTANTS FROM IT RATHER THAN IMPORTING THEM FROM ANOTHER PROVIDER OR TEST CODE +# +from __future__ import annotations + + +def get_base_airflow_version_tuple() -> tuple[int, int, int]: + from packaging.version import Version + + from airflow import __version__ + + airflow_version = Version(__version__) + return airflow_version.major, airflow_version.minor, airflow_version.micro + + +AIRFLOW_V_3_1_1_PLUS = get_base_airflow_version_tuple() >= (3, 1, 1) diff --git a/providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py b/providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py index dc87b5a9da758..90b7b2b4a1caf 100644 --- a/providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py +++ b/providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py @@ -17,6 +17,7 @@ from __future__ import annotations import copy +import logging import os import tempfile from pathlib import Path @@ -139,14 +140,15 @@ def test_wasb_read(self, mock_hook_cls, ti): "airflow.providers.microsoft.azure.hooks.wasb.WasbHook", **{"return_value.read_file.side_effect": AzureHttpError("failed to connect", 404)}, ) - def test_wasb_read_raises(self, mock_hook): + def test_wasb_read_raises(self, mock_hook, caplog): handler = self.wasb_task_handler - with mock.patch.object(handler.io.log, "error") as mock_error: + with caplog.at_level(logging.ERROR): handler.io.wasb_read(self.remote_log_location, return_error=True) - mock_error.assert_called_once_with( - "Could not read logs from remote/log/location/1.log", - exc_info=True, - ) + assert len(caplog.records) == 1 + rec = caplog.records[0] + assert rec.levelno == logging.ERROR + assert rec.message == "Could not read logs from remote/log/location/1.log" + assert rec.exc_info is not None @mock.patch("airflow.providers.microsoft.azure.hooks.wasb.WasbHook") @mock.patch.object(WasbRemoteLogIO, "wasb_read") @@ -180,17 +182,19 @@ def test_write_when_append_is_false(self, mock_hook): "text", self.container_name, self.remote_log_location, overwrite=True ) - def test_write_raises(self): + def test_write_raises(self, caplog): handler = self.wasb_task_handler - with mock.patch.object(handler.io.log, "error") as mock_error: + with caplog.at_level(logging.ERROR): with mock.patch("airflow.providers.microsoft.azure.hooks.wasb.WasbHook") as mock_hook: mock_hook.return_value.load_string.side_effect = AzureHttpError("failed to connect", 404) handler.io.write("text", self.remote_log_location, append=False) - mock_error.assert_called_once_with( - "Could not write logs to %s", "remote/log/location/1.log", exc_info=True - ) + assert len(caplog.records) == 1 + rec = caplog.records[0] + assert rec.levelno == logging.ERROR + assert rec.message == "Could not write logs to remote/log/location/1.log" + assert rec.exc_info is not None @pytest.mark.parametrize( "delete_local_copy, expected_existence_of_local_copy", diff --git a/providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/hooks/psrp.py b/providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/hooks/psrp.py index 8e87f564189e4..2308fd1b1bce4 100644 --- a/providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/hooks/psrp.py +++ b/providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/hooks/psrp.py @@ -19,7 +19,6 @@ from collections.abc import Callable, Generator from contextlib import contextmanager -from copy import copy from logging import DEBUG, ERROR, INFO, WARNING from typing import TYPE_CHECKING, Any, cast from weakref import WeakKeyDictionary @@ -168,8 +167,15 @@ def invoke(self) -> Generator[PowerShell, None, None]: Upon exit, the commands will be invoked. """ - logger = copy(self.log) - logger.setLevel(self._logging_level) + logger = self.log + # Compat: Airflow 3.1 use structlog, and doesn't have individual per-logger level + if hasattr(logger, "setLevel"): + logger.setLevel(self._logging_level) + elif not logger.is_enabled_for(self._logging_level): + from airflow.sdk.log import logger_at_level + + logger = logger_at_level(logger.name, self._logging_level) + local_context = self._conn is None if local_context: self.__enter__() diff --git a/providers/microsoft/psrp/tests/unit/microsoft/psrp/operators/test_psrp.py b/providers/microsoft/psrp/tests/unit/microsoft/psrp/operators/test_psrp.py index c38c8ad1be8f7..ca5642247058e 100644 --- a/providers/microsoft/psrp/tests/unit/microsoft/psrp/operators/test_psrp.py +++ b/providers/microsoft/psrp/tests/unit/microsoft/psrp/operators/test_psrp.py @@ -100,7 +100,7 @@ def test_execute(self, hook_impl, parameter, had_errors, rc, do_xcom_push): else: output = op.execute(None) assert output == [json.loads(output) for output in ps.output] if do_xcom_push else ps.output - is_logged = hook_impl.call_args.kwargs["on_output_callback"] == op.log.info + is_logged = hook_impl.call_args.kwargs["on_output_callback"] is not None assert do_xcom_push ^ is_logged expected_ps_calls = [ call.add_command(psrp_session_init), diff --git a/providers/openlineage/src/airflow/providers/openlineage/utils/selective_enable.py b/providers/openlineage/src/airflow/providers/openlineage/utils/selective_enable.py index 30dc825d4394f..edf6f9c858f84 100644 --- a/providers/openlineage/src/airflow/providers/openlineage/utils/selective_enable.py +++ b/providers/openlineage/src/airflow/providers/openlineage/utils/selective_enable.py @@ -24,8 +24,10 @@ from airflow.models.xcom_arg import XComArg if TYPE_CHECKING: + from airflow.providers.openlineage.utils.utils import AnyOperator from airflow.sdk import DAG, BaseOperator from airflow.sdk.definitions.mappedoperator import MappedOperator + from airflow.serialization.serialized_objects import SerializedDAG T = TypeVar("T", bound=DAG | BaseOperator | MappedOperator) else: @@ -76,7 +78,7 @@ def disable_lineage(obj: T) -> T: return obj -def is_task_lineage_enabled(task: BaseOperator | MappedOperator) -> bool: +def is_task_lineage_enabled(task: AnyOperator) -> bool: """Check if selective enable OpenLineage parameter is set to True on task level.""" if task.params.get(ENABLE_OL_PARAM_NAME) is False: log.debug( @@ -85,7 +87,7 @@ def is_task_lineage_enabled(task: BaseOperator | MappedOperator) -> bool: return task.params.get(ENABLE_OL_PARAM_NAME) is True -def is_dag_lineage_enabled(dag: DAG) -> bool: +def is_dag_lineage_enabled(dag: DAG | SerializedDAG) -> bool: """ Check if DAG is selectively enabled to emit OpenLineage events. diff --git a/providers/openlineage/src/airflow/providers/openlineage/utils/utils.py b/providers/openlineage/src/airflow/providers/openlineage/utils/utils.py index b9b66b5f42953..d08868961fe5c 100644 --- a/providers/openlineage/src/airflow/providers/openlineage/utils/utils.py +++ b/providers/openlineage/src/airflow/providers/openlineage/utils/utils.py @@ -34,6 +34,7 @@ # TODO: move this maybe to Airflow's logic? from airflow.models import DagRun, TaskReschedule +from airflow.models.mappedoperator import MappedOperator as SerializedMappedOperator from airflow.providers.openlineage import ( __version__ as OPENLINEAGE_PROVIDER_VERSION, conf, @@ -53,7 +54,7 @@ is_task_lineage_enabled, ) from airflow.providers.openlineage.version_compat import AIRFLOW_V_3_0_PLUS, get_base_airflow_version_tuple -from airflow.serialization.serialized_objects import SerializedBaseOperator +from airflow.serialization.serialized_objects import SerializedBaseOperator, SerializedDAG from airflow.utils.module_loading import import_string if AIRFLOW_V_3_0_PLUS: @@ -65,6 +66,8 @@ from airflow.utils.session import NEW_SESSION, provide_session if TYPE_CHECKING: + from typing import TypeAlias + from openlineage.client.event_v2 import Dataset as OpenLineageDataset from openlineage.client.facet_v2 import RunFacet, processing_engine_run @@ -79,6 +82,8 @@ ) from airflow.sdk.execution_time.task_runner import RuntimeTaskInstance from airflow.utils.state import DagRunState, TaskInstanceState + + AnyOperator: TypeAlias = BaseOperator | MappedOperator | SerializedBaseOperator | SerializedMappedOperator else: try: from airflow.sdk import DAG, BaseOperator @@ -128,13 +133,13 @@ def try_import_from_string(string: str) -> Any: return import_string(string) -def get_operator_class(task: BaseOperator) -> type: +def get_operator_class(task: BaseOperator | MappedOperator) -> type: if task.__class__.__name__ in ("DecoratedMappedOperator", "MappedOperator"): return task.operator_class return task.__class__ -def get_operator_provider_version(operator: BaseOperator | MappedOperator) -> str | None: +def get_operator_provider_version(operator: AnyOperator) -> str | None: """Get the provider package version for the given operator.""" try: class_path = get_fully_qualified_class_name(operator) @@ -214,7 +219,7 @@ def _truncate_string_to_byte_size(s: str, max_size: int = _MAX_DOC_BYTES) -> str return truncated.decode("utf-8", errors="ignore") -def get_task_documentation(operator: BaseOperator | MappedOperator | None) -> tuple[str | None, str | None]: +def get_task_documentation(operator: AnyOperator | None) -> tuple[str | None, str | None]: """Get task documentation and mime type, truncated to _MAX_DOC_BYTES bytes length, if present.""" if not operator: return None, None @@ -241,7 +246,7 @@ def get_task_documentation(operator: BaseOperator | MappedOperator | None) -> tu return None, None -def get_dag_documentation(dag: DAG | None) -> tuple[str | None, str | None]: +def get_dag_documentation(dag: DAG | SerializedDAG | None) -> tuple[str | None, str | None]: """Get dag documentation and mime type, truncated to _MAX_DOC_BYTES bytes length, if present.""" if not dag: return None, None @@ -312,23 +317,23 @@ def get_user_provided_run_facets(ti: TaskInstance, ti_state: TaskInstanceState) return custom_facets -def get_fully_qualified_class_name(operator: BaseOperator | MappedOperator) -> str: - if isinstance(operator, (MappedOperator, SerializedBaseOperator)): +def get_fully_qualified_class_name(operator: AnyOperator) -> str: + if isinstance(operator, (SerializedMappedOperator, SerializedBaseOperator)): # as in airflow.api_connexion.schemas.common_schema.ClassReferenceSchema return operator._task_module + "." + operator.task_type op_class = get_operator_class(operator) return op_class.__module__ + "." + op_class.__name__ -def is_operator_disabled(operator: BaseOperator | MappedOperator) -> bool: +def is_operator_disabled(operator: AnyOperator) -> bool: return get_fully_qualified_class_name(operator) in conf.disabled_operators() -def is_selective_lineage_enabled(obj: DAG | BaseOperator | MappedOperator) -> bool: +def is_selective_lineage_enabled(obj: DAG | SerializedDAG | AnyOperator) -> bool: """If selective enable is active check if DAG or Task is enabled to emit events.""" if not conf.selective_enable(): return True - if isinstance(obj, DAG): + if isinstance(obj, (DAG, SerializedDAG)): return is_dag_lineage_enabled(obj) if isinstance(obj, (BaseOperator, MappedOperator)): return is_task_lineage_enabled(obj) @@ -749,7 +754,7 @@ def get_airflow_state_run_facet( } -def _get_tasks_details(dag: DAG) -> dict: +def _get_tasks_details(dag: DAG | SerializedDAG) -> dict: tasks = { single_task.task_id: { "operator": get_fully_qualified_class_name(single_task), @@ -768,7 +773,7 @@ def _get_tasks_details(dag: DAG) -> dict: return tasks -def _get_task_groups_details(dag: DAG) -> dict: +def _get_task_groups_details(dag: DAG | SerializedDAG) -> dict: return { tg_id: { "parent_group": tg.parent_group.group_id, @@ -780,7 +785,7 @@ def _get_task_groups_details(dag: DAG) -> dict: } -def _emits_ol_events(task: BaseOperator | MappedOperator) -> bool: +def _emits_ol_events(task: AnyOperator) -> bool: config_selective_enabled = is_selective_lineage_enabled(task) config_disabled_for_operators = is_operator_disabled(task) # empty operators without callbacks/outlets are skipped for optimization by Airflow diff --git a/providers/smtp/provider.yaml b/providers/smtp/provider.yaml index 1e57ded9170d1..12888e1dfd68c 100644 --- a/providers/smtp/provider.yaml +++ b/providers/smtp/provider.yaml @@ -29,6 +29,7 @@ source-date-epoch: 1756877538 # In such case adding >= NEW_VERSION and bumping to NEW_VERSION in a provider have # to be done in the same PR versions: + - 2.3.1 - 2.2.1 - 2.2.0 - 2.1.2 diff --git a/providers/smtp/pyproject.toml b/providers/smtp/pyproject.toml index ac31d92cb0f95..fbffc9f60e24a 100644 --- a/providers/smtp/pyproject.toml +++ b/providers/smtp/pyproject.toml @@ -25,7 +25,7 @@ build-backend = "flit_core.buildapi" [project] name = "apache-airflow-providers-smtp" -version = "2.2.1" +version = "2.3.1" description = "Provider package apache-airflow-providers-smtp for Apache Airflow" readme = "README.rst" authors = [ @@ -96,8 +96,8 @@ apache-airflow-providers-common-sql = {workspace = true} apache-airflow-providers-standard = {workspace = true} [project.urls] -"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-smtp/2.2.1" -"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-smtp/2.2.1/changelog.html" +"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-smtp/2.3.1" +"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-smtp/2.3.1/changelog.html" "Bug Tracker" = "https://github.com/apache/airflow/issues" "Source Code" = "https://github.com/apache/airflow" "Slack Chat" = "https://s.apache.org/airflow-slack" diff --git a/providers/smtp/src/airflow/providers/smtp/__init__.py b/providers/smtp/src/airflow/providers/smtp/__init__.py index 2c0f51c66f5a0..1e3f8c6c78c63 100644 --- a/providers/smtp/src/airflow/providers/smtp/__init__.py +++ b/providers/smtp/src/airflow/providers/smtp/__init__.py @@ -29,7 +29,7 @@ __all__ = ["__version__"] -__version__ = "2.2.1" +__version__ = "2.3.1" if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse( "2.10.0" diff --git a/providers/snowflake/pyproject.toml b/providers/snowflake/pyproject.toml index 6f0f59c4658a6..9c120db632a78 100644 --- a/providers/snowflake/pyproject.toml +++ b/providers/snowflake/pyproject.toml @@ -66,10 +66,10 @@ dependencies = [ "pyarrow>=18.0.0; python_version >= '3.13'", "snowflake-connector-python>=3.7.1", "snowflake-sqlalchemy>=1.4.0", - "snowflake-snowpark-python>=1.17.0;python_version<'3.12'", # The "<9999" is a hint to the pip resolver to resolve this requirement early, # can be removed when the pip resolver is improved - "snowflake-snowpark-python>=1.27.0,<9999;python_version>='3.12' and python_version<'3.13'", + "snowflake-snowpark-python>=1.17.0,<9999;python_version<'3.12'", + "snowflake-snowpark-python>=1.27.0,<9999;python_version>='3.12' and python_version<'3.14'", ] # The optional dependencies should be modified in place in the generated file diff --git a/providers/snowflake/src/airflow/providers/snowflake/hooks/snowflake_sql_api.py b/providers/snowflake/src/airflow/providers/snowflake/hooks/snowflake_sql_api.py index 558e3bf564aaa..9f3e7c68be8b3 100644 --- a/providers/snowflake/src/airflow/providers/snowflake/hooks/snowflake_sql_api.py +++ b/providers/snowflake/src/airflow/providers/snowflake/hooks/snowflake_sql_api.py @@ -102,7 +102,7 @@ def __init__( "retry": retry_if_exception(self._should_retry_on_error), "wait": wait_exponential(multiplier=1, min=1, max=60), "stop": stop_after_attempt(5), - "before_sleep": before_sleep_log(self.log, log_level=20), # INFO level + "before_sleep": before_sleep_log(self.log, log_level=20), # type: ignore[arg-type] "reraise": True, } if api_retry_args: diff --git a/providers/ssh/src/airflow/providers/ssh/hooks/ssh.py b/providers/ssh/src/airflow/providers/ssh/hooks/ssh.py index 43fca90dce57b..3fcb1ff9fceab 100644 --- a/providers/ssh/src/airflow/providers/ssh/hooks/ssh.py +++ b/providers/ssh/src/airflow/providers/ssh/hooks/ssh.py @@ -19,6 +19,7 @@ from __future__ import annotations +import logging import os from base64 import decodebytes from collections.abc import Sequence @@ -391,6 +392,11 @@ def get_tunnel( host_pkey_directories=None, ) + if not hasattr(self.log, "handlers"): + # We need to not hit this https://github.com/pahaz/sshtunnel/blob/dc0732884379a19a21bf7a49650d0708519ec54f/sshtunnel.py#L238-L239 + paramkio_log = logging.getLogger("paramiko.transport") + paramkio_log.addHandler(logging.NullHandler()) + paramkio_log.propagate = True client = SSHTunnelForwarder(self.remote_host, **tunnel_kwargs) return client diff --git a/providers/standard/provider.yaml b/providers/standard/provider.yaml index e26410cd3a343..a600b0d4ddd98 100644 --- a/providers/standard/provider.yaml +++ b/providers/standard/provider.yaml @@ -27,6 +27,7 @@ source-date-epoch: 1756877597 # In such case adding >= NEW_VERSION and bumping to NEW_VERSION in a provider have # to be done in the same PR versions: + - 1.9.0 - 1.7.0 - 1.6.0 - 1.5.0 diff --git a/providers/standard/pyproject.toml b/providers/standard/pyproject.toml index 73919ece30f0d..ffe78afd6d65a 100644 --- a/providers/standard/pyproject.toml +++ b/providers/standard/pyproject.toml @@ -25,7 +25,7 @@ build-backend = "flit_core.buildapi" [project] name = "apache-airflow-providers-standard" -version = "1.7.0" +version = "1.9.0" description = "Provider package apache-airflow-providers-standard for Apache Airflow" readme = "README.rst" authors = [ @@ -95,8 +95,8 @@ apache-airflow-providers-common-sql = {workspace = true} apache-airflow-providers-standard = {workspace = true} [project.urls] -"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-standard/1.7.0" -"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-standard/1.7.0/changelog.html" +"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-standard/1.9.0" +"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-standard/1.9.0/changelog.html" "Bug Tracker" = "https://github.com/apache/airflow/issues" "Source Code" = "https://github.com/apache/airflow" "Slack Chat" = "https://s.apache.org/airflow-slack" diff --git a/providers/standard/src/airflow/providers/standard/__init__.py b/providers/standard/src/airflow/providers/standard/__init__.py index f401e7c10ad04..0bb1e166f9391 100644 --- a/providers/standard/src/airflow/providers/standard/__init__.py +++ b/providers/standard/src/airflow/providers/standard/__init__.py @@ -29,7 +29,7 @@ __all__ = ["__version__"] -__version__ = "1.7.0" +__version__ = "1.9.0" if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse( "2.10.0" diff --git a/providers/standard/src/airflow/providers/standard/example_dags/example_hitl_operator.py b/providers/standard/src/airflow/providers/standard/example_dags/example_hitl_operator.py index dd7b4dc277fdd..44d77ba4959a2 100644 --- a/providers/standard/src/airflow/providers/standard/example_dags/example_hitl_operator.py +++ b/providers/standard/src/airflow/providers/standard/example_dags/example_hitl_operator.py @@ -140,6 +140,7 @@ def notify(self, context: Context) -> None: notifiers=[hitl_request_callback], on_success_callback=hitl_success_callback, on_failure_callback=hitl_failure_callback, + assigned_users=[{"id": "admin", "name": "admin"}], ) # [END howto_hitl_approval_operator] diff --git a/providers/standard/src/airflow/providers/standard/exceptions.py b/providers/standard/src/airflow/providers/standard/exceptions.py index f47e9f3896ffb..98449fed17325 100644 --- a/providers/standard/src/airflow/providers/standard/exceptions.py +++ b/providers/standard/src/airflow/providers/standard/exceptions.py @@ -57,7 +57,7 @@ class DuplicateStateError(AirflowExternalTaskSensorException): """Raised when duplicate states are provided across allowed, skipped and failed states.""" -class HITLTriggerEventError(AirflowException): +class HITLTriggerEventError(Exception): """Raised when TriggerEvent contains error.""" diff --git a/providers/standard/src/airflow/providers/standard/operators/hitl.py b/providers/standard/src/airflow/providers/standard/operators/hitl.py index 440abf9a516c4..f40abe1e467a7 100644 --- a/providers/standard/src/airflow/providers/standard/operators/hitl.py +++ b/providers/standard/src/airflow/providers/standard/operators/hitl.py @@ -41,6 +41,7 @@ if TYPE_CHECKING: from airflow.sdk.definitions.context import Context + from airflow.sdk.execution_time.hitl import HITLUser from airflow.sdk.types import RuntimeTaskInstanceProtocol @@ -70,7 +71,7 @@ def __init__( multiple: bool = False, params: ParamsDict | dict[str, Any] | None = None, notifiers: Sequence[BaseNotifier] | BaseNotifier | None = None, - respondents: str | list[str] | None = None, + assigned_users: HITLUser | list[HITLUser] | None = None, **kwargs, ) -> None: super().__init__(**kwargs) @@ -86,7 +87,7 @@ def __init__( self.notifiers: Sequence[BaseNotifier] = ( [notifiers] if isinstance(notifiers, BaseNotifier) else notifiers or [] ) - self.respondents = [respondents] if isinstance(respondents, str) else respondents + self.assigned_users = [assigned_users] if isinstance(assigned_users, dict) else assigned_users self.validate_options() self.validate_params() @@ -138,7 +139,7 @@ def execute(self, context: Context): defaults=self.defaults, multiple=self.multiple, params=self.serialized_params, - respondents=self.respondents, + assigned_users=self.assigned_users, ) if self.execution_timeout: @@ -178,10 +179,12 @@ def execute_complete(self, context: Context, event: dict[str, Any]) -> Any: return HITLTriggerEventSuccessPayload( chosen_options=chosen_options, params_input=params_input, + responded_at=event["responded_at"], + responded_by_user=event["responded_by_user"], ) def process_trigger_event_error(self, event: dict[str, Any]) -> None: - if "error_type" == "timeout": + if event["error_type"] == "timeout": raise HITLTimeoutError(event) raise HITLTriggerEventError(event) diff --git a/providers/standard/src/airflow/providers/standard/triggers/hitl.py b/providers/standard/src/airflow/providers/standard/triggers/hitl.py index c5f32800058c2..b0b8ec71ef9a3 100644 --- a/providers/standard/src/airflow/providers/standard/triggers/hitl.py +++ b/providers/standard/src/airflow/providers/standard/triggers/hitl.py @@ -25,12 +25,13 @@ import asyncio from collections.abc import AsyncIterator from datetime import datetime -from typing import Any, Literal, TypedDict +from typing import TYPE_CHECKING, Any, Literal, TypedDict from uuid import UUID from asgiref.sync import sync_to_async from airflow.sdk.execution_time.hitl import ( + HITLUser, get_hitl_detail_content_detail, update_hitl_detail_response, ) @@ -43,6 +44,8 @@ class HITLTriggerEventSuccessPayload(TypedDict, total=False): chosen_options: list[str] params_input: dict[str, Any] + responded_by_user: HITLUser | None + responded_at: datetime timedout: bool @@ -100,19 +103,28 @@ async def run(self) -> AsyncIterator[TriggerEvent]: if self.timeout_datetime and self.timeout_datetime < utcnow(): # Fetch latest HITL detail before fallback resp = await sync_to_async(get_hitl_detail_content_detail)(ti_id=self.ti_id) + # Response already received, yield success and exit if resp.response_received and resp.chosen_options: - # Response already received, yield success and exit + if TYPE_CHECKING: + assert resp.responded_by_user is not None + assert resp.responded_at is not None + self.log.info( "[HITL] responded_by=%s (id=%s) options=%s at %s (timeout fallback skipped)", - resp.responded_user_name, - resp.responded_user_id, + resp.responded_by_user.name, + resp.responded_by_user.id, resp.chosen_options, - resp.response_at, + resp.responded_at, ) yield TriggerEvent( HITLTriggerEventSuccessPayload( chosen_options=resp.chosen_options, params_input=resp.params_input or {}, + responded_at=resp.responded_at, + responded_by_user=HITLUser( + id=resp.responded_by_user.id, + name=resp.responded_by_user.name, + ), timedout=False, ) ) @@ -127,11 +139,13 @@ async def run(self) -> AsyncIterator[TriggerEvent]: ) return - await sync_to_async(update_hitl_detail_response)( + resp = await sync_to_async(update_hitl_detail_response)( ti_id=self.ti_id, chosen_options=self.defaults, params_input=self.params, ) + if TYPE_CHECKING: + assert resp.responded_at is not None self.log.info( "[HITL] timeout reached before receiving response, fallback to default %s", self.defaults ) @@ -139,6 +153,8 @@ async def run(self) -> AsyncIterator[TriggerEvent]: HITLTriggerEventSuccessPayload( chosen_options=self.defaults, params_input=self.params, + responded_by_user=None, + responded_at=resp.responded_at, timedout=True, ) ) @@ -146,17 +162,25 @@ async def run(self) -> AsyncIterator[TriggerEvent]: resp = await sync_to_async(get_hitl_detail_content_detail)(ti_id=self.ti_id) if resp.response_received and resp.chosen_options: + if TYPE_CHECKING: + assert resp.responded_by_user is not None + assert resp.responded_at is not None self.log.info( "[HITL] responded_by=%s (id=%s) options=%s at %s", - resp.responded_user_name, - resp.responded_user_id, + resp.responded_by_user.name, + resp.responded_by_user.id, resp.chosen_options, - resp.response_at, + resp.responded_at, ) yield TriggerEvent( HITLTriggerEventSuccessPayload( chosen_options=resp.chosen_options, params_input=resp.params_input or {}, + responded_at=resp.responded_at, + responded_by_user=HITLUser( + id=resp.responded_by_user.id, + name=resp.responded_by_user.name, + ), timedout=False, ) ) diff --git a/providers/standard/tests/unit/standard/operators/test_datetime.py b/providers/standard/tests/unit/standard/operators/test_datetime.py index afc1d8ff012e2..0630a7e187912 100644 --- a/providers/standard/tests/unit/standard/operators/test_datetime.py +++ b/providers/standard/tests/unit/standard/operators/test_datetime.py @@ -28,11 +28,15 @@ from airflow.providers.standard.operators.datetime import BranchDateTimeOperator from airflow.providers.standard.operators.empty import EmptyOperator from airflow.timetables.base import DataInterval -from airflow.utils import timezone from airflow.utils.session import create_session from airflow.utils.state import State -from tests_common.test_utils.version_compat import AIRFLOW_V_3_0_1, AIRFLOW_V_3_0_PLUS +from tests_common.test_utils.version_compat import AIRFLOW_V_3_0_1, AIRFLOW_V_3_0_PLUS, AIRFLOW_V_3_1_PLUS + +if AIRFLOW_V_3_1_PLUS: + from airflow.sdk import timezone +else: + from airflow.utils import timezone # type: ignore[attr-defined,no-redef] pytestmark = pytest.mark.db_test @@ -113,7 +117,7 @@ def test_no_target_time(self): follow_task_ids_if_false="branch_2", target_upper=None, target_lower=None, - dag=self.dag, + dag=self.dag_maker.dag, ) @pytest.mark.parametrize( diff --git a/providers/standard/tests/unit/standard/operators/test_hitl.py b/providers/standard/tests/unit/standard/operators/test_hitl.py index 18646ab118dd6..f198cc461cf92 100644 --- a/providers/standard/tests/unit/standard/operators/test_hitl.py +++ b/providers/standard/tests/unit/standard/operators/test_hitl.py @@ -18,6 +18,8 @@ import pytest +from airflow.providers.standard.exceptions import HITLTimeoutError, HITLTriggerEventError + from tests_common.test_utils.version_compat import AIRFLOW_V_3_1_PLUS if not AIRFLOW_V_3_1_PLUS: @@ -43,6 +45,7 @@ ) from airflow.sdk import Param, timezone from airflow.sdk.definitions.param import ParamsDict +from airflow.sdk.execution_time.hitl import HITLUser from tests_common.test_utils.config import conf_vars @@ -66,7 +69,7 @@ def hitl_task_and_ti_for_generating_link(dag_maker: DagMaker) -> tuple[HITLOpera options=["1", "2", "3", "4", "5"], body="This is body", defaults=["1"], - respondents="test", + assigned_users=HITLUser(id="test", name="test"), multiple=True, params=ParamsDict({"input_1": 1, "input_2": 2, "input_3": 3}), ) @@ -165,7 +168,7 @@ def test_execute(self, dag_maker: DagMaker, session: Session) -> None: options=["1", "2", "3", "4", "5"], body="This is body", defaults=["1"], - respondents="test", + assigned_users=HITLUser(id="test", name="test"), multiple=False, params=ParamsDict({"input_1": 1}), notifiers=[notifier], @@ -181,10 +184,9 @@ def test_execute(self, dag_maker: DagMaker, session: Session) -> None: assert hitl_detail_model.defaults == ["1"] assert hitl_detail_model.multiple is False assert hitl_detail_model.params == {"input_1": 1} - assert hitl_detail_model.respondents == ["test"] - assert hitl_detail_model.response_at is None - assert hitl_detail_model.responded_user_id is None - assert hitl_detail_model.responded_user_name is None + assert hitl_detail_model.assignees == [{"id": "test", "name": "test"}] + assert hitl_detail_model.responded_at is None + assert hitl_detail_model.responded_by is None assert hitl_detail_model.chosen_options is None assert hitl_detail_model.params_input == {} @@ -230,13 +232,46 @@ def test_execute_complete(self) -> None: params={"input": 1}, ) + responded_at_dt = timezone.utcnow() + ret = hitl_op.execute_complete( context={}, - event={"chosen_options": ["1"], "params_input": {"input": 2}}, + event={ + "chosen_options": ["1"], + "params_input": {"input": 2}, + "responded_at": responded_at_dt, + "responded_by_user": {"id": "test", "name": "test"}, + }, ) - assert ret["chosen_options"] == ["1"] - assert ret["params_input"] == {"input": 2} + assert ret == { + "chosen_options": ["1"], + "params_input": {"input": 2}, + "responded_at": responded_at_dt, + "responded_by_user": {"id": "test", "name": "test"}, + } + + @pytest.mark.parametrize( + "event, expected_exception", + [ + ({"error": "unknown", "error_type": "unknown"}, HITLTriggerEventError), + ({"error": "this is timeotu", "error_type": "timeout"}, HITLTimeoutError), + ], + ) + def test_process_trigger_event_error( + self, + event: dict[str, Any], + expected_exception, + ) -> None: + hitl_op = HITLOperator( + task_id="hitl_test", + subject="This is subject", + body="This is body", + options=["1", "2", "3", "4", "5"], + params={"input": 1}, + ) + with pytest.raises(expected_exception): + hitl_op.process_trigger_event_error(event) def test_validate_chosen_options_with_invalid_content(self) -> None: hitl_op = HITLOperator( @@ -253,6 +288,7 @@ def test_validate_chosen_options_with_invalid_content(self) -> None: event={ "chosen_options": ["not exists"], "params_input": {"input": 2}, + "responded_by_user": {"id": "test", "name": "test"}, }, ) @@ -271,6 +307,7 @@ def test_validate_params_input_with_invalid_input(self) -> None: event={ "chosen_options": ["1"], "params_input": {"no such key": 2, "input": 333}, + "responded_by_user": {"id": "test", "name": "test"}, }, ) @@ -395,14 +432,23 @@ def test_execute_complete(self) -> None: subject="This is subject", ) + responded_at_dt = timezone.utcnow() + ret = hitl_op.execute_complete( context={}, - event={"chosen_options": ["Approve"], "params_input": {}}, + event={ + "chosen_options": ["Approve"], + "params_input": {}, + "responded_at": responded_at_dt, + "responded_by_user": {"id": "test", "name": "test"}, + }, ) assert ret == { "chosen_options": ["Approve"], "params_input": {}, + "responded_at": responded_at_dt, + "responded_by_user": {"id": "test", "name": "test"}, } def test_execute_complete_with_downstream_tasks(self, dag_maker) -> None: @@ -419,7 +465,12 @@ def test_execute_complete_with_downstream_tasks(self, dag_maker) -> None: with pytest.raises(DownstreamTasksSkipped) as exc_info: hitl_op.execute_complete( context={"ti": ti, "task": ti.task}, - event={"chosen_options": ["Reject"], "params_input": {}}, + event={ + "chosen_options": ["Reject"], + "params_input": {}, + "responded_at": timezone.utcnow(), + "responded_by_user": {"id": "test", "name": "test"}, + }, ) assert set(exc_info.value.tasks) == {"op1"} @@ -480,6 +531,8 @@ def test_execute_complete(self, dag_maker) -> None: event={ "chosen_options": ["branch_1"], "params_input": {}, + "responded_at": timezone.utcnow(), + "responded_by_user": {"id": "test", "name": "test"}, }, ) assert set(exc_info.value.tasks) == set((f"branch_{i}", -1) for i in range(2, 6)) @@ -495,6 +548,8 @@ def test_execute_complete_with_multiple_branches(self, dag_maker) -> None: branch_op >> [EmptyOperator(task_id=f"branch_{i}") for i in range(1, 6)] + responded_at_dt = timezone.utcnow() + dr = dag_maker.create_dagrun() ti = dr.get_task_instance("make_choice") with pytest.raises(DownstreamTasksSkipped) as exc_info: @@ -503,6 +558,8 @@ def test_execute_complete_with_multiple_branches(self, dag_maker) -> None: event={ "chosen_options": [f"branch_{i}" for i in range(1, 4)], "params_input": {}, + "responded_at": responded_at_dt, + "responded_by_user": {"id": "test", "name": "test"}, }, ) assert set(exc_info.value.tasks) == set((f"branch_{i}", -1) for i in range(4, 6)) @@ -524,7 +581,12 @@ def test_mapping_applies_for_single_choice(self, dag_maker): with pytest.raises(DownstreamTasksSkipped) as exc: op.execute_complete( context={"ti": ti, "task": ti.task}, - event={"chosen_options": ["Approve"], "params_input": {}}, + event={ + "chosen_options": ["Approve"], + "params_input": {}, + "responded_at": timezone.utcnow(), + "responded_by_user": {"id": "test", "name": "test"}, + }, ) # checks to see that the "archive" task was skipped assert set(exc.value.tasks) == {("archive", -1)} @@ -551,7 +613,12 @@ def test_mapping_with_multiple_choices(self, dag_maker): with pytest.raises(DownstreamTasksSkipped) as exc: op.execute_complete( context={"ti": ti, "task": ti.task}, - event={"chosen_options": ["Approve", "KeepAsIs"], "params_input": {}}, + event={ + "chosen_options": ["Approve", "KeepAsIs"], + "params_input": {}, + "responded_at": timezone.utcnow(), + "responded_by_user": {"id": "test", "name": "test"}, + }, ) # publish + keep chosen → only "other" skipped assert set(exc.value.tasks) == {("other", -1)} @@ -572,7 +639,12 @@ def test_fallback_to_option_when_not_mapped(self, dag_maker): with pytest.raises(DownstreamTasksSkipped) as exc: op.execute_complete( context={"ti": ti, "task": ti.task}, - event={"chosen_options": ["branch_2"], "params_input": {}}, + event={ + "chosen_options": ["branch_2"], + "params_input": {}, + "responded_at": timezone.utcnow(), + "responded_by_user": {"id": "test", "name": "test"}, + }, ) assert set(exc.value.tasks) == {("branch_1", -1)} @@ -593,7 +665,12 @@ def test_error_if_mapped_branch_not_direct_downstream(self, dag_maker): with pytest.raises(AirflowException, match="downstream|not found"): op.execute_complete( context={"ti": ti, "task": ti.task}, - event={"chosen_options": ["Approve"], "params_input": {}}, + event={ + "chosen_options": ["Approve"], + "params_input": {}, + "responded_at": timezone.utcnow(), + "responded_by_user": {"id": "test", "name": "test"}, + }, ) @pytest.mark.parametrize("bad", [123, ["publish"], {"x": "y"}, b"publish"]) diff --git a/providers/standard/tests/unit/standard/operators/test_python.py b/providers/standard/tests/unit/standard/operators/test_python.py index 62ac1f1ae39a5..f025d99a8525b 100644 --- a/providers/standard/tests/unit/standard/operators/test_python.py +++ b/providers/standard/tests/unit/standard/operators/test_python.py @@ -41,7 +41,6 @@ import pytest from slugify import slugify -from airflow.config_templates.airflow_local_settings import DEFAULT_LOGGING_CONFIG from airflow.exceptions import ( AirflowException, AirflowProviderDeprecationWarning, @@ -216,9 +215,6 @@ def render_templates(self, fn, **kwargs): class TestPythonOperator(BasePythonTest): opcls = PythonOperator - def setup_method(self): - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) - @pytest.fixture(autouse=True) def setup_tests(self): self.run = False @@ -1745,9 +1741,6 @@ def f(): class TestExternalPythonOperator(BaseTestPythonVirtualenvOperator): opcls = ExternalPythonOperator - def setup_method(self): - logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) - @staticmethod def default_kwargs(*, python_version=DEFAULT_PYTHON_VERSION, **kwargs): kwargs["python"] = sys.executable @@ -2345,7 +2338,7 @@ def test_short_circuit_with_teardowns_complicated_2(self, dag_maker): assert actual_skipped == {op3} @pytest.mark.parametrize("level", [logging.DEBUG, logging.INFO]) - def test_short_circuit_with_teardowns_debug_level(self, dag_maker, level, clear_db): + def test_short_circuit_with_teardowns_debug_level(self, dag_maker, level, clear_db, caplog): """ When logging is debug we convert to a list to log the tasks skipped before passing them to the skip method. @@ -2357,7 +2350,6 @@ def test_short_circuit_with_teardowns_debug_level(self, dag_maker, level, clear_ task_id="op1", python_callable=lambda: False, ) - op1.log.setLevel(level) op2 = PythonOperator(task_id="op2", python_callable=print) op3 = PythonOperator(task_id="op3", python_callable=print) t1 = PythonOperator(task_id="t1", python_callable=print).as_teardown(setups=s1) @@ -2372,7 +2364,12 @@ def test_short_circuit_with_teardowns_debug_level(self, dag_maker, level, clear_ dagrun = dag_maker.create_dagrun() tis = dagrun.get_task_instances() ti: TaskInstance = next(x for x in tis if x.task_id == "op1") - ti._run_raw_task() + + with caplog.at_level(level): + if hasattr(ti.task.log, "setLevel"): + # Compat with Pre Airflow 3.1 + ti.task.log.setLevel(level) + ti._run_raw_task() # we can't use assert_called_with because it's a set and therefore not ordered actual_kwargs = op1.skip.call_args.kwargs actual_skipped = actual_kwargs["tasks"] diff --git a/providers/standard/tests/unit/standard/sensors/test_external_task_sensor.py b/providers/standard/tests/unit/standard/sensors/test_external_task_sensor.py index a5a068f088f7c..2c6d230e1740a 100644 --- a/providers/standard/tests/unit/standard/sensors/test_external_task_sensor.py +++ b/providers/standard/tests/unit/standard/sensors/test_external_task_sensor.py @@ -1917,7 +1917,8 @@ def _factory(depth: int) -> DagBag: for dag in dags: if AIRFLOW_V_3_0_PLUS: - dag_bag.bag_dag(dag=sync_dag_to_db(dag)) + sync_dag_to_db(dag) + dag_bag.bag_dag(dag=dag) else: dag_bag.bag_dag(dag=dag, root_dag=dag) # type: ignore[call-arg] diff --git a/providers/standard/tests/unit/standard/triggers/test_hitl.py b/providers/standard/tests/unit/standard/triggers/test_hitl.py index 7b33715e68d35..1441d04bfc0ba 100644 --- a/providers/standard/tests/unit/standard/triggers/test_hitl.py +++ b/providers/standard/tests/unit/standard/triggers/test_hitl.py @@ -31,7 +31,7 @@ from uuid6 import uuid7 from airflow._shared.timezones.timezone import utc, utcnow -from airflow.api_fastapi.execution_api.datamodels.hitl import HITLDetailResponse +from airflow.api_fastapi.execution_api.datamodels.hitl import HITLDetailResponse, HITLUser from airflow.providers.standard.triggers.hitl import ( HITLTrigger, HITLTriggerEventFailurePayload, @@ -79,9 +79,8 @@ async def test_run_failed_due_to_timeout(self, mock_update, mock_supervisor_comm ) mock_supervisor_comms.send.return_value = HITLDetailResponse( response_received=False, - responded_user_id=None, - responded_user_name=None, - response_at=None, + responded_by_user=None, + responded_at=None, chosen_options=None, params_input={}, ) @@ -110,9 +109,8 @@ async def test_run_fallback_to_default_due_to_timeout(self, mock_update, mock_lo ) mock_supervisor_comms.send.return_value = HITLDetailResponse( response_received=False, - responded_user_id=None, - responded_user_name=None, - response_at=None, + responded_by_user=None, + responded_at=None, chosen_options=None, params_input={}, ) @@ -123,7 +121,13 @@ async def test_run_fallback_to_default_due_to_timeout(self, mock_update, mock_lo event = await trigger_task assert event == TriggerEvent( - HITLTriggerEventSuccessPayload(chosen_options=["1"], params_input={"input": 1}, timedout=True) + HITLTriggerEventSuccessPayload( + chosen_options=["1"], + params_input={"input": 1}, + responded_by_user=None, + responded_at=mock.ANY, + timedout=True, + ) ) assert mock_log.info.call_args == mock.call( @@ -149,9 +153,8 @@ async def test_run_should_check_response_in_timeout_handler( ) mock_supervisor_comms.send.return_value = HITLDetailResponse( response_received=True, - responded_user_id="1", - responded_user_name="test", - response_at=action_datetime, + responded_by_user=HITLUser(id="1", name="test"), + responded_at=action_datetime, chosen_options=["2"], params_input={}, ) @@ -162,7 +165,13 @@ async def test_run_should_check_response_in_timeout_handler( event = await trigger_task assert event == TriggerEvent( - HITLTriggerEventSuccessPayload(chosen_options=["2"], params_input={}, timedout=False) + HITLTriggerEventSuccessPayload( + chosen_options=["2"], + params_input={}, + responded_at=mock.ANY, + responded_by_user={"id": "1", "name": "test"}, + timedout=False, + ) ) assert mock_log.info.call_args == mock.call( @@ -188,9 +197,8 @@ async def test_run(self, mock_update, mock_log, mock_supervisor_comms, time_mach ) mock_supervisor_comms.send.return_value = HITLDetailResponse( response_received=True, - responded_user_id="test", - responded_user_name="test", - response_at=utcnow(), + responded_by_user=HITLUser(id="test", name="test"), + responded_at=utcnow(), chosen_options=["3"], params_input={"input": 50}, ) @@ -203,6 +211,8 @@ async def test_run(self, mock_update, mock_log, mock_supervisor_comms, time_mach HITLTriggerEventSuccessPayload( chosen_options=["3"], params_input={"input": 50}, + responded_at=mock.ANY, + responded_by_user={"id": "test", "name": "test"}, timedout=False, ) ) diff --git a/pyproject.toml b/pyproject.toml index 788a81f913f90..88c9abda275b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ requires = [ "pluggy==1.6.0", "smmap==5.0.2", "tomli==2.2.1; python_version < '3.11'", - "trove-classifiers==2025.9.8.13", + "trove-classifiers==2025.9.11.17", ] build-backend = "hatchling.build" @@ -64,11 +64,11 @@ classifiers = [ ] # Version is defined in src/airflow/__init__.py and it is automatically synchronized by prek -version = "3.1.0" +version = "3.1.1" dependencies = [ - "apache-airflow-task-sdk<1.2.0,>=1.0.4", - "apache-airflow-core==3.1.0", + "apache-airflow-task-sdk>=1.1.1", + "apache-airflow-core==3.1.1", "natsort>=8.4.0", ] @@ -257,7 +257,7 @@ packages = [] "apache-airflow-providers-jenkins>=3.7.2" ] "keycloak" = [ - "apache-airflow-providers-keycloak" + "apache-airflow-providers-keycloak>=0.0.1" ] "microsoft.azure" = [ "apache-airflow-providers-microsoft-azure>=10.5.1" @@ -444,7 +444,7 @@ packages = [] "apache-airflow-providers-influxdb>=2.8.0", "apache-airflow-providers-jdbc>=4.5.2", "apache-airflow-providers-jenkins>=3.7.2", - "apache-airflow-providers-keycloak", + "apache-airflow-providers-keycloak>=0.0.1", "apache-airflow-providers-microsoft-azure>=10.5.1", "apache-airflow-providers-microsoft-mssql>=3.9.2", "apache-airflow-providers-microsoft-psrp>=3.0.0", @@ -535,7 +535,7 @@ packages = [] "apache-airflow-providers-amazon[s3fs]", ] "uv" = [ - "uv>=0.8.15", + "uv>=0.9.4", ] @@ -1264,8 +1264,9 @@ dev = [ "apache-airflow-kubernetes-tests", "apache-airflow-task-sdk", "apache-airflow-ctl", - "apache-airflow-shared-timezones", + "apache-airflow-shared-logging", "apache-airflow-shared-secrets-masker", + "apache-airflow-shared-timezones", ] # To build docs: @@ -1312,8 +1313,9 @@ apache-airflow-helm-tests = { workspace = true } apache-airflow-kubernetes-tests = { workspace = true } apache-airflow-providers = { workspace = true } apache-aurflow-docker-stack = { workspace = true } -apache-airflow-shared-timezones = { workspace = true } +apache-airflow-shared-logging = { workspace = true } apache-airflow-shared-secrets-masker = { workspace = true } +apache-airflow-shared-timezones = { workspace = true } # Automatically generated provider workspace items (update_airflow_pyproject_toml.py) apache-airflow-providers-airbyte = { workspace = true } apache-airflow-providers-alibaba = { workspace = true } @@ -1429,8 +1431,9 @@ members = [ "task-sdk", "providers-summary-docs", "docker-stack-docs", - "shared/timezones", + "shared/logging", "shared/secrets_masker", + "shared/timezones", # Automatically generated provider workspace members (update_airflow_pyproject_toml.py) "providers/airbyte", "providers/alibaba", diff --git a/reproducible_build.yaml b/reproducible_build.yaml index 5e91bc02e84a2..6bbabcde953fd 100644 --- a/reproducible_build.yaml +++ b/reproducible_build.yaml @@ -1,2 +1,2 @@ -release-notes-hash: 5608b8ff344d72dd3417308a3d711c8a -source-date-epoch: 1756939245 +release-notes-hash: 53bf4fdf15ab8b5dd0361239ee093bc9 +source-date-epoch: 1760667548 diff --git a/scripts/ci/install_breeze.sh b/scripts/ci/install_breeze.sh index e67dce4f3c45a..c37784ef8475a 100755 --- a/scripts/ci/install_breeze.sh +++ b/scripts/ci/install_breeze.sh @@ -22,13 +22,11 @@ cd "$( dirname "${BASH_SOURCE[0]}" )/../../" PYTHON_ARG="" PIP_VERSION="25.2" -UV_VERSION="0.8.15" if [[ ${PYTHON_VERSION=} != "" ]]; then PYTHON_ARG="--python=$(which python"${PYTHON_VERSION}") " fi python -m pip install --upgrade "pip==${PIP_VERSION}" -python -m pip install "uv==${UV_VERSION}" uv tool uninstall apache-airflow-breeze >/dev/null 2>&1 || true # shellcheck disable=SC2086 uv tool install ${PYTHON_ARG} --force --editable ./dev/breeze/ diff --git a/scripts/ci/prek/check_contextmanager_class_decorators.py b/scripts/ci/prek/check_contextmanager_class_decorators.py new file mode 100644 index 0000000000000..149d00bc6c2be --- /dev/null +++ b/scripts/ci/prek/check_contextmanager_class_decorators.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +Check for problematic context manager decorators on test classes. + +Context managers (ContextDecorator, @contextlib.contextmanager) when used as class decorators +transform the class into a callable wrapper, which prevents pytest from collecting the class. +""" + +from __future__ import annotations + +import ast +import sys +from pathlib import Path + + +class ContextManagerClassDecoratorChecker(ast.NodeVisitor): + """AST visitor to check for context manager decorators on test classes.""" + + def __init__(self, filename: str): + self.filename = filename + self.errors: list[str] = [] + + def visit_ClassDef(self, node: ast.ClassDef) -> None: + """Check class definitions for problematic decorators.""" + if not node.name.startswith("Test"): + self.generic_visit(node) + return + + for decorator in node.decorator_list: + decorator_name = self._get_decorator_name(decorator) + if self._is_problematic_decorator(decorator_name): + self.errors.append( + f"{self.filename}:{node.lineno}: Class '{node.name}' uses @{decorator_name} " + f"decorator which prevents pytest collection. Use @pytest.mark.usefixtures instead." + ) + + self.generic_visit(node) + + def _get_decorator_name(self, decorator: ast.expr) -> str: + """Extract decorator name from AST node.""" + if isinstance(decorator, ast.Name): + return decorator.id + if isinstance(decorator, ast.Call): + if isinstance(decorator.func, ast.Name): + return decorator.func.id + if isinstance(decorator.func, ast.Attribute): + return f"{self._get_attr_chain(decorator.func)}" + elif isinstance(decorator, ast.Attribute): + return f"{self._get_attr_chain(decorator)}" + return "unknown" + + def _get_attr_chain(self, node: ast.Attribute) -> str: + """Get the full attribute chain (e.g., 'contextlib.contextmanager').""" + if isinstance(node.value, ast.Name): + return f"{node.value.id}.{node.attr}" + if isinstance(node.value, ast.Attribute): + return f"{self._get_attr_chain(node.value)}.{node.attr}" + return node.attr + + def _is_problematic_decorator(self, decorator_name: str) -> bool: + """Check if decorator is known to break pytest class collection.""" + problematic_decorators = { + "conf_vars", + "env_vars", + "contextlib.contextmanager", + "contextmanager", + } + return decorator_name in problematic_decorators + + +def check_file(filepath: Path) -> list[str]: + """Check a single file for problematic decorators.""" + try: + with open(filepath, encoding="utf-8") as f: + content = f.read() + + tree = ast.parse(content, filename=str(filepath)) + checker = ContextManagerClassDecoratorChecker(str(filepath)) + checker.visit(tree) + return checker.errors + except Exception as e: + return [f"{filepath}: Error parsing file: {e}"] + + +def main() -> int: + """Main entry point.""" + if len(sys.argv) < 2: + print("Usage: check_contextmanager_class_decorators.py ...") + return 1 + + all_errors = [] + + for arg in sys.argv[1:]: + path = Path(arg) + if path.is_file() and path.suffix == ".py": + if "test" in str(path): # Only check test files + all_errors.extend(check_file(path)) + else: + print(f"Skipping non-test file: {path}") + elif path.is_dir(): + for py_file in path.rglob("*.py"): + if "test" in str(py_file): # Only check test files + all_errors.extend(check_file(py_file)) + + if all_errors: + print("Found problematic context manager class decorators:") + for error in all_errors: + print(f" {error}") + return 1 + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/ci/prek/check_imports_in_providers.py b/scripts/ci/prek/check_imports_in_providers.py index c2b6976ea58df..4112b28bd0bc5 100755 --- a/scripts/ci/prek/check_imports_in_providers.py +++ b/scripts/ci/prek/check_imports_in_providers.py @@ -19,7 +19,7 @@ # requires-python = ">=3.10" # dependencies = [ # "rich>=13.6.0", -# "ruff==0.12.12", +# "ruff==0.14.1", # ] # /// from __future__ import annotations diff --git a/scripts/ci/prek/check_license.py b/scripts/ci/prek/check_license.py index ffac66c595459..c60d6bc9fa92b 100755 --- a/scripts/ci/prek/check_license.py +++ b/scripts/ci/prek/check_license.py @@ -37,8 +37,6 @@ "--user", f"{os.getuid()}:{os.getgid()}", "--rm", - "--platform", - "linux/amd64", "ghcr.io/apache/airflow-apache-rat:0.16.1-2024.03.23@sha256:83c4d2610ec4a439d1809a67fadbdc9a1df089ab130b32209351bdd4527a3f02", "-d", "/opt/airflow", diff --git a/scripts/ci/prek/common_prek_utils.py b/scripts/ci/prek/common_prek_utils.py index a7e01a331b8a6..03c22391187fb 100644 --- a/scripts/ci/prek/common_prek_utils.py +++ b/scripts/ci/prek/common_prek_utils.py @@ -276,17 +276,31 @@ def check_list_sorted(the_list: list[str], message: str, errors: list[str]) -> b def validate_cmd_result(cmd_result, include_ci_env_check=False): if include_ci_env_check: if cmd_result.returncode != 0 and os.environ.get("CI") != "true": - console.print( - "\n[yellow]If you see strange stacktraces above, especially about missing imports " - "run this command:[/]\n" - ) - console.print("[magenta]breeze ci-image build --python 3.10 --upgrade-to-newer-dependencies[/]\n") + if console: + console.print( + "\n[yellow]If you see strange stacktraces above, especially about missing imports " + "run this command:[/]\n" + ) + console.print( + "[magenta]breeze ci-image build --python 3.10 --upgrade-to-newer-dependencies[/]\n" + ) + else: + print( + "\nIf you see strange stacktraces above, especially about missing imports " + "run this command:\nbreeze ci-image build --python 3.10 --upgrade-to-newer-dependencies\n" + ) elif cmd_result.returncode != 0: - console.print( - "[warning]\nIf you see strange stacktraces above, " - "run `breeze ci-image build --python 3.10` and try again." - ) + if console: + console.print( + "[warning]\nIf you see strange stacktraces above, " + "run `breeze ci-image build --python 3.10` and try again." + ) + else: + print( + "\nIf you see strange stacktraces above, " + "run `breeze ci-image build --python 3.10` and try again." + ) sys.exit(cmd_result.returncode) diff --git a/scripts/ci/prek/ruff_format.py b/scripts/ci/prek/ruff_format.py index e82d1f8e106bc..ea6e44ec3bada 100755 --- a/scripts/ci/prek/ruff_format.py +++ b/scripts/ci/prek/ruff_format.py @@ -18,7 +18,7 @@ # /// script # requires-python = ">=3.10" # dependencies = [ -# "ruff==0.12.12", +# "ruff==0.14.1", # ] # /// diff --git a/scripts/ci/prek/supported_versions.py b/scripts/ci/prek/supported_versions.py index 0a331b1b81f88..d7188ee727146 100755 --- a/scripts/ci/prek/supported_versions.py +++ b/scripts/ci/prek/supported_versions.py @@ -41,7 +41,7 @@ ) SUPPORTED_VERSIONS = ( - ("3", "3.0.6", "Supported", "Apr 22, 2025", "TBD", "TBD"), + ("3", "3.1.1", "Supported", "Apr 22, 2025", "TBD", "TBD"), ("2", "2.11.0", "Supported", "Dec 17, 2020", "Oct 22, 2025", "Apr 22, 2026"), ("1.10", "1.10.15", "EOL", "Aug 27, 2018", "Dec 17, 2020", "June 17, 2021"), ("1.9", "1.9.0", "EOL", "Jan 03, 2018", "Aug 27, 2018", "Aug 27, 2018"), diff --git a/scripts/ci/prek/update_breeze_config_hash.py b/scripts/ci/prek/update_breeze_config_hash.py deleted file mode 100755 index a908c7f03a3e8..0000000000000 --- a/scripts/ci/prek/update_breeze_config_hash.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# /// script -# requires-python = ">=3.10" -# dependencies = [ -# "rich>=13.6.0", -# ] -# /// -from __future__ import annotations - -import hashlib -import sys -from pathlib import Path - -if __name__ not in ("__main__", "__mp_main__"): - raise SystemExit( - "This file is intended to be executed as an executable program. You cannot use it as a module." - f"To execute this script, run ./{__file__} [FILE] ..." - ) - -sys.path.insert(0, str(Path(__file__).parent.resolve())) # make sure common_prek_utils is imported -from common_prek_utils import AIRFLOW_BREEZE_SOURCES_PATH - - -def get_package_setup_metadata_hash() -> str: - """ - Retrieves hash of pyproject.toml file. - - This is used in order to determine if we need to upgrade Breeze, because some - setup files changed. Blake2b algorithm will not be flagged by security checkers - as insecure algorithm (in Python 3.9 and above we can use `usedforsecurity=False` - to disable it, but for now it's better to use more secure algorithms. - """ - try: - the_hash = hashlib.new("blake2b") - the_hash.update((AIRFLOW_BREEZE_SOURCES_PATH / "pyproject.toml").read_bytes()) - return the_hash.hexdigest() - except FileNotFoundError as e: - return f"Missing file {e.filename}" - - -def process_breeze_readme(): - breeze_readme = AIRFLOW_BREEZE_SOURCES_PATH / "README.md" - lines = breeze_readme.read_text().splitlines(keepends=True) - result_lines = [] - for line in lines: - if line.startswith("Package config hash:"): - line = f"Package config hash: {get_package_setup_metadata_hash()}\n" - result_lines.append(line) - breeze_readme.write_text("".join(result_lines)) - - -if __name__ == "__main__": - process_breeze_readme() diff --git a/scripts/ci/prek/upgrade_important_versions.py b/scripts/ci/prek/upgrade_important_versions.py index 9beecc67e7654..a97198e9b4e75 100755 --- a/scripts/ci/prek/upgrade_important_versions.py +++ b/scripts/ci/prek/upgrade_important_versions.py @@ -24,6 +24,13 @@ # "rich>=13.6.0", # ] # /// +# +# DEBUGGING +# * You can set UPGRADE_ALL_BY_DEFAULT to "false" to only upgrade those versions that +# are set by UPGRADE_NNNNNNN (NNNNNN > thing to upgrade version) +# * You can set VERBOSE="true" to see requests being made +# * You can set UPGRADE_NNNNNNN_INCLUDE_PRE_RELEASES="true" + from __future__ import annotations import os @@ -52,6 +59,8 @@ (AIRFLOW_ROOT_PATH / "scripts" / "docker" / "common.sh", False), (AIRFLOW_ROOT_PATH / "scripts" / "tools" / "setup_breeze", False), (AIRFLOW_ROOT_PATH / "pyproject.toml", False), + (AIRFLOW_ROOT_PATH / ".github" / "workflows" / "airflow-distributions-tests.yml", False), + (AIRFLOW_ROOT_PATH / "dev" / "breeze" / "pyproject.toml", False), (AIRFLOW_ROOT_PATH / "dev" / "breeze" / "src" / "airflow_breeze" / "global_constants.py", False), ( AIRFLOW_ROOT_PATH @@ -65,13 +74,14 @@ ), (AIRFLOW_ROOT_PATH / ".github" / "workflows" / "release_dockerhub_image.yml", False), (AIRFLOW_ROOT_PATH / ".github" / "actions" / "install-prek" / "action.yml", False), + (AIRFLOW_ROOT_PATH / ".github" / "actions" / "breeze" / "action.yml", False), (AIRFLOW_ROOT_PATH / ".github" / "workflows" / "basic-tests.yml", False), + (AIRFLOW_ROOT_PATH / ".github" / "workflows" / "ci-amd.yml", False), (AIRFLOW_ROOT_PATH / "dev" / "breeze" / "doc" / "ci" / "02_images.md", True), (AIRFLOW_ROOT_PATH / "docker-stack-docs" / "build-arg-ref.rst", True), (AIRFLOW_ROOT_PATH / "devel-common" / "pyproject.toml", True), (AIRFLOW_ROOT_PATH / "dev" / "breeze" / "pyproject.toml", False), (AIRFLOW_ROOT_PATH / ".pre-commit-config.yaml", False), - (AIRFLOW_ROOT_PATH / ".github" / "workflows" / "ci-amd.yml", False), (AIRFLOW_CORE_ROOT_PATH / "pyproject.toml", False), (AIRFLOW_CORE_ROOT_PATH / "docs" / "best-practices.rst", False), ] @@ -79,46 +89,82 @@ FILES_TO_UPDATE.append((file, False)) -def get_latest_pypi_version(package_name: str) -> str: +def get_latest_pypi_version(package_name: str, should_upgrade: bool) -> str: + if not should_upgrade: + return "" + if VERBOSE: + console.print(f"[bright_blue]Fetching latest version for {package_name} from PyPI") response = requests.get( f"https://pypi.org/pypi/{package_name}/json", headers={"User-Agent": "Python requests"} ) response.raise_for_status() # Ensure we got a successful response data = response.json() - latest_version = data["info"]["version"] # The version info is under the 'info' key + if os.environ.get(f"UPGRADE_{package_name.upper()}_INCLUDE_PRE_RELEASES", ""): + latest_version = str(sorted([Version(version) for version in data["releases"].keys()])[-1]) + else: + latest_version = data["info"]["version"] # The version info is under the 'info' key + if VERBOSE: + console.print(f"[bright_blue]Latest version for {package_name}: {latest_version}") return latest_version -def get_latest_python_version(python_major_minor: str, github_token: str | None) -> str | None: - latest_version = None - # Matches versions of vA.B.C and vA.B where C can only be numeric and v is optional - version_match = re.compile(rf"^v?{python_major_minor}\.?\d*$") +def get_all_python_versions() -> list[Version]: + if VERBOSE: + console.print("[bright_blue]Fetching all released Python versions from python.org") + url = "https://www.python.org/api/v2/downloads/release/?is_published=true" headers = {"User-Agent": "Python requests"} - if github_token: - headers["Authorization"] = f"Bearer {github_token}" - for i in range(5): - response = requests.get( - f"https://api.github.com/repos/python/cpython/tags?per_page=100&page={i + 1}", - headers=headers, - ) - response.raise_for_status() # Ensure we got a successful response - data = response.json() - versions = [str(tag["name"]) for tag in data if version_match.match(tag.get("name", ""))] - if versions: - latest_version = sorted(versions, key=Version, reverse=True)[0] - break - return latest_version[1:] if latest_version and latest_version.startswith("v") else latest_version + response = requests.get(url, headers=headers) + response.raise_for_status() + data = response.json() + versions = [] + matcher = re.compile(r"^Python ([\d.]+$)") + for release in data: + release_name = release["name"] + match = matcher.match(release_name) + if match: + versions.append(Version(match.group(1))) + return versions + + +def get_latest_python_version(python_major_minor: str, all_versions: list[Version]) -> str: + """ + Fetch the latest released Python version for a given major.minor (e.g. '3.12') using python.org API. + Much faster than paginating through all GitHub tags. + """ + # Only consider releases matching the major.minor.patch pattern + matching = [ + version for version in all_versions if python_major_minor == f"{version.major}.{version.minor}" + ] + if not matching: + console.print(f"[bright_red]No released Python versions found for {python_major_minor}") + sys.exit(1) + # Sort and return the latest version + latest_version = sorted(matching)[-1] + if VERBOSE: + console.print(f"[bright_blue]Latest version for {python_major_minor}: {latest_version}") + return str(latest_version) def get_latest_golang_version() -> str: + if not UPGRADE_GOLANG: + return "" + if VERBOSE: + console.print("[bright_blue]Fetching latest Go version from go.dev") response = requests.get("https://go.dev/dl/?mode=json") response.raise_for_status() # Ensure we got a successful response versions = response.json() stable_versions = [release["version"].replace("go", "") for release in versions if release["stable"]] - return sorted(stable_versions, key=Version, reverse=True)[0] + latest_version = sorted(stable_versions, key=Version, reverse=True)[0] + if VERBOSE: + console.print(f"[bright_blue]Latest version for Go: {latest_version}") + return latest_version def get_latest_lts_node_version() -> str: + if not UPGRADE_NODE_LTS: + return "" + if VERBOSE: + console.print("[bright_blue]Fetching latest LTS Node version from nodejs.org") response = requests.get("https://nodejs.org/dist/index.json") response.raise_for_status() # Ensure we got a successful response versions = response.json() @@ -126,7 +172,10 @@ def get_latest_lts_node_version() -> str: lts_versions = [version["version"] for version in versions if version["version"].startswith(lts_prefix)] # The json array is sorted from newest to oldest, so the first element is the latest LTS version # Skip leading v in version - return lts_versions[0][1:] + latest_version = lts_versions[0][1:] + if VERBOSE: + console.print(f"[bright_blue]Latest version for LTS Node: {latest_version}") + return latest_version class Quoting(Enum): @@ -138,38 +187,44 @@ class Quoting(Enum): PIP_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ - (re.compile(r"(AIRFLOW_PIP_VERSION=)([0-9.]+)"), Quoting.UNQUOTED), - (re.compile(r"(python -m pip install --upgrade pip==)([0-9.]+)"), Quoting.UNQUOTED), - (re.compile(r"(AIRFLOW_PIP_VERSION = )(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), - (re.compile(r"(PIP_VERSION = )(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), - (re.compile(r"(PIP_VERSION=)(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), - (re.compile(r"(\| *`AIRFLOW_PIP_VERSION` *\| *)(`[0-9.]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED), + (re.compile(r"(AIRFLOW_PIP_VERSION=)([0-9.abrc]+)"), Quoting.UNQUOTED), + (re.compile(r"(python -m pip install --upgrade pip==)([0-9.abrc]+)"), Quoting.UNQUOTED), + (re.compile(r"(AIRFLOW_PIP_VERSION = )(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), + (re.compile(r"(PIP_VERSION = )(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), + (re.compile(r"(PIP_VERSION=)(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), + (re.compile(r"(\| *`AIRFLOW_PIP_VERSION` *\| *)(`[0-9.abrc]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED), ] PYTHON_PATTERNS: list[tuple[str, Quoting]] = [ - (r"(\"{python_major_minor}\": \")([0-9.]+)(\")", Quoting.UNQUOTED), + (r"(\"{python_major_minor}\": \")([0-9.abrc]+)(\")", Quoting.UNQUOTED), ] GOLANG_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ - (re.compile(r"(GOLANG_MAJOR_MINOR_VERSION=)(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), - (re.compile(r"(\| *`GOLANG_MAJOR_MINOR_VERSION` *\| *)(`[0-9.]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED), + (re.compile(r"(GOLANG_MAJOR_MINOR_VERSION=)(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), + ( + re.compile(r"(\| *`GOLANG_MAJOR_MINOR_VERSION` *\| *)(`[0-9.abrc]+`)( *\|)"), + Quoting.REVERSE_SINGLE_QUOTED, + ), ] AIRFLOW_IMAGE_PYTHON_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ - (re.compile(r"(AIRFLOW_PYTHON_VERSION=)(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), - (re.compile(r"(\| ``AIRFLOW_PYTHON_VERSION`` *\| )(``[0-9.]+``)( *\|)"), Quoting.REVERSE_DOUBLE_QUOTED), + (re.compile(r"(AIRFLOW_PYTHON_VERSION=)(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), + ( + re.compile(r"(\| ``AIRFLOW_PYTHON_VERSION`` *\| )(``[0-9.abrc]+``)( *\|)"), + Quoting.REVERSE_DOUBLE_QUOTED, + ), ] UV_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ - (re.compile(r"(AIRFLOW_UV_VERSION=)([0-9.]+)"), Quoting.UNQUOTED), - (re.compile(r"(uv>=)([0-9.]+)"), Quoting.UNQUOTED), - (re.compile(r"(AIRFLOW_UV_VERSION = )(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), - (re.compile(r"^(\s*UV_VERSION = )(\"[0-9.]+\")", re.MULTILINE), Quoting.DOUBLE_QUOTED), - (re.compile(r"^(\s*UV_VERSION=)(\"[0-9.]+\")", re.MULTILINE), Quoting.DOUBLE_QUOTED), - (re.compile(r"(\| *`AIRFLOW_UV_VERSION` *\| *)(`[0-9.]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED), + (re.compile(r"(AIRFLOW_UV_VERSION=)([0-9.abrc]+)"), Quoting.UNQUOTED), + (re.compile(r"(uv>=)([0-9.abrc]+)"), Quoting.UNQUOTED), + (re.compile(r"(AIRFLOW_UV_VERSION = )(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), + (re.compile(r"^(\s*UV_VERSION = )(\"[0-9.abrc]+\")", re.MULTILINE), Quoting.DOUBLE_QUOTED), + (re.compile(r"^(\s*UV_VERSION=)(\"[0-9.abrc]+\")", re.MULTILINE), Quoting.DOUBLE_QUOTED), + (re.compile(r"(\| *`AIRFLOW_UV_VERSION` *\| *)(`[0-9.abrd]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED), ( re.compile( - r"(\")([0-9.]+)(\" # Keep this comment to " + r"(\")([0-9.abrc]+)(\" # Keep this comment to " r"allow automatic replacement of uv version)" ), Quoting.UNQUOTED, @@ -177,18 +232,18 @@ class Quoting(Enum): ] PREK_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ - (re.compile(r"(AIRFLOW_PREK_VERSION=)([0-9.]+)"), Quoting.UNQUOTED), - (re.compile(r"(AIRFLOW_PREK_VERSION = )(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), - (re.compile(r"(prek>=)([0-9.]+)"), Quoting.UNQUOTED), - (re.compile(r"(PREK_VERSION = )(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), - (re.compile(r"(PREK_VERSION=)(\"[0-9.]+\")"), Quoting.DOUBLE_QUOTED), + (re.compile(r"(AIRFLOW_PREK_VERSION=)([0-9.abrc]+)"), Quoting.UNQUOTED), + (re.compile(r"(AIRFLOW_PREK_VERSION = )(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), + (re.compile(r"(prek>=)([0-9.abrc]+)"), Quoting.UNQUOTED), + (re.compile(r"(PREK_VERSION = )(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), + (re.compile(r"(PREK_VERSION=)(\"[0-9.abrc]+\")"), Quoting.DOUBLE_QUOTED), ( - re.compile(r"(\| *`AIRFLOW_PREK_VERSION` *\| *)(`[0-9.]+`)( *\|)"), + re.compile(r"(\| *`AIRFLOW_PREK_VERSION` *\| *)(`[0-9.abrc]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED, ), ( re.compile( - r"(\")([0-9.]+)(\" # Keep this comment to allow automatic " + r"(\")([0-9.abrc]+)(\" # Keep this comment to allow automatic " r"replacement of prek version)" ), Quoting.UNQUOTED, @@ -196,7 +251,7 @@ class Quoting(Enum): ] NODE_LTS_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ - (re.compile(r"( *node: )([0-9.]+)"), Quoting.UNQUOTED), + (re.compile(r"(^ node: )([0-9.abrc]+)^"), Quoting.UNQUOTED), ] @@ -212,17 +267,25 @@ def get_replacement(value: str, quoting: Quoting) -> str: return value -UPGRADE_UV: bool = os.environ.get("UPGRADE_UV", "true").lower() == "true" -UPGRADE_PIP: bool = os.environ.get("UPGRADE_PIP", "true").lower() == "true" -UPGRADE_PYTHON: bool = os.environ.get("UPGRADE_PYTHON", "true").lower() == "true" -UPGRADE_GOLANG: bool = os.environ.get("UPGRADE_GOLANG", "true").lower() == "true" -UPGRADE_PREK: bool = os.environ.get("UPGRADE_PREK", "true").lower() == "true" -UPGRADE_NODE_LTS: bool = os.environ.get("UPGRADE_NODE_LTS", "true").lower() == "true" -UPGRADE_HATCH: bool = os.environ.get("UPGRADE_HATCH", "true").lower() == "true" -UPGRADE_PYYAML: bool = os.environ.get("UPGRADE_PYYAML", "true").lower() == "true" -UPGRADE_GITPYTHON: bool = os.environ.get("UPGRADE_GITPYTHON", "true").lower() == "true" -UPGRADE_RICH: bool = os.environ.get("UPGRADE_RICH", "true").lower() == "true" -UPGRADE_RUFF: bool = os.environ.get("UPGRADE_RUFF", "true").lower() == "true" +VERBOSE: bool = os.environ.get("VERBOSE", "false") == "true" +UPGRADE_ALL_BY_DEFAULT: bool = os.environ.get("UPGRADE_ALL_BY_DEFAULT", "true") == "true" +UPGRADE_ALL_BY_DEFAULT_STR: str = str(UPGRADE_ALL_BY_DEFAULT).lower() +if UPGRADE_ALL_BY_DEFAULT: + if VERBOSE == "true": + console.print("[bright_blue]Upgrading all important versions") + +UPGRADE_GITPYTHON: bool = os.environ.get("UPGRADE_GITPYTHON", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_GOLANG: bool = os.environ.get("UPGRADE_GOLANG", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_HATCH: bool = os.environ.get("UPGRADE_HATCH", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_NODE_LTS: bool = os.environ.get("UPGRADE_NODE_LTS", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_PIP: bool = os.environ.get("UPGRADE_PIP", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_PREK: bool = os.environ.get("UPGRADE_PREK", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_PYTHON: bool = os.environ.get("UPGRADE_PYTHON", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_PYYAML: bool = os.environ.get("UPGRADE_PYYAML", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_RICH: bool = os.environ.get("UPGRADE_RICH", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_RUFF: bool = os.environ.get("UPGRADE_RUFF", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_UV: bool = os.environ.get("UPGRADE_UV", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" +UPGRADE_MYPY: bool = os.environ.get("UPGRADE_MYPY", UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true" ALL_PYTHON_MAJOR_MINOR_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13"] DEFAULT_PROD_IMAGE_PYTHON_VERSION = "3.12" @@ -259,50 +322,53 @@ def replacer(match): gh_token = retrieve_gh_token(description="airflow-upgrade-important-versions", scopes="public_repo") changed = False golang_version = get_latest_golang_version() - pip_version = get_latest_pypi_version("pip") - uv_version = get_latest_pypi_version("uv") - setuptools_version = get_latest_pypi_version("setuptools") - prek_version = get_latest_pypi_version("prek") - hatch_version = get_latest_pypi_version("hatch") - pyyaml_version = get_latest_pypi_version("PyYAML") - gitpython_version = get_latest_pypi_version("GitPython") - rich_version = get_latest_pypi_version("rich") - ruff_version = get_latest_pypi_version("ruff") + pip_version = get_latest_pypi_version("pip", UPGRADE_PIP) + uv_version = get_latest_pypi_version("uv", UPGRADE_UV) + prek_version = get_latest_pypi_version("prek", UPGRADE_PREK) + hatch_version = get_latest_pypi_version("hatch", UPGRADE_HATCH) + pyyaml_version = get_latest_pypi_version("PyYAML", UPGRADE_PYYAML) + gitpython_version = get_latest_pypi_version("GitPython", UPGRADE_GITPYTHON) + ruff_version = get_latest_pypi_version("ruff", UPGRADE_RUFF) + rich_version = get_latest_pypi_version("rich", UPGRADE_RICH) + mypy_version = get_latest_pypi_version("mypy", UPGRADE_MYPY) node_lts_version = get_latest_lts_node_version() + latest_python_versions: dict[str, str] = {} + latest_image_python_version = "" + if UPGRADE_PYTHON: + all_python_versions = get_all_python_versions() if UPGRADE_PYTHON else None + for python_major_minor_version in ALL_PYTHON_MAJOR_MINOR_VERSIONS: + latest_python_versions[python_major_minor_version] = get_latest_python_version( + python_major_minor_version, all_python_versions + ) + if python_major_minor_version == DEFAULT_PROD_IMAGE_PYTHON_VERSION: + latest_image_python_version = latest_python_versions[python_major_minor_version] + console.print( + f"[bright_blue]Latest image python {python_major_minor_version} version: {latest_image_python_version}" + ) for file, keep_length in FILES_TO_UPDATE: console.print(f"[bright_blue]Updating {file}") file_content = file.read_text() new_content = file_content if UPGRADE_PIP: - console.print(f"[bright_blue]Latest pip version: {pip_version}") for line_pattern, quoting in PIP_PATTERNS: new_content = replace_version( line_pattern, get_replacement(pip_version, quoting), new_content, keep_length ) if UPGRADE_PYTHON: - for python_version in ALL_PYTHON_MAJOR_MINOR_VERSIONS: - latest_python_version = get_latest_python_version(python_version, gh_token) - if not latest_python_version: - console.print( - f"[red]Failed to get latest version for python {python_version}. Skipping.[/]" - ) - sys.exit(1) - console.print(f"[bright_blue]Latest python {python_version} version: {latest_python_version}") + for python_major_minor_version in ALL_PYTHON_MAJOR_MINOR_VERSIONS: + latest_python_version = latest_python_versions[python_major_minor_version] for line_format, quoting in PYTHON_PATTERNS: - line_pattern = re.compile(line_format.format(python_major_minor=python_version)) - console.print(line_pattern) + line_pattern = re.compile( + line_format.format(python_major_minor=python_major_minor_version) + ) new_content = replace_version( line_pattern, get_replacement(latest_python_version, quoting), new_content, keep_length, ) - if python_version == DEFAULT_PROD_IMAGE_PYTHON_VERSION: - console.print( - f"[bright_blue]Latest image python {python_version} version: {latest_python_version}" - ) + if python_major_minor_version == DEFAULT_PROD_IMAGE_PYTHON_VERSION: for line_pattern, quoting in AIRFLOW_IMAGE_PYTHON_PATTERNS: - console.print(line_pattern) new_content = replace_version( line_pattern, get_replacement(latest_python_version, quoting), @@ -310,25 +376,21 @@ def replacer(match): keep_length, ) if UPGRADE_GOLANG: - console.print(f"[bright_blue]Latest golang version: {golang_version}") for line_pattern, quoting in GOLANG_PATTERNS: new_content = replace_version( line_pattern, get_replacement(golang_version, quoting), new_content, keep_length ) if UPGRADE_UV: - console.print(f"[bright_blue]Latest uv version: {uv_version}") for line_pattern, quoting in UV_PATTERNS: new_content = replace_version( line_pattern, get_replacement(uv_version, quoting), new_content, keep_length ) if UPGRADE_PREK: - console.print(f"[bright_blue]Latest prek version: {prek_version}") for line_pattern, quoting in PREK_PATTERNS: new_content = replace_version( line_pattern, get_replacement(prek_version, quoting), new_content, keep_length ) if UPGRADE_NODE_LTS: - console.print(f"[bright_blue]Latest Node LTS version: {node_lts_version}") for line_pattern, quoting in NODE_LTS_PATTERNS: new_content = replace_version( line_pattern, @@ -337,65 +399,79 @@ def replacer(match): keep_length, ) if UPGRADE_HATCH: - console.print(f"[bright_blue]Latest hatch version: {hatch_version}") new_content = re.sub( - r"(HATCH_VERSION = )(\"[0-9.]+\")", + r"(HATCH_VERSION = )(\"[0-9.abrc]+\")", f'HATCH_VERSION = "{hatch_version}"', new_content, ) new_content = re.sub( - r"(HATCH_VERSION=)(\"[0-9.]+\")", + r"(HATCH_VERSION=)(\"[0-9.abrc]+\")", f'HATCH_VERSION="{hatch_version}"', new_content, ) + new_content = re.sub( + r"(hatch==)([0-9.abrc]+)", + f"hatch=={hatch_version}", + new_content, + ) + new_content = re.sub( + r"(hatch>=)([0-9.abrc]+)", + f"hatch>={hatch_version}", + new_content, + ) if UPGRADE_PYYAML: - console.print(f"[bright_blue]Latest PyYAML version: {pyyaml_version}") new_content = re.sub( - r"(PYYAML_VERSION = )(\"[0-9.]+\")", + r"(PYYAML_VERSION = )(\"[0-9.abrc]+\")", f'PYYAML_VERSION = "{pyyaml_version}"', new_content, ) new_content = re.sub( - r"(PYYAML_VERSION=)(\"[0-9.]+\")", + r"(PYYAML_VERSION=)(\"[0-9.abrc]+\")", f'PYYAML_VERSION="{pyyaml_version}"', new_content, ) if UPGRADE_GITPYTHON: - console.print(f"[bright_blue]Latest GitPython version: {gitpython_version}") new_content = re.sub( - r"(GITPYTHON_VERSION = )(\"[0-9.]+\")", + r"(GITPYTHON_VERSION = )(\"[0-9.abrc]+\")", f'GITPYTHON_VERSION = "{gitpython_version}"', new_content, ) new_content = re.sub( - r"(GITPYTHON_VERSION=)(\"[0-9.]+\")", + r"(GITPYTHON_VERSION=)(\"[0-9.abrc]+\")", f'GITPYTHON_VERSION="{gitpython_version}"', new_content, ) if UPGRADE_RICH: - console.print(f"[bright_blue]Latest rich version: {rich_version}") new_content = re.sub( - r"(RICH_VERSION = )(\"[0-9.]+\")", + r"(RICH_VERSION = )(\"[0-9.abrc]+\")", f'RICH_VERSION = "{rich_version}"', new_content, ) new_content = re.sub( - r"(RICH_VERSION=)(\"[0-9.]+\")", + r"(RICH_VERSION=)(\"[0-9.abrc]+\")", f'RICH_VERSION="{rich_version}"', new_content, ) if UPGRADE_RUFF: - console.print(f"[bright_blue]Latest ruff version: {ruff_version}") new_content = re.sub( - r"(ruff==)([0-9.]+)", + r"(ruff==)([0-9.abrc]+)", f"ruff=={ruff_version}", new_content, ) new_content = re.sub( - r"(ruff>=)([0-9.]+)", + r"(ruff>=)([0-9.abrc]+)", f"ruff>={ruff_version}", new_content, ) + if UPGRADE_MYPY: + console.print(f"[bright_blue]Latest mypy version: {mypy_version}") + + new_content = re.sub( + r"(mypy==)([0-9.]+)", + f"mypy=={mypy_version}", + new_content, + ) + if new_content != file_content: file.write_text(new_content) console.print(f"[bright_blue]Updated {file}") @@ -405,7 +481,7 @@ def replacer(match): copy_env = os.environ.copy() del copy_env["VIRTUAL_ENV"] subprocess.run( - ["uv", "sync", "--resolution", "highest"], + ["uv", "sync", "--resolution", "highest", "--upgrade"], check=True, cwd=AIRFLOW_ROOT_PATH / "dev" / "breeze", env=copy_env, diff --git a/scripts/docker/entrypoint_prod.sh b/scripts/docker/entrypoint_prod.sh index cd7a600641fc0..88135c145c128 100755 --- a/scripts/docker/entrypoint_prod.sh +++ b/scripts/docker/entrypoint_prod.sh @@ -337,4 +337,10 @@ if [[ ${AIRFLOW_COMMAND} =~ ^(scheduler|celery)$ ]] \ wait_for_celery_broker fi +# Exit cleanly if the init was only intended to migrate DB +if [[ "$#" -eq 0 && "${_AIRFLOW_DB_MIGRATE}" == "true" ]]; then + echo "[INFO] No commands passed and _AIRFLOW_DB_MIGRATE=true. Exiting script with code 0." + exit 0 +fi + exec "airflow" "${@}" diff --git a/scripts/in_container/bin/install_java.sh b/scripts/in_container/bin/install_java.sh index 8089e4338d97b..0aa15f8209518 100755 --- a/scripts/in_container/bin/install_java.sh +++ b/scripts/in_container/bin/install_java.sh @@ -25,6 +25,15 @@ BIN_PATH="/files/bin/java" if [[ $# != "0" && ${1} == "--reinstall" ]]; then rm -rf "${INSTALL_DIR}" rm -f "${BIN_PATH}" + mapfile -t files_to_delete < <(find /files/bin -type l -exec bash -c ' + for link; do + target=$(readlink "$link") + if [[ "$target" == /files/opt/java/* ]]; then + echo "$link" + fi + done + ' _ {} +) + rm -rf "${files_to_delete[@]}" fi hash -r @@ -34,7 +43,7 @@ if command -v java; then exit 1 fi -DOWNLOAD_URL='https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz' +DOWNLOAD_URL="https://download.java.net/openjdk/jdk25/ri/openjdk-25+36_linux-x64_bin.tar.gz" if [[ -e ${INSTALL_DIR} ]]; then echo "The install directory (${INSTALL_DIR}) already exists. This may mean java is already installed." diff --git a/scripts/in_container/run_generate_constraints.py b/scripts/in_container/run_generate_constraints.py index 16295360ebfad..42c865f967687 100755 --- a/scripts/in_container/run_generate_constraints.py +++ b/scripts/in_container/run_generate_constraints.py @@ -362,7 +362,14 @@ def generate_constraints_pypi_providers(config_params: ConfigParams) -> None: # # * no exclusions # - additional_constraints_for_highest_resolution: list[str] = [] + # https://github.com/alisaifee/flask-limiter/issues/479 + additional_constraints_for_highest_resolution: list[str] = [ + "google-ads!=28.0.0.post2", + "Flask-Limiter!=3.13", + # https://github.com/pallets/click/issues/3071 causing celery worker failure + # https://github.com/apache/airflow/commit/0560dccf0300069b660a801965b130dd2cd1e857 + "click!=8.3.0", + ] result = run_command( cmd=[ diff --git a/scripts/in_container/run_schema_defaults_check.py b/scripts/in_container/run_schema_defaults_check.py index ef672c297ca0c..e9744134360d5 100755 --- a/scripts/in_container/run_schema_defaults_check.py +++ b/scripts/in_container/run_schema_defaults_check.py @@ -28,11 +28,12 @@ import json import sys +from datetime import timedelta from pathlib import Path from typing import Any -def load_schema_defaults() -> dict[str, Any]: +def load_schema_defaults(object_type: str = "operator") -> dict[str, Any]: """Load default values from the JSON schema.""" schema_path = Path("airflow-core/src/airflow/serialization/schema.json") @@ -43,9 +44,9 @@ def load_schema_defaults() -> dict[str, Any]: with open(schema_path) as f: schema = json.load(f) - # Extract defaults from the operator definition - operator_def = schema.get("definitions", {}).get("operator", {}) - properties = operator_def.get("properties", {}) + # Extract defaults from the specified object type definition + object_def = schema.get("definitions", {}).get(object_type, {}) + properties = object_def.get("properties", {}) defaults = {} for field_name, field_def in properties.items(): @@ -55,7 +56,7 @@ def load_schema_defaults() -> dict[str, Any]: return defaults -def get_server_side_defaults() -> dict[str, Any]: +def get_server_side_operator_defaults() -> dict[str, Any]: """Get default values from server-side SerializedBaseOperator class.""" try: from airflow.serialization.serialized_objects import SerializedBaseOperator @@ -80,6 +81,8 @@ def get_server_side_defaults() -> dict[str, Any]: if isinstance(default_value, (set, tuple)): # Convert to list since schema.json is pure JSON default_value = list(default_value) + elif isinstance(default_value, timedelta): + default_value = default_value.total_seconds() server_defaults[field_name] = default_value return server_defaults @@ -92,14 +95,46 @@ def get_server_side_defaults() -> dict[str, Any]: sys.exit(1) -def compare_defaults() -> list[str]: - """Compare schema defaults with server-side defaults and return discrepancies.""" - schema_defaults = load_schema_defaults() - server_defaults = get_server_side_defaults() +def get_server_side_dag_defaults() -> dict[str, Any]: + """Get default values from server-side SerializedDAG class.""" + try: + from airflow.serialization.serialized_objects import SerializedDAG + + # DAG defaults are set in __init__, so we create a temporary instance + temp_dag = SerializedDAG(dag_id="temp") + + # Get all serializable DAG fields from the server-side class + serialized_fields = SerializedDAG.get_serialized_fields() + + server_defaults = {} + for field_name in serialized_fields: + if hasattr(temp_dag, field_name): + default_value = getattr(temp_dag, field_name) + # Only include actual default values that are not None, callables, or descriptors + if not callable(default_value) and not isinstance(default_value, (property, type)): + if isinstance(default_value, (set, tuple)): + # Convert to list since schema.json is pure JSON + default_value = list(default_value) + server_defaults[field_name] = default_value + + return server_defaults + + except ImportError as e: + print(f"Error importing SerializedDAG: {e}") + sys.exit(1) + except Exception as e: + print(f"Error getting server-side DAG defaults: {e}") + sys.exit(1) + + +def compare_operator_defaults() -> list[str]: + """Compare operator schema defaults with server-side defaults and return discrepancies.""" + schema_defaults = load_schema_defaults("operator") + server_defaults = get_server_side_operator_defaults() errors = [] - print(f"Found {len(schema_defaults)} schema defaults") - print(f"Found {len(server_defaults)} server-side defaults") + print(f"Found {len(schema_defaults)} operator schema defaults") + print(f"Found {len(server_defaults)} operator server-side defaults") # Check each server default against schema for field_name, server_value in server_defaults.items(): @@ -141,25 +176,82 @@ def compare_defaults() -> list[str]: return errors +def compare_dag_defaults() -> list[str]: + """Compare DAG schema defaults with server-side defaults and return discrepancies.""" + schema_defaults = load_schema_defaults("dag") + server_defaults = get_server_side_dag_defaults() + errors = [] + + print(f"Found {len(schema_defaults)} DAG schema defaults") + print(f"Found {len(server_defaults)} DAG server-side defaults") + + # Check each server default against schema + for field_name, server_value in server_defaults.items(): + schema_value = schema_defaults.get(field_name) + + # Check if field exists in schema + if field_name not in schema_defaults: + # Some server fields don't need defaults in schema (like None values, empty collections, or computed fields) + if ( + server_value is not None + and server_value not in [[], {}, (), set()] + and field_name not in ["dag_id", "dag_display_name"] + ): + errors.append( + f"DAG server field '{field_name}' has default {server_value!r} but no schema default" + ) + continue + + # Direct comparison + if schema_value != server_value: + errors.append( + f"DAG field '{field_name}': schema default is {schema_value!r}, " + f"server default is {server_value!r}" + ) + + # Check for schema defaults that don't have corresponding server defaults + for field_name, schema_value in schema_defaults.items(): + if field_name not in server_defaults: + # Some schema fields are computed properties (like has_on_*_callback) + computed_properties = { + "has_on_success_callback", + "has_on_failure_callback", + } + if field_name not in computed_properties: + errors.append( + f"DAG schema has default for '{field_name}' = {schema_value!r} but no corresponding server default" + ) + + return errors + + def main(): """Main function to run the schema defaults check.""" - print("Checking schema defaults against server-side SerializedBaseOperator...") + print("Checking schema defaults against server-side serialization classes...") + + # Check Operator defaults + print("\n1. Checking Operator defaults...") + operator_errors = compare_operator_defaults() + + # Check Dag defaults + print("\n2. Checking Dag defaults...") + dag_errors = compare_dag_defaults() - errors = compare_defaults() + all_errors = operator_errors + dag_errors - if errors: - print("❌ Found discrepancies between schema and server defaults:") - for error in errors: + if all_errors: + print("\n❌ Found discrepancies between schema and server defaults:") + for error in all_errors: print(f" • {error}") print() print("To fix these issues:") print("1. Update airflow-core/src/airflow/serialization/schema.json to match server defaults, OR") print( - "2. Update airflow-core/src/airflow/serialization/serialized_objects.py class defaults to match schema" + "2. Update airflow-core/src/airflow/serialization/serialized_objects.py class/init defaults to match schema" ) sys.exit(1) else: - print("✅ All schema defaults match server-side defaults!") + print("\n✅ All schema defaults match server-side defaults!") if __name__ == "__main__": diff --git a/scripts/tools/setup_breeze b/scripts/tools/setup_breeze index bf7aae61d23ce..a005d77e50e74 100755 --- a/scripts/tools/setup_breeze +++ b/scripts/tools/setup_breeze @@ -27,7 +27,7 @@ COLOR_YELLOW=$'\e[33m' COLOR_BLUE=$'\e[34m' COLOR_RESET=$'\e[0m' -UV_VERSION="0.8.15" +UV_VERSION="0.9.4" function manual_instructions() { echo diff --git a/shared/logging/pyproject.toml b/shared/logging/pyproject.toml new file mode 100644 index 0000000000000..f6b36f2092d55 --- /dev/null +++ b/shared/logging/pyproject.toml @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[project] +name = "apache-airflow-shared-logging" +description = "Shared logging code for Airflow distributions" +version = "0.0" +classifiers = [ + "Private :: Do Not Upload", +] + +dependencies = [ + "msgspec>=0.19.0", + "pygtrie>=2.5.0", + "structlog>=25.4.0", +] + +[dependency-groups] +dev = [ + "apache-airflow-devel-common", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["src/airflow_shared"] + +[tool.ruff] +extend = "../../pyproject.toml" +src = ["src"] + +[tool.ruff.lint.per-file-ignores] +# Ignore Doc rules et al for anything outside of tests +"!src/*" = ["D", "S101", "TRY002"] + +[tool.ruff.lint.flake8-tidy-imports] +# Override the workspace level default +ban-relative-imports = "parents" diff --git a/shared/logging/src/airflow_shared/logging/__init__.py b/shared/logging/src/airflow_shared/logging/__init__.py new file mode 100644 index 0000000000000..cc4ffd0b34350 --- /dev/null +++ b/shared/logging/src/airflow_shared/logging/__init__.py @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +__all__ = [ + "configure_logging", + "init_log_file", + "init_log_folder", + "translate_config_values", +] + +from ._config import translate_config_values +from .structlog import configure_logging, init_log_file, init_log_folder diff --git a/shared/logging/src/airflow_shared/logging/_config.py b/shared/logging/src/airflow_shared/logging/_config.py new file mode 100644 index 0000000000000..bd19b8dfdc44c --- /dev/null +++ b/shared/logging/src/airflow_shared/logging/_config.py @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import structlog.processors + +OLD_DEFAULT_LOG_FORMAT = "[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s" +OLD_DEFAULT_COLOR_LOG_FORMAT = ( + "[%(blue)s%(asctime)s%(reset)s] {%(blue)s%(filename)s:%(reset)s%(lineno)d} " + "%(log_color)s%(levelname)s%(reset)s - %(log_color)s%(message)s%(reset)s" +) + + +# This doesn't load the values from config, to avoid a cross dependency between shared logging and shared +# config modules. +def translate_config_values( + log_format: str, callsite_params: list[str] +) -> tuple[str, tuple[structlog.processors.CallsiteParameter, ...]]: + if log_format == OLD_DEFAULT_LOG_FORMAT: + # It's the default, use the coloured version by default. This will automatically not put color codes + # if we're not a tty, or if colors are disabled + log_format = OLD_DEFAULT_COLOR_LOG_FORMAT + + # This will raise an exception if the value isn't valid + params_out = tuple( + getattr(structlog.processors.CallsiteParameter, p, None) or structlog.processors.CallsiteParameter(p) + for p in filter(None, callsite_params) + ) + + return log_format, params_out diff --git a/shared/logging/src/airflow_shared/logging/_noncaching.py b/shared/logging/src/airflow_shared/logging/_noncaching.py new file mode 100644 index 0000000000000..7a8e21fbe3811 --- /dev/null +++ b/shared/logging/src/airflow_shared/logging/_noncaching.py @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import os +from typing import BinaryIO, TextIO, TypeVar + +__all__ = [ + "make_file_io_non_caching", +] + +_IO = TypeVar("_IO", TextIO, BinaryIO) + + +def make_file_io_non_caching(io: _IO) -> _IO: + try: + fd = io.fileno() + os.posix_fadvise(fd, 0, 0, os.POSIX_FADV_DONTNEED) + except Exception: + # in case either file descriptor cannot be retrieved or fadvise is not available + # we should simply return the wrapper retrieved by FileHandler's open method + # the advice to the kernel is just an advice and if we cannot give it, we won't + pass + return io diff --git a/shared/logging/src/airflow_shared/logging/percent_formatter.py b/shared/logging/src/airflow_shared/logging/percent_formatter.py new file mode 100644 index 0000000000000..33d566cf21e02 --- /dev/null +++ b/shared/logging/src/airflow_shared/logging/percent_formatter.py @@ -0,0 +1,175 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import collections.abc +import datetime +import operator +import re +import sys +from io import StringIO +from typing import TYPE_CHECKING, ClassVar + +import structlog.dev +from structlog.dev import ConsoleRenderer, Styles +from structlog.processors import CallsiteParameter + +if TYPE_CHECKING: + from structlog.typing import EventDict, WrappedLogger + + +class _LazyLogRecordDict(collections.abc.Mapping): + __slots__ = ("event", "styles", "level_styles", "method_name", "no_colors") + + def __init__(self, event: EventDict, method_name: str, level_styles: dict[str, str], styles: Styles): + self.event = event + self.method_name = method_name + self.level_styles = level_styles + self.styles = styles + self.no_colors = self.styles.reset == "" + + def __getitem__(self, key): + # Roughly compatible with names from https://github.com/python/cpython/blob/v3.13.7/Lib/logging/__init__.py#L571 + # Plus with ColoredLog added in + + if key in PercentFormatRender.callsite_parameters: + return self.event.get(PercentFormatRender.callsite_parameters[key].value) + if key == "name": + return self.event.get("logger") or self.event.get("logger_name") + if key == "levelname": + return self.event.get("level", self.method_name).upper() + if key == "asctime" or key == "created": + return ( + self.event.get("timestamp", None) + or datetime.datetime.now(tz=datetime.timezone.utc).isoformat() + ) + if key == "message": + return self.event["event"] + + if key in ("red", "green", "yellow", "blue", "purple", "cyan"): + if self.no_colors: + return "" + return getattr(structlog.dev, key.upper(), "") + if key == "reset": + return self.styles.reset + if key == "log_color": + if self.no_colors: + return "" + return self.level_styles.get(self.event.get("level", self.method_name), "") + + return self.event[key] + + def __iter__(self): + return self.event.__iter__() + + def __len__(self): + return len(self.event) + + +class PercentFormatRender(ConsoleRenderer): + """A Structlog processor that uses a stdlib-like percent based format string.""" + + _fmt: str + + # From https://github.com/python/cpython/blob/v3.12.11/Lib/logging/__init__.py#L563-L587 + callsite_parameters: ClassVar[dict[str, CallsiteParameter]] = { + "pathname": CallsiteParameter.PATHNAME, + "filename": CallsiteParameter.FILENAME, + "module": CallsiteParameter.MODULE, + "lineno": CallsiteParameter.LINENO, + "funcName": CallsiteParameter.FUNC_NAME, + "thread": CallsiteParameter.THREAD, + "threadName": CallsiteParameter.THREAD_NAME, + "process": CallsiteParameter.PROCESS, + # This one isn't listed in the docs until 3.14, but it's worked for a long time + "processName": CallsiteParameter.PROCESS_NAME, + } + + special_keys = { + "event", + "name", + "logger", + "logger_name", + "timestamp", + "level", + } | set(map(operator.attrgetter("value"), callsite_parameters.values())) + + @classmethod + def callsite_params_from_fmt_string(cls, fmt: str) -> collections.abc.Iterable[CallsiteParameter]: + # Pattern based on https://github.com/python/cpython/blob/v3.12.11/Lib/logging/__init__.py#L441, but + # with added grouping, and comments to aid clarity, even if we don't care about anything beyond the + # mapping key + pattern = re.compile( + r""" + %\( (?P \w+ ) \) # The mapping key (in parenthesis. The bit we care about) + [#0+ -]* # Conversion flags + (?: \*|\d+ )? # Minimum field width + (?: \. (?: \* | \d+ ) )? # Precision (floating point) + [diouxefgcrsa%] # Conversion type + """, + re.I | re.X, + ) + + for match in pattern.finditer(fmt): + if param := cls.callsite_parameters.get(match["key"]): + yield param + + def __init__(self, fmt: str, **kwargs): + super().__init__(**kwargs) + self._fmt = fmt + + def __call__(self, logger: WrappedLogger, method_name: str, event_dict: EventDict): + exc = event_dict.pop("exception", None) + exc_info = event_dict.pop("exc_info", None) + stack = event_dict.pop("stack", None) + params = _LazyLogRecordDict( + event_dict, + method_name, + # To maintain compat with old log levels, we don't want to color info, just everything else + {**ConsoleRenderer.get_default_level_styles(), "info": ""}, + self._styles, + ) + + sio = StringIO() + sio.write(self._fmt % params) + + sio.write( + "".join( + " " + self._default_column_formatter(key, val) + for key, val in event_dict.items() + if key not in self.special_keys + ).rstrip(" ") + ) + + if stack is not None: + sio.write("\n" + stack) + if exc_info or exc is not None: + sio.write("\n\n" + "=" * 79 + "\n") + + if exc_info: + if isinstance(exc_info, BaseException): + exc_info = (exc_info.__class__, exc_info, exc_info.__traceback__) + if not isinstance(exc_info, tuple): + if (exc_info := sys.exc_info()) == (None, None, None): + exc_info = None + if exc_info: + self._exception_formatter(sio, exc_info) + elif exc is not None: + sio.write("\n" + exc) + + return sio.getvalue() diff --git a/shared/logging/src/airflow_shared/logging/structlog.py b/shared/logging/src/airflow_shared/logging/structlog.py new file mode 100644 index 0000000000000..2d901b83031d3 --- /dev/null +++ b/shared/logging/src/airflow_shared/logging/structlog.py @@ -0,0 +1,643 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import codecs +import io +import itertools +import logging +import os +import re +import sys +from collections.abc import Callable, Iterable, Mapping, Sequence +from functools import cache, cached_property, partial +from pathlib import Path +from typing import TYPE_CHECKING, Any, BinaryIO, Generic, TextIO, TypeVar, cast + +import pygtrie +import structlog +import structlog.processors +from structlog.processors import NAME_TO_LEVEL, CallsiteParameter + +from ._noncaching import make_file_io_non_caching +from .percent_formatter import PercentFormatRender + +if TYPE_CHECKING: + from structlog.typing import ( + BindableLogger, + EventDict, + Processor, + WrappedLogger, + ) + + from .types import Logger + +log = logging.getLogger(__name__) + +__all__ = [ + "configure_logging", + "structlog_processors", +] + +JWT_PATTERN = re.compile(r"eyJ[\.A-Za-z0-9-_]*") + +LEVEL_TO_FILTERING_LOGGER: dict[int, type[Logger]] = {} + + +def _make_airflow_structlogger(min_level): + # This uses https://github.com/hynek/structlog/blob/2f0cc42d/src/structlog/_native.py#L126 + # as inspiration + + LEVEL_TO_NAME = {v: k for k, v in NAME_TO_LEVEL.items()} + + # A few things, namely paramiko _really_ wants this to be a stdlib logger. These fns pretends it is enough + # like it to function. + @cached_property + def handlers(self): + return [logging.NullHandler()] + + @property + def level(self): + return min_level + + @property + def name(self): + return self._logger.name + + def _nop(self: Any, event: str, *args: Any, **kw: Any) -> Any: + return None + + # Work around an issue in structlog https://github.com/hynek/structlog/issues/745 + def make_method( + level: int, + ) -> Callable[..., Any]: + name = LEVEL_TO_NAME[level] + if level < min_level: + return _nop + + def meth(self: Any, event: str, *args: Any, **kw: Any) -> Any: + if not args: + return self._proxy_to_logger(name, event, **kw) + + # See for reason https://github.com/python/cpython/blob/3.13/Lib/logging/__init__.py#L307-L326 + if args and len(args) == 1 and isinstance(args[0], Mapping) and args[0]: + args = args[0] + return self._proxy_to_logger(name, event % args, **kw) + + meth.__name__ = name + return meth + + base = structlog.make_filtering_bound_logger(min_level) + + cls = type( + f"AirflowBoundLoggerFilteringAt{LEVEL_TO_NAME.get(min_level, 'Notset').capitalize()}", + (base,), + { + "isEnabledFor": base.is_enabled_for, + "getEffectiveLevel": base.get_effective_level, + "level": level, + "name": name, + "handlers": handlers, + } + | {name: make_method(lvl) for lvl, name in LEVEL_TO_NAME.items()}, + ) + LEVEL_TO_FILTERING_LOGGER[min_level] = cls + return cls + + +AirflowBoundLoggerFilteringAtNotset = _make_airflow_structlogger(NAME_TO_LEVEL["notset"]) +AirflowBoundLoggerFilteringAtDebug = _make_airflow_structlogger(NAME_TO_LEVEL["debug"]) +AirflowBoundLoggerFilteringAtInfo = _make_airflow_structlogger(NAME_TO_LEVEL["info"]) +AirflowBoundLoggerFilteringAtWarning = _make_airflow_structlogger(NAME_TO_LEVEL["warning"]) +AirflowBoundLoggerFilteringAtError = _make_airflow_structlogger(NAME_TO_LEVEL["error"]) +AirflowBoundLoggerFilteringAtCritical = _make_airflow_structlogger(NAME_TO_LEVEL["critical"]) + +# We use a trie structure (sometimes also called a "prefix tree") so that we can easily and quickly find the +# most suitable log level to apply. This mirrors the logging level cascade behavior from stdlib logging, +# without the complexity of multiple handlers etc +PER_LOGGER_LEVELS = pygtrie.StringTrie(separator=".") +PER_LOGGER_LEVELS.update( + { + # Top level logging default - changed to respect config in `configure_logging` + "": NAME_TO_LEVEL["info"], + } +) + + +def make_filtering_logger() -> Callable[..., BindableLogger]: + def maker(logger: WrappedLogger, *args, **kwargs): + # If the logger is a NamedBytesLogger/NamedWriteLogger (an Airflow specific subclass) then + # look up the global per-logger config and redirect to a new class. + + logger_name = kwargs.get("context", {}).get("logger_name") + if not logger_name and isinstance(logger, (NamedWriteLogger, NamedBytesLogger)): + logger_name = logger.name + + if logger_name: + level = PER_LOGGER_LEVELS.longest_prefix(logger_name).get(PER_LOGGER_LEVELS[""]) + else: + level = PER_LOGGER_LEVELS[""] + return LEVEL_TO_FILTERING_LOGGER[level](logger, *args, **kwargs) # type: ignore[call-arg] + + return maker + + +class NamedBytesLogger(structlog.BytesLogger): + __slots__ = ("name",) + + def __init__(self, name: str | None = None, file: BinaryIO | None = None): + self.name = name + if file is not None: + file = make_file_io_non_caching(file) + super().__init__(file) + + +class NamedWriteLogger(structlog.WriteLogger): + __slots__ = ("name",) + + def __init__(self, name: str | None = None, file: TextIO | None = None): + self.name = name + if file is not None: + file = make_file_io_non_caching(file) + super().__init__(file) + + +LogOutputType = TypeVar("LogOutputType", bound=TextIO | BinaryIO) + + +class LoggerFactory(Generic[LogOutputType]): + def __init__( + self, + cls: Callable[[str | None, LogOutputType | None], WrappedLogger], + io: LogOutputType | None = None, + ): + self.cls = cls + self.io = io + + def __call__(self, logger_name: str | None = None, *args: Any) -> WrappedLogger: + return self.cls(logger_name, self.io) + + +def logger_name(logger: Any, method_name: Any, event_dict: EventDict) -> EventDict: + if logger_name := (event_dict.pop("logger_name", None) or getattr(logger, "name", None)): + event_dict.setdefault("logger", logger_name) + return event_dict + + +# `eyJ` is `{"` in base64 encoding -- and any value that starts like that is in high likely hood a JWT +# token. Better safe than sorry +def redact_jwt(logger: Any, method_name: str, event_dict: EventDict) -> EventDict: + for k, v in event_dict.items(): + if isinstance(v, str): + event_dict[k] = re.sub(JWT_PATTERN, "eyJ***", v) + return event_dict + + +def drop_positional_args(logger: Any, method_name: Any, event_dict: EventDict) -> EventDict: + event_dict.pop("positional_args", None) + return event_dict + + +# This is a placeholder fn, that is "edited" in place via the `suppress_logs_and_warning` decorator +# The reason we need to do it this way is that structlog caches loggers on first use, and those include the +# configured processors, so we can't get away with changing the config as it won't have any effect once the +# logger obj is created and has been used once +def respect_stdlib_disable(logger: Any, method_name: Any, event_dict: EventDict) -> EventDict: + return event_dict + + +@cache +def structlog_processors( + json_output: bool, + log_format: str = "", + colors: bool = True, + callsite_parameters: tuple[CallsiteParameter, ...] = (), +): + """ + Create the correct list of structlog processors for the given config. + + Return value is a tuple of three elements: + + 1. A list of processors shared for structlgo and stblib + 2. The final processor/renderer (one that outputs a string) for use with structlog.stdlib.ProcessorFormatter + + + ``callsite_parameters`` specifies the keys to add to the log event dict. If ``log_format`` is specified + then anything callsite related will be added to this list + + :meta private: + """ + timestamper = structlog.processors.MaybeTimeStamper(fmt="iso") + + # Processors shared between stdlib handlers and structlog processors + shared_processors: list[structlog.typing.Processor] = [ + respect_stdlib_disable, + timestamper, + structlog.contextvars.merge_contextvars, + structlog.processors.add_log_level, + structlog.stdlib.PositionalArgumentsFormatter(), + logger_name, + redact_jwt, + structlog.processors.StackInfoRenderer(), + ] + + if log_format: + # Maintain the order if any params that are given explicitly, then add on anything needed for the + # format string (so use a dict with None as the values as set doesn't preserve order) + params = { + param: None + for param in itertools.chain( + callsite_parameters or [], PercentFormatRender.callsite_params_from_fmt_string(log_format) + ) + } + shared_processors.append( + structlog.processors.CallsiteParameterAdder(list(params.keys()), additional_ignores=[__name__]) + ) + elif callsite_parameters: + shared_processors.append( + structlog.processors.CallsiteParameterAdder(callsite_parameters, additional_ignores=[__name__]) + ) + + # Imports to suppress showing code from these modules. We need the import to get the filepath for + # structlog to ignore. + + import contextlib + + import click + + suppress = (click, contextlib) + try: + import httpcore + + suppress += (httpcore,) + except ImportError: + pass + try: + import httpx + + suppress += (httpx,) + except ImportError: + pass + + if json_output: + dict_exc_formatter = structlog.tracebacks.ExceptionDictTransformer( + use_rich=False, show_locals=False, suppress=suppress + ) + + dict_tracebacks = structlog.processors.ExceptionRenderer(dict_exc_formatter) + + import msgspec + + def json_dumps(msg, default): + # Note: this is likely an "expensive" step, but lets massage the dict order for nice + # viewing of the raw JSON logs. + # Maybe we don't need this once the UI renders the JSON instead of displaying the raw text + msg = { + "timestamp": msg.pop("timestamp"), + "level": msg.pop("level"), + "event": msg.pop("event"), + **msg, + } + return msgspec.json.encode(msg, enc_hook=default) + + json = structlog.processors.JSONRenderer(serializer=json_dumps) + + def json_processor(logger: Any, method_name: Any, event_dict: EventDict) -> str: + return json(logger, method_name, event_dict).decode("utf-8") + + shared_processors.extend( + ( + dict_tracebacks, + structlog.processors.UnicodeDecoder(), + ), + ) + + return shared_processors, json_processor, json + + if os.getenv("DEV", "") != "": + # Only use Rich in dev -- optherwise for "production" deployments it makes the logs harder to read as + # it uses lots of ANSI escapes and non ASCII characters. Simpler is better for non-dev non-JSON + exc_formatter = structlog.dev.RichTracebackFormatter( + # These values are picked somewhat arbitrarily to produce useful-but-compact tracebacks. If + # we ever need to change these then they should be configurable. + extra_lines=0, + max_frames=30, + indent_guides=False, + suppress=suppress, + ) + else: + exc_formatter = structlog.dev.plain_traceback + + my_styles = structlog.dev.ConsoleRenderer.get_default_level_styles(colors=colors) + if colors: + my_styles["debug"] = structlog.dev.CYAN + + if log_format: + console = PercentFormatRender( + fmt=log_format, + exception_formatter=exc_formatter, + level_styles=my_styles, + colors=colors, + ) + else: + if callsite_parameters == (CallsiteParameter.FILENAME, CallsiteParameter.LINENO): + # Nicer formatting of the default callsite config + def log_loc(logger: Any, method_name: Any, event_dict: EventDict) -> EventDict: + if ( + event_dict.get("logger") != "py.warnings" + and "filename" in event_dict + and "lineno" in event_dict + ): + event_dict["loc"] = f"{event_dict.pop('filename')}:{event_dict.pop('lineno')}" + return event_dict + + shared_processors.append(log_loc) + console = structlog.dev.ConsoleRenderer( + exception_formatter=exc_formatter, + level_styles=my_styles, + colors=colors, + ) + + return shared_processors, console, console + + +def configure_logging( + *, + json_output: bool = False, + log_level: str = "DEBUG", + log_format: str = "", + stdlib_config: dict | None = None, + extra_processors: Sequence[Processor] | None = None, + callsite_parameters: Iterable[CallsiteParameter] | None = None, + colors: bool = True, + output: LogOutputType | None = None, + log_levels: str | dict[str, str] | None = None, + cache_logger_on_first_use: bool = True, +): + """ + Configure structlog (and stbilb's logging to send via structlog processors too). + + If percent_log_format is passed then it will be handled in a similar mode to stdlib, including + interpolations such as ``%(asctime)s`` etc. + + :param json_output: Set to true to write all logs as JSON (one per line) + :param log_level: The default log level to use for most logs + :param log_format: A percent-style log format to write non JSON logs with. + :param output: Where to write the logs too. If ``json_output`` is true this must be a binary stream + :param colors: Whether to use colors for non-JSON logs. This only works if standard out is a TTY (that is, + an interactive session), unless overridden by environment variables described below. + Please note that disabling colors also disables all styling, including bold and italics. + The following environment variables control color behavior (set to any non-empty value to activate): + + * ``NO_COLOR`` - Disables colors completely. This takes precedence over all other settings, + including ``FORCE_COLOR``. + + * ``FORCE_COLOR`` - Forces colors to be enabled, even when output is not going to a TTY. This only + takes effect if ``NO_COLOR`` is not set. + + :param callsite_parameters: A list parameters about the callsite (line number, function name etc) to + include in the logs. + + If ``log_format`` is specified, then anything required to populate that (such as ``%(lineno)d``) will + be automatically included. + :param log_levels: Levels of extra loggers to configure. + + To make this easier to use, this can be a string consisting of pairs of ``=`` (either + string, or space delimited) which will set the level for that specific logger. + + For example:: + + ``sqlalchemy=INFO sqlalchemy.engine=DEBUG`` + """ + if "fatal" not in NAME_TO_LEVEL: + NAME_TO_LEVEL["fatal"] = NAME_TO_LEVEL["critical"] + + def is_atty(): + return sys.stdout is not None and hasattr(sys.stdout, "isatty") and sys.stdout.isatty() + + colors = os.environ.get("NO_COLOR", "") == "" and ( + os.environ.get("FORCE_COLOR", "") != "" or (colors and is_atty()) + ) + + stdlib_config = stdlib_config or {} + extra_processors = extra_processors or () + + PER_LOGGER_LEVELS[""] = NAME_TO_LEVEL[log_level.lower()] + + # Extract per-logger-tree levels and set them + if isinstance(log_levels, str): + log_from_level = partial(re.compile(r"\s*=\s*").split, maxsplit=2) + log_levels = {log: level for log, level in map(log_from_level, re.split(r"[\s,]+", log_levels))} + if log_levels: + for log, level in log_levels.items(): + try: + loglevel = NAME_TO_LEVEL[level.lower()] + except KeyError: + raise ValueError(f"Invalid log level for logger {log!r}: {level!r}") from None + else: + PER_LOGGER_LEVELS[log] = loglevel + + shared_pre_chain, for_stdlib, for_structlog = structlog_processors( + json_output, + log_format=log_format, + colors=colors, + callsite_parameters=tuple(callsite_parameters or ()), + ) + shared_pre_chain += list(extra_processors) + pre_chain: list[structlog.typing.Processor] = [structlog.stdlib.add_logger_name] + shared_pre_chain + + # Don't cache the loggers during tests, it make it hard to capture them + if "PYTEST_VERSION" in os.environ: + cache_logger_on_first_use = False + + std_lib_formatter: list[Processor] = [ + # TODO: Don't include this if we are using PercentFormatter -- it'll delete something we + # just have to recerated! + structlog.stdlib.ProcessorFormatter.remove_processors_meta, + drop_positional_args, + for_stdlib, + ] + + wrapper_class = cast("type[BindableLogger]", make_filtering_logger()) + if json_output: + logger_factory = LoggerFactory(NamedBytesLogger, io=output) + else: + # There is no universal way of telling if a file-like-object is binary (and needs bytes) or text that + # works for files, sockets and io.StringIO/BytesIO. + + # If given a binary object, wrap it in a text mode wrapper + if output is not None and not hasattr(output, "encoding"): + output = io.TextIOWrapper(output, line_buffering=True) + logger_factory = LoggerFactory(NamedWriteLogger, io=output) + + structlog.configure( + processors=shared_pre_chain + [for_structlog], + cache_logger_on_first_use=cache_logger_on_first_use, + wrapper_class=wrapper_class, + logger_factory=logger_factory, + ) + + import logging.config + + config = {**stdlib_config} + config.setdefault("version", 1) + config.setdefault("disable_existing_loggers", False) + config["formatters"] = {**config.get("formatters", {})} + config["handlers"] = {**config.get("handlers", {})} + config["loggers"] = {**config.get("loggers", {})} + config["formatters"].update( + { + "structlog": { + "()": structlog.stdlib.ProcessorFormatter, + "use_get_message": False, + "processors": std_lib_formatter, + "foreign_pre_chain": pre_chain, + "pass_foreign_args": True, + }, + } + ) + for section in (config["loggers"], config["handlers"]): + for log_config in section.values(): + # We want everything to go via structlog, remove whatever the user might have configured + log_config.pop("stream", None) + log_config.pop("formatter", None) + # log_config.pop("handlers", None) + + if output and not hasattr(output, "encoding"): + # This is a BinaryIO, we need to give logging.StreamHandler a TextIO + output = codecs.lookup("utf-8").streamwriter(output) # type: ignore + + config["handlers"].update( + { + "default": { + "level": log_level.upper(), + "class": "logging.StreamHandler", + "formatter": "structlog", + "stream": output, + }, + } + ) + config["loggers"].update( + { + # Set Airflow logging to the level requested, but most everything else at "INFO" + "airflow": {"level": log_level.upper()}, + # These ones are too chatty even at info + "httpx": {"level": "WARN"}, + "sqlalchemy.engine": {"level": "WARN"}, + } + ) + config["root"] = { + "handlers": ["default"], + "level": "INFO", + "propagate": True, + } + + logging.config.dictConfig(config) + + +def init_log_folder(directory: str | os.PathLike[str], new_folder_permissions: int): + """ + Prepare the log folder and ensure its mode is as configured. + + To handle log writing when tasks are impersonated, the log files need to + be writable by the user that runs the Airflow command and the user + that is impersonated. This is mainly to handle corner cases with the + SubDagOperator. When the SubDagOperator is run, all of the operators + run under the impersonated user and create appropriate log files + as the impersonated user. However, if the user manually runs tasks + of the SubDagOperator through the UI, then the log files are created + by the user that runs the Airflow command. For example, the Airflow + run command may be run by the `airflow_sudoable` user, but the Airflow + tasks may be run by the `airflow` user. If the log files are not + writable by both users, then it's possible that re-running a task + via the UI (or vice versa) results in a permission error as the task + tries to write to a log file created by the other user. + + We leave it up to the user to manage their permissions by exposing configuration for both + new folders and new log files. Default is to make new log folders and files group-writeable + to handle most common impersonation use cases. The requirement in this case will be to make + sure that the same group is set as default group for both - impersonated user and main airflow + user. + """ + directory = Path(directory) + for parent in reversed(Path(directory).parents): + parent.mkdir(mode=new_folder_permissions, exist_ok=True) + directory.mkdir(mode=new_folder_permissions, exist_ok=True) + + +def init_log_file( + base_log_folder: str | os.PathLike[str], + local_relative_path: str | os.PathLike[str], + *, + new_folder_permissions: int = 0o775, + new_file_permissions: int = 0o664, +) -> Path: + """ + Ensure log file and parent directories are created with the correct permissions. + + Any directories that are missing are created with the right permission bits. + + See above ``init_log_folder`` method for more detailed explanation. + """ + full_path = Path(base_log_folder, local_relative_path) + init_log_folder(full_path.parent, new_folder_permissions) + + try: + full_path.touch(new_file_permissions) + except OSError as e: + log = structlog.get_logger(__name__) + log.warning("OSError while changing ownership of the log file. %s", e) + + return full_path + + +def logger_without_processor_of_type(logger: WrappedLogger, processor_type: type): + procs = getattr(logger, "_processors", None) + if procs is None: + procs = structlog.get_config()["processors"] + procs = [proc for proc in procs if not isinstance(proc, processor_type)] + + return structlog.wrap_logger( + getattr(logger, "_logger", None), processors=procs, **getattr(logger, "_context", {}) + ) + + +if __name__ == "__main__": + configure_logging( + # json_output=True, + log_format="[%(blue)s%(asctime)s%(reset)s] {%(blue)s%(filename)s:%(reset)s%(lineno)d} %(log_color)s%(levelname)s%(reset)s - %(log_color)s%(message)s%(reset)s", + ) + log = logging.getLogger("testing.stlib") + log2 = structlog.get_logger(logger_name="testing.structlog") + + def raises(): + try: + 1 / 0 + except ZeroDivisionError: + log.exception("str") + try: + 1 / 0 + except ZeroDivisionError: + log2.exception("std") + + def main(): + log.info("in main") + log2.info("in main", key="value") + raises() + + main() diff --git a/shared/logging/src/airflow_shared/logging/types.py b/shared/logging/src/airflow_shared/logging/types.py new file mode 100644 index 0000000000000..224fea5848cb8 --- /dev/null +++ b/shared/logging/src/airflow_shared/logging/types.py @@ -0,0 +1,43 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from typing import Any, Protocol + +from structlog.typing import FilteringBoundLogger + +__all__ = [ + "Logger", +] + + +class Logger(FilteringBoundLogger, Protocol): # noqa: D101 + name: str + + def isEnabledFor(self, level: int): ... + def getEffectiveLevel(self) -> int: ... + + # FilteringBoundLogger defines these methods with `event: str` -- in a few places in Airflow we do + # `self.log.exception(e)` or `self.log.info(rule_results_df)` so we correct the types to allow for this + # (as the code already did) + def debug(self, event: Any, *args: Any, **kw: Any) -> Any: ... + def info(self, event: Any, *args: Any, **kw: Any) -> Any: ... + def warning(self, event: Any, *args: Any, **kw: Any) -> Any: ... + def error(self, event: Any, *args: Any, **kw: Any) -> Any: ... + def exception(self, event: Any, *args: Any, **kw: Any) -> Any: ... + def log(self, level: int, event: Any, *args: Any, **kw: Any) -> Any: ... diff --git a/shared/logging/tests/logging/test_structlog.py b/shared/logging/tests/logging/test_structlog.py new file mode 100644 index 0000000000000..08d31b2ffe3fe --- /dev/null +++ b/shared/logging/tests/logging/test_structlog.py @@ -0,0 +1,369 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import contextlib +import io +import json +import logging +import os +import sys +import textwrap +from datetime import datetime, timezone +from unittest import mock + +import pytest +import structlog +from structlog.dev import BLUE, BRIGHT, CYAN, DIM, GREEN, MAGENTA, RESET_ALL as RESET +from structlog.processors import CallsiteParameter + +from airflow_shared.logging import structlog as structlog_module +from airflow_shared.logging.structlog import configure_logging + +# We don't want to use the caplog fixture in this test, as the main purpose of this file is to capture the +# _rendered_ output of the tests to make sure it is correct. + +PY_3_11 = sys.version_info >= (3, 11) + + +@pytest.fixture(autouse=True) +def set_time(time_machine): + time_machine.move_to(datetime(1985, 10, 26, microsecond=1, tzinfo=timezone.utc), tick=False) + + +@pytest.fixture +def structlog_config(): + @contextlib.contextmanager + def configurer(**kwargs): + prev_config = structlog.get_config() + + try: + if kwargs.get("json_output"): + buff = io.BytesIO() + else: + buff = io.StringIO() + + with mock.patch("sys.stdout") as mock_stdout: + mock_stdout.isatty.return_value = True + configure_logging(**kwargs, output=buff) + + yield buff + buff.seek(0) + finally: + structlog.configure(**prev_config) + + return configurer + + +@pytest.mark.parametrize( + ("get_logger", "config_kwargs", "extra_kwargs", "extra_output"), + [ + pytest.param( + structlog.get_logger, + {}, + {"key1": "value1"}, + f" {CYAN}key1{RESET}={MAGENTA}value1{RESET}", + id="structlog", + ), + pytest.param( + structlog.get_logger, + {"callsite_parameters": [CallsiteParameter.PROCESS]}, + {"key1": "value1"}, + f" {CYAN}key1{RESET}={MAGENTA}value1{RESET} {CYAN}process{RESET}={MAGENTA}{os.getpid()}{RESET}", + id="structlog-callsite", + ), + pytest.param( + logging.getLogger, + {}, + {}, + "", + id="stdlib", + ), + pytest.param( + logging.getLogger, + {"callsite_parameters": [CallsiteParameter.PROCESS]}, + {}, + f" {CYAN}process{RESET}={MAGENTA}{os.getpid()}{RESET}", + id="stdlib-callsite", + ), + ], +) +def test_colorful(structlog_config, get_logger, config_kwargs, extra_kwargs, extra_output): + with structlog_config(colors=True, **config_kwargs) as sio: + logger = get_logger("my.logger") + # Test that interoplations work too + x = "world" + logger.info("Hello %s", x, **extra_kwargs) + + written = sio.getvalue() + # This _might_ be a little bit too specific to structlog's ConsoleRender format + assert ( + written == f"{DIM}1985-10-26T00:00:00.000001Z{RESET} [{GREEN}{BRIGHT}info {RESET}]" + f" {BRIGHT}Hello world {RESET}" + f" [{RESET}{BRIGHT}{BLUE}my.logger{RESET}]{RESET}" + extra_output + "\n" + ) + + +@pytest.mark.parametrize( + ("no_color", "force_color", "is_tty", "colors_param", "expected_colors"), + [ + # NO_COLOR takes precedence over everything + pytest.param("1", "", True, True, False, id="no_color_set_tty_colors_true"), + pytest.param("1", "", True, False, False, id="no_color_set_tty_colors_false"), + pytest.param("1", "", False, True, False, id="no_color_set_no_tty_colors_true"), + pytest.param("1", "", False, False, False, id="no_color_set_no_tty_colors_false"), + pytest.param("1", "1", True, True, False, id="no_color_and_force_color_tty_colors_true"), + pytest.param("1", "1", True, False, False, id="no_color_and_force_color_tty_colors_false"), + pytest.param("1", "1", False, True, False, id="no_color_and_force_color_no_tty_colors_true"), + pytest.param("1", "1", False, False, False, id="no_color_and_force_color_no_tty_colors_false"), + # FORCE_COLOR takes precedence when NO_COLOR is not set + pytest.param("", "1", True, True, True, id="force_color_tty_colors_true"), + pytest.param("", "1", True, False, True, id="force_color_tty_colors_false"), + pytest.param("", "1", False, True, True, id="force_color_no_tty_colors_true"), + pytest.param("", "1", False, False, True, id="force_color_no_tty_colors_false"), + # When neither NO_COLOR nor FORCE_COLOR is set, check TTY and colors param + pytest.param("", "", True, True, True, id="tty_colors_true"), + pytest.param("", "", True, False, False, id="tty_colors_false"), + pytest.param("", "", False, True, False, id="no_tty_colors_true"), + pytest.param("", "", False, False, False, id="no_tty_colors_false"), + ], +) +def test_color_config(monkeypatch, no_color, force_color, is_tty, colors_param, expected_colors): + """Test all combinations of NO_COLOR, FORCE_COLOR, is_atty(), and colors parameter.""" + + monkeypatch.setenv("NO_COLOR", no_color) + monkeypatch.setenv("FORCE_COLOR", force_color) + + with mock.patch("sys.stdout") as mock_stdout: + mock_stdout.isatty.return_value = is_tty + + with mock.patch.object(structlog_module, "structlog_processors") as mock_processors: + mock_processors.return_value = ([], None, None) + + structlog_module.configure_logging(colors=colors_param) + + mock_processors.assert_called_once() + assert mock_processors.call_args.kwargs["colors"] == expected_colors + + +@pytest.mark.parametrize( + ("get_logger", "extra_kwargs", "extra_output"), + [ + pytest.param( + structlog.get_logger, + {"key1": "value1"}, + f" {CYAN}key1{RESET}={MAGENTA}value1{RESET}", + id="structlog", + ), + pytest.param( + logging.getLogger, + {}, + "", + id="stdlib", + ), + ], +) +def test_precent_fmt(structlog_config, get_logger, extra_kwargs, extra_output): + with structlog_config(colors=True, log_format="%(blue)s[%(asctime)s]%(reset)s %(message)s") as sio: + logger = get_logger("my.logger") + logger.info("Hello", **extra_kwargs) + + written = sio.getvalue() + print(written) + assert written == f"{BLUE}[1985-10-26T00:00:00.000001Z]{RESET} Hello" + extra_output + "\n" + + +def test_precent_fmt_force_no_colors( + structlog_config, +): + with structlog_config( + colors=False, + log_format="%(blue)s[%(asctime)s]%(reset)s {%(filename)s:%(lineno)d} %(log_color)s%(levelname)s - %(message)s", + ) as sio: + logger = structlog.get_logger("my.logger") + logger.info("Hello", key1="value1") + + lineno = sys._getframe().f_lineno - 2 + + written = sio.getvalue() + assert ( + written == f"[1985-10-26T00:00:00.000001Z] {{test_structlog.py:{lineno}}} INFO - Hello key1=value1\n" + ) + + +@pytest.mark.parametrize( + ("get_logger", "config_kwargs", "log_kwargs", "expected_kwargs"), + [ + pytest.param( + structlog.get_logger, + {}, + {"key1": "value1"}, + {"key1": "value1"}, + id="structlog", + ), + pytest.param( + structlog.get_logger, + {"callsite_parameters": [CallsiteParameter.PROCESS]}, + {"key1": "value1"}, + {"key1": "value1", "process": os.getpid()}, + id="structlog-callsite", + ), + pytest.param( + logging.getLogger, + {}, + {}, + {}, + id="stdlib", + ), + pytest.param( + logging.getLogger, + {"callsite_parameters": [CallsiteParameter.PROCESS]}, + {}, + {"process": os.getpid()}, + id="stdlib-callsite", + ), + ], +) +def test_json(structlog_config, get_logger, config_kwargs, log_kwargs, expected_kwargs): + with structlog_config(json_output=True, **(config_kwargs or {})) as bio: + logger = get_logger("my.logger") + logger.info("Hello", **log_kwargs) + + written = json.load(bio) + assert written == { + "event": "Hello", + "level": "info", + **expected_kwargs, + "logger": "my.logger", + "timestamp": "1985-10-26T00:00:00.000001Z", + } + + +@pytest.mark.parametrize( + ("get_logger"), + [ + pytest.param( + structlog.get_logger, + id="structlog", + ), + pytest.param( + logging.getLogger, + id="stdlib", + ), + ], +) +def test_precent_fmt_exc(structlog_config, get_logger, monkeypatch): + monkeypatch.setenv("DEV", "") + with structlog_config( + log_format="%(message)s", + colors=False, + ) as sio: + lineno = sys._getframe().f_lineno + 2 + try: + 1 / 0 + except ZeroDivisionError: + get_logger("logger").exception("Error") + written = sio.getvalue() + + expected = textwrap.dedent(f"""\ + Error + Traceback (most recent call last): + File "{__file__}", line {lineno}, in test_precent_fmt_exc + 1 / 0 + """) + if PY_3_11: + expected += " ~~^~~\n" + expected += "ZeroDivisionError: division by zero\n" + assert written == expected + + +@pytest.mark.parametrize( + ("get_logger"), + [ + pytest.param( + structlog.get_logger, + id="structlog", + ), + pytest.param( + logging.getLogger, + id="stdlib", + ), + ], +) +def test_json_exc(structlog_config, get_logger, monkeypatch): + with structlog_config(json_output=True) as bio: + lineno = sys._getframe().f_lineno + 2 + try: + 1 / 0 + except ZeroDivisionError: + get_logger("logger").exception("Error") + written = bio.getvalue() + + written = json.load(bio) + assert written == { + "event": "Error", + "exception": [ + { + "exc_notes": [], + "exc_type": "ZeroDivisionError", + "exc_value": "division by zero", + "exceptions": [], + "frames": [ + { + "filename": __file__, + "lineno": lineno, + "name": "test_json_exc", + }, + ], + "is_cause": False, + "is_group": False, + "syntax_error": None, + }, + ], + "level": "error", + "logger": "logger", + "timestamp": "1985-10-26T00:00:00.000001Z", + } + + +@pytest.mark.parametrize( + ("levels",), + ( + pytest.param("my.logger=warn", id="str"), + pytest.param({"my.logger": "warn"}, id="dict"), + ), +) +def test_logger_filtering(structlog_config, levels): + with structlog_config( + colors=False, + log_format="[%(name)s] %(message)s", + log_level="DEBUG", + log_levels=levels, + ) as sio: + structlog.get_logger("my").info("Hello", key1="value1") + structlog.get_logger("my.logger").info("Hello", key1="value2") + structlog.get_logger("my.logger.sub").info("Hello", key1="value3") + structlog.get_logger("other.logger").info("Hello", key1="value4") + structlog.get_logger("my.logger.sub").warning("Hello", key1="value5") + + written = sio.getvalue() + assert written == textwrap.dedent("""\ + [my] Hello key1=value1 + [other.logger] Hello key1=value4 + [my.logger.sub] Hello key1=value5 + """) diff --git a/shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py b/shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py index 5709f85ec5c12..5b7ff4e1c81e4 100644 --- a/shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py +++ b/shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py @@ -158,20 +158,29 @@ def reset_secrets_masker() -> None: _secrets_masker().reset_masker() +def _is_v1_env_var(v: Any) -> TypeGuard[_V1EnvVarLike]: + """Check if object is V1EnvVar, avoiding unnecessary imports.""" + # Quick check: if k8s not imported, can't be a V1EnvVar instance + if "kubernetes.client" not in sys.modules: + return False + + # K8s is loaded, safe to get/cache the type + v1_type = _get_v1_env_var_type_cached() + return isinstance(v, v1_type) + + @cache -def _get_v1_env_var_type() -> type: +def _get_v1_env_var_type_cached() -> type: + """Get V1EnvVar type (cached, only called when k8s is already loaded).""" try: from kubernetes.client import V1EnvVar return V1EnvVar except ImportError: + # Shouldn't happen since we check sys.modules first return type("V1EnvVar", (), {}) -def _is_v1_env_var(v: Any) -> TypeGuard[_V1EnvVarLike]: - return isinstance(v, _get_v1_env_var_type()) - - class SecretsMasker(logging.Filter): """Redact secrets from logs.""" diff --git a/shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py b/shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py index bada3b392817b..ef94dc46e0208 100644 --- a/shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py +++ b/shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py @@ -1110,3 +1110,44 @@ def test_merge_round_trip(self): assert final_dict["api"]["api_key"] == "new_api_key_67890" # User modification kept assert final_dict["api"]["timeout"] == 60 # User modification kept assert final_dict["app_name"] == "my_application" # Unchanged + + +class TestKubernetesImportAvoidance: + """Test that secrets masker doesn't import kubernetes unnecessarily.""" + + def test_no_k8s_import_when_not_needed(self): + """Ensure kubernetes is not imported when masking non-k8s secrets.""" + # Ensure kubernetes is not already imported + k8s_modules = [m for m in sys.modules if m.startswith("kubernetes")] + if k8s_modules: + pytest.skip("Kubernetes already imported, cannot test import avoidance") + + masker = SecretsMasker() + configure_secrets_masker_for_test(masker) + + masker.add_mask("test_secret", "password") + redacted = masker.redact({"password": "test_secret", "user": "admin"}) + + assert redacted["password"] == "***" + assert redacted["user"] == "admin" + + assert "kubernetes.client" not in sys.modules + + def test_k8s_objects_still_detected_when_imported(self): + """Ensure V1EnvVar objects are still properly detected when k8s is imported.""" + pytest.importorskip("kubernetes") + + from kubernetes.client import V1EnvVar + + # Create a V1EnvVar object with a sensitive name + env_var = V1EnvVar(name="password", value="secret123") + + masker = SecretsMasker() + configure_secrets_masker_for_test(masker) + + # Redact the V1EnvVar object - the name field is sensitive + redacted = masker.redact(env_var) + + # Should be redacted since "password" is a sensitive field name + assert redacted["value"] == "***" + assert redacted["name"] == "password" diff --git a/task-sdk/pyproject.toml b/task-sdk/pyproject.toml index 8140b78743407..5089ef2f5c9df 100644 --- a/task-sdk/pyproject.toml +++ b/task-sdk/pyproject.toml @@ -49,8 +49,10 @@ classifiers = [ "Topic :: System :: Monitoring", ] dependencies = [ - "apache-airflow-core<3.2.0,>=3.1.0", + "apache-airflow-core<3.2.0,>=3.1.1", + "asgiref>=2.3.0", "attrs>=24.2.0, !=25.2.0", + "babel>=2.17.0", "fsspec>=2023.10.0", "httpx>=0.27.0", "jinja2>=3.1.5", @@ -60,6 +62,7 @@ dependencies = [ "psutil>=6.1.0", "structlog>=25.4.0", "retryhttp>=1.2.0,!=1.3.0", + "greenback>=1.2.1", # Requests is known to introduce breaking changes, so we pin it to a specific range "requests>=2.31.0,<3", "types-requests>=2.31.0", @@ -71,6 +74,9 @@ dependencies = [ "colorlog>=6.8.2", "pydantic>2.11.0", # End of shared secrets_masker dependencies + # Start of shared logging dependencies + "pygtrie>=2.5.0", + # End of shared logging dependencies ] [project.urls] @@ -92,8 +98,9 @@ build-backend = "hatchling.build" path = "src/airflow/sdk/__init__.py" [tool.hatch.build.targets.sdist.force-include] -"../shared/timezones/src/airflow_shared/timezones" = "src/airflow/sdk/_shared/timezones" +"../shared/logging/src/airflow_shared/logging" = "src/airflow/sdk/_shared/logging" "../shared/secrets_masker/src/airflow_shared/secrets_masker" = "src/airflow/sdk/_shared/secrets_masker" +"../shared/timezones/src/airflow_shared/timezones" = "src/airflow/sdk/_shared/timezones" [tool.hatch.build.targets.wheel] packages = ["src/airflow"] @@ -148,7 +155,7 @@ exclude_also = [ [dependency-groups] codegen = [ - "datamodel-code-generator[http]==0.32.0", + "datamodel-code-generator[http]==0.33.0", "openapi-spec-validator>=0.7.1", "svcs>=25.1.0", "rich>=13.6.0", @@ -235,6 +242,7 @@ tmp_path_retention_policy = "failed" [tool.airflow] shared_distributions = [ - "apache-airflow-shared-timezones", + "apache-airflow-shared-logging", "apache-airflow-shared-secrets-masker", + "apache-airflow-shared-timezones", ] diff --git a/task-sdk/src/airflow/sdk/__init__.py b/task-sdk/src/airflow/sdk/__init__.py index 271e2d02ebaad..fcb4dfb9239ed 100644 --- a/task-sdk/src/airflow/sdk/__init__.py +++ b/task-sdk/src/airflow/sdk/__init__.py @@ -60,10 +60,10 @@ "teardown", ] -__version__ = "1.1.0" +__version__ = "1.1.1" if TYPE_CHECKING: - from airflow.sdk.api.datamodels._generated import DagRunState, TaskInstanceState, TriggerRule + from airflow.sdk.api.datamodels._generated import DagRunState, TaskInstanceState, TriggerRule, WeightRule from airflow.sdk.bases.hook import BaseHook from airflow.sdk.bases.notifier import BaseNotifier from airflow.sdk.bases.operator import BaseOperator, chain, chain_linear, cross_downstream diff --git a/task-sdk/src/airflow/sdk/_shared/logging b/task-sdk/src/airflow/sdk/_shared/logging new file mode 120000 index 0000000000000..fda343f9a7ea6 --- /dev/null +++ b/task-sdk/src/airflow/sdk/_shared/logging @@ -0,0 +1 @@ +../../../../../shared/logging/src/airflow_shared/logging/ \ No newline at end of file diff --git a/task-sdk/src/airflow/sdk/api/client.py b/task-sdk/src/airflow/sdk/api/client.py index 04575fa770d05..6d71a7f106b9b 100644 --- a/task-sdk/src/airflow/sdk/api/client.py +++ b/task-sdk/src/airflow/sdk/api/client.py @@ -44,6 +44,7 @@ DagRunStateResponse, DagRunType, HITLDetailResponse, + HITLUser, InactiveAssetsResponse, PrevSuccessfulDagRunResponse, TaskInstanceState, @@ -723,7 +724,7 @@ def add_response( defaults: list[str] | None = None, multiple: bool = False, params: dict[str, Any] | None = None, - respondents: list[str] | None = None, + assigned_users: list[HITLUser] | None = None, ) -> HITLDetailRequestResult: """Add a Human-in-the-loop response that waits for human response for a specific Task Instance.""" payload = CreateHITLDetailPayload( @@ -734,7 +735,7 @@ def add_response( defaults=defaults, multiple=multiple, params=params, - respondents=respondents, + assigned_users=assigned_users, ) resp = self.client.post( f"/hitlDetails/{ti_id}", @@ -809,6 +810,7 @@ def noop_handler(request: httpx.Request) -> httpx.Response: API_RETRY_WAIT_MIN = conf.getfloat("workers", "execution_api_retry_wait_min") API_RETRY_WAIT_MAX = conf.getfloat("workers", "execution_api_retry_wait_max") API_SSL_CERT_PATH = conf.get("api", "ssl_cert") +API_TIMEOUT = conf.getfloat("workers", "execution_api_timeout") class Client(httpx.Client): @@ -828,6 +830,10 @@ def __init__(self, *, base_url: str | None, dry_run: bool = False, token: str, * if API_SSL_CERT_PATH: ctx.load_verify_locations(API_SSL_CERT_PATH) kwargs["verify"] = ctx + + # Set timeout if not explicitly provided + kwargs.setdefault("timeout", API_TIMEOUT) + pyver = f"{'.'.join(map(str, sys.version_info[:3]))}" super().__init__( auth=auth, diff --git a/task-sdk/src/airflow/sdk/api/datamodels/_generated.py b/task-sdk/src/airflow/sdk/api/datamodels/_generated.py index cd861bf07d124..ba53f911216bd 100644 --- a/task-sdk/src/airflow/sdk/api/datamodels/_generated.py +++ b/task-sdk/src/airflow/sdk/api/datamodels/_generated.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: http://0.0.0.0:8080/execution/openapi.json -# version: 0.32.0 +# version: 0.33.0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file @@ -154,32 +154,13 @@ class DagRunType(str, Enum): ASSET_TRIGGERED = "asset_triggered" -class HITLDetailRequest(BaseModel): - """ - Schema for the request part of a Human-in-the-loop detail for a specific task instance. - """ - - ti_id: Annotated[UUID, Field(title="Ti Id")] - options: Annotated[list[str], Field(min_length=1, title="Options")] - subject: Annotated[str, Field(title="Subject")] - body: Annotated[str | None, Field(title="Body")] = None - defaults: Annotated[list[str] | None, Field(title="Defaults")] = None - multiple: Annotated[bool | None, Field(title="Multiple")] = False - params: Annotated[dict[str, Any] | None, Field(title="Params")] = None - respondents: Annotated[list[str] | None, Field(title="Respondents")] = None - - -class HITLDetailResponse(BaseModel): +class HITLUser(BaseModel): """ - Schema for the response part of a Human-in-the-loop detail for a specific task instance. + Schema for a Human-in-the-loop users. """ - response_received: Annotated[bool, Field(title="Response Received")] - responded_user_name: Annotated[str | None, Field(title="Responded User Name")] = None - responded_user_id: Annotated[str | None, Field(title="Responded User Id")] = None - response_at: Annotated[AwareDatetime | None, Field(title="Response At")] = None - chosen_options: Annotated[list[str] | None, Field(title="Chosen Options")] = None - params_input: Annotated[dict[str, Any] | None, Field(title="Params Input")] = None + id: Annotated[str, Field(title="Id")] + name: Annotated[str, Field(title="Name")] class InactiveAssetsResponse(BaseModel): @@ -561,6 +542,33 @@ class DagRun(BaseModel): consumed_asset_events: Annotated[list[AssetEventDagRunReference], Field(title="Consumed Asset Events")] +class HITLDetailRequest(BaseModel): + """ + Schema for the request part of a Human-in-the-loop detail for a specific task instance. + """ + + ti_id: Annotated[UUID, Field(title="Ti Id")] + options: Annotated[list[str], Field(min_length=1, title="Options")] + subject: Annotated[str, Field(title="Subject")] + body: Annotated[str | None, Field(title="Body")] = None + defaults: Annotated[list[str] | None, Field(title="Defaults")] = None + multiple: Annotated[bool | None, Field(title="Multiple")] = False + params: Annotated[dict[str, Any] | None, Field(title="Params")] = None + assigned_users: Annotated[list[HITLUser] | None, Field(title="Assigned Users")] = None + + +class HITLDetailResponse(BaseModel): + """ + Schema for the response part of a Human-in-the-loop detail for a specific task instance. + """ + + response_received: Annotated[bool, Field(title="Response Received")] + responded_by_user: HITLUser | None = None + responded_at: Annotated[AwareDatetime | None, Field(title="Responded At")] = None + chosen_options: Annotated[list[str] | None, Field(title="Chosen Options")] = None + params_input: Annotated[dict[str, Any] | None, Field(title="Params Input")] = None + + class HTTPValidationError(BaseModel): detail: Annotated[list[ValidationError] | None, Field(title="Detail")] = None diff --git a/task-sdk/src/airflow/sdk/bases/operator.py b/task-sdk/src/airflow/sdk/bases/operator.py index 7a8e80ec4d98a..a11b5894b0d60 100644 --- a/task-sdk/src/airflow/sdk/bases/operator.py +++ b/task-sdk/src/airflow/sdk/bases/operator.py @@ -1108,7 +1108,7 @@ def __init__( raise ValueError(f"pool slots for {self.task_id}{dag_str} cannot be less than 1") if sla is not None: warnings.warn( - "The SLA feature is removed in Airflow 3.0, to be replaced with a new implementation in >=3.1", + "The SLA feature is removed in Airflow 3.0, replaced with Deadline Alerts in >=3.1", stacklevel=2, ) @@ -1309,12 +1309,12 @@ def _convert__dag(self, dag: DAG | None) -> DAG | None: return dag if not isinstance(dag, DAG): - raise TypeError(f"Expected Dag; received {dag.__class__.__name__}") + raise TypeError(f"Expected dag; received {dag.__class__.__name__}") if self._dag is not None and self._dag is not dag: - raise ValueError(f"The Dag assigned to {self} can not be changed.") + raise ValueError(f"The dag assigned to {self} can not be changed.") if self.__from_mapped: - pass # Don't add to Dag -- the mapped task takes the place. + pass # Don't add to dag -- the mapped task takes the place. elif dag.task_dict.get(self.task_id) is not self: dag.add_task(self) return dag diff --git a/task-sdk/src/airflow/sdk/definitions/_internal/node.py b/task-sdk/src/airflow/sdk/definitions/_internal/node.py index 75958d047b421..86979e442cd5e 100644 --- a/task-sdk/src/airflow/sdk/definitions/_internal/node.py +++ b/task-sdk/src/airflow/sdk/definitions/_internal/node.py @@ -17,20 +17,21 @@ from __future__ import annotations -import logging import re from abc import ABCMeta, abstractmethod from collections.abc import Collection, Iterable, Sequence from datetime import datetime from typing import TYPE_CHECKING, Any +import structlog + from airflow.sdk.definitions._internal.mixins import DependencyMixin if TYPE_CHECKING: from airflow.sdk.definitions.dag import DAG from airflow.sdk.definitions.edges import EdgeModifier from airflow.sdk.definitions.taskgroup import TaskGroup - from airflow.sdk.types import Operator + from airflow.sdk.types import Logger, Operator from airflow.serialization.enums import DagAttributeTypes @@ -81,7 +82,7 @@ class DAGNode(DependencyMixin, metaclass=ABCMeta): _log_config_logger_name: str | None = None _logger_name: str | None = None - _cached_logger: logging.Logger | None = None + _cached_logger: Logger | None = None def __init__(self): self.upstream_task_ids = set() @@ -115,7 +116,7 @@ def dag_id(self) -> str: return "_in_memory_dag_" @property - def log(self) -> logging.Logger: + def log(self) -> Logger: """ Get a logger for this node. @@ -140,7 +141,7 @@ def log(self) -> logging.Logger: else self._log_config_logger_name ) - self._cached_logger = logging.getLogger(logger_name) + self._cached_logger = structlog.get_logger(logger_name) return self._cached_logger @property diff --git a/task-sdk/src/airflow/sdk/definitions/asset/decorators.py b/task-sdk/src/airflow/sdk/definitions/asset/decorators.py index 245cc24d27384..44d23efdbbad8 100644 --- a/task-sdk/src/airflow/sdk/definitions/asset/decorators.py +++ b/task-sdk/src/airflow/sdk/definitions/asset/decorators.py @@ -66,7 +66,7 @@ def from_definition(cls, definition: AssetDefinition | MultiAssetDefinition) -> ], outlets=[v for _, v in definition.iter_assets()], python_callable=definition._function, - definition_name=definition._function.__name__, + definition_name=definition.name, ) def _iter_kwargs(self, context: Mapping[str, Any]) -> Iterator[tuple[str, Any]]: @@ -137,6 +137,7 @@ class MultiAssetDefinition(BaseAsset): :meta private: """ + name: str _function: Callable _source: asset.multi @@ -231,7 +232,7 @@ def __call__(self, f: Callable) -> MultiAssetDefinition: raise ValueError("nested function not supported") if not self.outlets: raise ValueError("no outlets provided") - return MultiAssetDefinition(function=f, source=self) + return MultiAssetDefinition(function=f, source=self, name=f.__name__) def __call__(self, f: Callable) -> AssetDefinition: if f.__name__ != f.__qualname__: diff --git a/task-sdk/src/airflow/sdk/definitions/connection.py b/task-sdk/src/airflow/sdk/definitions/connection.py index cc2e92a41aa1a..b1fb1190bc311 100644 --- a/task-sdk/src/airflow/sdk/definitions/connection.py +++ b/task-sdk/src/airflow/sdk/definitions/connection.py @@ -17,10 +17,12 @@ # under the License. from __future__ import annotations +import asyncio import json import logging from json import JSONDecodeError from typing import Any +from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit import attrs @@ -30,6 +32,26 @@ log = logging.getLogger(__name__) +def _parse_netloc_to_hostname(uri_parts): + """ + Parse a URI string to get the correct Hostname. + + ``urlparse(...).hostname`` or ``urlsplit(...).hostname`` returns value into the lowercase in most cases, + there are some exclusion exists for specific cases such as https://bugs.python.org/issue32323 + In case if expected to get a path as part of hostname path, + then default behavior ``urlparse``/``urlsplit`` is unexpected. + """ + hostname = unquote(uri_parts.hostname or "") + if "/" in hostname: + hostname = uri_parts.netloc + if "@" in hostname: + hostname = hostname.rsplit("@", 1)[1] + if ":" in hostname: + hostname = hostname.split(":", 1)[0] + hostname = unquote(hostname) + return hostname + + def _prune_dict(val: Any, mode="strict"): """ Given dict ``val``, returns new dict based on ``val`` with all empty elements removed. @@ -103,7 +125,7 @@ class Connection: def get_uri(self) -> str: """Generate and return connection in URI format.""" - from urllib.parse import parse_qsl, quote, urlencode + from urllib.parse import parse_qsl if self.conn_type and "_" in self.conn_type: log.warning( @@ -155,10 +177,11 @@ def get_uri(self) -> str: if self.extra: try: - query: str | None = urlencode(self.extra_dejson) + extra_dejson = self.extra_dejson + query: str | None = urlencode(extra_dejson) except TypeError: query = None - if query and self.extra_dejson == dict(parse_qsl(query, keep_blank_values=True)): + if query and extra_dejson == dict(parse_qsl(query, keep_blank_values=True)): uri += ("?" if self.schema else "/?") + query else: uri += ("?" if self.schema else "/?") + urlencode({self.EXTRA_KEY: self.extra}) @@ -203,6 +226,24 @@ def get(cls, conn_id: str) -> Any: return _get_connection(conn_id) except AirflowRuntimeError as e: cls._handle_connection_error(e, conn_id) + except RuntimeError as e: + # The error from async_to_sync is a RuntimeError, so we have to fall back to text matching + if str(e).startswith("You cannot use AsyncToSync in the same thread as an async event loop"): + import greenback + + task = asyncio.current_task() + if greenback.has_portal(task): + import warnings + + warnings.warn( + "You should not use sync calls here -- use `await Conn.async_get` instead", + stacklevel=2, + ) + + return greenback.await_(cls.async_get(conn_id)) + + log.exception("async_to_sync failed") + raise @classmethod async def async_get(cls, conn_id: str) -> Any: @@ -297,6 +338,64 @@ def as_json(self) -> str: conn_repr.pop("conn_id", None) return json.dumps(conn_repr) + @classmethod + def from_uri(cls, uri: str, conn_id: str) -> Connection: + """ + Create a Connection from a URI string. + + :param uri: URI string to parse + :param conn_id: Connection ID to assign to the connection + :return: Connection object + """ + schemes_count_in_uri = uri.count("://") + if schemes_count_in_uri > 2: + raise AirflowException(f"Invalid connection string: {uri}.") + host_with_protocol = schemes_count_in_uri == 2 + uri_parts = urlsplit(uri) + conn_type = uri_parts.scheme + normalized_conn_type = cls._normalize_conn_type(conn_type) + rest_of_the_url = uri.replace(f"{conn_type}://", ("" if host_with_protocol else "//")) + if host_with_protocol: + uri_splits = rest_of_the_url.split("://", 1) + if "@" in uri_splits[0] or ":" in uri_splits[0]: + raise AirflowException(f"Invalid connection string: {uri}.") + uri_parts = urlsplit(rest_of_the_url) + protocol = uri_parts.scheme if host_with_protocol else None + host = _parse_netloc_to_hostname(uri_parts) + parsed_host = cls._create_host(protocol, host) + quoted_schema = uri_parts.path[1:] + schema = unquote(quoted_schema) if quoted_schema else quoted_schema + login = unquote(uri_parts.username) if uri_parts.username else uri_parts.username + password = unquote(uri_parts.password) if uri_parts.password else uri_parts.password + port = uri_parts.port + extra = None + if uri_parts.query: + query = dict(parse_qsl(uri_parts.query, keep_blank_values=True)) + if cls.EXTRA_KEY in query: + extra = query[cls.EXTRA_KEY] + else: + extra = json.dumps(query) + + return cls( + conn_id=conn_id, + conn_type=normalized_conn_type, + host=parsed_host, + schema=schema, + login=login, + password=password, + port=port, + extra=extra, + ) + + @staticmethod + def _create_host(protocol, host) -> str | None: + """Return the connection host with the protocol.""" + if not host: + return host + if protocol: + return f"{protocol}://{host}" + return host + @staticmethod def _normalize_conn_type(conn_type): if conn_type == "postgresql": diff --git a/task-sdk/src/airflow/sdk/definitions/dag.py b/task-sdk/src/airflow/sdk/definitions/dag.py index 36215420cd36c..d5ae8353bd93d 100644 --- a/task-sdk/src/airflow/sdk/definitions/dag.py +++ b/task-sdk/src/airflow/sdk/definitions/dag.py @@ -66,10 +66,12 @@ from pendulum.tz.timezone import FixedTimezone, Timezone + from airflow.models.taskinstance import TaskInstance as SchedulerTaskInstance from airflow.sdk.definitions.decorators import TaskDecoratorCollection from airflow.sdk.definitions.edges import EdgeInfoType from airflow.sdk.definitions.mappedoperator import MappedOperator from airflow.sdk.definitions.taskgroup import TaskGroup + from airflow.sdk.execution_time.supervisor import TaskRunResult from airflow.typing_compat import Self Operator: TypeAlias = BaseOperator | MappedOperator @@ -184,6 +186,15 @@ def _convert_access_control(access_control): return updated_access_control +def _convert_deadline(deadline: list[DeadlineAlert] | DeadlineAlert | None) -> list[DeadlineAlert] | None: + """Convert deadline parameter to a list of DeadlineAlert objects.""" + if deadline is None: + return None + if isinstance(deadline, DeadlineAlert): + return [deadline] + return list(deadline) + + def _convert_doc_md(doc_md: str | None) -> str | None: if doc_md is None: return doc_md @@ -324,7 +335,8 @@ class DAG: beyond this the scheduler will disable the DAG :param dagrun_timeout: Specify the duration a DagRun should be allowed to run before it times out or fails. Task instances that are running when a DagRun is timed out will be marked as skipped. - :param sla_miss_callback: DEPRECATED - The SLA feature is removed in Airflow 3.0, to be replaced with a new implementation in 3.1 + :param sla_miss_callback: DEPRECATED - The SLA feature is removed in Airflow 3.0, to be replaced with DeadlineAlerts in 3.1 + :param deadline: An optional DeadlineAlert for the Dag. :param catchup: Perform scheduler catchup (or only run latest)? Defaults to False :param on_failure_callback: A function or list of functions to be called when a DagRun of this dag fails. A context dictionary is passed as a single parameter to this function. @@ -437,11 +449,18 @@ def __rich_repr__(self): default=None, validator=attrs.validators.optional(attrs.validators.instance_of(timedelta)), ) - deadline: DeadlineAlert | None = attrs.field( + deadline: list[DeadlineAlert] | DeadlineAlert | None = attrs.field( default=None, - validator=attrs.validators.optional(attrs.validators.instance_of(DeadlineAlert)), + converter=_convert_deadline, + validator=attrs.validators.optional( + attrs.validators.deep_iterable( + member_validator=attrs.validators.instance_of(DeadlineAlert), + iterable_validator=attrs.validators.instance_of(list), + ) + ), ) + sla_miss_callback: None = attrs.field(default=None) catchup: bool = attrs.field( factory=_config_bool_factory("scheduler", "catchup_by_default"), ) @@ -514,6 +533,13 @@ def __attrs_post_init__(self): RemovedInAirflow4Warning, stacklevel=2, ) + if ( + active_runs_limit := self.timetable.active_runs_limit + ) is not None and active_runs_limit < self.max_active_runs: + raise ValueError( + f"Invalid max_active_runs: {type(self.timetable)} " + f"requires max_active_runs <= {active_runs_limit}" + ) @params.validator def _validate_params(self, _, params: ParamsDict): @@ -596,6 +622,15 @@ def _has_on_success_callback(self) -> bool: def _has_on_failure_callback(self) -> bool: return self.on_failure_callback is not None + @sla_miss_callback.validator + def _validate_sla_miss_callback(self, _, value): + if value is not None: + warnings.warn( + "The SLA feature is removed in Airflow 3.0, and replaced with a Deadline Alerts in >=3.1", + stacklevel=2, + ) + return value + def __repr__(self): return f"" @@ -1072,7 +1107,6 @@ def get_serialized_fields(cls): def get_edge_info(self, upstream_task_id: str, downstream_task_id: str) -> EdgeInfoType: """Return edge information for the given pair of tasks or an empty edge if there is no information.""" - # Note - older serialized Dags may not have edge_info being a dict at all empty = cast("EdgeInfoType", {}) if self.edge_info: return self.edge_info.get(upstream_task_id, {}).get(downstream_task_id, empty) @@ -1138,29 +1172,6 @@ def test( from airflow.utils.state import State from airflow.utils.types import DagRunTriggeredByType, DagRunType - if TYPE_CHECKING: - from airflow.models.taskinstance import TaskInstance - - def add_logger_if_needed(ti: TaskInstance): - """ - Add a formatted logger to the task instance. - - This allows all logs to surface to the command line, instead of into - a task file. Since this is a local test run, it is much better for - the user to see logs in the command line, rather than needing to - search for a log file. - - :param ti: The task instance that will receive a logger. - """ - format = logging.Formatter("[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s") - handler = logging.StreamHandler(sys.stdout) - handler.level = logging.INFO - handler.setFormatter(format) - # only add log handler once - if not any(isinstance(h, logging.StreamHandler) for h in ti.log.handlers): - log.debug("Adding Streamhandler to taskinstance %s", ti.task_id) - ti.log.addHandler(handler) - exit_stack = ExitStack() if conn_file_path or variable_file_path: @@ -1193,15 +1204,43 @@ def add_logger_if_needed(ti: TaskInstance): data_interval = ( self.timetable.infer_manual_data_interval(run_after=logical_date) if logical_date else None ) - scheduler_dag = SerializedDAG.deserialize_dag(SerializedDAG.serialize_dag(self)) # type: ignore[arg-type] + from airflow.models.dag_version import DagVersion + + version = DagVersion.get_version(self.dag_id) + if not version: + from airflow.dag_processing.bundles.manager import DagBundlesManager + from airflow.models.dagbag import DagBag, sync_bag_to_db + from airflow.sdk.definitions._internal.dag_parsing_context import ( + _airflow_parsing_context_manager, + ) + + manager = DagBundlesManager() + manager.sync_bundles_to_db(session=session) + session.commit() + # sync all bundles? or use the dags-folder bundle? + # What if the test dag is in a different bundle? + for bundle in manager.get_all_dag_bundles(): + if not bundle.is_initialized: + bundle.initialize() + with _airflow_parsing_context_manager(dag_id=self.dag_id): + dagbag = DagBag( + dag_folder=bundle.path, bundle_path=bundle.path, include_examples=False + ) + sync_bag_to_db(dagbag, bundle.name, bundle.version) + version = DagVersion.get_version(self.dag_id) + if version: + break + scheduler_dag = SerializedDAG.deserialize_dag(SerializedDAG.serialize_dag(self)) # Preserve callback functions from original Dag since they're lost during serialization # and yes it is a hack for now! It is a tradeoff for code simplicity. # Without it, we need "Scheduler Dag" (Serialized dag) for the scheduler bits # -- dep check, scheduling tis # and need real dag to get and run callbacks without having to load the dag model - scheduler_dag.on_success_callback = self.on_success_callback - scheduler_dag.on_failure_callback = self.on_failure_callback + # Scheduler DAG shouldn't have these attributes, but assigning them + # here is an easy hack to get this test() thing working. + scheduler_dag.on_success_callback = self.on_success_callback # type: ignore[attr-defined, union-attr] + scheduler_dag.on_failure_callback = self.on_failure_callback # type: ignore[attr-defined, union-attr] dr: DagRun = get_or_create_dagrun( dag=scheduler_dag, @@ -1291,7 +1330,6 @@ def add_logger_if_needed(ti: TaskInstance): else: # Run the task locally try: - add_logger_if_needed(ti) if mark_success: ti.set_state(State.SUCCESS) log.info("[DAG TEST] Marking success for %s on %s", task, ti.logical_date) @@ -1312,7 +1350,12 @@ def add_logger_if_needed(ti: TaskInstance): return dr -def _run_task(*, ti, task, run_triggerer=False): +def _run_task( + *, + ti: SchedulerTaskInstance, + task: Operator, + run_triggerer: bool = False, +) -> TaskRunResult | None: """ Run a single task instance, and push result to Xcom for downstream tasks. @@ -1322,6 +1365,7 @@ def _run_task(*, ti, task, run_triggerer=False): from airflow.sdk.module_loading import import_string from airflow.utils.state import State + taskrun_result: TaskRunResult | None log.info("[DAG TEST] starting task_id=%s map_index=%s", ti.task_id, ti.map_index) while True: try: @@ -1330,6 +1374,7 @@ def _run_task(*, ti, task, run_triggerer=False): from airflow.sdk.api.datamodels._generated import TaskInstance as TaskInstanceSDK from airflow.sdk.execution_time.comms import DeferTask from airflow.sdk.execution_time.supervisor import run_task_in_process + from airflow.serialization.serialized_objects import create_scheduler_operator # The API Server expects the task instance to be in QUEUED state before # it is run. @@ -1344,14 +1389,10 @@ def _run_task(*, ti, task, run_triggerer=False): dag_version_id=ti.dag_version_id, ) - taskrun_result = run_task_in_process( - ti=task_sdk_ti, - task=task, - ) - + taskrun_result = run_task_in_process(ti=task_sdk_ti, task=task) msg = taskrun_result.msg ti.set_state(taskrun_result.ti.state) - ti.task = taskrun_result.ti.task + ti.task = create_scheduler_operator(taskrun_result.ti.task) if ti.state == State.DEFERRED and isinstance(msg, DeferTask) and run_triggerer: from airflow.utils.session import create_session @@ -1371,16 +1412,19 @@ def _run_task(*, ti, task, run_triggerer=False): with create_session() as session: ti.state = State.SCHEDULED session.add(ti) + continue - return taskrun_result + break except Exception: log.exception("[DAG TEST] Error running task %s", ti) if ti.state not in State.finished: ti.set_state(State.FAILED) + taskrun_result = None break raise log.info("[DAG TEST] end task task_id=%s map_index=%s", ti.task_id, ti.map_index) + return taskrun_result def _run_inline_trigger(trigger, task_sdk_ti): @@ -1439,7 +1483,7 @@ def dag( catchup: bool = ..., on_success_callback: None | DagStateChangeCallback | list[DagStateChangeCallback] = None, on_failure_callback: None | DagStateChangeCallback | list[DagStateChangeCallback] = None, - deadline: DeadlineAlert | None = None, + deadline: list[DeadlineAlert] | DeadlineAlert | None = None, doc_md: str | None = None, params: ParamsDict | dict[str, Any] | None = None, access_control: dict[str, dict[str, Collection[str]]] | dict[str, Collection[str]] | None = None, diff --git a/task-sdk/src/airflow/sdk/definitions/variable.py b/task-sdk/src/airflow/sdk/definitions/variable.py index 1386aee258e1a..2e4c9aae3ca0f 100644 --- a/task-sdk/src/airflow/sdk/definitions/variable.py +++ b/task-sdk/src/airflow/sdk/definitions/variable.py @@ -44,7 +44,6 @@ class Variable: value: Any | None = None description: str | None = None - # TODO: Extend this definition for reading/writing variables without context @classmethod def get(cls, key: str, default: Any = NOTSET, deserialize_json: bool = False): from airflow.sdk.exceptions import AirflowRuntimeError, ErrorType diff --git a/task-sdk/src/airflow/sdk/execution_time/context.py b/task-sdk/src/airflow/sdk/execution_time/context.py index 570cd25d9a3ef..58bd2521b0278 100644 --- a/task-sdk/src/airflow/sdk/execution_time/context.py +++ b/task-sdk/src/airflow/sdk/execution_time/context.py @@ -116,6 +116,14 @@ def _process_connection_result_conn(conn_result: ReceiveMsgType | None) -> Conne return Connection(**conn_result.model_dump(exclude={"type"}, by_alias=True)) +def _mask_connection_secrets(conn: Connection) -> None: + """Mask sensitive connection fields from logs.""" + if conn.password: + mask_secret(conn.password) + if conn.extra: + mask_secret(conn.extra) + + def _convert_variable_result_to_variable(var_result: VariableResult, deserialize_json: bool) -> Variable: from airflow.sdk.definitions.variable import Variable @@ -127,72 +135,116 @@ def _convert_variable_result_to_variable(var_result: VariableResult, deserialize def _get_connection(conn_id: str) -> Connection: + from airflow.sdk.execution_time.cache import SecretCache from airflow.sdk.execution_time.supervisor import ensure_secrets_backend_loaded - # TODO: check cache first (also in _async_get_connection) - # enabled only if SecretCache.init() has been called first + # Check cache first (optional; only on dag processor) + try: + uri = SecretCache.get_connection_uri(conn_id) + from airflow.sdk.definitions.connection import Connection - # iterate over configured backends if not in cache (or expired) + conn = Connection.from_uri(uri, conn_id=conn_id) + _mask_connection_secrets(conn) + return conn + except SecretCache.NotPresentException: + pass # continue to backends + + # Iterate over configured backends (which may include SupervisorCommsSecretsBackend + # in worker contexts or MetastoreBackend in API server contexts) backends = ensure_secrets_backend_loaded() for secrets_backend in backends: try: - conn = secrets_backend.get_connection(conn_id=conn_id) + conn = secrets_backend.get_connection(conn_id=conn_id) # type: ignore[assignment] if conn: - # TODO: this should probably be in get conn - if conn.password: - mask_secret(conn.password) - if conn.extra: - mask_secret(conn.extra) + SecretCache.save_connection_uri(conn_id, conn.get_uri()) + _mask_connection_secrets(conn) return conn except Exception: - log.exception( + log.debug( "Unable to retrieve connection from secrets backend (%s). " "Checking subsequent secrets backend.", type(secrets_backend).__name__, ) - if backends: - log.debug( - "Connection not found in any of the configured Secrets Backends. Trying to retrieve from API server", - conn_id=conn_id, - ) + # If no backend found the connection, raise an error + from airflow.exceptions import AirflowNotFoundException - # TODO: This should probably be moved to a separate module like `airflow.sdk.execution_time.comms` - # or `airflow.sdk.execution_time.connection` - # A reason to not move it to `airflow.sdk.execution_time.comms` is that it - # will make that module depend on Task SDK, which is not ideal because we intend to - # keep Task SDK as a separate package than execution time mods. - # Also applies to _async_get_connection. - from airflow.sdk.execution_time.comms import GetConnection - from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS + raise AirflowNotFoundException(f"The conn_id `{conn_id}` isn't defined") - msg = SUPERVISOR_COMMS.send(GetConnection(conn_id=conn_id)) - return _process_connection_result_conn(msg) +async def _async_get_connection(conn_id: str) -> Connection: + from asgiref.sync import sync_to_async + from airflow.sdk.execution_time.cache import SecretCache -async def _async_get_connection(conn_id: str) -> Connection: - # TODO: add async support for secrets backends + # Check cache first + try: + uri = SecretCache.get_connection_uri(conn_id) + from airflow.sdk.definitions.connection import Connection - from airflow.sdk.execution_time.comms import GetConnection - from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS + conn = Connection.from_uri(uri, conn_id=conn_id) + _mask_connection_secrets(conn) + return conn + except SecretCache.NotPresentException: + pass # continue to backends - msg = await SUPERVISOR_COMMS.asend(GetConnection(conn_id=conn_id)) + from airflow.sdk.execution_time.supervisor import ensure_secrets_backend_loaded - return _process_connection_result_conn(msg) + # Try secrets backends + backends = ensure_secrets_backend_loaded() + for secrets_backend in backends: + try: + # Use async method if available, otherwise wrap sync method + if hasattr(secrets_backend, "aget_connection"): + conn = await secrets_backend.aget_connection(conn_id) # type: ignore[assignment] + else: + conn = await sync_to_async(secrets_backend.get_connection)(conn_id) # type: ignore[assignment] + + if conn: + SecretCache.save_connection_uri(conn_id, conn.get_uri()) + _mask_connection_secrets(conn) + return conn + except Exception: + # If one backend fails, try the next one + log.debug( + "Unable to retrieve connection from secrets backend (%s). " + "Checking subsequent secrets backend.", + type(secrets_backend).__name__, + ) + + # If no backend found the connection, raise an error + from airflow.exceptions import AirflowNotFoundException + + raise AirflowNotFoundException(f"The conn_id `{conn_id}` isn't defined") def _get_variable(key: str, deserialize_json: bool) -> Any: - # TODO: check cache first - # enabled only if SecretCache.init() has been called first + from airflow.sdk.execution_time.cache import SecretCache from airflow.sdk.execution_time.supervisor import ensure_secrets_backend_loaded + # Check cache first + try: + var_val = SecretCache.get_variable(key) + if var_val is not None: + if deserialize_json: + import json + + var_val = json.loads(var_val) + if isinstance(var_val, str): + mask_secret(var_val, key) + return var_val + except SecretCache.NotPresentException: + pass # Continue to check backends + backends = ensure_secrets_backend_loaded() - # iterate over backends if not in cache (or expired) + + # Iterate over backends if not in cache (or expired) for secrets_backend in backends: try: var_val = secrets_backend.get_variable(key=key) if var_val is not None: + # Save raw value before deserialization to maintain cache consistency + SecretCache.save_variable(key, var_val) if deserialize_json: import json @@ -206,29 +258,13 @@ def _get_variable(key: str, deserialize_json: bool) -> Any: type(secrets_backend).__name__, ) - if backends: - log.debug( - "Variable not found in any of the configured Secrets Backends. Trying to retrieve from API server", - key=key, - ) - - # TODO: This should probably be moved to a separate module like `airflow.sdk.execution_time.comms` - # or `airflow.sdk.execution_time.variable` - # A reason to not move it to `airflow.sdk.execution_time.comms` is that it - # will make that module depend on Task SDK, which is not ideal because we intend to - # keep Task SDK as a separate package than execution time mods. - from airflow.sdk.execution_time.comms import ErrorResponse, GetVariable - from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS - - msg = SUPERVISOR_COMMS.send(GetVariable(key=key)) - - if isinstance(msg, ErrorResponse): - raise AirflowRuntimeError(msg) + # If no backend found the variable, raise a not found error (mirrors _get_connection) + from airflow.sdk.exceptions import AirflowRuntimeError, ErrorType + from airflow.sdk.execution_time.comms import ErrorResponse - if TYPE_CHECKING: - assert isinstance(msg, VariableResult) - variable = _convert_variable_result_to_variable(msg, deserialize_json) - return variable.value + raise AirflowRuntimeError( + ErrorResponse(error=ErrorType.VARIABLE_NOT_FOUND, detail={"message": f"Variable {key} not found"}) + ) def _set_variable(key: str, value: Any, description: str | None = None, serialize_json: bool = False) -> None: @@ -239,19 +275,23 @@ def _set_variable(key: str, value: Any, description: str | None = None, serializ # keep Task SDK as a separate package than execution time mods. import json + from airflow.sdk.execution_time.cache import SecretCache from airflow.sdk.execution_time.comms import PutVariable + from airflow.sdk.execution_time.secrets.execution_api import ExecutionAPISecretsBackend from airflow.sdk.execution_time.supervisor import ensure_secrets_backend_loaded from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS # check for write conflicts on the worker for secrets_backend in ensure_secrets_backend_loaded(): + if isinstance(secrets_backend, ExecutionAPISecretsBackend): + continue try: var_val = secrets_backend.get_variable(key=key) if var_val is not None: _backend_name = type(secrets_backend).__name__ log.warning( "The variable %s is defined in the %s secrets backend, which takes " - "precedence over reading from the database. The value in the database will be " + "precedence over reading from the API Server. The value from the API Server will be " "updated, but to read it you have to delete the conflicting variable " "from %s", key, @@ -272,6 +312,9 @@ def _set_variable(key: str, value: Any, description: str | None = None, serializ SUPERVISOR_COMMS.send(PutVariable(key=key, value=value, description=description)) + # Invalidate cache after setting the variable + SecretCache.invalidate_variable(key) + def _delete_variable(key: str) -> None: # TODO: This should probably be moved to a separate module like `airflow.sdk.execution_time.comms` @@ -279,6 +322,7 @@ def _delete_variable(key: str) -> None: # A reason to not move it to `airflow.sdk.execution_time.comms` is that it # will make that module depend on Task SDK, which is not ideal because we intend to # keep Task SDK as a separate package than execution time mods. + from airflow.sdk.execution_time.cache import SecretCache from airflow.sdk.execution_time.comms import DeleteVariable from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS @@ -286,6 +330,9 @@ def _delete_variable(key: str) -> None: if TYPE_CHECKING: assert isinstance(msg, OKResponse) + # Invalidate cache after deleting the variable + SecretCache.invalidate_variable(key) + class ConnectionAccessor: """Wrapper to access Connection entries in template.""" @@ -305,12 +352,16 @@ def __eq__(self, other): return True def get(self, conn_id: str, default_conn: Any = None) -> Any: + from airflow.exceptions import AirflowNotFoundException + try: return _get_connection(conn_id) except AirflowRuntimeError as e: if e.error.error == ErrorType.CONNECTION_NOT_FOUND: return default_conn raise + except AirflowNotFoundException: + return default_conn class VariableAccessor: diff --git a/task-sdk/src/airflow/sdk/execution_time/execute_workload.py b/task-sdk/src/airflow/sdk/execution_time/execute_workload.py index b06a0d22cb4e4..605dc806ba59f 100644 --- a/task-sdk/src/airflow/sdk/execution_time/execute_workload.py +++ b/task-sdk/src/airflow/sdk/execution_time/execute_workload.py @@ -48,7 +48,7 @@ def execute_workload(workload: ExecuteTask) -> None: dispose_orm(do_log=False) - configure_logging(output=sys.stdout.buffer, enable_pretty_log=False) + configure_logging(output=sys.stdout.buffer, json_output=True) if not isinstance(workload, workloads.ExecuteTask): raise ValueError(f"Executor does not know how to handle {type(workload)}") diff --git a/task-sdk/src/airflow/sdk/execution_time/hitl.py b/task-sdk/src/airflow/sdk/execution_time/hitl.py index 500be78ab4e22..07f94e63c0529 100644 --- a/task-sdk/src/airflow/sdk/execution_time/hitl.py +++ b/task-sdk/src/airflow/sdk/execution_time/hitl.py @@ -17,9 +17,10 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, TypedDict from uuid import UUID +from airflow.sdk.api.datamodels._generated import HITLUser as APIHITLUser from airflow.sdk.execution_time.comms import ( CreateHITLDetailPayload, GetHITLDetailResponse, @@ -30,6 +31,11 @@ from airflow.sdk.api.datamodels._generated import HITLDetailResponse +class HITLUser(TypedDict): + id: str + name: str + + def upsert_hitl_detail( ti_id: UUID, options: list[str], @@ -38,7 +44,7 @@ def upsert_hitl_detail( defaults: list[str] | None = None, multiple: bool = False, params: dict[str, Any] | None = None, - respondents: list[str] | None = None, + assigned_users: list[HITLUser] | None = None, ) -> None: from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS @@ -51,7 +57,11 @@ def upsert_hitl_detail( defaults=defaults, params=params, multiple=multiple, - respondents=respondents, + assigned_users=( + [APIHITLUser(id=user["id"], name=user["name"]) for user in assigned_users] + if assigned_users + else [] + ), ) ) diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/middleware.py b/task-sdk/src/airflow/sdk/execution_time/secrets/__init__.py similarity index 58% rename from airflow-core/src/airflow/api_fastapi/auth/managers/simple/middleware.py rename to task-sdk/src/airflow/sdk/execution_time/secrets/__init__.py index 536442cf5bf19..26c6e744de454 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/middleware.py +++ b/task-sdk/src/airflow/sdk/execution_time/secrets/__init__.py @@ -1,3 +1,4 @@ +# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -14,19 +15,15 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +"""Secrets backends for task execution contexts.""" from __future__ import annotations -from fastapi import Request -from starlette.middleware.base import BaseHTTPMiddleware - -from airflow.api_fastapi.auth.managers.simple.services.login import SimpleAuthManagerLogin - +from airflow.sdk.execution_time.secrets.execution_api import ExecutionAPISecretsBackend -class SimpleAllAdminMiddleware(BaseHTTPMiddleware): - """Middleware that automatically generates and includes auth header for simple auth manager.""" +__all__ = ["ExecutionAPISecretsBackend", "DEFAULT_SECRETS_SEARCH_PATH_WORKERS"] - async def dispatch(self, request: Request, call_next): - token = SimpleAuthManagerLogin.create_token_all_admins() - request.scope["headers"].append((b"authorization", f"Bearer {token}".encode())) - return await call_next(request) +DEFAULT_SECRETS_SEARCH_PATH_WORKERS = [ + "airflow.secrets.environment_variables.EnvironmentVariablesBackend", + "airflow.sdk.execution_time.secrets.execution_api.ExecutionAPISecretsBackend", +] diff --git a/task-sdk/src/airflow/sdk/execution_time/secrets/execution_api.py b/task-sdk/src/airflow/sdk/execution_time/secrets/execution_api.py new file mode 100644 index 0000000000000..8f32282c2bcb6 --- /dev/null +++ b/task-sdk/src/airflow/sdk/execution_time/secrets/execution_api.py @@ -0,0 +1,146 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""Secrets backend that routes requests to the Execution API.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from airflow.secrets.base_secrets import BaseSecretsBackend + +if TYPE_CHECKING: + from airflow.sdk import Connection + + +class ExecutionAPISecretsBackend(BaseSecretsBackend): + """ + Secrets backend for client contexts (workers, DAG processors, triggerers). + + Routes connection and variable requests through SUPERVISOR_COMMS to the + Execution API server. This backend should only be registered in client + processes, not in API server/scheduler processes. + """ + + def get_conn_value(self, conn_id: str) -> str | None: + """ + Get connection URI via SUPERVISOR_COMMS. + + Not used since we override get_connection directly. + """ + raise NotImplementedError("Use get_connection instead") + + def get_connection(self, conn_id: str) -> Connection | None: # type: ignore[override] + """ + Return connection object by routing through SUPERVISOR_COMMS. + + :param conn_id: connection id + :return: Connection object or None if not found + """ + from airflow.sdk.execution_time.comms import ErrorResponse, GetConnection + from airflow.sdk.execution_time.context import _process_connection_result_conn + from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS + + try: + msg = SUPERVISOR_COMMS.send(GetConnection(conn_id=conn_id)) + + if isinstance(msg, ErrorResponse): + # Connection not found or error occurred + return None + + # Convert ExecutionAPI response to SDK Connection + return _process_connection_result_conn(msg) + except Exception: + # If SUPERVISOR_COMMS fails for any reason, return None + # to allow fallback to other backends + return None + + def get_variable(self, key: str) -> str | None: + """ + Return variable value by routing through SUPERVISOR_COMMS. + + :param key: Variable key + :return: Variable value or None if not found + """ + from airflow.sdk.execution_time.comms import ErrorResponse, GetVariable, VariableResult + from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS + + try: + msg = SUPERVISOR_COMMS.send(GetVariable(key=key)) + + if isinstance(msg, ErrorResponse): + # Variable not found or error occurred + return None + + # Extract value from VariableResult + if isinstance(msg, VariableResult): + return msg.value # Already a string | None + return None + except Exception: + # If SUPERVISOR_COMMS fails for any reason, return None + # to allow fallback to other backends + return None + + async def aget_connection(self, conn_id: str) -> Connection | None: # type: ignore[override] + """ + Return connection object asynchronously via SUPERVISOR_COMMS. + + :param conn_id: connection id + :return: Connection object or None if not found + """ + from airflow.sdk.execution_time.comms import ErrorResponse, GetConnection + from airflow.sdk.execution_time.context import _process_connection_result_conn + from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS + + try: + msg = await SUPERVISOR_COMMS.asend(GetConnection(conn_id=conn_id)) + + if isinstance(msg, ErrorResponse): + # Connection not found or error occurred + return None + + # Convert ExecutionAPI response to SDK Connection + return _process_connection_result_conn(msg) + except Exception: + # If SUPERVISOR_COMMS fails for any reason, return None + # to allow fallback to other backends + return None + + async def aget_variable(self, key: str) -> str | None: + """ + Return variable value asynchronously via SUPERVISOR_COMMS. + + :param key: Variable key + :return: Variable value or None if not found + """ + from airflow.sdk.execution_time.comms import ErrorResponse, GetVariable, VariableResult + from airflow.sdk.execution_time.task_runner import SUPERVISOR_COMMS + + try: + msg = await SUPERVISOR_COMMS.asend(GetVariable(key=key)) + + if isinstance(msg, ErrorResponse): + # Variable not found or error occurred + return None + + # Extract value from VariableResult + if isinstance(msg, VariableResult): + return msg.value # Already a string | None + return None + except Exception: + # If SUPERVISOR_COMMS fails for any reason, return None + # to allow fallback to other backends + return None diff --git a/task-sdk/src/airflow/sdk/execution_time/supervisor.py b/task-sdk/src/airflow/sdk/execution_time/supervisor.py index 3d87cc6618110..c1301a94e461f 100644 --- a/task-sdk/src/airflow/sdk/execution_time/supervisor.py +++ b/task-sdk/src/airflow/sdk/execution_time/supervisor.py @@ -217,10 +217,11 @@ def _configure_logs_over_json_channel(log_fd: int): # A channel that the task can send JSON-formatted logs over. # # JSON logs sent this way will be handled nicely - from airflow.sdk.log import configure_logging + from airflow.sdk.log import configure_logging, reset_logging log_io = os.fdopen(log_fd, "wb", buffering=0) - configure_logging(enable_pretty_log=False, output=log_io, sending_to_supervisor=True) + reset_logging() + configure_logging(json_output=True, output=log_io, sending_to_supervisor=True) def _reopen_std_io_handles(child_stdin, child_stdout, child_stderr): @@ -537,16 +538,22 @@ def _register_pipe_readers(self, stdout: socket, stderr: socket, requests: socke ) ) - target_loggers: tuple[FilteringBoundLogger, ...] = (self.process_log,) + from airflow.sdk._shared.logging.structlog import logger_without_processor_of_type + + std_handle_log = logger_without_processor_of_type( + self.process_log, structlog.processors.CallsiteParameterAdder + ) + target_loggers: tuple[FilteringBoundLogger, ...] = (std_handle_log,) + if self.subprocess_logs_to_stdout: target_loggers += (log,) self.selector.register( - stdout, selectors.EVENT_READ, self._create_log_forwarder(target_loggers, channel="stdout") + stdout, selectors.EVENT_READ, self._create_log_forwarder(target_loggers, "task.stdout") ) self.selector.register( stderr, selectors.EVENT_READ, - self._create_log_forwarder(target_loggers, channel="stderr", log_level=logging.ERROR), + self._create_log_forwarder(target_loggers, "task.stderr", log_level=logging.ERROR), ) self.selector.register( logs, @@ -561,10 +568,10 @@ def _register_pipe_readers(self, stdout: socket, stderr: socket, requests: socke length_prefixed_frame_reader(self.handle_requests(log), on_close=self._on_socket_closed), ) - def _create_log_forwarder(self, loggers, channel, log_level=logging.INFO) -> Callable[[socket], bool]: + def _create_log_forwarder(self, loggers, name, log_level=logging.INFO) -> Callable[[socket], bool]: """Create a socket handler that forwards logs to a logger.""" return make_buffered_socket_reader( - forward_to_log(loggers, chan=channel, level=log_level), on_close=self._on_socket_closed + forward_to_log(loggers, logger=name, level=log_level), on_close=self._on_socket_closed ) def _on_socket_closed(self, sock: socket): @@ -802,11 +809,12 @@ def _check_subprocess_exit( self.process_log.critical(SIGSEGV_MESSAGE) # psutil turns signal exit codes into an enum for us. Handy. (Otherwise it's a plain integer) if exit_code and (name := getattr(exit_code, "name")): elif name := getattr(self._exit_code, "name", None): - message = "Process terminated by signal" + message = "Process terminated by signal." level = logging.ERROR if self._exit_code == -signal.SIGKILL: - message += ". For more information, see https://airflow.apache.org/docs/apache-airflow/stable/troubleshooting.html#TaskRunner-killed" + message += " Likely out of memory error (OOM)." level = logging.CRITICAL + message += " For more information, see https://airflow.apache.org/docs/apache-airflow/stable/troubleshooting.html#process-terminated-by-signal." self.process_log.log(level, message, signal=int(self._exit_code), signal_name=name) elif self._exit_code: # Run of the mill exit code (1, 42, etc). @@ -1342,7 +1350,7 @@ def _handle_request(self, msg: ToSupervisor, log: FilteringBoundLogger, req_id: defaults=msg.defaults, params=msg.params, multiple=msg.multiple, - respondents=msg.respondents, + assigned_users=msg.assigned_users, ) self.send_msg(resp, request_id=req_id, error=None, **dump_opts) elif isinstance(msg, MaskSecret): @@ -1366,7 +1374,12 @@ def _send_new_log_fd(self, req_id: int) -> None: raise RuntimeError("send_fds is not available on this platform") child_logs, read_logs = socketpair() - target_loggers: tuple[FilteringBoundLogger, ...] = (self.process_log,) + from airflow.sdk._shared.logging.structlog import logger_without_processor_of_type + + std_handle_log = logger_without_processor_of_type( + self.process_log, structlog.processors.CallsiteParameterAdder + ) + target_loggers: tuple[FilteringBoundLogger, ...] = (std_handle_log,) if self.subprocess_logs_to_stdout: target_loggers += (log,) @@ -1714,12 +1727,7 @@ def process_log_messages_from_subprocess( if ts := event.get("timestamp"): # We use msgspec to decode the timestamp as it does it orders of magnitude quicker than # datetime.strptime cn - # - # We remove the timezone info here, as the json encoding has `+00:00`, and since the log came - # from a subprocess we know that the timezone of the log message is the same, so having some - # messages include tz (from subprocess) but others not (ones from supervisor process) is - # confusing. - event["timestamp"] = msgspec.json.decode(f'"{ts}"', type=datetime).replace(tzinfo=None) + event["timestamp"] = msgspec.json.decode(f'"{ts}"', type=datetime) if exc := event.pop("exception", None): # TODO: convert the dict back to a pretty stack trace @@ -1732,7 +1740,7 @@ def process_log_messages_from_subprocess( def forward_to_log( - target_loggers: tuple[FilteringBoundLogger, ...], chan: str, level: int + target_loggers: tuple[FilteringBoundLogger, ...], logger: str, level: int ) -> Generator[None, bytes | bytearray, None]: while True: line = yield @@ -1743,17 +1751,52 @@ def forward_to_log( except UnicodeDecodeError: msg = line.decode("ascii", errors="replace") for log in target_loggers: - log.log(level, msg, chan=chan) + log.log(level, msg, logger=logger) def ensure_secrets_backend_loaded() -> list[BaseSecretsBackend]: - """Initialize the secrets backend on workers.""" + """ + Initialize secrets backend with auto-detected context. + + Detection strategy: + 1. SUPERVISOR_COMMS exists and is set → client chain (ExecutionAPISecretsBackend) + 2. _AIRFLOW_PROCESS_CONTEXT=server env var → server chain (MetastoreBackend) + 3. Neither → fallback chain (only env vars + external backends, no MetastoreBackend) + + Client contexts: task runner in worker (has SUPERVISOR_COMMS) + Server contexts: API server, scheduler (set _AIRFLOW_PROCESS_CONTEXT=server) + Fallback contexts: supervisor, unknown contexts (no SUPERVISOR_COMMS, no env var) + + The fallback chain ensures supervisor can use external secrets (AWS Secrets Manager, + Vault, etc.) while falling back to API client, without trying MetastoreBackend. + """ + import os + from airflow.configuration import ensure_secrets_loaded - from airflow.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS + from airflow.sdk.execution_time.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS - backends = ensure_secrets_loaded(default_backends=DEFAULT_SECRETS_SEARCH_PATH_WORKERS) + # 1. Check for client context (SUPERVISOR_COMMS) + try: + from airflow.sdk.execution_time import task_runner + + if hasattr(task_runner, "SUPERVISOR_COMMS") and task_runner.SUPERVISOR_COMMS is not None: + # Client context: task runner with SUPERVISOR_COMMS + return ensure_secrets_loaded(default_backends=DEFAULT_SECRETS_SEARCH_PATH_WORKERS) + except (ImportError, AttributeError): + pass - return backends + # 2. Check for explicit server context + if os.environ.get("_AIRFLOW_PROCESS_CONTEXT") == "server": + # Server context: API server, scheduler + # uses the default server list + return ensure_secrets_loaded() + + # 3. Fallback for unknown contexts (supervisor, etc.) + # Only env vars + external backends from config, no MetastoreBackend, no ExecutionAPISecretsBackend + fallback_backends = [ + "airflow.secrets.environment_variables.EnvironmentVariablesBackend", + ] + return ensure_secrets_loaded(default_backends=fallback_backends) def _configure_logging(log_path: str, client: Client) -> tuple[FilteringBoundLogger, BinaryIO | TextIO]: @@ -1766,16 +1809,16 @@ def _configure_logging(log_path: str, client: Client) -> tuple[FilteringBoundLog log_file = init_log_file(log_path) - pretty_logs = False - if pretty_logs: - log_file_descriptor = log_file.open("a", buffering=1) - underlying_logger: WrappedLogger = structlog.WriteLogger(cast("TextIO", log_file_descriptor)) - else: + json_logs = True + if json_logs: log_file_descriptor = log_file.open("ab") - underlying_logger = structlog.BytesLogger(cast("BinaryIO", log_file_descriptor)) + underlying_logger: WrappedLogger = structlog.BytesLogger(cast("BinaryIO", log_file_descriptor)) + else: + log_file_descriptor = log_file.open("a", buffering=1) + underlying_logger = structlog.WriteLogger(cast("TextIO", log_file_descriptor)) with _remote_logging_conn(client): - processors = logging_processors(enable_pretty_log=pretty_logs)[0] + processors = logging_processors(json_output=json_logs) logger = structlog.wrap_logger(underlying_logger, processors=processors, logger_name="task").bind() return logger, log_file_descriptor @@ -1878,7 +1921,13 @@ def supervise( exit_code = process.wait() end = time.monotonic() - log.info("Task finished", exit_code=exit_code, duration=end - start, final_state=process.final_state) + log.info( + "Task finished", + task_instance_id=str(ti.id), + exit_code=exit_code, + duration=end - start, + final_state=process.final_state, + ) if log_path and log_file_descriptor: log_file_descriptor.close() return exit_code diff --git a/task-sdk/src/airflow/sdk/execution_time/task_runner.py b/task-sdk/src/airflow/sdk/execution_time/task_runner.py index f8f1427fa5507..409982d1a6bf9 100644 --- a/task-sdk/src/airflow/sdk/execution_time/task_runner.py +++ b/task-sdk/src/airflow/sdk/execution_time/task_runner.py @@ -562,7 +562,7 @@ def log_url(self) -> str: try_number = ( f"?try_number={try_number_value}" if try_number_value is not None and try_number_value > 0 else "" ) - _log_uri = f"{base_url}dags/{self.dag_id}/runs/{run_id}/tasks/{self.task_id}{map_index}{try_number}" + _log_uri = f"{base_url.rstrip('/')}/dags/{self.dag_id}/runs/{run_id}/tasks/{self.task_id}{map_index}{try_number}" return _log_uri @property @@ -599,23 +599,6 @@ def _xcom_push_to_db(ti: RuntimeTaskInstance, key: str, value: Any) -> None: ) -def get_log_url_from_ti(ti: RuntimeTaskInstance) -> str: - from urllib.parse import quote - - from airflow.configuration import conf - - run_id = quote(ti.run_id) - base_url = conf.get("api", "base_url", fallback="http://localhost:8080/") - map_index_value = getattr(ti, "map_index", -1) - map_index = f"/mapped/{map_index_value}" if map_index_value is not None and map_index_value >= 0 else "" - try_number_value = getattr(ti, "try_number", 0) - try_number = ( - f"?try_number={try_number_value}" if try_number_value is not None and try_number_value > 0 else "" - ) - _log_uri = f"{base_url}dags/{ti.dag_id}/runs/{run_id}/tasks/{ti.task_id}{map_index}{try_number}" - return _log_uri - - def parse(what: StartupDetails, log: Logger) -> RuntimeTaskInstance: # TODO: Task-SDK: # Using DagBag here is about 98% wrong, but it'll do for now @@ -650,7 +633,7 @@ def parse(what: StartupDetails, log: Logger) -> RuntimeTaskInstance: log.error( "Dag not found during start up", dag_id=what.ti.dag_id, bundle=bundle_info, path=what.dag_rel_path ) - exit(1) + sys.exit(1) # install_loader() @@ -664,7 +647,7 @@ def parse(what: StartupDetails, log: Logger) -> RuntimeTaskInstance: bundle=bundle_info, path=what.dag_rel_path, ) - exit(1) + sys.exit(1) if not isinstance(task, (BaseOperator, MappedOperator)): raise TypeError( @@ -717,7 +700,7 @@ def startup() -> tuple[RuntimeTaskInstance, Context, Logger]: from airflow.sdk.log import configure_logging log_io = os.fdopen(logs.fds[0], "wb", buffering=0) - configure_logging(enable_pretty_log=False, output=log_io, sending_to_supervisor=True) + configure_logging(json_output=True, output=log_io, sending_to_supervisor=True) else: print("Unable to re-configure logging after sudo, we didn't get an FD", file=sys.stderr) diff --git a/task-sdk/src/airflow/sdk/log.py b/task-sdk/src/airflow/sdk/log.py index cae38961d918a..6e0d280d2d7ba 100644 --- a/task-sdk/src/airflow/sdk/log.py +++ b/task-sdk/src/airflow/sdk/log.py @@ -17,95 +17,28 @@ # under the License. from __future__ import annotations -import io -import itertools -import logging.config -import os -import re -import sys import warnings from functools import cache from pathlib import Path -from typing import TYPE_CHECKING, Any, BinaryIO, Generic, TextIO, TypeVar, cast +from typing import TYPE_CHECKING, Any, BinaryIO, TextIO -import msgspec import structlog +import structlog.processors # We have to import this here, as it is used in the type annotations at runtime even if it seems it is # not used in the code. This is because Pydantic uses type at runtime to validate the types of the fields. from pydantic import JsonValue # noqa: TC002 if TYPE_CHECKING: - from collections.abc import Callable - - from structlog.typing import EventDict, ExcInfo, FilteringBoundLogger, Processor + from structlog.typing import EventDict, FilteringBoundLogger, Processor from airflow.logging_config import RemoteLogIO - from airflow.sdk.types import RuntimeTaskInstanceProtocol as RuntimeTI + from airflow.sdk.types import Logger, RuntimeTaskInstanceProtocol as RuntimeTI __all__ = ["configure_logging", "reset_logging", "mask_secret"] -JWT_PATTERN = re.compile(r"eyJ[\.A-Za-z0-9-_]*") - - -def exception_group_tracebacks( - format_exception: Callable[[ExcInfo], list[dict[str, Any]]], -) -> Processor: - # Make mypy happy - if not hasattr(__builtins__, "BaseExceptionGroup"): - T = TypeVar("T") - - class BaseExceptionGroup(Generic[T]): - exceptions: list[T] - - def _exception_group_tracebacks(logger: Any, method_name: Any, event_dict: EventDict) -> EventDict: - if exc_info := event_dict.get("exc_info", None): - group: BaseExceptionGroup[Exception] | None = None - if exc_info is True: - # `log.exception('mesg")` case - exc_info = sys.exc_info() - if exc_info[0] is None: - exc_info = None - - if ( - isinstance(exc_info, tuple) - and len(exc_info) == 3 - and isinstance(exc_info[1], BaseExceptionGroup) - ): - group = exc_info[1] - elif isinstance(exc_info, BaseExceptionGroup): - group = exc_info - - if group: - # Only remove it from event_dict if we handle it - del event_dict["exc_info"] - event_dict["exception"] = list( - itertools.chain.from_iterable( - format_exception((type(exc), exc, exc.__traceback__)) # type: ignore[attr-defined,arg-type] - for exc in (*group.exceptions, group) - ) - ) - - return event_dict - - return _exception_group_tracebacks - - -def logger_name(logger: Any, method_name: Any, event_dict: EventDict) -> EventDict: - if logger_name := event_dict.pop("logger_name", None): - event_dict.setdefault("logger", logger_name) - return event_dict - - -def redact_jwt(logger: Any, method_name: str, event_dict: EventDict) -> EventDict: - for k, v in event_dict.items(): - if isinstance(v, str): - event_dict[k] = re.sub(JWT_PATTERN, "eyJ***", v) - return event_dict - - def mask_logs(logger: Any, method_name: str, event_dict: EventDict) -> EventDict: from airflow.sdk._shared.secrets_masker import redact @@ -113,158 +46,33 @@ def mask_logs(logger: Any, method_name: str, event_dict: EventDict) -> EventDict return event_dict -def drop_positional_args(logger: Any, method_name: Any, event_dict: EventDict) -> EventDict: - event_dict.pop("positional_args", None) - return event_dict - - -class StdBinaryStreamHandler(logging.StreamHandler): - """A logging.StreamHandler that sends logs as binary JSON over the given stream.""" - - stream: BinaryIO - - def __init__(self, stream: BinaryIO): - super().__init__(stream) - - def emit(self, record: logging.LogRecord): - try: - msg = self.format(record) - buffer = bytearray(msg, "utf-8", "backslashreplace") - - buffer += b"\n" - - stream = self.stream - stream.write(buffer) - self.flush() - except RecursionError: # See issue 36272 - raise - except Exception: - self.handleError(record) - - @cache -def logging_processors(enable_pretty_log: bool, mask_secrets: bool = True, colored_console_log: bool = True): - if enable_pretty_log: - timestamper = structlog.processors.MaybeTimeStamper(fmt="%Y-%m-%d %H:%M:%S.%f") - else: - timestamper = structlog.processors.MaybeTimeStamper(fmt="iso") - - processors: list[structlog.typing.Processor] = [ - timestamper, - structlog.contextvars.merge_contextvars, - structlog.processors.add_log_level, - structlog.stdlib.PositionalArgumentsFormatter(), - logger_name, - redact_jwt, - structlog.processors.StackInfoRenderer(), - ] - - if mask_secrets: - processors.append(mask_logs) - - # Imports to suppress showing code from these modules. We need the import to get the filepath for - # structlog to ignore. - import contextlib - - import click - import httpcore - import httpx - - suppress = ( - click, - contextlib, - httpx, - httpcore, - httpx, - ) +def logging_processors( + json_output: bool, + log_format: str = "", + colors: bool = True, + sending_to_supervisor: bool = False, +) -> tuple[Processor, ...]: + from airflow.sdk._shared.logging.structlog import structlog_processors - if enable_pretty_log: - if colored_console_log: - rich_exc_formatter = structlog.dev.RichTracebackFormatter( - # These values are picked somewhat arbitrarily to produce useful-but-compact tracebacks. If - # we ever need to change these then they should be configurable. - extra_lines=0, - max_frames=30, - indent_guides=False, - suppress=suppress, - ) - my_styles = structlog.dev.ConsoleRenderer.get_default_level_styles() - my_styles["debug"] = structlog.dev.CYAN - - console = structlog.dev.ConsoleRenderer( - exception_formatter=rich_exc_formatter, level_styles=my_styles - ) - else: - # Create a console renderer without colors - use the same RichTracebackFormatter - # but rely on ConsoleRenderer(colors=False) to disable colors - rich_exc_formatter = structlog.dev.RichTracebackFormatter( - extra_lines=0, - max_frames=30, - indent_guides=False, - suppress=suppress, - ) - console = structlog.dev.ConsoleRenderer( - colors=False, - exception_formatter=rich_exc_formatter, - ) - processors.append(console) - return processors, { - "timestamper": timestamper, - "console": console, - } - dict_exc_formatter = structlog.tracebacks.ExceptionDictTransformer( - use_rich=False, show_locals=False, suppress=suppress - ) + extra_processors: tuple[Processor, ...] = () - dict_tracebacks = structlog.processors.ExceptionRenderer(dict_exc_formatter) - if hasattr(__builtins__, "BaseExceptionGroup"): - exc_group_processor = exception_group_tracebacks(dict_exc_formatter) - processors.append(exc_group_processor) - else: - exc_group_processor = None - - def json_dumps(msg, default): - # Note: this is likely an "expensive" step, but lets massage the dict order for nice - # viewing of the raw JSON logs. - # Maybe we don't need this once the UI renders the JSON instead of displaying the raw text - msg = { - "timestamp": msg.pop("timestamp"), - "level": msg.pop("level"), - "event": msg.pop("event"), - **msg, - } - return msgspec.json.encode(msg, enc_hook=default) - - def json_processor(logger: Any, method_name: Any, event_dict: EventDict) -> str: - # Stdlib logging doesn't need the re-ordering, it's fine as it is - return msgspec.json.encode(event_dict).decode("utf-8") - - json = structlog.processors.JSONRenderer(serializer=json_dumps) - - processors.extend( - ( - dict_tracebacks, - structlog.processors.UnicodeDecoder(), - ), - ) + mask_secrets = not sending_to_supervisor + if mask_secrets: + extra_processors += (mask_logs,) - # Include the remote logging provider for tasks if there are any we need (such as upload to Cloudwatch) if (remote := load_remote_log_handler()) and (remote_processors := getattr(remote, "processors")): - processors.extend(remote_processors) + extra_processors += remote_processors - processors.append(json) - - return processors, { - "timestamper": timestamper, - "exc_group_processor": exc_group_processor, - "dict_tracebacks": dict_tracebacks, - "json": json_processor, - } + procs, _, final_writer = structlog_processors( + json_output=json_output, log_format=log_format, colors=colors + ) + return tuple(procs) + extra_processors + (final_writer,) @cache def configure_logging( - enable_pretty_log: bool = True, + json_output: bool = False, log_level: str = "DEFAULT", output: BinaryIO | TextIO | None = None, cache_logger_on_first_use: bool = True, @@ -272,217 +80,59 @@ def configure_logging( colored_console_log: bool | None = None, ): """Set up struct logging and stdlib logging config.""" + from airflow.configuration import conf + if log_level == "DEFAULT": log_level = "INFO" - from airflow.configuration import conf log_level = conf.get("logging", "logging_level", fallback="INFO") # If colored_console_log is not explicitly set, read from configuration if colored_console_log is None: - from airflow.configuration import conf - colored_console_log = conf.getboolean("logging", "colored_console_log", fallback=True) - lvl = structlog.stdlib.NAME_TO_LEVEL[log_level.lower()] + from airflow.sdk._shared.logging import configure_logging, translate_config_values - if enable_pretty_log: - formatter = "colored" - else: - formatter = "plain" - processors, named = logging_processors( - enable_pretty_log, mask_secrets=not sending_to_supervisor, colored_console_log=colored_console_log + log_fmt, callsite_params = translate_config_values( + log_format=conf.get("logging", "log_format"), + callsite_params=conf.getlist("logging", "callsite_parameters", fallback=[]), ) - timestamper = named["timestamper"] - - pre_chain: list[structlog.typing.Processor] = [ - # Add the log level and a timestamp to the event_dict if the log entry - # is not from structlog. - structlog.stdlib.add_log_level, - structlog.stdlib.add_logger_name, - timestamper, - structlog.contextvars.merge_contextvars, - redact_jwt, - ] - - # Don't cache the loggers during tests, it make it hard to capture them - if "PYTEST_CURRENT_TEST" in os.environ: - cache_logger_on_first_use = False - - color_formatter: list[structlog.typing.Processor] = [ - structlog.stdlib.ProcessorFormatter.remove_processors_meta, - drop_positional_args, - ] - std_lib_formatter: list[structlog.typing.Processor] = [ - structlog.stdlib.ProcessorFormatter.remove_processors_meta, - drop_positional_args, - ] - if (remote := load_remote_log_handler()) and (remote_processors := getattr(remote, "processors")): - # Ensure we add in any remote log processor before we add `console` or `json` formatter so these get - # called with the event_dict as a dict still - color_formatter.extend(remote_processors) - std_lib_formatter.extend(remote_processors) - - wrapper_class = structlog.make_filtering_bound_logger(lvl) - if enable_pretty_log: - if output is not None and not isinstance(output, TextIO): - wrapper = io.TextIOWrapper(output, line_buffering=True) - logger_factory = structlog.WriteLoggerFactory(wrapper) - else: - logger_factory = structlog.WriteLoggerFactory(output) - structlog.configure( - processors=processors, - cache_logger_on_first_use=cache_logger_on_first_use, - wrapper_class=wrapper_class, - logger_factory=logger_factory, - ) - color_formatter.append(named["console"]) - else: - if output is not None and "b" not in output.mode: - if not hasattr(output, "buffer"): - raise ValueError( - f"output needed to be a binary stream, but it didn't have a buffer attribute ({output=})" - ) - output = cast("TextIO", output).buffer - if TYPE_CHECKING: - # Not all binary streams are isinstance of BinaryIO, so we check via looking at `mode` at - # runtime. mypy doesn't grok that though - assert isinstance(output, BinaryIO) - structlog.configure( - processors=processors, - cache_logger_on_first_use=cache_logger_on_first_use, - wrapper_class=wrapper_class, - logger_factory=structlog.BytesLoggerFactory(output), - ) + mask_secrets = not sending_to_supervisor + extra_processors: tuple[Processor, ...] = () - if processor := named["exc_group_processor"]: - pre_chain.append(processor) - pre_chain.append(named["dict_tracebacks"]) - color_formatter.append(named["json"]) - std_lib_formatter.append(named["json"]) + if mask_secrets: + extra_processors += (mask_logs,) + + if (remote := load_remote_log_handler()) and (remote_processors := getattr(remote, "processors")): + extra_processors += remote_processors + + configure_logging( + json_output=json_output, + log_level=log_level, + log_format=log_fmt, + output=output, + cache_logger_on_first_use=cache_logger_on_first_use, + colors=colored_console_log, + extra_processors=extra_processors, + callsite_parameters=callsite_params, + ) global _warnings_showwarning if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning - - if sys.platform == "darwin": - # This warning is not "end-user actionable" so we silence it. - warnings.filterwarnings( - "ignore", r"This process \(pid=\d+\) is multi-threaded, use of fork\(\).*" - ) - # Capture warnings and show them via structlog + # Capture warnings and show them via structlog -- i.e. in task logs warnings.showwarning = _showwarning - logging.config.dictConfig( - { - "version": 1, - "disable_existing_loggers": False, - "formatters": { - "plain": { - "()": structlog.stdlib.ProcessorFormatter, - "processors": std_lib_formatter, - "foreign_pre_chain": pre_chain, - "pass_foreign_args": True, - }, - "colored": { - "()": structlog.stdlib.ProcessorFormatter, - "processors": color_formatter, - "foreign_pre_chain": pre_chain, - "pass_foreign_args": True, - }, - }, - "handlers": { - "default": { - "level": log_level.upper(), - "class": "logging.StreamHandler", - "formatter": formatter, - }, - "to_supervisor": { - "level": log_level.upper(), - "()": StdBinaryStreamHandler, - "formatter": formatter, - "stream": output, - }, - }, - "loggers": { - # Set Airflow logging to the level requested, but most everything else at "INFO" - "": { - "handlers": ["to_supervisor" if sending_to_supervisor else "default"], - "level": "INFO", - "propagate": True, - }, - "airflow": {"level": log_level.upper()}, - # These ones are too chatty even at info - "httpx": {"level": "WARN"}, - "sqlalchemy.engine": {"level": "WARN"}, - }, - } - ) - - -def reset_logging(): - global _warnings_showwarning - warnings.showwarning = _warnings_showwarning - configure_logging.cache_clear() - - -_warnings_showwarning: Any = None +def logger_at_level(name: str, level: int) -> Logger: + """Create a new logger at the given level.""" + from airflow.sdk._shared.logging.structlog import LEVEL_TO_FILTERING_LOGGER -def _showwarning( - message: Warning | str, - category: type[Warning], - filename: str, - lineno: int, - file: TextIO | None = None, - line: str | None = None, -) -> Any: - """ - Redirects warnings to structlog so they appear in task logs etc. - - Implementation of showwarnings which redirects to logging, which will first - check to see if the file parameter is None. If a file is specified, it will - delegate to the original warnings implementation of showwarning. Otherwise, - it will call warnings.formatwarning and will log the resulting string to a - warnings logger named "py.warnings" with level logging.WARNING. - """ - if file is not None: - if _warnings_showwarning is not None: - _warnings_showwarning(message, category, filename, lineno, file, line) - else: - log = structlog.get_logger(logger_name="py.warnings") - log.warning(str(message), category=category.__name__, filename=filename, lineno=lineno) - - -def _prepare_log_folder(directory: Path, mode: int): - """ - Prepare the log folder and ensure its mode is as configured. - - To handle log writing when tasks are impersonated, the log files need to - be writable by the user that runs the Airflow command and the user - that is impersonated. This is mainly to handle corner cases with the - SubDagOperator. When the SubDagOperator is run, all of the operators - run under the impersonated user and create appropriate log files - as the impersonated user. However, if the user manually runs tasks - of the SubDagOperator through the UI, then the log files are created - by the user that runs the Airflow command. For example, the Airflow - run command may be run by the `airflow_sudoable` user, but the Airflow - tasks may be run by the `airflow` user. If the log files are not - writable by both users, then it's possible that re-running a task - via the UI (or vice versa) results in a permission error as the task - tries to write to a log file created by the other user. - - We leave it up to the user to manage their permissions by exposing configuration for both - new folders and new log files. Default is to make new log folders and files group-writeable - to handle most common impersonation use cases. The requirement in this case will be to make - sure that the same group is set as default group for both - impersonated user and main airflow - user. - """ - for parent in reversed(directory.parents): - parent.mkdir(mode=mode, exist_ok=True) - directory.mkdir(mode=mode, exist_ok=True) + return structlog.wrap_logger( + None, wrapper_class=LEVEL_TO_FILTERING_LOGGER[level], logger_factory_args=(name) + ) def init_log_file(local_relative_path: str) -> Path: @@ -490,12 +140,9 @@ def init_log_file(local_relative_path: str) -> Path: Ensure log file and parent directories are created. Any directories that are missing are created with the right permission bits. - - See above ``_prepare_log_folder`` method for more detailed explanation. """ - # NOTE: This is duplicated from airflow.utils.log.file_task_handler:FileTaskHandler._init_file, but we - # want to remove that from airflow.configuration import conf + from airflow.sdk._shared.logging import init_log_file new_file_permissions = int( conf.get("logging", "file_task_handler_new_file_permissions", fallback="0o664"), @@ -507,17 +154,13 @@ def init_log_file(local_relative_path: str) -> Path: ) base_log_folder = conf.get("logging", "base_log_folder") - full_path = Path(base_log_folder, local_relative_path) - - _prepare_log_folder(full_path.parent, new_folder_permissions) - - try: - full_path.touch(new_file_permissions) - except OSError as e: - log = structlog.get_logger(__name__) - log.warning("OSError while changing ownership of the log file. %s", e) - return full_path + return init_log_file( + base_log_folder, + local_relative_path, + new_folder_permissions=new_folder_permissions, + new_file_permissions=new_file_permissions, + ) def load_remote_log_handler() -> RemoteLogIO | None: @@ -594,3 +237,51 @@ def mask_secret(secret: JsonValue, name: str | None = None) -> None: if comms := getattr(task_runner, "SUPERVISOR_COMMS", None): comms.send(MaskSecret(value=secret, name=name)) + + +def reset_logging(): + """ + Convince for testing. Not for production use. + + :meta private: + """ + from airflow.sdk._shared.logging.structlog import structlog_processors + + global _warnings_showwarning + warnings.showwarning = _warnings_showwarning + _warnings_showwarning = None + structlog_processors.cache_clear() + logging_processors.cache_clear() + + +_warnings_showwarning: Any = None + + +def _showwarning( + message: Warning | str, + category: type[Warning], + filename: str, + lineno: int, + file: TextIO | None = None, + line: str | None = None, +) -> Any: + """ + Redirects warnings to structlog so they appear in task logs etc. + + Implementation of showwarnings which redirects to logging, which will first + check to see if the file parameter is None. If a file is specified, it will + delegate to the original warnings implementation of showwarning. Otherwise, + it will call warnings.formatwarning and will log the resulting string to a + warnings logger named "py.warnings" with level logging.WARNING. + """ + if file is not None: + if _warnings_showwarning is not None: + _warnings_showwarning(message, category, filename, lineno, file, line) + else: + from airflow.sdk._shared.logging.structlog import logger_without_processor_of_type + + log = logger_without_processor_of_type( + structlog.get_logger("py.warnings").bind(), structlog.processors.CallsiteParameterAdder + ) + + log.warning(str(message), category=category.__name__, filename=filename, lineno=lineno) diff --git a/task-sdk/src/airflow/sdk/types.py b/task-sdk/src/airflow/sdk/types.py index 247e1b8f3f088..c7084629085dd 100644 --- a/task-sdk/src/airflow/sdk/types.py +++ b/task-sdk/src/airflow/sdk/types.py @@ -29,6 +29,8 @@ from pydantic import AwareDatetime + from airflow.sdk._shared.logging.types import Logger as Logger + from airflow.sdk.api.datamodels._generated import TaskInstanceState from airflow.sdk.bases.operator import BaseOperator from airflow.sdk.definitions.asset import Asset, AssetAlias, AssetAliasEvent, AssetRef, BaseAssetUniqueKey from airflow.sdk.definitions.context import Context @@ -67,6 +69,7 @@ class RuntimeTaskInstanceProtocol(Protocol): hostname: str | None = None start_date: AwareDatetime end_date: AwareDatetime | None = None + state: TaskInstanceState | None = None def xcom_pull( self, diff --git a/task-sdk/tests/conftest.py b/task-sdk/tests/conftest.py index b930bc5a9f0bc..b924bc4384c5e 100644 --- a/task-sdk/tests/conftest.py +++ b/task-sdk/tests/conftest.py @@ -54,11 +54,20 @@ def pytest_configure(config: pytest.Config) -> None: # Always skip looking for tests in these folders! config.addinivalue_line("norecursedirs", "tests/test_dags") + config.addinivalue_line("markers", "log_level: ") + import airflow.settings airflow.settings.configure_policy_plugin_manager() +@pytest.fixture(scope="session", autouse=True) +def _init_log(): + from airflow.sdk.log import configure_logging + + configure_logging() + + @pytest.hookimpl(tryfirst=True) def pytest_runtest_setup(item): if next(item.iter_markers(name="db_test"), None): @@ -90,31 +99,42 @@ def test_dags_dir(): @pytest.fixture -def captured_logs(request): +def captured_logs(request, monkeypatch): import structlog + import structlog.processors + from airflow.sdk._shared.logging.structlog import PER_LOGGER_LEVELS from airflow.sdk.log import configure_logging, reset_logging # Use our real log config reset_logging() - configure_logging(enable_pretty_log=False) + configure_logging(json_output=False, colored_console_log=False) # Get log level from test parameter, which can either be a single log level or a # tuple of log level and desired output type, defaulting to INFO if not provided log_level = logging.INFO output = "dict" - param = getattr(request, "param", logging.INFO) + + param = getattr(request, "param", None) + if not param: + mark = next(request.node.iter_markers(name="log_level"), None) + param = mark.args[0] if mark is not None else None + if isinstance(param, int): log_level = param elif isinstance(param, tuple): log_level = param[0] output = param[1] - # We want to capture all logs, but we don't want to see them in the test output - structlog.configure(wrapper_class=structlog.make_filtering_bound_logger(log_level)) + monkeypatch.setitem(PER_LOGGER_LEVELS, "", log_level) cur_processors = structlog.get_config()["processors"] processors = cur_processors.copy() + + if not any(isinstance(proc, structlog.processors.MaybeTimeStamper) for proc in processors): + timestamper = structlog.processors.MaybeTimeStamper(fmt="iso") + processors.append(timestamper) + if output == "dict": # We need to replace remove the last processor (the one that turns JSON into text, as we want the # event dict for tests) @@ -155,6 +175,48 @@ def _disable_ol_plugin(): airflow.plugins_manager.plugins = None +@pytest.fixture(autouse=True) +def _cleanup_async_resources(request): + """ + Clean up async resources that can cause Python 3.12 fork warnings. + + Problem: asgiref.sync.sync_to_async (used in _async_get_connection) creates + ThreadPoolExecutors that persist between tests. When supervisor.py calls + os.fork() in subsequent tests, Python 3.12+ warns about forking a + multi-threaded process. + + Solution: Clean up asgiref's ThreadPoolExecutors after async tests to ensure + subsequent tests start with a clean thread environment. + """ + yield + + # Only clean up after async tests to avoid unnecessary overhead + if "asyncio" in request.keywords: + # Clean up asgiref ThreadPoolExecutors that persist between tests + # These are created by sync_to_async() calls in async connection retrieval + try: + from asgiref.sync import SyncToAsync + + # SyncToAsync maintains a class-level executor for performance + # We need to shut it down to prevent multi-threading warnings on fork() + if hasattr(SyncToAsync, "single_thread_executor") and SyncToAsync.single_thread_executor: + if not SyncToAsync.single_thread_executor._shutdown: + SyncToAsync.single_thread_executor.shutdown(wait=True) + SyncToAsync.single_thread_executor = None + + # SyncToAsync also maintains a WeakKeyDictionary of context-specific executors + # Clean these up too to ensure complete thread cleanup + if hasattr(SyncToAsync, "context_to_thread_executor"): + for executor in list(SyncToAsync.context_to_thread_executor.values()): + if hasattr(executor, "shutdown") and not getattr(executor, "_shutdown", True): + executor.shutdown(wait=True) + SyncToAsync.context_to_thread_executor.clear() + + except (ImportError, AttributeError): + # If asgiref structure changes, fail gracefully + pass + + class MakeTIContextCallable(Protocol): def __call__( self, diff --git a/task-sdk/tests/task_sdk/api/test_client.py b/task-sdk/tests/task_sdk/api/test_client.py index 986ab5fe5e8bf..32a709663acb2 100644 --- a/task-sdk/tests/task_sdk/api/test_client.py +++ b/task-sdk/tests/task_sdk/api/test_client.py @@ -30,7 +30,7 @@ from uuid6 import uuid7 from airflow.sdk import timezone -from airflow.sdk.api.client import RemoteValidationError, ServerResponseError +from airflow.sdk.api.client import Client, RemoteValidationError, ServerResponseError from airflow.sdk.api.datamodels._generated import ( AssetEventsResponse, AssetResponse, @@ -38,6 +38,7 @@ DagRunState, DagRunStateResponse, HITLDetailResponse, + HITLUser, VariableResponse, XComResponse, ) @@ -98,6 +99,23 @@ def handle_request(request: httpx.Request) -> httpx.Response: assert isinstance(err.value, FileNotFoundError) + @mock.patch("airflow.sdk.api.client.API_TIMEOUT", 60.0) + def test_timeout_configuration(self): + def handle_request(request: httpx.Request) -> httpx.Response: + return httpx.Response(status_code=200) + + client = make_client(httpx.MockTransport(handle_request)) + assert client.timeout == httpx.Timeout(60.0) + + def test_timeout_can_be_overridden(self): + def handle_request(request: httpx.Request) -> httpx.Response: + return httpx.Response(status_code=200) + + client = Client( + base_url="test://server", token="", transport=httpx.MockTransport(handle_request), timeout=120.0 + ) + assert client.timeout == httpx.Timeout(120.0) + def test_error_parsing(self): responses = [ httpx.Response(422, json={"detail": [{"loc": ["#0"], "msg": "err", "type": "required"}]}) @@ -1289,7 +1307,7 @@ def handle_request(request: httpx.Request) -> httpx.Response: assert result.defaults == ["Approval"] assert result.params is None assert result.multiple is False - assert result.respondents is None + assert result.assigned_users is None def test_update_response(self, time_machine: TimeMachineFixture) -> None: time_machine.move_to(datetime(2025, 7, 3, 0, 0, 0)) @@ -1302,10 +1320,9 @@ def handle_request(request: httpx.Request) -> httpx.Response: json={ "chosen_options": ["Approval"], "params_input": {}, - "responded_user_id": "admin", - "responded_user_name": "admin", + "responded_by_user": {"id": "admin", "name": "admin"}, "response_received": True, - "response_at": "2025-07-03T00:00:00Z", + "responded_at": "2025-07-03T00:00:00Z", }, ) return httpx.Response(status_code=400, json={"detail": "Bad Request"}) @@ -1320,9 +1337,8 @@ def handle_request(request: httpx.Request) -> httpx.Response: assert result.response_received is True assert result.chosen_options == ["Approval"] assert result.params_input == {} - assert result.responded_user_id == "admin" - assert result.responded_user_name == "admin" - assert result.response_at == timezone.datetime(2025, 7, 3, 0, 0, 0) + assert result.responded_by_user == HITLUser(id="admin", name="admin") + assert result.responded_at == timezone.datetime(2025, 7, 3, 0, 0, 0) def test_get_detail_response(self, time_machine: TimeMachineFixture) -> None: time_machine.move_to(datetime(2025, 7, 3, 0, 0, 0)) @@ -1335,10 +1351,9 @@ def handle_request(request: httpx.Request) -> httpx.Response: json={ "chosen_options": ["Approval"], "params_input": {}, - "responded_user_id": "admin", - "responded_user_name": "admin", + "responded_by_user": {"id": "admin", "name": "admin"}, "response_received": True, - "response_at": "2025-07-03T00:00:00Z", + "responded_at": "2025-07-03T00:00:00Z", }, ) return httpx.Response(status_code=400, json={"detail": "Bad Request"}) @@ -1349,6 +1364,5 @@ def handle_request(request: httpx.Request) -> httpx.Response: assert result.response_received is True assert result.chosen_options == ["Approval"] assert result.params_input == {} - assert result.responded_user_id == "admin" - assert result.responded_user_name == "admin" - assert result.response_at == timezone.datetime(2025, 7, 3, 0, 0, 0) + assert result.responded_by_user == HITLUser(id="admin", name="admin") + assert result.responded_at == timezone.datetime(2025, 7, 3, 0, 0, 0) diff --git a/task-sdk/tests/task_sdk/bases/test_hook.py b/task-sdk/tests/task_sdk/bases/test_hook.py index 4c691266f8205..df1c28593e9df 100644 --- a/task-sdk/tests/task_sdk/bases/test_hook.py +++ b/task-sdk/tests/task_sdk/bases/test_hook.py @@ -55,7 +55,7 @@ def test_get_connection(self, mock_supervisor_comms): hook = BaseHook(logger_name="") hook.get_connection(conn_id="test_conn") - mock_supervisor_comms.send.assert_called_once_with( + mock_supervisor_comms.send.assert_any_call( msg=GetConnection(conn_id="test_conn"), ) diff --git a/task-sdk/tests/task_sdk/bases/test_operator.py b/task-sdk/tests/task_sdk/bases/test_operator.py index 28dd11a91abdb..62302ce488843 100644 --- a/task-sdk/tests/task_sdk/bases/test_operator.py +++ b/task-sdk/tests/task_sdk/bases/test_operator.py @@ -949,10 +949,12 @@ def test_execute_subclassed_op_warns_once(self, captured_logs): "event": "ExtendedHelloWorldOperator.execute cannot be called outside of the Task Runner!", "level": "warning", "timestamp": mock.ANY, + "logger": "tests.task_sdk.bases.test_operator", + "loc": mock.ANY, }, ] - def test_decorated_operators(self, captured_logs): + def test_decorated_operators(self, caplog): with DAG("d1") as dag: @dag.task(task_id="task_id", dag=dag) @@ -963,15 +965,13 @@ def say_hello(**context): op = say_hello() op.operator.execute(context={}) - assert captured_logs == [ - { - "event": "HelloWorldOperator.execute cannot be called outside of the Task Runner!", - "level": "warning", - "timestamp": mock.ANY, - }, - ] + assert { + "event": "HelloWorldOperator.execute cannot be called outside of the Task Runner!", + "log_level": "warning", + } in caplog - def test_python_op(self, captured_logs): + @pytest.mark.log_level(logging.WARNING) + def test_python_op(self, caplog): from airflow.providers.standard.operators.python import PythonOperator with DAG("d1"): @@ -985,13 +985,10 @@ def say_hello(**context): python_callable=say_hello, ) op.execute(context={}, PythonOperator__sentinel=ExecutorSafeguard.sentinel_value) - assert captured_logs == [ - { - "event": "HelloWorldOperator.execute cannot be called outside of the Task Runner!", - "level": "warning", - "timestamp": mock.ANY, - }, - ] + assert { + "event": "HelloWorldOperator.execute cannot be called outside of the Task Runner!", + "log_level": "warning", + } in caplog def test_partial_default_args(): diff --git a/task-sdk/tests/task_sdk/definitions/test_asset_decorators.py b/task-sdk/tests/task_sdk/definitions/test_asset_decorators.py index 3dfc0b44588a0..000e86bc90690 100644 --- a/task-sdk/tests/task_sdk/definitions/test_asset_decorators.py +++ b/task-sdk/tests/task_sdk/definitions/test_asset_decorators.py @@ -440,3 +440,26 @@ def test_determine_kwargs_defaults( assert mock_supervisor_comms.mock_calls == [ mock.call.send(GetAssetByName(name="inlet_asset_1")), ] + + def test_from_definition_custom_name(self, mock_supervisor_comms, func_fixer): + @func_fixer + def example_asset_func(self): + pass + + definition = asset(schedule=None, name="custom_name")(example_asset_func) + op = _AssetMainOperator.from_definition(definition) + assert op.task_id == "example_asset_func" + assert op.python_callable == example_asset_func + assert op._definition_name == "custom_name" + + mock_supervisor_comms.send.side_effect = [ + AssetResult(name="custom_name", uri="s3://bucket/object1", group="Asset") + ] + + assert op.determine_kwargs(context={}) == { + "self": Asset(name="custom_name", uri="s3://bucket/object1", group="Asset") + } + + assert mock_supervisor_comms.mock_calls == [ + mock.call.send(GetAssetByName(name="custom_name", uri="s3://bucket/object1", group="Asset")) + ] diff --git a/task-sdk/tests/task_sdk/definitions/test_connections.py b/task-sdk/tests/task_sdk/definitions/test_connection.py similarity index 65% rename from task-sdk/tests/task_sdk/definitions/test_connections.py rename to task-sdk/tests/task_sdk/definitions/test_connection.py index 05a80f59c7c69..73bc938abc14a 100644 --- a/task-sdk/tests/task_sdk/definitions/test_connections.py +++ b/task-sdk/tests/task_sdk/definitions/test_connection.py @@ -28,7 +28,7 @@ from airflow.sdk import Connection from airflow.sdk.exceptions import ErrorType from airflow.sdk.execution_time.comms import ConnectionResult, ErrorResponse -from airflow.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS +from airflow.sdk.execution_time.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS from tests_common.test_utils.config import conf_vars @@ -265,7 +265,7 @@ def test_backend_fallback_to_env_var(self, mock_get_connection, mock_env_get, mo mock_env_get.return_value = Connection(conn_id="something", conn_type="some-type") backends = initialize_secrets_backends(DEFAULT_SECRETS_SEARCH_PATH_WORKERS) - assert len(backends) == 2 + assert len(backends) == 3 backend_classes = [backend.__class__.__name__ for backend in backends] assert "LocalFilesystemBackend" in backend_classes @@ -273,3 +273,127 @@ def test_backend_fallback_to_env_var(self, mock_get_connection, mock_env_get, mo # mock_env is only called when LocalFilesystemBackend doesn't have it mock_env_get.assert_called() assert conn == Connection(conn_id="something", conn_type="some-type") + + +class TestConnectionFromUri: + """Test the Connection.from_uri() classmethod.""" + + def test_from_uri_basic(self): + """Test basic URI parsing.""" + uri = "postgres://user:pass@host:5432/db" + conn = Connection.from_uri(uri, conn_id="test_conn") + + assert conn.conn_id == "test_conn" + assert conn.conn_type == "postgres" + assert conn.host == "host" + assert conn.login == "user" + assert conn.password == "pass" + assert conn.port == 5432 + assert conn.schema == "db" + assert conn.extra is None + + def test_from_uri_with_query_params(self): + """Test URI parsing with query parameters.""" + uri = "mysql://user:pass@host:3306/db?charset=utf8&timeout=30" + conn = Connection.from_uri(uri, conn_id="test_conn") + + assert conn.conn_id == "test_conn" + assert conn.conn_type == "mysql" + assert conn.host == "host" + assert conn.login == "user" + assert conn.password == "pass" + assert conn.port == 3306 + assert conn.schema == "db" + # Extra should be JSON string with query params + extra_dict = json.loads(conn.extra) + assert extra_dict == {"charset": "utf8", "timeout": "30"} + + def test_from_uri_with_extra_key(self): + """Test URI parsing with __extra__ query parameter.""" + extra_value = json.dumps({"ssl_mode": "require", "connect_timeout": 10}) + uri = f"postgres://user:pass@host:5432/db?__extra__={extra_value}" + conn = Connection.from_uri(uri, conn_id="test_conn") + + assert conn.conn_id == "test_conn" + assert conn.conn_type == "postgres" + assert conn.extra == extra_value + + def test_from_uri_with_protocol_in_host(self): + """Test URI parsing with protocol in host (double ://).""" + uri = "http://https://example.com:8080/path" + conn = Connection.from_uri(uri, conn_id="test_conn") + + assert conn.conn_id == "test_conn" + assert conn.conn_type == "http" + assert conn.host == "https://example.com" + assert conn.port == 8080 + assert conn.schema == "path" + + def test_from_uri_encoded_credentials(self): + """Test URI parsing with URL-encoded credentials.""" + uri = "postgres://user%40domain:pass%21word@host:5432/db" + conn = Connection.from_uri(uri, conn_id="test_conn") + + assert conn.conn_id == "test_conn" + assert conn.conn_type == "postgres" + assert conn.login == "user@domain" + assert conn.password == "pass!word" + + def test_from_uri_minimal(self): + """Test URI parsing with minimal information.""" + uri = "redis://" + conn = Connection.from_uri(uri, conn_id="test_conn") + + assert conn.conn_id == "test_conn" + assert conn.conn_type == "redis" + assert conn.host == "" # urlsplit returns empty string, not None for minimal URI + assert conn.login is None + assert conn.password is None + assert conn.port is None + assert conn.schema == "" + + def test_from_uri_conn_type_normalization(self): + """Test that connection types are normalized.""" + # postgresql -> postgres + uri = "postgresql://user:pass@host:5432/db" + conn = Connection.from_uri(uri, conn_id="test_conn") + assert conn.conn_type == "postgres" + + # hyphen to underscore + uri = "google-cloud-platform://user:pass@host/db" + conn = Connection.from_uri(uri, conn_id="test_conn") + assert conn.conn_type == "google_cloud_platform" + + def test_from_uri_too_many_schemes_error(self): + """Test that too many schemes in URI raises an error.""" + uri = "http://https://ftp://example.com" + with pytest.raises(AirflowException, match="Invalid connection string"): + Connection.from_uri(uri, conn_id="test_conn") + + def test_from_uri_invalid_protocol_host_error(self): + """Test that invalid protocol host raises an error.""" + uri = "http://user@host://example.com" + with pytest.raises(AirflowException, match="Invalid connection string"): + Connection.from_uri(uri, conn_id="test_conn") + + def test_from_uri_roundtrip(self): + """Test that from_uri and get_uri are inverse operations.""" + original_uri = "postgres://user:pass@host:5432/db?param1=value1¶m2=value2" + conn = Connection.from_uri(original_uri, conn_id="test_conn") + roundtrip_uri = conn.get_uri() + + # Parse both URIs to compare (order of query params might differ) + conn_from_original = Connection.from_uri(original_uri, conn_id="test") + conn_from_roundtrip = Connection.from_uri(roundtrip_uri, conn_id="test") + + assert conn_from_original.conn_type == conn_from_roundtrip.conn_type + assert conn_from_original.host == conn_from_roundtrip.host + assert conn_from_original.login == conn_from_roundtrip.login + assert conn_from_original.password == conn_from_roundtrip.password + assert conn_from_original.port == conn_from_roundtrip.port + assert conn_from_original.schema == conn_from_roundtrip.schema + # Check extra content is equivalent (JSON order might differ) + if conn_from_original.extra: + original_extra = json.loads(conn_from_original.extra) + roundtrip_extra = json.loads(conn_from_roundtrip.extra) + assert original_extra == roundtrip_extra diff --git a/task-sdk/tests/task_sdk/definitions/test_dag.py b/task-sdk/tests/task_sdk/definitions/test_dag.py index ed8db6b0aac5a..10f745f9b9131 100644 --- a/task-sdk/tests/task_sdk/definitions/test_dag.py +++ b/task-sdk/tests/task_sdk/definitions/test_dag.py @@ -466,6 +466,21 @@ def test_create_dag_while_active_context(): # No asserts needed, it just needs to not fail +@pytest.mark.parametrize("max_active_runs", [0, 1]) +def test_continuous_schedule_interval_limits_max_active_runs(max_active_runs): + from airflow.timetables.simple import ContinuousTimetable + + dag = DAG(dag_id="continuous", schedule="@continuous", max_active_runs=max_active_runs) + assert isinstance(dag.timetable, ContinuousTimetable) + assert dag.max_active_runs == max_active_runs + + +def test_continuous_schedule_interval_limits_max_active_runs_error(): + with pytest.raises(ValueError) as ctx: + DAG(dag_id="continuous", schedule="@continuous", max_active_runs=2) + assert str(ctx.value) == "Invalid max_active_runs: ContinuousTimetable requires max_active_runs <= 1" + + class TestDagDecorator: DEFAULT_ARGS = { "owner": "test", diff --git a/task-sdk/tests/task_sdk/definitions/test_variables.py b/task-sdk/tests/task_sdk/definitions/test_variables.py index c85924df6a6d9..7ab388d6d504f 100644 --- a/task-sdk/tests/task_sdk/definitions/test_variables.py +++ b/task-sdk/tests/task_sdk/definitions/test_variables.py @@ -26,7 +26,7 @@ from airflow.configuration import initialize_secrets_backends from airflow.sdk import Variable from airflow.sdk.execution_time.comms import PutVariable, VariableResult -from airflow.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS +from airflow.sdk.execution_time.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS from tests_common.test_utils.config import conf_vars @@ -176,9 +176,11 @@ def test_backend_fallback_to_env_var(self, mock_get_variable, mock_env_get, mock mock_env_get.return_value = "fake_value" backends = initialize_secrets_backends(DEFAULT_SECRETS_SEARCH_PATH_WORKERS) - assert len(backends) == 2 + # LocalFilesystemBackend (custom), EnvironmentVariablesBackend, ExecutionAPISecretsBackend + assert len(backends) == 3 backend_classes = [backend.__class__.__name__ for backend in backends] assert "LocalFilesystemBackend" in backend_classes + assert "ExecutionAPISecretsBackend" in backend_classes var = Variable.get(key="fake_var_key") # mock_env is only called when LocalFilesystemBackend doesn't have it diff --git a/task-sdk/tests/task_sdk/definitions/test_xcom_arg.py b/task-sdk/tests/task_sdk/definitions/test_xcom_arg.py index 2a554669004be..0bef4c59ad43f 100644 --- a/task-sdk/tests/task_sdk/definitions/test_xcom_arg.py +++ b/task-sdk/tests/task_sdk/definitions/test_xcom_arg.py @@ -22,7 +22,6 @@ import pytest import structlog -from pytest_unordered import unordered from airflow.exceptions import AirflowSkipException from airflow.sdk import TaskInstanceState @@ -91,7 +90,7 @@ def c_to_none(v): assert results == {"a", "b", None} -def test_xcom_convert_to_kwargs_fails_task(run_ti: RunTI, mock_supervisor_comms, captured_logs): +def test_xcom_convert_to_kwargs_fails_task(run_ti: RunTI, mock_supervisor_comms, caplog): results = set() with DAG("test") as dag: @@ -119,35 +118,30 @@ def c_to_none(v): assert run_ti(dag, "pull", map_index) == TaskInstanceState.SUCCESS # Clear captured logs from the above - captured_logs[:] = [] + caplog.clear() # But the third one fails because the map() result cannot be used as kwargs. assert run_ti(dag, "pull", 2) == TaskInstanceState.FAILED - assert captured_logs == unordered( - [ + assert { + "event": "Task failed with exception", + "log_level": "error", + "exception": [ { - "event": "Task failed with exception", - "level": "error", - "timestamp": mock.ANY, - "exception": [ - { - "exc_notes": [], - "exc_type": "ValueError", - "exc_value": "expand_kwargs() expects a list[dict], not list[None]", - "frames": mock.ANY, - "is_cause": False, - "is_group": False, - "exceptions": [], - "syntax_error": None, - } - ], - }, - ] - ) - - -def test_xcom_map_error_fails_task(mock_supervisor_comms, run_ti, captured_logs): + "exc_notes": [], + "exc_type": "ValueError", + "exc_value": "expand_kwargs() expects a list[dict], not list[None]", + "frames": mock.ANY, + "is_cause": False, + "is_group": False, + "exceptions": [], + "syntax_error": None, + } + ], + } in caplog + + +def test_xcom_map_error_fails_task(mock_supervisor_comms, run_ti, caplog): with DAG("test") as dag: @dag.task() @@ -170,27 +164,23 @@ def does_not_work_with_c(v): # The third one (for "c") will fail. assert run_ti(dag, "pull", 2) == TaskInstanceState.FAILED - assert captured_logs == unordered( - [ + assert { + "event": "Task failed with exception", + "log_level": "error", + "timestamp": mock.ANY, + "exception": [ { - "event": "Task failed with exception", - "level": "error", - "timestamp": mock.ANY, - "exception": [ - { - "exc_notes": [], - "exc_type": "RuntimeError", - "exc_value": "nope", - "frames": mock.ANY, - "is_cause": False, - "is_group": False, - "exceptions": [], - "syntax_error": None, - } - ], - }, - ] - ) + "exc_notes": [], + "exc_type": "RuntimeError", + "exc_value": "nope", + "frames": mock.ANY, + "is_cause": False, + "is_group": False, + "exceptions": [], + "syntax_error": None, + } + ], + } in caplog def test_xcom_map_nest(mock_supervisor_comms, run_ti): diff --git a/task-sdk/tests/task_sdk/execution_time/test_context.py b/task-sdk/tests/task_sdk/execution_time/test_context.py index 54e2c66bee82f..df048d1bf4844 100644 --- a/task-sdk/tests/task_sdk/execution_time/test_context.py +++ b/task-sdk/tests/task_sdk/execution_time/test_context.py @@ -58,11 +58,14 @@ TriggeringAssetEventsAccessor, VariableAccessor, _AssetRefResolutionMixin, + _async_get_connection, _convert_variable_result_to_variable, + _get_connection, _process_connection_result_conn, context_to_airflow_vars, set_current_context, ) +from airflow.sdk.execution_time.secrets import ExecutionAPISecretsBackend def test_convert_connection_result_conn(): @@ -259,7 +262,7 @@ def test_getattr_connection_for_extra_dejson_decode_error(self, mock_log, mock_s # empty in case of failed deserialising assert dejson == {} - mock_log.exception.assert_called_once_with( + mock_log.exception.assert_any_call( "Failed to deserialize extra property `extra`, returning empty dictionary" ) @@ -730,3 +733,134 @@ def test_source_task_instance_xcom_pull(self, sample_inlet_evnets_accessor, mock map_index=0, ), ) + + +class TestAsyncGetConnection: + """Test async connection retrieval with secrets backends.""" + + @pytest.mark.asyncio + async def test_async_get_connection_from_secrets_backend(self, mock_supervisor_comms): + """Test that _async_get_connection successfully retrieves from secrets backend using sync_to_async.""" + sample_connection = Connection( + conn_id="test_conn", conn_type="postgres", host="localhost", port=5432, login="user" + ) + + class MockSecretsBackend: + """Simple mock secrets backend for testing.""" + + def __init__(self, connections: dict[str, Connection | None] | None = None): + self.connections = connections or {} + + def get_connection(self, conn_id: str) -> Connection | None: + return self.connections.get(conn_id) + + backend = MockSecretsBackend({"test_conn": sample_connection}) + + with patch( + "airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded", autospec=True + ) as mock_load: + mock_load.return_value = [backend] + + result = await _async_get_connection("test_conn") + + assert result == sample_connection + # Should not have tried SUPERVISOR_COMMS since secrets backend had the connection + mock_supervisor_comms.send.assert_not_called() + mock_supervisor_comms.asend.assert_not_called() + + +class TestSecretsBackend: + """Test that connection resolution uses the backend chain correctly.""" + + def test_execution_api_backend_in_worker_chain(self): + """Test that ExecutionAPISecretsBackend is in the worker search path.""" + from airflow.sdk.execution_time.secrets import DEFAULT_SECRETS_SEARCH_PATH_WORKERS + + assert ( + "airflow.sdk.execution_time.secrets.execution_api.ExecutionAPISecretsBackend" + in DEFAULT_SECRETS_SEARCH_PATH_WORKERS + ) + + def test_metastore_backend_in_server_chain(self): + """Test that MetastoreBackend is in the API server search path.""" + from airflow.secrets import DEFAULT_SECRETS_SEARCH_PATH + + assert "airflow.secrets.metastore.MetastoreBackend" in DEFAULT_SECRETS_SEARCH_PATH + assert ( + "airflow.sdk.execution_time.secrets.execution_api.ExecutionAPISecretsBackend" + not in DEFAULT_SECRETS_SEARCH_PATH + ) + + def test_get_connection_uses_backend_chain(self, mock_supervisor_comms): + """Test that _get_connection properly iterates through backends.""" + from airflow.sdk.api.datamodels._generated import ConnectionResponse + from airflow.sdk.execution_time.comms import ConnectionResult + + # Mock connection response + conn_response = ConnectionResponse( + conn_id="test_conn", + conn_type="http", + host="example.com", + port=443, + ) + conn_result = ConnectionResult.from_conn_response(conn_response) + mock_supervisor_comms.send.return_value = conn_result + + # Mock the backend loading to include our SupervisorComms backend + supervisor_backend = ExecutionAPISecretsBackend() + + with patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") as mock_load: + mock_load.return_value = [supervisor_backend] + + conn = _get_connection("test_conn") + + assert conn is not None + assert conn.conn_id == "test_conn" + assert conn.host == "example.com" + mock_supervisor_comms.send.assert_called_once() + + def test_get_connection_backend_fallback(self, mock_supervisor_comms): + """Test that _get_connection falls through backends correctly.""" + from airflow.sdk.api.datamodels._generated import ConnectionResponse + from airflow.sdk.execution_time.comms import ConnectionResult + + # First backend returns nothing (simulating env var backend with no env var) + class EmptyBackend: + def get_connection(self, conn_id): + return None + + # Second backend returns the connection + conn_response = ConnectionResponse( + conn_id="test_conn", + conn_type="postgres", + host="db.example.com", + ) + conn_result = ConnectionResult.from_conn_response(conn_response) + mock_supervisor_comms.send.return_value = conn_result + + supervisor_backend = ExecutionAPISecretsBackend() + + with patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") as mock_load: + mock_load.return_value = [EmptyBackend(), supervisor_backend] + + conn = _get_connection("test_conn") + + assert conn is not None + assert conn.conn_id == "test_conn" + # SupervisorComms backend was called (first backend returned None) + mock_supervisor_comms.send.assert_called_once() + + def test_get_connection_not_found_raises_error(self, mock_supervisor_comms): + """Test that _get_connection raises error when no backend finds connection.""" + from airflow.exceptions import AirflowNotFoundException + + # Backend returns None (not found) + class EmptyBackend: + def get_connection(self, conn_id): + return None + + with patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") as mock_load: + mock_load.return_value = [EmptyBackend()] + + with pytest.raises(AirflowNotFoundException, match="isn't defined"): + _get_connection("nonexistent_conn") diff --git a/task-sdk/tests/task_sdk/execution_time/test_context_cache.py b/task-sdk/tests/task_sdk/execution_time/test_context_cache.py new file mode 100644 index 0000000000000..d415c0334a4ed --- /dev/null +++ b/task-sdk/tests/task_sdk/execution_time/test_context_cache.py @@ -0,0 +1,333 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from unittest.mock import AsyncMock, MagicMock, call, patch + +import pytest + +from airflow.sdk.definitions.connection import Connection +from airflow.sdk.execution_time.cache import SecretCache +from airflow.sdk.execution_time.comms import ConnectionResult, VariableResult +from airflow.sdk.execution_time.context import ( + _delete_variable, + _get_connection, + _get_variable, + _set_variable, +) +from airflow.sdk.execution_time.secrets import ExecutionAPISecretsBackend + +from tests_common.test_utils.config import conf_vars + + +class TestConnectionCacheIntegration: + """Test the integration of SecretCache with connection access.""" + + @staticmethod + @conf_vars({("secrets", "use_cache"): "true"}) + def setup_method(): + SecretCache.reset() + SecretCache.init() + + @staticmethod + def teardown_method(): + SecretCache.reset() + + @patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") + def test_get_connection_uses_cache_when_available(self, mock_ensure_backends): + """Test that _get_connection uses cache when connection is cached.""" + conn_id = "test_conn" + uri = "postgres://user:pass@host:5432/db" + + SecretCache.save_connection_uri(conn_id, uri) + + result = _get_connection(conn_id) + assert result.conn_id == conn_id + assert result.conn_type == "postgres" + assert result.host == "host" + assert result.login == "user" + assert result.password == "pass" + assert result.port == 5432 + assert result.schema == "db" + + mock_ensure_backends.assert_not_called() + + @patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") + def test_get_connection_from_backend_saves_to_cache(self, mock_ensure_backends): + """Test that connection from secrets backend is retrieved correctly and cached.""" + conn_id = "test_conn" + conn = Connection(conn_id=conn_id, conn_type="mysql", host="host", port=3306) + + mock_backend = MagicMock(spec=["get_connection"]) + mock_backend.get_connection.return_value = conn + mock_ensure_backends.return_value = [mock_backend] + + result = _get_connection(conn_id) + assert result.conn_id == conn_id + assert result.conn_type == "mysql" + mock_backend.get_connection.assert_called_once_with(conn_id=conn_id) + + cached_uri = SecretCache.get_connection_uri(conn_id) + cached_conn = Connection.from_uri(cached_uri, conn_id=conn_id) + assert cached_conn.conn_type == "mysql" + assert cached_conn.host == "host" + + @patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") + def test_get_connection_from_api(self, mock_ensure_backends, mock_supervisor_comms): + """Test that connection from API server works correctly.""" + conn_id = "test_conn" + conn_result = ConnectionResult( + conn_id=conn_id, + conn_type="mysql", + host="host", + port=3306, + login="user", + password="pass", + ) + + mock_ensure_backends.return_value = [ExecutionAPISecretsBackend()] + + mock_supervisor_comms.send.return_value = conn_result + + result = _get_connection(conn_id) + + assert result.conn_id == conn_id + assert result.conn_type == "mysql" + # Called for GetConnection (and possibly MaskSecret) + assert mock_supervisor_comms.send.call_count >= 1 + + cached_uri = SecretCache.get_connection_uri(conn_id) + cached_conn = Connection.from_uri(cached_uri, conn_id=conn_id) + assert cached_conn.conn_type == "mysql" + assert cached_conn.host == "host" + + @patch("airflow.sdk.execution_time.context.mask_secret") + def test_get_connection_masks_secrets(self, mock_mask_secret): + """Test that connection secrets are masked from logs.""" + conn_id = "test_conn" + conn = Connection( + conn_id=conn_id, conn_type="mysql", login="user", password="password", extra='{"key": "value"}' + ) + + mock_backend = MagicMock(spec=["get_connection"]) + mock_backend.get_connection.return_value = conn + + with patch( + "airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded", return_value=[mock_backend] + ): + result = _get_connection(conn_id) + + assert result.conn_id == conn_id + # Check that password and extra were masked + mock_mask_secret.assert_has_calls( + [ + call("password"), + call('{"key": "value"}'), + ], + any_order=True, + ) + + +class TestVariableCacheIntegration: + """Test the integration of SecretCache with variable access.""" + + @staticmethod + @conf_vars({("secrets", "use_cache"): "true"}) + def setup_method(): + SecretCache.reset() + SecretCache.init() + + @staticmethod + def teardown_method(): + SecretCache.reset() + + @patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") + def test_get_variable_uses_cache_when_available(self, mock_ensure_backends): + """Test that _get_variable uses cache when variable is cached.""" + key = "test_key" + value = "test_value" + SecretCache.save_variable(key, value) + + result = _get_variable(key, deserialize_json=False) + assert result == value + mock_ensure_backends.assert_not_called() + + @patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") + def test_get_variable_from_backend_saves_to_cache(self, mock_ensure_backends): + """Test that variable from secrets backend is saved to cache.""" + key = "test_key" + value = "test_value" + + mock_backend = MagicMock(spec=["get_variable"]) + mock_backend.get_variable.return_value = value + mock_ensure_backends.return_value = [mock_backend] + + result = _get_variable(key, deserialize_json=False) + assert result == value + mock_backend.get_variable.assert_called_once_with(key=key) + cached_value = SecretCache.get_variable(key) + assert cached_value == value + + @patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") + def test_get_variable_from_api_saves_to_cache(self, mock_ensure_backends, mock_supervisor_comms): + """Test that variable from API server is saved to cache.""" + key = "test_key" + value = "test_value" + var_result = VariableResult(key=key, value=value) + + mock_ensure_backends.return_value = [ExecutionAPISecretsBackend()] + mock_supervisor_comms.send.return_value = var_result + + result = _get_variable(key, deserialize_json=False) + + assert result == value + cached_value = SecretCache.get_variable(key) + assert cached_value == value + + @patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") + def test_get_variable_with_json_deserialization(self, mock_ensure_backends): + """Test that _get_variable handles JSON deserialization correctly with cache.""" + key = "test_key" + json_value = '{"key": "value", "number": 42}' + SecretCache.save_variable(key, json_value) + + result = _get_variable(key, deserialize_json=True) + assert result == {"key": "value", "number": 42} + cached_value = SecretCache.get_variable(key) + assert cached_value == json_value + + def test_set_variable_invalidates_cache(self, mock_supervisor_comms): + """Test that _set_variable invalidates the cache.""" + key = "test_key" + old_value = "old_value" + new_value = "new_value" + SecretCache.save_variable(key, old_value) + + _set_variable(key, new_value) + mock_supervisor_comms.send.assert_called_once() + with pytest.raises(SecretCache.NotPresentException): + SecretCache.get_variable(key) + + def test_delete_variable_invalidates_cache(self, mock_supervisor_comms): + """Test that _delete_variable invalidates the cache.""" + key = "test_key" + value = "test_value" + SecretCache.save_variable(key, value) + + from airflow.sdk.execution_time.comms import OKResponse + + mock_supervisor_comms.send.return_value = OKResponse(ok=True) + + _delete_variable(key) + mock_supervisor_comms.send.assert_called_once() + with pytest.raises(SecretCache.NotPresentException): + SecretCache.get_variable(key) + + +class TestAsyncConnectionCache: + """Test the integration of SecretCache with async connection access.""" + + @staticmethod + @conf_vars({("secrets", "use_cache"): "true"}) + def setup_method(): + SecretCache.reset() + SecretCache.init() + + @staticmethod + def teardown_method(): + SecretCache.reset() + + @pytest.mark.asyncio + async def test_async_get_connection_uses_cache(self): + """Test that _async_get_connection uses cache when connection is cached.""" + from airflow.sdk.execution_time.context import _async_get_connection + + conn_id = "test_conn" + uri = "postgres://user:pass@host:5432/db" + + SecretCache.save_connection_uri(conn_id, uri) + + result = await _async_get_connection(conn_id) + assert result.conn_id == conn_id + assert result.conn_type == "postgres" + assert result.host == "host" + assert result.login == "user" + assert result.password == "pass" + assert result.port == 5432 + assert result.schema == "db" + + @pytest.mark.asyncio + async def test_async_get_connection_from_api(self, mock_supervisor_comms): + """Test that async connection from API server works correctly.""" + from airflow.sdk.execution_time.context import _async_get_connection + + conn_id = "test_conn" + conn_result = ConnectionResult( + conn_id=conn_id, + conn_type="mysql", + host="host", + port=3306, + ) + + # Configure asend to return the conn_result when awaited + mock_supervisor_comms.asend = AsyncMock(return_value=conn_result) + + result = await _async_get_connection(conn_id) + + assert result.conn_id == conn_id + assert result.conn_type == "mysql" + mock_supervisor_comms.asend.assert_called_once() + + cached_uri = SecretCache.get_connection_uri(conn_id) + cached_conn = Connection.from_uri(cached_uri, conn_id=conn_id) + assert cached_conn.conn_type == "mysql" + assert cached_conn.host == "host" + + +class TestCacheDisabled: + """Test behavior when cache is disabled.""" + + @staticmethod + @conf_vars({("secrets", "use_cache"): "false"}) + def setup_method(): + SecretCache.reset() + SecretCache.init() + + @staticmethod + def teardown_method(): + SecretCache.reset() + + @patch("airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded") + def test_get_connection_no_cache_when_disabled(self, mock_ensure_backends, mock_supervisor_comms): + """Test that cache is not used when disabled.""" + conn_id = "test_conn" + conn_result = ConnectionResult(conn_id=conn_id, conn_type="mysql", host="host") + + mock_ensure_backends.return_value = [ExecutionAPISecretsBackend()] + + mock_supervisor_comms.send.return_value = conn_result + + result = _get_connection(conn_id) + + assert result.conn_id == conn_id + # Called for GetConnection (and possibly MaskSecret) + assert mock_supervisor_comms.send.call_count >= 1 + + _get_connection(conn_id) + + # Called twice since cache is disabled + assert mock_supervisor_comms.send.call_count >= 2 diff --git a/task-sdk/tests/task_sdk/execution_time/test_hitl.py b/task-sdk/tests/task_sdk/execution_time/test_hitl.py index a5ed016f44de8..cd3682d922efe 100644 --- a/task-sdk/tests/task_sdk/execution_time/test_hitl.py +++ b/task-sdk/tests/task_sdk/execution_time/test_hitl.py @@ -20,9 +20,10 @@ from uuid6 import uuid7 from airflow.sdk import timezone -from airflow.sdk.api.datamodels._generated import HITLDetailResponse +from airflow.sdk.api.datamodels._generated import HITLDetailResponse, HITLUser as APIHITLUser from airflow.sdk.execution_time.comms import CreateHITLDetailPayload from airflow.sdk.execution_time.hitl import ( + HITLUser, get_hitl_detail_content_detail, update_hitl_detail_response, upsert_hitl_detail, @@ -39,7 +40,7 @@ def test_upsert_hitl_detail(mock_supervisor_comms) -> None: body="Optional body", defaults=["Approve", "Reject"], params={"input_1": 1}, - respondents=["test"], + assigned_users=[HITLUser(id="test", name="test")], multiple=False, ) mock_supervisor_comms.send.assert_called_with( @@ -50,7 +51,7 @@ def test_upsert_hitl_detail(mock_supervisor_comms) -> None: body="Optional body", defaults=["Approve", "Reject"], params={"input_1": 1}, - respondents=["test"], + assigned_users=[APIHITLUser(id="test", name="test")], multiple=False, ) ) @@ -61,9 +62,8 @@ def test_update_hitl_detail_response(mock_supervisor_comms) -> None: mock_supervisor_comms.send.return_value = HITLDetailResponse( response_received=True, chosen_options=["Approve"], - response_at=timestamp, - responded_user_id="admin", - responded_user_name="admin", + responded_at=timestamp, + responded_by_user=APIHITLUser(id="admin", name="admin"), params_input={"input_1": 1}, ) resp = update_hitl_detail_response( @@ -74,9 +74,8 @@ def test_update_hitl_detail_response(mock_supervisor_comms) -> None: assert resp == HITLDetailResponse( response_received=True, chosen_options=["Approve"], - response_at=timestamp, - responded_user_id="admin", - responded_user_name="admin", + responded_at=timestamp, + responded_by_user=APIHITLUser(id="admin", name="admin"), params_input={"input_1": 1}, ) @@ -85,17 +84,15 @@ def test_get_hitl_detail_content_detail(mock_supervisor_comms) -> None: mock_supervisor_comms.send.return_value = HITLDetailResponse( response_received=False, chosen_options=None, - response_at=None, - responded_user_id=None, - responded_user_name=None, + responded_at=None, + responded_by_user=None, params_input={}, ) resp = get_hitl_detail_content_detail(TI_ID) assert resp == HITLDetailResponse( response_received=False, chosen_options=None, - response_at=None, - responded_user_id=None, - responded_user_name=None, + responded_at=None, + responded_by_user=None, params_input={}, ) diff --git a/task-sdk/tests/task_sdk/execution_time/test_secrets.py b/task-sdk/tests/task_sdk/execution_time/test_secrets.py new file mode 100644 index 0000000000000..bda87a6a64ae0 --- /dev/null +++ b/task-sdk/tests/task_sdk/execution_time/test_secrets.py @@ -0,0 +1,169 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from __future__ import annotations + +import pytest + +from airflow.sdk.execution_time.secrets.execution_api import ExecutionAPISecretsBackend + + +class TestExecutionAPISecretsBackend: + """Test ExecutionAPISecretsBackend.""" + + def test_get_connection_via_supervisor_comms(self, mock_supervisor_comms): + """Test that connection is retrieved via SUPERVISOR_COMMS.""" + from airflow.sdk.api.datamodels._generated import ConnectionResponse + from airflow.sdk.execution_time.comms import ConnectionResult + + # Mock connection response + conn_response = ConnectionResponse( + conn_id="test_conn", + conn_type="http", + host="example.com", + port=443, + schema="https", + ) + conn_result = ConnectionResult.from_conn_response(conn_response) + mock_supervisor_comms.send.return_value = conn_result + + backend = ExecutionAPISecretsBackend() + conn = backend.get_connection("test_conn") + + assert conn is not None + assert conn.conn_id == "test_conn" + assert conn.conn_type == "http" + assert conn.host == "example.com" + mock_supervisor_comms.send.assert_called_once() + + def test_get_connection_not_found(self, mock_supervisor_comms): + """Test that None is returned when connection not found.""" + from airflow.sdk.exceptions import ErrorType + from airflow.sdk.execution_time.comms import ErrorResponse + + # Mock error response + error_response = ErrorResponse(error=ErrorType.CONNECTION_NOT_FOUND, detail={"message": "Not found"}) + mock_supervisor_comms.send.return_value = error_response + + backend = ExecutionAPISecretsBackend() + conn = backend.get_connection("nonexistent") + + assert conn is None + mock_supervisor_comms.send.assert_called_once() + + def test_get_variable_via_supervisor_comms(self, mock_supervisor_comms): + """Test that variable is retrieved via SUPERVISOR_COMMS.""" + from airflow.sdk.execution_time.comms import VariableResult + + # Mock variable response + var_result = VariableResult(key="test_var", value="test_value") + mock_supervisor_comms.send.return_value = var_result + + backend = ExecutionAPISecretsBackend() + value = backend.get_variable("test_var") + + assert value == "test_value" + mock_supervisor_comms.send.assert_called_once() + + def test_get_variable_not_found(self, mock_supervisor_comms): + """Test that None is returned when variable not found.""" + from airflow.sdk.exceptions import ErrorType + from airflow.sdk.execution_time.comms import ErrorResponse + + # Mock error response + error_response = ErrorResponse(error=ErrorType.VARIABLE_NOT_FOUND, detail={"message": "Not found"}) + mock_supervisor_comms.send.return_value = error_response + + backend = ExecutionAPISecretsBackend() + value = backend.get_variable("nonexistent") + + assert value is None + mock_supervisor_comms.send.assert_called_once() + + def test_get_connection_handles_exception(self, mock_supervisor_comms): + """Test that exceptions are handled gracefully.""" + mock_supervisor_comms.send.side_effect = RuntimeError("Connection failed") + + backend = ExecutionAPISecretsBackend() + conn = backend.get_connection("test_conn") + + # Should return None on exception to allow fallback to other backends + assert conn is None + + def test_get_variable_handles_exception(self, mock_supervisor_comms): + """Test that exceptions are handled gracefully for variables.""" + mock_supervisor_comms.send.side_effect = RuntimeError("Communication failed") + + backend = ExecutionAPISecretsBackend() + value = backend.get_variable("test_var") + + # Should return None on exception to allow fallback to other backends + assert value is None + + def test_get_conn_value_not_implemented(self): + """Test that get_conn_value raises NotImplementedError.""" + backend = ExecutionAPISecretsBackend() + with pytest.raises(NotImplementedError, match="Use get_connection instead"): + backend.get_conn_value("test_conn") + + +class TestContextDetection: + """Test context detection in ensure_secrets_backend_loaded.""" + + def test_client_context_with_supervisor_comms(self, mock_supervisor_comms): + """Client context: SUPERVISOR_COMMS set → uses worker chain.""" + from airflow.sdk.execution_time.supervisor import ensure_secrets_backend_loaded + + backends = ensure_secrets_backend_loaded() + backend_classes = [type(b).__name__ for b in backends] + assert "ExecutionAPISecretsBackend" in backend_classes + assert "MetastoreBackend" not in backend_classes + + def test_server_context_with_env_var(self, monkeypatch): + """Server context: env var set → uses server chain.""" + import sys + + from airflow.sdk.execution_time.supervisor import ensure_secrets_backend_loaded + + monkeypatch.setenv("_AIRFLOW_PROCESS_CONTEXT", "server") + # Ensure SUPERVISOR_COMMS is not available + if "airflow.sdk.execution_time.task_runner" in sys.modules: + monkeypatch.delitem(sys.modules, "airflow.sdk.execution_time.task_runner") + + backends = ensure_secrets_backend_loaded() + backend_classes = [type(b).__name__ for b in backends] + assert "MetastoreBackend" in backend_classes + assert "ExecutionAPISecretsBackend" not in backend_classes + + def test_fallback_context_no_markers(self, monkeypatch): + """Fallback context: no SUPERVISOR_COMMS, no env var → only env vars + external.""" + import sys + + from airflow.sdk.execution_time.supervisor import ensure_secrets_backend_loaded + + # Ensure no SUPERVISOR_COMMS + if "airflow.sdk.execution_time.task_runner" in sys.modules: + monkeypatch.delitem(sys.modules, "airflow.sdk.execution_time.task_runner") + + # Ensure no env var + monkeypatch.delenv("_AIRFLOW_PROCESS_CONTEXT", raising=False) + + backends = ensure_secrets_backend_loaded() + backend_classes = [type(b).__name__ for b in backends] + assert "EnvironmentVariablesBackend" in backend_classes + assert "MetastoreBackend" not in backend_classes + assert "ExecutionAPISecretsBackend" not in backend_classes diff --git a/task-sdk/tests/task_sdk/execution_time/test_supervisor.py b/task-sdk/tests/task_sdk/execution_time/test_supervisor.py index 2277e74b8d235..8ccb1bab4d559 100644 --- a/task-sdk/tests/task_sdk/execution_time/test_supervisor.py +++ b/task-sdk/tests/task_sdk/execution_time/test_supervisor.py @@ -223,6 +223,8 @@ class TestWatchedSubprocess: def disable_log_upload(self, spy_agency): spy_agency.spy_on(ActivitySubprocess._upload_logs, call_original=False) + # TODO: Investigate and fix it after 3.1.0 + @pytest.mark.xfail(reason="Fails on Py 3.12 with multi-threading error only in tests.") def test_reading_from_pipes(self, captured_logs, time_machine, client_with_ti_start): def subprocess_main(): # This is run in the subprocess! @@ -244,7 +246,7 @@ def subprocess_main(): logging.getLogger("airflow.foobar").error("An error message") - warnings.warn("Warning should be captured too", stacklevel=1) + warnings.warn("Warning should be appear from the correct callsite", stacklevel=1) line = lineno() - 2 # Line the error should be on @@ -272,40 +274,38 @@ def subprocess_main(): assert captured_logs == unordered( [ { - "chan": "stdout", + "logger": "task.stdout", "event": "I'm a short message", "level": "info", - "logger": "task", "timestamp": "2024-11-07T12:34:56.078901Z", }, { - "chan": "stderr", + "logger": "task.stderr", "event": "stderr message", "level": "error", - "logger": "task", "timestamp": "2024-11-07T12:34:56.078901Z", }, { - "chan": "stdout", + "logger": "task.stdout", "event": "Message split across two writes", "level": "info", - "logger": "task", "timestamp": "2024-11-07T12:34:56.078901Z", }, { "event": "An error message", "level": "error", "logger": "airflow.foobar", - "timestamp": instant.replace(tzinfo=None), + "timestamp": instant, + "loc": mock.ANY, }, { "category": "UserWarning", - "event": "Warning should be captured too", + "event": "Warning should be appear from the correct callsite", "filename": __file__, "level": "warning", "lineno": line, "logger": "py.warnings", - "timestamp": instant.replace(tzinfo=None), + "timestamp": instant, }, ] ) @@ -324,6 +324,8 @@ def subprocess_main(): logging.root.info("Log on old socket") json.dump({"level": "info", "event": "Log on new socket"}, fp=fd) + line = lineno() - 3 # Line the error should be on + proc = ActivitySubprocess.start( dag_rel_path=os.devnull, bundle_info=FAKE_BUNDLE, @@ -344,8 +346,20 @@ def subprocess_main(): assert rc == 0 assert captured_logs == unordered( [ - {"event": "Log on new socket", "level": "info", "logger": "task", "timestamp": mock.ANY}, - {"event": "Log on old socket", "level": "info", "logger": "root", "timestamp": mock.ANY}, + { + "event": "Log on new socket", + "level": "info", + "logger": "task", + "timestamp": mock.ANY, + # Since this is set as json, without filename or linno, we _should_ not add any. + }, + { + "event": "Log on old socket", + "level": "info", + "logger": "root", + "timestamp": mock.ANY, + "loc": f"{os.path.basename(__file__)}:{line}", + }, ] ) @@ -578,10 +592,9 @@ def test_run_simple_dag(self, test_dags_dir, captured_logs, time_machine, mocker # We should have a log from the task! assert { - "chan": "stdout", + "logger": "task.stdout", "event": "Hello World hello!", "level": "info", - "logger": "task", "timestamp": "2024-11-07T12:34:56.078901Z", } in captured_logs @@ -653,6 +666,8 @@ def test_supervise_handles_deferred_task( "timestamp": mocker.ANY, "level": "info", "logger": "supervisor", + "loc": mocker.ANY, + "task_instance_id": str(ti.id), } in captured_logs def test_supervisor_handles_already_running_task(self): @@ -766,6 +781,7 @@ def handle_request(request: httpx.Request) -> httpx.Response: "logger": "supervisor", "timestamp": mocker.ANY, "ti_id": ti_id, + "loc": mocker.ANY, }, { "detail": { @@ -777,12 +793,14 @@ def handle_request(request: httpx.Request) -> httpx.Response: "level": "error", "logger": "task", "timestamp": mocker.ANY, + "loc": mocker.ANY, }, { "event": "Task killed!", "level": "error", "logger": "task", "timestamp": mocker.ANY, + "loc": mocker.ANY, }, ] @@ -840,6 +858,7 @@ def test_heartbeat_failures_handling(self, monkeypatch, mocker, captured_logs, t "logger": "supervisor", "timestamp": mocker.ANY, "exception": mocker.ANY, + "loc": mocker.ANY, } assert expected_log in captured_logs @@ -859,6 +878,7 @@ def test_heartbeat_failures_handling(self, monkeypatch, mocker, captured_logs, t "failed_heartbeats": max_failed_heartbeats, "logger": "supervisor", "timestamp": mocker.ANY, + "loc": mocker.ANY, } in captured_logs @pytest.mark.parametrize( @@ -934,21 +954,29 @@ def test_overtime_handling( mock_logger.warning.assert_not_called() @pytest.mark.parametrize( - ["signal_to_raise", "log_pattern"], + ["signal_to_raise", "log_pattern", "level"], ( pytest.param( signal.SIGKILL, - re.compile(r"Process terminated by signal. For more information, see"), + re.compile(r"Process terminated by signal. Likely out of memory error"), + "critical", id="kill", ), + pytest.param( + signal.SIGTERM, + re.compile(r"Process terminated by signal. For more information"), + "error", + id="term", + ), pytest.param( signal.SIGSEGV, re.compile(r".*SIGSEGV \(Segmentation Violation\) signal indicates", re.DOTALL), + "critical", id="segv", ), ), ) - def test_exit_by_signal(self, signal_to_raise, log_pattern, cap_structlog, client_with_ti_start): + def test_exit_by_signal(self, signal_to_raise, log_pattern, level, cap_structlog, client_with_ti_start): def subprocess_main(): import faulthandler import os @@ -980,7 +1008,7 @@ def subprocess_main(): rc = proc.wait() assert { - "log_level": "critical", + "log_level": level, "event": log_pattern, } in cap_structlog assert rc == -signal_to_raise @@ -1144,36 +1172,34 @@ def _handler(sig, frame): assert proc.wait() == exit_after or -signal.SIGKILL exit_after = exit_after or signal.SIGKILL - logs = [{"event": m["event"], "chan": m.get("chan"), "logger": m["logger"]} for m in captured_logs] + logs = [{"event": m["event"], "logger": m["logger"]} for m in captured_logs] expected_logs = [ - {"chan": "stdout", "event": "Ready", "logger": "task"}, + {"logger": "task.stdout", "event": "Ready"}, ] # Work out what logs we expect to see if signal_to_send == signal.SIGINT: - expected_logs.append({"chan": "stderr", "event": "Signal 2 received", "logger": "task"}) + expected_logs.append({"logger": "task.stderr", "event": "Signal 2 received"}) if signal_to_send == signal.SIGTERM or ( signal_to_send == signal.SIGINT and exit_after != signal.SIGINT ): if signal_to_send == signal.SIGINT: expected_logs.append( { - "chan": None, "event": "Process did not terminate in time; escalating", "logger": "supervisor", } ) - expected_logs.append({"chan": "stderr", "event": "Signal 15 received", "logger": "task"}) + expected_logs.append({"logger": "task.stderr", "event": "Signal 15 received"}) if exit_after == signal.SIGKILL: if signal_to_send in {signal.SIGINT, signal.SIGTERM}: expected_logs.append( { - "chan": None, "event": "Process did not terminate in time; escalating", "logger": "supervisor", } ) - expected_logs.extend(({"chan": None, "event": "Process exited", "logger": "supervisor"},)) + expected_logs.extend(({"event": "Process exited", "logger": "supervisor"},)) assert logs == expected_logs def test_service_subprocess(self, watched_subprocess, mock_process, mocker): @@ -2006,7 +2032,7 @@ class RequestTestCase: "defaults": ["Approve"], "multiple": False, "params": {}, - "respondents": None, + "assigned_users": None, "type": "HITLDetailRequestResult", }, client_mock=ClientMock( @@ -2017,7 +2043,7 @@ class RequestTestCase: "multiple": False, "options": ["Approve", "Reject"], "params": {}, - "respondents": None, + "assigned_users": None, "subject": "This is subject", "ti_id": TI_ID, }, diff --git a/task-sdk/tests/task_sdk/execution_time/test_task_runner.py b/task-sdk/tests/task_sdk/execution_time/test_task_runner.py index 65c236a051a2f..930d80590ea7b 100644 --- a/task-sdk/tests/task_sdk/execution_time/test_task_runner.py +++ b/task-sdk/tests/task_sdk/execution_time/test_task_runner.py @@ -1287,7 +1287,7 @@ def test_get_connection_from_context(self, create_runtime_ti, mock_supervisor_co # Access the connection from the context conn_from_context = context["conn"].test_conn - mock_supervisor_comms.send.assert_called_once_with(GetConnection(conn_id="test_conn")) + mock_supervisor_comms.send.assert_any_call(GetConnection(conn_id="test_conn")) assert conn_from_context == Connection( conn_id="test_conn", @@ -1384,7 +1384,7 @@ def test_get_variable_from_context( # Access the variable from the context var_from_context = context["var"][accessor_type].test_key - mock_supervisor_comms.send.assert_called_once_with(GetVariable(key="test_key")) + mock_supervisor_comms.send.assert_any_call(GetVariable(key="test_key")) assert var_from_context == expected_value @@ -2691,6 +2691,31 @@ class CustomOperator(BaseOperator): assert state == expected_state assert collected_results == expected_results + @pytest.mark.parametrize( + ["base_url", "expected_url"], + [ + ("http://localhost:8080/", "http://localhost:8080/dags/test_dag/runs/test_run/tasks/test_task"), + ("http://localhost:8080", "http://localhost:8080/dags/test_dag/runs/test_run/tasks/test_task"), + ( + "https://airflow.example.com/", + "https://airflow.example.com/dags/test_dag/runs/test_run/tasks/test_task", + ), + ( + "https://airflow.example.com", + "https://airflow.example.com/dags/test_dag/runs/test_run/tasks/test_task", + ), + ], + ids=["localhost_with_slash", "localhost_no_slash", "domain_with_slash", "domain_no_slash"], + ) + def test_runtime_task_instance_log_url_property(self, create_runtime_ti, base_url, expected_url): + """Test that RuntimeTaskInstance.log_url property correctly handles various base_url formats.""" + task = BaseOperator(task_id="test_task") + runtime_ti = create_runtime_ti(task=task, dag_id="test_dag", run_id="test_run", try_number=0) + + with patch("airflow.configuration.conf.get", return_value=base_url): + log_url = runtime_ti.log_url + assert log_url == expected_url + def test_task_runner_on_failure_callback_context(self, create_runtime_ti): """Test that on_failure_callback context has end_date and duration.""" from airflow.exceptions import AirflowException diff --git a/task-sdk/tests/task_sdk/log/test_log.py b/task-sdk/tests/task_sdk/log/test_log.py deleted file mode 100644 index 6de87dcfc6f93..0000000000000 --- a/task-sdk/tests/task_sdk/log/test_log.py +++ /dev/null @@ -1,225 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -from __future__ import annotations - -import json -import logging -import unittest.mock -from unittest import mock - -import pytest -import structlog -from uuid6 import UUID - -from airflow.sdk._shared.secrets_masker import SecretsMasker -from airflow.sdk.api.datamodels._generated import TaskInstance -from airflow.sdk.log import configure_logging, reset_logging - - -@pytest.mark.parametrize( - "captured_logs", [(logging.INFO, "json")], indirect=True, ids=["log_level=info,formatter=json"] -) -def test_json_rendering(captured_logs): - """ - Test that the JSON formatter renders correctly. - """ - logger = structlog.get_logger() - - secrets_masker = SecretsMasker() - - with mock.patch("airflow.sdk._shared.secrets_masker._secrets_masker", return_value=secrets_masker): - logger.info( - "A test message with a Pydantic class", - pydantic_class=TaskInstance( - id=UUID("ffec3c8e-2898-46f8-b7d5-3cc571577368"), - dag_id="test_dag", - task_id="test_task", - run_id="test_run", - try_number=1, - dag_version_id=UUID("ffec3c8e-2898-46f8-b7d5-3cc571577368"), - ), - ) - assert captured_logs - assert isinstance(captured_logs[0], bytes) - assert json.loads(captured_logs[0]) == { - "event": "A test message with a Pydantic class", - "pydantic_class": "TaskInstance(id=UUID('ffec3c8e-2898-46f8-b7d5-3cc571577368'), task_id='test_task', dag_id='test_dag', run_id='test_run', " - "try_number=1, dag_version_id=UUID('ffec3c8e-2898-46f8-b7d5-3cc571577368'), map_index=-1, hostname=None, context_carrier=None)", - "timestamp": unittest.mock.ANY, - "level": "info", - } - - -@pytest.mark.parametrize( - "captured_logs", [(logging.INFO, "json")], indirect=True, ids=["log_level=info,formatter=json"] -) -def test_jwt_token_is_redacted(captured_logs): - """ - Tests that jwt token is redacted. - """ - logger = structlog.get_logger() - logger.info( - "Executing workload", - token="eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ1cm46YWlyZmxvdy5hcGFjaGUub3JnOnRhc2siLCJuYmYiOjE3NDM0OTQ1NjgsImV4cCI6MTc0MzQ5NTE2OCwiaWF0IjoxNzQzNDk0NTY4LCJzdWIiOiIwMTk1ZjA1Zi1kNjRhLTc2NjMtOWQ2Yy1lYzYwYTM0MmQ5NTYifQ.df0ZNUbXwnoed2O1bjXQkPV8Df1mmMUu1b_PJrQuHoft9fhPRQELVDp-s3PtL6QYSSrF_81FzsQ7YHAu7bk-1g", - pydantic_class=TaskInstance( - id=UUID("ffec3c8e-2898-46f8-b7d5-3cc571577368"), - dag_id="test_dag", - task_id="test_task", - run_id="test_run", - try_number=1, - dag_version_id=UUID("ffec3c8e-2898-46f8-b7d5-3cc571577368"), - ), - ) - assert captured_logs - assert isinstance(captured_logs[0], bytes) - assert json.loads(captured_logs[0]) == { - "event": "Executing workload", - "level": "info", - "pydantic_class": "TaskInstance(id=UUID('ffec3c8e-2898-46f8-b7d5-3cc571577368'), " - "task_id='test_task', dag_id='test_dag', run_id='test_run', " - "try_number=1, dag_version_id=UUID('ffec3c8e-2898-46f8-b7d5-3cc571577368'), map_index=-1, hostname=None, context_carrier=None)", - "timestamp": unittest.mock.ANY, - "token": "eyJ***", - } - - -@pytest.mark.parametrize( - "captured_logs", [(logging.INFO, "json")], indirect=True, ids=["log_level=info,formatter=json"] -) -def test_logs_are_masked(captured_logs): - """ - Test that JSON logs are masked. - """ - logger = structlog.get_logger() - secrets_masker = SecretsMasker() - secrets_masker.add_mask("password") - with mock.patch( - "airflow.sdk._shared.secrets_masker.redact", - side_effect=lambda event: { - "event": "Connection *** is ***", - "level": "info", - "pydantic_class": TaskInstance( - id=UUID("ffec3c8e-2898-46f8-b7d5-3cc571577368"), - task_id="test_task", - dag_id="test_dag", - run_id="test_run", - try_number=1, - map_index=-1, - hostname=None, - dag_version_id=UUID("ffec3c8e-2898-46f8-b7d5-3cc571577368"), - ), - "timestamp": "2025-03-25T05:13:27.073918Z", - }, - ): - logger.info( - "Connection password is password123", - pydantic_class=TaskInstance( - id=UUID("ffec3c8e-2898-46f8-b7d5-3cc571577368"), - dag_id="test_dag", - task_id="test_task", - run_id="test_run", - try_number=1, - dag_version_id=UUID("ffec3c8e-2898-46f8-b7d5-3cc571577368"), - ), - ) - assert captured_logs - assert isinstance(captured_logs[0], bytes) - - log_entry = json.loads(captured_logs[0]) - assert log_entry == { - "event": "Connection *** is ***", - "level": "info", - "pydantic_class": "TaskInstance(id=UUID('ffec3c8e-2898-46f8-b7d5-3cc571577368'), " - "task_id='test_task', dag_id='test_dag', run_id='test_run', " - "try_number=1, dag_version_id=UUID('ffec3c8e-2898-46f8-b7d5-3cc571577368'), map_index=-1, hostname=None, context_carrier=None)", - "timestamp": "2025-03-25T05:13:27.073918Z", - } - - -def test_logging_processors_with_colors(): - """Test that logging_processors creates colored console renderer when colored_console_log=True.""" - from airflow.sdk.log import logging_processors - - _, named = logging_processors(enable_pretty_log=True, colored_console_log=True) - assert "console" in named - console_renderer = named["console"] - assert hasattr(console_renderer, "_styles") - - -def test_logging_processors_without_colors(): - """Test that logging_processors creates non-colored console renderer when colored_console_log=False.""" - from airflow.sdk.log import logging_processors - - _, named = logging_processors(enable_pretty_log=True, colored_console_log=False) - assert "console" in named - console_renderer = named["console"] - assert hasattr(console_renderer, "_styles") - assert console_renderer._styles.__name__ == "_PlainStyles" - - -def test_logging_processors_json_format(): - """Test that logging_processors creates JSON renderer when enable_pretty_log=False.""" - from airflow.sdk.log import logging_processors - - _, named = logging_processors(enable_pretty_log=False, colored_console_log=True) - assert "console" not in named - assert "json" in named - - -def test_configure_logging_respects_colored_console_log_config(): - """Test that configure_logging respects the colored_console_log configuration.""" - - mock_conf = mock.MagicMock() - mock_conf.get.return_value = "INFO" - mock_conf.getboolean.return_value = False # colored_console_log = False - - with mock.patch("airflow.configuration.conf", mock_conf): - reset_logging() - configure_logging(enable_pretty_log=True) - # Check that getboolean was called with colored_console_log - calls = [call for call in mock_conf.getboolean.call_args_list if call[0][1] == "colored_console_log"] - assert len(calls) == 1 - assert calls[0] == mock.call("logging", "colored_console_log", fallback=True) - - -def test_configure_logging_explicit_colored_console_log(): - """Test that configure_logging respects explicit colored_console_log parameter.""" - - mock_conf = mock.MagicMock() - mock_conf.get.return_value = "INFO" - mock_conf.getboolean.return_value = True # colored_console_log = True - - with mock.patch("airflow.configuration.conf", mock_conf): - reset_logging() - # Explicitly disable colors despite config saying True - configure_logging(enable_pretty_log=True, colored_console_log=False) - mock_conf.getboolean.assert_not_called() - - -def test_configure_logging_no_airflow_config(): - """Test that configure_logging defaults work correctly.""" - - # This test can be removed or repurposed since we now always import airflow.configuration - mock_conf = mock.MagicMock() - mock_conf.get.return_value = "INFO" - mock_conf.getboolean.return_value = True # colored_console_log = True by default - - with mock.patch("airflow.configuration.conf", mock_conf): - reset_logging() - configure_logging(enable_pretty_log=True) - mock_conf.getboolean.assert_called_with("logging", "colored_console_log", fallback=True)