commit 559e74f3e54b9f674d3e2fe564e6469177b46cbb Author: Hosanna Amane Date: Fri Jan 7 11:48:48 2022 +0000 *white-labeling:logo: added jool logo to devenv/docker/blocks/grafana/.env diff --git a/.bingo/.gitignore b/.bingo/.gitignore new file mode 100644 index 00000000..4f2055b6 --- /dev/null +++ b/.bingo/.gitignore @@ -0,0 +1,12 @@ + +# Ignore everything +* + +# But not these files: +!.gitignore +!*.mod +!README.md +!Variables.mk +!variables.env + +*tmp.mod diff --git a/.bingo/README.md b/.bingo/README.md new file mode 100644 index 00000000..1d8a1360 --- /dev/null +++ b/.bingo/README.md @@ -0,0 +1,14 @@ +# Project Development Dependencies. + +This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo. + +- Run `bingo get` to install all tools having each own module file in this directory. +- Run `bingo get ` to install that have own module file in this directory. +- For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $() variable where is the .bingo/.mod. +- For shell: Run `source .bingo/variables.env` to source all environment variable for each tool. +- For go: Import `.bingo/variables.go` to for variable names. +- See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies. + +## Requirements + +- Go 1.14+ diff --git a/.bingo/Variables.mk b/.bingo/Variables.mk new file mode 100644 index 00000000..33598267 --- /dev/null +++ b/.bingo/Variables.mk @@ -0,0 +1,31 @@ +# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.5.1. DO NOT EDIT. +# All tools are designed to be build inside $GOBIN. +BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +GOPATH ?= $(shell go env GOPATH) +GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin +GO ?= $(shell which go) + +# Below generated variables ensure that every time a tool under each variable is invoked, the correct version +# will be used; reinstalling only if needed. +# For example for drone variable: +# +# In your main Makefile (for non array binaries): +# +#include .bingo/Variables.mk # Assuming -dir was set to .bingo . +# +#command: $(DRONE) +# @echo "Running drone" +# @$(DRONE) +# +DRONE := $(GOBIN)/drone-v1.4.0 +$(DRONE): $(BINGO_DIR)/drone.mod + @# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies. + @echo "(re)installing $(GOBIN)/drone-v1.4.0" + @cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=drone.mod -o=$(GOBIN)/drone-v1.4.0 "github.com/drone/drone-cli/drone" + +WIRE := $(GOBIN)/wire-v0.5.0 +$(WIRE): $(BINGO_DIR)/wire.mod + @# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies. + @echo "(re)installing $(GOBIN)/wire-v0.5.0" + @cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=wire.mod -o=$(GOBIN)/wire-v0.5.0 "github.com/google/wire/cmd/wire" + diff --git a/.bingo/drone.mod b/.bingo/drone.mod new file mode 100644 index 00000000..1c1ff39e --- /dev/null +++ b/.bingo/drone.mod @@ -0,0 +1,7 @@ +module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT + +go 1.17 + +replace github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible + +require github.com/drone/drone-cli v1.4.0 // drone diff --git a/.bingo/go.mod b/.bingo/go.mod new file mode 100644 index 00000000..610249af --- /dev/null +++ b/.bingo/go.mod @@ -0,0 +1 @@ +module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files. \ No newline at end of file diff --git a/.bingo/variables.env b/.bingo/variables.env new file mode 100644 index 00000000..3ef96581 --- /dev/null +++ b/.bingo/variables.env @@ -0,0 +1,14 @@ +# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.5.1. DO NOT EDIT. +# All tools are designed to be build inside $GOBIN. +# Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk. +GOBIN=${GOBIN:=$(go env GOBIN)} + +if [ -z "$GOBIN" ]; then + GOBIN="$(go env GOPATH)/bin" +fi + + +DRONE="${GOBIN}/drone-v1.4.0" + +WIRE="${GOBIN}/wire-v0.5.0" + diff --git a/.bingo/wire.mod b/.bingo/wire.mod new file mode 100644 index 00000000..fc39b30d --- /dev/null +++ b/.bingo/wire.mod @@ -0,0 +1,5 @@ +module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT + +go 1.16 + +require github.com/google/wire v0.5.0 // cmd/wire diff --git a/.bra.toml b/.bra.toml new file mode 100644 index 00000000..e9be6c13 --- /dev/null +++ b/.bra.toml @@ -0,0 +1,22 @@ +[run] +init_cmds = [ + ["make", "gen-go"], + ["go", "run", "build.go", "-dev", "build-cli"], + ["go", "run", "build.go", "-dev", "build-server"], + ["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"] +] +watch_all = true +follow_symlinks = true +watch_dirs = [ + "$WORKDIR/pkg", + "$WORKDIR/public/views", + "$WORKDIR/conf", +] +watch_exts = [".go", ".ini", ".toml", ".template.html"] +ignore_files = ["wire_gen.go"] +build_delay = 1500 +cmds = [ + ["make", "gen-go"], + ["go", "run", "build.go", "-dev", "build-server"], + ["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"] +] diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 00000000..f7b0acde --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,15 @@ +[dev] +last 1 chrome versions +last 1 firefox versions +last 1 safari versions + +[production] +last 2 Firefox versions +last 2 Chrome versions +last 2 Safari versions +last 2 Edge versions +last 1 ios_saf versions +last 1 and_chr versions +last 1 samsung versions + + diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..0afd96e1 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,11 @@ +version: 2.1 +jobs: + build: + docker: + - image: alpine:3.7 + steps: + - run: + name: The First Step + command: | + echo 'Fake step!' + diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..7ed8d016 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +.awcache +.dockerignore +.git +.gitignore +.github +.vscode +bin +data* +dist +docker +Dockerfile +docs +dump.rdb +node_modules +**/node_modules +/tmp +*.yml +!.yarnrc.yml +*.md +.yarn/* +!.yarn/patches +!.yarn/releases +!.yarn/plugins +!.yarn/versions +!.yarn/cache diff --git a/.drone.star b/.drone.star new file mode 100644 index 00000000..171a65a1 --- /dev/null +++ b/.drone.star @@ -0,0 +1,17 @@ +# To generate the .drone.yml file: +# 1. Modify the *.star definitions +# 2. Login to drone and export the env variables (token and server) shown here: https://drone.grafana.net/account +# 3. Run `make drone` +# More information about this process here: https://github.com/grafana/deployment_tools/blob/master/docs/infrastructure/drone/signing.md + +load('scripts/drone/pipelines/pr.star', 'pr_pipelines') +load('scripts/drone/pipelines/main.star', 'main_pipelines') +load('scripts/drone/pipelines/release.star', 'release_pipelines', 'test_release_pipelines') +load('scripts/drone/version.star', 'version_branch_pipelines') +load('scripts/drone/pipelines/cron.star', 'cronjobs') +load('scripts/drone/vault.star', 'secrets') + +def main(ctx): + edition = 'oss' + return pr_pipelines(edition=edition) + main_pipelines(edition=edition) + release_pipelines() + \ + test_release_pipelines() + version_branch_pipelines() + cronjobs(edition=edition) + secrets() diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 00000000..5ce8311f --- /dev/null +++ b/.drone.yml @@ -0,0 +1,4346 @@ +--- +depends_on: [] +kind: pipeline +name: pr-test +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: [] +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} + - yarn install --immutable + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - ./bin/grabpl verify-drone + depends_on: + - grabpl + image: byrnedo/alpine-curl:0.1.8 + name: lint-drone +- commands: + - |- + echo -e "unknwon + referer + errorstring + eror + iam + wan" > words_to_ignore.txt + - codespell -I words_to_ignore.txt docs/ + - rm words_to_ignore.txt + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: codespell +- commands: + - ./bin/grabpl shellcheck + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: shellcheck +- commands: + - ./bin/grabpl lint-backend --edition oss + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend +- commands: + - yarn run prettier:check + - yarn run lint + - yarn run i18n:compile + - yarn run typecheck + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: lint-frontend +- commands: + - ./bin/grabpl test-backend --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend +- commands: + - ./bin/grabpl integration-tests --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration +- commands: + - yarn run ci:test-frontend + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: test-frontend +trigger: + event: + - pull_request +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +depends_on: [] +kind: pipeline +name: pr-build-e2e +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: [] +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} + - yarn install --immutable + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} + --variants linux-x64,linux-x64-musl,osx64,win64,armv6 --no-pull-enterprise + depends_on: + - initialize + environment: {} + image: grafana/build-container:1.4.8 + name: build-backend +- commands: + - ./bin/grabpl build-frontend --jobs 8 --no-install-deps --edition oss --build-id + ${DRONE_BUILD_NUMBER} --no-pull-enterprise + depends_on: + - initialize + environment: + NODE_OPTIONS: --max_old_space_size=8192 + image: grafana/build-container:1.4.8 + name: build-frontend +- commands: + - ./bin/grabpl build-plugins --jobs 8 --edition oss --no-install-deps + depends_on: + - initialize + environment: null + image: grafana/build-container:1.4.8 + name: build-plugins +- commands: + - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . + depends_on: + - build-backend + image: grafana/build-container:1.4.8 + name: validate-scuemata +- commands: + - '# Make sure the git tree is clean.' + - '# Stashing changes, since packages that were produced in build-backend step are + needed.' + - git stash + - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . + - '# The above command generates Typescript files (*.gen.ts) from all appropriate + .cue files.' + - '# It is required that the generated Typescript be in sync with the input CUE + files.' + - '# ...Modulo eslint auto-fixes...:' + - yarn run eslint . --ext .gen.ts --fix + - '# If any filenames are emitted by the below script, run the generator command + `grafana-cli cue gen-ts` locally and commit the result.' + - ./scripts/clean-git-or-error.sh + - '# Un-stash changes.' + - git stash pop + depends_on: + - validate-scuemata + image: grafana/build-container:1.4.8 + name: ensure-cuetsified +- commands: + - . scripts/build/gpg-test-vars.sh && ./bin/grabpl package --jobs 8 --edition oss + --build-id ${DRONE_BUILD_NUMBER} --no-pull-enterprise --variants linux-x64,linux-x64-musl,osx64,win64,armv6 + depends_on: + - build-plugins + - build-backend + - build-frontend + environment: null + image: grafana/build-container:1.4.8 + name: package +- commands: + - ./e2e/start-server + depends_on: + - package + detach: true + environment: + PORT: 3001 + image: grafana/build-container:1.4.8 + name: end-to-end-tests-server +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite dashboards-suite + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-dashboards-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite smoke-tests-suite + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-smoke-tests-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite panels-suite + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-panels-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite various-suite + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-various-suite +- commands: + - apt-get update + - apt-get install -yq zip + - ls -lah ./e2e + - find ./e2e -type f -name "*.mp4" + - printenv GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY > /tmp/gcpkey_upload_artifacts.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey_upload_artifacts.json + - find ./e2e -type f -name "*spec.ts.mp4" | zip e2e/videos.zip -@ + - gsutil cp e2e/videos.zip gs://$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - export E2E_ARTIFACTS_VIDEO_ZIP=https://storage.googleapis.com/$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - 'echo "E2E Test artifacts uploaded to: $${E2E_ARTIFACTS_VIDEO_ZIP}"' + - 'curl -X POST https://api.github.com/repos/${DRONE_REPO}/statuses/${DRONE_COMMIT_SHA} + -H "Authorization: token $${GITHUB_TOKEN}" -d "{\"state\":\"success\",\"target_url\":\"$${E2E_ARTIFACTS_VIDEO_ZIP}\", + \"description\": \"Click on the details to download e2e recording videos\", \"context\": + \"e2e_artifacts\"}"' + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + E2E_TEST_ARTIFACTS_BUCKET: releng-pipeline-artifacts-dev + GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY: + from_secret: gcp_upload_artifacts_key + GITHUB_TOKEN: + from_secret: github_token + image: google/cloud-sdk:367.0.0 + name: e2e_tests_artifacts_upload +- commands: + - yarn storybook:build + - ./bin/grabpl verify-storybook + depends_on: + - build-frontend + environment: + NODE_OPTIONS: --max_old_space_size=4096 + image: grafana/build-container:1.4.8 + name: build-storybook +- commands: + - yarn wait-on http://$HOST:$PORT + - pa11y-ci --config .pa11yci-pr.conf.js + depends_on: + - end-to-end-tests-server + environment: + GRAFANA_MISC_STATS_API_KEY: + from_secret: grafana_misc_stats_api_key + HOST: end-to-end-tests-server + PORT: 3001 + failure: always + image: hugohaggmark/docker-puppeteer + name: test-a11y-frontend +- commands: + - ./scripts/ci-reference-docs-lint.sh ci + depends_on: + - build-frontend + image: grafana/build-container:1.4.8 + name: build-frontend-docs +- commands: + - mkdir -p /hugo/content/docs/grafana + - cp -r docs/sources/* /hugo/content/docs/grafana/latest/ + - cd /hugo && make prod + depends_on: + - build-frontend-docs + image: grafana/docs-base:latest + name: build-docs-website +- commands: + - ls dist/*.tar.gz* + - cp dist/*.tar.gz* packaging/docker/ + depends_on: + - package + image: grafana/build-container:1.4.8 + name: copy-packages-for-docker +- depends_on: + - copy-packages-for-docker + image: grafana/drone-grafana-docker:0.3.2 + name: build-docker-images + settings: + archs: amd64 + dry_run: true + edition: oss + ubuntu: false +trigger: + event: + - pull_request +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +depends_on: [] +kind: pipeline +name: pr-integration-tests +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: +- environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: grafanatest + POSTGRES_PASSWORD: grafanatest + POSTGRES_USER: grafanatest + image: postgres:12.3-alpine + name: postgres + volumes: + - name: postgres + path: /var/lib/postgresql/data/pgdata +- environment: + MYSQL_DATABASE: grafana_tests + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_USER: grafana + image: mysql:5.6.48 + name: mysql + volumes: + - name: mysql + path: /var/lib/mysql +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - apt-get update + - apt-get install -yq postgresql-client + - dockerize -wait tcp://postgres:5432 -timeout 120s + - psql -p 5432 -h postgres -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql + - go clean -testcache + - ./bin/grabpl integration-tests --database postgres + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: postgres + PGPASSWORD: grafanatest + POSTGRES_HOST: postgres + image: grafana/build-container:1.4.8 + name: postgres-integration-tests +- commands: + - apt-get update + - apt-get install -yq default-mysql-client + - dockerize -wait tcp://mysql:3306 -timeout 120s + - cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h mysql -P 3306 -u root + -prootpass + - go clean -testcache + - ./bin/grabpl integration-tests --database mysql + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: mysql + MYSQL_HOST: mysql + image: grafana/build-container:1.4.8 + name: mysql-integration-tests +trigger: + event: + - pull_request +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +depends_on: [] +kind: pipeline +name: main-test +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: [] +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} + - yarn install --immutable + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - ./bin/grabpl verify-drone + depends_on: + - grabpl + image: byrnedo/alpine-curl:0.1.8 + name: lint-drone +- commands: + - |- + echo -e "unknwon + referer + errorstring + eror + iam + wan" > words_to_ignore.txt + - codespell -I words_to_ignore.txt docs/ + - rm words_to_ignore.txt + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: codespell +- commands: + - ./bin/grabpl shellcheck + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: shellcheck +- commands: + - ./bin/grabpl lint-backend --edition oss + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend +- commands: + - yarn run prettier:check + - yarn run lint + - yarn run i18n:compile + - yarn run typecheck + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: lint-frontend +- commands: + - ./bin/grabpl test-backend --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend +- commands: + - ./bin/grabpl integration-tests --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration +- commands: + - yarn run ci:test-frontend + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: test-frontend +trigger: + branch: main + event: + - push +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +depends_on: [] +kind: pipeline +name: main-build-e2e-publish +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: [] +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} + - yarn install --immutable + image: grafana/build-container:1.4.8 + name: initialize +- image: grafana/drone-downstream + name: trigger-enterprise-downstream + settings: + params: + - SOURCE_BUILD_NUMBER=${DRONE_BUILD_NUMBER} + - SOURCE_COMMIT=${DRONE_COMMIT} + repositories: + - grafana/grafana-enterprise@main + server: https://drone.grafana.net + token: + from_secret: drone_token +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} + --no-pull-enterprise + depends_on: + - initialize + environment: {} + image: grafana/build-container:1.4.8 + name: build-backend +- commands: + - ./bin/grabpl build-frontend --jobs 8 --no-install-deps --edition oss --build-id + ${DRONE_BUILD_NUMBER} --no-pull-enterprise + depends_on: + - initialize + environment: + NODE_OPTIONS: --max_old_space_size=8192 + image: grafana/build-container:1.4.8 + name: build-frontend +- commands: + - ./bin/grabpl build-plugins --jobs 8 --edition oss --no-install-deps --sign --signing-admin + depends_on: + - initialize + environment: + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: build-plugins +- commands: + - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . + depends_on: + - build-backend + image: grafana/build-container:1.4.8 + name: validate-scuemata +- commands: + - '# Make sure the git tree is clean.' + - '# Stashing changes, since packages that were produced in build-backend step are + needed.' + - git stash + - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . + - '# The above command generates Typescript files (*.gen.ts) from all appropriate + .cue files.' + - '# It is required that the generated Typescript be in sync with the input CUE + files.' + - '# ...Modulo eslint auto-fixes...:' + - yarn run eslint . --ext .gen.ts --fix + - '# If any filenames are emitted by the below script, run the generator command + `grafana-cli cue gen-ts` locally and commit the result.' + - ./scripts/clean-git-or-error.sh + - '# Un-stash changes.' + - git stash pop + depends_on: + - validate-scuemata + image: grafana/build-container:1.4.8 + name: ensure-cuetsified +- commands: + - ./bin/grabpl package --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} --no-pull-enterprise + --sign + depends_on: + - build-plugins + - build-backend + - build-frontend + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package +- commands: + - ./e2e/start-server + depends_on: + - package + detach: true + environment: + PORT: 3001 + image: grafana/build-container:1.4.8 + name: end-to-end-tests-server +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite dashboards-suite + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-dashboards-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite smoke-tests-suite + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-smoke-tests-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite panels-suite + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-panels-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite various-suite + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-various-suite +- commands: + - apt-get update + - apt-get install -yq zip + - ls -lah ./e2e + - find ./e2e -type f -name "*.mp4" + - printenv GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY > /tmp/gcpkey_upload_artifacts.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey_upload_artifacts.json + - find ./e2e -type f -name "*spec.ts.mp4" | zip e2e/videos.zip -@ + - gsutil cp e2e/videos.zip gs://$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - export E2E_ARTIFACTS_VIDEO_ZIP=https://storage.googleapis.com/$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - 'echo "E2E Test artifacts uploaded to: $${E2E_ARTIFACTS_VIDEO_ZIP}"' + - 'curl -X POST https://api.github.com/repos/${DRONE_REPO}/statuses/${DRONE_COMMIT_SHA} + -H "Authorization: token $${GITHUB_TOKEN}" -d "{\"state\":\"success\",\"target_url\":\"$${E2E_ARTIFACTS_VIDEO_ZIP}\", + \"description\": \"Click on the details to download e2e recording videos\", \"context\": + \"e2e_artifacts\"}"' + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + E2E_TEST_ARTIFACTS_BUCKET: releng-pipeline-artifacts-dev + GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY: + from_secret: gcp_upload_artifacts_key + GITHUB_TOKEN: + from_secret: github_token + image: google/cloud-sdk:367.0.0 + name: e2e_tests_artifacts_upload +- commands: + - yarn storybook:build + - ./bin/grabpl verify-storybook + depends_on: + - build-frontend + environment: + NODE_OPTIONS: --max_old_space_size=4096 + image: grafana/build-container:1.4.8 + name: build-storybook +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - gsutil -m rsync -d -r ./packages/grafana-ui/dist/storybook gs://$${PRERELEASE_BUCKET}/artifacts/storybook/canary + depends_on: + - build-storybook + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + GCP_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: store-storybook +- commands: + - yarn wait-on http://$HOST:$PORT + - pa11y-ci --config .pa11yci.conf.js --json > pa11y-ci-results.json + depends_on: + - end-to-end-tests-server + environment: + GRAFANA_MISC_STATS_API_KEY: + from_secret: grafana_misc_stats_api_key + HOST: end-to-end-tests-server + PORT: 3001 + failure: ignore + image: hugohaggmark/docker-puppeteer + name: test-a11y-frontend +- commands: + - ./scripts/ci-frontend-metrics.sh | ./bin/grabpl publish-metrics $${GRAFANA_MISC_STATS_API_KEY} + depends_on: + - test-a11y-frontend + environment: + GRAFANA_MISC_STATS_API_KEY: + from_secret: grafana_misc_stats_api_key + failure: ignore + image: grafana/build-container:1.4.8 + name: publish-frontend-metrics +- commands: + - ./scripts/ci-reference-docs-lint.sh ci + depends_on: + - build-frontend + image: grafana/build-container:1.4.8 + name: build-frontend-docs +- commands: + - ls dist/*.tar.gz* + - cp dist/*.tar.gz* packaging/docker/ + depends_on: + - package + image: grafana/build-container:1.4.8 + name: copy-packages-for-docker +- depends_on: + - copy-packages-for-docker + image: grafana/drone-grafana-docker:0.3.2 + name: build-docker-images + settings: + dry_run: false + edition: oss + password: + from_secret: docker_password + ubuntu: false + username: + from_secret: docker_user +- depends_on: + - copy-packages-for-docker + image: grafana/drone-grafana-docker:0.3.2 + name: build-docker-images-ubuntu + settings: + dry_run: false + edition: oss + password: + from_secret: docker_password + ubuntu: true + username: + from_secret: docker_user +- commands: + - ./scripts/circle-release-canary-packages.sh + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + NPM_TOKEN: + from_secret: npm_token + image: grafana/build-container:1.4.8 + name: release-canary-npm-packages +- commands: + - ./bin/grabpl upload-packages --edition oss --packages-bucket grafana-downloads + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages +- commands: + - ./bin/grabpl upload-cdn --edition oss --bucket "grafana-static-assets" + depends_on: + - end-to-end-tests-server + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets +trigger: + branch: main + event: + - push +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +depends_on: [] +kind: pipeline +name: main-integration-tests +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: +- environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: grafanatest + POSTGRES_PASSWORD: grafanatest + POSTGRES_USER: grafanatest + image: postgres:12.3-alpine + name: postgres + volumes: + - name: postgres + path: /var/lib/postgresql/data/pgdata +- environment: + MYSQL_DATABASE: grafana_tests + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_USER: grafana + image: mysql:5.6.48 + name: mysql + volumes: + - name: mysql + path: /var/lib/mysql +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - apt-get update + - apt-get install -yq postgresql-client + - dockerize -wait tcp://postgres:5432 -timeout 120s + - psql -p 5432 -h postgres -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql + - go clean -testcache + - ./bin/grabpl integration-tests --database postgres + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: postgres + PGPASSWORD: grafanatest + POSTGRES_HOST: postgres + image: grafana/build-container:1.4.8 + name: postgres-integration-tests +- commands: + - apt-get update + - apt-get install -yq default-mysql-client + - dockerize -wait tcp://mysql:3306 -timeout 120s + - cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h mysql -P 3306 -u root + -prootpass + - go clean -testcache + - ./bin/grabpl integration-tests --database mysql + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: mysql + MYSQL_HOST: mysql + image: grafana/build-container:1.4.8 + name: mysql-integration-tests +trigger: + branch: main + event: + - push +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +depends_on: +- main-test +- main-build-e2e-publish +- main-integration-tests +kind: pipeline +name: windows-main +platform: + arch: amd64 + os: windows + version: "1809" +services: [] +steps: +- commands: + - echo $env:DRONE_RUNNER_NAME + image: mcr.microsoft.com/windows:1809 + name: identify-runner +- commands: + - $$ProgressPreference = "SilentlyContinue" + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/windows/grabpl.exe + -OutFile grabpl.exe + image: grafana/ci-wix:0.1.1 + name: initialize +- commands: + - $$gcpKey = $$env:GCP_KEY + - '[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($$gcpKey)) + > gcpkey.json' + - dos2unix gcpkey.json + - gcloud auth activate-service-account --key-file=gcpkey.json + - rm gcpkey.json + - cp C:\App\nssm-2.24.zip . + - .\grabpl.exe windows-installer --edition oss --packages-bucket grafana-downloads + --build-id $$env:DRONE_BUILD_NUMBER + - $$fname = ((Get-Childitem grafana*.msi -name) -split "`n")[0] + - gsutil cp $$fname gs://grafana-downloads/oss/main/ + - gsutil cp "$$fname.sha256" gs://grafana-downloads/oss/main/ + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GITHUB_TOKEN: + from_secret: github_token + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/ci-wix:0.1.1 + name: build-windows-installer +trigger: + branch: main + event: + - push +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +depends_on: [] +kind: pipeline +name: notify-drone-changes +platform: + arch: amd64 + os: linux +steps: +- image: plugins/slack + name: slack + settings: + channel: slack-webhooks-test + template: "`.drone.yml` and `starlark` files have been changed on the OSS repo, + by: {{build.author}}. \nBranch: \nCommit hash: " + webhook: + from_secret: drone-changes-webhook +trigger: + branch: main + event: + - push + paths: + exclude: + - exclude + include: + - .drone.yml +type: docker +--- +depends_on: +- main-test +- main-build-e2e-publish +- main-integration-tests +- windows-main +kind: pipeline +name: publish-main +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: [] +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - ./bin/grabpl store-packages --edition oss --gcp-key /tmp/gcpkey.json --build-id + ${DRONE_BUILD_NUMBER} + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_COM_API_KEY: + from_secret: grafana_api_key + image: grafana/grafana-ci-deploy:1.3.1 + name: store-packages-oss +trigger: + branch: main + event: + - push +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +depends_on: +- main-test +- main-build-e2e-publish +- main-integration-tests +- windows-main +- publish-main +kind: pipeline +name: notify-main +platform: + arch: amd64 + os: linux +steps: +- image: plugins/slack + name: slack + settings: + channel: grafana-ci-notifications + template: |- + Build {{build.number}} failed for commit: : {{build.link}} + Branch: + Author: {{build.author}} + webhook: + from_secret: slack_webhook +trigger: + branch: main + event: + - push + status: + - failure +type: docker +--- +depends_on: [] +kind: pipeline +name: oss-build-release +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: +- environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: grafanatest + POSTGRES_PASSWORD: grafanatest + POSTGRES_USER: grafanatest + image: postgres:12.3-alpine + name: postgres + volumes: + - name: postgres + path: /var/lib/postgresql/data/pgdata +- environment: + MYSQL_DATABASE: grafana_tests + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_USER: grafana + image: mysql:5.6.48 + name: mysql + volumes: + - name: mysql + path: /var/lib/mysql +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + - ./bin/grabpl verify-version ${DRONE_TAG} + - ./bin/grabpl gen-version ${DRONE_TAG} + - yarn install --immutable + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - |- + echo -e "unknwon + referer + errorstring + eror + iam + wan" > words_to_ignore.txt + - codespell -I words_to_ignore.txt docs/ + - rm words_to_ignore.txt + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: codespell +- commands: + - ./bin/grabpl shellcheck + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: shellcheck +- commands: + - ./bin/grabpl lint-backend --edition oss + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend +- commands: + - yarn run prettier:check + - yarn run lint + - yarn run i18n:compile + - yarn run typecheck + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: lint-frontend +- commands: + - ./bin/grabpl test-backend --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend +- commands: + - ./bin/grabpl integration-tests --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration +- commands: + - yarn run ci:test-frontend + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: test-frontend +- commands: + - apt-get update + - apt-get install -yq postgresql-client + - dockerize -wait tcp://postgres:5432 -timeout 120s + - psql -p 5432 -h postgres -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql + - go clean -testcache + - ./bin/grabpl integration-tests --database postgres + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: postgres + PGPASSWORD: grafanatest + POSTGRES_HOST: postgres + image: grafana/build-container:1.4.8 + name: postgres-integration-tests +- commands: + - apt-get update + - apt-get install -yq default-mysql-client + - dockerize -wait tcp://mysql:3306 -timeout 120s + - cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h mysql -P 3306 -u root + -prootpass + - go clean -testcache + - ./bin/grabpl integration-tests --database mysql + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: mysql + MYSQL_HOST: mysql + image: grafana/build-container:1.4.8 + name: mysql-integration-tests +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition oss --github-token $${GITHUB_TOKEN} + --no-pull-enterprise ${DRONE_TAG} + depends_on: + - initialize + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: build-backend +- commands: + - ./bin/grabpl build-frontend --jobs 8 --github-token $${GITHUB_TOKEN} --no-install-deps + --edition oss --no-pull-enterprise ${DRONE_TAG} + depends_on: + - initialize + environment: + NODE_OPTIONS: --max_old_space_size=8192 + image: grafana/build-container:1.4.8 + name: build-frontend +- commands: + - ./bin/grabpl build-plugins --jobs 8 --edition oss --no-install-deps --sign --signing-admin + depends_on: + - initialize + environment: + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: build-plugins +- commands: + - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . + depends_on: + - build-backend + image: grafana/build-container:1.4.8 + name: validate-scuemata +- commands: + - '# Make sure the git tree is clean.' + - '# Stashing changes, since packages that were produced in build-backend step are + needed.' + - git stash + - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . + - '# The above command generates Typescript files (*.gen.ts) from all appropriate + .cue files.' + - '# It is required that the generated Typescript be in sync with the input CUE + files.' + - '# ...Modulo eslint auto-fixes...:' + - yarn run eslint . --ext .gen.ts --fix + - '# If any filenames are emitted by the below script, run the generator command + `grafana-cli cue gen-ts` locally and commit the result.' + - ./scripts/clean-git-or-error.sh + - '# Un-stash changes.' + - git stash pop + depends_on: + - validate-scuemata + image: grafana/build-container:1.4.8 + name: ensure-cuetsified +- commands: + - ./bin/grabpl package --jobs 8 --edition oss --github-token $${GITHUB_TOKEN} --no-pull-enterprise + --sign ${DRONE_TAG} + depends_on: + - build-plugins + - build-backend + - build-frontend + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package +- commands: + - ./e2e/start-server + depends_on: + - package + detach: true + environment: + PORT: 3001 + image: grafana/build-container:1.4.8 + name: end-to-end-tests-server +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite dashboards-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-dashboards-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite smoke-tests-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-smoke-tests-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite panels-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-panels-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite various-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-various-suite +- commands: + - apt-get update + - apt-get install -yq zip + - ls -lah ./e2e + - find ./e2e -type f -name "*.mp4" + - printenv GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY > /tmp/gcpkey_upload_artifacts.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey_upload_artifacts.json + - find ./e2e -type f -name "*spec.ts.mp4" | zip e2e/videos.zip -@ + - gsutil cp e2e/videos.zip gs://$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - export E2E_ARTIFACTS_VIDEO_ZIP=https://storage.googleapis.com/$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - 'echo "E2E Test artifacts uploaded to: $${E2E_ARTIFACTS_VIDEO_ZIP}"' + - 'curl -X POST https://api.github.com/repos/${DRONE_REPO}/statuses/${DRONE_COMMIT_SHA} + -H "Authorization: token $${GITHUB_TOKEN}" -d "{\"state\":\"success\",\"target_url\":\"$${E2E_ARTIFACTS_VIDEO_ZIP}\", + \"description\": \"Click on the details to download e2e recording videos\", \"context\": + \"e2e_artifacts\"}"' + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + E2E_TEST_ARTIFACTS_BUCKET: releng-pipeline-artifacts-dev + GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY: + from_secret: gcp_upload_artifacts_key + GITHUB_TOKEN: + from_secret: github_token + image: google/cloud-sdk:367.0.0 + name: e2e_tests_artifacts_upload +- commands: + - ls dist/*.tar.gz* + - cp dist/*.tar.gz* packaging/docker/ + depends_on: + - package + image: grafana/build-container:1.4.8 + name: copy-packages-for-docker +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition oss --shouldSave + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition oss --shouldSave --ubuntu + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images-ubuntu + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - yarn storybook:build + - ./bin/grabpl verify-storybook + depends_on: + - build-frontend + environment: + NODE_OPTIONS: --max_old_space_size=4096 + image: grafana/build-container:1.4.8 + name: build-storybook +- commands: + - ./bin/grabpl upload-cdn --edition oss --bucket "$${PRERELEASE_BUCKET}/artifacts/static-assets" + depends_on: + - end-to-end-tests-server + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets +- commands: + - ./bin/grabpl upload-packages --edition oss --packages-bucket $${PRERELEASE_BUCKET}/artifacts/downloads/${DRONE_TAG} + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - gsutil -m rsync -d -r ./packages/grafana-ui/dist/storybook gs://$${PRERELEASE_BUCKET}/artifacts/storybook/latest + - gsutil -m rsync -d -r ./packages/grafana-ui/dist/storybook gs://$${PRERELEASE_BUCKET}/artifacts/storybook/${DRONE_TAG} + depends_on: + - build-storybook + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + GCP_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: store-storybook +- commands: + - ./scripts/build/build-npm-packages.sh ${DRONE_TAG} + depends_on: + - store-storybook + image: grafana/build-container:1.4.8 + name: build-npm-packages +- commands: + - ./scripts/build/store-npm-packages.sh ${DRONE_TAG} + depends_on: + - build-npm-packages + environment: + GCP_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: store-npm-packages +trigger: + ref: + - refs/tags/v* + repo: + exclude: + - grafana/grafana +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +depends_on: +- oss-build-release +kind: pipeline +name: oss-windows-release +platform: + arch: amd64 + os: windows + version: "1809" +services: [] +steps: +- commands: + - echo $env:DRONE_RUNNER_NAME + image: mcr.microsoft.com/windows:1809 + name: identify-runner +- commands: + - $$ProgressPreference = "SilentlyContinue" + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/windows/grabpl.exe + -OutFile grabpl.exe + image: grafana/ci-wix:0.1.1 + name: initialize +- commands: + - $$gcpKey = $$env:GCP_KEY + - '[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($$gcpKey)) + > gcpkey.json' + - dos2unix gcpkey.json + - gcloud auth activate-service-account --key-file=gcpkey.json + - rm gcpkey.json + - cp C:\App\nssm-2.24.zip . + - .\grabpl.exe windows-installer --edition oss ${DRONE_TAG} + - $$fname = ((Get-Childitem grafana*.msi -name) -split "`n")[0] + - gsutil cp $$fname gs://%PRERELEASE_BUCKET%/artifacts/downloads/oss/release/ + - gsutil cp "$$fname.sha256" gs://%PRERELEASE_BUCKET%/artifacts/downloads/oss/release/ + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GITHUB_TOKEN: + from_secret: github_token + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/ci-wix:0.1.1 + name: build-windows-installer +trigger: + ref: + - refs/tags/v* + repo: + exclude: + - grafana/grafana +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +clone: + disable: true +depends_on: [] +image_pull_secrets: +- dockerconfigjson +kind: pipeline +name: enterprise-build-release +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: +- environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: grafanatest + POSTGRES_PASSWORD: grafanatest + POSTGRES_USER: grafanatest + image: postgres:12.3-alpine + name: postgres + volumes: + - name: postgres + path: /var/lib/postgresql/data/pgdata +- environment: + MYSQL_DATABASE: grafana_tests + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_USER: grafana + image: mysql:5.6.48 + name: mysql + volumes: + - name: mysql + path: /var/lib/mysql +- environment: {} + image: redis:6.2.1-alpine + name: redis +- environment: {} + image: memcached:1.6.9-alpine + name: memcached +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - git clone "https://$${GITHUB_TOKEN}@github.com/grafana/grafana-enterprise.git" + - cd grafana-enterprise + - git checkout ${DRONE_TAG} + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: clone-enterprise +- commands: + - mv bin/grabpl /tmp/ + - rmdir bin + - mv grafana-enterprise /tmp/ + - /tmp/grabpl init-enterprise --github-token $${GITHUB_TOKEN} /tmp/grafana-enterprise + ${DRONE_TAG} + - mv /tmp/grafana-enterprise/deployment_tools_config.json deployment_tools_config.json + - mkdir bin + - mv /tmp/grabpl bin/ + - make gen-go + - ./bin/grabpl verify-version ${DRONE_TAG} + - ./bin/grabpl gen-version ${DRONE_TAG} + - yarn install --immutable + depends_on: + - clone-enterprise + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - |- + echo -e "unknwon + referer + errorstring + eror + iam + wan" > words_to_ignore.txt + - codespell -I words_to_ignore.txt docs/ + - rm words_to_ignore.txt + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: codespell +- commands: + - ./bin/grabpl shellcheck + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: shellcheck +- commands: + - ./bin/grabpl lint-backend --edition enterprise + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend +- commands: + - yarn run prettier:check + - yarn run lint + - yarn run i18n:compile + - yarn run typecheck + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: lint-frontend +- commands: + - ./bin/grabpl test-backend --edition enterprise + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend +- commands: + - ./bin/grabpl integration-tests --edition enterprise + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration +- commands: + - yarn run ci:test-frontend + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: test-frontend +- commands: + - apt-get update + - apt-get install -yq postgresql-client + - dockerize -wait tcp://postgres:5432 -timeout 120s + - psql -p 5432 -h postgres -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql + - go clean -testcache + - ./bin/grabpl integration-tests --database postgres + depends_on: + - initialize + environment: + GRAFANA_TEST_DB: postgres + PGPASSWORD: grafanatest + POSTGRES_HOST: postgres + image: grafana/build-container:1.4.8 + name: postgres-integration-tests +- commands: + - apt-get update + - apt-get install -yq default-mysql-client + - dockerize -wait tcp://mysql:3306 -timeout 120s + - cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h mysql -P 3306 -u root + -prootpass + - go clean -testcache + - ./bin/grabpl integration-tests --database mysql + depends_on: + - initialize + environment: + GRAFANA_TEST_DB: mysql + MYSQL_HOST: mysql + image: grafana/build-container:1.4.8 + name: mysql-integration-tests +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition enterprise --github-token $${GITHUB_TOKEN} + --no-pull-enterprise ${DRONE_TAG} + depends_on: + - initialize + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: build-backend +- commands: + - ./bin/grabpl build-frontend --jobs 8 --github-token $${GITHUB_TOKEN} --no-install-deps + --edition enterprise --no-pull-enterprise ${DRONE_TAG} + depends_on: + - initialize + environment: + NODE_OPTIONS: --max_old_space_size=8192 + image: grafana/build-container:1.4.8 + name: build-frontend +- commands: + - ./bin/grabpl build-plugins --jobs 8 --edition enterprise --no-install-deps --sign + --signing-admin + depends_on: + - initialize + environment: + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: build-plugins +- commands: + - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . + depends_on: + - build-backend + image: grafana/build-container:1.4.8 + name: validate-scuemata +- commands: + - '# Make sure the git tree is clean.' + - '# Stashing changes, since packages that were produced in build-backend step are + needed.' + - git stash + - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . + - '# The above command generates Typescript files (*.gen.ts) from all appropriate + .cue files.' + - '# It is required that the generated Typescript be in sync with the input CUE + files.' + - '# ...Modulo eslint auto-fixes...:' + - yarn run eslint . --ext .gen.ts --fix + - '# If any filenames are emitted by the below script, run the generator command + `grafana-cli cue gen-ts` locally and commit the result.' + - ./scripts/clean-git-or-error.sh + - '# Un-stash changes.' + - git stash pop + depends_on: + - validate-scuemata + image: grafana/build-container:1.4.8 + name: ensure-cuetsified +- commands: + - ./bin/grabpl lint-backend --edition enterprise2 + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend-enterprise2 +- commands: + - ./bin/grabpl test-backend --edition enterprise2 + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-enterprise2 +- commands: + - ./bin/grabpl integration-tests --edition enterprise2 + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration-enterprise2 +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition enterprise2 --github-token $${GITHUB_TOKEN} + --no-pull-enterprise ${DRONE_TAG} + depends_on: + - initialize + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: build-backend-enterprise2 +- commands: + - ./bin/grabpl package --jobs 8 --edition enterprise --github-token $${GITHUB_TOKEN} + --no-pull-enterprise --sign ${DRONE_TAG} + depends_on: + - build-plugins + - build-backend + - build-frontend + - build-backend-enterprise2 + - test-backend-enterprise2 + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package +- commands: + - ./e2e/start-server + depends_on: + - package + detach: true + environment: + PACKAGE_FILE: dist/grafana-enterprise-*linux-amd64.tar.gz + PORT: 3001 + RUNDIR: e2e/tmp-grafana-enterprise + image: grafana/build-container:1.4.8 + name: end-to-end-tests-server +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite dashboards-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-dashboards-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite smoke-tests-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-smoke-tests-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite panels-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-panels-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite various-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-various-suite +- commands: + - apt-get update + - apt-get install -yq zip + - ls -lah ./e2e + - find ./e2e -type f -name "*.mp4" + - printenv GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY > /tmp/gcpkey_upload_artifacts.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey_upload_artifacts.json + - find ./e2e -type f -name "*spec.ts.mp4" | zip e2e/videos.zip -@ + - gsutil cp e2e/videos.zip gs://$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - export E2E_ARTIFACTS_VIDEO_ZIP=https://storage.googleapis.com/$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - 'echo "E2E Test artifacts uploaded to: $${E2E_ARTIFACTS_VIDEO_ZIP}"' + - 'curl -X POST https://api.github.com/repos/${DRONE_REPO}/statuses/${DRONE_COMMIT_SHA} + -H "Authorization: token $${GITHUB_TOKEN}" -d "{\"state\":\"success\",\"target_url\":\"$${E2E_ARTIFACTS_VIDEO_ZIP}\", + \"description\": \"Click on the details to download e2e recording videos\", \"context\": + \"e2e_artifacts\"}"' + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + E2E_TEST_ARTIFACTS_BUCKET: releng-pipeline-artifacts-dev + GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY: + from_secret: gcp_upload_artifacts_key + GITHUB_TOKEN: + from_secret: github_token + image: google/cloud-sdk:367.0.0 + name: e2e_tests_artifacts_upload +- commands: + - ls dist/*.tar.gz* + - cp dist/*.tar.gz* packaging/docker/ + depends_on: + - package + image: grafana/build-container:1.4.8 + name: copy-packages-for-docker +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition enterprise --shouldSave + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition enterprise --shouldSave --ubuntu + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images-ubuntu + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - dockerize -wait tcp://redis:6379/0 -timeout 120s + - ./bin/grabpl integration-tests + depends_on: + - initialize + environment: + REDIS_URL: redis://redis:6379/0 + image: grafana/build-container:1.4.8 + name: redis-integration-tests +- commands: + - dockerize -wait tcp://memcached:11211 -timeout 120s + - ./bin/grabpl integration-tests + depends_on: + - initialize + environment: + MEMCACHED_HOSTS: memcached:11211 + image: grafana/build-container:1.4.8 + name: memcached-integration-tests +- commands: + - ./bin/grabpl upload-cdn --edition enterprise --bucket "$${PRERELEASE_BUCKET}/artifacts/static-assets" + depends_on: + - package + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets +- commands: + - ./bin/grabpl upload-packages --edition enterprise --packages-bucket $${PRERELEASE_BUCKET}/artifacts/downloads/${DRONE_TAG} + depends_on: + - package + - redis-integration-tests + - memcached-integration-tests + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages +- commands: + - ./bin/grabpl package --jobs 8 --edition enterprise2 --github-token $${GITHUB_TOKEN} + --no-pull-enterprise --sign ${DRONE_TAG} + depends_on: + - build-plugins + - build-backend + - build-frontend + - build-backend-enterprise2 + - test-backend-enterprise2 + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package-enterprise2 +- commands: + - ./bin/grabpl upload-cdn --edition enterprise2 --bucket "$${PRERELEASE_BUCKET}/artifacts/static-assets" + depends_on: + - package-enterprise2 + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets-enterprise2 +- commands: + - ./bin/grabpl upload-packages --edition enterprise2 --packages-bucket $${PRERELEASE_BUCKET}/artifacts/downloads-enterprise2/${DRONE_TAG} + depends_on: + - package-enterprise2 + - redis-integration-tests + - memcached-integration-tests + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages-enterprise2 +trigger: + ref: + - refs/tags/v* + repo: + exclude: + - grafana/grafana +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +clone: + disable: true +depends_on: +- enterprise-build-release +image_pull_secrets: +- dockerconfigjson +kind: pipeline +name: enterprise-windows-release +platform: + arch: amd64 + os: windows + version: "1809" +services: [] +steps: +- commands: + - echo $env:DRONE_RUNNER_NAME + image: mcr.microsoft.com/windows:1809 + name: identify-runner +- commands: + - $$ProgressPreference = "SilentlyContinue" + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/windows/grabpl.exe + -OutFile grabpl.exe + - git clone "https://$$env:GITHUB_TOKEN@github.com/grafana/grafana-enterprise.git" + - cd grafana-enterprise + - git checkout ${DRONE_TAG} + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/ci-wix:0.1.1 + name: clone +- commands: + - cp -r grafana-enterprise C:\App\grafana-enterprise + - rm -r -force grafana-enterprise + - cp grabpl.exe C:\App\grabpl.exe + - rm -force grabpl.exe + - C:\App\grabpl.exe init-enterprise --github-token $$env:GITHUB_TOKEN C:\App\grafana-enterprise + - cp C:\App\grabpl.exe grabpl.exe + depends_on: + - clone + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/ci-wix:0.1.1 + name: initialize +- commands: + - $$gcpKey = $$env:GCP_KEY + - '[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($$gcpKey)) + > gcpkey.json' + - dos2unix gcpkey.json + - gcloud auth activate-service-account --key-file=gcpkey.json + - rm gcpkey.json + - cp C:\App\nssm-2.24.zip . + - .\grabpl.exe windows-installer --edition enterprise ${DRONE_TAG} + - $$fname = ((Get-Childitem grafana*.msi -name) -split "`n")[0] + - gsutil cp $$fname gs://%PRERELEASE_BUCKET%/artifacts/downloads/enterprise/release/ + - gsutil cp "$$fname.sha256" gs://%PRERELEASE_BUCKET%/artifacts/downloads/enterprise/release/ + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GITHUB_TOKEN: + from_secret: github_token + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/ci-wix:0.1.1 + name: build-windows-installer +trigger: + ref: + - refs/tags/v* + repo: + exclude: + - grafana/grafana +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +depends_on: [] +kind: pipeline +name: oss-build-test-release +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: +- environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: grafanatest + POSTGRES_PASSWORD: grafanatest + POSTGRES_USER: grafanatest + image: postgres:12.3-alpine + name: postgres + volumes: + - name: postgres + path: /var/lib/postgresql/data/pgdata +- environment: + MYSQL_DATABASE: grafana_tests + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_USER: grafana + image: mysql:5.6.48 + name: mysql + volumes: + - name: mysql + path: /var/lib/mysql +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + - ./bin/grabpl verify-version v7.3.0-test + - ./bin/grabpl gen-version v7.3.0-test + - yarn install --immutable + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - |- + echo -e "unknwon + referer + errorstring + eror + iam + wan" > words_to_ignore.txt + - codespell -I words_to_ignore.txt docs/ + - rm words_to_ignore.txt + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: codespell +- commands: + - ./bin/grabpl shellcheck + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: shellcheck +- commands: + - ./bin/grabpl lint-backend --edition oss + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend +- commands: + - yarn run prettier:check + - yarn run lint + - yarn run i18n:compile + - yarn run typecheck + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: lint-frontend +- commands: + - ./bin/grabpl test-backend --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend +- commands: + - ./bin/grabpl integration-tests --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration +- commands: + - yarn run ci:test-frontend + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: test-frontend +- commands: + - apt-get update + - apt-get install -yq postgresql-client + - dockerize -wait tcp://postgres:5432 -timeout 120s + - psql -p 5432 -h postgres -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql + - go clean -testcache + - ./bin/grabpl integration-tests --database postgres + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: postgres + PGPASSWORD: grafanatest + POSTGRES_HOST: postgres + image: grafana/build-container:1.4.8 + name: postgres-integration-tests +- commands: + - apt-get update + - apt-get install -yq default-mysql-client + - dockerize -wait tcp://mysql:3306 -timeout 120s + - cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h mysql -P 3306 -u root + -prootpass + - go clean -testcache + - ./bin/grabpl integration-tests --database mysql + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: mysql + MYSQL_HOST: mysql + image: grafana/build-container:1.4.8 + name: mysql-integration-tests +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition oss --github-token $${GITHUB_TOKEN} + --no-pull-enterprise v7.3.0-test + depends_on: + - initialize + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: build-backend +- commands: + - ./bin/grabpl build-frontend --jobs 8 --github-token $${GITHUB_TOKEN} --no-install-deps + --edition oss --no-pull-enterprise v7.3.0-test + depends_on: + - initialize + environment: + NODE_OPTIONS: --max_old_space_size=8192 + image: grafana/build-container:1.4.8 + name: build-frontend +- commands: + - ./bin/grabpl build-plugins --jobs 8 --edition oss --no-install-deps --sign --signing-admin + depends_on: + - initialize + environment: + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: build-plugins +- commands: + - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . + depends_on: + - build-backend + image: grafana/build-container:1.4.8 + name: validate-scuemata +- commands: + - '# Make sure the git tree is clean.' + - '# Stashing changes, since packages that were produced in build-backend step are + needed.' + - git stash + - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . + - '# The above command generates Typescript files (*.gen.ts) from all appropriate + .cue files.' + - '# It is required that the generated Typescript be in sync with the input CUE + files.' + - '# ...Modulo eslint auto-fixes...:' + - yarn run eslint . --ext .gen.ts --fix + - '# If any filenames are emitted by the below script, run the generator command + `grafana-cli cue gen-ts` locally and commit the result.' + - ./scripts/clean-git-or-error.sh + - '# Un-stash changes.' + - git stash pop + depends_on: + - validate-scuemata + image: grafana/build-container:1.4.8 + name: ensure-cuetsified +- commands: + - ./bin/grabpl package --jobs 8 --edition oss --github-token $${GITHUB_TOKEN} --no-pull-enterprise + --sign v7.3.0-test + depends_on: + - build-plugins + - build-backend + - build-frontend + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package +- commands: + - ./e2e/start-server + depends_on: + - package + detach: true + environment: + PORT: 3001 + image: grafana/build-container:1.4.8 + name: end-to-end-tests-server +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite dashboards-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-dashboards-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite smoke-tests-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-smoke-tests-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite panels-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-panels-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite various-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-various-suite +- commands: + - apt-get update + - apt-get install -yq zip + - ls -lah ./e2e + - find ./e2e -type f -name "*.mp4" + - printenv GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY > /tmp/gcpkey_upload_artifacts.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey_upload_artifacts.json + - find ./e2e -type f -name "*spec.ts.mp4" | zip e2e/videos.zip -@ + - gsutil cp e2e/videos.zip gs://$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - export E2E_ARTIFACTS_VIDEO_ZIP=https://storage.googleapis.com/$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - 'echo "E2E Test artifacts uploaded to: $${E2E_ARTIFACTS_VIDEO_ZIP}"' + - 'curl -X POST https://api.github.com/repos/${DRONE_REPO}/statuses/${DRONE_COMMIT_SHA} + -H "Authorization: token $${GITHUB_TOKEN}" -d "{\"state\":\"success\",\"target_url\":\"$${E2E_ARTIFACTS_VIDEO_ZIP}\", + \"description\": \"Click on the details to download e2e recording videos\", \"context\": + \"e2e_artifacts\"}"' + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + E2E_TEST_ARTIFACTS_BUCKET: releng-pipeline-artifacts-dev + GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY: + from_secret: gcp_upload_artifacts_key + GITHUB_TOKEN: + from_secret: github_token + image: google/cloud-sdk:367.0.0 + name: e2e_tests_artifacts_upload +- commands: + - ls dist/*.tar.gz* + - cp dist/*.tar.gz* packaging/docker/ + depends_on: + - package + image: grafana/build-container:1.4.8 + name: copy-packages-for-docker +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition oss --shouldSave + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition oss --shouldSave --ubuntu + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images-ubuntu + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - yarn storybook:build + - ./bin/grabpl verify-storybook + depends_on: + - build-frontend + environment: + NODE_OPTIONS: --max_old_space_size=4096 + image: grafana/build-container:1.4.8 + name: build-storybook +- commands: + - ./bin/grabpl upload-cdn --edition oss --bucket "grafana-static-assets" + depends_on: + - end-to-end-tests-server + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets +- commands: + - ./bin/grabpl upload-packages --edition oss --packages-bucket grafana-downloads-test + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages +- commands: + - echo Testing release + depends_on: + - build-storybook + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + GCP_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: store-storybook +trigger: + event: + - custom +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +depends_on: +- oss-build-test-release +kind: pipeline +name: oss-windows-test-release +platform: + arch: amd64 + os: windows + version: "1809" +services: [] +steps: +- commands: + - echo $env:DRONE_RUNNER_NAME + image: mcr.microsoft.com/windows:1809 + name: identify-runner +- commands: + - $$ProgressPreference = "SilentlyContinue" + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/windows/grabpl.exe + -OutFile grabpl.exe + image: grafana/ci-wix:0.1.1 + name: initialize +- commands: + - $$gcpKey = $$env:GCP_KEY + - '[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($$gcpKey)) + > gcpkey.json' + - dos2unix gcpkey.json + - gcloud auth activate-service-account --key-file=gcpkey.json + - rm gcpkey.json + - cp C:\App\nssm-2.24.zip . + - .\grabpl.exe windows-installer --edition oss --packages-bucket grafana-downloads-test + v7.3.0-test + - $$fname = ((Get-Childitem grafana*.msi -name) -split "`n")[0] + - gsutil cp $$fname gs://grafana-downloads-test/oss/release/ + - gsutil cp "$$fname.sha256" gs://grafana-downloads-test/oss/release/ + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GITHUB_TOKEN: + from_secret: github_token + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/ci-wix:0.1.1 + name: build-windows-installer +trigger: + event: + - custom +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +clone: + disable: true +depends_on: [] +image_pull_secrets: +- dockerconfigjson +kind: pipeline +name: enterprise-build-test-release +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: +- environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: grafanatest + POSTGRES_PASSWORD: grafanatest + POSTGRES_USER: grafanatest + image: postgres:12.3-alpine + name: postgres + volumes: + - name: postgres + path: /var/lib/postgresql/data/pgdata +- environment: + MYSQL_DATABASE: grafana_tests + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_USER: grafana + image: mysql:5.6.48 + name: mysql + volumes: + - name: mysql + path: /var/lib/mysql +- environment: {} + image: redis:6.2.1-alpine + name: redis +- environment: {} + image: memcached:1.6.9-alpine + name: memcached +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - git clone "https://$${GITHUB_TOKEN}@github.com/grafana/grafana-enterprise.git" + - cd grafana-enterprise + - git checkout main + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: clone-enterprise +- commands: + - mv bin/grabpl /tmp/ + - rmdir bin + - mv grafana-enterprise /tmp/ + - /tmp/grabpl init-enterprise --github-token $${GITHUB_TOKEN} /tmp/grafana-enterprise + - mv /tmp/grafana-enterprise/deployment_tools_config.json deployment_tools_config.json + - mkdir bin + - mv /tmp/grabpl bin/ + - make gen-go + - ./bin/grabpl verify-version v7.3.0-test + - ./bin/grabpl gen-version v7.3.0-test + - yarn install --immutable + depends_on: + - clone-enterprise + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - |- + echo -e "unknwon + referer + errorstring + eror + iam + wan" > words_to_ignore.txt + - codespell -I words_to_ignore.txt docs/ + - rm words_to_ignore.txt + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: codespell +- commands: + - ./bin/grabpl shellcheck + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: shellcheck +- commands: + - ./bin/grabpl lint-backend --edition enterprise + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend +- commands: + - yarn run prettier:check + - yarn run lint + - yarn run i18n:compile + - yarn run typecheck + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: lint-frontend +- commands: + - ./bin/grabpl test-backend --edition enterprise + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend +- commands: + - ./bin/grabpl integration-tests --edition enterprise + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration +- commands: + - yarn run ci:test-frontend + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: test-frontend +- commands: + - apt-get update + - apt-get install -yq postgresql-client + - dockerize -wait tcp://postgres:5432 -timeout 120s + - psql -p 5432 -h postgres -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql + - go clean -testcache + - ./bin/grabpl integration-tests --database postgres + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: postgres + PGPASSWORD: grafanatest + POSTGRES_HOST: postgres + image: grafana/build-container:1.4.8 + name: postgres-integration-tests +- commands: + - apt-get update + - apt-get install -yq default-mysql-client + - dockerize -wait tcp://mysql:3306 -timeout 120s + - cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h mysql -P 3306 -u root + -prootpass + - go clean -testcache + - ./bin/grabpl integration-tests --database mysql + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: mysql + MYSQL_HOST: mysql + image: grafana/build-container:1.4.8 + name: mysql-integration-tests +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition enterprise --github-token $${GITHUB_TOKEN} + --no-pull-enterprise v7.3.0-test + depends_on: + - initialize + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: build-backend +- commands: + - ./bin/grabpl build-frontend --jobs 8 --github-token $${GITHUB_TOKEN} --no-install-deps + --edition enterprise --no-pull-enterprise v7.3.0-test + depends_on: + - initialize + environment: + NODE_OPTIONS: --max_old_space_size=8192 + image: grafana/build-container:1.4.8 + name: build-frontend +- commands: + - ./bin/grabpl build-plugins --jobs 8 --edition enterprise --no-install-deps --sign + --signing-admin + depends_on: + - initialize + environment: + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: build-plugins +- commands: + - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . + depends_on: + - build-backend + image: grafana/build-container:1.4.8 + name: validate-scuemata +- commands: + - '# Make sure the git tree is clean.' + - '# Stashing changes, since packages that were produced in build-backend step are + needed.' + - git stash + - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . + - '# The above command generates Typescript files (*.gen.ts) from all appropriate + .cue files.' + - '# It is required that the generated Typescript be in sync with the input CUE + files.' + - '# ...Modulo eslint auto-fixes...:' + - yarn run eslint . --ext .gen.ts --fix + - '# If any filenames are emitted by the below script, run the generator command + `grafana-cli cue gen-ts` locally and commit the result.' + - ./scripts/clean-git-or-error.sh + - '# Un-stash changes.' + - git stash pop + depends_on: + - validate-scuemata + image: grafana/build-container:1.4.8 + name: ensure-cuetsified +- commands: + - ./bin/grabpl lint-backend --edition enterprise2 + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend-enterprise2 +- commands: + - ./bin/grabpl test-backend --edition enterprise2 + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-enterprise2 +- commands: + - ./bin/grabpl integration-tests --edition enterprise2 + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration-enterprise2 +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition enterprise2 --github-token $${GITHUB_TOKEN} + --no-pull-enterprise v7.3.0-test + depends_on: + - initialize + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: build-backend-enterprise2 +- commands: + - ./bin/grabpl package --jobs 8 --edition enterprise --github-token $${GITHUB_TOKEN} + --no-pull-enterprise --sign v7.3.0-test + depends_on: + - build-plugins + - build-backend + - build-frontend + - build-backend-enterprise2 + - test-backend-enterprise2 + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package +- commands: + - ./e2e/start-server + depends_on: + - package + detach: true + environment: + PACKAGE_FILE: dist/grafana-enterprise-*linux-amd64.tar.gz + PORT: 3001 + RUNDIR: e2e/tmp-grafana-enterprise + image: grafana/build-container:1.4.8 + name: end-to-end-tests-server +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite dashboards-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-dashboards-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite smoke-tests-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-smoke-tests-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite panels-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-panels-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite various-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-various-suite +- commands: + - apt-get update + - apt-get install -yq zip + - ls -lah ./e2e + - find ./e2e -type f -name "*.mp4" + - printenv GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY > /tmp/gcpkey_upload_artifacts.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey_upload_artifacts.json + - find ./e2e -type f -name "*spec.ts.mp4" | zip e2e/videos.zip -@ + - gsutil cp e2e/videos.zip gs://$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - export E2E_ARTIFACTS_VIDEO_ZIP=https://storage.googleapis.com/$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - 'echo "E2E Test artifacts uploaded to: $${E2E_ARTIFACTS_VIDEO_ZIP}"' + - 'curl -X POST https://api.github.com/repos/${DRONE_REPO}/statuses/${DRONE_COMMIT_SHA} + -H "Authorization: token $${GITHUB_TOKEN}" -d "{\"state\":\"success\",\"target_url\":\"$${E2E_ARTIFACTS_VIDEO_ZIP}\", + \"description\": \"Click on the details to download e2e recording videos\", \"context\": + \"e2e_artifacts\"}"' + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + E2E_TEST_ARTIFACTS_BUCKET: releng-pipeline-artifacts-dev + GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY: + from_secret: gcp_upload_artifacts_key + GITHUB_TOKEN: + from_secret: github_token + image: google/cloud-sdk:367.0.0 + name: e2e_tests_artifacts_upload +- commands: + - ls dist/*.tar.gz* + - cp dist/*.tar.gz* packaging/docker/ + depends_on: + - package + image: grafana/build-container:1.4.8 + name: copy-packages-for-docker +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition enterprise --shouldSave + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition enterprise --shouldSave --ubuntu + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images-ubuntu + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - dockerize -wait tcp://redis:6379/0 -timeout 120s + - ./bin/grabpl integration-tests + depends_on: + - grabpl + environment: + REDIS_URL: redis://redis:6379/0 + image: grafana/build-container:1.4.8 + name: redis-integration-tests +- commands: + - dockerize -wait tcp://memcached:11211 -timeout 120s + - ./bin/grabpl integration-tests + depends_on: + - grabpl + environment: + MEMCACHED_HOSTS: memcached:11211 + image: grafana/build-container:1.4.8 + name: memcached-integration-tests +- commands: + - ./bin/grabpl upload-cdn --edition enterprise --bucket "grafana-static-assets" + depends_on: + - package + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets +- commands: + - ./bin/grabpl upload-packages --edition enterprise --packages-bucket grafana-downloads-test + depends_on: + - package + - redis-integration-tests + - memcached-integration-tests + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages +- commands: + - ./bin/grabpl package --jobs 8 --edition enterprise2 --github-token $${GITHUB_TOKEN} + --no-pull-enterprise --sign v7.3.0-test + depends_on: + - build-plugins + - build-backend + - build-frontend + - build-backend-enterprise2 + - test-backend-enterprise2 + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package-enterprise2 +- commands: + - ./bin/grabpl upload-cdn --edition enterprise2 --bucket "grafana-static-assets" + depends_on: + - package-enterprise2 + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets-enterprise2 +- commands: + - ./bin/grabpl upload-packages --edition enterprise2 --packages-bucket grafana-downloads-test + depends_on: + - package-enterprise2 + - redis-integration-tests + - memcached-integration-tests + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages-enterprise2 +trigger: + event: + - custom +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +clone: + disable: true +depends_on: +- enterprise-build-test-release +image_pull_secrets: +- dockerconfigjson +kind: pipeline +name: enterprise-windows-test-release +platform: + arch: amd64 + os: windows + version: "1809" +services: [] +steps: +- commands: + - echo $env:DRONE_RUNNER_NAME + image: mcr.microsoft.com/windows:1809 + name: identify-runner +- commands: + - $$ProgressPreference = "SilentlyContinue" + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/windows/grabpl.exe + -OutFile grabpl.exe + - git clone "https://$$env:GITHUB_TOKEN@github.com/grafana/grafana-enterprise.git" + - cd grafana-enterprise + - git checkout main + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/ci-wix:0.1.1 + name: clone +- commands: + - cp -r grafana-enterprise C:\App\grafana-enterprise + - rm -r -force grafana-enterprise + - cp grabpl.exe C:\App\grabpl.exe + - rm -force grabpl.exe + - C:\App\grabpl.exe init-enterprise --github-token $$env:GITHUB_TOKEN C:\App\grafana-enterprise + - cp C:\App\grabpl.exe grabpl.exe + depends_on: + - clone + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/ci-wix:0.1.1 + name: initialize +- commands: + - $$gcpKey = $$env:GCP_KEY + - '[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($$gcpKey)) + > gcpkey.json' + - dos2unix gcpkey.json + - gcloud auth activate-service-account --key-file=gcpkey.json + - rm gcpkey.json + - cp C:\App\nssm-2.24.zip . + - .\grabpl.exe windows-installer --edition enterprise --packages-bucket grafana-downloads-test + v7.3.0-test + - $$fname = ((Get-Childitem grafana*.msi -name) -split "`n")[0] + - gsutil cp $$fname gs://grafana-downloads-test/enterprise/release/ + - gsutil cp "$$fname.sha256" gs://grafana-downloads-test/enterprise/release/ + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GITHUB_TOKEN: + from_secret: github_token + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/ci-wix:0.1.1 + name: build-windows-installer +trigger: + event: + - custom +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +depends_on: +- oss-build-test-release +- oss-windows-test-release +- enterprise-build-test-release +- enterprise-windows-test-release +kind: pipeline +name: publish-test-release +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: [] +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + - ./bin/grabpl verify-version v7.3.0-test + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - ./bin/grabpl store-packages --edition oss --gcp-key /tmp/gcpkey.json --deb-db-bucket + grafana-testing-aptly-db --deb-repo-bucket grafana-testing-repo --packages-bucket + grafana-downloads-test --rpm-repo-bucket grafana-testing-repo --simulate-release + v7.3.0-test + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_COM_API_KEY: + from_secret: grafana_api_key + image: grafana/grafana-ci-deploy:1.3.1 + name: store-packages-oss +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - ./bin/grabpl store-packages --edition enterprise --gcp-key /tmp/gcpkey.json --deb-db-bucket + grafana-testing-aptly-db --deb-repo-bucket grafana-testing-repo --packages-bucket + grafana-downloads-test --rpm-repo-bucket grafana-testing-repo --simulate-release + v7.3.0-test + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_COM_API_KEY: + from_secret: grafana_api_key + image: grafana/grafana-ci-deploy:1.3.1 + name: store-packages-enterprise +trigger: + event: + - custom +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +depends_on: +- oss-build-test-release +- oss-windows-test-release +- enterprise-build-test-release +- enterprise-windows-test-release +- publish-test-release +kind: pipeline +name: notify-test-release +platform: + arch: amd64 + os: linux +steps: +- image: plugins/slack + name: slack + settings: + channel: grafana-ci-notifications + template: |- + Build {{build.number}} failed for commit: : {{build.link}} + Branch: + Author: {{build.author}} + webhook: + from_secret: slack_webhook +trigger: + event: + - custom + status: + - failure +type: docker +--- +depends_on: [] +kind: pipeline +name: oss-build-release-branch +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: +- environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: grafanatest + POSTGRES_PASSWORD: grafanatest + POSTGRES_USER: grafanatest + image: postgres:12.3-alpine + name: postgres + volumes: + - name: postgres + path: /var/lib/postgresql/data/pgdata +- environment: + MYSQL_DATABASE: grafana_tests + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_USER: grafana + image: mysql:5.6.48 + name: mysql + volumes: + - name: mysql + path: /var/lib/mysql +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - make gen-go + - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} + - yarn install --immutable + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - |- + echo -e "unknwon + referer + errorstring + eror + iam + wan" > words_to_ignore.txt + - codespell -I words_to_ignore.txt docs/ + - rm words_to_ignore.txt + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: codespell +- commands: + - ./bin/grabpl shellcheck + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: shellcheck +- commands: + - ./bin/grabpl lint-backend --edition oss + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend +- commands: + - yarn run prettier:check + - yarn run lint + - yarn run i18n:compile + - yarn run typecheck + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: lint-frontend +- commands: + - ./bin/grabpl test-backend --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend +- commands: + - ./bin/grabpl integration-tests --edition oss + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration +- commands: + - yarn run ci:test-frontend + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: test-frontend +- commands: + - apt-get update + - apt-get install -yq postgresql-client + - dockerize -wait tcp://postgres:5432 -timeout 120s + - psql -p 5432 -h postgres -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql + - go clean -testcache + - ./bin/grabpl integration-tests --database postgres + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: postgres + PGPASSWORD: grafanatest + POSTGRES_HOST: postgres + image: grafana/build-container:1.4.8 + name: postgres-integration-tests +- commands: + - apt-get update + - apt-get install -yq default-mysql-client + - dockerize -wait tcp://mysql:3306 -timeout 120s + - cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h mysql -P 3306 -u root + -prootpass + - go clean -testcache + - ./bin/grabpl integration-tests --database mysql + depends_on: + - grabpl + environment: + GRAFANA_TEST_DB: mysql + MYSQL_HOST: mysql + image: grafana/build-container:1.4.8 + name: mysql-integration-tests +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} + --no-pull-enterprise + depends_on: + - initialize + environment: {} + image: grafana/build-container:1.4.8 + name: build-backend +- commands: + - ./bin/grabpl build-frontend --jobs 8 --no-install-deps --edition oss --build-id + ${DRONE_BUILD_NUMBER} --no-pull-enterprise + depends_on: + - initialize + environment: + NODE_OPTIONS: --max_old_space_size=8192 + image: grafana/build-container:1.4.8 + name: build-frontend +- commands: + - ./bin/grabpl build-plugins --jobs 8 --edition oss --no-install-deps --sign --signing-admin + depends_on: + - initialize + environment: + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: build-plugins +- commands: + - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . + depends_on: + - build-backend + image: grafana/build-container:1.4.8 + name: validate-scuemata +- commands: + - '# Make sure the git tree is clean.' + - '# Stashing changes, since packages that were produced in build-backend step are + needed.' + - git stash + - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . + - '# The above command generates Typescript files (*.gen.ts) from all appropriate + .cue files.' + - '# It is required that the generated Typescript be in sync with the input CUE + files.' + - '# ...Modulo eslint auto-fixes...:' + - yarn run eslint . --ext .gen.ts --fix + - '# If any filenames are emitted by the below script, run the generator command + `grafana-cli cue gen-ts` locally and commit the result.' + - ./scripts/clean-git-or-error.sh + - '# Un-stash changes.' + - git stash pop + depends_on: + - validate-scuemata + image: grafana/build-container:1.4.8 + name: ensure-cuetsified +- commands: + - ./bin/grabpl package --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} --no-pull-enterprise + --sign + depends_on: + - build-plugins + - build-backend + - build-frontend + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package +- commands: + - ./e2e/start-server + depends_on: + - package + detach: true + environment: + PORT: 3001 + image: grafana/build-container:1.4.8 + name: end-to-end-tests-server +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite dashboards-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-dashboards-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite smoke-tests-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-smoke-tests-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite panels-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-panels-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite various-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-various-suite +- commands: + - apt-get update + - apt-get install -yq zip + - ls -lah ./e2e + - find ./e2e -type f -name "*.mp4" + - printenv GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY > /tmp/gcpkey_upload_artifacts.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey_upload_artifacts.json + - find ./e2e -type f -name "*spec.ts.mp4" | zip e2e/videos.zip -@ + - gsutil cp e2e/videos.zip gs://$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - export E2E_ARTIFACTS_VIDEO_ZIP=https://storage.googleapis.com/$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - 'echo "E2E Test artifacts uploaded to: $${E2E_ARTIFACTS_VIDEO_ZIP}"' + - 'curl -X POST https://api.github.com/repos/${DRONE_REPO}/statuses/${DRONE_COMMIT_SHA} + -H "Authorization: token $${GITHUB_TOKEN}" -d "{\"state\":\"success\",\"target_url\":\"$${E2E_ARTIFACTS_VIDEO_ZIP}\", + \"description\": \"Click on the details to download e2e recording videos\", \"context\": + \"e2e_artifacts\"}"' + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + E2E_TEST_ARTIFACTS_BUCKET: releng-pipeline-artifacts-dev + GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY: + from_secret: gcp_upload_artifacts_key + GITHUB_TOKEN: + from_secret: github_token + image: google/cloud-sdk:367.0.0 + name: e2e_tests_artifacts_upload +- commands: + - ls dist/*.tar.gz* + - cp dist/*.tar.gz* packaging/docker/ + depends_on: + - package + image: grafana/build-container:1.4.8 + name: copy-packages-for-docker +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition oss --shouldSave + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition oss --shouldSave --ubuntu + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images-ubuntu + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - yarn storybook:build + - ./bin/grabpl verify-storybook + depends_on: + - build-frontend + environment: + NODE_OPTIONS: --max_old_space_size=4096 + image: grafana/build-container:1.4.8 + name: build-storybook +- commands: + - ./bin/grabpl upload-cdn --edition oss --bucket "grafana-static-assets" + depends_on: + - end-to-end-tests-server + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets +- commands: + - ./bin/grabpl upload-packages --edition oss --packages-bucket grafana-downloads + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages +trigger: + ref: + - refs/heads/v[0-9]* +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +depends_on: +- oss-build-release-branch +kind: pipeline +name: oss-windows-release-branch +platform: + arch: amd64 + os: windows + version: "1809" +services: [] +steps: +- commands: + - echo $env:DRONE_RUNNER_NAME + image: mcr.microsoft.com/windows:1809 + name: identify-runner +- commands: + - $$ProgressPreference = "SilentlyContinue" + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/windows/grabpl.exe + -OutFile grabpl.exe + image: grafana/ci-wix:0.1.1 + name: initialize +- commands: + - $$gcpKey = $$env:GCP_KEY + - '[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($$gcpKey)) + > gcpkey.json' + - dos2unix gcpkey.json + - gcloud auth activate-service-account --key-file=gcpkey.json + - rm gcpkey.json + - cp C:\App\nssm-2.24.zip . + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GITHUB_TOKEN: + from_secret: github_token + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/ci-wix:0.1.1 + name: build-windows-installer +trigger: + ref: + - refs/heads/v[0-9]* +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +clone: + disable: true +depends_on: [] +image_pull_secrets: +- dockerconfigjson +kind: pipeline +name: enterprise-build-release-branch +node: + type: no-parallel +platform: + arch: amd64 + os: linux +services: +- environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: grafanatest + POSTGRES_PASSWORD: grafanatest + POSTGRES_USER: grafanatest + image: postgres:12.3-alpine + name: postgres + volumes: + - name: postgres + path: /var/lib/postgresql/data/pgdata +- environment: + MYSQL_DATABASE: grafana_tests + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_USER: grafana + image: mysql:5.6.48 + name: mysql + volumes: + - name: mysql + path: /var/lib/mysql +- environment: {} + image: redis:6.2.1-alpine + name: redis +- environment: {} + image: memcached:1.6.9-alpine + name: memcached +steps: +- commands: + - mkdir -p bin + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/grabpl + - chmod +x bin/grabpl + image: byrnedo/alpine-curl:0.1.8 + name: grabpl +- commands: + - echo $DRONE_RUNNER_NAME + image: alpine:3.14.3 + name: identify-runner +- commands: + - git clone "https://$${GITHUB_TOKEN}@github.com/grafana/grafana-enterprise.git" + - cd grafana-enterprise + - git checkout ${DRONE_BRANCH} + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: clone-enterprise +- commands: + - mv bin/grabpl /tmp/ + - rmdir bin + - mv grafana-enterprise /tmp/ + - /tmp/grabpl init-enterprise --github-token $${GITHUB_TOKEN} /tmp/grafana-enterprise + - mv /tmp/grafana-enterprise/deployment_tools_config.json deployment_tools_config.json + - mkdir bin + - mv /tmp/grabpl bin/ + - make gen-go + - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} + - yarn install --immutable + depends_on: + - clone-enterprise + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/build-container:1.4.8 + name: initialize +- commands: + - |- + echo -e "unknwon + referer + errorstring + eror + iam + wan" > words_to_ignore.txt + - codespell -I words_to_ignore.txt docs/ + - rm words_to_ignore.txt + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: codespell +- commands: + - ./bin/grabpl shellcheck + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: shellcheck +- commands: + - ./bin/grabpl lint-backend --edition enterprise + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend +- commands: + - yarn run prettier:check + - yarn run lint + - yarn run i18n:compile + - yarn run typecheck + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: lint-frontend +- commands: + - ./bin/grabpl test-backend --edition enterprise + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend +- commands: + - ./bin/grabpl integration-tests --edition enterprise + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration +- commands: + - yarn run ci:test-frontend + depends_on: + - initialize + environment: + TEST_MAX_WORKERS: 50% + image: grafana/build-container:1.4.8 + name: test-frontend +- commands: + - apt-get update + - apt-get install -yq postgresql-client + - dockerize -wait tcp://postgres:5432 -timeout 120s + - psql -p 5432 -h postgres -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql + - go clean -testcache + - ./bin/grabpl integration-tests --database postgres + depends_on: + - initialize + environment: + GRAFANA_TEST_DB: postgres + PGPASSWORD: grafanatest + POSTGRES_HOST: postgres + image: grafana/build-container:1.4.8 + name: postgres-integration-tests +- commands: + - apt-get update + - apt-get install -yq default-mysql-client + - dockerize -wait tcp://mysql:3306 -timeout 120s + - cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h mysql -P 3306 -u root + -prootpass + - go clean -testcache + - ./bin/grabpl integration-tests --database mysql + depends_on: + - initialize + environment: + GRAFANA_TEST_DB: mysql + MYSQL_HOST: mysql + image: grafana/build-container:1.4.8 + name: mysql-integration-tests +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition enterprise --build-id ${DRONE_BUILD_NUMBER} + --no-pull-enterprise + depends_on: + - initialize + environment: {} + image: grafana/build-container:1.4.8 + name: build-backend +- commands: + - ./bin/grabpl build-frontend --jobs 8 --no-install-deps --edition enterprise --build-id + ${DRONE_BUILD_NUMBER} --no-pull-enterprise + depends_on: + - initialize + environment: + NODE_OPTIONS: --max_old_space_size=8192 + image: grafana/build-container:1.4.8 + name: build-frontend +- commands: + - ./bin/grabpl build-plugins --jobs 8 --edition enterprise --no-install-deps --sign + --signing-admin + depends_on: + - initialize + environment: + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: build-plugins +- commands: + - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . + depends_on: + - build-backend + image: grafana/build-container:1.4.8 + name: validate-scuemata +- commands: + - '# Make sure the git tree is clean.' + - '# Stashing changes, since packages that were produced in build-backend step are + needed.' + - git stash + - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . + - '# The above command generates Typescript files (*.gen.ts) from all appropriate + .cue files.' + - '# It is required that the generated Typescript be in sync with the input CUE + files.' + - '# ...Modulo eslint auto-fixes...:' + - yarn run eslint . --ext .gen.ts --fix + - '# If any filenames are emitted by the below script, run the generator command + `grafana-cli cue gen-ts` locally and commit the result.' + - ./scripts/clean-git-or-error.sh + - '# Un-stash changes.' + - git stash pop + depends_on: + - validate-scuemata + image: grafana/build-container:1.4.8 + name: ensure-cuetsified +- commands: + - ./bin/grabpl lint-backend --edition enterprise2 + depends_on: + - initialize + environment: + CGO_ENABLED: "1" + image: grafana/build-container:1.4.8 + name: lint-backend-enterprise2 +- commands: + - ./bin/grabpl test-backend --edition enterprise2 + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-enterprise2 +- commands: + - ./bin/grabpl integration-tests --edition enterprise2 + depends_on: + - initialize + image: grafana/build-container:1.4.8 + name: test-backend-integration-enterprise2 +- commands: + - ./bin/grabpl build-backend --jobs 8 --edition enterprise2 --build-id ${DRONE_BUILD_NUMBER} + --variants linux-x64 --no-pull-enterprise + depends_on: + - initialize + environment: {} + image: grafana/build-container:1.4.8 + name: build-backend-enterprise2 +- commands: + - ./bin/grabpl package --jobs 8 --edition enterprise --build-id ${DRONE_BUILD_NUMBER} + --no-pull-enterprise --sign + depends_on: + - build-plugins + - build-backend + - build-frontend + - build-backend-enterprise2 + - test-backend-enterprise2 + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package +- commands: + - ./e2e/start-server + depends_on: + - package + detach: true + environment: + PACKAGE_FILE: dist/grafana-enterprise-*linux-amd64.tar.gz + PORT: 3001 + RUNDIR: e2e/tmp-grafana-enterprise + image: grafana/build-container:1.4.8 + name: end-to-end-tests-server +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite dashboards-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-dashboards-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite smoke-tests-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-smoke-tests-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite panels-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-panels-suite +- commands: + - apt-get install -y netcat + - ./bin/grabpl e2e-tests --port 3001 --suite various-suite --tries 3 + depends_on: + - package + environment: + HOST: end-to-end-tests-server + image: cypress/included:9.2.0 + name: end-to-end-tests-various-suite +- commands: + - apt-get update + - apt-get install -yq zip + - ls -lah ./e2e + - find ./e2e -type f -name "*.mp4" + - printenv GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY > /tmp/gcpkey_upload_artifacts.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey_upload_artifacts.json + - find ./e2e -type f -name "*spec.ts.mp4" | zip e2e/videos.zip -@ + - gsutil cp e2e/videos.zip gs://$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - export E2E_ARTIFACTS_VIDEO_ZIP=https://storage.googleapis.com/$${E2E_TEST_ARTIFACTS_BUCKET}/${DRONE_BUILD_NUMBER}/artifacts/videos/videos.zip + - 'echo "E2E Test artifacts uploaded to: $${E2E_ARTIFACTS_VIDEO_ZIP}"' + - 'curl -X POST https://api.github.com/repos/${DRONE_REPO}/statuses/${DRONE_COMMIT_SHA} + -H "Authorization: token $${GITHUB_TOKEN}" -d "{\"state\":\"success\",\"target_url\":\"$${E2E_ARTIFACTS_VIDEO_ZIP}\", + \"description\": \"Click on the details to download e2e recording videos\", \"context\": + \"e2e_artifacts\"}"' + depends_on: + - end-to-end-tests-dashboards-suite + - end-to-end-tests-panels-suite + - end-to-end-tests-smoke-tests-suite + - end-to-end-tests-various-suite + environment: + E2E_TEST_ARTIFACTS_BUCKET: releng-pipeline-artifacts-dev + GCP_GRAFANA_UPLOAD_ARTIFACTS_KEY: + from_secret: gcp_upload_artifacts_key + GITHUB_TOKEN: + from_secret: github_token + image: google/cloud-sdk:367.0.0 + name: e2e_tests_artifacts_upload +- commands: + - ls dist/*.tar.gz* + - cp dist/*.tar.gz* packaging/docker/ + depends_on: + - package + image: grafana/build-container:1.4.8 + name: copy-packages-for-docker +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition enterprise --shouldSave + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - printenv GCP_KEY | base64 -d > /tmp/gcpkey.json + - gcloud auth activate-service-account --key-file=/tmp/gcpkey.json + - ./bin/grabpl build-docker --edition enterprise --shouldSave --ubuntu + depends_on: + - copy-packages-for-docker + environment: + GCP_KEY: + from_secret: gcp_key + image: google/cloud-sdk + name: package-docker-images-ubuntu + volumes: + - name: docker + path: /var/run/docker.sock +- commands: + - yarn storybook:build + - ./bin/grabpl verify-storybook + depends_on: + - build-frontend + environment: + NODE_OPTIONS: --max_old_space_size=4096 + image: grafana/build-container:1.4.8 + name: build-storybook +- commands: + - dockerize -wait tcp://redis:6379/0 -timeout 120s + - ./bin/grabpl integration-tests + depends_on: + - initialize + environment: + REDIS_URL: redis://redis:6379/0 + image: grafana/build-container:1.4.8 + name: redis-integration-tests +- commands: + - dockerize -wait tcp://memcached:11211 -timeout 120s + - ./bin/grabpl integration-tests + depends_on: + - initialize + environment: + MEMCACHED_HOSTS: memcached:11211 + image: grafana/build-container:1.4.8 + name: memcached-integration-tests +- commands: + - ./bin/grabpl upload-cdn --edition enterprise --bucket "grafana-static-assets" + depends_on: + - package + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets +- commands: + - ./bin/grabpl upload-packages --edition enterprise --packages-bucket grafana-downloads + depends_on: + - package + - redis-integration-tests + - memcached-integration-tests + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages +- commands: + - ./bin/grabpl package --jobs 8 --edition enterprise2 --build-id ${DRONE_BUILD_NUMBER} + --no-pull-enterprise --variants linux-x64 --sign + depends_on: + - build-plugins + - build-backend + - build-frontend + - build-backend-enterprise2 + - test-backend-enterprise2 + environment: + GITHUB_TOKEN: + from_secret: github_token + GPG_KEY_PASSWORD: + from_secret: gpg_key_password + GPG_PRIV_KEY: + from_secret: gpg_priv_key + GPG_PUB_KEY: + from_secret: gpg_pub_key + GRAFANA_API_KEY: + from_secret: grafana_api_key + image: grafana/build-container:1.4.8 + name: package-enterprise2 +- commands: + - ./bin/grabpl upload-cdn --edition enterprise2 --bucket "grafana-static-assets" + depends_on: + - package-enterprise2 + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-cdn-assets-enterprise2 +- commands: + - ./bin/grabpl upload-packages --edition enterprise2 --packages-bucket grafana-downloads-enterprise2 + depends_on: + - package-enterprise2 + - redis-integration-tests + - memcached-integration-tests + environment: + GCP_GRAFANA_UPLOAD_KEY: + from_secret: gcp_key + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/grafana-ci-deploy:1.3.1 + name: upload-packages-enterprise2 +trigger: + ref: + - refs/heads/v[0-9]* +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +- name: postgres + temp: + medium: memory +- name: mysql + temp: + medium: memory +--- +clone: + disable: true +depends_on: +- enterprise-build-release-branch +image_pull_secrets: +- dockerconfigjson +kind: pipeline +name: enterprise-windows-release-branch +platform: + arch: amd64 + os: windows + version: "1809" +services: [] +steps: +- commands: + - echo $env:DRONE_RUNNER_NAME + image: mcr.microsoft.com/windows:1809 + name: identify-runner +- commands: + - $$ProgressPreference = "SilentlyContinue" + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.7.8/windows/grabpl.exe + -OutFile grabpl.exe + - git clone "https://$$env:GITHUB_TOKEN@github.com/grafana/grafana-enterprise.git" + - cd grafana-enterprise + - git checkout $$env:DRONE_BRANCH + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/ci-wix:0.1.1 + name: clone +- commands: + - cp -r grafana-enterprise C:\App\grafana-enterprise + - rm -r -force grafana-enterprise + - cp grabpl.exe C:\App\grabpl.exe + - rm -force grabpl.exe + - C:\App\grabpl.exe init-enterprise --github-token $$env:GITHUB_TOKEN C:\App\grafana-enterprise + - cp C:\App\grabpl.exe grabpl.exe + depends_on: + - clone + environment: + GITHUB_TOKEN: + from_secret: github_token + image: grafana/ci-wix:0.1.1 + name: initialize +- commands: + - $$gcpKey = $$env:GCP_KEY + - '[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($$gcpKey)) + > gcpkey.json' + - dos2unix gcpkey.json + - gcloud auth activate-service-account --key-file=gcpkey.json + - rm gcpkey.json + - cp C:\App\nssm-2.24.zip . + depends_on: + - initialize + environment: + GCP_KEY: + from_secret: gcp_key + GITHUB_TOKEN: + from_secret: github_token + PRERELEASE_BUCKET: + from_secret: prerelease_bucket + image: grafana/ci-wix:0.1.1 + name: build-windows-installer +trigger: + ref: + - refs/heads/v[0-9]* +type: docker +volumes: +- host: + path: /var/run/docker.sock + name: docker +--- +kind: pipeline +name: scan-grafana/grafana:latest-image +platform: + arch: amd64 + os: linux +steps: +- commands: + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/grafana:latest + image: aquasec/trivy:0.21.0 + name: scan-unkown-low-medium-vulnerabilities +- commands: + - trivy --exit-code 1 --severity HIGH,CRITICAL grafana/grafana:latest + image: aquasec/trivy:0.21.0 + name: scan-high-critical-vulnerabilities +- image: plugins/slack + name: slack-notify-failure + settings: + channel: grafana-backend-ops + template: 'Nightly docker image scan job for grafana/grafana:latest failed: {{build.link}}' + webhook: + from_secret: slack_webhook_backend + when: + status: failure +trigger: + cron: nightly + event: cron +type: docker +--- +kind: pipeline +name: scan-grafana/grafana:main-image +platform: + arch: amd64 + os: linux +steps: +- commands: + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/grafana:main + image: aquasec/trivy:0.21.0 + name: scan-unkown-low-medium-vulnerabilities +- commands: + - trivy --exit-code 1 --severity HIGH,CRITICAL grafana/grafana:main + image: aquasec/trivy:0.21.0 + name: scan-high-critical-vulnerabilities +- image: plugins/slack + name: slack-notify-failure + settings: + channel: grafana-backend-ops + template: 'Nightly docker image scan job for grafana/grafana:main failed: {{build.link}}' + webhook: + from_secret: slack_webhook_backend + when: + status: failure +trigger: + cron: nightly + event: cron +type: docker +--- +kind: pipeline +name: scan-grafana/grafana:latest-ubuntu-image +platform: + arch: amd64 + os: linux +steps: +- commands: + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/grafana:latest-ubuntu + image: aquasec/trivy:0.21.0 + name: scan-unkown-low-medium-vulnerabilities +- commands: + - trivy --exit-code 1 --severity HIGH,CRITICAL grafana/grafana:latest-ubuntu + image: aquasec/trivy:0.21.0 + name: scan-high-critical-vulnerabilities +- image: plugins/slack + name: slack-notify-failure + settings: + channel: grafana-backend-ops + template: 'Nightly docker image scan job for grafana/grafana:latest-ubuntu failed: + {{build.link}}' + webhook: + from_secret: slack_webhook_backend + when: + status: failure +trigger: + cron: nightly + event: cron +type: docker +--- +kind: pipeline +name: scan-grafana/grafana:main-ubuntu-image +platform: + arch: amd64 + os: linux +steps: +- commands: + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/grafana:main-ubuntu + image: aquasec/trivy:0.21.0 + name: scan-unkown-low-medium-vulnerabilities +- commands: + - trivy --exit-code 1 --severity HIGH,CRITICAL grafana/grafana:main-ubuntu + image: aquasec/trivy:0.21.0 + name: scan-high-critical-vulnerabilities +- image: plugins/slack + name: slack-notify-failure + settings: + channel: grafana-backend-ops + template: 'Nightly docker image scan job for grafana/grafana:main-ubuntu failed: + {{build.link}}' + webhook: + from_secret: slack_webhook_backend + when: + status: failure +trigger: + cron: nightly + event: cron +type: docker +--- +get: + name: .dockerconfigjson + path: secret/data/common/gcr +kind: secret +name: dockerconfigjson +--- +get: + name: pat + path: infra/data/ci/github/grafanabot +kind: secret +name: github_token +--- +get: + name: machine-user-token + path: infra/data/ci/drone +kind: secret +name: drone_token +--- +get: + name: bucket + path: infra/data/ci/grafana/prerelease +kind: secret +name: prerelease_bucket +--- +get: + name: credentials.json + path: infra/data/ci/grafana/releng/artifacts-uploader-service-account +kind: secret +name: gcp_upload_artifacts_key +--- +kind: signature +hmac: ca3826510f1b87e8ba9d1cbc5af4ccacfa1117c8bb52f30510e9ce381dc5b2e8 + +... diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..3a8c0c77 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,30 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 120 + +[*.go] +indent_style = tab +indent_size = 4 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{js,ts,tsx,scss}] +quote_type = single + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab +indent_size = 2 + +[*.star] +indent_size = 4 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..4608870d --- /dev/null +++ b/.eslintignore @@ -0,0 +1,14 @@ +node_modules +compiled +build +vendor +devenv +data +dist +e2e/tmp +public/lib/monaco +deployment_tools_config.json + +# Auto-generated localisation files +public/locales/_build/ +public/locales/**/*.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..56189b54 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,28 @@ +{ + "extends": ["@grafana/eslint-config"], + "root": true, + "plugins": ["no-only-tests", "@emotion", "lodash"], + "rules": { + "no-only-tests/no-only-tests": "error", + "react/prop-types": "off", + "@emotion/jsx-import": "error", + "lodash/import-scope": [2, "member"] + }, + "overrides": [ + { + "files": ["packages/grafana-ui/src/components/uPlot/**/*.{ts,tsx}"], + "rules": { + "react-hooks/rules-of-hooks": "off", + "react-hooks/exhaustive-deps": "off" + } + }, + { + "files": ["packages/grafana-ui/src/components/ThemeDemos/**/*.{ts,tsx}"], + "rules": { + "@emotion/jsx-import": "off", + "react/jsx-uses-react": "off", + "react/react-in-jsx-scope": "off" + } + } + ] +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..6313b56c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..dcd27cb3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,150 @@ +# Lines starting with '#' are comments. +# Each line is a file pattern followed by one or more owners. + +# More details are here: https://help.github.com/articles/about-codeowners/ + +# The '*' pattern is global owners. + +# Order is important. The last matching pattern has the most precedence. +# The folders are ordered as follows: + +# In each subsection folders are ordered first by depth, then alphabetically. +# This should make it easy to add new rules without breaking existing ones. + +# Documentation owner: Jita Chatterjee +/docs/ @grafana/docs-squad @pkolyvas +/contribute/ @marcusolsson @grafana/docs-squad @pkolyvas +/docs/sources/developers/plugins/ @marcusolsson @grafana/docs-squad @grafana/plugins-platform-frontend @grafana/plugins-platform-backend +/docs/sources/developers/plugins/backend @marcusolsson @grafana/docs-squad @grafana/plugins-platform-backend +/docs/sources/enterprise/ @osg-grafana @grafana/docs-squad + +# Backend code +*.go @grafana/backend-platform +go.mod @grafana/backend-platform +go.sum @grafana/backend-platform +/.bingo @grafana/backend-platform + +# Continuous Integration +.drone.yml @grafana/grafana-release-eng +.drone.star @grafana/grafana-release-eng +/scripts/drone/ @grafana/grafana-release-eng + +# Cloud Datasources backend code +/pkg/tsdb/cloudwatch @grafana/cloud-datasources @grafana/observability-squad +/pkg/tsdb/azuremonitor @grafana/cloud-datasources +/pkg/tsdb/cloudmonitoring @grafana/cloud-datasources + +# Observability backend code +/pkg/tsdb/influxdb @grafana/observability-squad +/pkg/tsdb/elasticsearch @grafana/observability-squad +/pkg/tsdb/graphite @grafana/observability-squad +/pkg/tsdb/jaeger @grafana/observability-squad +/pkg/tsdb/loki @grafana/observability-squad +/pkg/tsdb/zipkin @grafana/observability-squad +/pkg/tsdb/tempo @grafana/observability-squad + +# Database migrations +/pkg/services/sqlstore/migrations @grafana/backend-platform @grafana/hosted-grafana-team +*_mig.go @grafana/backend-platform @grafana/hosted-grafana-team + +# Grafana live +/pkg/services/live/ @grafana/grafana-edge-squad + +# Unified Alerting +/pkg/services/ngalert @grafana/alerting-squad +/pkg/services/sqlstore/migrations/ualert @grafana/alerting-squad + +# Library Services +/pkg/services/libraryelements @grafana/user-essentials +/pkg/services/librarypanels @grafana/user-essentials + +# Plugins +/pkg/api/pluginproxy @grafana/plugins-platform-backend +/pkg/plugins @grafana/plugins-platform-backend +/pkg/services/datasourceproxy @grafana/plugins-platform-backend +/pkg/services/datasources @grafana/plugins-platform-backend + +# Dashboard previews / crawler (behind feature flag) +/pkg/services/thumbs @grafana/grafana-edge-squad + +# Backend code docs +/contribute/style-guides/backend.md @grafana/backend-platform +/contribute/architecture/backend @grafana/backend-platform +/contribute/engineering/backend @grafana/backend-platform + +/e2e @grafana/user-essentials +/packages @grafana/user-essentials @grafana/plugins-platform-frontend @grafana/grafana-bi-squad +/packages/grafana-e2e-selectors @grafana/user-essentials +/packages/grafana-e2e @grafana/user-essentials +/packages/grafana-toolkit @grafana/plugins-platform-frontend +/packages/grafana-ui/.storybook @grafana/plugins-platform-frontend +/packages/grafana-ui/src/components/DateTimePickers @grafana/grafana-bi-squad +/packages/grafana-ui/src/components/GraphNG @grafana/grafana-bi-squad +/packages/grafana-ui/src/components/Table @grafana/grafana-bi-squad +/packages/grafana-ui/src/components/TimeSeries @grafana/grafana-bi-squad +/packages/grafana-ui/src/components/uPlot @grafana/grafana-bi-squad +/packages/grafana-ui/src/utils/storybook @grafana/plugins-platform-frontend +/packages/jaeger-ui-components/ @grafana/observability-squad +/plugins-bundled @grafana/plugins-platform-frontend +# public folder +/public/app/core/components/TimePicker @grafana/grafana-bi-squad +/public/app/core/components/Layers @grafana/grafana-edge-squad +/public/app/features/canvas/ @grafana/grafana-edge-squad +/public/app/features/dimensions/ @grafana/grafana-edge-squad +/public/app/features/live/ @grafana/grafana-edge-squad +/public/app/features/explore/ @grafana/observability-squad +/public/app/features/plugins @grafana/plugins-platform-frontend +/public/app/plugins/panel/alertlist @grafana/alerting-squad +/public/app/plugins/panel/barchart @grafana/grafana-bi-squad +/public/app/plugins/panel/heatmap @grafana/grafana-bi-squad +/public/app/plugins/panel/histogram @grafana/grafana-bi-squad +/public/app/plugins/panel/nodeGraph @grafana/observability-squad +/public/app/plugins/panel/piechart @grafana/grafana-bi-squad +/public/app/plugins/panel/state-timeline @grafana/grafana-bi-squad +/public/app/plugins/panel/status-history @grafana/grafana-bi-squad +/public/app/plugins/panel/table @grafana/grafana-bi-squad +/public/app/plugins/panel/timeseries @grafana/grafana-bi-squad +/public/app/plugins/panel/geomap @grafana/grafana-edge-squad +/public/app/plugins/panel/canvas @grafana/grafana-edge-squad +/public/app/plugins/panel/candlestick @grafana/grafana-edge-squad +/public/app/plugins/panel/icon @grafana/grafana-edge-squad +/scripts/build/release-packages.sh @grafana/plugins-platform-frontend +/scripts/circle-release-next-packages.sh @grafana/plugins-platform-frontend +/scripts/ci-frontend-metrics.sh @grafana/user-essentials @grafana/plugins-platform-frontend @grafana/grafana-bi-squad +/scripts/ci-reference-docs-build.sh @grafana/plugins-platform-frontend +/scripts/ci-reference-docs-lint.sh @grafana/plugins-platform-frontend +/scripts/grunt @grafana/frontend-ops +/scripts/webpack @grafana/frontend-ops +/scripts/generate-a11y-report.sh @grafana/user-essentials +package.json @grafana/frontend-ops +tsconfig.json @grafana/frontend-ops +lerna.json @grafana/frontend-ops +.babelrc @grafana/frontend-ops +.prettierrc.js @grafana/frontend-ops +.eslintrc @grafana/frontend-ops +.pa11yci.conf.js @grafana/user-essentials +.pa11yci-pr.conf.js @grafana/user-essentials + +# @grafana/ui component documentation +*.mdx @marcusolsson @jessover9000 @grafana/plugins-platform-frontend + +# Core datasources +/public/app/plugins/datasource/cloudwatch @grafana/cloud-datasources @grafana/observability-squad +/public/app/plugins/datasource/elasticsearch @grafana/observability-squad +/public/app/plugins/datasource/grafana-azure-monitor-datasource @grafana/cloud-datasources +/public/app/plugins/datasource/graphite @grafana/observability-squad +/public/app/plugins/datasource/influxdb @grafana/observability-squad +/public/app/plugins/datasource/jaeger @grafana/observability-squad +/public/app/plugins/datasource/loki @grafana/observability-squad +/public/app/plugins/datasource/mssql @grafana/backend-platform +/public/app/plugins/datasource/mysql @grafana/backend-platform +/public/app/plugins/datasource/opentsdb @grafana/backend-platform +/public/app/plugins/datasource/postgres @grafana/backend-platform +/public/app/plugins/datasource/prometheus @grafana/observability-squad +/public/app/plugins/datasource/cloud-monitoring @grafana/cloud-datasources +/public/app/plugins/datasource/zipkin @grafana/observability-squad +/public/app/plugins/datasource/tempo @grafana/observability-squad +/public/app/plugins/datasource/alertmanager @grafana/alerting-squad + +# Cloud middleware +/grafana-mixin/ @grafana/hosted-grafana-team diff --git a/.github/ISSUE_TEMPLATE/1-bug_report.md b/.github/ISSUE_TEMPLATE/1-bug_report.md new file mode 100644 index 00000000..a2fecc38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1-bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Report a bug you found when using Grafana +labels: 'type: bug' +--- + + + +**What happened**: + +**What you expected to happen**: + +**How to reproduce it (as minimally and precisely as possible)**: + +**Anything else we need to know?**: + +**Environment**: +- Grafana version: +- Data source type & version: +- OS Grafana is installed on: +- User OS & Browser: +- Grafana plugins: +- Others: diff --git a/.github/ISSUE_TEMPLATE/2-accessibility.md b/.github/ISSUE_TEMPLATE/2-accessibility.md new file mode 100644 index 00000000..51b3ecc2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2-accessibility.md @@ -0,0 +1,26 @@ +--- +name: Accessibility issue +about: Help make Grafana be better at keyboard navigation, screen-readable and accessible to all. +labels: 'type: accessibility' +--- + + + +**Steps to reproduce**: + +**Actual Result**: + +**Expected Result** + +**Relevant WCAG Criteria:** [#.#.# WCAG Criterion](link to https://www.w3.org/WAI/WCAG21/quickref/?versions=2.0) + +**Environment**: +- Grafana version: +- Data source type & version: +- User OS & Browser: +- Others: diff --git a/.github/ISSUE_TEMPLATE/3-grafana_ui_component.md b/.github/ISSUE_TEMPLATE/3-grafana_ui_component.md new file mode 100644 index 00000000..0ac30e2a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/3-grafana_ui_component.md @@ -0,0 +1,39 @@ +--- +name: '@grafana/ui component request' +about: Suggest a component for the @grafana/ui package +labels: 'area/grafana/ui' +--- + + + +**Why is this component needed**: + +___ + - [ ] Is/could it be used in more than one place in Grafana? + +**Where is/could it be used?**: + +___ +- [ ] Post screenshots possible. +- [ ] It has a single use case. +- [ ] It is/could be used in multiple places. + +**Implementation** (Checklist meant for the person implementing the component) + +- [ ] Component has a story in Storybook. +- [ ] Props and naming follows [our style guide](https://github.com/grafana/grafana/blob/main/contribute/style-guides/frontend.md). +- [ ] It is extendable (rest props are spread, styles with className work, and so on). +- [ ] Uses [theme for spacing, colors, and so on](https://github.com/grafana/grafana/blob/main/contribute/style-guides/themes.md). +- [ ] Works with both light and dark theme. + +**Documentation** + +- [ ] Properties are documented. +- [ ] Use cases are described. +- [ ] Code examples for the different use cases. +- [ ] Dos and don'ts. +- [ ] Styling guidelines, specific color usage (if applicable). diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..d5f2b80c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Feature Request + url: https://github.com/grafana/grafana/discussions/new + about: Discuss ideas for new features of changes + - name: Questions & Help + url: https://community.grafana.com + about: Please ask and answer questions here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..fdd84f2a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,34 @@ + + +**What this PR does / why we need it**: + +**Which issue(s) this PR fixes**: + + + +Fixes # + +**Special notes for your reviewer**: + diff --git a/.github/bot.md b/.github/bot.md new file mode 100644 index 00000000..c08f03d1 --- /dev/null +++ b/.github/bot.md @@ -0,0 +1,30 @@ +# GitHub & grafanabot automation + +The bot is configured via [commands.json](https://github.com/grafana/grafana/blob/main/.github/commands.json) and some other GitHub workflows [workflows](https://github.com/grafana/grafana/tree/main/.github/workflows). + +Comment commands: + +* Write the word `/duplicate #` anywhere in a comment and the bot will add the correct label and standard message. +* Write the word `/needsMoreInfo` anywhere in a comment and the bot will add the correct label and standard message. + +Label commands: + +* Add label `bot/question` the the bot will close with standard question message and add label `type/question` +* Add label `bot/duplicate` the the bot will close with standard duplicate message and add label `type/duplicate` +* Add label `bot/needs more info` for bot to request more info (or use comment command mentioned above) +* Add label `bot/close feature request` for bot to close a feature request with standard message and adds label `not implemented` +* Add label `bot/no new info` for bot to close an issue where we asked for more info but has not received any updates in at least 14 days. + +## Metrics + +Metrics are configured in [metrics-collector.json](https://github.com/grafana/grafana/blob/main/.github/metrics-collector.json) and are also defined in the +[metrics-collector](https://github.com/grafana/grafana-github-actions/blob/main/metrics-collector/index.ts) GitHub action. + +## Backport PR + +To automatically backport a PR to a release branch like v7.3.x add a label named `backport v7.3.x`. The label name should follow the pattern `backport `. Once merged grafanabot will automatically +try to cherry-pick the PR merge commit into that branch and open a PR. It will sync the milestone with the source PR so make sure the source PR also is assigned the milestone for the patch release. If the PR is already merged you can still add this label and trigger the backport automation. + +If there are merge conflicts the bot will write a comment on the source PR saying the cherry-pick failed. In this case you have to do the cherry pick and backport PR manually. + +The backport logic is written [here](https://github.com/grafana/grafana-github-actions/blob/main/backport/backport.ts) diff --git a/.github/commands.json b/.github/commands.json new file mode 100644 index 00000000..27e7bf31 --- /dev/null +++ b/.github/commands.json @@ -0,0 +1,181 @@ +[ + { + "type":"label", + "name":"bot/question", + "addLabel":"type/question", + "removeLabel":"bot/question", + "action":"close", + "comment":"Please ask your question on [community.grafana.com/](https://community.grafana.com/). To avoid having your issue closed in the future, please read our [CONTRIBUTING](https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md) guidelines.\n\nHappy graphing!" + }, + { + "type":"comment", + "name":"duplicate", + "allowUsers":[], + "action":"updateLabels", + "addLabel":"type/duplicate" + }, + { + "type":"label", + "name":"bot/duplicate", + "addLabel":"type/duplicate", + "removeLabel":"bot/duplicate", + "action":"close", + "comment":"Thanks for creating this issue! It looks like this has already been reported by another user. We’ve closed this in favor of the existing one. Please consider adding any details you think is missing to that issue.\n\nTo avoid having your issue closed in the future, please read our [CONTRIBUTING](https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md) guidelines.\n\nHappy graphing!" + }, + { + "type":"comment", + "name":"needsMoreInfo", + "allowUsers":[], + "action":"updateLabels", + "addLabel":"bot/needs more info" + }, + { + "type":"label", + "name":"bot/needs more info", + "action":"updateLabels", + "addLabel":"needs more info", + "removeLabel":"bot/needs more info", + "comment":"Thanks for creating this issue! We think it's missing some basic information. \r\n\r\nFollow the issue template and add additional information that will help us replicate the problem. \r\nFor data visualization issues: \r\n- Query results from the inspect drawer (data tab & query inspector)\r\n- Panel settings can be extracted in the panel inspect drawer JSON tab\r\n\r\nFor dashboard related issues: \r\n- Dashboard JSON can be found in the dashboard settings JSON model view\r\n\r\nFor authentication, provisioning and alerting issues, Grafana server logs are useful. \r\n\r\nHappy graphing!" + }, + { + "type":"label", + "name":"bot/no new info", + "action":"close", + "comment":"We've closed this issue since it needs more information and hasn't had any activity recently. We can re-open it after you you add more information. To avoid having your issue closed in the future, please read our [CONTRIBUTING](https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md) guidelines.\n\nHappy graphing!" + }, + { + "type":"label", + "name":"bot/close feature request", + "action":"close", + "addLabel":"not implemented", + "comment":"This feature request has been open for a long time with few received upvotes or comments, so we are closing it. We're trying to limit open GitHub issues in order to better track planned work and features. \r\n\r\nThis doesn't mean that we'll never ever implement it or that we will never accept a PR for it. A closed issue can still attract upvotes and act as a ticket to track feature demand\/interest. \r\n\r\nThank You to you for taking the time to create this issue!" + }, + { + "type":"label", + "name":"oss-user-essentials", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/78" + } + }, + { + "type":"label", + "name":"area/plugins-catalog", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/76" + } + }, + { + "type":"label", + "name":"type/docs", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/69" + } + }, + { + "type":"label", + "name":"datasource/Azure", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/97" + } + }, + { + "type":"label", + "name":"datasource/CloudWatch", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/97" + } + }, + { + "type":"label", + "name":"datasource/GoogleCloudMonitoring", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/97" + } + }, + { + "type":"label", + "name":"oss-observability", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/54" + } + }, + { + "type":"label", + "name":"datasource/Prometheus", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/54" + } + }, + { + "type":"label", + "name":"datasource/InfluxDB", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/54" + } + }, + { + "type":"label", + "name":"datasource/OpenSearch", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/54" + } + }, + { + "type":"label", + "name":"datasource/Loki", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/54" + } + }, + { + "type":"label", + "name":"datasource/Tempo", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/54" + } + }, + { + "type":"label", + "name":"datasource/Elasticsearch", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/54" + } + }, + { + "type":"label", + "name":"area/explore", + "action":"addToProject", + "addToProject":{ + "url":"https://github.com/orgs/grafana/projects/54" + } + }, + { + "type":"label", + "name":"oss-user-essentials", + "action":"removeFromProject", + "removeFromProject":{ + "url":"https://github.com/orgs/grafana/projects/78" + } + }, + { + "type":"label", + "name":"oss-user-essentials", + "action":"removeFromProject", + "removeFromProject":{ + "url":"https://github.com/grafana/grafana/projects/33" + } + } +] diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..5db8a102 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/metrics-collector.json b/.github/metrics-collector.json new file mode 100644 index 00000000..f3014402 --- /dev/null +++ b/.github/metrics-collector.json @@ -0,0 +1,32 @@ +{ + "queries": [ + { + "name": "type_bug", + "query": "label:\"type/bug\" is:open" + }, + { + "name": "type_docs", + "query": "label:\"type/docs\" is:open" + }, + { + "name": "needs_investigation", + "query": "label:\"needs investigation\" is:open" + }, + { + "name": "needs_more_info", + "query": "label:\"needs more info\" is:open" + }, + { + "name": "unlabeled", + "query": "is:open is:issue no:label" + }, + { + "name": "open_prs", + "query": "is:open is:pr" + }, + { + "name": "milestone_7_4_open", + "query": "is:open is:issue milestone:7.4" + } + ] +} diff --git a/.github/pr-checks.json b/.github/pr-checks.json new file mode 100644 index 00000000..15cc829c --- /dev/null +++ b/.github/pr-checks.json @@ -0,0 +1,9 @@ +[ + { + "type": "check-milestone", + "title": "Milestone Check", + "targetUrl": "https://github.com/grafana/grafana/blob/main/contribute/merge-pull-request.md#assign-a-milestone", + "success": "Milestone set", + "failure": "Milestone not set" + } +] \ No newline at end of file diff --git a/.github/pr-commands.json b/.github/pr-commands.json new file mode 100644 index 00000000..86532bda --- /dev/null +++ b/.github/pr-commands.json @@ -0,0 +1,190 @@ +[ + { + "type": "changedfiles", + "matches": [ + "docs/**/*", + "contribute/**/*" + ], + "action": "updateLabel", + "addLabel": "type/docs" + }, + { + "type": "changedfiles", + "matches": [ + "public/**/*", + "packages/**/*", + "e2e/**/*", + "plugins-bundled/**/*", + "scripts/build/release-packages.sh", + "scripts/circle-release-next-packages.sh", + "scripts/ci-frontend-metrics.sh", + "scripts/grunt/**/*", + "scripts/webpack/**/*", + "package.json", + "tsconfig.json", + "lerna.json", + ".babelrc", + ".prettierrc.js", + ".eslintrc", + "**/*.mdx" + ], + "action": "updateLabel", + "addLabel": "area/frontend" + }, + { + "type": "changedfiles", + "matches": [ + "**/*.go", + "go.mod", + "go.sum", + "contribute/style-guides/backend.md", + "contribute/architecture/backend/**/*", + "scripts/go/**/*" + ], + "action": "updateLabel", + "addLabel": "area/backend" + }, + { + "type": "changedfiles", + "matches": [ + "pkg/services/sqlstore/migrations/**/*", + "**/*_mig.go" + ], + "action": "updateLabel", + "addLabel": "area/backend/db/migration" + }, + { + "type": "changedfiles", + "matches": [ "public/app/features/explore/**/*"], + "action": "updateLabel", + "addLabel": "area/explore" + }, + { + "type": "changedfiles", + "matches": [ + ".circleci/**/*", + "packaging/**/*", + "scripts/build/**/*", + "scripts/*.sh", + "Makefile", + "Dockerfile", + "Dockerfile.ubuntu" + ], + "action": "updateLabel", + "addLabel": "type/build-packaging" + }, + { + "type": "changedfiles", + "matches": [ + "scripts/*.star", + ".drone.star", + ".drone.yml" + ], + "action": "updateLabel", + "addLabel": "type/ci" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/grafana-azure-monitor-datasource/**/*", "pkg/tsdb/azuremonitor/**/*"], + "action": "updateLabel", + "addLabel": "datasource/Azure" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/cloud-monitoring/**/*", "pkg/tsdb/cloudmonitoring/**/*"], + "action": "updateLabel", + "addLabel": "datasource/GoogleCloudMonitoring" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/cloudwatch/**/*", "pkg/tsdb/cloudwatch/**/*"], + "action": "updateLabel", + "addLabel": "datasource/CloudWatch" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/elasticsearch/**/*", "pkg/tsdb/elasticsearch/**/*"], + "action": "updateLabel", + "addLabel": "datasource/Elasticsearch" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/graphite/**/*", "pkg/tsdb/graphite/**/*"], + "action": "updateLabel", + "addLabel": "datasource/Graphite" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/influxdb/**/*", "pkg/tsdb/influx/**/*"], + "action": "updateLabel", + "addLabel": "datasource/InfluxDB" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/jaeger"], + "action": "updateLabel", + "addLabel": "datasource/Jaeger" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/loki/**/*", "pkg/tsdb/loki/**/*"], + "action": "updateLabel", + "addLabel": "datasource/Loki" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/mssql/**/*", "pkg/tsdb/mssql/**/*"], + "action": "updateLabel", + "addLabel": "datasource/MSSQL" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/mysql/**/*", "pkg/tsdb/mysql/**/*"], + "action": "updateLabel", + "addLabel": "datasource/MySQL" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/opentsdb/**/*", "pkg/tsdb/opentsdb/**/*"], + "action": "updateLabel", + "addLabel": "datasource/OpenTSDB" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/postgres/**/*", "pkg/tsdb/postgres/**/*"], + "action": "updateLabel", + "addLabel": "datasource/Postgres" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/prometheus/**/*", "pkg/tsdb/prometheus/**/*"], + "action": "updateLabel", + "addLabel": "datasource/Prometheus" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/tempo/**/*", "pkg/tsdb/tempo/**/*"], + "action": "updateLabel", + "addLabel": "datasource/Tempo" + }, + { + "type": "changedfiles", + "matches": [ "public/app/plugins/datasource/zipkin/**/*"], + "action": "updateLabel", + "addLabel": "datasource/Zipkin" + }, + { + "type": "changedfiles", + "matches": ["public/app/features/variables/**/*", "public/app/features/templating/**/*"], + "action": "updateLabel", + "addLabel": "area/dashboard/templating" + }, + { + "type": "author", + "name": "pr/external", + "notMemberOf": { "org": "grafana" }, + "ignoreList": ["renovate[bot]"], + "action": "updateLabel", + "addLabel": "pr/external" + } +] diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 00000000..e1167c1d --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,47 @@ +{ + "extends": [ + "config:base" + ], + "enabledManagers": ["npm"], + "ignoreDeps": [ + "@types/systemjs", + "@types/d3-force", // we should bump this once we move to esm modules + "@types/d3-interpolate", // we should bump this once we move to esm modules + "@types/d3-scale-chromatic", // we should bump this once we move to esm modules + "@types/react-icons", // jaeger-ui-components is being refactored to use @grafana/ui icons instead + "d3", + "d3-force", // we should bump this once we move to esm modules + "d3-interpolate", // we should bump this once we move to esm modules + "d3-scale-chromatic", // we should bump this once we move to esm modules + "eslint", // wait until `eslint-plugin-react-hooks>4.2.0` is released + "execa", // we should bump this once we move to esm modules + "history", // we should bump this together with react-router-dom + "react-icons", // jaeger-ui-components is being refactored to use @grafana/ui icons instead + "react-router-dom", // we should bump this together with history + "slate", + "slate-plain-serializer", + "systemjs", + "ts-loader", // we should remove ts-loader and use babel-loader instead + "ora" // we should bump this once we move to esm modules + ], + "ignorePaths": ["packages/grafana-toolkit/package.json", "emails/**", "plugins-bundled/**", "**/mocks/**"], + "labels": ["area/frontend", "dependencies"], + "packageRules": [ + { + "matchUpdateTypes": ["patch"], + "extends": ["schedule:monthly"] + } + ], + "patch": { + "enabled": false + }, + "pin": { + "enabled": false + }, + "prConcurrentLimit": 10, + "reviewers": ["team:grafana/frontend-ops"], + "separateMajorMinor": false, + "vulnerabilityAlerts": { + "addLabels": ["area/security"] + } +} diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..701b0b26 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,47 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# General configuration +# Label to use when marking as stale +staleLabel: stale + +# Pull request specific configuration +pulls: + # Number of days of inactivity before an Issue or Pull Request becomes stale + daysUntilStale: 14 + # Number of days of inactivity before a stale Issue or Pull Request is closed. + # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. + daysUntilClose: 30 + # Comment to post when marking as stale. Set to `false` to disable + markComment: > + This pull request has been automatically marked as stale because it has not had + activity in the last 2 weeks. It will be closed in 30 days if no further activity occurs. Please + feel free to give a status update now, ping for review, or re-open when it's ready. + Thank you for your contributions! + # Comment to post when closing a stale Issue or Pull Request. + closeComment: > + This pull request has been automatically closed because it has not had + activity in the last 30 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. + Thank you for your contributions! + # Limit the number of actions per hour, from 1-30. Default is 30 + limitPerRun: 1 + +exemptLabels: + - help wanted + - type/bug + - type/feature-request + - Epic + - no stalebot + +# Issue specific configuration +issues: + limitPerRun: 1 + daysUntilStale: 100000 + daysUntilClose: 100000 + markComment: > + This issue has been automatically marked as stale because it has not had activity in the + last 100 days. It will be closed in the next 100 days if no activity occurs. + Thank you for your contributions. + closeComment: > + This issue has been automatically closed because it has not had activity in the + last month and a half. If this issue is still valid, please ping a maintainer and ask them to check this again. + Thank you for your contributions. diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 00000000..55dc5c8d --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,26 @@ +name: Backport PR Creator +on: + pull_request_target: + types: + - closed + - labeled + +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Run backport + uses: ./actions/backport + with: + metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}} + token: ${{secrets.GH_BOT_ACCESS_TOKEN}} + labelsToAdd: "backport" + title: "[{{base}}] {{originalTitle}}" diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml new file mode 100644 index 00000000..9d83e714 --- /dev/null +++ b/.github/workflows/bump-version.yml @@ -0,0 +1,98 @@ +name: Bump version +on: + workflow_dispatch: + inputs: + version: + required: true + default: '7.x.x' + workflow_call: + inputs: + version_call: + description: Needs to match, exactly, the name of a version + required: true + type: string + secrets: + token: + required: true + metricsWriteAPIKey: + required: true +jobs: + main: + runs-on: ubuntu-latest + steps: + # This is a basic workflow to help you get started with Actions + - uses: actions-ecosystem/action-regex-match@v2.0.2 + if: ${{ github.event.inputs.version != '' }} + id: regex-match + with: + text: ${{ github.event.inputs.version }} + regex: '^(\d+.\d+).\d+(?:-beta.\d+)?$' + - uses: actions-ecosystem/action-regex-match@v2.0.2 + if: ${{ inputs.version_call != '' }} + id: regex-match-version-call + with: + text: ${{ inputs.version_call }} + regex: '^(\d+.\d+).\d+(?:-beta\d+)?$' + - name: Validate input version + if: ${{ steps.regex-match.outputs.match == '' && github.event.inputs.version != '' }} + run: | + echo "The input version format is not correct, please respect:\ + major.minor.patch or major.minor.patch-beta.number format. \ + example: 7.4.3 or 7.4.3-beta.1" + exit 1 + - name: Validate input version call + if: ${{ inputs.version_call != '' && steps.regex-match-version-call.outputs.match == '' }} + run: | + echo "The input version format is not correct, please respect:\ + major.minor.patch or major.minor.patch-beta format. \ + example: 7.4.3 or 7.4.3-beta1" + exit 1 + + - uses: actions/checkout@v2 + + - name: Set intermedia variables + id: intermedia + run: | + echo "::set-output name=short_ref::${GITHUB_REF#refs/*/}" + echo "::set-output name=check_passed::false" + echo "::set-output name=branch_name::v${{steps.regex-match.outputs.group1}}" + echo "::set-output name=branch_exist::$(git ls-remote --heads https://github.com/grafana/grafana.git v${{ steps.regex-match.outputs.group1 }}.x | wc -l)" + + - name: Check input version is aligned with branch(not main) + if: ${{ github.event.inputs.version != '' && steps.intermedia.outputs.branch_exist != '0' && !contains(steps.intermedia.outputs.short_ref, steps.intermedia.outputs.branch_name) }} + run: | + echo " You need to run the workflow on branch v${{steps.regex-match.outputs.group1}}.x + exit 1 + + - name: Check input version is aligned with branch(main) + if: ${{ github.event.inputs.version != '' && steps.intermedia.outputs.branch_exist == '0' && !contains(steps.intermedia.outputs.short_ref, 'main') }} + run: | + echo "When you want to deliver a new new minor version, you might want to create a new branch first \ + with naming convention v[major].[minor].x, and just run the workflow on that branch. \ + Run the workflow on main only when needed" + exit 1 + + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - uses: actions/setup-node@v2.4.1 + with: + node-version: '14' + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Run bump version (manually invoked) + if: ${{ github.event.inputs.version != '' }} + uses: ./actions/bump-version + with: + token: ${{ secrets.GH_BOT_ACCESS_TOKEN }} + metricsWriteAPIKey: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }} + - name: Run bump version (workflow invoked) + if: ${{ inputs.version_call != '' }} + uses: ./actions/bump-version + with: + version_call: ${{ inputs.version_call }} + token: ${{ secrets.token }} + metricsWriteAPIKey: ${{ secrets.metricsWriteAPIKey }} diff --git a/.github/workflows/close-milestone.yml b/.github/workflows/close-milestone.yml new file mode 100644 index 00000000..a495eab7 --- /dev/null +++ b/.github/workflows/close-milestone.yml @@ -0,0 +1,39 @@ +name: Close milestone +on: + workflow_dispatch: + inputs: + version: + required: true + description: Needs to match, exactly, the name of a milestone + workflow_call: + inputs: + version_call: + description: Needs to match, exactly, the name of a milestone + required: true + type: string + secrets: + token: + required: true +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Close milestone (manually invoked) + if: ${{ github.event.inputs.version != '' }} + uses: ./actions/close-milestone + with: + token: ${{ secrets.GH_BOT_ACCESS_TOKEN }} + - name: Close milestone (workflow invoked) + if: ${{ inputs.version_call != '' }} + uses: ./actions/close-milestone + with: + version_call: ${{ inputs.version_call }} + token: ${{ secrets.token }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..034a18f6 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,66 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +name: "CodeQL" + +on: + push: + branches: [main, v1.8.x, v2.0.x, v2.1.x, v2.6.x, v3.0.x, v3.1.x, v4.0.x, v4.1.x, v4.2.x, v4.3.x, v4.4.x, v4.5.x, v4.6.x, v4.7.x, v5.0.x, v5.1.x, v5.2.x, v5.3.x, v5.4.x, v6.0.x, v6.1.x, v6.2.x, v6.3.x, v6.4.x, v6.5.x, v6.6.x, v6.7.x, v7.0.x, v7.1.x, v7.2.x] + pull_request: + # The branches below must be a subset of the branches above + branches: [main] + schedule: + - cron: '0 4 * * 6' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] + language: ['javascript', 'go', 'python'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml new file mode 100644 index 00000000..969c4869 --- /dev/null +++ b/.github/workflows/commands.yml @@ -0,0 +1,25 @@ +name: Run commands when issues are labeled or comments added +on: + issues: + types: [labeled, unlabeled] + issue_comment: + types: [created] + +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Run Commands + uses: ./actions/commands + with: + metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}} + token: ${{secrets.GH_BOT_ACCESS_TOKEN}} + configPath: commands diff --git a/.github/workflows/detect-breaking-changes-build.yml b/.github/workflows/detect-breaking-changes-build.yml new file mode 100644 index 00000000..3554b8af --- /dev/null +++ b/.github/workflows/detect-breaking-changes-build.yml @@ -0,0 +1,54 @@ +name: Levitate / Detect breaking changes + +on: pull_request + +jobs: + build: + name: Detect + runs-on: ubuntu-latest + env: + GITHUB_STEP_NUMBER: 7 + + steps: + - uses: actions/checkout@v2 + + - name: Setup environment + uses: actions/setup-node@v2 + with: + node-version: '16' + + - name: Get link for the Github Action job + id: job + uses: actions/github-script@v5 + with: + script: | + const script = require('./.github/workflows/scripts/pr-get-job-link.js') + await script({github, context, core}) + + - name: Install dependencies + run: yarn install --immutable + + - name: Build packages + run: yarn packages:build + + - name: Detect breaking changes + id: breaking-changes + run: ./scripts/check-breaking-changes.sh + env: + FORCE_COLOR: 3 + GITHUB_JOB_LINK: ${{ steps.job.outputs.link }} + + - name: Persisting the check output + run: | + mkdir -p ./levitate + echo "{ \"exit_code\": ${{ steps.breaking-changes.outputs.is_breaking }}, \"message\": \"${{ steps.breaking-changes.outputs.message }}\", \"job_link\": \"${{ steps.job.outputs.link }}#step:${GITHUB_STEP_NUMBER}:1\" }" > ./levitate/result.json + + - name: Upload check output as artifact + uses: actions/upload-artifact@v2 + with: + name: levitate + path: levitate/ + + - name: Exit + run: exit ${{ steps.breaking-changes.outputs.is_breaking }} + shell: bash diff --git a/.github/workflows/detect-breaking-changes-report.yml b/.github/workflows/detect-breaking-changes-report.yml new file mode 100644 index 00000000..94a64eb5 --- /dev/null +++ b/.github/workflows/detect-breaking-changes-report.yml @@ -0,0 +1,163 @@ +name: Levitate / Report breaking changes + +on: + workflow_run: + workflows: ["Levitate / Detect breaking changes"] + types: [completed] + +jobs: + notify: + name: Report + runs-on: ubuntu-latest + env: + ARTIFACT_FOLDER: '${{ github.workspace }}/tmp' + ARTIFACT_NAME: 'levitate' + + steps: + - uses: actions/checkout@v2 + + - name: 'Download artifact' + uses: actions/github-script@v5 + env: + RUN_ID: ${{ github.event.workflow_run.id }} + with: + script: | + const fs = require('fs'); + + const { owner, repo } = context.repo; + const runId = process.env.RUN_ID; + const artifactName = process.env.ARTIFACT_NAME; + const artifactFolder = process.env.ARTIFACT_FOLDER; + const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner, + repo, + run_id: runId, + }); + const artifact = artifacts.data.artifacts.find(a => a.name === artifactName); + + if (!artifact) { + throw new Error(`Could not find artifact ${ artifactName } in workflow (${ runId })`); + } + + const download = await github.rest.actions.downloadArtifact({ + owner, + repo, + artifact_id: artifact.id, + archive_format: 'zip', + }); + + fs.mkdirSync(artifactFolder, { recursive: true }); + fs.writeFileSync(`${ artifactFolder }/${ artifactName }.zip`, Buffer.from(download.data)); + + - name: Unzip artifact + run: unzip "${ARTIFACT_FOLDER}/${ARTIFACT_NAME}.zip" -d "${ARTIFACT_FOLDER}" + + - name: Parsing levitate result + uses: actions/github-script@v5 + id: levitate-run + with: + script: | + const filePath = `${ process.env.ARTIFACT_FOLDER }/result.json`; + const script = require('./.github/workflows/scripts/json-file-to-job-output.js'); + await script({ core, filePath }); + + - name: Check if "breaking change" label exists + id: does-label-exist + uses: actions/github-script@v5 + env: + PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} + with: + script: | + const { data } = await github.rest.issues.listLabelsOnIssue({ + issue_number: process.env.PR_NUMBER, + owner: context.repo.owner, + repo: context.repo.repo, + }); + const labels = data.map(({ name }) => name); + const doesExist = labels.includes('breaking change'); + + return doesExist ? 1 : 0; + + - name: Comment on PR + if: ${{ steps.levitate-run.outputs.exit_code == 1 }} + uses: marocchino/sticky-pull-request-comment@v2 + with: + number: ${{ github.event.workflow_run.pull_requests[0].number }} + message: | + ⚠️   **Possible breaking changes** + + _(Open the links below in a new tab to go to the correct steps)_ + + ${{ steps.levitate-run.outputs.message }} + + [Check console output](${{ steps.levitate-run.outputs.job_link }}) + + - name: Remove comment on PR + if: ${{ steps.levitate-run.outputs.exit_code == 0 }} + uses: marocchino/sticky-pull-request-comment@v2 + with: + number: ${{ github.event.workflow_run.pull_requests[0].number }} + delete: true + + + - name: Add "breaking change" label + if: ${{ steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0 }} + uses: actions/github-script@v5 + env: + PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} + with: + script: | + await github.rest.issues.addLabels({ + issue_number: process.env.PR_NUMBER, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['breaking change'] + }) + + - name: Remove "breaking change" label + if: ${{ steps.levitate-run.outputs.exit_code == 0 && steps.does-label-exist.outputs.result == 1 }} + uses: actions/github-script@v5 + env: + PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} + with: + script: | + await github.rest.issues.removeLabel({ + issue_number: process.env.PR_NUMBER, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'breaking change' + }) + + # This is very weird, the actual request goes through (comes back with a 201), but does not assign the team. + # Related issue: https://github.com/renovatebot/renovate/issues/1908 + - name: Add "grafana/plugins-platform-frontend" as a reviewer + if: ${{ steps.levitate-run.outputs.exit_code == 1 }} + uses: actions/github-script@v5 + env: + PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} + with: + script: | + await github.rest.pulls.requestReviewers({ + pull_number: process.env.PR_NUMBER, + owner: context.repo.owner, + repo: context.repo.repo, + reviewers: [], + team_reviewers: ['grafana/plugins-platform-frontend'] + }); + + - name: Remove "grafana/plugins-platform-frontend" from the list of reviewers + if: ${{ steps.levitate-run.outputs.exit_code == 0 }} + uses: actions/github-script@v5 + env: + PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} + with: + script: | + await github.rest.pulls.removeRequestedReviewers({ + pull_number: process.env.PR_NUMBER, + owner: context.repo.owner, + repo: context.repo.repo, + reviewers: [], + team_reviewers: ['grafana/plugins-platform-frontend'] + }); + + diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml new file mode 100644 index 00000000..9f1f1fe3 --- /dev/null +++ b/.github/workflows/github-release.yml @@ -0,0 +1,24 @@ +name: Create or update GitHub release +on: + workflow_dispatch: + inputs: + version: + required: true + description: Needs to match, exactly, the name of a milestone (NO v prefix) +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Run github release action + uses: ./actions/github-release + with: + token: ${{secrets.GH_BOT_ACCESS_TOKEN}} + metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}} diff --git a/.github/workflows/metrics-collector.yml b/.github/workflows/metrics-collector.yml new file mode 100644 index 00000000..84dec4e2 --- /dev/null +++ b/.github/workflows/metrics-collector.yml @@ -0,0 +1,35 @@ +# +# When triggered by the cron job it will also collect metrics for: +# * number of issues without label +# * number of issues with "needs more info" +# * number of issues with "needs investigation" +# * number of issues with label type/bug +# * number of open issues in current milestone +# +# https://github.com/grafana/grafana-github-actions/blob/main/metrics-collector/index.ts +# +name: Github issue metrics collection +on: + schedule: + - cron: "*/10 * * * *" + issues: + types: [opened, closed] + +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Run metrics collector + uses: ./actions/metrics-collector + with: + metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}} + token: ${{secrets.GH_BOT_ACCESS_TOKEN}} + configPath: "metrics-collector" diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml new file mode 100644 index 00000000..6d0a4079 --- /dev/null +++ b/.github/workflows/pr-checks.yml @@ -0,0 +1,28 @@ +name: PR Checks +on: + pull_request_target: + types: + - opened + - synchronize + issues: + types: + - milestoned + - demilestoned + +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Run PR Checks + uses: ./actions/pr-checks + with: + token: ${{secrets.GITHUB_TOKEN}} + configPath: pr-checks diff --git a/.github/workflows/pr-commands-closed.yml b/.github/workflows/pr-commands-closed.yml new file mode 100644 index 00000000..bc179127 --- /dev/null +++ b/.github/workflows/pr-commands-closed.yml @@ -0,0 +1,17 @@ +name: Run when PRs are closed +on: + pull_request: + types: + - closed + +jobs: + close_job: + # this job will only run if the PR has been closed without being merged + if: github.event.pull_request.merged == false + runs-on: ubuntu-latest + steps: + - run: | + echo PR #${{ github.event.number }} has been closed without being merged, removing milestone. + gh pr edit ${{ github.event.number }} --milestone "" --repo $GITHUB_REPOSITORY + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/pr-commands.yml b/.github/workflows/pr-commands.yml new file mode 100644 index 00000000..cd115987 --- /dev/null +++ b/.github/workflows/pr-commands.yml @@ -0,0 +1,25 @@ +name: PR automation +on: + pull_request_target: + types: + - opened + - synchronize + +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Run Commands + uses: ./actions/commands + with: + metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}} + token: ${{secrets.GH_BOT_ACCESS_TOKEN}} + configPath: pr-commands diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 00000000..ed4c15a2 --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,37 @@ +name: Prepare release +on: + workflow_dispatch: + inputs: + version_input: + description: 'The version to be released please respect: major.minor.patch or major.minor.patch-beta format. example: 7.4.3 or 7.4.3-beta1' + required: true +jobs: + call-remove-milestone: + uses: grafana/grafana/.github/workflows/remove-milestone.yml@main + with: + version_call: ${{ github.event.inputs.version_input }} + secrets: + token: ${{ secrets.GH_BOT_ACCESS_TOKEN }} + call-close-milestone: + uses: grafana/grafana/.github/workflows/close-milestone.yml@main + with: + version_call: ${{ github.event.inputs.version_input }} + secrets: + token: ${{ secrets.GH_BOT_ACCESS_TOKEN }} + needs: call-remove-milestone + call-bump-version: + uses: grafana/grafana/.github/workflows/bump-version.yml@main + with: + version_call: ${{ github.event.inputs.version_input }} + secrets: + token: ${{ secrets.GH_BOT_ACCESS_TOKEN }} + metricsWriteAPIKey: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }} + needs: call-close-milestone + call-update-changelog: + uses: grafana/grafana/.github/workflows/update-changelog.yml@main + with: + version_call: ${{ github.event.inputs.version_input }} + secrets: + token: ${{ secrets.GH_BOT_ACCESS_TOKEN }} + metricsWriteAPIKey: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }} + needs: call-bump-version diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..1bf64485 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,49 @@ +name: publish_docs + +on: + push: + branches: + - main + paths: + - 'docs/sources/**' + - 'packages/grafana-*/**' + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - run: git clone --single-branch --no-tags --depth 1 -b master https://grafanabot:${{ secrets.GH_BOT_ACCESS_TOKEN }}@github.com/grafana/website-sync ./.github/actions/website-sync + - name: generate-packages-docs + uses: actions/setup-node@v2.4.1 + id: generate-docs + with: + node-version: '14' + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn config get cacheFolder)" + - uses: actions/cache@v2.1.6 + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + yarn- + - run: yarn install --immutable + - run: ./scripts/ci-reference-docs-build.sh + - name: publish-to-git + uses: ./.github/actions/website-sync + id: publish + with: + repository: grafana/website + branch: master + host: github.com + github_pat: '${{ secrets.GH_BOT_ACCESS_TOKEN }}' + source_folder: docs/sources + target_folder: content/docs/grafana/next + allow_no_changes: 'true' + - shell: bash + run: | + test -n "${{ steps.publish.outputs.commit_hash }}" + test -n "${{ steps.publish.outputs.working_directory }}" diff --git a/.github/workflows/remove-milestone.yml b/.github/workflows/remove-milestone.yml new file mode 100644 index 00000000..ac2504a4 --- /dev/null +++ b/.github/workflows/remove-milestone.yml @@ -0,0 +1,39 @@ +name: Remove milestone +on: + workflow_dispatch: + inputs: + version: + required: true + description: Needs to match, exactly, the name of a milestone + workflow_call: + inputs: + version_call: + description: Needs to match, exactly, the name of a milestone + required: true + type: string + secrets: + token: + required: true +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Remove milestone from open issues (manually invoked) + if: ${{ github.event.inputs.version != '' }} + uses: ./actions/remove-milestone + with: + token: ${{ secrets.GH_BOT_ACCESS_TOKEN }} + - name: Remove milestone from open issues (workflow invoked) + if: ${{ inputs.version_call != '' }} + uses: ./actions/remove-milestone + with: + version_call: ${{ inputs.version_call }} + token: ${{ secrets.token }} diff --git a/.github/workflows/scripts/json-file-to-job-output.js b/.github/workflows/scripts/json-file-to-job-output.js new file mode 100644 index 00000000..0f6dd1e6 --- /dev/null +++ b/.github/workflows/scripts/json-file-to-job-output.js @@ -0,0 +1,27 @@ +module.exports = async ({ core, filePath }) => { + try { + const fs = require('fs'); + const content = await readFile(fs, filePath); + const result = JSON.parse(content); + + core.startGroup('Parsing json file...'); + + for (const property in result) { + core.info(`${property} <- ${result[property]}`); + core.setOutput(property, result[property]); + } + + core.endGroup(); + } catch (error) { + core.restFailed(error.message); + } +} + +async function readFile(fs, path) { + return new Promise((resolve, reject) => { + fs.readFile(path, (error, data) => { + if (error) return reject(error); + return resolve(data); + }); + }); +} \ No newline at end of file diff --git a/.github/workflows/scripts/pr-get-job-link.js b/.github/workflows/scripts/pr-get-job-link.js new file mode 100644 index 00000000..a4e6bc2f --- /dev/null +++ b/.github/workflows/scripts/pr-get-job-link.js @@ -0,0 +1,9 @@ + +module.exports = async ({ github, context, core }) => { + const { owner, repo } = context.repo; + const url = `https://api.github.com/repos/${owner}/${repo}/actions/runs/${context.runId}/jobs` + const result = await github.request(url) + const link = `https://github.com/grafana/grafana/runs/${result.data.jobs[0].id}?check_suite_focus=true`; + + core.setOutput('link', link); +} \ No newline at end of file diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml new file mode 100644 index 00000000..9ea0da23 --- /dev/null +++ b/.github/workflows/update-changelog.yml @@ -0,0 +1,43 @@ +name: Update changelog +on: + workflow_dispatch: + inputs: + version: + required: true + description: Needs to match, exactly, the name of a milestone + workflow_call: + inputs: + version_call: + description: Needs to match, exactly, the name of a milestone + required: true + type: string + secrets: + token: + required: true + metricsWriteAPIKey: + required: true +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout Actions + uses: actions/checkout@v2 + with: + repository: "grafana/grafana-github-actions" + path: ./actions + ref: main + - name: Install Actions + run: npm install --production --prefix ./actions + - name: Run update changelog (manually invoked) + if: ${{ github.event.inputs.version != '' }} + uses: ./actions/update-changelog + with: + token: ${{ secrets.GH_BOT_ACCESS_TOKEN }} + metricsWriteAPIKey: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }} + - name: Run update changelog (workflow invoked) + if: ${{ inputs.version_call != '' }} + uses: ./actions/update-changelog + with: + version_call: ${{ inputs.version_call }} + token: ${{ secrets.token }} + metricsWriteAPIKey: ${{ secrets.metricsWriteAPIKey }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b1e2b273 --- /dev/null +++ b/.gitignore @@ -0,0 +1,158 @@ +node_modules +npm-debug.log +yarn-error.log +coverage/ +.aws-config.json +awsconfig +/.awcache +/dist +/public/build +public/dist/tsconfig.tsbuildinfo +/public/views/index.html +/public/views/error.html +/emails/dist +/reports +/e2e/tmp +vendor/ +/docs/menu.yaml +/requests + +# Yarn +.yarn/* +!.yarn/patches +!.yarn/releases +!.yarn/plugins +!.yarn/sdks +!.yarn/versions +# we temporarily commit this file because yarn downloading it +# somehow produces different checksum values +!.yarn/cache/pa11y-ci-https-1e9675e9e1-668c9119bd.zip +.pnp.* + +# Enterprise emails +/emails/templates/enterprise_* +/public/emails/enterprise_* + +# Enterprise reporting fonts +/public/fonts/dejavu + +# Enterprise devenv +/devenv/docker/blocks/grafana-enterprise + +/tmp +tools/phantomjs/phantomjs +tools/phantomjs/phantomjs.exe +profile.out +coverage.txt + +docs/AWS_S3_BUCKET +docs/GIT_BRANCH +docs/GITCOMMIT +docs/changed-files + +# locally required config files +public/css/*.min.css + +# Editor junk +*.sublime-workspace +*.swp +.idea/ +*.iml +*.tmp +.DS_Store +.vscode/ +!.vscode/launch.json +.vs/ +.eslintcache +.stylelintcache + +/data/* +/bin/* + +# devenv +/devenv/docker-compose.yaml +/devenv/.env + +conf/custom.ini +/conf/provisioning/**/custom.yaml +/conf/provisioning/**/dev.yaml +/conf/ldap_dev.toml +/conf/ldap_freeipa.toml +profile.cov +/grafana +/local +.notouch +/Makefile.local +/pkg/cmd/grafana-cli/grafana-cli +/pkg/cmd/grafana-server/grafana-server +/pkg/cmd/grafana-server/debug +/pkg/extensions/* +/pkg/server/wireexts_enterprise.go +/pkg/cmd/grafana-cli/runner/wireexts_enterprise.go +!/pkg/extensions/main.go +/public/app/extensions +debug.test +/examples/*/dist +/packaging/**/*.rpm +/packaging/**/*.deb +/packaging/**/*.tar.gz +/packaging/**/*.tar.gz.sha256 + +# Ignore OSX indexing +.DS_Store + +/vendor/**/*.py +/vendor/**/*.xml +/vendor/**/*.yml +/vendor/**/*_test.go +/vendor/**/.editorconfig +*.orig + +/devenv/bulk-dashboards/*.json +/devenv/bulk_alerting_dashboards/*.json +/devenv/datasources_bulk.yaml +/devenv/bulk_alerting_dashboards/bulk_alerting_datasources.yaml + +/scripts/build/release_publisher/release_publisher +*.patch + +# Ignoring frontend packages specifics +/packages/**/dist +/packages/**/compiled +/packages/**/.rpt2_cache +/packages/**/tsdoc-metadata.json + +# Ignore go local build dependencies +/scripts/go/bin/** + +# Ignore compilation stats from `yarn stats` +compilation-stats.json + +# e2e tests +/packages/grafana-e2e/cypress/screenshots +/packages/grafana-e2e/cypress/videos +/packages/grafana-e2e/cypress/logs +/e2e/server.log +/e2e/**/screenshots +!/e2e/**/screenshots/expected/* +/e2e/**/videos/* + +# a11y tests +/pa11y-ci-results.json +/pa11y-ci-report + +# report dumping the whole system env +/report.*.json + +# auto generated frontend docs +/docs/sources/packages_api + +# auto generated Go files +*_gen.go + +# Auto-generated localisation files +public/locales/_build/ +public/locales/**/*.js + +deployment_tools_config.json + diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..aad24318 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +yarn run precommit diff --git a/.linguirc b/.linguirc new file mode 100644 index 00000000..383d2fae --- /dev/null +++ b/.linguirc @@ -0,0 +1,27 @@ +{ + "locales": [ + "en", + "fr", + "es" + ], + "catalogs": [ + { + "path": "public/locales/{locale}/messages", + "include": [ + "public/app" + ], + "exclude": [ + "**/node_modules/**", + "public/app/plugins" + ] + } + ], + "fallbackLocales": { + "default": "en" + }, + "sourceLocale": "en", + "format": "po", + "formatOptions": { + "lineNumbers": false + } +} diff --git a/.pa11yci-pr.conf.js b/.pa11yci-pr.conf.js new file mode 100644 index 00000000..dc01c785 --- /dev/null +++ b/.pa11yci-pr.conf.js @@ -0,0 +1,123 @@ +var config = { + defaults: { + concurrency: 1, + runners: ['axe'], + useIncognitoBrowserContext: false, + chromeLaunchConfig: { + args: ['--no-sandbox'], + }, + // see https://github.com/grafana/grafana/pull/41693#issuecomment-979921463 for context + // on why we're ignoring singleValue/react-select-*-placeholder elements + hideElements: '#updateVersion, [class*="-singleValue"], [id^="react-select-"][id$="-placeholder"]', + }, + + urls: [ + { + url: '${HOST}/login', + wait: 500, + rootElement: '.main-view', + threshold: 12, + }, + { + url: '${HOST}/login', + wait: 500, + actions: [ + "wait for element input[name='user'] to be added", + "set field input[name='user'] to admin", + "set field input[name='password'] to admin", + "click element button[aria-label='Login button']", + "wait for element [aria-label='Skip change password button'] to be visible", + ], + threshold: 13, + rootElement: '.main-view', + }, + { + url: '${HOST}/?orgId=1', + wait: 500, + threshold: 0, + }, + { + url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=settings', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/?orgId=1&search=open', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/alerting/list', + wait: 500, + rootElement: '.main-view', + // the unified alerting promotion alert's content contrast is too low + // see https://github.com/grafana/grafana/pull/41829 + threshold: 5, + }, + { + url: '${HOST}/datasources', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/org/users', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/org/teams', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/plugins', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/org', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/org/apikeys', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + { + url: '${HOST}/dashboards', + wait: 500, + rootElement: '.main-view', + threshold: 0, + }, + ], +}; + +function myPa11yCiConfiguration(urls, defaults) { + const HOST_SERVER = process.env.HOST || 'localhost'; + const PORT_SERVER = process.env.PORT || '3001'; + for (var idx = 0; idx < urls.length; idx++) { + urls[idx] = { ...urls[idx], url: urls[idx].url.replace('${HOST}', `${HOST_SERVER}:${PORT_SERVER}`) }; + } + + return { + defaults: defaults, + urls: urls, + }; +} + +module.exports = myPa11yCiConfiguration(config.urls, config.defaults); diff --git a/.pa11yci.conf.js b/.pa11yci.conf.js new file mode 100644 index 00000000..b2fbf427 --- /dev/null +++ b/.pa11yci.conf.js @@ -0,0 +1,106 @@ +var config = { + defaults: { + concurrency: 1, + runners: ['axe'], + useIncognitoBrowserContext: false, + chromeLaunchConfig: { + args: ['--no-sandbox'], + }, + // see https://github.com/grafana/grafana/pull/41693#issuecomment-979921463 for context + // on why we're ignoring singleValue/react-select-*-placeholder elements + hideElements: '#updateVersion, [class*="-singleValue"], [id^="react-select-"][id$="-placeholder"]', + }, + + urls: [ + { + url: '${HOST}/login', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/login', //skip password and login + actions: [ + "wait for element input[name='user'] to be added", + "set field input[name='user'] to admin", + "set field input[name='password'] to admin", + "click element button[aria-label='Login button']", + "wait for element [aria-label='Skip change password button'] to be visible", + ], + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/?orgId=1', + wait: 500, + }, + { + url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=settings', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/?orgId=1&search=open', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/alerting/list', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/datasources', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/org/users', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/org/teams', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/plugins', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/org', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/org/apikeys', + wait: 500, + rootElement: '.main-view', + }, + { + url: '${HOST}/dashboards', + wait: 500, + rootElement: '.main-view', + }, + ], +}; + +function myPa11yCiConfiguration(urls, defaults) { + const HOST_SERVER = process.env.HOST || 'localhost'; + const PORT_SERVER = process.env.PORT || '3001'; + for (var idx = 0; idx < urls.length; idx++) { + urls[idx] = { ...urls[idx], url: urls[idx].url.replace('${HOST}', `${HOST_SERVER}:${PORT_SERVER}`) }; + } + return { + defaults: defaults, + urls: urls, + }; +} + +module.exports = myPa11yCiConfiguration(config.urls, config.defaults); diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..9f8fae45 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,13 @@ +.git +.github +dist/ +pkg/ +node_modules +public/vendor/ +vendor/ +/data/ +e2e/tmp +public/build/ +public/sass/*.generated.scss +devenv/ +public/lib/monaco diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..c14684b0 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,3 @@ +module.exports = { + ...require('@grafana/toolkit/src/config/prettier.plugin.config.json'), +}; diff --git a/.vim/coc-settings.json b/.vim/coc-settings.json new file mode 100644 index 00000000..28b790db --- /dev/null +++ b/.vim/coc-settings.json @@ -0,0 +1,6 @@ +{ + "eslint.packageManager": "yarn", + "eslint.nodePath": ".yarn/sdks", + "workspace.workspaceFolderCheckCwd": false, + "tsserver.tsdk": ".yarn/sdks/typescript/lib" +} diff --git a/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs b/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs new file mode 100644 index 00000000..f55248f9 --- /dev/null +++ b/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs @@ -0,0 +1,546 @@ +/* eslint-disable */ +//prettier-ignore +module.exports = { +name: "@yarnpkg/plugin-interactive-tools", +factory: function (require) { +var plugin=(()=>{var ZP=Object.create,Pg=Object.defineProperty,$P=Object.defineProperties,eI=Object.getOwnPropertyDescriptor,tI=Object.getOwnPropertyDescriptors,nI=Object.getOwnPropertyNames,L_=Object.getOwnPropertySymbols,rI=Object.getPrototypeOf,nD=Object.prototype.hasOwnProperty,lS=Object.prototype.propertyIsEnumerable;var sS=(i,o,a)=>o in i?Pg(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a,Ht=(i,o)=>{for(var a in o||(o={}))nD.call(o,a)&&sS(i,a,o[a]);if(L_)for(var a of L_(o))lS.call(o,a)&&sS(i,a,o[a]);return i},Zr=(i,o)=>$P(i,tI(o)),iI=i=>Pg(i,"__esModule",{value:!0});var wl=(i,o)=>{var a={};for(var c in i)nD.call(i,c)&&o.indexOf(c)<0&&(a[c]=i[c]);if(i!=null&&L_)for(var c of L_(i))o.indexOf(c)<0&&lS.call(i,c)&&(a[c]=i[c]);return a};var Ke=(i,o)=>()=>(o||i((o={exports:{}}).exports,o),o.exports),uI=(i,o)=>{for(var a in o)Pg(i,a,{get:o[a],enumerable:!0})},oI=(i,o,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let c of nI(o))!nD.call(i,c)&&c!=="default"&&Pg(i,c,{get:()=>o[c],enumerable:!(a=eI(o,c))||a.enumerable});return i},ou=i=>oI(iI(Pg(i!=null?ZP(rI(i)):{},"default",i&&i.__esModule&&"default"in i?{get:()=>i.default,enumerable:!0}:{value:i,enumerable:!0})),i);var Ig=Ke((mW,aS)=>{"use strict";var fS=Object.getOwnPropertySymbols,lI=Object.prototype.hasOwnProperty,sI=Object.prototype.propertyIsEnumerable;function aI(i){if(i==null)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(i)}function fI(){try{if(!Object.assign)return!1;var i=new String("abc");if(i[5]="de",Object.getOwnPropertyNames(i)[0]==="5")return!1;for(var o={},a=0;a<10;a++)o["_"+String.fromCharCode(a)]=a;var c=Object.getOwnPropertyNames(o).map(function(t){return o[t]});if(c.join("")!=="0123456789")return!1;var _={};return"abcdefghijklmnopqrst".split("").forEach(function(t){_[t]=t}),Object.keys(Object.assign({},_)).join("")==="abcdefghijklmnopqrst"}catch(t){return!1}}aS.exports=fI()?Object.assign:function(i,o){for(var a,c=aI(i),_,t=1;t{"use strict";var rD=Ig(),$f=typeof Symbol=="function"&&Symbol.for,bg=$f?Symbol.for("react.element"):60103,cI=$f?Symbol.for("react.portal"):60106,dI=$f?Symbol.for("react.fragment"):60107,pI=$f?Symbol.for("react.strict_mode"):60108,hI=$f?Symbol.for("react.profiler"):60114,vI=$f?Symbol.for("react.provider"):60109,mI=$f?Symbol.for("react.context"):60110,gI=$f?Symbol.for("react.forward_ref"):60112,yI=$f?Symbol.for("react.suspense"):60113,_I=$f?Symbol.for("react.memo"):60115,EI=$f?Symbol.for("react.lazy"):60116,cS=typeof Symbol=="function"&&Symbol.iterator;function Bg(i){for(var o="https://reactjs.org/docs/error-decoder.html?invariant="+i,a=1;aN_.length&&N_.push(i)}function sD(i,o,a,c){var _=typeof i;(_==="undefined"||_==="boolean")&&(i=null);var t=!1;if(i===null)t=!0;else switch(_){case"string":case"number":t=!0;break;case"object":switch(i.$$typeof){case bg:case cI:t=!0}}if(t)return a(c,i,o===""?"."+aD(i,0):o),1;if(t=0,o=o===""?".":o+":",Array.isArray(i))for(var O=0;O{"use strict";var xI="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";SS.exports=xI});var pD=Ke((_W,CS)=>{"use strict";var dD=function(){};process.env.NODE_ENV!=="production"&&(xS=TS(),F_={},AS=Function.call.bind(Object.prototype.hasOwnProperty),dD=function(i){var o="Warning: "+i;typeof console!="undefined"&&console.error(o);try{throw new Error(o)}catch(a){}});var xS,F_,AS;function RS(i,o,a,c,_){if(process.env.NODE_ENV!=="production"){for(var t in i)if(AS(i,t)){var O;try{if(typeof i[t]!="function"){var N=Error((c||"React class")+": "+a+" type `"+t+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof i[t]+"`.");throw N.name="Invariant Violation",N}O=i[t](o,t,c,a,null,xS)}catch(T){O=T}if(O&&!(O instanceof Error)&&dD((c||"React class")+": type specification of "+a+" `"+t+"` is invalid; the type checker function must return `null` or an `Error` but returned a "+typeof O+". You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument)."),O instanceof Error&&!(O.message in F_)){F_[O.message]=!0;var M=_?_():"";dD("Failed "+a+" type: "+O.message+(M!=null?M:""))}}}}RS.resetWarningCache=function(){process.env.NODE_ENV!=="production"&&(F_={})};CS.exports=RS});var OS=Ke(Eu=>{"use strict";process.env.NODE_ENV!=="production"&&function(){"use strict";var i=Ig(),o=pD(),a="16.13.1",c=typeof Symbol=="function"&&Symbol.for,_=c?Symbol.for("react.element"):60103,t=c?Symbol.for("react.portal"):60106,O=c?Symbol.for("react.fragment"):60107,N=c?Symbol.for("react.strict_mode"):60108,M=c?Symbol.for("react.profiler"):60114,T=c?Symbol.for("react.provider"):60109,B=c?Symbol.for("react.context"):60110,H=c?Symbol.for("react.concurrent_mode"):60111,q=c?Symbol.for("react.forward_ref"):60112,ne=c?Symbol.for("react.suspense"):60113,m=c?Symbol.for("react.suspense_list"):60120,he=c?Symbol.for("react.memo"):60115,De=c?Symbol.for("react.lazy"):60116,se=c?Symbol.for("react.block"):60121,fe=c?Symbol.for("react.fundamental"):60117,_e=c?Symbol.for("react.responder"):60118,ce=c?Symbol.for("react.scope"):60119,me=typeof Symbol=="function"&&Symbol.iterator,ie="@@iterator";function Oe(Q){if(Q===null||typeof Q!="object")return null;var we=me&&Q[me]||Q[ie];return typeof we=="function"?we:null}var Ue={current:null},je={suspense:null},at={current:null},Dt=/^(.*)[\\\/]/;function Qe(Q,we,Ne){var Le="";if(we){var pt=we.fileName,Yn=pt.replace(Dt,"");if(/^index\./.test(Yn)){var Cn=pt.match(Dt);if(Cn){var cr=Cn[1];if(cr){var Si=cr.replace(Dt,"");Yn=Si+"/"+Yn}}}Le=" (at "+Yn+":"+we.lineNumber+")"}else Ne&&(Le=" (created by "+Ne+")");return` + in `+(Q||"Unknown")+Le}var ut=1;function Ve(Q){return Q._status===ut?Q._result:null}function It(Q,we,Ne){var Le=we.displayName||we.name||"";return Q.displayName||(Le!==""?Ne+"("+Le+")":Ne)}function Xt(Q){if(Q==null)return null;if(typeof Q.tag=="number"&&dt("Received an unexpected object in getComponentName(). This is likely a bug in React. Please file an issue."),typeof Q=="function")return Q.displayName||Q.name||null;if(typeof Q=="string")return Q;switch(Q){case O:return"Fragment";case t:return"Portal";case M:return"Profiler";case N:return"StrictMode";case ne:return"Suspense";case m:return"SuspenseList"}if(typeof Q=="object")switch(Q.$$typeof){case B:return"Context.Consumer";case T:return"Context.Provider";case q:return It(Q,Q.render,"ForwardRef");case he:return Xt(Q.type);case se:return Xt(Q.render);case De:{var we=Q,Ne=Ve(we);if(Ne)return Xt(Ne);break}}return null}var rt={},X=null;function de(Q){X=Q}rt.getCurrentStack=null,rt.getStackAddendum=function(){var Q="";if(X){var we=Xt(X.type),Ne=X._owner;Q+=Qe(we,X._source,Ne&&Xt(Ne.type))}var Le=rt.getCurrentStack;return Le&&(Q+=Le()||""),Q};var Ce={current:!1},oe={ReactCurrentDispatcher:Ue,ReactCurrentBatchConfig:je,ReactCurrentOwner:at,IsSomeRendererActing:Ce,assign:i};i(oe,{ReactDebugCurrentFrame:rt,ReactComponentTreeHook:{}});function He(Q){{for(var we=arguments.length,Ne=new Array(we>1?we-1:0),Le=1;Le1?we-1:0),Le=1;Le0&&typeof Ne[Ne.length-1]=="string"&&Ne[Ne.length-1].indexOf(` + in`)===0;if(!Le){var pt=oe.ReactDebugCurrentFrame,Yn=pt.getStackAddendum();Yn!==""&&(we+="%s",Ne=Ne.concat([Yn]))}var Cn=Ne.map(function(Mu){return""+Mu});Cn.unshift("Warning: "+we),Function.prototype.apply.call(console[Q],console,Cn);try{var cr=0,Si="Warning: "+we.replace(/%s/g,function(){return Ne[cr++]});throw new Error(Si)}catch(Mu){}}}var nn={};function an(Q,we){{var Ne=Q.constructor,Le=Ne&&(Ne.displayName||Ne.name)||"ReactClass",pt=Le+"."+we;if(nn[pt])return;dt("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",we,Le),nn[pt]=!0}}var Mn={isMounted:function(Q){return!1},enqueueForceUpdate:function(Q,we,Ne){an(Q,"forceUpdate")},enqueueReplaceState:function(Q,we,Ne,Le){an(Q,"replaceState")},enqueueSetState:function(Q,we,Ne,Le){an(Q,"setState")}},lr={};Object.freeze(lr);function ln(Q,we,Ne){this.props=Q,this.context=we,this.refs=lr,this.updater=Ne||Mn}ln.prototype.isReactComponent={},ln.prototype.setState=function(Q,we){if(!(typeof Q=="object"||typeof Q=="function"||Q==null))throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,Q,we,"setState")},ln.prototype.forceUpdate=function(Q){this.updater.enqueueForceUpdate(this,Q,"forceUpdate")};{var Vt={isMounted:["isMounted","Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."],replaceState:["replaceState","Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."]},Dr=function(Q,we){Object.defineProperty(ln.prototype,Q,{get:function(){He("%s(...) is deprecated in plain JavaScript React classes. %s",we[0],we[1])}})};for(var w in Vt)Vt.hasOwnProperty(w)&&Dr(w,Vt[w])}function jt(){}jt.prototype=ln.prototype;function Xn(Q,we,Ne){this.props=Q,this.context=we,this.refs=lr,this.updater=Ne||Mn}var vr=Xn.prototype=new jt;vr.constructor=Xn,i(vr,ln.prototype),vr.isPureReactComponent=!0;function jr(){var Q={current:null};return Object.seal(Q),Q}var fr=Object.prototype.hasOwnProperty,zr={key:!0,ref:!0,__self:!0,__source:!0},Qt,wu,d0;d0={};function Ro(Q){if(fr.call(Q,"ref")){var we=Object.getOwnPropertyDescriptor(Q,"ref").get;if(we&&we.isReactWarning)return!1}return Q.ref!==void 0}function Jo(Q){if(fr.call(Q,"key")){var we=Object.getOwnPropertyDescriptor(Q,"key").get;if(we&&we.isReactWarning)return!1}return Q.key!==void 0}function Ps(Q,we){var Ne=function(){Qt||(Qt=!0,dt("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://fb.me/react-special-props)",we))};Ne.isReactWarning=!0,Object.defineProperty(Q,"key",{get:Ne,configurable:!0})}function Zo(Q,we){var Ne=function(){wu||(wu=!0,dt("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://fb.me/react-special-props)",we))};Ne.isReactWarning=!0,Object.defineProperty(Q,"ref",{get:Ne,configurable:!0})}function $o(Q){if(typeof Q.ref=="string"&&at.current&&Q.__self&&at.current.stateNode!==Q.__self){var we=Xt(at.current.type);d0[we]||(dt('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref',Xt(at.current.type),Q.ref),d0[we]=!0)}}var qt=function(Q,we,Ne,Le,pt,Yn,Cn){var cr={$$typeof:_,type:Q,key:we,ref:Ne,props:Cn,_owner:Yn};return cr._store={},Object.defineProperty(cr._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(cr,"_self",{configurable:!1,enumerable:!1,writable:!1,value:Le}),Object.defineProperty(cr,"_source",{configurable:!1,enumerable:!1,writable:!1,value:pt}),Object.freeze&&(Object.freeze(cr.props),Object.freeze(cr)),cr};function Ai(Q,we,Ne){var Le,pt={},Yn=null,Cn=null,cr=null,Si=null;if(we!=null){Ro(we)&&(Cn=we.ref,$o(we)),Jo(we)&&(Yn=""+we.key),cr=we.__self===void 0?null:we.__self,Si=we.__source===void 0?null:we.__source;for(Le in we)fr.call(we,Le)&&!zr.hasOwnProperty(Le)&&(pt[Le]=we[Le])}var Mu=arguments.length-2;if(Mu===1)pt.children=Ne;else if(Mu>1){for(var zu=Array(Mu),Hu=0;Hu1){for(var Su=Array(Hu),Ti=0;Ti is not supported and will be removed in a future major release. Did you mean to render instead?")),Ne.Provider},set:function(Cn){Ne.Provider=Cn}},_currentValue:{get:function(){return Ne._currentValue},set:function(Cn){Ne._currentValue=Cn}},_currentValue2:{get:function(){return Ne._currentValue2},set:function(Cn){Ne._currentValue2=Cn}},_threadCount:{get:function(){return Ne._threadCount},set:function(Cn){Ne._threadCount=Cn}},Consumer:{get:function(){return Le||(Le=!0,dt("Rendering is not supported and will be removed in a future major release. Did you mean to render instead?")),Ne.Consumer}}}),Ne.Consumer=Yn}return Ne._currentRenderer=null,Ne._currentRenderer2=null,Ne}function Wt(Q){var we={$$typeof:De,_ctor:Q,_status:-1,_result:null};{var Ne,Le;Object.defineProperties(we,{defaultProps:{configurable:!0,get:function(){return Ne},set:function(pt){dt("React.lazy(...): It is not supported to assign `defaultProps` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),Ne=pt,Object.defineProperty(we,"defaultProps",{enumerable:!0})}},propTypes:{configurable:!0,get:function(){return Le},set:function(pt){dt("React.lazy(...): It is not supported to assign `propTypes` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),Le=pt,Object.defineProperty(we,"propTypes",{enumerable:!0})}}})}return we}function Ru(Q){return Q!=null&&Q.$$typeof===he?dt("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."):typeof Q!="function"?dt("forwardRef requires a render function but was given %s.",Q===null?"null":typeof Q):Q.length!==0&&Q.length!==2&&dt("forwardRef render functions accept exactly two parameters: props and ref. %s",Q.length===1?"Did you forget to use the ref parameter?":"Any additional parameter will be undefined."),Q!=null&&(Q.defaultProps!=null||Q.propTypes!=null)&&dt("forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?"),{$$typeof:q,render:Q}}function eu(Q){return typeof Q=="string"||typeof Q=="function"||Q===O||Q===H||Q===M||Q===N||Q===ne||Q===m||typeof Q=="object"&&Q!==null&&(Q.$$typeof===De||Q.$$typeof===he||Q.$$typeof===T||Q.$$typeof===B||Q.$$typeof===q||Q.$$typeof===fe||Q.$$typeof===_e||Q.$$typeof===ce||Q.$$typeof===se)}function Q0(Q,we){return eu(Q)||dt("memo: The first argument must be a component. Instead received: %s",Q===null?"null":typeof Q),{$$typeof:he,type:Q,compare:we===void 0?null:we}}function Yi(){var Q=Ue.current;if(Q===null)throw Error(`Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: +1. You might have mismatching versions of React and the renderer (such as React DOM) +2. You might be breaking the Rules of Hooks +3. You might have more than one copy of React in the same app +See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.`);return Q}function Ql(Q,we){var Ne=Yi();if(we!==void 0&&dt("useContext() second argument is reserved for future use in React. Passing it is not supported. You passed: %s.%s",we,typeof we=="number"&&Array.isArray(arguments[2])?` + +Did you call array.map(useContext)? Calling Hooks inside a loop is not supported. Learn more at https://fb.me/rules-of-hooks`:""),Q._context!==void 0){var Le=Q._context;Le.Consumer===Q?dt("Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be removed in a future major release. Did you mean to call useContext(Context) instead?"):Le.Provider===Q&&dt("Calling useContext(Context.Provider) is not supported. Did you mean to call useContext(Context) instead?")}return Ne.useContext(Q,we)}function ko(Q){var we=Yi();return we.useState(Q)}function ai(Q,we,Ne){var Le=Yi();return Le.useReducer(Q,we,Ne)}function ao(Q){var we=Yi();return we.useRef(Q)}function Jl(Q,we){var Ne=Yi();return Ne.useEffect(Q,we)}function Lo(Q,we){var Ne=Yi();return Ne.useLayoutEffect(Q,we)}function bs(Q,we){var Ne=Yi();return Ne.useCallback(Q,we)}function $n(Q,we){var Ne=Yi();return Ne.useMemo(Q,we)}function tl(Q,we,Ne){var Le=Yi();return Le.useImperativeHandle(Q,we,Ne)}function fo(Q,we){{var Ne=Yi();return Ne.useDebugValue(Q,we)}}var I0;I0=!1;function Sl(){if(at.current){var Q=Xt(at.current.type);if(Q)return` + +Check the render method of \``+Q+"`."}return""}function No(Q){if(Q!==void 0){var we=Q.fileName.replace(/^.*[\\\/]/,""),Ne=Q.lineNumber;return` + +Check your code at `+we+":"+Ne+"."}return""}function wt(Q){return Q!=null?No(Q.__source):""}var bt={};function Hn(Q){var we=Sl();if(!we){var Ne=typeof Q=="string"?Q:Q.displayName||Q.name;Ne&&(we=` + +Check the top-level render call using <`+Ne+">.")}return we}function qr(Q,we){if(!(!Q._store||Q._store.validated||Q.key!=null)){Q._store.validated=!0;var Ne=Hn(we);if(!bt[Ne]){bt[Ne]=!0;var Le="";Q&&Q._owner&&Q._owner!==at.current&&(Le=" It was passed a child from "+Xt(Q._owner.type)+"."),de(Q),dt('Each child in a list should have a unique "key" prop.%s%s See https://fb.me/react-warning-keys for more information.',Ne,Le),de(null)}}}function Ki(Q,we){if(typeof Q=="object"){if(Array.isArray(Q))for(var Ne=0;Ne",pt=" Did you accidentally export a JSX literal instead of a component?"):Cn=typeof Q,dt("React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",Cn,pt)}var cr=Ai.apply(this,arguments);if(cr==null)return cr;if(Le)for(var Si=2;Si{"use strict";process.env.NODE_ENV==="production"?hD.exports=wS():hD.exports=OS()});var MS=Ke((Wv,Ug)=>{(function(){var i,o="4.17.21",a=200,c="Unsupported core-js use. Try https://npms.io/search?q=ponyfill.",_="Expected a function",t="Invalid `variable` option passed into `_.template`",O="__lodash_hash_undefined__",N=500,M="__lodash_placeholder__",T=1,B=2,H=4,q=1,ne=2,m=1,he=2,De=4,se=8,fe=16,_e=32,ce=64,me=128,ie=256,Oe=512,Ue=30,je="...",at=800,Dt=16,Qe=1,ut=2,Ve=3,It=1/0,Xt=9007199254740991,rt=17976931348623157e292,X=0/0,de=4294967295,Ce=de-1,oe=de>>>1,He=[["ary",me],["bind",m],["bindKey",he],["curry",se],["curryRight",fe],["flip",Oe],["partial",_e],["partialRight",ce],["rearg",ie]],dt="[object Arguments]",At="[object Array]",nn="[object AsyncFunction]",an="[object Boolean]",Mn="[object Date]",lr="[object DOMException]",ln="[object Error]",Vt="[object Function]",Dr="[object GeneratorFunction]",w="[object Map]",jt="[object Number]",Xn="[object Null]",vr="[object Object]",jr="[object Promise]",fr="[object Proxy]",zr="[object RegExp]",Qt="[object Set]",wu="[object String]",d0="[object Symbol]",Ro="[object Undefined]",Jo="[object WeakMap]",Ps="[object WeakSet]",Zo="[object ArrayBuffer]",$o="[object DataView]",qt="[object Float32Array]",Ai="[object Float64Array]",su="[object Int8Array]",mi="[object Int16Array]",wr="[object Int32Array]",el="[object Uint8Array]",Y0="[object Uint8ClampedArray]",Uu="[object Uint16Array]",K0="[object Uint32Array]",Xr=/\b__p \+= '';/g,Oo=/\b(__p \+=) '' \+/g,Mo=/(__e\(.*?\)|\b__t\)) \+\n'';/g,F0=/&(?:amp|lt|gt|quot|#39);/g,au=/[&<>"']/g,Li=RegExp(F0.source),Is=RegExp(au.source),Xl=/<%-([\s\S]+?)%>/g,P0=/<%([\s\S]+?)%>/g,p0=/<%=([\s\S]+?)%>/g,Hr=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Ri=/^\w*$/,X0=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,gi=/[\\^$.*+?()[\]{}|]/g,en=RegExp(gi.source),bn=/^\s+/,Oi=/\s/,yi=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Wt=/\{\n\/\* \[wrapped with (.+)\] \*/,Ru=/,? & /,eu=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Q0=/[()=,{}\[\]\/\s]/,Yi=/\\(\\)?/g,Ql=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,ko=/\w*$/,ai=/^[-+]0x[0-9a-f]+$/i,ao=/^0b[01]+$/i,Jl=/^\[object .+?Constructor\]$/,Lo=/^0o[0-7]+$/i,bs=/^(?:0|[1-9]\d*)$/,$n=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,tl=/($^)/,fo=/['\n\r\u2028\u2029\\]/g,I0="\\ud800-\\udfff",Sl="\\u0300-\\u036f",No="\\ufe20-\\ufe2f",wt="\\u20d0-\\u20ff",bt=Sl+No+wt,Hn="\\u2700-\\u27bf",qr="a-z\\xdf-\\xf6\\xf8-\\xff",Ki="\\xac\\xb1\\xd7\\xf7",Qr="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",Ou="\\u2000-\\u206f",h0=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Ni="A-Z\\xc0-\\xd6\\xd8-\\xde",v0="\\ufe0e\\ufe0f",vs=Ki+Qr+Ou+h0,Tt="['\u2019]",co="["+I0+"]",nl="["+vs+"]",Zl="["+bt+"]",ju="\\d+",ms="["+Hn+"]",b0="["+qr+"]",Q="[^"+I0+vs+ju+Hn+qr+Ni+"]",we="\\ud83c[\\udffb-\\udfff]",Ne="(?:"+Zl+"|"+we+")",Le="[^"+I0+"]",pt="(?:\\ud83c[\\udde6-\\uddff]){2}",Yn="[\\ud800-\\udbff][\\udc00-\\udfff]",Cn="["+Ni+"]",cr="\\u200d",Si="(?:"+b0+"|"+Q+")",Mu="(?:"+Cn+"|"+Q+")",zu="(?:"+Tt+"(?:d|ll|m|re|s|t|ve))?",Hu="(?:"+Tt+"(?:D|LL|M|RE|S|T|VE))?",Su=Ne+"?",Ti="["+v0+"]?",Fo="(?:"+cr+"(?:"+[Le,pt,Yn].join("|")+")"+Ti+Su+")*",ku="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",po="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",qu=Ti+Su+Fo,Ia="(?:"+[ms,pt,Yn].join("|")+")"+qu,m0="(?:"+[Le+Zl+"?",Zl,pt,Yn,co].join("|")+")",ua=RegExp(Tt,"g"),J0=RegExp(Zl,"g"),oa=RegExp(we+"(?="+we+")|"+m0+qu,"g"),ba=RegExp([Cn+"?"+b0+"+"+zu+"(?="+[nl,Cn,"$"].join("|")+")",Mu+"+"+Hu+"(?="+[nl,Cn+Si,"$"].join("|")+")",Cn+"?"+Si+"+"+zu,Cn+"+"+Hu,po,ku,ju,Ia].join("|"),"g"),gs=RegExp("["+cr+I0+bt+v0+"]"),S0=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Qn=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],fc=-1,fi={};fi[qt]=fi[Ai]=fi[su]=fi[mi]=fi[wr]=fi[el]=fi[Y0]=fi[Uu]=fi[K0]=!0,fi[dt]=fi[At]=fi[Zo]=fi[an]=fi[$o]=fi[Mn]=fi[ln]=fi[Vt]=fi[w]=fi[jt]=fi[vr]=fi[zr]=fi[Qt]=fi[wu]=fi[Jo]=!1;var $r={};$r[dt]=$r[At]=$r[Zo]=$r[$o]=$r[an]=$r[Mn]=$r[qt]=$r[Ai]=$r[su]=$r[mi]=$r[wr]=$r[w]=$r[jt]=$r[vr]=$r[zr]=$r[Qt]=$r[wu]=$r[d0]=$r[el]=$r[Y0]=$r[Uu]=$r[K0]=!0,$r[ln]=$r[Vt]=$r[Jo]=!1;var $l={\u00C0:"A",\u00C1:"A",\u00C2:"A",\u00C3:"A",\u00C4:"A",\u00C5:"A",\u00E0:"a",\u00E1:"a",\u00E2:"a",\u00E3:"a",\u00E4:"a",\u00E5:"a",\u00C7:"C",\u00E7:"c",\u00D0:"D",\u00F0:"d",\u00C8:"E",\u00C9:"E",\u00CA:"E",\u00CB:"E",\u00E8:"e",\u00E9:"e",\u00EA:"e",\u00EB:"e",\u00CC:"I",\u00CD:"I",\u00CE:"I",\u00CF:"I",\u00EC:"i",\u00ED:"i",\u00EE:"i",\u00EF:"i",\u00D1:"N",\u00F1:"n",\u00D2:"O",\u00D3:"O",\u00D4:"O",\u00D5:"O",\u00D6:"O",\u00D8:"O",\u00F2:"o",\u00F3:"o",\u00F4:"o",\u00F5:"o",\u00F6:"o",\u00F8:"o",\u00D9:"U",\u00DA:"U",\u00DB:"U",\u00DC:"U",\u00F9:"u",\u00FA:"u",\u00FB:"u",\u00FC:"u",\u00DD:"Y",\u00FD:"y",\u00FF:"y",\u00C6:"Ae",\u00E6:"ae",\u00DE:"Th",\u00FE:"th",\u00DF:"ss",\u0100:"A",\u0102:"A",\u0104:"A",\u0101:"a",\u0103:"a",\u0105:"a",\u0106:"C",\u0108:"C",\u010A:"C",\u010C:"C",\u0107:"c",\u0109:"c",\u010B:"c",\u010D:"c",\u010E:"D",\u0110:"D",\u010F:"d",\u0111:"d",\u0112:"E",\u0114:"E",\u0116:"E",\u0118:"E",\u011A:"E",\u0113:"e",\u0115:"e",\u0117:"e",\u0119:"e",\u011B:"e",\u011C:"G",\u011E:"G",\u0120:"G",\u0122:"G",\u011D:"g",\u011F:"g",\u0121:"g",\u0123:"g",\u0124:"H",\u0126:"H",\u0125:"h",\u0127:"h",\u0128:"I",\u012A:"I",\u012C:"I",\u012E:"I",\u0130:"I",\u0129:"i",\u012B:"i",\u012D:"i",\u012F:"i",\u0131:"i",\u0134:"J",\u0135:"j",\u0136:"K",\u0137:"k",\u0138:"k",\u0139:"L",\u013B:"L",\u013D:"L",\u013F:"L",\u0141:"L",\u013A:"l",\u013C:"l",\u013E:"l",\u0140:"l",\u0142:"l",\u0143:"N",\u0145:"N",\u0147:"N",\u014A:"N",\u0144:"n",\u0146:"n",\u0148:"n",\u014B:"n",\u014C:"O",\u014E:"O",\u0150:"O",\u014D:"o",\u014F:"o",\u0151:"o",\u0154:"R",\u0156:"R",\u0158:"R",\u0155:"r",\u0157:"r",\u0159:"r",\u015A:"S",\u015C:"S",\u015E:"S",\u0160:"S",\u015B:"s",\u015D:"s",\u015F:"s",\u0161:"s",\u0162:"T",\u0164:"T",\u0166:"T",\u0163:"t",\u0165:"t",\u0167:"t",\u0168:"U",\u016A:"U",\u016C:"U",\u016E:"U",\u0170:"U",\u0172:"U",\u0169:"u",\u016B:"u",\u016D:"u",\u016F:"u",\u0171:"u",\u0173:"u",\u0174:"W",\u0175:"w",\u0176:"Y",\u0177:"y",\u0178:"Y",\u0179:"Z",\u017B:"Z",\u017D:"Z",\u017A:"z",\u017C:"z",\u017E:"z",\u0132:"IJ",\u0133:"ij",\u0152:"Oe",\u0153:"oe",\u0149:"'n",\u017F:"s"},la={"&":"&","<":"<",">":">",'"':""","'":"'"},hf={"&":"&","<":"<",">":">",""":'"',"'":"'"},Bs={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Ba=parseFloat,Us=parseInt,g0=typeof global=="object"&&global&&global.Object===Object&&global,js=typeof self=="object"&&self&&self.Object===Object&&self,ji=g0||js||Function("return this")(),U=typeof Wv=="object"&&Wv&&!Wv.nodeType&&Wv,z=U&&typeof Ug=="object"&&Ug&&!Ug.nodeType&&Ug,G=z&&z.exports===U,$=G&&g0.process,Te=function(){try{var xe=z&&z.require&&z.require("util").types;return xe||$&&$.binding&&$.binding("util")}catch(tt){}}(),ye=Te&&Te.isArrayBuffer,Ae=Te&&Te.isDate,Z=Te&&Te.isMap,ke=Te&&Te.isRegExp,Je=Te&&Te.isSet,vt=Te&&Te.isTypedArray;function ue(xe,tt,Ye){switch(Ye.length){case 0:return xe.call(tt);case 1:return xe.call(tt,Ye[0]);case 2:return xe.call(tt,Ye[0],Ye[1]);case 3:return xe.call(tt,Ye[0],Ye[1],Ye[2])}return xe.apply(tt,Ye)}function qe(xe,tt,Ye,Yt){for(var Kt=-1,pr=xe==null?0:xe.length;++Kt-1}function rn(xe,tt,Ye){for(var Yt=-1,Kt=xe==null?0:xe.length;++Yt-1;);return Ye}function Tl(xe,tt){for(var Ye=xe.length;Ye--&&Et(tt,xe[Ye],0)>-1;);return Ye}function mf(xe,tt){for(var Ye=xe.length,Yt=0;Ye--;)xe[Ye]===tt&&++Yt;return Yt}var Io=Jn($l),ys=Jn(la);function zs(xe){return"\\"+Bs[xe]}function bo(xe,tt){return xe==null?i:xe[tt]}function Bo(xe){return gs.test(xe)}function _s(xe){return S0.test(xe)}function Qu(xe){for(var tt,Ye=[];!(tt=xe.next()).done;)Ye.push(tt.value);return Ye}function Tu(xe){var tt=-1,Ye=Array(xe.size);return xe.forEach(function(Yt,Kt){Ye[++tt]=[Kt,Yt]}),Ye}function Ei(xe,tt){return function(Ye){return xe(tt(Ye))}}function C0(xe,tt){for(var Ye=-1,Yt=xe.length,Kt=0,pr=[];++Ye-1}function ca(p,v){var x=this.__data__,P=ns(x,p);return P<0?(++this.size,x.push([p,v])):x[P][1]=v,this}io.prototype.clear=Ua,io.prototype.delete=Ef,io.prototype.get=cc,io.prototype.has=ws,io.prototype.set=ca;function U0(p){var v=-1,x=p==null?0:p.length;for(this.clear();++v=v?p:v)),p}function j0(p,v,x,P,W,ee){var ve,Ee=v&T,Ie=v&B,_t=v&H;if(x&&(ve=W?x(p,P,W,ee):x(p)),ve!==i)return ve;if(!bu(p))return p;var St=tr(p);if(St){if(ve=xs(p),!Ee)return iu(p,ve)}else{var Rt=Iu(p),on=Rt==Vt||Rt==Dr;if(Zs(p))return mc(p,Ee);if(Rt==vr||Rt==dt||on&&!W){if(ve=Ie||on?{}:Dc(p),!Ee)return Ie?rs(p,ol(ve,p)):o0(p,Df(ve,p))}else{if(!$r[Rt])return W?p:{};ve=Th(p,Rt,Ee)}}ee||(ee=new ul);var kn=ee.get(p);if(kn)return kn;ee.set(p,ve),bd(p)?p.forEach(function(ar){ve.add(j0(ar,v,x,ar,p,ee))}):Dp(p)&&p.forEach(function(ar,ui){ve.set(ui,j0(ar,v,x,ui,p,ee))});var rr=_t?Ie?sr:r1:Ie?dn:L0,br=St?i:rr(p);return nt(br||p,function(ar,ui){br&&(ui=ar,ar=p[ui]),Ts(ve,ui,j0(ar,v,x,ui,p,ee))}),ve}function wf(p){var v=L0(p);return function(x){return Wc(x,p,v)}}function Wc(p,v,x){var P=x.length;if(p==null)return!P;for(p=xn(p);P--;){var W=x[P],ee=v[W],ve=p[W];if(ve===i&&!(W in p)||!ee(ve))return!1}return!0}function pc(p,v,x){if(typeof p!="function")throw new ti(_);return Ja(function(){p.apply(i,x)},v)}function Ol(p,v,x,P){var W=-1,ee=sn,ve=!0,Ee=p.length,Ie=[],_t=v.length;if(!Ee)return Ie;x&&(v=Nt(v,_i(x))),P?(ee=rn,ve=!1):v.length>=a&&(ee=rl,ve=!1,v=new go(v));e:for(;++WW?0:W+x),P=P===i||P>W?W:Mr(P),P<0&&(P+=W),P=x>P?0:Sp(P);x0&&x(Ee)?v>1?qi(Ee,v-1,x,P,W):Dn(W,Ee):P||(W[W.length]=Ee)}return W}var y=yc(),g=yc(!0);function A(p,v){return p&&y(p,v,L0)}function F(p,v){return p&&g(p,v,L0)}function b(p,v){return Pt(v,function(x){return Aa(p[x])})}function J(p,v){v=Vs(v,p);for(var x=0,P=v.length;p!=null&&xv}function kt(p,v){return p!=null&&li.call(p,v)}function xr(p,v){return p!=null&&v in xn(p)}function i0(p,v,x){return p>=Kn(v,x)&&p=120&&St.length>=120)?new go(ve&&St):i}St=p[0];var Rt=-1,on=Ee[0];e:for(;++Rt-1;)Ee!==p&&O0.call(Ee,Ie,1),O0.call(p,Ie,1);return p}function ad(p,v){for(var x=p?v.length:0,P=x-1;x--;){var W=v[x];if(x==P||W!==ee){var ee=W;Do(W)?O0.call(p,W,1):R2(p,W)}}return p}function fd(p,v){return p+Ds(E0()*(v-p+1))}function C2(p,v,x,P){for(var W=-1,ee=ni($u((v-p)/(x||1)),0),ve=Ye(ee);ee--;)ve[P?ee:++W]=p,p+=x;return ve}function Yc(p,v){var x="";if(!p||v<1||v>Xt)return x;do v%2&&(x+=p),v=Ds(v/2),v&&(p+=p);while(v);return x}function Ir(p,v){return l1(P2(p,v,s0),p+"")}function cd(p){return Ha(Nc(p))}function dd(p,v){var x=Nc(p);return Sc(x,r0(v,0,x.length))}function Ya(p,v,x,P){if(!bu(p))return p;v=Vs(v,p);for(var W=-1,ee=v.length,ve=ee-1,Ee=p;Ee!=null&&++WW?0:W+v),x=x>W?W:x,x<0&&(x+=W),W=v>x?0:x-v>>>0,v>>>=0;for(var ee=Ye(W);++P>>1,ve=p[ee];ve!==null&&!Bl(ve)&&(x?ve<=v:ve=a){var _t=v?null:fm(p);if(_t)return $0(_t);ve=!1,W=rl,Ie=new go}else Ie=v?[]:Ee;e:for(;++P=P?p:sl(p,v,x)}var Zc=Es||function(p){return ji.clearTimeout(p)};function mc(p,v){if(v)return p.slice();var x=p.length,P=Hi?Hi(x):new p.constructor(x);return p.copy(P),P}function gc(p){var v=new p.constructor(p.byteLength);return new R0(v).set(new R0(p)),v}function hd(p,v){var x=v?gc(p.buffer):p.buffer;return new p.constructor(x,p.byteOffset,p.byteLength)}function Eh(p){var v=new p.constructor(p.source,ko.exec(p));return v.lastIndex=p.lastIndex,v}function Cf(p){return Rr?xn(Rr.call(p)):{}}function $c(p,v){var x=v?gc(p.buffer):p.buffer;return new p.constructor(x,p.byteOffset,p.length)}function Dh(p,v){if(p!==v){var x=p!==i,P=p===null,W=p===p,ee=Bl(p),ve=v!==i,Ee=v===null,Ie=v===v,_t=Bl(v);if(!Ee&&!_t&&!ee&&p>v||ee&&ve&&Ie&&!Ee&&!_t||P&&ve&&Ie||!x&&Ie||!W)return 1;if(!P&&!ee&&!_t&&p=Ee)return Ie;var _t=x[P];return Ie*(_t=="desc"?-1:1)}}return p.index-v.index}function Gs(p,v,x,P){for(var W=-1,ee=p.length,ve=x.length,Ee=-1,Ie=v.length,_t=ni(ee-ve,0),St=Ye(Ie+_t),Rt=!P;++Ee1?x[W-1]:i,ve=W>2?x[2]:i;for(ee=p.length>3&&typeof ee=="function"?(W--,ee):i,ve&&lo(x[0],x[1],ve)&&(ee=W<3?i:ee,W=1),v=xn(v);++P-1?W[ee?v[ve]:ve]:i}}function t1(p){return cl(function(v){var x=v.length,P=x,W=Vr.prototype.thru;for(p&&v.reverse();P--;){var ee=v[P];if(typeof ee!="function")throw new ti(_);if(W&&!ve&&qo(ee)=="wrapper")var ve=new Vr([],!0)}for(P=ve?P:x;++P1&&di.reverse(),St&&IeEe))return!1;var _t=ee.get(p),St=ee.get(v);if(_t&&St)return _t==v&&St==p;var Rt=-1,on=!0,kn=x&ne?new go:i;for(ee.set(p,v),ee.set(v,p);++Rt1?"& ":"")+v[P],v=v.join(x>2?", ":" "),p.replace(yi,`{ +/* [wrapped with `+v+`] */ +`)}function us(p){return tr(p)||pl(p)||!!(vo&&p&&p[vo])}function Do(p,v){var x=typeof p;return v=v==null?Xt:v,!!v&&(x=="number"||x!="symbol"&&bs.test(p))&&p>-1&&p%1==0&&p0){if(++v>=at)return arguments[0]}else v=0;return p.apply(i,arguments)}}function Sc(p,v){var x=-1,P=p.length,W=P-1;for(v=v===i?P:v;++x1?p[v-1]:i;return x=typeof x=="function"?(p.pop(),x):i,Td(p,x)});function zh(p){var v=Y(p);return v.__chain__=!0,v}function Hh(p,v){return v(p),p}function y1(p,v){return v(p)}var $2=cl(function(p){var v=p.length,x=v?p[0]:0,P=this.__wrapped__,W=function(ee){return Wa(ee,p)};return v>1||this.__actions__.length||!(P instanceof ft)||!Do(x)?this.thru(W):(P=P.slice(x,+x+(v?1:0)),P.__actions__.push({func:y1,args:[W],thisArg:i}),new Vr(P,this.__chain__).thru(function(ee){return v&&!ee.length&&ee.push(i),ee}))});function qh(){return zh(this)}function ep(){return new Vr(this.value(),this.__chain__)}function Wh(){this.__values__===i&&(this.__values__=fv(this.value()));var p=this.__index__>=this.__values__.length,v=p?i:this.__values__[this.__index__++];return{done:p,value:v}}function _m(){return this}function Em(p){for(var v,x=this;x instanceof ii;){var P=b2(x);P.__index__=0,P.__values__=i,v?W.__wrapped__=P:v=P;var W=P;x=x.__wrapped__}return W.__wrapped__=p,v}function If(){var p=this.__wrapped__;if(p instanceof ft){var v=p;return this.__actions__.length&&(v=new ft(this)),v=v.reverse(),v.__actions__.push({func:y1,args:[G2],thisArg:i}),new Vr(v,this.__chain__)}return this.thru(G2)}function bf(){return _h(this.__wrapped__,this.__actions__)}var Cd=Ka(function(p,v,x){li.call(p,x)?++p[x]:Gu(p,x,1)});function Dm(p,v,x){var P=tr(p)?Mt:od;return x&&lo(p,v,x)&&(v=i),P(p,Vn(v,3))}function tp(p,v){var x=tr(p)?Pt:Vc;return x(p,Vn(v,3))}var xd=Ll(z2),np=Ll(a1);function Vh(p,v){return qi(_1(p,v),1)}function rp(p,v){return qi(_1(p,v),It)}function Gh(p,v,x){return x=x===i?1:Mr(x),qi(_1(p,v),x)}function Yh(p,v){var x=tr(p)?nt:Cs;return x(p,Vn(v,3))}function ip(p,v){var x=tr(p)?Ct:pa;return x(p,Vn(v,3))}var wm=Ka(function(p,v,x){li.call(p,x)?p[x].push(v):Gu(p,x,[v])});function Sm(p,v,x,P){p=hl(p)?p:Nc(p),x=x&&!P?Mr(x):0;var W=p.length;return x<0&&(x=ni(W+x,0)),S1(p)?x<=W&&p.indexOf(v,x)>-1:!!W&&Et(p,v,x)>-1}var Tm=Ir(function(p,v,x){var P=-1,W=typeof v=="function",ee=hl(p)?Ye(p.length):[];return Cs(p,function(ve){ee[++P]=W?ue(v,ve,x):Ml(ve,v,x)}),ee}),Kh=Ka(function(p,v,x){Gu(p,x,v)});function _1(p,v){var x=tr(p)?Nt:S2;return x(p,Vn(v,3))}function Cm(p,v,x,P){return p==null?[]:(tr(v)||(v=v==null?[]:[v]),x=P?i:x,tr(x)||(x=x==null?[]:[x]),yo(p,v,x))}var up=Ka(function(p,v,x){p[x?0:1].push(v)},function(){return[[],[]]});function op(p,v,x){var P=tr(p)?dr:Sr,W=arguments.length<3;return P(p,Vn(v,4),x,W,Cs)}function xm(p,v,x){var P=tr(p)?er:Sr,W=arguments.length<3;return P(p,Vn(v,4),x,W,pa)}function Am(p,v){var x=tr(p)?Pt:Vc;return x(p,Od(Vn(v,3)))}function Xh(p){var v=tr(p)?Ha:cd;return v(p)}function Rm(p,v,x){(x?lo(p,v,x):v===i)?v=1:v=Mr(v);var P=tr(p)?qa:dd;return P(p,v)}function Om(p){var v=tr(p)?da:ll;return v(p)}function lp(p){if(p==null)return 0;if(hl(p))return S1(p)?tu(p):p.length;var v=Iu(p);return v==w||v==Qt?p.size:Va(p).length}function sp(p,v,x){var P=tr(p)?Cr:gh;return x&&lo(p,v,x)&&(v=i),P(p,Vn(v,3))}var Ca=Ir(function(p,v){if(p==null)return[];var x=v.length;return x>1&&lo(p,v[0],v[1])?v=[]:x>2&&lo(v[0],v[1],v[2])&&(v=[v[0]]),yo(p,qi(v,1),[])}),E1=fa||function(){return ji.Date.now()};function ap(p,v){if(typeof v!="function")throw new ti(_);return p=Mr(p),function(){if(--p<1)return v.apply(this,arguments)}}function Qh(p,v,x){return v=x?i:v,v=p&&v==null?p.length:v,hn(p,me,i,i,i,i,v)}function Ad(p,v){var x;if(typeof v!="function")throw new ti(_);return p=Mr(p),function(){return--p>0&&(x=v.apply(this,arguments)),p<=1&&(v=i),x}}var D1=Ir(function(p,v,x){var P=m;if(x.length){var W=C0(x,yr(D1));P|=_e}return hn(p,P,v,x,W)}),Jh=Ir(function(p,v,x){var P=m|he;if(x.length){var W=C0(x,yr(Jh));P|=_e}return hn(v,P,p,x,W)});function fp(p,v,x){v=x?i:v;var P=hn(p,se,i,i,i,i,i,v);return P.placeholder=fp.placeholder,P}function Zh(p,v,x){v=x?i:v;var P=hn(p,fe,i,i,i,i,i,v);return P.placeholder=Zh.placeholder,P}function cp(p,v,x){var P,W,ee,ve,Ee,Ie,_t=0,St=!1,Rt=!1,on=!0;if(typeof p!="function")throw new ti(_);v=vl(v)||0,bu(x)&&(St=!!x.leading,Rt="maxWait"in x,ee=Rt?ni(vl(x.maxWait)||0,v):ee,on="trailing"in x?!!x.trailing:on);function kn(a0){var Ms=P,Co=W;return P=W=i,_t=a0,ve=p.apply(Co,Ms),ve}function rr(a0){return _t=a0,Ee=Ja(ui,v),St?kn(a0):ve}function br(a0){var Ms=a0-Ie,Co=a0-_t,kv=v-Ms;return Rt?Kn(kv,ee-Co):kv}function ar(a0){var Ms=a0-Ie,Co=a0-_t;return Ie===i||Ms>=v||Ms<0||Rt&&Co>=ee}function ui(){var a0=E1();if(ar(a0))return di(a0);Ee=Ja(ui,br(a0))}function di(a0){return Ee=i,on&&P?kn(a0):(P=W=i,ve)}function zl(){Ee!==i&&Zc(Ee),_t=0,P=Ie=W=Ee=i}function Zi(){return Ee===i?ve:di(E1())}function so(){var a0=E1(),Ms=ar(a0);if(P=arguments,W=this,Ie=a0,Ms){if(Ee===i)return rr(Ie);if(Rt)return Zc(Ee),Ee=Ja(ui,v),kn(Ie)}return Ee===i&&(Ee=Ja(ui,v)),ve}return so.cancel=zl,so.flush=Zi,so}var $h=Ir(function(p,v){return pc(p,1,v)}),ev=Ir(function(p,v,x){return pc(p,vl(v)||0,x)});function dp(p){return hn(p,Oe)}function Rd(p,v){if(typeof p!="function"||v!=null&&typeof v!="function")throw new ti(_);var x=function(){var P=arguments,W=v?v.apply(this,P):P[0],ee=x.cache;if(ee.has(W))return ee.get(W);var ve=p.apply(this,P);return x.cache=ee.set(W,ve)||ee,ve};return x.cache=new(Rd.Cache||U0),x}Rd.Cache=U0;function Od(p){if(typeof p!="function")throw new ti(_);return function(){var v=arguments;switch(v.length){case 0:return!p.call(this);case 1:return!p.call(this,v[0]);case 2:return!p.call(this,v[0],v[1]);case 3:return!p.call(this,v[0],v[1],v[2])}return!p.apply(this,v)}}function H0(p){return Ad(2,p)}var Md=k2(function(p,v){v=v.length==1&&tr(v[0])?Nt(v[0],_i(Vn())):Nt(qi(v,1),_i(Vn()));var x=v.length;return Ir(function(P){for(var W=-1,ee=Kn(P.length,x);++W=v}),pl=u0(function(){return arguments}())?u0:function(p){return Yu(p)&&li.call(p,"callee")&&!B0.call(p,"callee")},tr=Ye.isArray,Js=ye?_i(ye):We;function hl(p){return p!=null&&Pd(p.length)&&!Aa(p)}function l0(p){return Yu(p)&&hl(p)}function rv(p){return p===!0||p===!1||Yu(p)&>(p)==an}var Zs=no||jp,gp=Ae?_i(Ae):ze;function Fm(p){return Yu(p)&&p.nodeType===1&&!xc(p)}function iv(p){if(p==null)return!0;if(hl(p)&&(tr(p)||typeof p=="string"||typeof p.splice=="function"||Zs(p)||Ra(p)||pl(p)))return!p.length;var v=Iu(p);if(v==w||v==Qt)return!p.size;if(Nf(p))return!Va(p).length;for(var x in p)if(li.call(p,x))return!1;return!0}function yp(p,v){return lt(p,v)}function Pm(p,v,x){x=typeof x=="function"?x:i;var P=x?x(p,v):i;return P===i?lt(p,v,i,x):!!P}function _p(p){if(!Yu(p))return!1;var v=gt(p);return v==ln||v==lr||typeof p.message=="string"&&typeof p.name=="string"&&!xc(p)}function Cc(p){return typeof p=="number"&&nu(p)}function Aa(p){if(!bu(p))return!1;var v=gt(p);return v==Vt||v==Dr||v==nn||v==fr}function Ep(p){return typeof p=="number"&&p==Mr(p)}function Pd(p){return typeof p=="number"&&p>-1&&p%1==0&&p<=Xt}function bu(p){var v=typeof p;return p!=null&&(v=="object"||v=="function")}function Yu(p){return p!=null&&typeof p=="object"}var Dp=Z?_i(Z):Wn;function wp(p,v){return p===v||si(p,v,jn(v))}function uv(p,v,x){return x=typeof x=="function"?x:i,si(p,v,jn(v),x)}function Im(p){return ov(p)&&p!=+p}function bm(p){if(Nl(p))throw new Kt(c);return ur(p)}function Bm(p){return p===null}function Id(p){return p==null}function ov(p){return typeof p=="number"||Yu(p)&>(p)==jt}function xc(p){if(!Yu(p)||gt(p)!=vr)return!1;var v=il(p);if(v===null)return!0;var x=li.call(v,"constructor")&&v.constructor;return typeof x=="function"&&x instanceof x&&Fu.call(x)==aa}var w1=ke?_i(ke):ci;function Um(p){return Ep(p)&&p>=-Xt&&p<=Xt}var bd=Je?_i(Je):Qi;function S1(p){return typeof p=="string"||!tr(p)&&Yu(p)&>(p)==wu}function Bl(p){return typeof p=="symbol"||Yu(p)&>(p)==d0}var Ra=vt?_i(vt):Gr;function lv(p){return p===i}function jm(p){return Yu(p)&&Iu(p)==Jo}function sv(p){return Yu(p)&>(p)==Ps}var av=gd(ld),zm=gd(function(p,v){return p<=v});function fv(p){if(!p)return[];if(hl(p))return S1(p)?ei(p):iu(p);if(Pu&&p[Pu])return Qu(p[Pu]());var v=Iu(p),x=v==w?Tu:v==Qt?$0:Nc;return x(p)}function Oa(p){if(!p)return p===0?p:0;if(p=vl(p),p===It||p===-It){var v=p<0?-1:1;return v*rt}return p===p?p:0}function Mr(p){var v=Oa(p),x=v%1;return v===v?x?v-x:v:0}function Sp(p){return p?r0(Mr(p),0,de):0}function vl(p){if(typeof p=="number")return p;if(Bl(p))return X;if(bu(p)){var v=typeof p.valueOf=="function"?p.valueOf():p;p=bu(v)?v+"":v}if(typeof p!="string")return p===0?p:+p;p=Nu(p);var x=ao.test(p);return x||Lo.test(p)?Us(p.slice(2),x?2:8):ai.test(p)?X:+p}function yu(p){return M0(p,dn(p))}function T1(p){return p?r0(Mr(p),-Xt,Xt):p===0?p:0}function Ui(p){return p==null?"":al(p)}var Tp=uo(function(p,v){if(Nf(v)||hl(v)){M0(v,L0(v),p);return}for(var x in v)li.call(v,x)&&Ts(p,x,v[x])}),Bd=uo(function(p,v){M0(v,dn(v),p)}),To=uo(function(p,v,x,P){M0(v,dn(v),p,P)}),Os=uo(function(p,v,x,P){M0(v,L0(v),p,P)}),Bf=cl(Wa);function Ud(p,v){var x=ri(p);return v==null?x:Df(x,v)}var Cp=Ir(function(p,v){p=xn(p);var x=-1,P=v.length,W=P>2?v[2]:i;for(W&&lo(v[0],v[1],W)&&(P=1);++x1),ee}),M0(p,sr(p),x),P&&(x=j0(x,T|B|H,cm));for(var W=v.length;W--;)R2(x,v[W]);return x});function R1(p,v){return tf(p,Od(Vn(v)))}var Rp=cl(function(p,v){return p==null?{}:vh(p,v)});function tf(p,v){if(p==null)return{};var x=Nt(sr(p),function(P){return[P]});return v=Vn(v),mh(p,x,function(P,W){return v(P,W[0])})}function Hm(p,v,x){v=Vs(v,p);var P=-1,W=v.length;for(W||(W=1,p=i);++Pv){var P=p;p=v,v=P}if(x||p%1||v%1){var W=E0();return Kn(p+W*(v-p+Ba("1e-"+((W+"").length-1))),v)}return fd(p,v)}var Gd=xf(function(p,v,x){return v=v.toLowerCase(),p+(x?Wo(v):v)});function Wo(p){return kp(Ui(p).toLowerCase())}function Yd(p){return p=Ui(p),p&&p.replace($n,Io).replace(J0,"")}function Wm(p,v,x){p=Ui(p),v=al(v);var P=p.length;x=x===i?P:r0(Mr(x),0,P);var W=x;return x-=v.length,x>=0&&p.slice(x,W)==v}function k1(p){return p=Ui(p),p&&Is.test(p)?p.replace(au,ys):p}function Vm(p){return p=Ui(p),p&&en.test(p)?p.replace(gi,"\\$&"):p}var Gm=xf(function(p,v,x){return p+(x?"-":"")+v.toLowerCase()}),dv=xf(function(p,v,x){return p+(x?" ":"")+v.toLowerCase()}),Ym=wh("toLowerCase");function pv(p,v,x){p=Ui(p),v=Mr(v);var P=v?tu(p):0;if(!v||P>=v)return p;var W=(v-P)/2;return Ea(Ds(W),x)+p+Ea($u(W),x)}function Km(p,v,x){p=Ui(p),v=Mr(v);var P=v?tu(p):0;return v&&P>>0,x?(p=Ui(p),p&&(typeof v=="string"||v!=null&&!w1(v))&&(v=al(v),!v&&Bo(p))?ma(ei(p),0,x):p.split(v,x)):[]}var Hf=xf(function(p,v,x){return p+(x?" ":"")+kp(v)});function vv(p,v,x){return p=Ui(p),x=x==null?0:r0(Mr(x),0,p.length),v=al(v),p.slice(x,x+v.length)==v}function mv(p,v,x){var P=Y.templateSettings;x&&lo(p,v,x)&&(v=i),p=Ui(p),v=To({},v,P,Rf);var W=To({},v.imports,P.imports,Rf),ee=L0(W),ve=Po(W,ee),Ee,Ie,_t=0,St=v.interpolate||tl,Rt="__p += '",on=gu((v.escape||tl).source+"|"+St.source+"|"+(St===p0?Ql:tl).source+"|"+(v.evaluate||tl).source+"|$","g"),kn="//# sourceURL="+(li.call(v,"sourceURL")?(v.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++fc+"]")+` +`;p.replace(on,function(ar,ui,di,zl,Zi,so){return di||(di=zl),Rt+=p.slice(_t,so).replace(fo,zs),ui&&(Ee=!0,Rt+=`' + +__e(`+ui+`) + +'`),Zi&&(Ie=!0,Rt+=`'; +`+Zi+`; +__p += '`),di&&(Rt+=`' + +((__t = (`+di+`)) == null ? '' : __t) + +'`),_t=so+ar.length,ar}),Rt+=`'; +`;var rr=li.call(v,"variable")&&v.variable;if(!rr)Rt=`with (obj) { +`+Rt+` +} +`;else if(Q0.test(rr))throw new Kt(t);Rt=(Ie?Rt.replace(Xr,""):Rt).replace(Oo,"$1").replace(Mo,"$1;"),Rt="function("+(rr||"obj")+`) { +`+(rr?"":`obj || (obj = {}); +`)+"var __t, __p = ''"+(Ee?", __e = _.escape":"")+(Ie?`, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +`:`; +`)+Rt+`return __p +}`;var br=wv(function(){return pr(ee,kn+"return "+Rt).apply(i,ve)});if(br.source=Rt,_p(br))throw br;return br}function gv(p){return Ui(p).toLowerCase()}function Kd(p){return Ui(p).toUpperCase()}function Xd(p,v,x){if(p=Ui(p),p&&(x||v===i))return Nu(p);if(!p||!(v=al(v)))return p;var P=ei(p),W=ei(v),ee=vf(P,W),ve=Tl(P,W)+1;return ma(P,ee,ve).join("")}function Mp(p,v,x){if(p=Ui(p),p&&(x||v===i))return p.slice(0,ho(p)+1);if(!p||!(v=al(v)))return p;var P=ei(p),W=Tl(P,ei(v))+1;return ma(P,0,W).join("")}function yv(p,v,x){if(p=Ui(p),p&&(x||v===i))return p.replace(bn,"");if(!p||!(v=al(v)))return p;var P=ei(p),W=vf(P,ei(v));return ma(P,W).join("")}function Qd(p,v){var x=Ue,P=je;if(bu(v)){var W="separator"in v?v.separator:W;x="length"in v?Mr(v.length):x,P="omission"in v?al(v.omission):P}p=Ui(p);var ee=p.length;if(Bo(p)){var ve=ei(p);ee=ve.length}if(x>=ee)return p;var Ee=x-tu(P);if(Ee<1)return P;var Ie=ve?ma(ve,0,Ee).join(""):p.slice(0,Ee);if(W===i)return Ie+P;if(ve&&(Ee+=Ie.length-Ee),w1(W)){if(p.slice(Ee).search(W)){var _t,St=Ie;for(W.global||(W=gu(W.source,Ui(ko.exec(W))+"g")),W.lastIndex=0;_t=W.exec(St);)var Rt=_t.index;Ie=Ie.slice(0,Rt===i?Ee:Rt)}}else if(p.indexOf(al(W),Ee)!=Ee){var on=Ie.lastIndexOf(W);on>-1&&(Ie=Ie.slice(0,on))}return Ie+P}function _v(p){return p=Ui(p),p&&Li.test(p)?p.replace(F0,Bi):p}var Ev=xf(function(p,v,x){return p+(x?" ":"")+v.toUpperCase()}),kp=wh("toUpperCase");function Dv(p,v,x){return p=Ui(p),v=x?i:v,v===i?_s(p)?yf(p):y0(p):p.match(v)||[]}var wv=Ir(function(p,v){try{return ue(p,i,v)}catch(x){return _p(x)?x:new Kt(x)}}),$m=cl(function(p,v){return nt(v,function(x){x=Fl(x),Gu(p,x,D1(p[x],p))}),p});function Sv(p){var v=p==null?0:p.length,x=Vn();return p=v?Nt(p,function(P){if(typeof P[1]!="function")throw new ti(_);return[x(P[0]),P[1]]}):[],Ir(function(P){for(var W=-1;++WXt)return[];var x=de,P=Kn(p,de);v=Vn(v),p-=de;for(var W=T0(P,v);++x0||v<0)?new ft(x):(p<0?x=x.takeRight(-p):p&&(x=x.drop(p)),v!==i&&(v=Mr(v),x=v<0?x.dropRight(-v):x.take(v-p)),x)},ft.prototype.takeRightWhile=function(p){return this.reverse().takeWhile(p).reverse()},ft.prototype.toArray=function(){return this.take(de)},A(ft.prototype,function(p,v){var x=/^(?:filter|find|map|reject)|While$/.test(v),P=/^(?:head|last)$/.test(v),W=Y[P?"take"+(v=="last"?"Right":""):v],ee=P||/^find/.test(v);!W||(Y.prototype[v]=function(){var ve=this.__wrapped__,Ee=P?[1]:arguments,Ie=ve instanceof ft,_t=Ee[0],St=Ie||tr(ve),Rt=function(ui){var di=W.apply(Y,Dn([ui],Ee));return P&&on?di[0]:di};St&&x&&typeof _t=="function"&&_t.length!=1&&(Ie=St=!1);var on=this.__chain__,kn=!!this.__actions__.length,rr=ee&&!on,br=Ie&&!kn;if(!ee&&St){ve=br?ve:new ft(this);var ar=p.apply(ve,Ee);return ar.__actions__.push({func:y1,args:[Rt],thisArg:i}),new Vr(ar,on)}return rr&&br?p.apply(this,Ee):(ar=this.thru(Rt),rr?P?ar.value()[0]:ar.value():ar)})}),nt(["pop","push","shift","sort","splice","unshift"],function(p){var v=Jr[p],x=/^(?:push|sort|unshift)$/.test(p)?"tap":"thru",P=/^(?:pop|shift)$/.test(p);Y.prototype[p]=function(){var W=arguments;if(P&&!this.__chain__){var ee=this.value();return v.apply(tr(ee)?ee:[],W)}return this[x](function(ve){return v.apply(tr(ve)?ve:[],W)})}}),A(ft.prototype,function(p,v){var x=Y[v];if(x){var P=x.name+"";li.call(On,P)||(On[P]=[]),On[P].push({name:v,func:x})}}),On[ya(i,he).name]=[{name:"wrapper",func:i}],ft.prototype.clone=Di,ft.prototype.reverse=ru,ft.prototype.value=D0,Y.prototype.at=$2,Y.prototype.chain=qh,Y.prototype.commit=ep,Y.prototype.next=Wh,Y.prototype.plant=Em,Y.prototype.reverse=If,Y.prototype.toJSON=Y.prototype.valueOf=Y.prototype.value=bf,Y.prototype.first=Y.prototype.head,Pu&&(Y.prototype[Pu]=_m),Y},to=eo();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(ji._=to,define(function(){return to})):z?((z.exports=to)._=to,U._=to):ji._=to}).call(Wv)});var mD=Ke((wW,vD)=>{"use strict";var Ii=vD.exports;vD.exports.default=Ii;var Du="[",jg="]",Vv="\x07",P_=";",kS=process.env.TERM_PROGRAM==="Apple_Terminal";Ii.cursorTo=(i,o)=>{if(typeof i!="number")throw new TypeError("The `x` argument is required");return typeof o!="number"?Du+(i+1)+"G":Du+(o+1)+";"+(i+1)+"H"};Ii.cursorMove=(i,o)=>{if(typeof i!="number")throw new TypeError("The `x` argument is required");let a="";return i<0?a+=Du+-i+"D":i>0&&(a+=Du+i+"C"),o<0?a+=Du+-o+"A":o>0&&(a+=Du+o+"B"),a};Ii.cursorUp=(i=1)=>Du+i+"A";Ii.cursorDown=(i=1)=>Du+i+"B";Ii.cursorForward=(i=1)=>Du+i+"C";Ii.cursorBackward=(i=1)=>Du+i+"D";Ii.cursorLeft=Du+"G";Ii.cursorSavePosition=kS?"7":Du+"s";Ii.cursorRestorePosition=kS?"8":Du+"u";Ii.cursorGetPosition=Du+"6n";Ii.cursorNextLine=Du+"E";Ii.cursorPrevLine=Du+"F";Ii.cursorHide=Du+"?25l";Ii.cursorShow=Du+"?25h";Ii.eraseLines=i=>{let o="";for(let a=0;a[jg,"8",P_,P_,o,Vv,i,jg,"8",P_,P_,Vv].join("");Ii.image=(i,o={})=>{let a=`${jg}1337;File=inline=1`;return o.width&&(a+=`;width=${o.width}`),o.height&&(a+=`;height=${o.height}`),o.preserveAspectRatio===!1&&(a+=";preserveAspectRatio=0"),a+":"+i.toString("base64")+Vv};Ii.iTerm={setCwd:(i=process.cwd())=>`${jg}50;CurrentDir=${i}${Vv}`,annotation:(i,o={})=>{let a=`${jg}1337;`,c=typeof o.x!="undefined",_=typeof o.y!="undefined";if((c||_)&&!(c&&_&&typeof o.length!="undefined"))throw new Error("`x`, `y` and `length` must be defined when `x` or `y` is defined");return i=i.replace(/\|/g,""),a+=o.isHidden?"AddHiddenAnnotation=":"AddAnnotation=",o.length>0?a+=(c?[i,o.length,o.x,o.y]:[o.length,i]).join("|"):a+=i,a+Vv}}});var NS=Ke((SW,gD)=>{"use strict";var LS=(i,o)=>{for(let a of Reflect.ownKeys(o))Object.defineProperty(i,a,Object.getOwnPropertyDescriptor(o,a));return i};gD.exports=LS;gD.exports.default=LS});var IS=Ke((TW,I_)=>{"use strict";var AI=NS(),b_=new WeakMap,PS=(i,o={})=>{if(typeof i!="function")throw new TypeError("Expected a function");let a,c=!1,_=0,t=i.displayName||i.name||"",O=function(...N){if(b_.set(O,++_),c){if(o.throw===!0)throw new Error(`Function \`${t}\` can only be called once`);return a}return c=!0,a=i.apply(this,N),i=null,a};return AI(O,i),b_.set(O,_),O};I_.exports=PS;I_.exports.default=PS;I_.exports.callCount=i=>{if(!b_.has(i))throw new Error(`The given function \`${i.name}\` is not wrapped by the \`onetime\` package`);return b_.get(i)}});var bS=Ke((CW,B_)=>{B_.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];process.platform!=="win32"&&B_.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&B_.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")});var DD=Ke((xW,zg)=>{var RI=require("assert"),Hg=bS(),OI=/^win/i.test(process.platform),U_=require("events");typeof U_!="function"&&(U_=U_.EventEmitter);var Yl;process.__signal_exit_emitter__?Yl=process.__signal_exit_emitter__:(Yl=process.__signal_exit_emitter__=new U_,Yl.count=0,Yl.emitted={});Yl.infinite||(Yl.setMaxListeners(Infinity),Yl.infinite=!0);zg.exports=function(i,o){RI.equal(typeof i,"function","a callback must be provided for exit handler"),qg===!1&&BS();var a="exit";o&&o.alwaysLast&&(a="afterexit");var c=function(){Yl.removeListener(a,i),Yl.listeners("exit").length===0&&Yl.listeners("afterexit").length===0&&yD()};return Yl.on(a,i),c};zg.exports.unload=yD;function yD(){!qg||(qg=!1,Hg.forEach(function(i){try{process.removeListener(i,_D[i])}catch(o){}}),process.emit=ED,process.reallyExit=US,Yl.count-=1)}function Gv(i,o,a){Yl.emitted[i]||(Yl.emitted[i]=!0,Yl.emit(i,o,a))}var _D={};Hg.forEach(function(i){_D[i]=function(){var a=process.listeners(i);a.length===Yl.count&&(yD(),Gv("exit",null,i),Gv("afterexit",null,i),OI&&i==="SIGHUP"&&(i="SIGINT"),process.kill(process.pid,i))}});zg.exports.signals=function(){return Hg};zg.exports.load=BS;var qg=!1;function BS(){qg||(qg=!0,Yl.count+=1,Hg=Hg.filter(function(i){try{return process.on(i,_D[i]),!0}catch(o){return!1}}),process.emit=kI,process.reallyExit=MI)}var US=process.reallyExit;function MI(i){process.exitCode=i||0,Gv("exit",process.exitCode,null),Gv("afterexit",process.exitCode,null),US.call(process,process.exitCode)}var ED=process.emit;function kI(i,o){if(i==="exit"){o!==void 0&&(process.exitCode=o);var a=ED.apply(this,arguments);return Gv("exit",process.exitCode,null),Gv("afterexit",process.exitCode,null),a}else return ED.apply(this,arguments)}});var zS=Ke((AW,jS)=>{"use strict";var LI=IS(),NI=DD();jS.exports=LI(()=>{NI(()=>{process.stderr.write("[?25h")},{alwaysLast:!0})})});var wD=Ke(Yv=>{"use strict";var FI=zS(),j_=!1;Yv.show=(i=process.stderr)=>{!i.isTTY||(j_=!1,i.write("[?25h"))};Yv.hide=(i=process.stderr)=>{!i.isTTY||(FI(),j_=!0,i.write("[?25l"))};Yv.toggle=(i,o)=>{i!==void 0&&(j_=i),j_?Yv.show(o):Yv.hide(o)}});var VS=Ke(Wg=>{"use strict";var HS=Wg&&Wg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Wg,"__esModule",{value:!0});var qS=HS(mD()),WS=HS(wD()),PI=(i,{showCursor:o=!1}={})=>{let a=0,c="",_=!1,t=O=>{!o&&!_&&(WS.default.hide(),_=!0);let N=O+` +`;N!==c&&(c=N,i.write(qS.default.eraseLines(a)+N),a=N.split(` +`).length)};return t.clear=()=>{i.write(qS.default.eraseLines(a)),c="",a=0},t.done=()=>{c="",a=0,o||(WS.default.show(),_=!1)},t};Wg.default={create:PI}});var YS=Ke((MW,GS)=>{GS.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY_BUILD_BASE",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}}]});var QS=Ke(Pa=>{"use strict";var KS=YS(),jc=process.env;Object.defineProperty(Pa,"_vendors",{value:KS.map(function(i){return i.constant})});Pa.name=null;Pa.isPR=null;KS.forEach(function(i){var o=Array.isArray(i.env)?i.env:[i.env],a=o.every(function(c){return XS(c)});if(Pa[i.constant]=a,a)switch(Pa.name=i.name,typeof i.pr){case"string":Pa.isPR=!!jc[i.pr];break;case"object":"env"in i.pr?Pa.isPR=i.pr.env in jc&&jc[i.pr.env]!==i.pr.ne:"any"in i.pr?Pa.isPR=i.pr.any.some(function(c){return!!jc[c]}):Pa.isPR=XS(i.pr);break;default:Pa.isPR=null}});Pa.isCI=!!(jc.CI||jc.CONTINUOUS_INTEGRATION||jc.BUILD_NUMBER||jc.RUN_ID||Pa.name);function XS(i){return typeof i=="string"?!!jc[i]:Object.keys(i).every(function(o){return jc[o]===i[o]})}});var ZS=Ke((LW,JS)=>{"use strict";JS.exports=QS().isCI});var eT=Ke((NW,$S)=>{"use strict";var II=i=>{let o=new Set;do for(let a of Reflect.ownKeys(i))o.add([i,a]);while((i=Reflect.getPrototypeOf(i))&&i!==Object.prototype);return o};$S.exports=(i,{include:o,exclude:a}={})=>{let c=_=>{let t=O=>typeof O=="string"?_===O:O.test(_);return o?o.some(t):a?!a.some(t):!0};for(let[_,t]of II(i.constructor.prototype)){if(t==="constructor"||!c(t))continue;let O=Reflect.getOwnPropertyDescriptor(_,t);O&&typeof O.value=="function"&&(i[t]=i[t].bind(i))}return i}});var lT=Ke(lu=>{"use strict";Object.defineProperty(lu,"__esModule",{value:!0});var Kv,Vg,z_,H_,SD;typeof window=="undefined"||typeof MessageChannel!="function"?(Xv=null,TD=null,CD=function(){if(Xv!==null)try{var i=lu.unstable_now();Xv(!0,i),Xv=null}catch(o){throw setTimeout(CD,0),o}},tT=Date.now(),lu.unstable_now=function(){return Date.now()-tT},Kv=function(i){Xv!==null?setTimeout(Kv,0,i):(Xv=i,setTimeout(CD,0))},Vg=function(i,o){TD=setTimeout(i,o)},z_=function(){clearTimeout(TD)},H_=function(){return!1},SD=lu.unstable_forceFrameRate=function(){}):(q_=window.performance,xD=window.Date,nT=window.setTimeout,rT=window.clearTimeout,typeof console!="undefined"&&(iT=window.cancelAnimationFrame,typeof window.requestAnimationFrame!="function"&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),typeof iT!="function"&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")),typeof q_=="object"&&typeof q_.now=="function"?lu.unstable_now=function(){return q_.now()}:(uT=xD.now(),lu.unstable_now=function(){return xD.now()-uT}),Gg=!1,Yg=null,W_=-1,AD=5,RD=0,H_=function(){return lu.unstable_now()>=RD},SD=function(){},lu.unstable_forceFrameRate=function(i){0>i||125G_(O,a))M!==void 0&&0>G_(M,O)?(i[c]=M,i[N]=a,c=N):(i[c]=O,i[t]=a,c=t);else if(M!==void 0&&0>G_(M,a))i[c]=M,i[N]=a,c=N;else break e}}return o}return null}function G_(i,o){var a=i.sortIndex-o.sortIndex;return a!==0?a:i.id-o.id}var ec=[],d2=[],bI=1,Fs=null,ps=3,K_=!1,$p=!1,Kg=!1;function X_(i){for(var o=df(d2);o!==null;){if(o.callback===null)Y_(d2);else if(o.startTime<=i)Y_(d2),o.sortIndex=o.expirationTime,MD(ec,o);else break;o=df(d2)}}function kD(i){if(Kg=!1,X_(i),!$p)if(df(ec)!==null)$p=!0,Kv(LD);else{var o=df(d2);o!==null&&Vg(kD,o.startTime-i)}}function LD(i,o){$p=!1,Kg&&(Kg=!1,z_()),K_=!0;var a=ps;try{for(X_(o),Fs=df(ec);Fs!==null&&(!(Fs.expirationTime>o)||i&&!H_());){var c=Fs.callback;if(c!==null){Fs.callback=null,ps=Fs.priorityLevel;var _=c(Fs.expirationTime<=o);o=lu.unstable_now(),typeof _=="function"?Fs.callback=_:Fs===df(ec)&&Y_(ec),X_(o)}else Y_(ec);Fs=df(ec)}if(Fs!==null)var t=!0;else{var O=df(d2);O!==null&&Vg(kD,O.startTime-o),t=!1}return t}finally{Fs=null,ps=a,K_=!1}}function oT(i){switch(i){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var BI=SD;lu.unstable_ImmediatePriority=1;lu.unstable_UserBlockingPriority=2;lu.unstable_NormalPriority=3;lu.unstable_IdlePriority=5;lu.unstable_LowPriority=4;lu.unstable_runWithPriority=function(i,o){switch(i){case 1:case 2:case 3:case 4:case 5:break;default:i=3}var a=ps;ps=i;try{return o()}finally{ps=a}};lu.unstable_next=function(i){switch(ps){case 1:case 2:case 3:var o=3;break;default:o=ps}var a=ps;ps=o;try{return i()}finally{ps=a}};lu.unstable_scheduleCallback=function(i,o,a){var c=lu.unstable_now();if(typeof a=="object"&&a!==null){var _=a.delay;_=typeof _=="number"&&0<_?c+_:c,a=typeof a.timeout=="number"?a.timeout:oT(i)}else a=oT(i),_=c;return a=_+a,i={id:bI++,callback:o,priorityLevel:i,startTime:_,expirationTime:a,sortIndex:-1},_>c?(i.sortIndex=_,MD(d2,i),df(ec)===null&&i===df(d2)&&(Kg?z_():Kg=!0,Vg(kD,_-c))):(i.sortIndex=a,MD(ec,i),$p||K_||($p=!0,Kv(LD))),i};lu.unstable_cancelCallback=function(i){i.callback=null};lu.unstable_wrapCallback=function(i){var o=ps;return function(){var a=ps;ps=o;try{return i.apply(this,arguments)}finally{ps=a}}};lu.unstable_getCurrentPriorityLevel=function(){return ps};lu.unstable_shouldYield=function(){var i=lu.unstable_now();X_(i);var o=df(ec);return o!==Fs&&Fs!==null&&o!==null&&o.callback!==null&&o.startTime<=i&&o.expirationTime{"use strict";process.env.NODE_ENV!=="production"&&function(){"use strict";Object.defineProperty(bi,"__esModule",{value:!0});var i=!1,o=!1,a=!0,c,_,t,O,N;if(typeof window=="undefined"||typeof MessageChannel!="function"){var M=null,T=null,B=function(){if(M!==null)try{var wt=bi.unstable_now(),bt=!0;M(bt,wt),M=null}catch(Hn){throw setTimeout(B,0),Hn}},H=Date.now();bi.unstable_now=function(){return Date.now()-H},c=function(wt){M!==null?setTimeout(c,0,wt):(M=wt,setTimeout(B,0))},_=function(wt,bt){T=setTimeout(wt,bt)},t=function(){clearTimeout(T)},O=function(){return!1},N=bi.unstable_forceFrameRate=function(){}}else{var q=window.performance,ne=window.Date,m=window.setTimeout,he=window.clearTimeout;if(typeof console!="undefined"){var De=window.requestAnimationFrame,se=window.cancelAnimationFrame;typeof De!="function"&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),typeof se!="function"&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if(typeof q=="object"&&typeof q.now=="function")bi.unstable_now=function(){return q.now()};else{var fe=ne.now();bi.unstable_now=function(){return ne.now()-fe}}var _e=!1,ce=null,me=-1,ie=5,Oe=0,Ue=300,je=!1;if(o&&navigator!==void 0&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0){var at=navigator.scheduling;O=function(){var wt=bi.unstable_now();return wt>=Oe?je||at.isInputPending()?!0:wt>=Ue:!1},N=function(){je=!0}}else O=function(){return bi.unstable_now()>=Oe},N=function(){};bi.unstable_forceFrameRate=function(wt){if(wt<0||wt>125){console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported");return}wt>0?ie=Math.floor(1e3/wt):ie=5};var Dt=function(){if(ce!==null){var wt=bi.unstable_now();Oe=wt+ie;var bt=!0;try{var Hn=ce(bt,wt);Hn?ut.postMessage(null):(_e=!1,ce=null)}catch(qr){throw ut.postMessage(null),qr}}else _e=!1;je=!1},Qe=new MessageChannel,ut=Qe.port2;Qe.port1.onmessage=Dt,c=function(wt){ce=wt,_e||(_e=!0,ut.postMessage(null))},_=function(wt,bt){me=m(function(){wt(bi.unstable_now())},bt)},t=function(){he(me),me=-1}}function Ve(wt,bt){var Hn=wt.length;wt.push(bt),rt(wt,bt,Hn)}function It(wt){var bt=wt[0];return bt===void 0?null:bt}function Xt(wt){var bt=wt[0];if(bt!==void 0){var Hn=wt.pop();return Hn!==bt&&(wt[0]=Hn,X(wt,Hn,0)),bt}else return null}function rt(wt,bt,Hn){for(var qr=Hn;;){var Ki=Math.floor((qr-1)/2),Qr=wt[Ki];if(Qr!==void 0&&de(Qr,bt)>0)wt[Ki]=bt,wt[qr]=Qr,qr=Ki;else return}}function X(wt,bt,Hn){for(var qr=Hn,Ki=wt.length;qrfr){if(fr*=2,fr>jr){console.error("Scheduler Profiling: Event log exceeded maximum size. Don't forget to call `stopLoggingProfilingEvents()`."),wr();return}var Hn=new Int32Array(fr*4);Hn.set(Qt),zr=Hn.buffer,Qt=Hn}Qt.set(wt,bt)}}function mi(){fr=vr,zr=new ArrayBuffer(fr*4),Qt=new Int32Array(zr),wu=0}function wr(){var wt=zr;return fr=0,zr=null,Qt=null,wu=0,wt}function el(wt,bt){a&&(Vt[Xn]++,Qt!==null&&su([d0,bt*1e3,wt.id,wt.priorityLevel]))}function Y0(wt,bt){a&&(Vt[Dr]=Ce,Vt[w]=0,Vt[Xn]--,Qt!==null&&su([Ro,bt*1e3,wt.id]))}function Uu(wt,bt){a&&(Vt[Xn]--,Qt!==null&&su([Ps,bt*1e3,wt.id]))}function K0(wt,bt){a&&(Vt[Dr]=Ce,Vt[w]=0,Vt[Xn]--,Qt!==null&&su([Jo,bt*1e3,wt.id]))}function Xr(wt,bt){a&&(an++,Vt[Dr]=wt.priorityLevel,Vt[w]=wt.id,Vt[jt]=an,Qt!==null&&su([Zo,bt*1e3,wt.id,an]))}function Oo(wt,bt){a&&(Vt[Dr]=Ce,Vt[w]=0,Vt[jt]=0,Qt!==null&&su([$o,bt*1e3,wt.id,an]))}function Mo(wt){a&&(Mn++,Qt!==null&&su([qt,wt*1e3,Mn]))}function F0(wt){a&&Qt!==null&&su([Ai,wt*1e3,Mn])}var au=1073741823,Li=-1,Is=250,Xl=5e3,P0=1e4,p0=au,Hr=[],Ri=[],X0=1,gi=!1,en=null,bn=dt,Oi=!1,yi=!1,Wt=!1;function Ru(wt){for(var bt=It(Ri);bt!==null;){if(bt.callback===null)Xt(Ri);else if(bt.startTime<=wt)Xt(Ri),bt.sortIndex=bt.expirationTime,Ve(Hr,bt),a&&(el(bt,wt),bt.isQueued=!0);else return;bt=It(Ri)}}function eu(wt){if(Wt=!1,Ru(wt),!yi)if(It(Hr)!==null)yi=!0,c(Q0);else{var bt=It(Ri);bt!==null&&_(eu,bt.startTime-wt)}}function Q0(wt,bt){a&&F0(bt),yi=!1,Wt&&(Wt=!1,t()),Oi=!0;var Hn=bn;try{if(a)try{return Yi(wt,bt)}catch(Qr){if(en!==null){var qr=bi.unstable_now();K0(en,qr),en.isQueued=!1}throw Qr}else return Yi(wt,bt)}finally{if(en=null,bn=Hn,Oi=!1,a){var Ki=bi.unstable_now();Mo(Ki)}}}function Yi(wt,bt){var Hn=bt;for(Ru(Hn),en=It(Hr);en!==null&&!(i&&gi)&&!(en.expirationTime>Hn&&(!wt||O()));){var qr=en.callback;if(qr!==null){en.callback=null,bn=en.priorityLevel;var Ki=en.expirationTime<=Hn;Xr(en,Hn);var Qr=qr(Ki);Hn=bi.unstable_now(),typeof Qr=="function"?(en.callback=Qr,Oo(en,Hn)):(a&&(Y0(en,Hn),en.isQueued=!1),en===It(Hr)&&Xt(Hr)),Ru(Hn)}else Xt(Hr);en=It(Hr)}if(en!==null)return!0;var Ou=It(Ri);return Ou!==null&&_(eu,Ou.startTime-Hn),!1}function Ql(wt,bt){switch(wt){case oe:case He:case dt:case At:case nn:break;default:wt=dt}var Hn=bn;bn=wt;try{return bt()}finally{bn=Hn}}function ko(wt){var bt;switch(bn){case oe:case He:case dt:bt=dt;break;default:bt=bn;break}var Hn=bn;bn=bt;try{return wt()}finally{bn=Hn}}function ai(wt){var bt=bn;return function(){var Hn=bn;bn=bt;try{return wt.apply(this,arguments)}finally{bn=Hn}}}function ao(wt){switch(wt){case oe:return Li;case He:return Is;case nn:return p0;case At:return P0;case dt:default:return Xl}}function Jl(wt,bt,Hn){var qr=bi.unstable_now(),Ki,Qr;if(typeof Hn=="object"&&Hn!==null){var Ou=Hn.delay;typeof Ou=="number"&&Ou>0?Ki=qr+Ou:Ki=qr,Qr=typeof Hn.timeout=="number"?Hn.timeout:ao(wt)}else Qr=ao(wt),Ki=qr;var h0=Ki+Qr,Ni={id:X0++,callback:bt,priorityLevel:wt,startTime:Ki,expirationTime:h0,sortIndex:-1};return a&&(Ni.isQueued=!1),Ki>qr?(Ni.sortIndex=Ki,Ve(Ri,Ni),It(Hr)===null&&Ni===It(Ri)&&(Wt?t():Wt=!0,_(eu,Ki-qr))):(Ni.sortIndex=h0,Ve(Hr,Ni),a&&(el(Ni,qr),Ni.isQueued=!0),!yi&&!Oi&&(yi=!0,c(Q0))),Ni}function Lo(){gi=!0}function bs(){gi=!1,!yi&&!Oi&&(yi=!0,c(Q0))}function $n(){return It(Hr)}function tl(wt){if(a&&wt.isQueued){var bt=bi.unstable_now();Uu(wt,bt),wt.isQueued=!1}wt.callback=null}function fo(){return bn}function I0(){var wt=bi.unstable_now();Ru(wt);var bt=It(Hr);return bt!==en&&en!==null&&bt!==null&&bt.callback!==null&&bt.startTime<=wt&&bt.expirationTime{"use strict";process.env.NODE_ENV==="production"?ND.exports=lT():ND.exports=sT()});var aT=Ke((bW,Xg)=>{Xg.exports=function i(o){"use strict";var a=Ig(),c=ki(),_=Q_();function t(y){for(var g="https://reactjs.org/docs/error-decoder.html?invariant="+y,A=1;AX0||(y.current=Ri[X0],Ri[X0]=null,X0--)}function en(y,g){X0++,Ri[X0]=y.current,y.current=g}var bn={},Oi={current:bn},yi={current:!1},Wt=bn;function Ru(y,g){var A=y.type.contextTypes;if(!A)return bn;var F=y.stateNode;if(F&&F.__reactInternalMemoizedUnmaskedChildContext===g)return F.__reactInternalMemoizedMaskedChildContext;var b={},J;for(J in A)b[J]=g[J];return F&&(y=y.stateNode,y.__reactInternalMemoizedUnmaskedChildContext=g,y.__reactInternalMemoizedMaskedChildContext=b),b}function eu(y){return y=y.childContextTypes,y!=null}function Q0(y){gi(yi,y),gi(Oi,y)}function Yi(y){gi(yi,y),gi(Oi,y)}function Ql(y,g,A){if(Oi.current!==bn)throw Error(t(168));en(Oi,g,y),en(yi,A,y)}function ko(y,g,A){var F=y.stateNode;if(y=g.childContextTypes,typeof F.getChildContext!="function")return A;F=F.getChildContext();for(var b in F)if(!(b in y))throw Error(t(108,Ue(g)||"Unknown",b));return a({},A,{},F)}function ai(y){var g=y.stateNode;return g=g&&g.__reactInternalMemoizedMergedChildContext||bn,Wt=Oi.current,en(Oi,g,y),en(yi,yi.current,y),!0}function ao(y,g,A){var F=y.stateNode;if(!F)throw Error(t(169));A?(g=ko(y,g,Wt),F.__reactInternalMemoizedMergedChildContext=g,gi(yi,y),gi(Oi,y),en(Oi,g,y)):gi(yi,y),en(yi,A,y)}var Jl=_.unstable_runWithPriority,Lo=_.unstable_scheduleCallback,bs=_.unstable_cancelCallback,$n=_.unstable_shouldYield,tl=_.unstable_requestPaint,fo=_.unstable_now,I0=_.unstable_getCurrentPriorityLevel,Sl=_.unstable_ImmediatePriority,No=_.unstable_UserBlockingPriority,wt=_.unstable_NormalPriority,bt=_.unstable_LowPriority,Hn=_.unstable_IdlePriority,qr={},Ki=tl!==void 0?tl:function(){},Qr=null,Ou=null,h0=!1,Ni=fo(),v0=1e4>Ni?fo:function(){return fo()-Ni};function vs(){switch(I0()){case Sl:return 99;case No:return 98;case wt:return 97;case bt:return 96;case Hn:return 95;default:throw Error(t(332))}}function Tt(y){switch(y){case 99:return Sl;case 98:return No;case 97:return wt;case 96:return bt;case 95:return Hn;default:throw Error(t(332))}}function co(y,g){return y=Tt(y),Jl(y,g)}function nl(y,g,A){return y=Tt(y),Lo(y,g,A)}function Zl(y){return Qr===null?(Qr=[y],Ou=Lo(Sl,ms)):Qr.push(y),qr}function ju(){if(Ou!==null){var y=Ou;Ou=null,bs(y)}ms()}function ms(){if(!h0&&Qr!==null){h0=!0;var y=0;try{var g=Qr;co(99,function(){for(;y=g&&(ho=!0),y.firstContext=null)}function ku(y,g){if(Mu!==y&&g!==!1&&g!==0)if((typeof g!="number"||g===1073741823)&&(Mu=y,g=1073741823),g={context:y,observedBits:g,next:null},Si===null){if(cr===null)throw Error(t(308));Si=g,cr.dependencies={expirationTime:0,firstContext:g,responders:null}}else Si=Si.next=g;return ln?y._currentValue:y._currentValue2}var po=!1;function qu(y){return{baseState:y,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Ia(y){return{baseState:y.baseState,firstUpdate:y.firstUpdate,lastUpdate:y.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function m0(y,g){return{expirationTime:y,suspenseConfig:g,tag:0,payload:null,callback:null,next:null,nextEffect:null}}function ua(y,g){y.lastUpdate===null?y.firstUpdate=y.lastUpdate=g:(y.lastUpdate.next=g,y.lastUpdate=g)}function J0(y,g){var A=y.alternate;if(A===null){var F=y.updateQueue,b=null;F===null&&(F=y.updateQueue=qu(y.memoizedState))}else F=y.updateQueue,b=A.updateQueue,F===null?b===null?(F=y.updateQueue=qu(y.memoizedState),b=A.updateQueue=qu(A.memoizedState)):F=y.updateQueue=Ia(b):b===null&&(b=A.updateQueue=Ia(F));b===null||F===b?ua(F,g):F.lastUpdate===null||b.lastUpdate===null?(ua(F,g),ua(b,g)):(ua(F,g),b.lastUpdate=g)}function oa(y,g){var A=y.updateQueue;A=A===null?y.updateQueue=qu(y.memoizedState):ba(y,A),A.lastCapturedUpdate===null?A.firstCapturedUpdate=A.lastCapturedUpdate=g:(A.lastCapturedUpdate.next=g,A.lastCapturedUpdate=g)}function ba(y,g){var A=y.alternate;return A!==null&&g===A.updateQueue&&(g=y.updateQueue=Ia(g)),g}function gs(y,g,A,F,b,J){switch(A.tag){case 1:return y=A.payload,typeof y=="function"?y.call(J,F,b):y;case 3:y.effectTag=y.effectTag&-4097|64;case 0:if(y=A.payload,b=typeof y=="function"?y.call(J,F,b):y,b==null)break;return a({},F,b);case 2:po=!0}return F}function S0(y,g,A,F,b){po=!1,g=ba(y,g);for(var J=g.baseState,pe=null,gt=0,xt=g.firstUpdate,kt=J;xt!==null;){var xr=xt.expirationTime;xrci?(Qi=ur,ur=null):Qi=ur.sibling;var Gr=du(We,ur,lt[ci],$t);if(Gr===null){ur===null&&(ur=Qi);break}y&&ur&&Gr.alternate===null&&g(We,ur),ze=J(Gr,ze,ci),si===null?Wn=Gr:si.sibling=Gr,si=Gr,ur=Qi}if(ci===lt.length)return A(We,ur),Wn;if(ur===null){for(;cici?(Qi=ur,ur=null):Qi=ur.sibling;var Cu=du(We,ur,Gr.value,$t);if(Cu===null){ur===null&&(ur=Qi);break}y&&ur&&Cu.alternate===null&&g(We,ur),ze=J(Cu,ze,ci),si===null?Wn=Cu:si.sibling=Cu,si=Cu,ur=Qi}if(Gr.done)return A(We,ur),Wn;if(ur===null){for(;!Gr.done;ci++,Gr=lt.next())Gr=i0(We,Gr.value,$t),Gr!==null&&(ze=J(Gr,ze,ci),si===null?Wn=Gr:si.sibling=Gr,si=Gr);return Wn}for(ur=F(We,ur);!Gr.done;ci++,Gr=lt.next())Gr=z0(ur,We,ci,Gr.value,$t),Gr!==null&&(y&&Gr.alternate!==null&&ur.delete(Gr.key===null?ci:Gr.key),ze=J(Gr,ze,ci),si===null?Wn=Gr:si.sibling=Gr,si=Gr);return y&&ur.forEach(function(Va){return g(We,Va)}),Wn}return function(We,ze,lt,$t){var Wn=typeof lt=="object"&<!==null&<.type===B&<.key===null;Wn&&(lt=lt.props.children);var si=typeof lt=="object"&<!==null;if(si)switch(lt.$$typeof){case M:e:{for(si=lt.key,Wn=ze;Wn!==null;){if(Wn.key===si)if(Wn.tag===7?lt.type===B:Wn.elementType===lt.type){A(We,Wn.sibling),ze=b(Wn,lt.type===B?lt.props.children:lt.props,$t),ze.ref=js(We,Wn,lt),ze.return=We,We=ze;break e}else{A(We,Wn);break}else g(We,Wn);Wn=Wn.sibling}lt.type===B?(ze=r0(lt.props.children,We.mode,$t,lt.key),ze.return=We,We=ze):($t=Wa(lt.type,lt.key,lt.props,null,We.mode,$t),$t.ref=js(We,ze,lt),$t.return=We,We=$t)}return pe(We);case T:e:{for(Wn=lt.key;ze!==null;){if(ze.key===Wn)if(ze.tag===4&&ze.stateNode.containerInfo===lt.containerInfo&&ze.stateNode.implementation===lt.implementation){A(We,ze.sibling),ze=b(ze,lt.children||[],$t),ze.return=We,We=ze;break e}else{A(We,ze);break}else g(We,ze);ze=ze.sibling}ze=wf(lt,We.mode,$t),ze.return=We,We=ze}return pe(We)}if(typeof lt=="string"||typeof lt=="number")return lt=""+lt,ze!==null&&ze.tag===6?(A(We,ze.sibling),ze=b(ze,lt,$t),ze.return=We,We=ze):(A(We,ze),ze=j0(lt,We.mode,$t),ze.return=We,We=ze),pe(We);if(g0(lt))return Ml(We,ze,lt,$t);if(ie(lt))return u0(We,ze,lt,$t);if(si&&ji(We,lt),typeof lt=="undefined"&&!Wn)switch(We.tag){case 1:case 0:throw We=We.type,Error(t(152,We.displayName||We.name||"Component"))}return A(We,ze)}}var z=U(!0),G=U(!1),$={},Te={current:$},ye={current:$},Ae={current:$};function Z(y){if(y===$)throw Error(t(174));return y}function ke(y,g){en(Ae,g,y),en(ye,y,y),en(Te,$,y),g=It(g),gi(Te,y),en(Te,g,y)}function Je(y){gi(Te,y),gi(ye,y),gi(Ae,y)}function vt(y){var g=Z(Ae.current),A=Z(Te.current);g=Xt(A,y.type,g),A!==g&&(en(ye,y,y),en(Te,g,y))}function ue(y){ye.current===y&&(gi(Te,y),gi(ye,y))}var qe={current:0};function nt(y){for(var g=y;g!==null;){if(g.tag===13){var A=g.memoizedState;if(A!==null&&(A=A.dehydrated,A===null||Xr(A)||Oo(A)))return g}else if(g.tag===19&&g.memoizedProps.revealOrder!==void 0){if((g.effectTag&64)!=0)return g}else if(g.child!==null){g.child.return=g,g=g.child;continue}if(g===y)break;for(;g.sibling===null;){if(g.return===null||g.return===y)return null;g=g.return}g.sibling.return=g.return,g=g.sibling}return null}function Ct(y,g){return{responder:y,props:g}}var Mt=O.ReactCurrentDispatcher,Pt=O.ReactCurrentBatchConfig,sn=0,rn=null,Nt=null,Dn=null,dr=null,er=null,Cr=null,Rn=0,Lr=null,y0=0,Nr=!1,it=null,Et=0;function et(){throw Error(t(321))}function Ft(y,g){if(g===null)return!1;for(var A=0;ARn&&(Rn=xr,ja(Rn))):(dc(xr,xt.suspenseConfig),J=xt.eagerReducer===y?xt.eagerState:y(J,xt.action)),pe=xt,xt=xt.next}while(xt!==null&&xt!==F);kt||(gt=pe,b=J),Ne(J,g.memoizedState)||(ho=!0),g.memoizedState=J,g.baseUpdate=gt,g.baseState=b,A.lastRenderedState=J}return[g.memoizedState,A.dispatch]}function T0(y){var g=Jn();return typeof y=="function"&&(y=y()),g.memoizedState=g.baseState=y,y=g.queue={last:null,dispatch:null,lastRenderedReducer:fu,lastRenderedState:y},y=y.dispatch=zs.bind(null,rn,y),[g.memoizedState,y]}function Z0(y){return Lu(fu,y)}function Nu(y,g,A,F){return y={tag:y,create:g,destroy:A,deps:F,next:null},Lr===null?(Lr={lastEffect:null},Lr.lastEffect=y.next=y):(g=Lr.lastEffect,g===null?Lr.lastEffect=y.next=y:(A=g.next,g.next=y,y.next=A,Lr.lastEffect=y)),y}function _i(y,g,A,F){var b=Jn();y0|=y,b.memoizedState=Nu(g,A,void 0,F===void 0?null:F)}function Po(y,g,A,F){var b=Sr();F=F===void 0?null:F;var J=void 0;if(Nt!==null){var pe=Nt.memoizedState;if(J=pe.destroy,F!==null&&Ft(F,pe.deps)){Nu(0,A,J,F);return}}y0|=y,b.memoizedState=Nu(g,A,J,F)}function rl(y,g){return _i(516,192,y,g)}function vf(y,g){return Po(516,192,y,g)}function Tl(y,g){if(typeof g=="function")return y=y(),g(y),function(){g(null)};if(g!=null)return y=y(),g.current=y,function(){g.current=null}}function mf(){}function Io(y,g){return Jn().memoizedState=[y,g===void 0?null:g],y}function ys(y,g){var A=Sr();g=g===void 0?null:g;var F=A.memoizedState;return F!==null&&g!==null&&Ft(g,F[1])?F[0]:(A.memoizedState=[y,g],y)}function zs(y,g,A){if(!(25>Et))throw Error(t(301));var F=y.alternate;if(y===rn||F!==null&&F===rn)if(Nr=!0,y={expirationTime:sn,suspenseConfig:null,action:A,eagerReducer:null,eagerState:null,next:null},it===null&&(it=new Map),A=it.get(g),A===void 0)it.set(g,y);else{for(g=A;g.next!==null;)g=g.next;g.next=y}else{var b=D0(),J=fi.suspense;b=Un(b,y,J),J={expirationTime:b,suspenseConfig:J,action:A,eagerReducer:null,eagerState:null,next:null};var pe=g.last;if(pe===null)J.next=J;else{var gt=pe.next;gt!==null&&(J.next=gt),pe.next=J}if(g.last=J,y.expirationTime===0&&(F===null||F.expirationTime===0)&&(F=g.lastRenderedReducer,F!==null))try{var xt=g.lastRenderedState,kt=F(xt,A);if(J.eagerReducer=F,J.eagerState=kt,Ne(kt,xt))return}catch(xr){}finally{}t0(y,b)}}var bo={readContext:ku,useCallback:et,useContext:et,useEffect:et,useImperativeHandle:et,useLayoutEffect:et,useMemo:et,useReducer:et,useRef:et,useState:et,useDebugValue:et,useResponder:et,useDeferredValue:et,useTransition:et},Bo={readContext:ku,useCallback:Io,useContext:ku,useEffect:rl,useImperativeHandle:function(y,g,A){return A=A!=null?A.concat([y]):null,_i(4,36,Tl.bind(null,g,y),A)},useLayoutEffect:function(y,g){return _i(4,36,y,g)},useMemo:function(y,g){var A=Jn();return g=g===void 0?null:g,y=y(),A.memoizedState=[y,g],y},useReducer:function(y,g,A){var F=Jn();return g=A!==void 0?A(g):g,F.memoizedState=F.baseState=g,y=F.queue={last:null,dispatch:null,lastRenderedReducer:y,lastRenderedState:g},y=y.dispatch=zs.bind(null,rn,y),[F.memoizedState,y]},useRef:function(y){var g=Jn();return y={current:y},g.memoizedState=y},useState:T0,useDebugValue:mf,useResponder:Ct,useDeferredValue:function(y,g){var A=T0(y),F=A[0],b=A[1];return rl(function(){_.unstable_next(function(){var J=Pt.suspense;Pt.suspense=g===void 0?null:g;try{b(y)}finally{Pt.suspense=J}})},[y,g]),F},useTransition:function(y){var g=T0(!1),A=g[0],F=g[1];return[Io(function(b){F(!0),_.unstable_next(function(){var J=Pt.suspense;Pt.suspense=y===void 0?null:y;try{F(!1),b()}finally{Pt.suspense=J}})},[y,A]),A]}},_s={readContext:ku,useCallback:ys,useContext:ku,useEffect:vf,useImperativeHandle:function(y,g,A){return A=A!=null?A.concat([y]):null,Po(4,36,Tl.bind(null,g,y),A)},useLayoutEffect:function(y,g){return Po(4,36,y,g)},useMemo:function(y,g){var A=Sr();g=g===void 0?null:g;var F=A.memoizedState;return F!==null&&g!==null&&Ft(g,F[1])?F[0]:(y=y(),A.memoizedState=[y,g],y)},useReducer:Lu,useRef:function(){return Sr().memoizedState},useState:Z0,useDebugValue:mf,useResponder:Ct,useDeferredValue:function(y,g){var A=Z0(y),F=A[0],b=A[1];return vf(function(){_.unstable_next(function(){var J=Pt.suspense;Pt.suspense=g===void 0?null:g;try{b(y)}finally{Pt.suspense=J}})},[y,g]),F},useTransition:function(y){var g=Z0(!1),A=g[0],F=g[1];return[ys(function(b){F(!0),_.unstable_next(function(){var J=Pt.suspense;Pt.suspense=y===void 0?null:y;try{F(!1),b()}finally{Pt.suspense=J}})},[y,A]),A]}},Qu=null,Tu=null,Ei=!1;function C0(y,g){var A=Ho(5,null,null,0);A.elementType="DELETED",A.type="DELETED",A.stateNode=g,A.return=y,A.effectTag=8,y.lastEffect!==null?(y.lastEffect.nextEffect=A,y.lastEffect=A):y.firstEffect=y.lastEffect=A}function $0(y,g){switch(y.tag){case 5:return g=Uu(g,y.type,y.pendingProps),g!==null?(y.stateNode=g,!0):!1;case 6:return g=K0(g,y.pendingProps),g!==null?(y.stateNode=g,!0):!1;case 13:return!1;default:return!1}}function Uo(y){if(Ei){var g=Tu;if(g){var A=g;if(!$0(y,g)){if(g=Mo(A),!g||!$0(y,g)){y.effectTag=y.effectTag&-1025|2,Ei=!1,Qu=y;return}C0(Qu,A)}Qu=y,Tu=F0(g)}else y.effectTag=y.effectTag&-1025|2,Ei=!1,Qu=y}}function sa(y){for(y=y.return;y!==null&&y.tag!==5&&y.tag!==3&&y.tag!==13;)y=y.return;Qu=y}function es(y){if(!w||y!==Qu)return!1;if(!Ei)return sa(y),Ei=!0,!1;var g=y.type;if(y.tag!==5||g!=="head"&&g!=="body"&&!dt(g,y.memoizedProps))for(g=Tu;g;)C0(y,g),g=Mo(g);if(sa(y),y.tag===13){if(!w)throw Error(t(316));if(y=y.memoizedState,y=y!==null?y.dehydrated:null,!y)throw Error(t(317));Tu=Is(y)}else Tu=Qu?Mo(y.stateNode):null;return!0}function tu(){w&&(Tu=Qu=null,Ei=!1)}var ei=O.ReactCurrentOwner,ho=!1;function Bi(y,g,A,F){g.child=y===null?G(g,null,A,F):z(g,y.child,A,F)}function Ci(y,g,A,F,b){A=A.render;var J=g.ref;return Fo(g,b),F=un(y,g,A,F,J,b),y!==null&&!ho?(g.updateQueue=y.updateQueue,g.effectTag&=-517,y.expirationTime<=b&&(y.expirationTime=0),gu(y,g,b)):(g.effectTag|=1,Bi(y,g,F,b),g.child)}function gf(y,g,A,F,b,J){if(y===null){var pe=A.type;return typeof pe=="function"&&!Df(pe)&&pe.defaultProps===void 0&&A.compare===null&&A.defaultProps===void 0?(g.tag=15,g.type=pe,yf(y,g,pe,F,b,J)):(y=Wa(A.type,null,F,null,g.mode,J),y.ref=g.ref,y.return=g,g.child=y)}return pe=y.child,bg)&&Vr.set(y,g)))}}function ro(y,g){y.expirationTimey?g:y)}function n0(y){if(y.lastExpiredTime!==0)y.callbackExpirationTime=1073741823,y.callbackPriority=99,y.callbackNode=Zl(io.bind(null,y));else{var g=mo(y),A=y.callbackNode;if(g===0)A!==null&&(y.callbackNode=null,y.callbackExpirationTime=0,y.callbackPriority=90);else{var F=D0();if(g===1073741823?F=99:g===1||g===2?F=95:(F=10*(1073741821-g)-10*(1073741821-F),F=0>=F?99:250>=F?98:5250>=F?97:95),A!==null){var b=y.callbackPriority;if(y.callbackExpirationTime===g&&b>=F)return;A!==qr&&bs(A)}y.callbackExpirationTime=g,y.callbackPriority=F,g=g===1073741823?Zl(io.bind(null,y)):nl(F,jo.bind(null,y),{timeout:10*(1073741821-g)-v0()}),y.callbackNode=g}}}function jo(y,g){if(ru=0,g)return g=D0(),pa(y,g),n0(y),null;var A=mo(y);if(A!==0){if(g=y.callbackNode,(Fn&(nu|cu))!==Ar)throw Error(t(327));if(Ws(),y===ae&&A===Fe||ws(y,A),re!==null){var F=Fn;Fn|=nu;var b=U0(y);do try{rd();break}catch(gt){ca(y,gt)}while(1);if(zu(),Fn=F,$u.current=b,Re===ni)throw g=st,ws(y,A),Ol(y,A),n0(y),g;if(re===null)switch(b=y.finishedWork=y.current.alternate,y.finishedExpirationTime=A,F=Re,ae=null,F){case Fi:case ni:throw Error(t(345));case Kn:pa(y,2=A){y.lastPingedTime=A,ws(y,A);break}}if(J=mo(y),J!==0&&J!==A)break;if(F!==0&&F!==A){y.lastPingedTime=F;break}y.timeoutHandle=an(Al.bind(null,y),b);break}Al(y);break;case _0:if(Ol(y,A),F=y.lastSuspendedTime,A===F&&(y.nextKnownPendingLevel=qc(b)),_n&&(b=y.lastPingedTime,b===0||b>=A)){y.lastPingedTime=A,ws(y,A);break}if(b=mo(y),b!==0&&b!==A)break;if(F!==0&&F!==A){y.lastPingedTime=F;break}if(Jt!==1073741823?F=10*(1073741821-Jt)-v0():mt===1073741823?F=0:(F=10*(1073741821-mt)-5e3,b=v0(),A=10*(1073741821-A)-b,F=b-F,0>F&&(F=0),F=(120>F?120:480>F?480:1080>F?1080:1920>F?1920:3e3>F?3e3:4320>F?4320:1960*_f(F/1960))-F,A=F?F=0:(b=pe.busyDelayMs|0,J=v0()-(10*(1073741821-J)-(pe.timeoutMs|0||5e3)),F=J<=b?0:b+F-J),10 component higher in the tree to provide a loading indicator or placeholder to display.`+Hr(b))}Re!==E0&&(Re=Kn),J=Cl(J,b),xt=F;do{switch(xt.tag){case 3:pe=J,xt.effectTag|=4096,xt.expirationTime=g;var ze=Es(xt,pe,g);oa(xt,ze);break e;case 1:pe=J;var lt=xt.type,$t=xt.stateNode;if((xt.effectTag&64)==0&&(typeof lt.getDerivedStateFromError=="function"||$t!==null&&typeof $t.componentDidCatch=="function"&&(mr===null||!mr.has($t)))){xt.effectTag|=4096,xt.expirationTime=g;var Wn=fa(xt,pe,g);oa(xt,Wn);break e}}xt=xt.return}while(xt!==null)}re=go(re)}catch(si){g=si;continue}break}while(1)}function U0(){var y=$u.current;return $u.current=bo,y===null?bo:y}function dc(y,g){ySn&&(Sn=y)}function D2(){for(;re!==null;)re=id(re)}function rd(){for(;re!==null&&!$n();)re=id(re)}function id(y){var g=qa(y.alternate,y,Fe);return y.memoizedProps=y.pendingProps,g===null&&(g=go(y)),Ds.current=null,g}function go(y){re=y;do{var g=re.alternate;if(y=re.return,(re.effectTag&2048)==0){e:{var A=g;g=re;var F=Fe,b=g.pendingProps;switch(g.tag){case 2:break;case 16:break;case 15:case 0:break;case 1:eu(g.type)&&Q0(g);break;case 3:Je(g),Yi(g),b=g.stateNode,b.pendingContext&&(b.context=b.pendingContext,b.pendingContext=null),(A===null||A.child===null)&&es(g)&&Ju(g),Jr(g);break;case 5:ue(g);var J=Z(Ae.current);if(F=g.type,A!==null&&g.stateNode!=null)Wu(A,g,F,b,J),A.ref!==g.ref&&(g.effectTag|=128);else if(b){if(A=Z(Te.current),es(g)){if(b=g,!w)throw Error(t(175));A=au(b.stateNode,b.type,b.memoizedProps,J,A,b),b.updateQueue=A,A=A!==null,A&&Ju(g)}else{var pe=de(F,b,J,A,g);ti(pe,g,!1,!1),g.stateNode=pe,oe(pe,F,b,J,A)&&Ju(g)}g.ref!==null&&(g.effectTag|=128)}else if(g.stateNode===null)throw Error(t(166));break;case 6:if(A&&g.stateNode!=null)An(A,g,A.memoizedProps,b);else{if(typeof b!="string"&&g.stateNode===null)throw Error(t(166));if(A=Z(Ae.current),J=Z(Te.current),es(g)){if(A=g,!w)throw Error(t(176));(A=Li(A.stateNode,A.memoizedProps,A))&&Ju(g)}else g.stateNode=nn(b,A,J,g)}break;case 11:break;case 13:if(gi(qe,g),b=g.memoizedState,(g.effectTag&64)!=0){g.expirationTime=F;break e}b=b!==null,J=!1,A===null?g.memoizedProps.fallback!==void 0&&es(g):(F=A.memoizedState,J=F!==null,b||F===null||(F=A.child.sibling,F!==null&&(pe=g.firstEffect,pe!==null?(g.firstEffect=F,F.nextEffect=pe):(g.firstEffect=g.lastEffect=F,F.nextEffect=null),F.effectTag=8))),b&&!J&&(g.mode&2)!=0&&(A===null&&g.memoizedProps.unstable_avoidThisFallback!==!0||(qe.current&1)!=0?Re===Fi&&(Re=e0):((Re===Fi||Re===e0)&&(Re=_0),Sn!==0&&ae!==null&&(Ol(ae,Fe),Cs(ae,Sn)))),Dr&&b&&(g.effectTag|=4),Vt&&(b||J)&&(g.effectTag|=4);break;case 7:break;case 8:break;case 12:break;case 4:Je(g),Jr(g);break;case 10:Su(g);break;case 9:break;case 14:break;case 17:eu(g.type)&&Q0(g);break;case 19:if(gi(qe,g),b=g.memoizedState,b===null)break;if(J=(g.effectTag&64)!=0,pe=b.rendering,pe===null){if(J)Fu(b,!1);else if(Re!==Fi||A!==null&&(A.effectTag&64)!=0)for(A=g.child;A!==null;){if(pe=nt(A),pe!==null){for(g.effectTag|=64,Fu(b,!1),A=pe.updateQueue,A!==null&&(g.updateQueue=A,g.effectTag|=4),b.lastEffect===null&&(g.firstEffect=null),g.lastEffect=b.lastEffect,A=F,b=g.child;b!==null;)J=b,F=A,J.effectTag&=2,J.nextEffect=null,J.firstEffect=null,J.lastEffect=null,pe=J.alternate,pe===null?(J.childExpirationTime=0,J.expirationTime=F,J.child=null,J.memoizedProps=null,J.memoizedState=null,J.updateQueue=null,J.dependencies=null):(J.childExpirationTime=pe.childExpirationTime,J.expirationTime=pe.expirationTime,J.child=pe.child,J.memoizedProps=pe.memoizedProps,J.memoizedState=pe.memoizedState,J.updateQueue=pe.updateQueue,F=pe.dependencies,J.dependencies=F===null?null:{expirationTime:F.expirationTime,firstContext:F.firstContext,responders:F.responders}),b=b.sibling;en(qe,qe.current&1|2,g),g=g.child;break e}A=A.sibling}}else{if(!J)if(A=nt(pe),A!==null){if(g.effectTag|=64,J=!0,A=A.updateQueue,A!==null&&(g.updateQueue=A,g.effectTag|=4),Fu(b,!0),b.tail===null&&b.tailMode==="hidden"&&!pe.alternate){g=g.lastEffect=b.lastEffect,g!==null&&(g.nextEffect=null);break}}else v0()>b.tailExpiration&&1b&&(b=F),pe>b&&(b=pe),J=J.sibling;A.childExpirationTime=b}if(g!==null)return g;y!==null&&(y.effectTag&2048)==0&&(y.firstEffect===null&&(y.firstEffect=re.firstEffect),re.lastEffect!==null&&(y.lastEffect!==null&&(y.lastEffect.nextEffect=re.firstEffect),y.lastEffect=re.lastEffect),1y?g:y}function Al(y){var g=vs();return co(99,ul.bind(null,y,g)),null}function ul(y,g){do Ws();while(ri!==null);if((Fn&(nu|cu))!==Ar)throw Error(t(327));var A=y.finishedWork,F=y.finishedExpirationTime;if(A===null)return null;if(y.finishedWork=null,y.finishedExpirationTime=0,A===y.current)throw Error(t(177));y.callbackNode=null,y.callbackExpirationTime=0,y.callbackPriority=90,y.nextKnownPendingLevel=0;var b=qc(A);if(y.firstPendingTime=b,F<=y.lastSuspendedTime?y.firstSuspendedTime=y.lastSuspendedTime=y.nextKnownPendingLevel=0:F<=y.firstSuspendedTime&&(y.firstSuspendedTime=F-1),F<=y.lastPingedTime&&(y.lastPingedTime=0),F<=y.lastExpiredTime&&(y.lastExpiredTime=0),y===ae&&(re=ae=null,Fe=0),1=A?Kt(y,g,A):(en(qe,qe.current&1,g),g=gu(y,g,A),g!==null?g.sibling:null);en(qe,qe.current&1,g);break;case 19:if(F=g.childExpirationTime>=A,(y.effectTag&64)!=0){if(F)return xn(y,g,A);g.effectTag|=64}if(b=g.memoizedState,b!==null&&(b.rendering=null,b.tail=null),en(qe,qe.current,g),!F)return null}return gu(y,g,A)}ho=!1}}else ho=!1;switch(g.expirationTime=0,g.tag){case 2:if(F=g.type,y!==null&&(y.alternate=null,g.alternate=null,g.effectTag|=2),y=g.pendingProps,b=Ru(g,Oi.current),Fo(g,A),b=un(null,g,F,y,b,A),g.effectTag|=1,typeof b=="object"&&b!==null&&typeof b.render=="function"&&b.$$typeof===void 0){if(g.tag=1,fn(),eu(F)){var J=!0;ai(g)}else J=!1;g.memoizedState=b.state!==null&&b.state!==void 0?b.state:null;var pe=F.getDerivedStateFromProps;typeof pe=="function"&&$l(g,F,pe,y),b.updater=la,g.stateNode=b,b._reactInternalFiber=g,Us(g,F,y,A),g=tt(null,g,F,!0,J,A)}else g.tag=0,Bi(null,g,b,A),g=g.child;return g;case 16:if(b=g.elementType,y!==null&&(y.alternate=null,g.alternate=null,g.effectTag|=2),y=g.pendingProps,Oe(b),b._status!==1)throw b._result;switch(b=b._result,g.type=b,J=g.tag=ol(b),y=Yn(b,y),J){case 0:g=to(null,g,b,y,A);break;case 1:g=xe(null,g,b,y,A);break;case 11:g=Ci(null,g,b,y,A);break;case 14:g=gf(null,g,b,Yn(b.type,y),F,A);break;default:throw Error(t(306,b,""))}return g;case 0:return F=g.type,b=g.pendingProps,b=g.elementType===F?b:Yn(F,b),to(y,g,F,b,A);case 1:return F=g.type,b=g.pendingProps,b=g.elementType===F?b:Yn(F,b),xe(y,g,F,b,A);case 3:if(Ye(g),F=g.updateQueue,F===null)throw Error(t(282));if(b=g.memoizedState,b=b!==null?b.element:null,S0(g,F,g.pendingProps,null,A),F=g.memoizedState.element,F===b)tu(),g=gu(y,g,A);else{if((b=g.stateNode.hydrate)&&(w?(Tu=F0(g.stateNode.containerInfo),Qu=g,b=Ei=!0):b=!1),b)for(A=G(g,null,F,A),g.child=A;A;)A.effectTag=A.effectTag&-3|1024,A=A.sibling;else Bi(y,g,F,A),tu();g=g.child}return g;case 5:return vt(g),y===null&&Uo(g),F=g.type,b=g.pendingProps,J=y!==null?y.memoizedProps:null,pe=b.children,dt(F,b)?pe=null:J!==null&&dt(F,J)&&(g.effectTag|=16),eo(y,g),g.mode&4&&A!==1&&At(F,b)?(g.expirationTime=g.childExpirationTime=1,g=null):(Bi(y,g,pe,A),g=g.child),g;case 6:return y===null&&Uo(g),null;case 13:return Kt(y,g,A);case 4:return ke(g,g.stateNode.containerInfo),F=g.pendingProps,y===null?g.child=z(g,null,F,A):Bi(y,g,F,A),g.child;case 11:return F=g.type,b=g.pendingProps,b=g.elementType===F?b:Yn(F,b),Ci(y,g,F,b,A);case 7:return Bi(y,g,g.pendingProps,A),g.child;case 8:return Bi(y,g,g.pendingProps.children,A),g.child;case 12:return Bi(y,g,g.pendingProps.children,A),g.child;case 10:e:{if(F=g.type._context,b=g.pendingProps,pe=g.memoizedProps,J=b.value,Hu(g,J),pe!==null){var gt=pe.value;if(J=Ne(gt,J)?0:(typeof F._calculateChangedBits=="function"?F._calculateChangedBits(gt,J):1073741823)|0,J===0){if(pe.children===b.children&&!yi.current){g=gu(y,g,A);break e}}else for(gt=g.child,gt!==null&&(gt.return=g);gt!==null;){var xt=gt.dependencies;if(xt!==null){pe=gt.child;for(var kt=xt.firstContext;kt!==null;){if(kt.context===F&&(kt.observedBits&J)!=0){gt.tag===1&&(kt=m0(A,null),kt.tag=2,J0(gt,kt)),gt.expirationTime=g&&y<=g}function Ol(y,g){var A=y.firstSuspendedTime,F=y.lastSuspendedTime;Ag||A===0)&&(y.lastSuspendedTime=g),g<=y.lastPingedTime&&(y.lastPingedTime=0),g<=y.lastExpiredTime&&(y.lastExpiredTime=0)}function Cs(y,g){g>y.firstPendingTime&&(y.firstPendingTime=g);var A=y.firstSuspendedTime;A!==0&&(g>=A?y.firstSuspendedTime=y.lastSuspendedTime=y.nextKnownPendingLevel=0:g>=y.lastSuspendedTime&&(y.lastSuspendedTime=g+1),g>y.nextKnownPendingLevel&&(y.nextKnownPendingLevel=g))}function pa(y,g){var A=y.lastExpiredTime;(A===0||A>g)&&(y.lastExpiredTime=g)}function od(y){var g=y._reactInternalFiber;if(g===void 0)throw typeof y.render=="function"?Error(t(188)):Error(t(268,Object.keys(y)));return y=Qe(g),y===null?null:y.stateNode}function ha(y,g){y=y.memoizedState,y!==null&&y.dehydrated!==null&&y.retryTime{"use strict";Object.defineProperty(tc,"__esModule",{value:!0});var UI=0;tc.__interactionsRef=null;tc.__subscriberRef=null;tc.unstable_clear=function(i){return i()};tc.unstable_getCurrent=function(){return null};tc.unstable_getThreadID=function(){return++UI};tc.unstable_trace=function(i,o,a){return a()};tc.unstable_wrap=function(i){return i};tc.unstable_subscribe=function(){};tc.unstable_unsubscribe=function(){}});var cT=Ke(mu=>{"use strict";process.env.NODE_ENV!=="production"&&function(){"use strict";Object.defineProperty(mu,"__esModule",{value:!0});var i=!0,o=0,a=0,c=0;mu.__interactionsRef=null,mu.__subscriberRef=null,i&&(mu.__interactionsRef={current:new Set},mu.__subscriberRef={current:null});function _(fe){if(!i)return fe();var _e=mu.__interactionsRef.current;mu.__interactionsRef.current=new Set;try{return fe()}finally{mu.__interactionsRef.current=_e}}function t(){return i?mu.__interactionsRef.current:null}function O(){return++c}function N(fe,_e,ce){var me=arguments.length>3&&arguments[3]!==void 0?arguments[3]:o;if(!i)return ce();var ie={__count:1,id:a++,name:fe,timestamp:_e},Oe=mu.__interactionsRef.current,Ue=new Set(Oe);Ue.add(ie),mu.__interactionsRef.current=Ue;var je=mu.__subscriberRef.current,at;try{je!==null&&je.onInteractionTraced(ie)}finally{try{je!==null&&je.onWorkStarted(Ue,me)}finally{try{at=ce()}finally{mu.__interactionsRef.current=Oe;try{je!==null&&je.onWorkStopped(Ue,me)}finally{ie.__count--,je!==null&&ie.__count===0&&je.onInteractionScheduledWorkCompleted(ie)}}}}return at}function M(fe){var _e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:o;if(!i)return fe;var ce=mu.__interactionsRef.current,me=mu.__subscriberRef.current;me!==null&&me.onWorkScheduled(ce,_e),ce.forEach(function(Ue){Ue.__count++});var ie=!1;function Oe(){var Ue=mu.__interactionsRef.current;mu.__interactionsRef.current=ce,me=mu.__subscriberRef.current;try{var je;try{me!==null&&me.onWorkStarted(ce,_e)}finally{try{je=fe.apply(void 0,arguments)}finally{mu.__interactionsRef.current=Ue,me!==null&&me.onWorkStopped(ce,_e)}}return je}finally{ie||(ie=!0,ce.forEach(function(at){at.__count--,me!==null&&at.__count===0&&me.onInteractionScheduledWorkCompleted(at)}))}}return Oe.cancel=function(){me=mu.__subscriberRef.current;try{me!==null&&me.onWorkCanceled(ce,_e)}finally{ce.forEach(function(je){je.__count--,me&&je.__count===0&&me.onInteractionScheduledWorkCompleted(je)})}},Oe}var T=null;i&&(T=new Set);function B(fe){i&&(T.add(fe),T.size===1&&(mu.__subscriberRef.current={onInteractionScheduledWorkCompleted:ne,onInteractionTraced:q,onWorkCanceled:se,onWorkScheduled:m,onWorkStarted:he,onWorkStopped:De}))}function H(fe){i&&(T.delete(fe),T.size===0&&(mu.__subscriberRef.current=null))}function q(fe){var _e=!1,ce=null;if(T.forEach(function(me){try{me.onInteractionTraced(fe)}catch(ie){_e||(_e=!0,ce=ie)}}),_e)throw ce}function ne(fe){var _e=!1,ce=null;if(T.forEach(function(me){try{me.onInteractionScheduledWorkCompleted(fe)}catch(ie){_e||(_e=!0,ce=ie)}}),_e)throw ce}function m(fe,_e){var ce=!1,me=null;if(T.forEach(function(ie){try{ie.onWorkScheduled(fe,_e)}catch(Oe){ce||(ce=!0,me=Oe)}}),ce)throw me}function he(fe,_e){var ce=!1,me=null;if(T.forEach(function(ie){try{ie.onWorkStarted(fe,_e)}catch(Oe){ce||(ce=!0,me=Oe)}}),ce)throw me}function De(fe,_e){var ce=!1,me=null;if(T.forEach(function(ie){try{ie.onWorkStopped(fe,_e)}catch(Oe){ce||(ce=!0,me=Oe)}}),ce)throw me}function se(fe,_e){var ce=!1,me=null;if(T.forEach(function(ie){try{ie.onWorkCanceled(fe,_e)}catch(Oe){ce||(ce=!0,me=Oe)}}),ce)throw me}mu.unstable_clear=_,mu.unstable_getCurrent=t,mu.unstable_getThreadID=O,mu.unstable_trace=N,mu.unstable_wrap=M,mu.unstable_subscribe=B,mu.unstable_unsubscribe=H}()});var dT=Ke((jW,FD)=>{"use strict";process.env.NODE_ENV==="production"?FD.exports=fT():FD.exports=cT()});var pT=Ke((zW,Qg)=>{"use strict";process.env.NODE_ENV!=="production"&&(Qg.exports=function i(o){"use strict";var a=Ig(),c=ki(),_=pD(),t=Q_(),O=dT(),N=0,M=1,T=2,B=3,H=4,q=5,ne=6,m=7,he=8,De=9,se=10,fe=11,_e=12,ce=13,me=14,ie=15,Oe=16,Ue=17,je=18,at=19,Dt=20,Qe=21,ut=function(){};ut=function(f,d){for(var E=arguments.length,C=new Array(E>2?E-2:0),R=2;R8)throw new Error("warningWithoutStack() currently supports at most 8 arguments.");if(!f){if(typeof console!="undefined"){var j=C.map(function(le){return""+le});j.unshift("Warning: "+d),Function.prototype.apply.call(console.error,console,j)}try{var V=0,te="Warning: "+d.replace(/%s/g,function(){return C[V++]});throw new Error(te)}catch(le){}}};var Ve=ut;function It(f){return f._reactInternalFiber}function Xt(f,d){f._reactInternalFiber=d}var rt=c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;rt.hasOwnProperty("ReactCurrentDispatcher")||(rt.ReactCurrentDispatcher={current:null}),rt.hasOwnProperty("ReactCurrentBatchConfig")||(rt.ReactCurrentBatchConfig={suspense:null});var X=typeof Symbol=="function"&&Symbol.for,de=X?Symbol.for("react.element"):60103,Ce=X?Symbol.for("react.portal"):60106,oe=X?Symbol.for("react.fragment"):60107,He=X?Symbol.for("react.strict_mode"):60108,dt=X?Symbol.for("react.profiler"):60114,At=X?Symbol.for("react.provider"):60109,nn=X?Symbol.for("react.context"):60110,an=X?Symbol.for("react.concurrent_mode"):60111,Mn=X?Symbol.for("react.forward_ref"):60112,lr=X?Symbol.for("react.suspense"):60113,ln=X?Symbol.for("react.suspense_list"):60120,Vt=X?Symbol.for("react.memo"):60115,Dr=X?Symbol.for("react.lazy"):60116,w=X?Symbol.for("react.fundamental"):60117,jt=X?Symbol.for("react.responder"):60118,Xn=X?Symbol.for("react.scope"):60119,vr=typeof Symbol=="function"&&Symbol.iterator,jr="@@iterator";function fr(f){if(f===null||typeof f!="object")return null;var d=vr&&f[vr]||f[jr];return typeof d=="function"?d:null}var zr=Ve;zr=function(f,d){if(!f){for(var E=rt.ReactDebugCurrentFrame,C=E.getStackAddendum(),R=arguments.length,j=new Array(R>2?R-2:0),V=2;V import('./MyComponent'))`,C),f._status=Ro,f._result=R}},function(C){f._status===d0&&(f._status=Jo,f._result=C)})}}function $o(f,d,E){var C=d.displayName||d.name||"";return f.displayName||(C!==""?E+"("+C+")":E)}function qt(f){if(f==null)return null;if(typeof f.tag=="number"&&Ve(!1,"Received an unexpected object in getComponentName(). This is likely a bug in React. Please file an issue."),typeof f=="function")return f.displayName||f.name||null;if(typeof f=="string")return f;switch(f){case oe:return"Fragment";case Ce:return"Portal";case dt:return"Profiler";case He:return"StrictMode";case lr:return"Suspense";case ln:return"SuspenseList"}if(typeof f=="object")switch(f.$$typeof){case nn:return"Context.Consumer";case At:return"Context.Provider";case Mn:return $o(f,f.render,"ForwardRef");case Vt:return qt(f.type);case Dr:{var d=f,E=Ps(d);if(E)return qt(E);break}}return null}var Ai=0,su=1,mi=2,wr=4,el=6,Y0=8,Uu=16,K0=32,Xr=64,Oo=128,Mo=256,F0=512,au=1024,Li=1028,Is=932,Xl=2047,P0=2048,p0=4096,Hr=!0,Ri=!0,X0=!0,gi=!0,en=!0,bn=!0,Oi=!1,yi=!1,Wt=!1,Ru=!1,eu=!1,Q0=!0,Yi=!1,Ql=!1,ko=!1,ai=!1,ao=!1,Jl=rt.ReactCurrentOwner;function Lo(f){var d=f,E=f;if(f.alternate)for(;d.return;)d=d.return;else{var C=d;do d=C,(d.effectTag&(mi|au))!==Ai&&(E=d.return),C=d.return;while(C)}return d.tag===B?E:null}function bs(f){return Lo(f)===f}function $n(f){{var d=Jl.current;if(d!==null&&d.tag===M){var E=d,C=E.stateNode;C._warnedAboutRefsInRender||Ve(!1,"%s is accessing isMounted inside its render() function. render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.",qt(E.type)||"A component"),C._warnedAboutRefsInRender=!0}}var R=It(f);return R?Lo(R)===R:!1}function tl(f){if(Lo(f)!==f)throw Error("Unable to find node on an unmounted component.")}function fo(f){var d=f.alternate;if(!d){var E=Lo(f);if(E===null)throw Error("Unable to find node on an unmounted component.");return E!==f?null:f}for(var C=f,R=d;;){var j=C.return;if(j===null)break;var V=j.alternate;if(V===null){var te=j.return;if(te!==null){C=R=te;continue}break}if(j.child===V.child){for(var le=j.child;le;){if(le===C)return tl(j),f;if(le===R)return tl(j),d;le=le.sibling}throw Error("Unable to find node on an unmounted component.")}if(C.return!==R.return)C=j,R=V;else{for(var Be=!1,Xe=j.child;Xe;){if(Xe===C){Be=!0,C=j,R=V;break}if(Xe===R){Be=!0,R=j,C=V;break}Xe=Xe.sibling}if(!Be){for(Xe=V.child;Xe;){if(Xe===C){Be=!0,C=V,R=j;break}if(Xe===R){Be=!0,R=V,C=j;break}Xe=Xe.sibling}if(!Be)throw Error("Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.")}}if(C.alternate!==R)throw Error("Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue.")}if(C.tag!==B)throw Error("Unable to find node on an unmounted component.");return C.stateNode.current===C?f:d}function I0(f){var d=fo(f);if(!d)return null;for(var E=d;;){if(E.tag===q||E.tag===ne)return E;if(E.child){E.child.return=E,E=E.child;continue}if(E===d)return null;for(;!E.sibling;){if(!E.return||E.return===d)return null;E=E.return}E.sibling.return=E.return,E=E.sibling}return null}function Sl(f){var d=fo(f);if(!d)return null;for(var E=d;;){if(E.tag===q||E.tag===ne||Wt&&E.tag===Dt)return E;if(E.child&&E.tag!==H){E.child.return=E,E=E.child;continue}if(E===d)return null;for(;!E.sibling;){if(!E.return||E.return===d)return null;E=E.return}E.sibling.return=E.return,E=E.sibling}return null}var No=o.getPublicInstance,wt=o.getRootHostContext,bt=o.getChildHostContext,Hn=o.prepareForCommit,qr=o.resetAfterCommit,Ki=o.createInstance,Qr=o.appendInitialChild,Ou=o.finalizeInitialChildren,h0=o.prepareUpdate,Ni=o.shouldSetTextContent,v0=o.shouldDeprioritizeSubtree,vs=o.createTextInstance,Tt=o.setTimeout,co=o.clearTimeout,nl=o.noTimeout,Zl=o.now,ju=o.isPrimaryRenderer,ms=o.warnsIfNotActing,b0=o.supportsMutation,Q=o.supportsPersistence,we=o.supportsHydration,Ne=o.mountResponderInstance,Le=o.unmountResponderInstance,pt=o.getFundamentalComponentInstance,Yn=o.mountFundamentalComponent,Cn=o.shouldUpdateFundamentalComponent,cr=o.getInstanceFromNode,Si=o.appendChild,Mu=o.appendChildToContainer,zu=o.commitTextUpdate,Hu=o.commitMount,Su=o.commitUpdate,Ti=o.insertBefore,Fo=o.insertInContainerBefore,ku=o.removeChild,po=o.removeChildFromContainer,qu=o.resetTextContent,Ia=o.hideInstance,m0=o.hideTextInstance,ua=o.unhideInstance,J0=o.unhideTextInstance,oa=o.updateFundamentalComponent,ba=o.unmountFundamentalComponent,gs=o.cloneInstance,S0=o.createContainerChildSet,Qn=o.appendChildToContainerChildSet,fc=o.finalizeContainerChildren,fi=o.replaceContainerChildren,$r=o.cloneHiddenInstance,$l=o.cloneHiddenTextInstance,la=o.cloneInstance,hf=o.canHydrateInstance,Bs=o.canHydrateTextInstance,Ba=o.canHydrateSuspenseInstance,Us=o.isSuspenseInstancePending,g0=o.isSuspenseInstanceFallback,js=o.registerSuspenseInstanceRetry,ji=o.getNextHydratableSibling,U=o.getFirstHydratableChild,z=o.hydrateInstance,G=o.hydrateTextInstance,$=o.hydrateSuspenseInstance,Te=o.getNextHydratableInstanceAfterSuspenseInstance,ye=o.commitHydratedContainer,Ae=o.commitHydratedSuspenseInstance,Z=o.clearSuspenseBoundary,ke=o.clearSuspenseBoundaryFromContainer,Je=o.didNotMatchHydratedContainerTextInstance,vt=o.didNotMatchHydratedTextInstance,ue=o.didNotHydrateContainerInstance,qe=o.didNotHydrateInstance,nt=o.didNotFindHydratableContainerInstance,Ct=o.didNotFindHydratableContainerTextInstance,Mt=o.didNotFindHydratableContainerSuspenseInstance,Pt=o.didNotFindHydratableInstance,sn=o.didNotFindHydratableTextInstance,rn=o.didNotFindHydratableSuspenseInstance,Nt=/^(.*)[\\\/]/,Dn=function(f,d,E){var C="";if(d){var R=d.fileName,j=R.replace(Nt,"");if(/^index\./.test(j)){var V=R.match(Nt);if(V){var te=V[1];if(te){var le=te.replace(Nt,"");j=le+"/"+j}}}C=" (at "+j+":"+d.lineNumber+")"}else E&&(C=" (created by "+E+")");return` + in `+(f||"Unknown")+C},dr=rt.ReactDebugCurrentFrame;function er(f){switch(f.tag){case B:case H:case ne:case m:case se:case De:return"";default:var d=f._debugOwner,E=f._debugSource,C=qt(f.type),R=null;return d&&(R=qt(d.type)),Dn(C,E,R)}}function Cr(f){var d="",E=f;do d+=er(E),E=E.return;while(E);return d}var Rn=null,Lr=null;function y0(){{if(Rn===null)return null;var f=Rn._debugOwner;if(f!==null&&typeof f!="undefined")return qt(f.type)}return null}function Nr(){return Rn===null?"":Cr(Rn)}function it(){dr.getCurrentStack=null,Rn=null,Lr=null}function Et(f){dr.getCurrentStack=Nr,Rn=f,Lr=null}function et(f){Lr=f}var Ft="\u269B",un="\u26D4",fn=typeof performance!="undefined"&&typeof performance.mark=="function"&&typeof performance.clearMarks=="function"&&typeof performance.measure=="function"&&typeof performance.clearMeasures=="function",Jn=null,Sr=null,fu=null,Lu=!1,T0=!1,Z0=!1,Nu=0,_i=0,Po=new Set,rl=function(f){return Ft+" "+f},vf=function(f,d){var E=d?un+" ":Ft+" ",C=d?" Warning: "+d:"";return""+E+f+C},Tl=function(f){performance.mark(rl(f))},mf=function(f){performance.clearMarks(rl(f))},Io=function(f,d,E){var C=rl(d),R=vf(f,E);try{performance.measure(R,C)}catch(j){}performance.clearMarks(C),performance.clearMeasures(R)},ys=function(f,d){return f+" (#"+d+")"},zs=function(f,d,E){return E===null?f+" ["+(d?"update":"mount")+"]":f+"."+E},bo=function(f,d){var E=qt(f.type)||"Unknown",C=f._debugID,R=f.alternate!==null,j=zs(E,R,d);if(Lu&&Po.has(j))return!1;Po.add(j);var V=ys(j,C);return Tl(V),!0},Bo=function(f,d){var E=qt(f.type)||"Unknown",C=f._debugID,R=f.alternate!==null,j=zs(E,R,d),V=ys(j,C);mf(V)},_s=function(f,d,E){var C=qt(f.type)||"Unknown",R=f._debugID,j=f.alternate!==null,V=zs(C,j,d),te=ys(V,R);Io(V,te,E)},Qu=function(f){switch(f.tag){case B:case q:case ne:case H:case m:case se:case De:case he:return!0;default:return!1}},Tu=function(){Sr!==null&&fu!==null&&Bo(fu,Sr),fu=null,Sr=null,Z0=!1},Ei=function(){for(var f=Jn;f;)f._debugIsCurrentlyTiming&&_s(f,null,null),f=f.return},C0=function(f){f.return!==null&&C0(f.return),f._debugIsCurrentlyTiming&&bo(f,null)},$0=function(){Jn!==null&&C0(Jn)};function Uo(){Hr&&_i++}function sa(){Hr&&(Lu&&(T0=!0),Sr!==null&&Sr!=="componentWillMount"&&Sr!=="componentWillReceiveProps"&&(Z0=!0))}function es(f){if(Hr){if(!fn||Qu(f)||(Jn=f,!bo(f,null)))return;f._debugIsCurrentlyTiming=!0}}function tu(f){if(Hr){if(!fn||Qu(f))return;f._debugIsCurrentlyTiming=!1,Bo(f,null)}}function ei(f){if(Hr){if(!fn||Qu(f)||(Jn=f.return,!f._debugIsCurrentlyTiming))return;f._debugIsCurrentlyTiming=!1,_s(f,null,null)}}function ho(f){if(Hr){if(!fn||Qu(f)||(Jn=f.return,!f._debugIsCurrentlyTiming))return;f._debugIsCurrentlyTiming=!1;var d=f.tag===ce?"Rendering was suspended":"An error was thrown inside this error boundary";_s(f,null,d)}}function Bi(f,d){if(Hr){if(!fn||(Tu(),!bo(f,d)))return;fu=f,Sr=d}}function Ci(){if(Hr){if(!fn)return;if(Sr!==null&&fu!==null){var f=Z0?"Scheduled a cascading update":null;_s(fu,Sr,f)}Sr=null,fu=null}}function gf(f){if(Hr){if(Jn=f,!fn)return;Nu=0,Tl("(React Tree Reconciliation)"),$0()}}function yf(f,d){if(Hr){if(!fn)return;var E=null;if(f!==null)if(f.tag===B)E="A top-level update interrupted the previous render";else{var C=qt(f.type)||"Unknown";E="An update to "+C+" interrupted the previous render"}else Nu>1&&(E="There were cascading updates");Nu=0;var R=d?"(React Tree Reconciliation: Completed Root)":"(React Tree Reconciliation: Yielded)";Ei(),Io(R,"(React Tree Reconciliation)",E)}}function eo(){if(Hr){if(!fn)return;Lu=!0,T0=!1,Po.clear(),Tl("(Committing Changes)")}}function to(){if(Hr){if(!fn)return;var f=null;T0?f="Lifecycle hook scheduled a cascading update":Nu>0&&(f="Caused by a cascading update in earlier commit"),T0=!1,Nu++,Lu=!1,Po.clear(),Io("(Committing Changes)","(Committing Changes)",f)}}function xe(){if(Hr){if(!fn)return;_i=0,Tl("(Committing Snapshot Effects)")}}function tt(){if(Hr){if(!fn)return;var f=_i;_i=0,Io("(Committing Snapshot Effects: "+f+" Total)","(Committing Snapshot Effects)",null)}}function Ye(){if(Hr){if(!fn)return;_i=0,Tl("(Committing Host Effects)")}}function Yt(){if(Hr){if(!fn)return;var f=_i;_i=0,Io("(Committing Host Effects: "+f+" Total)","(Committing Host Effects)",null)}}function Kt(){if(Hr){if(!fn)return;_i=0,Tl("(Calling Lifecycle Methods)")}}function pr(){if(Hr){if(!fn)return;var f=_i;_i=0,Io("(Calling Lifecycle Methods: "+f+" Total)","(Calling Lifecycle Methods)",null)}}var Wr=[],xn;xn=[];var gu=-1;function Ju(f){return{current:f}}function ti(f,d){if(gu<0){Ve(!1,"Unexpected pop.");return}d!==xn[gu]&&Ve(!1,"Unexpected Fiber popped."),f.current=Wr[gu],Wr[gu]=null,xn[gu]=null,gu--}function Jr(f,d,E){gu++,Wr[gu]=f.current,xn[gu]=E,f.current=d}var Wu;Wu={};var An={};Object.freeze(An);var x0=Ju(An),Fu=Ju(!1),li=An;function Cl(f,d,E){return ai?An:E&&Xi(d)?li:x0.current}function Hs(f,d,E){if(!ai){var C=f.stateNode;C.__reactInternalMemoizedUnmaskedChildContext=d,C.__reactInternalMemoizedMaskedChildContext=E}}function Vu(f,d){if(ai)return An;var E=f.type,C=E.contextTypes;if(!C)return An;var R=f.stateNode;if(R&&R.__reactInternalMemoizedUnmaskedChildContext===d)return R.__reactInternalMemoizedMaskedChildContext;var j={};for(var V in C)j[V]=d[V];{var te=qt(E)||"Unknown";_(C,j,"context",te,Nr)}return R&&Hs(f,d,j),j}function aa(){return ai?!1:Fu.current}function Xi(f){if(ai)return!1;var d=f.childContextTypes;return d!=null}function qs(f){ai||(ti(Fu,f),ti(x0,f))}function A0(f){ai||(ti(Fu,f),ti(x0,f))}function zi(f,d,E){if(!ai){if(x0.current!==An)throw Error("Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.");Jr(x0,d,f),Jr(Fu,E,f)}}function R0(f,d,E){if(ai)return E;var C=f.stateNode,R=d.childContextTypes;if(typeof C.getChildContext!="function"){{var j=qt(d)||"Unknown";Wu[j]||(Wu[j]=!0,Ve(!1,"%s.childContextTypes is specified but there is no getChildContext() method on the instance. You can either define getChildContext() on %s or remove childContextTypes from it.",j,j))}return E}var V;et("getChildContext"),Bi(f,"getChildContext"),V=C.getChildContext(),Ci(),et(null);for(var te in V)if(!(te in R))throw Error((qt(d)||"Unknown")+'.getChildContext(): key "'+te+'" is not defined in childContextTypes.');{var le=qt(d)||"Unknown";_(R,V,"child context",le,Nr)}return a({},E,{},V)}function Hi(f){if(ai)return!1;var d=f.stateNode,E=d&&d.__reactInternalMemoizedMergedChildContext||An;return li=x0.current,Jr(x0,E,f),Jr(Fu,Fu.current,f),!0}function il(f,d,E){if(!ai){var C=f.stateNode;if(!C)throw Error("Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.");if(E){var R=R0(f,d,li);C.__reactInternalMemoizedMergedChildContext=R,ti(Fu,f),ti(x0,f),Jr(x0,R,f),Jr(Fu,E,f)}else ti(Fu,f),Jr(Fu,E,f)}}function xl(f){if(ai)return An;if(!(bs(f)&&f.tag===M))throw Error("Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.");var d=f;do{switch(d.tag){case B:return d.stateNode.context;case M:{var E=d.type;if(Xi(E))return d.stateNode.__reactInternalMemoizedMergedChildContext;break}}d=d.return}while(d!==null);throw Error("Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.")}var B0=1,O0=2,vo=t.unstable_runWithPriority,Pu=t.unstable_scheduleCallback,Zu=t.unstable_cancelCallback,ts=t.unstable_shouldYield,Es=t.unstable_requestPaint,fa=t.unstable_now,_f=t.unstable_getCurrentPriorityLevel,$u=t.unstable_ImmediatePriority,Ds=t.unstable_UserBlockingPriority,Ar=t.unstable_NormalPriority,no=t.unstable_LowPriority,nu=t.unstable_IdlePriority;if(bn&&!(O.__interactionsRef!=null&&O.__interactionsRef.current!=null))throw Error("It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling");var cu={},Fi=99,ni=98,Kn=97,e0=96,_0=95,E0=90,Fn=ts,ae=Es!==void 0?Es:function(){},re=null,Fe=null,Re=!1,st=fa(),mt=st<1e4?fa:function(){return fa()-st};function Jt(){switch(_f()){case $u:return Fi;case Ds:return ni;case Ar:return Kn;case no:return e0;case nu:return _0;default:throw Error("Unknown priority level.")}}function On(f){switch(f){case Fi:return $u;case ni:return Ds;case Kn:return Ar;case e0:return no;case _0:return nu;default:throw Error("Unknown priority level.")}}function Sn(f,d){var E=On(f);return vo(E,d)}function _n(f,d,E){var C=On(f);return Pu(C,d,E)}function Tn(f){return re===null?(re=[f],Fe=Pu($u,Pi)):re.push(f),cu}function ir(f){f!==cu&&Zu(f)}function Bt(){if(Fe!==null){var f=Fe;Fe=null,Zu(f)}Pi()}function Pi(){if(!Re&&re!==null){Re=!0;var f=0;try{var d=!0,E=re;Sn(Fi,function(){for(;f1?d-1:0),C=1;C2?E-2:0),R=2;R0&&(za.forEach(function(Lt){f.add(qt(Lt.type)||"Component"),ns.add(Lt.type)}),za=[]);var d=new Set;Ha.length>0&&(Ha.forEach(function(Lt){d.add(qt(Lt.type)||"Component"),ns.add(Lt.type)}),Ha=[]);var E=new Set;qa.length>0&&(qa.forEach(function(Lt){E.add(qt(Lt.type)||"Component"),ns.add(Lt.type)}),qa=[]);var C=new Set;da.length>0&&(da.forEach(function(Lt){C.add(qt(Lt.type)||"Component"),ns.add(Lt.type)}),da=[]);var R=new Set;Ss.length>0&&(Ss.forEach(function(Lt){R.add(qt(Lt.type)||"Component"),ns.add(Lt.type)}),Ss=[]);var j=new Set;if(Ts.length>0&&(Ts.forEach(function(Lt){j.add(qt(Lt.type)||"Component"),ns.add(Lt.type)}),Ts=[]),d.size>0){var V=zo(d);Ve(!1,`Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move code with side effects to componentDidMount, and set initial state in the constructor. + +Please update the following components: %s`,V)}if(C.size>0){var te=zo(C);Ve(!1,`Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. +* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state + +Please update the following components: %s`,te)}if(j.size>0){var le=zo(j);Ve(!1,`Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. + +Please update the following components: %s`,le)}if(f.size>0){var Be=zo(f);Ws(!1,`componentWillMount has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move code with side effects to componentDidMount, and set initial state in the constructor. +* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. + +Please update the following components: %s`,Be)}if(E.size>0){var Xe=zo(E);Ws(!1,`componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. +* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state +* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. + +Please update the following components: %s`,Xe)}if(R.size>0){var ht=zo(R);Ws(!1,`componentWillUpdate has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. +* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. + +Please update the following components: %s`,ht)}};var Ho=new Map,Df=new Set;Rl.recordLegacyContextWarning=function(f,d){var E=ud(f);if(E===null){Ve(!1,"Expected to find a StrictMode component in a strict mode tree. This error is likely caused by a bug in React. Please file an issue.");return}if(!Df.has(f.type)){var C=Ho.get(E);(f.type.contextTypes!=null||f.type.childContextTypes!=null||d!==null&&typeof d.getChildContext=="function")&&(C===void 0&&(C=[],Ho.set(E,C)),C.push(f))}},Rl.flushLegacyContextWarning=function(){Ho.forEach(function(f,d){var E=new Set;f.forEach(function(j){E.add(qt(j.type)||"Component"),Df.add(j.type)});var C=zo(E),R=Cr(d);Ve(!1,`Legacy context API has been detected within a strict-mode tree. + +The old API will be supported in all 16.x releases, but applications using it should migrate to the new version. + +Please update the following components: %s + +Learn more about this warning here: https://fb.me/react-legacy-context%s`,C,R)})},Rl.discardPendingWarnings=function(){za=[],Ha=[],qa=[],da=[],Ss=[],Ts=[],Ho=new Map}}var ol=null,Gu=null,Wa=function(f){ol=f};function r0(f){{if(ol===null)return f;var d=ol(f);return d===void 0?f:d.current}}function j0(f){return r0(f)}function wf(f){{if(ol===null)return f;var d=ol(f);if(d===void 0){if(f!=null&&typeof f.render=="function"){var E=r0(f.render);if(f.render!==E){var C={$$typeof:Mn,render:E};return f.displayName!==void 0&&(C.displayName=f.displayName),C}}return f}return d.current}}function Wc(f,d){{if(ol===null)return!1;var E=f.elementType,C=d.type,R=!1,j=typeof C=="object"&&C!==null?C.$$typeof:null;switch(f.tag){case M:{typeof C=="function"&&(R=!0);break}case N:{(typeof C=="function"||j===Dr)&&(R=!0);break}case fe:{(j===Mn||j===Dr)&&(R=!0);break}case me:case ie:{(j===Vt||j===Dr)&&(R=!0);break}default:return!1}if(R){var V=ol(E);if(V!==void 0&&V===ol(C))return!0}return!1}}function pc(f){{if(ol===null||typeof WeakSet!="function")return;Gu===null&&(Gu=new WeakSet),Gu.add(f)}}var Ol=function(f,d){{if(ol===null)return;var E=d.staleFamilies,C=d.updatedFamilies;nf(),Op(function(){pa(f.current,C,E)})}},Cs=function(f,d){{if(f.context!==An)return;nf(),pv(function(){o_(d,f,null,null)})}};function pa(f,d,E){{var C=f.alternate,R=f.child,j=f.sibling,V=f.tag,te=f.type,le=null;switch(V){case N:case ie:case M:le=te;break;case fe:le=te.render;break;default:break}if(ol===null)throw new Error("Expected resolveFamily to be set during hot reload.");var Be=!1,Xe=!1;if(le!==null){var ht=ol(le);ht!==void 0&&(E.has(ht)?Xe=!0:d.has(ht)&&(V===M?Xe=!0:Be=!0))}Gu!==null&&(Gu.has(f)||C!==null&&Gu.has(C))&&(Xe=!0),Xe&&(f._debugNeedsRemount=!0),(Xe||Be)&&gl(f,Un),R!==null&&!Xe&&pa(R,d,E),j!==null&&pa(j,d,E)}}var od=function(f,d){{var E=new Set,C=new Set(d.map(function(R){return R.current}));return ha(f.current,C,E),E}};function ha(f,d,E){{var C=f.child,R=f.sibling,j=f.tag,V=f.type,te=null;switch(j){case N:case ie:case M:te=V;break;case fe:te=V.render;break;default:break}var le=!1;te!==null&&d.has(te)&&(le=!0),le?hc(f,E):C!==null&&ha(C,d,E),R!==null&&ha(R,d,E)}}function hc(f,d){{var E=Vc(f,d);if(E)return;for(var C=f;;){switch(C.tag){case q:d.add(C.stateNode);return;case H:d.add(C.stateNode.containerInfo);return;case B:d.add(C.stateNode.containerInfo);return}if(C.return===null)throw new Error("Expected to reach root first.");C=C.return}}}function Vc(f,d){for(var E=f,C=!1;;){if(E.tag===q)C=!0,d.add(E.stateNode);else if(E.child!==null){E.child.return=E,E=E.child;continue}if(E===f)return C;for(;E.sibling===null;){if(E.return===null||E.return===f)return C;E=E.return}E.sibling.return=E.return,E=E.sibling}return!1}function qi(f,d){if(f&&f.defaultProps){var E=a({},d),C=f.defaultProps;for(var R in C)E[R]===void 0&&(E[R]=C[R]);return E}return d}function y(f){if(Zo(f),f._status!==Ro)throw f._result;return f._result}var g=Ju(null),A;A={};var F=null,b=null,J=null,pe=!1;function gt(){F=null,b=null,J=null,pe=!1}function xt(){pe=!0}function kt(){pe=!1}function xr(f,d){var E=f.type._context;ju?(Jr(g,E._currentValue,f),E._currentValue=d,E._currentRenderer===void 0||E._currentRenderer===null||E._currentRenderer===A||Ve(!1,"Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported."),E._currentRenderer=A):(Jr(g,E._currentValue2,f),E._currentValue2=d,E._currentRenderer2===void 0||E._currentRenderer2===null||E._currentRenderer2===A||Ve(!1,"Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported."),E._currentRenderer2=A)}function i0(f){var d=g.current;ti(g,f);var E=f.type._context;ju?E._currentValue=d:E._currentValue2=d}function du(f,d,E){if(go(E,d))return 0;var C=typeof f._calculateChangedBits=="function"?f._calculateChangedBits(E,d):Vr;return(C&Vr)!==C&&Qt(!1,"calculateChangedBits: Expected the return value to be a 31-bit integer. Instead received: %s",C),C|0}function z0(f,d){for(var E=f;E!==null;){var C=E.alternate;if(E.childExpirationTime=d&&sp(),E.firstContext=null)}}function We(f,d){if(pe&&Qt(!1,"Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()."),J!==f){if(!(d===!1||d===0)){var E;typeof d!="number"||d===Vr?(J=f,E=Vr):E=d;var C={context:f,observedBits:E,next:null};if(b===null){if(F===null)throw Error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().");b=C,F.dependencies={expirationTime:ft,firstContext:C,responders:null}}else b=b.next=C}}return ju?f._currentValue:f._currentValue2}var ze=0,lt=1,$t=2,Wn=3,si=!1,ur,ci;ur=!1,ci=null;function Qi(f){var d={baseState:f,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null};return d}function Gr(f){var d={baseState:f.baseState,firstUpdate:f.firstUpdate,lastUpdate:f.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null};return d}function Cu(f,d){var E={expirationTime:f,suspenseConfig:d,tag:ze,payload:null,callback:null,next:null,nextEffect:null};return E.priority=Jt(),E}function Va(f,d){f.lastUpdate===null?f.firstUpdate=f.lastUpdate=d:(f.lastUpdate.next=d,f.lastUpdate=d)}function Ga(f,d){var E=f.alternate,C,R;E===null?(C=f.updateQueue,R=null,C===null&&(C=f.updateQueue=Qi(f.memoizedState))):(C=f.updateQueue,R=E.updateQueue,C===null?R===null?(C=f.updateQueue=Qi(f.memoizedState),R=E.updateQueue=Qi(E.memoizedState)):C=f.updateQueue=Gr(R):R===null&&(R=E.updateQueue=Gr(C))),R===null||C===R?Va(C,d):C.lastUpdate===null||R.lastUpdate===null?(Va(C,d),Va(R,d)):(Va(C,d),R.lastUpdate=d),f.tag===M&&(ci===C||R!==null&&ci===R)&&!ur&&(Ve(!1,"An update (setState, replaceState, or forceUpdate) was scheduled from inside an update function. Update functions should be pure, with zero side-effects. Consider using componentDidUpdate or a callback."),ur=!0)}function ld(f,d){var E=f.updateQueue;E===null?E=f.updateQueue=Qi(f.memoizedState):E=S2(f,E),E.lastCapturedUpdate===null?E.firstCapturedUpdate=E.lastCapturedUpdate=d:(E.lastCapturedUpdate.next=d,E.lastCapturedUpdate=d)}function S2(f,d){var E=f.alternate;return E!==null&&d===E.updateQueue&&(d=f.updateQueue=Gr(d)),d}function T2(f,d,E,C,R,j){switch(E.tag){case lt:{var V=E.payload;if(typeof V=="function"){xt(),Ri&&f.mode&mr&&V.call(j,C,R);var te=V.call(j,C,R);return kt(),te}return V}case Wn:f.effectTag=f.effectTag&~p0|Xr;case ze:{var le=E.payload,Be;return typeof le=="function"?(xt(),Ri&&f.mode&mr&&le.call(j,C,R),Be=le.call(j,C,R),kt()):Be=le,Be==null?C:a({},C,Be)}case $t:return si=!0,C}return C}function Sf(f,d,E,C,R){si=!1,d=S2(f,d),ci=d;for(var j=d.baseState,V=null,te=ft,le=d.firstUpdate,Be=j;le!==null;){var Xe=le.expirationTime;if(Xe from render. Or maybe you meant to call this function rather than return it."))}function Eh(f){function d(ot,Ot){if(!!f){var $e=ot.lastEffect;$e!==null?($e.nextEffect=Ot,ot.lastEffect=Ot):ot.firstEffect=ot.lastEffect=Ot,Ot.nextEffect=null,Ot.effectTag=Y0}}function E(ot,Ot){if(!f)return null;for(var $e=Ot;$e!==null;)d(ot,$e),$e=$e.sibling;return null}function C(ot,Ot){for(var $e=new Map,Ut=Ot;Ut!==null;)Ut.key!==null?$e.set(Ut.key,Ut):$e.set(Ut.index,Ut),Ut=Ut.sibling;return $e}function R(ot,Ot,$e){var Ut=Co(ot,Ot,$e);return Ut.index=0,Ut.sibling=null,Ut}function j(ot,Ot,$e){if(ot.index=$e,!f)return Ot;var Ut=ot.alternate;if(Ut!==null){var Pn=Ut.index;return PnKr?(xu=hr,hr=null):xu=hr.sibling;var w0=Lt(ot,hr,$e[Kr],Ut);if(w0===null){hr===null&&(hr=xu);break}f&&hr&&w0.alternate===null&&d(ot,hr),hu=j(w0,hu,Kr),Ku===null?pi=w0:Ku.sibling=w0,Ku=w0,hr=xu}if(Kr===$e.length)return E(ot,hr),pi;if(hr===null){for(;Kr<$e.length;Kr++){var W0=ht(ot,$e[Kr],Ut);W0!==null&&(hu=j(W0,hu,Kr),Ku===null?pi=W0:Ku.sibling=W0,Ku=W0)}return pi}for(var ks=C(ot,hr);Kr<$e.length;Kr++){var Xu=Gt(ks,ot,Kr,$e[Kr],Ut);Xu!==null&&(f&&Xu.alternate!==null&&ks.delete(Xu.key===null?Kr:Xu.key),hu=j(Xu,hu,Kr),Ku===null?pi=Xu:Ku.sibling=Xu,Ku=Xu)}return f&&ks.forEach(function(yl){return d(ot,yl)}),pi}function kr(ot,Ot,$e,Ut){var Pn=fr($e);if(typeof Pn!="function")throw Error("An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.");{typeof Symbol=="function"&&$e[Symbol.toStringTag]==="Generator"&&(Qc||Qt(!1,"Using Generators as children is unsupported and will likely yield unexpected results because enumerating a generator mutates it. You may convert it to an array with `Array.from()` or the `[...spread]` operator before rendering. Keep in mind you might need to polyfill these features for older browsers."),Qc=!0),$e.entries===Pn&&(pd||Qt(!1,"Using Maps as children is unsupported and will likely yield unexpected results. Convert it to a sequence/iterable of keyed ReactElements instead."),pd=!0);var vn=Pn.call($e);if(vn)for(var Wi=null,pi=vn.next();!pi.done;pi=vn.next()){var Ku=pi.value;Wi=zt(Ku,Wi)}}var hr=Pn.call($e);if(hr==null)throw Error("An iterable object provided no iterator.");for(var hu=null,Kr=null,xu=Ot,w0=0,W0=0,ks=null,Xu=hr.next();xu!==null&&!Xu.done;W0++,Xu=hr.next()){xu.index>W0?(ks=xu,xu=null):ks=xu.sibling;var yl=Lt(ot,xu,Xu.value,Ut);if(yl===null){xu===null&&(xu=ks);break}f&&xu&&yl.alternate===null&&d(ot,xu),w0=j(yl,w0,W0),Kr===null?hu=yl:Kr.sibling=yl,Kr=yl,xu=ks}if(Xu.done)return E(ot,xu),hu;if(xu===null){for(;!Xu.done;W0++,Xu=hr.next()){var uf=ht(ot,Xu.value,Ut);uf!==null&&(w0=j(uf,w0,W0),Kr===null?hu=uf:Kr.sibling=uf,Kr=uf)}return hu}for(var Vo=C(ot,xu);!Xu.done;W0++,Xu=hr.next()){var Ls=Gt(Vo,ot,W0,Xu.value,Ut);Ls!==null&&(f&&Ls.alternate!==null&&Vo.delete(Ls.key===null?W0:Ls.key),w0=j(Ls,w0,W0),Kr===null?hu=Ls:Kr.sibling=Ls,Kr=Ls)}return f&&Vo.forEach(function($d){return d(ot,$d)}),hu}function oi(ot,Ot,$e,Ut){if(Ot!==null&&Ot.tag===ne){E(ot,Ot.sibling);var Pn=R(Ot,$e,Ut);return Pn.return=ot,Pn}E(ot,Ot);var vn=_g($e,ot.mode,Ut);return vn.return=ot,vn}function Mi(ot,Ot,$e,Ut){for(var Pn=$e.key,vn=Ot;vn!==null;){if(vn.key===Pn)if(vn.tag===m?$e.type===oe:vn.elementType===$e.type||Wc(vn,$e)){E(ot,vn.sibling);var Wi=R(vn,$e.type===oe?$e.props.children:$e.props,Ut);return Wi.ref=mc(ot,vn,$e),Wi.return=ot,Wi._debugSource=$e._source,Wi._debugOwner=$e._owner,Wi}else{E(ot,vn);break}else d(ot,vn);vn=vn.sibling}if($e.type===oe){var pi=rf($e.props.children,ot.mode,Ut,$e.key);return pi.return=ot,pi}else{var Ku=yg($e,ot.mode,Ut);return Ku.ref=mc(ot,Ot,$e),Ku.return=ot,Ku}}function N0(ot,Ot,$e,Ut){for(var Pn=$e.key,vn=Ot;vn!==null;){if(vn.key===Pn)if(vn.tag===H&&vn.stateNode.containerInfo===$e.containerInfo&&vn.stateNode.implementation===$e.implementation){E(ot,vn.sibling);var Wi=R(vn,$e.children||[],Ut);return Wi.return=ot,Wi}else{E(ot,vn);break}else d(ot,vn);vn=vn.sibling}var pi=Eg($e,ot.mode,Ut);return pi.return=ot,pi}function $i(ot,Ot,$e,Ut){var Pn=typeof $e=="object"&&$e!==null&&$e.type===oe&&$e.key===null;Pn&&($e=$e.props.children);var vn=typeof $e=="object"&&$e!==null;if(vn)switch($e.$$typeof){case de:return V(Mi(ot,Ot,$e,Ut));case Ce:return V(N0(ot,Ot,$e,Ut))}if(typeof $e=="string"||typeof $e=="number")return V(oi(ot,Ot,""+$e,Ut));if(Zc($e))return gn(ot,Ot,$e,Ut);if(fr($e))return kr(ot,Ot,$e,Ut);if(vn&&gc(ot,$e),typeof $e=="function"&&hd(),typeof $e=="undefined"&&!Pn)switch(ot.tag){case M:{var Wi=ot.stateNode;if(Wi.render._isMockFunction)break}case N:{var pi=ot.type;throw Error((pi.displayName||pi.name||"Component")+"(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.")}}return E(ot,Ot)}return $i}var Cf=Eh(!0),$c=Eh(!1);function Dh(f,d){if(!(f===null||d.child===f.child))throw Error("Resuming work not yet implemented.");if(d.child!==null){var E=d.child,C=Co(E,E.pendingProps,E.expirationTime);for(d.child=C,C.return=d;E.sibling!==null;)E=E.sibling,C=C.sibling=Co(E,E.pendingProps,E.expirationTime),C.return=d;C.sibling=null}}function am(f,d){for(var E=f.child;E!==null;)kv(E,d),E=E.sibling}var Gs={},ga=Ju(Gs),iu=Ju(Gs),M0=Ju(Gs);function o0(f){if(f===Gs)throw Error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.");return f}function rs(){var f=o0(M0.current);return f}function Ka(f,d){Jr(M0,d,f),Jr(iu,f,f),Jr(ga,Gs,f);var E=wt(d);ti(ga,f),Jr(ga,E,f)}function uo(f){ti(ga,f),ti(iu,f),ti(M0,f)}function fl(){var f=o0(ga.current);return f}function yc(f){var d=o0(M0.current),E=o0(ga.current),C=bt(E,f.type,d);E!==C&&(Jr(iu,f,f),Jr(ga,C,f))}function L2(f){iu.current===f&&(ti(ga,f),ti(iu,f))}var wh=0,xf=1,Af=1,e1=2,Ll=Ju(wh);function t1(f,d){return(f&d)!=0}function ya(f){return f&xf}function vd(f,d){return f&xf|d}function md(f,d){return f|d}function Fr(f,d){Jr(Ll,d,f)}function Ea(f){ti(Ll,f)}function N2(f,d){var E=f.memoizedState;if(E!==null)return E.dehydrated!==null;var C=f.memoizedProps;return C.fallback===void 0?!1:C.unstable_avoidThisFallback!==!0?!0:!d}function n1(f){for(var d=f;d!==null;){if(d.tag===ce){var E=d.memoizedState;if(E!==null){var C=E.dehydrated;if(C===null||Us(C)||g0(C))return d}}else if(d.tag===at&&d.memoizedProps.revealOrder!==void 0){var R=(d.effectTag&Xr)!==Ai;if(R)return d}else if(d.child!==null){d.child.return=d,d=d.child;continue}if(d===f)return null;for(;d.sibling===null;){if(d.return===null||d.return===f)return null;d=d.return}d.sibling.return=d.return,d=d.sibling}return null}var gd={},wi=Array.isArray;function F2(f,d,E,C){return{fiber:C,props:d,responder:f,rootEventTypes:null,state:E}}function fm(f,d,E,C,R){var j=gd,V=f.getInitialState;V!==null&&(j=V(d));var te=F2(f,d,j,E);if(!R)for(var le=E;le!==null;){var Be=le.tag;if(Be===q){R=le.stateNode;break}else if(Be===B){R=le.stateNode.containerInfo;break}le=le.return}Ne(f,te,d,j,R),C.set(f,te)}function yd(f,d,E,C,R){var j,V;if(f&&(j=f.responder,V=f.props),!(j&&j.$$typeof===jt))throw Error("An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponder().");var te=V;if(E.has(j)){Qt(!1,'Duplicate event responder "%s" found in event listeners. Event listeners passed to elements cannot use the same event responder more than once.',j.displayName);return}E.add(j);var le=C.get(j);le===void 0?fm(j,te,d,C,R):(le.props=te,le.fiber=d)}function hn(f,d,E){var C=new Set,R=d.dependencies;if(f!=null){R===null&&(R=d.dependencies={expirationTime:ft,firstContext:null,responders:new Map});var j=R.responders;if(j===null&&(j=new Map),wi(f))for(var V=0,te=f.length;V0){var j=R.dispatch;if(xs!==null){var V=xs.get(R);if(V!==void 0){xs.delete(R);var te=C.memoizedState,le=V;do{var Be=le.action;te=f(te,Be),le=le.next}while(le!==null);return go(te,C.memoizedState)||sp(),C.memoizedState=te,C.baseUpdate===R.last&&(C.baseState=te),R.lastRenderedState=te,[te,j]}}return[C.memoizedState,j]}var Xe=R.last,ht=C.baseUpdate,Lt=C.baseState,Gt;if(ht!==null?(Xe!==null&&(Xe.next=null),Gt=ht.next):Gt=Xe!==null?Xe.next:null,Gt!==null){var zt=Lt,gn=null,kr=null,oi=ht,Mi=Gt,N0=!1;do{var $i=Mi.expirationTime;if($iIu&&(Iu=$i,Qd(Iu));else if(yv($i,Mi.suspenseConfig),Mi.eagerReducer===f)zt=Mi.eagerState;else{var ot=Mi.action;zt=f(zt,ot)}oi=Mi,Mi=Mi.next}while(Mi!==null&&Mi!==Gt);N0||(kr=oi,gn=zt),go(zt,C.memoizedState)||sp(),C.memoizedState=zt,C.baseUpdate=kr,C.baseState=gn,R.lastRenderedState=zt}var Ot=R.dispatch;return[C.memoizedState,Ot]}function Pf(f){var d=wc();typeof f=="function"&&(f=f()),d.memoizedState=d.baseState=f;var E=d.queue={last:null,dispatch:null,lastRenderedReducer:P2,lastRenderedState:f},C=E.dispatch=a1.bind(null,dl,E);return[d.memoizedState,C]}function o1(f){return u1(P2,f)}function Ja(f,d,E,C){var R={tag:f,create:d,destroy:E,deps:C,next:null};if(is===null)is=Qa(),is.lastEffect=R.next=R;else{var j=is.lastEffect;if(j===null)is.lastEffect=R.next=R;else{var V=j.next;j.next=R,R.next=V,is.lastEffect=R}}return R}function l1(f){var d=wc(),E={current:f};return Object.seal(E),d.memoizedState=E,E}function I2(f){var d=i1();return d.memoizedState}function wd(f,d,E,C){var R=wc(),j=C===void 0?null:C;kf|=f,R.memoizedState=Ja(d,E,void 0,j)}function Sc(f,d,E,C){var R=i1(),j=C===void 0?null:C,V=void 0;if(jn!==null){var te=jn.memoizedState;if(V=te.destroy,j!==null){var le=te.deps;if(Nf(j,le)){Ja(Of,E,V,j);return}}}kf|=f,R.memoizedState=Ja(d,E,V,j)}function s1(f,d){return typeof jest!="undefined"&&Mv(dl),wd(wr|F0,sr|r1,f,d)}function Fl(f,d){return typeof jest!="undefined"&&Mv(dl),Sc(wr|F0,sr|r1,f,d)}function Da(f,d){return wd(wr,Mf|cl,f,d)}function Ch(f,d){return Sc(wr,Mf|cl,f,d)}function b2(f,d){if(typeof d=="function"){var E=d,C=f();return E(C),function(){E(null)}}else if(d!=null){var R=d;R.hasOwnProperty("current")||Qt(!1,"Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: %s.","an object with keys {"+Object.keys(R).join(", ")+"}");var j=f();return R.current=j,function(){R.current=null}}}function B2(f,d,E){typeof d!="function"&&Qt(!1,"Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.",d!==null?typeof d:"null");var C=E!=null?E.concat([f]):null;return wd(wr,Mf|cl,b2.bind(null,d,f),C)}function xh(f,d,E){typeof d!="function"&&Qt(!1,"Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.",d!==null?typeof d:"null");var C=E!=null?E.concat([f]):null;return Sc(wr,Mf|cl,b2.bind(null,d,f),C)}function Sd(f,d){}var Ah=Sd;function Pl(f,d){var E=wc(),C=d===void 0?null:d;return E.memoizedState=[f,C],f}function os(f,d){var E=i1(),C=d===void 0?null:d,R=E.memoizedState;if(R!==null&&C!==null){var j=R[1];if(Nf(C,j))return R[0]}return E.memoizedState=[f,C],f}function As(f,d){var E=wc(),C=d===void 0?null:d,R=f();return E.memoizedState=[R,C],R}function Ys(f,d){var E=i1(),C=d===void 0?null:d,R=E.memoizedState;if(R!==null&&C!==null){var j=R[1];if(Nf(C,j))return R[0]}var V=f();return E.memoizedState=[V,C],V}function U2(f,d){var E=Pf(f),C=E[0],R=E[1];return s1(function(){t.unstable_next(function(){var j=qo.suspense;qo.suspense=d===void 0?null:d;try{R(f)}finally{qo.suspense=j}})},[f,d]),C}function Rh(f,d){var E=o1(f),C=E[0],R=E[1];return Fl(function(){t.unstable_next(function(){var j=qo.suspense;qo.suspense=d===void 0?null:d;try{R(f)}finally{qo.suspense=j}})},[f,d]),C}function j2(f){var d=Pf(!1),E=d[0],C=d[1],R=Pl(function(j){C(!0),t.unstable_next(function(){var V=qo.suspense;qo.suspense=f===void 0?null:f;try{C(!1),j()}finally{qo.suspense=V}})},[f,E]);return[R,E]}function z2(f){var d=o1(!1),E=d[0],C=d[1],R=os(function(j){C(!0),t.unstable_next(function(){var V=qo.suspense;qo.suspense=f===void 0?null:f;try{C(!1),j()}finally{qo.suspense=V}})},[f,E]);return[R,E]}function a1(f,d,E){if(!(Dc=0){var E=c1()-d1;f.actualDuration+=E,d&&(f.selfBaseDuration=E),d1=-1}}var bl=null,$a=null,wa=!1;function V2(){wa&&Qt(!1,"We should not be hydrating here. This is a bug in React. Please file a bug.")}function G2(f){if(!we)return!1;var d=f.stateNode.containerInfo;return $a=U(d),bl=f,wa=!0,!0}function hm(f,d){return we?($a=ji(d),X2(f),wa=!0,!0):!1}function Y2(f,d){switch(f.tag){case B:ue(f.stateNode.containerInfo,d);break;case q:qe(f.type,f.memoizedProps,f.stateNode,d);break}var E=nE();E.stateNode=d,E.return=f,E.effectTag=Y0,f.lastEffect!==null?(f.lastEffect.nextEffect=E,f.lastEffect=E):f.firstEffect=f.lastEffect=E}function Fh(f,d){switch(d.effectTag=d.effectTag&~au|mi,f.tag){case B:{var E=f.stateNode.containerInfo;switch(d.tag){case q:var C=d.type,R=d.pendingProps;nt(E,C,R);break;case ne:var j=d.pendingProps;Ct(E,j);break;case ce:Mt(E);break}break}case q:{var V=f.type,te=f.memoizedProps,le=f.stateNode;switch(d.tag){case q:var Be=d.type,Xe=d.pendingProps;Pt(V,te,le,Be,Xe);break;case ne:var ht=d.pendingProps;sn(V,te,le,ht);break;case ce:rn(V,te,le);break}break}default:return}}function Ph(f,d){switch(f.tag){case q:{var E=f.type,C=f.pendingProps,R=hf(d,E,C);return R!==null?(f.stateNode=R,!0):!1}case ne:{var j=f.pendingProps,V=Bs(d,j);return V!==null?(f.stateNode=V,!0):!1}case ce:{if(Oi){var te=Ba(d);if(te!==null){var le={dehydrated:te,retryTime:Di};f.memoizedState=le;var Be=rE(te);return Be.return=f,f.child=Be,!0}}return!1}default:return!1}}function K2(f){if(!!wa){var d=$a;if(!d){Fh(bl,f),wa=!1,bl=f;return}var E=d;if(!Ph(f,d)){if(d=ji(E),!d||!Ph(f,d)){Fh(bl,f),wa=!1,bl=f;return}Y2(bl,E)}bl=f,$a=U(d)}}function vm(f,d,E){if(!we)throw Error("Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.");var C=f.stateNode,R=z(C,f.type,f.memoizedProps,d,E,f);return f.updateQueue=R,R!==null}function mm(f){if(!we)throw Error("Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.");var d=f.stateNode,E=f.memoizedProps,C=G(d,E,f);if(C){var R=bl;if(R!==null)switch(R.tag){case B:{var j=R.stateNode.containerInfo;Je(j,d,E);break}case q:{var V=R.type,te=R.memoizedProps,le=R.stateNode;vt(V,te,le,d,E);break}}}return C}function Ih(f){if(!we)throw Error("Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.");var d=f.memoizedState,E=d!==null?d.dehydrated:null;if(!E)throw Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.");$(E,f)}function gm(f){if(!we)throw Error("Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.");var d=f.memoizedState,E=d!==null?d.dehydrated:null;if(!E)throw Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.");return Te(E)}function X2(f){for(var d=f.return;d!==null&&d.tag!==q&&d.tag!==B&&d.tag!==ce;)d=d.return;bl=d}function h1(f){if(!we||f!==bl)return!1;if(!wa)return X2(f),wa=!0,!1;var d=f.type;if(f.tag!==q||d!=="head"&&d!=="body"&&!Ni(d,f.memoizedProps))for(var E=$a;E;)Y2(f,E),E=ji(E);return X2(f),f.tag===ce?$a=gm(f):$a=bl?ji(f.stateNode):null,!0}function v1(){!we||(bl=null,$a=null,wa=!1)}var m1=rt.ReactCurrentOwner,Sa=!1,Q2,Ks,Xs,Qs,J2,Ta,g1,Td,Tc,Z2;Q2={},Ks={},Xs={},Qs={},J2={},Ta=!1,g1=!1,Td={},Tc={},Z2={};function wo(f,d,E,C){f===null?d.child=$c(d,null,E,C):d.child=Cf(d,f.child,E,C)}function bh(f,d,E,C){d.child=Cf(d,f.child,null,C),d.child=Cf(d,null,E,C)}function Bh(f,d,E,C,R){if(d.type!==d.elementType){var j=E.propTypes;j&&_(j,C,"prop",qt(E),Nr)}var V=E.render,te=d.ref,le;return u0(d,R),m1.current=d,et("render"),le=Ff(f,d,V,C,te,R),Ri&&d.mode&mr&&d.memoizedState!==null&&(le=Ff(f,d,V,C,te,R)),et(null),f!==null&&!Sa?(_d(f,d,R),Ca(f,d,R)):(d.effectTag|=su,wo(f,d,le,R),d.child)}function Uh(f,d,E,C,R,j){if(f===null){var V=E.type;if(a0(V)&&E.compare===null&&E.defaultProps===void 0){var te=V;return te=r0(V),d.tag=ie,d.type=te,tp(d,V),jh(f,d,te,C,R,j)}{var le=V.propTypes;le&&_(le,C,"prop",qt(V),Nr)}var Be=gg(E.type,null,C,null,d.mode,j);return Be.ref=d.ref,Be.return=d,d.child=Be,Be}{var Xe=E.type,ht=Xe.propTypes;ht&&_(ht,C,"prop",qt(Xe),Nr)}var Lt=f.child;if(R component appears to have a render method, but doesn't extend React.Component. This is likely to cause errors. Change %s to extend React.Component instead.",le,le),Q2[le]=!0)}d.mode&mr&&Rl.recordLegacyContextWarning(d,null),m1.current=d,te=Ff(null,d,E,R,j,C)}if(d.effectTag|=su,typeof te=="object"&&te!==null&&typeof te.render=="function"&&te.$$typeof===void 0){{var Be=qt(E)||"Unknown";Ks[Be]||(Ve(!1,"The <%s /> component appears to be a function component that returns a class instance. Change %s to a class that extends React.Component instead. If you can't use a class try assigning the prototype on the function as a workaround. `%s.prototype = React.Component.prototype`. Don't use an arrow function since it cannot be called with `new` by React.",Be,Be,Be),Ks[Be]=!0)}d.tag=M,Ed();var Xe=!1;Xi(E)?(Xe=!0,Hi(d)):Xe=!1,d.memoizedState=te.state!==null&&te.state!==void 0?te.state:null;var ht=E.getDerivedStateFromProps;return typeof ht=="function"&&Tf(d,E,ht,R),al(d,te),vc(d,E,R,C),ep(null,d,E,!0,Xe,C)}else return d.tag=N,ai&&E.contextTypes&&Ve(!1,"%s uses the legacy contextTypes API which is no longer supported. Use React.createContext() with React.useContext() instead.",qt(E)||"Unknown"),Ri&&d.mode&mr&&d.memoizedState!==null&&(te=Ff(null,d,E,R,j,C)),wo(null,d,te,C),tp(d,E),d.child}function tp(f,d){if(d&&d.childContextTypes&&Ve(!1,"%s(...): childContextTypes cannot be defined on a function component.",d.displayName||d.name||"Component"),f.ref!==null){var E="",C=y0();C&&(E+=` + +Check the render method of \``+C+"`.");var R=C||f._debugID||"",j=f._debugSource;j&&(R=j.fileName+":"+j.lineNumber),J2[R]||(J2[R]=!0,Qt(!1,"Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?%s",E))}if(Ql&&d.defaultProps!==void 0){var V=qt(d)||"Unknown";Z2[V]||(Ve(!1,"%s: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.",V),Z2[V]=!0)}if(typeof d.getDerivedStateFromProps=="function"){var te=qt(d)||"Unknown";Qs[te]||(Ve(!1,"%s: Function components do not support getDerivedStateFromProps.",te),Qs[te]=!0)}if(typeof d.contextType=="object"&&d.contextType!==null){var le=qt(d)||"Unknown";Xs[le]||(Ve(!1,"%s: Function components do not support contextType.",le),Xs[le]=!0)}}var xd={dehydrated:null,retryTime:ft};function np(f,d,E){return t1(f,e1)&&(d===null||d.memoizedState!==null)}function Vh(f,d,E){var C=d.mode,R=d.pendingProps;s_(d)&&(d.effectTag|=Xr);var j=Ll.current,V=!1,te=(d.effectTag&Xr)!==Ai;if(te||np(j,f,d)?(V=!0,d.effectTag&=~Xr):(f===null||f.memoizedState!==null)&&R.fallback!==void 0&&R.unstable_avoidThisFallback!==!0&&(j=md(j,Af)),j=ya(j),Fr(d,j),"maxDuration"in R&&(g1||(g1=!0,Qt(!1,"maxDuration has been removed from React. Remove the maxDuration prop."))),f===null){if(R.fallback!==void 0&&(K2(d),Oi)){var le=d.memoizedState;if(le!==null){var Be=le.dehydrated;if(Be!==null)return Gh(d,Be,E)}}if(V){var Xe=R.fallback,ht=rf(null,C,ft,null);if(ht.return=d,(d.mode&Y)===Rr){var Lt=d.memoizedState,Gt=Lt!==null?d.child.child:d.child;ht.child=Gt;for(var zt=Gt;zt!==null;)zt.return=ht,zt=zt.sibling}var gn=rf(Xe,C,E,null);return gn.return=d,ht.sibling=gn,d.memoizedState=xd,d.child=ht,gn}else{var kr=R.children;return d.memoizedState=null,d.child=$c(d,null,kr,E)}}else{var oi=f.memoizedState;if(oi!==null){if(Oi){var Mi=oi.dehydrated;if(Mi!==null)if(te){if(d.memoizedState!==null)return d.child=f.child,d.effectTag|=Xr,null;var N0=R.fallback,$i=rf(null,C,ft,null);if($i.return=d,$i.child=null,(d.mode&Y)===Rr)for(var ot=$i.child=d.child;ot!==null;)ot.return=$i,ot=ot.sibling;else Cf(d,f.child,null,E);if(en&&d.mode&ii){for(var Ot=0,$e=$i.child;$e!==null;)Ot+=$e.treeBaseDuration,$e=$e.sibling;$i.treeBaseDuration=Ot}var Ut=rf(N0,C,E,null);return Ut.return=d,$i.sibling=Ut,Ut.effectTag|=mi,$i.childExpirationTime=ft,d.memoizedState=xd,d.child=$i,Ut}else return Yh(f,d,Mi,oi,E)}var Pn=f.child,vn=Pn.sibling;if(V){var Wi=R.fallback,pi=Co(Pn,Pn.pendingProps,ft);if(pi.return=d,(d.mode&Y)===Rr){var Ku=d.memoizedState,hr=Ku!==null?d.child.child:d.child;if(hr!==Pn.child){pi.child=hr;for(var hu=hr;hu!==null;)hu.return=pi,hu=hu.sibling}}if(en&&d.mode&ii){for(var Kr=0,xu=pi.child;xu!==null;)Kr+=xu.treeBaseDuration,xu=xu.sibling;pi.treeBaseDuration=Kr}var w0=Co(vn,Wi,vn.expirationTime);return w0.return=d,pi.sibling=w0,pi.childExpirationTime=ft,d.memoizedState=xd,d.child=pi,w0}else{var W0=R.children,ks=Pn.child,Xu=Cf(d,ks,W0,E);return d.memoizedState=null,d.child=Xu}}else{var yl=f.child;if(V){var uf=R.fallback,Vo=rf(null,C,ft,null);if(Vo.return=d,Vo.child=yl,yl!==null&&(yl.return=Vo),(d.mode&Y)===Rr){var Ls=d.memoizedState,$d=Ls!==null?d.child.child:d.child;Vo.child=$d;for(var Gf=$d;Gf!==null;)Gf.return=Vo,Gf=Gf.sibling}if(en&&d.mode&ii){for(var Fc=0,Hl=Vo.child;Hl!==null;)Fc+=Hl.treeBaseDuration,Hl=Hl.sibling;Vo.treeBaseDuration=Fc}var Go=rf(uf,C,E,null);return Go.return=d,Vo.sibling=Go,Go.effectTag|=mi,Vo.childExpirationTime=ft,d.memoizedState=xd,d.child=Vo,Go}else{d.memoizedState=null;var N1=R.children;return d.child=Cf(d,yl,N1,E)}}}}function rp(f,d,E){d.memoizedState=null;var C=d.pendingProps,R=C.children;return wo(f,d,R,E),d.child}function Gh(f,d,E){if((f.mode&Y)===Rr)Qt(!1,"Cannot hydrate Suspense in legacy mode. Switch from ReactDOM.hydrate(element, container) to ReactDOM.createBlockingRoot(container, { hydrate: true }).render(element) or remove the Suspense components from the server rendered components."),f.expirationTime=Un;else if(g0(d)){var C=jl(),R=ws(C);bn&&x(R),f.expirationTime=R}else f.expirationTime=Di,bn&&x(Di);return null}function Yh(f,d,E,C,R){if(V2(),(d.mode&Y)===Rr||g0(E))return rp(f,d,R);var j=f.childExpirationTime>=R;if(Sa||j){if(R. Use lowercase "%s" instead.',f,f.toLowerCase());break}case"forward":case"backward":{Qt(!1,'"%s" is not a valid value for revealOrder on . React uses the -s suffix in the spelling. Use "%ss" instead.',f,f.toLowerCase());break}default:Qt(!1,'"%s" is not a supported revealOrder on . Did you mean "together", "forwards" or "backwards"?',f);break}else Qt(!1,'%s is not a supported value for revealOrder on . Did you mean "together", "forwards" or "backwards"?',f)}function Kh(f,d){f!==void 0&&!Tc[f]&&(f!=="collapsed"&&f!=="hidden"?(Tc[f]=!0,Qt(!1,'"%s" is not a supported value for tail on . Did you mean "collapsed" or "hidden"?',f)):d!=="forwards"&&d!=="backwards"&&(Tc[f]=!0,Qt(!1,' is only valid if revealOrder is "forwards" or "backwards". Did you mean to specify revealOrder="forwards"?',f)))}function _1(f,d){{var E=Array.isArray(f),C=!E&&typeof fr(f)=="function";if(E||C){var R=E?"array":"iterable";return Qt(!1,"A nested %s was passed to row #%s in . Wrap it in an additional SuspenseList to configure its revealOrder: ... {%s} ... ",R,d,R),!1}}return!0}function Cm(f,d){if((d==="forwards"||d==="backwards")&&f!==void 0&&f!==null&&f!==!1)if(Array.isArray(f)){for(var E=0;E. This is not useful since it needs multiple rows. Did you mean to pass multiple children or an array?',d)}}function up(f,d,E,C,R,j){var V=f.memoizedState;V===null?f.memoizedState={isBackwards:d,rendering:null,last:C,tail:E,tailExpiration:0,tailMode:R,lastEffect:j}:(V.isBackwards=d,V.rendering=null,V.last=C,V.tail=E,V.tailExpiration=0,V.tailMode=R,V.lastEffect=j)}function op(f,d,E){var C=d.pendingProps,R=C.revealOrder,j=C.tail,V=C.children;Tm(R),Kh(j,R),Cm(V,R),wo(f,d,V,E);var te=Ll.current,le=t1(te,e1);if(le)te=vd(te,e1),d.effectTag|=Xr;else{var Be=f!==null&&(f.effectTag&Xr)!==Ai;Be&&wm(d,d.child,E),te=ya(te)}if(Fr(d,te),(d.mode&Y)===Rr)d.memoizedState=null;else switch(R){case"forwards":{var Xe=Sm(d.child),ht;Xe===null?(ht=d.child,d.child=null):(ht=Xe.sibling,Xe.sibling=null),up(d,!1,ht,Xe,j,d.lastEffect);break}case"backwards":{var Lt=null,Gt=d.child;for(d.child=null;Gt!==null;){var zt=Gt.alternate;if(zt!==null&&n1(zt)===null){d.child=Gt;break}var gn=Gt.sibling;Gt.sibling=Lt,Lt=Gt,Gt=gn}up(d,!0,Lt,null,j,d.lastEffect);break}case"together":{up(d,!1,null,null,void 0,d.lastEffect);break}default:d.memoizedState=null}return d.child}function xm(f,d,E){Ka(d,d.stateNode.containerInfo);var C=d.pendingProps;return f===null?d.child=Cf(d,null,C,E):wo(f,d,C,E),d.child}function Am(f,d,E){var C=d.type,R=C._context,j=d.pendingProps,V=d.memoizedProps,te=j.value;{var le=d.type.propTypes;le&&_(le,j,"prop","Context.Provider",Nr)}if(xr(d,te),V!==null){var Be=V.value,Xe=du(R,te,Be);if(Xe===0){if(V.children===j.children&&!aa())return Ca(f,d,E)}else Ml(d,R,Xe,E)}var ht=j.children;return wo(f,d,ht,E),d.child}var Xh=!1;function Rm(f,d,E){var C=d.type;C._context===void 0?C!==C.Consumer&&(Xh||(Xh=!0,Qt(!1,"Rendering directly is not supported and will be removed in a future major release. Did you mean to render instead?"))):C=C._context;var R=d.pendingProps,j=R.children;typeof j!="function"&&Ve(!1,"A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it."),u0(d,E);var V=We(C,R.unstable_observedBits),te;return m1.current=d,et("render"),te=j(V),et(null),d.effectTag|=su,wo(f,d,te,E),d.child}function Om(f,d,E){var C=d.type.impl;if(C.reconcileChildren===!1)return null;var R=d.pendingProps,j=R.children;return wo(f,d,j,E),d.child}function lp(f,d,E){var C=d.pendingProps,R=C.children;return wo(f,d,R,E),d.child}function sp(){Sa=!0}function Ca(f,d,E){tu(d),f!==null&&(d.dependencies=f.dependencies),en&&Nh(d);var C=d.expirationTime;C!==ft&&Qd(C);var R=d.childExpirationTime;return R=E;le&&(d.effectTag|=wr)}break;case ce:{var Be=d.memoizedState;if(Be!==null){if(Oi&&Be.dehydrated!==null){Fr(d,ya(Ll.current)),d.effectTag|=Xr;break}var Xe=d.child,ht=Xe.childExpirationTime;if(ht!==ft&&ht>=E)return Vh(f,d,E);Fr(d,ya(Ll.current));var Lt=Ca(f,d,E);return Lt!==null?Lt.sibling:null}else Fr(d,ya(Ll.current));break}case at:{var Gt=(f.effectTag&Xr)!==Ai,zt=d.childExpirationTime>=E;if(Gt){if(zt)return op(f,d,E);d.effectTag|=Xr}var gn=d.memoizedState;if(gn!==null&&(gn.rendering=null,gn.tail=null),Fr(d,Ll.current),zt)break;return null}}return Ca(f,d,E)}else Sa=!1}else Sa=!1;switch(d.expirationTime=ft,d.tag){case T:return Dm(f,d,d.type,E);case Oe:{var kr=d.elementType;return bf(f,d,kr,C,E)}case N:{var oi=d.type,Mi=d.pendingProps,N0=d.elementType===oi?Mi:qi(oi,Mi);return $2(f,d,oi,N0,E)}case M:{var $i=d.type,ot=d.pendingProps,Ot=d.elementType===$i?ot:qi($i,ot);return qh(f,d,$i,Ot,E)}case B:return _m(f,d,E);case q:return Em(f,d,E);case ne:return If(f,d);case ce:return Vh(f,d,E);case H:return xm(f,d,E);case fe:{var $e=d.type,Ut=d.pendingProps,Pn=d.elementType===$e?Ut:qi($e,Ut);return Bh(f,d,$e,Pn,E)}case m:return ym(f,d,E);case he:return zh(f,d,E);case _e:return Hh(f,d,E);case se:return Am(f,d,E);case De:return Rm(f,d,E);case me:{var vn=d.type,Wi=d.pendingProps,pi=qi(vn,Wi);if(d.type!==d.elementType){var Ku=vn.propTypes;Ku&&_(Ku,pi,"prop",qt(vn),Nr)}return pi=qi(vn.type,pi),Uh(f,d,vn,pi,C,E)}case ie:return jh(f,d,d.type,d.pendingProps,C,E);case Ue:{var hr=d.type,hu=d.pendingProps,Kr=d.elementType===hr?hu:qi(hr,hu);return Cd(f,d,hr,Kr,E)}case at:return op(f,d,E);case Dt:{if(Wt)return Om(f,d,E);break}case Qe:{if(Ru)return lp(f,d,E);break}}throw Error("Unknown unit of work tag ("+d.tag+"). This error is likely caused by a bug in React. Please file an issue.")}function Qh(f,d,E,C){return{currentFiber:f,impl:E,instance:null,prevProps:null,props:d,state:C}}function Ad(f){return f.tag===ce&&f.memoizedState!==null}function D1(f){return f.child.sibling.child}var Jh={};function fp(f,d,E){if(Ru){if(f.tag===q){var C=f.type,R=f.memoizedProps,j=f.stateNode,V=No(j);V!==null&&d(C,R||Jh,V)===!0&&E.push(V)}var te=f.child;Ad(f)&&(te=D1(f)),te!==null&&cp(te,d,E)}}function Zh(f,d){if(Ru){if(f.tag===q){var E=f.type,C=f.memoizedProps,R=f.stateNode,j=No(R);if(j!==null&&d(E,C,j)===!0)return j}var V=f.child;if(Ad(f)&&(V=D1(f)),V!==null)return $h(V,d)}return null}function cp(f,d,E){for(var C=f;C!==null;)fp(C,d,E),C=C.sibling}function $h(f,d){for(var E=f;E!==null;){var C=Zh(E,d);if(C!==null)return C;E=E.sibling}return null}function ev(f,d,E){if(Rd(f,d))E.push(f.stateNode.methods);else{var C=f.child;Ad(f)&&(C=D1(f)),C!==null&&dp(C,d,E)}}function dp(f,d,E){for(var C=f;C!==null;)ev(C,d,E),C=C.sibling}function Rd(f,d){return f.tag===Qe&&f.type===d&&f.stateNode!==null}function Od(f,d){return{getChildren:function(){var E=d.fiber,C=E.child,R=[];return C!==null&&dp(C,f,R),R.length===0?null:R},getChildrenFromRoot:function(){for(var E=d.fiber,C=E;C!==null;){var R=C.return;if(R===null||(C=R,C.tag===Qe&&C.type===f))break}var j=[];return dp(C.child,f,j),j.length===0?null:j},getParent:function(){for(var E=d.fiber.return;E!==null;){if(E.tag===Qe&&E.type===f)return E.stateNode.methods;E=E.return}return null},getProps:function(){var E=d.fiber;return E.memoizedProps},queryAllNodes:function(E){var C=d.fiber,R=C.child,j=[];return R!==null&&cp(R,E,j),j.length===0?null:j},queryFirstNode:function(E){var C=d.fiber,R=C.child;return R!==null?$h(R,E):null},containsNode:function(E){for(var C=cr(E);C!==null;){if(C.tag===Qe&&C.type===f&&C.stateNode===d)return!0;C=C.return}return!1}}}function H0(f){f.effectTag|=wr}function Md(f){f.effectTag|=Oo}var xa,ef,kd,Ld;if(b0)xa=function(f,d,E,C){for(var R=d.child;R!==null;){if(R.tag===q||R.tag===ne)Qr(f,R.stateNode);else if(Wt&&R.tag===Dt)Qr(f,R.stateNode.instance);else if(R.tag!==H){if(R.child!==null){R.child.return=R,R=R.child;continue}}if(R===d)return;for(;R.sibling===null;){if(R.return===null||R.return===d)return;R=R.return}R.sibling.return=R.return,R=R.sibling}},ef=function(f){},kd=function(f,d,E,C,R){var j=f.memoizedProps;if(j!==C){var V=d.stateNode,te=fl(),le=h0(V,E,j,C,R,te);d.updateQueue=le,le&&H0(d)}},Ld=function(f,d,E,C){E!==C&&H0(d)};else if(Q){xa=function(f,d,E,C){for(var R=d.child;R!==null;){e:if(R.tag===q){var j=R.stateNode;if(E&&C){var V=R.memoizedProps,te=R.type;j=$r(j,te,V,R)}Qr(f,j)}else if(R.tag===ne){var le=R.stateNode;if(E&&C){var Be=R.memoizedProps;le=$l(le,Be,R)}Qr(f,le)}else if(Wt&&R.tag===Dt){var Xe=R.stateNode.instance;if(E&&C){var ht=R.memoizedProps,Lt=R.type;Xe=$r(Xe,Lt,ht,R)}Qr(f,Xe)}else if(R.tag!==H){if(R.tag===ce){if((R.effectTag&wr)!==Ai){var Gt=R.memoizedState!==null;if(Gt){var zt=R.child;if(zt!==null){zt.child!==null&&(zt.child.return=zt,xa(f,zt,!0,Gt));var gn=zt.sibling;if(gn!==null){gn.return=R,R=gn;continue}}}}if(R.child!==null){R.child.return=R,R=R.child;continue}}else if(R.child!==null){R.child.return=R,R=R.child;continue}}if(R=R,R===d)return;for(;R.sibling===null;){if(R.return===null||R.return===d)return;R=R.return}R.sibling.return=R.return,R=R.sibling}};var pp=function(f,d,E,C){for(var R=d.child;R!==null;){e:if(R.tag===q){var j=R.stateNode;if(E&&C){var V=R.memoizedProps,te=R.type;j=$r(j,te,V,R)}Qn(f,j)}else if(R.tag===ne){var le=R.stateNode;if(E&&C){var Be=R.memoizedProps;le=$l(le,Be,R)}Qn(f,le)}else if(Wt&&R.tag===Dt){var Xe=R.stateNode.instance;if(E&&C){var ht=R.memoizedProps,Lt=R.type;Xe=$r(Xe,Lt,ht,R)}Qn(f,Xe)}else if(R.tag!==H){if(R.tag===ce){if((R.effectTag&wr)!==Ai){var Gt=R.memoizedState!==null;if(Gt){var zt=R.child;if(zt!==null){zt.child!==null&&(zt.child.return=zt,pp(f,zt,!0,Gt));var gn=zt.sibling;if(gn!==null){gn.return=R,R=gn;continue}}}}if(R.child!==null){R.child.return=R,R=R.child;continue}}else if(R.child!==null){R.child.return=R,R=R.child;continue}}if(R=R,R===d)return;for(;R.sibling===null;){if(R.return===null||R.return===d)return;R=R.return}R.sibling.return=R.return,R=R.sibling}};ef=function(f){var d=f.stateNode,E=f.firstEffect===null;if(!E){var C=d.containerInfo,R=S0(C);pp(R,f,!1,!1),d.pendingChildren=R,H0(f),fc(C,R)}},kd=function(f,d,E,C,R){var j=f.stateNode,V=f.memoizedProps,te=d.firstEffect===null;if(te&&V===C){d.stateNode=j;return}var le=d.stateNode,Be=fl(),Xe=null;if(V!==C&&(Xe=h0(le,E,V,C,R,Be)),te&&Xe===null){d.stateNode=j;return}var ht=gs(j,Xe,E,V,C,d,te,le);Ou(ht,E,C,R,Be)&&H0(d),d.stateNode=ht,te?H0(d):xa(ht,d,!1,!1)},Ld=function(f,d,E,C){if(E!==C){var R=rs(),j=fl();d.stateNode=vs(C,R,j,d),H0(d)}}}else ef=function(f){},kd=function(f,d,E,C,R){},Ld=function(f,d,E,C){};function Nd(f,d){switch(f.tailMode){case"hidden":{for(var E=f.tail,C=null;E!==null;)E.alternate!==null&&(C=E),E=E.sibling;C===null?f.tail=null:C.sibling=null;break}case"collapsed":{for(var R=f.tail,j=null;R!==null;)R.alternate!==null&&(j=R),R=R.sibling;j===null?!d&&f.tail!==null?f.tail.sibling=null:f.tail=null:j.sibling=null;break}}}function tv(f,d,E){var C=d.pendingProps;switch(d.tag){case T:break;case Oe:break;case ie:case N:break;case M:{var R=d.type;Xi(R)&&qs(d);break}case B:{uo(d),A0(d);var j=d.stateNode;if(j.pendingContext&&(j.context=j.pendingContext,j.pendingContext=null),f===null||f.child===null){var V=h1(d);V&&H0(d)}ef(d);break}case q:{L2(d);var te=rs(),le=d.type;if(f!==null&&d.stateNode!=null){if(kd(f,d,le,C,te),yi){var Be=f.memoizedProps.listeners,Xe=C.listeners;Be!==Xe&&H0(d)}f.ref!==d.ref&&Md(d)}else{if(!C){if(d.stateNode===null)throw Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.");break}var ht=fl(),Lt=h1(d);if(Lt){if(vm(d,te,ht)&&H0(d),yi){var Gt=C.listeners;Gt!=null&&hn(Gt,d,te)}}else{var zt=Ki(le,C,te,ht,d);if(xa(zt,d,!1,!1),d.stateNode=zt,yi){var gn=C.listeners;gn!=null&&hn(gn,d,te)}Ou(zt,le,C,te,ht)&&H0(d)}d.ref!==null&&Md(d)}break}case ne:{var kr=C;if(f&&d.stateNode!=null){var oi=f.memoizedProps;Ld(f,d,oi,kr)}else{if(typeof kr!="string"&&d.stateNode===null)throw Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.");var Mi=rs(),N0=fl(),$i=h1(d);$i?mm(d)&&H0(d):d.stateNode=vs(kr,Mi,N0,d)}break}case fe:break;case ce:{Ea(d);var ot=d.memoizedState;if(Oi&&ot!==null&&ot.dehydrated!==null)if(f===null){var Ot=h1(d);if(!Ot)throw Error("A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.");return Ih(d),bn&&x(Di),null}else return v1(),(d.effectTag&Xr)===Ai&&(d.memoizedState=null),d.effectTag|=wr,null;if((d.effectTag&Xr)!==Ai)return d.expirationTime=E,d;var $e=ot!==null,Ut=!1;if(f===null)d.memoizedProps.fallback!==void 0&&h1(d);else{var Pn=f.memoizedState;if(Ut=Pn!==null,!$e&&Pn!==null){var vn=f.child.sibling;if(vn!==null){var Wi=d.firstEffect;Wi!==null?(d.firstEffect=vn,vn.nextEffect=Wi):(d.firstEffect=d.lastEffect=vn,vn.nextEffect=null),vn.effectTag=Y0}}}if($e&&!Ut&&(d.mode&Y)!==Rr){var pi=f===null&&d.memoizedProps.unstable_avoidThisFallback!==!0;pi||t1(Ll.current,Af)?_v():Ev()}Q&&$e&&(d.effectTag|=wr),b0&&($e||Ut)&&(d.effectTag|=wr),Yi&&d.updateQueue!==null&&d.memoizedProps.suspenseCallback!=null&&(d.effectTag|=wr);break}case m:break;case he:break;case _e:break;case H:uo(d),ef(d);break;case se:i0(d);break;case De:break;case me:break;case Ue:{var Ku=d.type;Xi(Ku)&&qs(d);break}case at:{Ea(d);var hr=d.memoizedState;if(hr===null)break;var hu=(d.effectTag&Xr)!==Ai,Kr=hr.rendering;if(Kr===null)if(hu)Nd(hr,!1);else{var xu=Dv()&&(f===null||(f.effectTag&Xr)===Ai);if(!xu)for(var w0=d.child;w0!==null;){var W0=n1(w0);if(W0!==null){hu=!0,d.effectTag|=Xr,Nd(hr,!1);var ks=W0.updateQueue;return ks!==null&&(d.updateQueue=ks,d.effectTag|=wr),hr.lastEffect===null&&(d.firstEffect=null),d.lastEffect=hr.lastEffect,am(d,E),Fr(d,vd(Ll.current,e1)),d.child}w0=w0.sibling}}else{if(!hu){var Xu=n1(Kr);if(Xu!==null){d.effectTag|=Xr,hu=!0;var yl=Xu.updateQueue;if(yl!==null&&(d.updateQueue=yl,d.effectTag|=wr),Nd(hr,!0),hr.tail===null&&hr.tailMode==="hidden"&&!Kr.alternate){var uf=d.lastEffect=hr.lastEffect;return uf!==null&&(uf.nextEffect=null),null}}else if(mt()>hr.tailExpiration&&E>Di){d.effectTag|=Xr,hu=!0,Nd(hr,!1);var Vo=E-1;d.expirationTime=d.childExpirationTime=Vo,bn&&x(Vo)}}if(hr.isBackwards)Kr.sibling=d.child,d.child=Kr;else{var Ls=hr.last;Ls!==null?Ls.sibling=Kr:d.child=Kr,hr.last=Kr}}if(hr.tail!==null){if(hr.tailExpiration===0){var $d=500;hr.tailExpiration=mt()+$d}var Gf=hr.tail;hr.rendering=Gf,hr.tail=Gf.sibling,hr.lastEffect=d.lastEffect,Gf.sibling=null;var Fc=Ll.current;return hu?Fc=vd(Fc,e1):Fc=ya(Fc),Fr(d,Fc),Gf}break}case Dt:{if(Wt){var Hl=d.type.impl,Go=d.stateNode;if(Go===null){var N1=Hl.getInitialState,v_;N1!==void 0&&(v_=N1(C)),Go=d.stateNode=Qh(d,C,Hl,v_||{});var m_=pt(Go);if(Go.instance=m_,Hl.reconcileChildren===!1)return null;xa(m_,d,!1,!1),Yn(Go)}else{var _E=Go.props;if(Go.prevProps=_E,Go.props=C,Go.currentFiber=d,Q){var g_=la(Go);Go.instance=g_,xa(g_,d,!1,!1)}var EE=Cn(Go);EE&&H0(d)}}break}case Qe:{if(Ru)if(f===null){var DE=d.type,Ag={fiber:d,methods:null};if(d.stateNode=Ag,Ag.methods=Od(DE,Ag),yi){var y_=C.listeners;if(y_!=null){var wE=rs();hn(y_,d,wE)}}d.ref!==null&&(Md(d),H0(d))}else{if(yi){var SE=f.memoizedProps.listeners,TE=C.listeners;(SE!==TE||d.ref!==null)&&H0(d)}else d.ref!==null&&H0(d);f.ref!==d.ref&&Md(d)}break}default:throw Error("Unknown unit of work tag ("+d.tag+"). This error is likely caused by a bug in React. Please file an issue.")}return null}function Mm(f,d){switch(f.tag){case M:{var E=f.type;Xi(E)&&qs(f);var C=f.effectTag;return C&p0?(f.effectTag=C&~p0|Xr,f):null}case B:{uo(f),A0(f);var R=f.effectTag;if((R&Xr)!==Ai)throw Error("The root failed to unmount after an error. This is likely a bug in React. Please file an issue.");return f.effectTag=R&~p0|Xr,f}case q:return L2(f),null;case ce:{if(Ea(f),Oi){var j=f.memoizedState;if(j!==null&&j.dehydrated!==null){if(f.alternate===null)throw Error("Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue.");v1()}}var V=f.effectTag;return V&p0?(f.effectTag=V&~p0|Xr,f):null}case at:return Ea(f),null;case H:return uo(f),null;case se:return i0(f),null;default:return null}}function nv(f){switch(f.tag){case M:{var d=f.type.childContextTypes;d!=null&&qs(f);break}case B:{uo(f),A0(f);break}case q:{L2(f);break}case H:uo(f);break;case ce:Ea(f);break;case at:Ea(f);break;case se:i0(f);break;default:break}}function hp(f,d){return{value:f,source:d,stack:Cr(d)}}var vp=function(f,d,E,C,R,j,V,te,le){var Be=Array.prototype.slice.call(arguments,3);try{d.apply(E,Be)}catch(Xe){this.onError(Xe)}};if(typeof window!="undefined"&&typeof window.dispatchEvent=="function"&&typeof document!="undefined"&&typeof document.createEvent=="function"){var mp=document.createElement("react"),km=function(f,d,E,C,R,j,V,te,le){if(typeof document=="undefined")throw Error("The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.");var Be=document.createEvent("Event"),Xe=!0,ht=window.event,Lt=Object.getOwnPropertyDescriptor(window,"event"),Gt=Array.prototype.slice.call(arguments,3);function zt(){mp.removeEventListener(N0,zt,!1),typeof window.event!="undefined"&&window.hasOwnProperty("event")&&(window.event=ht),d.apply(E,Gt),Xe=!1}var gn,kr=!1,oi=!1;function Mi($i){if(gn=$i.error,kr=!0,gn===null&&$i.colno===0&&$i.lineno===0&&(oi=!0),$i.defaultPrevented&&gn!=null&&typeof gn=="object")try{gn._suppressLogging=!0}catch(ot){}}var N0="react-"+(f||"invokeguardedcallback");window.addEventListener("error",Mi),mp.addEventListener(N0,zt,!1),Be.initEvent(N0,!1,!1),mp.dispatchEvent(Be),Lt&&Object.defineProperty(window,"event",Lt),Xe&&(kr?oi&&(gn=new Error("A cross-origin error was thrown. React doesn't have access to the actual error object in development. See https://fb.me/react-crossorigin-error for more information.")):gn=new Error(`An error was thrown inside one of your components, but React doesn't know what it was. This is likely due to browser flakiness. React does its best to preserve the "Pause on exceptions" behavior of the DevTools, which requires some DEV-mode only tricks. It's possible that these don't work in your browser. Try triggering the error in production mode, or switching to a modern browser. If you suspect that this is actually an issue with React, please file an issue.`),this.onError(gn)),window.removeEventListener("error",Mi)};vp=km}var Lm=vp,So=!1,Fd=null,Nm={onError:function(f){So=!0,Fd=f}};function pl(f,d,E,C,R,j,V,te,le){So=!1,Fd=null,Lm.apply(Nm,arguments)}function tr(){return So}function Js(){if(So){var f=Fd;return So=!1,Fd=null,f}else throw Error("clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.")}function hl(f){return!0}function l0(f){var d=hl(f);if(d!==!1){var E=f.error;{var C=f.componentName,R=f.componentStack,j=f.errorBoundaryName,V=f.errorBoundaryFound,te=f.willRetry;if(E!=null&&E._suppressLogging){if(V&&te)return;console.error(E)}var le=C?"The above error occurred in the <"+C+"> component:":"The above error occurred in one of your React components:",Be;V&&j?te?Be="React will try to recreate this component tree from scratch "+("using the error boundary you provided, "+j+"."):Be="This error was initially handled by the error boundary "+j+`. +Recreating the tree from scratch failed so React will unmount the tree.`:Be=`Consider adding an error boundary to your tree to customize error handling behavior. +Visit https://fb.me/react-error-boundaries to learn more about error boundaries.`;var Xe=""+le+R+` + +`+(""+Be);console.error(Xe)}}}var rv=null;rv=new Set;var Zs=typeof WeakSet=="function"?WeakSet:Set;function gp(f,d){var E=d.source,C=d.stack;C===null&&E!==null&&(C=Cr(E));var R={componentName:E!==null?qt(E.type):null,componentStack:C!==null?C:"",error:d.value,errorBoundary:null,errorBoundaryName:null,errorBoundaryFound:!1,willRetry:!1};f!==null&&f.tag===M&&(R.errorBoundary=f.stateNode,R.errorBoundaryName=qt(f.type),R.errorBoundaryFound=!0,R.willRetry=!0);try{l0(R)}catch(j){setTimeout(function(){throw j})}}var Fm=function(f,d){Bi(f,"componentWillUnmount"),d.props=f.memoizedProps,d.state=f.memoizedState,d.componentWillUnmount(),Ci()};function iv(f,d){if(pl(null,Fm,null,f,d),tr()){var E=Js();qf(f,E)}}function yp(f){var d=f.ref;if(d!==null)if(typeof d=="function"){if(pl(null,d,null,null),tr()){var E=Js();qf(f,E)}}else d.current=null}function Pm(f,d){if(pl(null,d,null),tr()){var E=Js();qf(f,E)}}function _p(f,d){switch(d.tag){case N:case fe:case ie:{Cc(cm,Of,d);return}case M:{if(d.effectTag&Mo&&f!==null){var E=f.memoizedProps,C=f.memoizedState;Bi(d,"getSnapshotBeforeUpdate");var R=d.stateNode;d.type===d.elementType&&!Ta&&(R.props!==d.memoizedProps&&Qt(!1,"Expected %s props to match memoized props before getSnapshotBeforeUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.",qt(d.type)||"instance"),R.state!==d.memoizedState&&Qt(!1,"Expected %s state to match memoized state before getSnapshotBeforeUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.",qt(d.type)||"instance"));var j=R.getSnapshotBeforeUpdate(d.elementType===d.type?E:qi(d.type,E),C);{var V=rv;j===void 0&&!V.has(d.type)&&(V.add(d.type),Ve(!1,"%s.getSnapshotBeforeUpdate(): A snapshot value (or null) must be returned. You have returned undefined.",qt(d.type)))}R.__reactInternalSnapshotBeforeUpdate=j,Ci()}return}case B:case q:case ne:case H:case Ue:return;default:throw Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.")}}function Cc(f,d,E){var C=E.updateQueue,R=C!==null?C.lastEffect:null;if(R!==null){var j=R.next,V=j;do{if((V.tag&f)!==Of){var te=V.destroy;V.destroy=void 0,te!==void 0&&te()}if((V.tag&d)!==Of){var le=V.create;V.destroy=le();{var Be=V.destroy;if(Be!==void 0&&typeof Be!="function"){var Xe=void 0;Be===null?Xe=" You returned null. If your effect does not require clean up, return undefined (or nothing).":typeof Be.then=="function"?Xe=` + +It looks like you wrote useEffect(async () => ...) or returned a Promise. Instead, write the async function inside your effect and call it immediately: + +useEffect(() => { + async function fetchData() { + // You can await here + const response = await MyAPI.getData(someId); + // ... + } + fetchData(); +}, [someId]); // Or [] if effect doesn't need props or state + +Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching`:Xe=" You returned: "+Be,Ve(!1,"An effect function must not return anything besides a function, which is used for clean-up.%s%s",Xe,Cr(E))}}}V=V.next}while(V!==j)}}function Aa(f){if((f.effectTag&F0)!==Ai)switch(f.tag){case N:case fe:case ie:{Cc(sr,Of,f),Cc(Of,r1,f);break}default:break}}function Ep(f,d,E,C){switch(E.tag){case N:case fe:case ie:{Cc(dm,cl,E);break}case M:{var R=E.stateNode;if(E.effectTag&wr)if(d===null)Bi(E,"componentDidMount"),E.type===E.elementType&&!Ta&&(R.props!==E.memoizedProps&&Qt(!1,"Expected %s props to match memoized props before componentDidMount. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.",qt(E.type)||"instance"),R.state!==E.memoizedState&&Qt(!1,"Expected %s state to match memoized state before componentDidMount. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.",qt(E.type)||"instance")),R.componentDidMount(),Ci();else{var j=E.elementType===E.type?d.memoizedProps:qi(E.type,d.memoizedProps),V=d.memoizedState;Bi(E,"componentDidUpdate"),E.type===E.elementType&&!Ta&&(R.props!==E.memoizedProps&&Qt(!1,"Expected %s props to match memoized props before componentDidUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.",qt(E.type)||"instance"),R.state!==E.memoizedState&&Qt(!1,"Expected %s state to match memoized state before componentDidUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.",qt(E.type)||"instance")),R.componentDidUpdate(j,V,R.__reactInternalSnapshotBeforeUpdate),Ci()}var te=E.updateQueue;te!==null&&(E.type===E.elementType&&!Ta&&(R.props!==E.memoizedProps&&Qt(!1,"Expected %s props to match memoized props before processing the update queue. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.",qt(E.type)||"instance"),R.state!==E.memoizedState&&Qt(!1,"Expected %s state to match memoized state before processing the update queue. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.",qt(E.type)||"instance")),yo(E,te,R,C));return}case B:{var le=E.updateQueue;if(le!==null){var Be=null;if(E.child!==null)switch(E.child.tag){case q:Be=No(E.child.stateNode);break;case M:Be=E.child.stateNode;break}yo(E,le,Be,C)}return}case q:{var Xe=E.stateNode;if(d===null&&E.effectTag&wr){var ht=E.type,Lt=E.memoizedProps;Hu(Xe,ht,Lt,E)}return}case ne:return;case H:return;case _e:{if(en){var Gt=E.memoizedProps.onRender;typeof Gt=="function"&&(bn?Gt(E.memoizedProps.id,d===null?"mount":"update",E.actualDuration,E.treeBaseDuration,E.actualStartTime,Il(),f.memoizedInteractions):Gt(E.memoizedProps.id,d===null?"mount":"update",E.actualDuration,E.treeBaseDuration,E.actualStartTime,Il()))}return}case ce:{Bl(f,E);return}case at:case Ue:case Dt:case Qe:return;default:throw Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.")}}function Pd(f,d){if(b0)for(var E=f;;){if(E.tag===q){var C=E.stateNode;d?Ia(C):ua(E.stateNode,E.memoizedProps)}else if(E.tag===ne){var R=E.stateNode;d?m0(R):J0(R,E.memoizedProps)}else if(E.tag===ce&&E.memoizedState!==null&&E.memoizedState.dehydrated===null){var j=E.child.sibling;j.return=E,E=j;continue}else if(E.child!==null){E.child.return=E,E=E.child;continue}if(E===f)return;for(;E.sibling===null;){if(E.return===null||E.return===f)return;E=E.return}E.sibling.return=E.return,E=E.sibling}}function bu(f){var d=f.ref;if(d!==null){var E=f.stateNode,C;switch(f.tag){case q:C=No(E);break;default:C=E}Ru&&f.tag===Qe&&(C=E.methods),typeof d=="function"?d(C):(d.hasOwnProperty("current")||Ve(!1,"Unexpected ref object provided for %s. Use either a ref-setter function or React.createRef().%s",qt(f.type),Cr(f)),d.current=C)}}function Yu(f){var d=f.ref;d!==null&&(typeof d=="function"?d(null):d.current=null)}function Dp(f,d,E){switch(kn(d),d.tag){case N:case fe:case me:case ie:{var C=d.updateQueue;if(C!==null){var R=C.lastEffect;if(R!==null){var j=R.next,V=E>Kn?Kn:E;Sn(V,function(){var oi=j;do{var Mi=oi.destroy;Mi!==void 0&&Pm(d,Mi),oi=oi.next}while(oi!==j)})}}break}case M:{yp(d);var te=d.stateNode;typeof te.componentWillUnmount=="function"&&iv(d,te);return}case q:{if(yi){var le=d.dependencies;if(le!==null){var Be=le.responders;if(Be!==null){for(var Xe=Array.from(Be.values()),ht=0,Lt=Xe.length;ht component higher in the tree to provide a loading indicator or placeholder to display.`+Cr(E))}kp(),C=hp(C,E);var Lt=d;do{switch(Lt.tag){case B:{var Gt=C;Lt.effectTag|=p0,Lt.expirationTime=R;var zt=sv(Lt,Gt,R);ld(Lt,zt);return}case M:var gn=C,kr=Lt.type,oi=Lt.stateNode;if((Lt.effectTag&Xr)===Ai&&(typeof kr.getDerivedStateFromError=="function"||oi!==null&&typeof oi.componentDidCatch=="function"&&!Ip(oi))){Lt.effectTag|=p0,Lt.expirationTime=R;var Mi=av(Lt,gn,R);ld(Lt,Mi);return}break;default:break}Lt=Lt.return}while(Lt!==null)}var Oa=Math.ceil,Mr=rt.ReactCurrentDispatcher,Sp=rt.ReactCurrentOwner,vl=rt.IsSomeRendererActing,yu=0,T1=1,Ui=2,Tp=4,Bd=8,To=16,Os=32,Bf=0,Ud=1,Cp=2,C1=3,x1=4,xp=5,nr=yu,ml=null,Gn=null,q0=ft,k0=Bf,jd=null,Ul=Un,A1=Un,Ac=null,Rc=ft,zd=!1,Ap=0,L0=500,dn=null,Hd=!1,qd=null,Oc=null,Mc=!1,kc=null,R1=E0,Rp=ft,tf=null,Hm=50,Lc=0,Wd=null,cv=50,O1=0,Uf=null,jf=null,M1=ft;function jl(){return(nr&(To|Os))!==yu?n0(mt()):(M1!==ft||(M1=n0(mt())),M1)}function Nc(){return n0(mt())}function zf(f,d,E){var C=d.mode;if((C&Y)===Rr)return Un;var R=Jt();if((C&ri)===Rr)return R===Fi?Un:t0;if((nr&To)!==yu)return q0;var j;if(E!==null)j=ca(f,E.timeoutMs|0||Ef);else switch(R){case Fi:j=Un;break;case ni:j=ja(f);break;case Kn:case e0:j=ws(f);break;case _0:j=ru;break;default:throw Error("Expected a valid priority level")}return ml!==null&&j===q0&&(j-=1),j}function qm(f,d){sg(),dg(f);var E=Vd(f,d);if(E===null){fg(f);return}Hp(f,d),sa();var C=Jt();if(d===Un?(nr&Bd)!==yu&&(nr&(To|Os))===yu?(W(E,d),k1(E)):(Wo(E),W(E,d),nr===yu&&Bt()):(Wo(E),W(E,d)),(nr&Tp)!==yu&&(C===ni||C===Fi))if(tf===null)tf=new Map([[E,d]]);else{var R=tf.get(E);(R===void 0||R>d)&&tf.set(E,d)}}var gl=qm;function Vd(f,d){f.expirationTimeR?C:R}function Wo(f){var d=f.lastExpiredTime;if(d!==ft){f.callbackExpirationTime=Un,f.callbackPriority=Fi,f.callbackNode=Tn(k1.bind(null,f));return}var E=Gd(f),C=f.callbackNode;if(E===ft){C!==null&&(f.callbackNode=null,f.callbackExpirationTime=ft,f.callbackPriority=E0);return}var R=jl(),j=rd(R,E);if(C!==null){var V=f.callbackPriority,te=f.callbackExpirationTime;if(te===E&&V>=j)return;ir(C)}f.callbackExpirationTime=E,f.callbackPriority=j;var le;E===Un?le=Tn(k1.bind(null,f)):ao?le=_n(j,Yd.bind(null,f)):le=_n(j,Yd.bind(null,f),{timeout:jo(E)-mt()}),f.callbackNode=le}function Yd(f,d){if(M1=ft,d){var E=jl();return Vp(f,E),Wo(f),null}var C=Gd(f);if(C!==ft){var R=f.callbackNode;if((nr&(To|Os))!==yu)throw Error("Should not already be working.");if(nf(),(f!==ml||C!==q0)&&(Hf(f,C),ee(f,C)),Gn!==null){var j=nr;nr|=To;var V=mv(f),te=Kd(f);gf(Gn);do try{eg();break}catch(Xe){vv(f,Xe)}while(!0);if(gt(),nr=j,gv(V),bn&&Xd(te),k0===Ud){var le=jd;throw zp(),Hf(f,C),Vf(f,C),Wo(f),le}if(Gn!==null)zp();else{Av();var Be=f.finishedWork=f.current.alternate;f.finishedExpirationTime=C,Wm(f,Be,k0,C)}if(Wo(f),f.callbackNode===R)return Yd.bind(null,f)}}return null}function Wm(f,d,E,C){switch(ml=null,E){case Bf:case Ud:throw Error("Root did not complete. This is a bug in React.");case Cp:{Vp(f,C>ru?ru:C);break}case C1:{Vf(f,C);var R=f.lastSuspendedTime;C===R&&(f.nextKnownPendingLevel=Lp(d)),p();var j=Ul===Un;if(j&&!(Q0&&Wf.current)){var V=Ap+L0-mt();if(V>10){if(zd){var te=f.lastPingedTime;if(te===ft||te>=C){f.lastPingedTime=C,Hf(f,C);break}}var le=Gd(f);if(le!==ft&&le!==C)break;if(R!==ft&&R!==C){f.lastPingedTime=R;break}f.timeoutHandle=Tt(s0.bind(null,f),V);break}}s0(f);break}case x1:{Vf(f,C);var Be=f.lastSuspendedTime;if(C===Be&&(f.nextKnownPendingLevel=Lp(d)),p(),!(Q0&&Wf.current)){if(zd){var Xe=f.lastPingedTime;if(Xe===ft||Xe>=C){f.lastPingedTime=C,Hf(f,C);break}}var ht=Gd(f);if(ht!==ft&&ht!==C)break;if(Be!==ft&&Be!==C){f.lastPingedTime=Be;break}var Lt;if(A1!==Un)Lt=jo(A1)-mt();else if(Ul===Un)Lt=0;else{var Gt=wv(Ul),zt=mt(),gn=jo(C)-zt,kr=zt-Gt;kr<0&&(kr=0),Lt=Up(kr)-kr,gn10){f.timeoutHandle=Tt(s0.bind(null,f),Lt);break}}s0(f);break}case xp:{if(!(Q0&&Wf.current)&&Ul!==Un&&Ac!==null){var oi=jp(Ul,C,Ac);if(oi>10){Vf(f,C),f.timeoutHandle=Tt(s0.bind(null,f),oi);break}}s0(f);break}default:throw Error("Unknown root exit status.")}}function k1(f){var d=f.lastExpiredTime,E=d!==ft?d:Un;if(f.finishedExpirationTime===E)s0(f);else{if((nr&(To|Os))!==yu)throw Error("Should not already be working.");if(nf(),(f!==ml||E!==q0)&&(Hf(f,E),ee(f,E)),Gn!==null){var C=nr;nr|=To;var R=mv(f),j=Kd(f);gf(Gn);do try{Sv();break}catch(te){vv(f,te)}while(!0);if(gt(),nr=C,gv(R),bn&&Xd(j),k0===Ud){var V=jd;throw zp(),Hf(f,E),Vf(f,E),Wo(f),V}if(Gn!==null)throw Error("Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.");Av(),f.finishedWork=f.current.alternate,f.finishedExpirationTime=E,Vm(f,k0,E),Wo(f)}}return null}function Vm(f,d,E){ml=null,(d===C1||d===x1)&&p(),s0(f)}function Gm(f,d){Vp(f,d),Wo(f),(nr&(To|Os))===yu&&Bt()}function dv(){if((nr&(T1|To|Os))!==yu){(nr&To)!==yu&&Qt(!1,"unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering.");return}Km(),nf()}function Ym(f){return Sn(Kn,f)}function pv(f,d,E,C){return Sn(Fi,f.bind(null,d,E,C))}function Km(){if(tf!==null){var f=tf;tf=null,f.forEach(function(d,E){Vp(E,d),Wo(E)}),Bt()}}function Xm(f,d){var E=nr;nr|=T1;try{return f(d)}finally{nr=E,nr===yu&&Bt()}}function Qm(f,d){var E=nr;nr|=Ui;try{return f(d)}finally{nr=E,nr===yu&&Bt()}}function hv(f,d,E,C){var R=nr;nr|=Tp;try{return Sn(ni,f.bind(null,d,E,C))}finally{nr=R,nr===yu&&Bt()}}function Jm(f,d){var E=nr;nr&=~T1,nr|=Bd;try{return f(d)}finally{nr=E,nr===yu&&Bt()}}function Op(f,d){if((nr&(To|Os))!==yu)throw Error("flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.");var E=nr;nr|=T1;try{return Sn(Fi,f.bind(null,d))}finally{nr=E,Bt()}}function Zm(f){var d=nr;nr|=T1;try{Sn(Fi,f)}finally{nr=d,nr===yu&&Bt()}}function Hf(f,d){f.finishedWork=null,f.finishedExpirationTime=ft;var E=f.timeoutHandle;if(E!==nl&&(f.timeoutHandle=nl,co(E)),Gn!==null)for(var C=Gn.return;C!==null;)nv(C),C=C.return;ml=f,Gn=Co(f.current,null,d),q0=d,k0=Bf,jd=null,Ul=Un,A1=Un,Ac=null,Rc=ft,zd=!1,bn&&(jf=null),Rl.discardPendingWarnings(),$s=null}function vv(f,d){do{try{if(gt(),Ed(),it(),Gn===null||Gn.return===null)return k0=Ud,jd=d,null;en&&Gn.mode&ii&&p1(Gn,!0),fv(f,Gn.return,Gn,d,q0),Gn=Tv(Gn)}catch(E){d=E;continue}return}while(!0)}function mv(f){var d=Mr.current;return Mr.current=f1,d===null?f1:d}function gv(f){Mr.current=f}function Kd(f){if(bn){var d=O.__interactionsRef.current;return O.__interactionsRef.current=f.memoizedInteractions,d}return null}function Xd(f){bn&&(O.__interactionsRef.current=f)}function Mp(){Ap=mt()}function yv(f,d){fru&&(Ul=f),d!==null&&fru&&(A1=f,Ac=d)}function Qd(f){f>Rc&&(Rc=f)}function _v(){k0===Bf&&(k0=C1)}function Ev(){(k0===Bf||k0===C1)&&(k0=x1),Rc!==ft&&ml!==null&&(Vf(ml,q0),u_(ml,Rc))}function kp(){k0!==xp&&(k0=Cp)}function Dv(){return k0===Bf}function wv(f){var d=jo(f);return d-Ef}function $m(f,d){var E=jo(f);return E-(d.timeoutMs|0||Ef)}function Sv(){for(;Gn!==null;)Gn=Jd(Gn)}function eg(){for(;Gn!==null&&!Fn();)Gn=Jd(Gn)}function Jd(f){var d=f.alternate;es(f),Et(f);var E;return en&&(f.mode&ii)!==Rr?(W2(f),E=L1(d,f,q0),p1(f,!0)):E=L1(d,f,q0),it(),f.memoizedProps=f.pendingProps,E===null&&(E=Tv(f)),Sp.current=null,E}function Tv(f){Gn=f;do{var d=Gn.alternate,E=Gn.return;if((Gn.effectTag&P0)===Ai){Et(Gn);var C=void 0;if(!en||(Gn.mode&ii)===Rr?C=tv(d,Gn,q0):(W2(Gn),C=tv(d,Gn,q0),p1(Gn,!1)),ei(Gn),it(),tg(Gn),C!==null)return C;if(E!==null&&(E.effectTag&P0)===Ai){E.firstEffect===null&&(E.firstEffect=Gn.firstEffect),Gn.lastEffect!==null&&(E.lastEffect!==null&&(E.lastEffect.nextEffect=Gn.firstEffect),E.lastEffect=Gn.lastEffect);var R=Gn.effectTag;R>su&&(E.lastEffect!==null?E.lastEffect.nextEffect=Gn:E.firstEffect=Gn,E.lastEffect=Gn)}}else{var j=Mm(Gn,q0);if(en&&(Gn.mode&ii)!==Rr){p1(Gn,!1);for(var V=Gn.actualDuration,te=Gn.child;te!==null;)V+=te.actualDuration,te=te.sibling;Gn.actualDuration=V}if(j!==null)return ho(Gn),j.effectTag&=Xl,j;ei(Gn),E!==null&&(E.firstEffect=E.lastEffect=null,E.effectTag|=P0)}var le=Gn.sibling;if(le!==null)return le;Gn=E}while(Gn!==null);return k0===Bf&&(k0=xp),null}function Lp(f){var d=f.expirationTime,E=f.childExpirationTime;return d>E?d:E}function tg(f){if(!(q0!==Di&&f.childExpirationTime===Di)){var d=ft;if(en&&(f.mode&ii)!==Rr){for(var E=f.actualDuration,C=f.selfBaseDuration,R=f.alternate===null||f.child!==f.alternate.child,j=f.child;j!==null;){var V=j.expirationTime,te=j.childExpirationTime;V>d&&(d=V),te>d&&(d=te),R&&(E+=j.actualDuration),C+=j.treeBaseDuration,j=j.sibling}f.actualDuration=E,f.treeBaseDuration=C}else for(var le=f.child;le!==null;){var Be=le.expirationTime,Xe=le.childExpirationTime;Be>d&&(d=Be),Xe>d&&(d=Xe),le=le.sibling}f.childExpirationTime=d}}function s0(f){var d=Jt();return Sn(Fi,Np.bind(null,f,d)),null}function Np(f,d){do nf();while(kc!==null);if(ag(),(nr&(To|Os))!==yu)throw Error("Should not already be working.");var E=f.finishedWork,C=f.finishedExpirationTime;if(E===null)return null;if(f.finishedWork=null,f.finishedExpirationTime=ft,E===f.current)throw Error("Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.");f.callbackNode=null,f.callbackExpirationTime=ft,f.callbackPriority=E0,f.nextKnownPendingLevel=ft,eo();var R=Lp(E);oE(f,C,R),f===ml&&(ml=null,Gn=null,q0=ft);var j;if(E.effectTag>su?E.lastEffect!==null?(E.lastEffect.nextEffect=E,j=E.firstEffect):j=E:j=E.firstEffect,j!==null){var V=nr;nr|=Os;var te=Kd(f);Sp.current=null,xe(),Hn(f.containerInfo),dn=j;do if(pl(null,ng,null),tr()){if(dn===null)throw Error("Should be working on an effect.");var le=Js();qf(dn,le),dn=dn.nextEffect}while(dn!==null);tt(),en&&Lh(),Ye(),dn=j;do if(pl(null,rg,null,f,d),tr()){if(dn===null)throw Error("Should be working on an effect.");var Be=Js();qf(dn,Be),dn=dn.nextEffect}while(dn!==null);Yt(),qr(f.containerInfo),f.current=E,Kt(),dn=j;do if(pl(null,Fp,null,f,C),tr()){if(dn===null)throw Error("Should be working on an effect.");var Xe=Js();qf(dn,Xe),dn=dn.nextEffect}while(dn!==null);pr(),dn=null,ae(),bn&&Xd(te),nr=V}else f.current=E,xe(),tt(),en&&Lh(),Ye(),Yt(),Kt(),pr();to();var ht=Mc;if(Mc)Mc=!1,kc=f,Rp=C,R1=d;else for(dn=j;dn!==null;){var Lt=dn.nextEffect;dn.nextEffect=null,dn=Lt}var Gt=f.firstPendingTime;if(Gt!==ft){if(bn){if(jf!==null){var zt=jf;jf=null;for(var gn=0;gnKn?Kn:R1;return R1=E0,Sn(f,Pp)}}function Pp(){if(kc===null)return!1;var f=kc,d=Rp;if(kc=null,Rp=ft,(nr&(To|Os))!==yu)throw Error("Cannot flush passive effects while already rendering.");var E=nr;nr|=Os;for(var C=Kd(f),R=f.current.firstEffect;R!==null;){{if(Et(R),pl(null,Aa,null,R),tr()){if(R===null)throw Error("Should be working on an effect.");var j=Js();qf(R,j)}it()}var V=R.nextEffect;R.nextEffect=null,R=V}return bn&&(Xd(C),ve(f,d)),nr=E,Bt(),O1=kc===null?0:O1+1,!0}function Ip(f){return Oc!==null&&Oc.has(f)}function bp(f){Oc===null?Oc=new Set([f]):Oc.add(f)}function ig(f){Hd||(Hd=!0,qd=f)}var ug=ig;function Cv(f,d,E){var C=hp(E,d),R=sv(f,C,Un);Ga(f,R);var j=Vd(f,Un);j!==null&&(Wo(j),W(j,Un))}function qf(f,d){if(f.tag===B){Cv(f,f,d);return}for(var E=f.return;E!==null;){if(E.tag===B){Cv(E,f,d);return}else if(E.tag===M){var C=E.type,R=E.stateNode;if(typeof C.getDerivedStateFromError=="function"||typeof R.componentDidCatch=="function"&&!Ip(R)){var j=hp(d,f),V=av(E,j,Un);Ga(E,V);var te=Vd(E,Un);te!==null&&(Wo(te),W(te,Un));return}}E=E.return}}function Bp(f,d,E){var C=f.pingCache;if(C!==null&&C.delete(d),ml===f&&q0===E){k0===x1||k0===C1&&Ul===Un&&mt()-ApHm)throw Lc=0,Wd=null,Error("Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.");O1>cv&&(O1=0,Qt(!1,"Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render."))}function ag(){Rl.flushLegacyContextWarning(),gi&&Rl.flushPendingUnsafeLifecycleWarnings()}function Av(){var f=!0;yf(Uf,f),Uf=null}function zp(){var f=!1;yf(Uf,f),Uf=null}function Hp(f,d){Hr&&ml!==null&&d>q0&&(Uf=f)}var Zd=null;function fg(f){{var d=f.tag;if(d!==B&&d!==M&&d!==N&&d!==fe&&d!==me&&d!==ie)return;var E=qt(f.type)||"ReactComponent";if(Zd!==null){if(Zd.has(E))return;Zd.add(E)}else Zd=new Set([E]);Ve(!1,"Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s",d===M?"the componentWillUnmount method":"a useEffect cleanup function",Cr(f))}}var L1;if(X0){var cg=null;L1=function(f,d,E){var C=r_(cg,d);try{return ap(f,d,E)}catch(j){if(j!==null&&typeof j=="object"&&typeof j.then=="function")throw j;if(gt(),Ed(),nv(d),r_(d,C),en&&d.mode&ii&&W2(d),pl(null,ap,null,f,d,E),tr()){var R=Js();throw R}else throw j}}}else L1=ap;var Rv=!1,Ov=!1;function dg(f){if(f.tag===M)switch(Lr){case"getChildContext":if(Ov)return;Ve(!1,"setState(...): Cannot call setState() inside getChildContext()"),Ov=!0;break;case"render":if(Rv)return;Ve(!1,"Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state."),Rv=!0;break}}var Wf={current:!1};function qp(f){ms===!0&&vl.current===!0&&Wf.current!==!0&&Ve(!1,`It looks like you're using the wrong act() around your test interactions. +Be sure to use the matching version of act() corresponding to your renderer: + +// for react-dom: +import {act} from 'react-dom/test-utils'; +// ... +act(() => ...); + +// for react-test-renderer: +import TestRenderer from 'react-test-renderer'; +const {act} = TestRenderer; +// ... +act(() => ...);%s`,Cr(f))}function Mv(f){ms===!0&&(f.mode&mr)!==Rr&&vl.current===!1&&Wf.current===!1&&Ve(!1,`An update to %s ran an effect, but was not wrapped in act(...). + +When testing, code that causes React state updates should be wrapped into act(...): + +act(() => { + /* fire events that update state */ +}); +/* assert on the output */ + +This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act%s`,qt(f.type),Cr(f))}function pg(f){ms===!0&&nr===yu&&vl.current===!1&&Wf.current===!1&&Ve(!1,`An update to %s inside a test was not wrapped in act(...). + +When testing, code that causes React state updates should be wrapped into act(...): + +act(() => { + /* fire events that update state */ +}); +/* assert on the output */ + +This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act%s`,qt(f.type),Cr(f))}var hg=pg,Wp=!1;function vg(f){Wp===!1&&t.unstable_flushAllWithoutAsserting===void 0&&(f.mode&Y||f.mode&ri?(Wp=!0,Ve(!1,`In Concurrent or Sync modes, the "scheduler" module needs to be mocked to guarantee consistent behaviour across tests and browsers. For example, with jest: +jest.mock('scheduler', () => require('scheduler/unstable_mock')); + +For more info, visit https://fb.me/react-mock-scheduler`)):eu===!0&&(Wp=!0,Ve(!1,`Starting from React v17, the "scheduler" module will need to be mocked to guarantee consistent behaviour across tests and browsers. For example, with jest: +jest.mock('scheduler', () => require('scheduler/unstable_mock')); + +For more info, visit https://fb.me/react-mock-scheduler`)))}var $s=null;function mg(f){{var d=Jt();if((f.mode&ri)!==Ai&&(d===ni||d===Fi))for(var E=f;E!==null;){var C=E.alternate;if(C!==null)switch(E.tag){case M:var R=C.updateQueue;if(R!==null)for(var j=R.firstUpdate;j!==null;){var V=j.priority;if(V===ni||V===Fi){$s===null?$s=new Set([qt(E.type)]):$s.add(qt(E.type));break}j=j.next}break;case N:case fe:case ie:if(E.memoizedState!==null&&E.memoizedState.baseUpdate!==null)for(var te=E.memoizedState.baseUpdate;te!==null;){var le=te.priority;if(le===ni||le===Fi){$s===null?$s=new Set([qt(E.type)]):$s.add(qt(E.type));break}if(te.next===E.memoizedState.baseUpdate)break;te=te.next}break;default:break}E=E.return}}}function p(){if($s!==null){var f=[];$s.forEach(function(d){return f.push(d)}),$s=null,f.length>0&&Ve(!1,`%s triggered a user-blocking update that suspended. + +The fix is to split the update into multiple parts: a user-blocking update to provide immediate feedback, and another update that triggers the bulk of the changes. + +Refer to the documentation for useTransition to learn how to implement this pattern.`,f.sort().join(", "))}}function v(f,d){return d*1e3+f.interactionThreadID}function x(f){!bn||(jf===null?jf=[f]:jf.push(f))}function P(f,d,E){if(!!bn&&E.size>0){var C=f.pendingInteractionMap,R=C.get(d);R!=null?E.forEach(function(te){R.has(te)||te.__count++,R.add(te)}):(C.set(d,new Set(E)),E.forEach(function(te){te.__count++}));var j=O.__subscriberRef.current;if(j!==null){var V=v(f,d);j.onWorkScheduled(E,V)}}}function W(f,d){!bn||P(f,d,O.__interactionsRef.current)}function ee(f,d){if(!!bn){var E=new Set;if(f.pendingInteractionMap.forEach(function(j,V){V>=d&&j.forEach(function(te){return E.add(te)})}),f.memoizedInteractions=E,E.size>0){var C=O.__subscriberRef.current;if(C!==null){var R=v(f,d);try{C.onWorkStarted(E,R)}catch(j){_n(Fi,function(){throw j})}}}}}function ve(f,d){if(!!bn){var E=f.firstPendingTime,C;try{if(C=O.__subscriberRef.current,C!==null&&f.memoizedInteractions.size>0){var R=v(f,d);C.onWorkStopped(f.memoizedInteractions,R)}}catch(V){_n(Fi,function(){throw V})}finally{var j=f.pendingInteractionMap;j.forEach(function(V,te){te>E&&(j.delete(te),V.forEach(function(le){if(le.__count--,C!==null&&le.__count===0)try{C.onInteractionScheduledWorkCompleted(le)}catch(Be){_n(Fi,function(){throw Be})}}))})}}}var Ee=null,Ie=null,_t=!1,St=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!="undefined";function Rt(f){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__=="undefined")return!1;var d=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(d.isDisabled)return!0;if(!d.supportsFiber)return Ve(!1,"The installed version of React DevTools is too old and will not work with the current version of React. Please update React DevTools. https://fb.me/react-devtools"),!0;try{var E=d.inject(f);Ee=function(C,R){try{var j=(C.current.effectTag&Xr)===Xr;if(en){var V=Nc(),te=rd(V,R);d.onCommitFiberRoot(E,C,te,j)}else d.onCommitFiberRoot(E,C,void 0,j)}catch(le){_t||(_t=!0,Ve(!1,"React DevTools encountered an error: %s",le))}},Ie=function(C){try{d.onCommitFiberUnmount(E,C)}catch(R){_t||(_t=!0,Ve(!1,"React DevTools encountered an error: %s",R))}}}catch(C){Ve(!1,"React DevTools encountered an error: %s.",C)}return!0}function on(f,d){typeof Ee=="function"&&Ee(f,d)}function kn(f){typeof Ie=="function"&&Ie(f)}var rr;{rr=!1;try{var br=Object.preventExtensions({}),ar=new Map([[br,null]]),ui=new Set([br]);ar.set(0,0),ui.add(0)}catch(f){rr=!0}}var di=1;function zl(f,d,E,C){this.tag=f,this.key=E,this.elementType=null,this.type=null,this.stateNode=null,this.return=null,this.child=null,this.sibling=null,this.index=0,this.ref=null,this.pendingProps=d,this.memoizedProps=null,this.updateQueue=null,this.memoizedState=null,this.dependencies=null,this.mode=C,this.effectTag=Ai,this.nextEffect=null,this.firstEffect=null,this.lastEffect=null,this.expirationTime=ft,this.childExpirationTime=ft,this.alternate=null,en&&(this.actualDuration=Number.NaN,this.actualStartTime=Number.NaN,this.selfBaseDuration=Number.NaN,this.treeBaseDuration=Number.NaN,this.actualDuration=0,this.actualStartTime=-1,this.selfBaseDuration=0,this.treeBaseDuration=0),Hr&&(this._debugID=di++,this._debugIsCurrentlyTiming=!1),this._debugSource=null,this._debugOwner=null,this._debugNeedsRemount=!1,this._debugHookTypes=null,!rr&&typeof Object.preventExtensions=="function"&&Object.preventExtensions(this)}var Zi=function(f,d,E,C){return new zl(f,d,E,C)};function so(f){var d=f.prototype;return!!(d&&d.isReactComponent)}function a0(f){return typeof f=="function"&&!so(f)&&f.defaultProps===void 0}function Ms(f){if(typeof f=="function")return so(f)?M:N;if(f!=null){var d=f.$$typeof;if(d===Mn)return fe;if(d===Vt)return me}return T}function Co(f,d,E){var C=f.alternate;C===null?(C=Zi(f.tag,d,f.key,f.mode),C.elementType=f.elementType,C.type=f.type,C.stateNode=f.stateNode,C._debugID=f._debugID,C._debugSource=f._debugSource,C._debugOwner=f._debugOwner,C._debugHookTypes=f._debugHookTypes,C.alternate=f,f.alternate=C):(C.pendingProps=d,C.effectTag=Ai,C.nextEffect=null,C.firstEffect=null,C.lastEffect=null,en&&(C.actualDuration=0,C.actualStartTime=-1)),C.childExpirationTime=f.childExpirationTime,C.expirationTime=f.expirationTime,C.child=f.child,C.memoizedProps=f.memoizedProps,C.memoizedState=f.memoizedState,C.updateQueue=f.updateQueue;var R=f.dependencies;switch(C.dependencies=R===null?null:{expirationTime:R.expirationTime,firstContext:R.firstContext,responders:R.responders},C.sibling=f.sibling,C.index=f.index,C.ref=f.ref,en&&(C.selfBaseDuration=f.selfBaseDuration,C.treeBaseDuration=f.treeBaseDuration),C._debugNeedsRemount=f._debugNeedsRemount,C.tag){case T:case N:case ie:C.type=r0(f.type);break;case M:C.type=j0(f.type);break;case fe:C.type=wf(f.type);break;default:break}return C}function kv(f,d){f.effectTag&=mi,f.nextEffect=null,f.firstEffect=null,f.lastEffect=null;var E=f.alternate;if(E===null)f.childExpirationTime=ft,f.expirationTime=d,f.child=null,f.memoizedProps=null,f.memoizedState=null,f.updateQueue=null,f.dependencies=null,en&&(f.selfBaseDuration=0,f.treeBaseDuration=0);else{f.childExpirationTime=E.childExpirationTime,f.expirationTime=E.expirationTime,f.child=E.child,f.memoizedProps=E.memoizedProps,f.memoizedState=E.memoizedState,f.updateQueue=E.updateQueue;var C=E.dependencies;f.dependencies=C===null?null:{expirationTime:C.expirationTime,firstContext:C.firstContext,responders:C.responders},en&&(f.selfBaseDuration=E.selfBaseDuration,f.treeBaseDuration=E.treeBaseDuration)}return f}function J4(f){var d;return f===O0?d=ri|Y|mr:f===B0?d=Y|mr:d=Rr,en&&St&&(d|=ii),Zi(B,null,null,d)}function gg(f,d,E,C,R,j){var V,te=T,le=f;if(typeof f=="function")so(f)?(te=M,le=j0(le)):le=r0(le);else if(typeof f=="string")te=q;else{e:switch(f){case oe:return rf(E.children,R,j,d);case an:te=he,R|=ri|Y|mr;break;case He:te=he,R|=mr;break;case dt:return $4(E,R,j,d);case lr:return eE(E,R,j,d);case ln:return tE(E,R,j,d);default:{if(typeof f=="object"&&f!==null)switch(f.$$typeof){case At:te=se;break e;case nn:te=De;break e;case Mn:te=fe,le=wf(le);break e;case Vt:te=me;break e;case Dr:te=Oe,le=null;break e;case w:if(Wt)return n_(f,E,R,j,d);break;case Xn:if(Ru)return Z4(f,E,R,j,d)}var Be="";{(f===void 0||typeof f=="object"&&f!==null&&Object.keys(f).length===0)&&(Be+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");var Xe=C?qt(C.type):null;Xe&&(Be+=` + +Check the render method of \``+Xe+"`.")}throw Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: "+(f==null?f:typeof f)+"."+Be)}}}return V=Zi(te,E,d,R),V.elementType=f,V.type=le,V.expirationTime=j,V}function yg(f,d,E){var C=null;C=f._owner;var R=f.type,j=f.key,V=f.props,te=gg(R,j,V,C,d,E);return te._debugSource=f._source,te._debugOwner=f._owner,te}function rf(f,d,E,C){var R=Zi(m,f,C,d);return R.expirationTime=E,R}function n_(f,d,E,C,R){var j=Zi(Dt,d,R,E);return j.elementType=f,j.type=f,j.expirationTime=C,j}function Z4(f,d,E,C,R){var j=Zi(Qe,d,R,E);return j.type=f,j.elementType=f,j.expirationTime=C,j}function $4(f,d,E,C){(typeof f.id!="string"||typeof f.onRender!="function")&&Ve(!1,'Profiler must specify an "id" string and "onRender" function as props');var R=Zi(_e,f,C,d|ii);return R.elementType=dt,R.type=dt,R.expirationTime=E,R}function eE(f,d,E,C){var R=Zi(ce,f,C,d);return R.type=lr,R.elementType=lr,R.expirationTime=E,R}function tE(f,d,E,C){var R=Zi(at,f,C,d);return R.type=ln,R.elementType=ln,R.expirationTime=E,R}function _g(f,d,E){var C=Zi(ne,f,null,d);return C.expirationTime=E,C}function nE(){var f=Zi(q,null,null,Rr);return f.elementType="DELETED",f.type="DELETED",f}function rE(f){var d=Zi(je,null,null,Rr);return d.stateNode=f,d}function Eg(f,d,E){var C=f.children!==null?f.children:[],R=Zi(H,C,f.key,d);return R.expirationTime=E,R.stateNode={containerInfo:f.containerInfo,pendingChildren:null,implementation:f.implementation},R}function r_(f,d){return f===null&&(f=Zi(T,null,null,Rr)),f.tag=d.tag,f.key=d.key,f.elementType=d.elementType,f.type=d.type,f.stateNode=d.stateNode,f.return=d.return,f.child=d.child,f.sibling=d.sibling,f.index=d.index,f.ref=d.ref,f.pendingProps=d.pendingProps,f.memoizedProps=d.memoizedProps,f.updateQueue=d.updateQueue,f.memoizedState=d.memoizedState,f.dependencies=d.dependencies,f.mode=d.mode,f.effectTag=d.effectTag,f.nextEffect=d.nextEffect,f.firstEffect=d.firstEffect,f.lastEffect=d.lastEffect,f.expirationTime=d.expirationTime,f.childExpirationTime=d.childExpirationTime,f.alternate=d.alternate,en&&(f.actualDuration=d.actualDuration,f.actualStartTime=d.actualStartTime,f.selfBaseDuration=d.selfBaseDuration,f.treeBaseDuration=d.treeBaseDuration),f._debugID=d._debugID,f._debugSource=d._debugSource,f._debugOwner=d._debugOwner,f._debugIsCurrentlyTiming=d._debugIsCurrentlyTiming,f._debugNeedsRemount=d._debugNeedsRemount,f._debugHookTypes=d._debugHookTypes,f}function iE(f,d,E){this.tag=d,this.current=null,this.containerInfo=f,this.pendingChildren=null,this.pingCache=null,this.finishedExpirationTime=ft,this.finishedWork=null,this.timeoutHandle=nl,this.context=null,this.pendingContext=null,this.hydrate=E,this.callbackNode=null,this.callbackPriority=E0,this.firstPendingTime=ft,this.firstSuspendedTime=ft,this.lastSuspendedTime=ft,this.nextKnownPendingLevel=ft,this.lastPingedTime=ft,this.lastExpiredTime=ft,bn&&(this.interactionThreadID=O.unstable_getThreadID(),this.memoizedInteractions=new Set,this.pendingInteractionMap=new Map),Yi&&(this.hydrationCallbacks=null)}function uE(f,d,E,C){var R=new iE(f,d,E);Yi&&(R.hydrationCallbacks=C);var j=J4(d);return R.current=j,j.stateNode=R,R}function i_(f,d){var E=f.firstSuspendedTime,C=f.lastSuspendedTime;return E!==ft&&E>=d&&C<=d}function Vf(f,d){var E=f.firstSuspendedTime,C=f.lastSuspendedTime;Ed||E===ft)&&(f.lastSuspendedTime=d),d<=f.lastPingedTime&&(f.lastPingedTime=ft),d<=f.lastExpiredTime&&(f.lastExpiredTime=ft)}function u_(f,d){var E=f.firstPendingTime;d>E&&(f.firstPendingTime=d);var C=f.firstSuspendedTime;C!==ft&&(d>=C?f.firstSuspendedTime=f.lastSuspendedTime=f.nextKnownPendingLevel=ft:d>=f.lastSuspendedTime&&(f.lastSuspendedTime=d+1),d>f.nextKnownPendingLevel&&(f.nextKnownPendingLevel=d))}function oE(f,d,E){f.firstPendingTime=E,d<=f.lastSuspendedTime?f.firstSuspendedTime=f.lastSuspendedTime=f.nextKnownPendingLevel=ft:d<=f.firstSuspendedTime&&(f.firstSuspendedTime=d-1),d<=f.lastPingedTime&&(f.lastPingedTime=ft),d<=f.lastExpiredTime&&(f.lastExpiredTime=ft)}function Vp(f,d){var E=f.lastExpiredTime;(E===ft||E>d)&&(f.lastExpiredTime=d)}var lE={debugTool:null},Lv=lE,Dg,wg;Dg=!1,wg={};function sE(f){if(!f)return An;var d=It(f),E=xl(d);if(d.tag===M){var C=d.type;if(Xi(C))return R0(d,C,E)}return E}function Sg(f){var d=It(f);if(d===void 0)throw typeof f.render=="function"?Error("Unable to find node on an unmounted component."):Error("Argument appears to not be a ReactComponent. Keys: "+Object.keys(f));var E=I0(d);return E===null?null:E.stateNode}function aE(f,d){{var E=It(f);if(E===void 0)throw typeof f.render=="function"?Error("Unable to find node on an unmounted component."):Error("Argument appears to not be a ReactComponent. Keys: "+Object.keys(f));var C=I0(E);if(C===null)return null;if(C.mode&mr){var R=qt(E.type)||"Component";wg[R]||(wg[R]=!0,E.mode&mr?Ve(!1,"%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://fb.me/react-strict-mode-find-node%s",d,d,R,Cr(C)):Ve(!1,"%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://fb.me/react-strict-mode-find-node%s",d,d,R,Cr(C)))}return C.stateNode}return Sg(f)}function fE(f,d,E,C){return uE(f,d,E,C)}function o_(f,d,E,C){var R=d.current,j=jl();typeof jest!="undefined"&&(vg(R),qp(R));var V=_o(),te=zf(j,R,V);Lv.debugTool&&(R.alternate===null?Lv.debugTool.onMountContainer(d):f===null?Lv.debugTool.onUnmountContainer(d):Lv.debugTool.onUpdateContainer(d));var le=sE(E);d.context===null?d.context=le:d.pendingContext=le,Lr==="render"&&Rn!==null&&!Dg&&(Dg=!0,Ve(!1,`Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate. + +Check the render method of %s.`,qt(Rn.type)||"Unknown"));var Be=Cu(te,V);return Be.payload={element:f},C=C===void 0?null:C,C!==null&&(typeof C!="function"&&Ve(!1,"render(...): Expected the last optional `callback` argument to be a function. Instead received: %s.",C),Be.callback=C),Ga(R,Be),gl(R,te),te}function cE(f){var d=f.current;if(!d.child)return null;switch(d.child.tag){case q:return No(d.child.stateNode);default:return d.child.stateNode}}function dE(f){switch(f.tag){case B:var d=f.stateNode;d.hydrate&&Gm(d,d.firstPendingTime);break;case ce:Op(function(){return gl(f,Un)});var E=ja(jl());Nv(f,E);break}}function l_(f,d){var E=f.memoizedState;E!==null&&E.dehydrated!==null&&E.retryTime=d.length)return C;var R=d[E],j=Array.isArray(f)?f.slice():a({},f);return j[R]=xg(f[R],d,E+1,C),j},p_=function(f,d,E){return xg(f,d,0,E)};a_=function(f,d,E,C){for(var R=f.memoizedState;R!==null&&d>0;)R=R.next,d--;if(R!==null){var j=p_(R.memoizedState,E,C);R.memoizedState=j,R.baseState=j,f.memoizedProps=a({},f.memoizedProps),gl(f,Un)}},f_=function(f,d,E){f.pendingProps=p_(f.memoizedProps,d,E),f.alternate&&(f.alternate.pendingProps=f.pendingProps),gl(f,Un)},c_=function(f){gl(f,Un)},d_=function(f){Cg=f}}function mE(f){var d=f.findFiberByHostInstance,E=rt.ReactCurrentDispatcher;return Rt(a({},f,{overrideHookState:a_,overrideProps:f_,setSuspenseHandler:d_,scheduleUpdate:c_,currentDispatcherRef:E,findHostInstanceByFiber:function(C){var R=I0(C);return R===null?null:R.stateNode},findFiberByHostInstance:function(C){return d?d(C):null},findHostInstancesForRefresh:od,scheduleRefresh:Ol,scheduleRoot:Cs,setRefreshHandler:Wa,getCurrentFiber:function(){return Rn}}))}var h_=Object.freeze({createContainer:fE,updateContainer:o_,batchedEventUpdates:Qm,batchedUpdates:Xm,unbatchedUpdates:Jm,deferredUpdates:Ym,syncUpdates:pv,discreteUpdates:hv,flushDiscreteUpdates:dv,flushControlled:Zm,flushSync:Op,flushPassiveEffects:nf,IsThisRendererActing:Wf,getPublicRootInstance:cE,attemptSynchronousHydration:dE,attemptUserBlockingHydration:pE,attemptContinuousHydration:Tg,attemptHydrationAtCurrentPriority:hE,findHostInstance:Sg,findHostInstanceWithWarning:aE,findHostInstanceWithNoPortals:vE,shouldSuspend:s_,injectIntoDevTools:mE}),gE=h_.default||h_;Qg.exports=gE;var yE=Qg.exports;return Qg.exports=i,yE})});var hT=Ke((HW,PD)=>{"use strict";process.env.NODE_ENV==="production"?PD.exports=aT():PD.exports=pT()});var mT=Ke((qW,vT)=>{"use strict";var jI={ALIGN_COUNT:8,ALIGN_AUTO:0,ALIGN_FLEX_START:1,ALIGN_CENTER:2,ALIGN_FLEX_END:3,ALIGN_STRETCH:4,ALIGN_BASELINE:5,ALIGN_SPACE_BETWEEN:6,ALIGN_SPACE_AROUND:7,DIMENSION_COUNT:2,DIMENSION_WIDTH:0,DIMENSION_HEIGHT:1,DIRECTION_COUNT:3,DIRECTION_INHERIT:0,DIRECTION_LTR:1,DIRECTION_RTL:2,DISPLAY_COUNT:2,DISPLAY_FLEX:0,DISPLAY_NONE:1,EDGE_COUNT:9,EDGE_LEFT:0,EDGE_TOP:1,EDGE_RIGHT:2,EDGE_BOTTOM:3,EDGE_START:4,EDGE_END:5,EDGE_HORIZONTAL:6,EDGE_VERTICAL:7,EDGE_ALL:8,EXPERIMENTAL_FEATURE_COUNT:1,EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS:0,FLEX_DIRECTION_COUNT:4,FLEX_DIRECTION_COLUMN:0,FLEX_DIRECTION_COLUMN_REVERSE:1,FLEX_DIRECTION_ROW:2,FLEX_DIRECTION_ROW_REVERSE:3,JUSTIFY_COUNT:6,JUSTIFY_FLEX_START:0,JUSTIFY_CENTER:1,JUSTIFY_FLEX_END:2,JUSTIFY_SPACE_BETWEEN:3,JUSTIFY_SPACE_AROUND:4,JUSTIFY_SPACE_EVENLY:5,LOG_LEVEL_COUNT:6,LOG_LEVEL_ERROR:0,LOG_LEVEL_WARN:1,LOG_LEVEL_INFO:2,LOG_LEVEL_DEBUG:3,LOG_LEVEL_VERBOSE:4,LOG_LEVEL_FATAL:5,MEASURE_MODE_COUNT:3,MEASURE_MODE_UNDEFINED:0,MEASURE_MODE_EXACTLY:1,MEASURE_MODE_AT_MOST:2,NODE_TYPE_COUNT:2,NODE_TYPE_DEFAULT:0,NODE_TYPE_TEXT:1,OVERFLOW_COUNT:3,OVERFLOW_VISIBLE:0,OVERFLOW_HIDDEN:1,OVERFLOW_SCROLL:2,POSITION_TYPE_COUNT:2,POSITION_TYPE_RELATIVE:0,POSITION_TYPE_ABSOLUTE:1,PRINT_OPTIONS_COUNT:3,PRINT_OPTIONS_LAYOUT:1,PRINT_OPTIONS_STYLE:2,PRINT_OPTIONS_CHILDREN:4,UNIT_COUNT:4,UNIT_UNDEFINED:0,UNIT_POINT:1,UNIT_PERCENT:2,UNIT_AUTO:3,WRAP_COUNT:3,WRAP_NO_WRAP:0,WRAP_WRAP:1,WRAP_WRAP_REVERSE:2};vT.exports=jI});var ET=Ke((WW,gT)=>{"use strict";var zI=Object.assign||function(i){for(var o=1;o"}}]),i}(),yT=function(){J_(i,null,[{key:"fromJS",value:function(a){var c=a.width,_=a.height;return new i(c,_)}}]);function i(o,a){bD(this,i),this.width=o,this.height=a}return J_(i,[{key:"fromJS",value:function(a){a(this.width,this.height)}},{key:"toString",value:function(){return""}}]),i}(),_T=function(){function i(o,a){bD(this,i),this.unit=o,this.value=a}return J_(i,[{key:"fromJS",value:function(a){a(this.unit,this.value)}},{key:"toString",value:function(){switch(this.unit){case nc.UNIT_POINT:return String(this.value);case nc.UNIT_PERCENT:return this.value+"%";case nc.UNIT_AUTO:return"auto";default:return this.value+"?"}}},{key:"valueOf",value:function(){return this.value}}]),i}();gT.exports=function(i,o){function a(O,N,M){var T=O[N];O[N]=function(){for(var B=arguments.length,H=Array(B),q=0;q1?H-1:0),ne=1;ne1&&arguments[1]!==void 0?arguments[1]:NaN,M=arguments.length>2&&arguments[2]!==void 0?arguments[2]:NaN,T=arguments.length>3&&arguments[3]!==void 0?arguments[3]:nc.DIRECTION_LTR;return O.call(this,N,M,T)}),zI({Config:o.Config,Node:o.Node,Layout:i("Layout",HI),Size:i("Size",yT),Value:i("Value",_T),getInstanceCount:function(){return o.getInstanceCount.apply(o,arguments)}},nc)}});var DT=Ke((exports,module)=>{(function(i,o){typeof define=="function"&&define.amd?define([],function(){return o}):typeof module=="object"&&module.exports?module.exports=o:(i.nbind=i.nbind||{}).init=o})(exports,function(Module,cb){typeof Module=="function"&&(cb=Module,Module={}),Module.onRuntimeInitialized=function(i,o){return function(){i&&i.apply(this,arguments);try{Module.ccall("nbind_init")}catch(a){o(a);return}o(null,{bind:Module._nbind_value,reflect:Module.NBind.reflect,queryType:Module.NBind.queryType,toggleLightGC:Module.toggleLightGC,lib:Module})}}(Module.onRuntimeInitialized,cb);var Module;Module||(Module=(typeof Module!="undefined"?Module:null)||{});var moduleOverrides={};for(var key in Module)Module.hasOwnProperty(key)&&(moduleOverrides[key]=Module[key]);var ENVIRONMENT_IS_WEB=!1,ENVIRONMENT_IS_WORKER=!1,ENVIRONMENT_IS_NODE=!1,ENVIRONMENT_IS_SHELL=!1;if(Module.ENVIRONMENT)if(Module.ENVIRONMENT==="WEB")ENVIRONMENT_IS_WEB=!0;else if(Module.ENVIRONMENT==="WORKER")ENVIRONMENT_IS_WORKER=!0;else if(Module.ENVIRONMENT==="NODE")ENVIRONMENT_IS_NODE=!0;else if(Module.ENVIRONMENT==="SHELL")ENVIRONMENT_IS_SHELL=!0;else throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");else ENVIRONMENT_IS_WEB=typeof window=="object",ENVIRONMENT_IS_WORKER=typeof importScripts=="function",ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof require=="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER,ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){Module.print||(Module.print=console.log),Module.printErr||(Module.printErr=console.warn);var nodeFS,nodePath;Module.read=function(o,a){nodeFS||(nodeFS={}("")),nodePath||(nodePath={}("")),o=nodePath.normalize(o);var c=nodeFS.readFileSync(o);return a?c:c.toString()},Module.readBinary=function(o){var a=Module.read(o,!0);return a.buffer||(a=new Uint8Array(a)),assert(a.buffer),a},Module.load=function(o){globalEval(read(o))},Module.thisProgram||(process.argv.length>1?Module.thisProgram=process.argv[1].replace(/\\/g,"/"):Module.thisProgram="unknown-program"),Module.arguments=process.argv.slice(2),typeof module!="undefined"&&(module.exports=Module),Module.inspect=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL)Module.print||(Module.print=print),typeof printErr!="undefined"&&(Module.printErr=printErr),typeof read!="undefined"?Module.read=read:Module.read=function(){throw"no read() available"},Module.readBinary=function(o){if(typeof readbuffer=="function")return new Uint8Array(readbuffer(o));var a=read(o,"binary");return assert(typeof a=="object"),a},typeof scriptArgs!="undefined"?Module.arguments=scriptArgs:typeof arguments!="undefined"&&(Module.arguments=arguments),typeof quit=="function"&&(Module.quit=function(i,o){quit(i)});else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(Module.read=function(o){var a=new XMLHttpRequest;return a.open("GET",o,!1),a.send(null),a.responseText},ENVIRONMENT_IS_WORKER&&(Module.readBinary=function(o){var a=new XMLHttpRequest;return a.open("GET",o,!1),a.responseType="arraybuffer",a.send(null),new Uint8Array(a.response)}),Module.readAsync=function(o,a,c){var _=new XMLHttpRequest;_.open("GET",o,!0),_.responseType="arraybuffer",_.onload=function(){_.status==200||_.status==0&&_.response?a(_.response):c()},_.onerror=c,_.send(null)},typeof arguments!="undefined"&&(Module.arguments=arguments),typeof console!="undefined")Module.print||(Module.print=function(o){console.log(o)}),Module.printErr||(Module.printErr=function(o){console.warn(o)});else{var TRY_USE_DUMP=!1;Module.print||(Module.print=TRY_USE_DUMP&&typeof dump!="undefined"?function(i){dump(i)}:function(i){})}ENVIRONMENT_IS_WORKER&&(Module.load=importScripts),typeof Module.setWindowTitle=="undefined"&&(Module.setWindowTitle=function(i){document.title=i})}else throw"Unknown runtime environment. Where are we?";function globalEval(i){eval.call(null,i)}!Module.load&&Module.read&&(Module.load=function(o){globalEval(Module.read(o))}),Module.print||(Module.print=function(){}),Module.printErr||(Module.printErr=Module.print),Module.arguments||(Module.arguments=[]),Module.thisProgram||(Module.thisProgram="./this.program"),Module.quit||(Module.quit=function(i,o){throw o}),Module.print=Module.print,Module.printErr=Module.printErr,Module.preRun=[],Module.postRun=[];for(var key in moduleOverrides)moduleOverrides.hasOwnProperty(key)&&(Module[key]=moduleOverrides[key]);moduleOverrides=void 0;var Runtime={setTempRet0:function(i){return tempRet0=i,i},getTempRet0:function(){return tempRet0},stackSave:function(){return STACKTOP},stackRestore:function(i){STACKTOP=i},getNativeTypeSize:function(i){switch(i){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(i[i.length-1]==="*")return Runtime.QUANTUM_SIZE;if(i[0]==="i"){var o=parseInt(i.substr(1));return assert(o%8==0),o/8}else return 0}}},getNativeFieldSize:function(i){return Math.max(Runtime.getNativeTypeSize(i),Runtime.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(i,o){return o==="double"||o==="i64"?i&7&&(assert((i&7)==4),i+=4):assert((i&3)==0),i},getAlignSize:function(i,o,a){return!a&&(i=="i64"||i=="double")?8:i?Math.min(o||(i?Runtime.getNativeFieldSize(i):0),Runtime.QUANTUM_SIZE):Math.min(o,8)},dynCall:function(i,o,a){return a&&a.length?Module["dynCall_"+i].apply(null,[o].concat(a)):Module["dynCall_"+i].call(null,o)},functionPointers:[],addFunction:function(i){for(var o=0;o>2],a=(o+i+15|0)&-16;if(HEAP32[DYNAMICTOP_PTR>>2]=a,a>=TOTAL_MEMORY){var c=enlargeMemory();if(!c)return HEAP32[DYNAMICTOP_PTR>>2]=o,0}return o},alignMemory:function(i,o){var a=i=Math.ceil(i/(o||16))*(o||16);return a},makeBigInt:function(i,o,a){var c=a?+(i>>>0)+ +(o>>>0)*4294967296:+(i>>>0)+ +(o|0)*4294967296;return c},GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module.Runtime=Runtime;var ABORT=0,EXITSTATUS=0;function assert(i,o){i||abort("Assertion failed: "+o)}function getCFunc(ident){var func=Module["_"+ident];if(!func)try{func=eval("_"+ident)}catch(i){}return assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)"),func}var cwrap,ccall;(function(){var JSfuncs={stackSave:function(){Runtime.stackSave()},stackRestore:function(){Runtime.stackRestore()},arrayToC:function(i){var o=Runtime.stackAlloc(i.length);return writeArrayToMemory(i,o),o},stringToC:function(i){var o=0;if(i!=null&&i!==0){var a=(i.length<<2)+1;o=Runtime.stackAlloc(a),stringToUTF8(i,o,a)}return o}},toC={string:JSfuncs.stringToC,array:JSfuncs.arrayToC};ccall=function(o,a,c,_,t){var O=getCFunc(o),N=[],M=0;if(_)for(var T=0;T<_.length;T++){var B=toC[c[T]];B?(M===0&&(M=Runtime.stackSave()),N[T]=B(_[T])):N[T]=_[T]}var H=O.apply(null,N);if(a==="string"&&(H=Pointer_stringify(H)),M!==0){if(t&&t.async){EmterpreterAsync.asyncFinalizers.push(function(){Runtime.stackRestore(M)});return}Runtime.stackRestore(M)}return H};var sourceRegex=/^function\s*[a-zA-Z$_0-9]*\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/;function parseJSFunc(i){var o=i.toString().match(sourceRegex).slice(1);return{arguments:o[0],body:o[1],returnValue:o[2]}}var JSsource=null;function ensureJSsource(){if(!JSsource){JSsource={};for(var i in JSfuncs)JSfuncs.hasOwnProperty(i)&&(JSsource[i]=parseJSFunc(JSfuncs[i]))}}cwrap=function(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident),numericArgs=argTypes.every(function(i){return i==="number"}),numericRet=returnType!=="string";if(numericRet&&numericArgs)return cfunc;var argNames=argTypes.map(function(i,o){return"$"+o}),funcstr="(function("+argNames.join(",")+") {",nargs=argTypes.length;if(!numericArgs){ensureJSsource(),funcstr+="var stack = "+JSsource.stackSave.body+";";for(var i=0;i>0]=o;break;case"i8":HEAP8[i>>0]=o;break;case"i16":HEAP16[i>>1]=o;break;case"i32":HEAP32[i>>2]=o;break;case"i64":tempI64=[o>>>0,(tempDouble=o,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[i>>2]=tempI64[0],HEAP32[i+4>>2]=tempI64[1];break;case"float":HEAPF32[i>>2]=o;break;case"double":HEAPF64[i>>3]=o;break;default:abort("invalid type for setValue: "+a)}}Module.setValue=setValue;function getValue(i,o,a){switch(o=o||"i8",o.charAt(o.length-1)==="*"&&(o="i32"),o){case"i1":return HEAP8[i>>0];case"i8":return HEAP8[i>>0];case"i16":return HEAP16[i>>1];case"i32":return HEAP32[i>>2];case"i64":return HEAP32[i>>2];case"float":return HEAPF32[i>>2];case"double":return HEAPF64[i>>3];default:abort("invalid type for setValue: "+o)}return null}Module.getValue=getValue;var ALLOC_NORMAL=0,ALLOC_STACK=1,ALLOC_STATIC=2,ALLOC_DYNAMIC=3,ALLOC_NONE=4;Module.ALLOC_NORMAL=ALLOC_NORMAL,Module.ALLOC_STACK=ALLOC_STACK,Module.ALLOC_STATIC=ALLOC_STATIC,Module.ALLOC_DYNAMIC=ALLOC_DYNAMIC,Module.ALLOC_NONE=ALLOC_NONE;function allocate(i,o,a,c){var _,t;typeof i=="number"?(_=!0,t=i):(_=!1,t=i.length);var O=typeof o=="string"?o:null,N;if(a==ALLOC_NONE?N=c:N=[typeof _malloc=="function"?_malloc:Runtime.staticAlloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][a===void 0?ALLOC_STATIC:a](Math.max(t,O?1:o.length)),_){var c=N,M;for(assert((N&3)==0),M=N+(t&~3);c>2]=0;for(M=N+t;c>0]=0;return N}if(O==="i8")return i.subarray||i.slice?HEAPU8.set(i,N):HEAPU8.set(new Uint8Array(i),N),N;for(var T=0,B,H,q;T>0],a|=c,!(c==0&&!o||(_++,o&&_==o)););o||(o=_);var t="";if(a<128){for(var O=1024,N;o>0;)N=String.fromCharCode.apply(String,HEAPU8.subarray(i,i+Math.min(o,O))),t=t?t+N:N,i+=O,o-=O;return t}return Module.UTF8ToString(i)}Module.Pointer_stringify=Pointer_stringify;function AsciiToString(i){for(var o="";;){var a=HEAP8[i++>>0];if(!a)return o;o+=String.fromCharCode(a)}}Module.AsciiToString=AsciiToString;function stringToAscii(i,o){return writeAsciiToMemory(i,o,!1)}Module.stringToAscii=stringToAscii;var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):void 0;function UTF8ArrayToString(i,o){for(var a=o;i[a];)++a;if(a-o>16&&i.subarray&&UTF8Decoder)return UTF8Decoder.decode(i.subarray(o,a));for(var c,_,t,O,N,M,T="";;){if(c=i[o++],!c)return T;if(!(c&128)){T+=String.fromCharCode(c);continue}if(_=i[o++]&63,(c&224)==192){T+=String.fromCharCode((c&31)<<6|_);continue}if(t=i[o++]&63,(c&240)==224?c=(c&15)<<12|_<<6|t:(O=i[o++]&63,(c&248)==240?c=(c&7)<<18|_<<12|t<<6|O:(N=i[o++]&63,(c&252)==248?c=(c&3)<<24|_<<18|t<<12|O<<6|N:(M=i[o++]&63,c=(c&1)<<30|_<<24|t<<18|O<<12|N<<6|M))),c<65536)T+=String.fromCharCode(c);else{var B=c-65536;T+=String.fromCharCode(55296|B>>10,56320|B&1023)}}}Module.UTF8ArrayToString=UTF8ArrayToString;function UTF8ToString(i){return UTF8ArrayToString(HEAPU8,i)}Module.UTF8ToString=UTF8ToString;function stringToUTF8Array(i,o,a,c){if(!(c>0))return 0;for(var _=a,t=a+c-1,O=0;O=55296&&N<=57343&&(N=65536+((N&1023)<<10)|i.charCodeAt(++O)&1023),N<=127){if(a>=t)break;o[a++]=N}else if(N<=2047){if(a+1>=t)break;o[a++]=192|N>>6,o[a++]=128|N&63}else if(N<=65535){if(a+2>=t)break;o[a++]=224|N>>12,o[a++]=128|N>>6&63,o[a++]=128|N&63}else if(N<=2097151){if(a+3>=t)break;o[a++]=240|N>>18,o[a++]=128|N>>12&63,o[a++]=128|N>>6&63,o[a++]=128|N&63}else if(N<=67108863){if(a+4>=t)break;o[a++]=248|N>>24,o[a++]=128|N>>18&63,o[a++]=128|N>>12&63,o[a++]=128|N>>6&63,o[a++]=128|N&63}else{if(a+5>=t)break;o[a++]=252|N>>30,o[a++]=128|N>>24&63,o[a++]=128|N>>18&63,o[a++]=128|N>>12&63,o[a++]=128|N>>6&63,o[a++]=128|N&63}}return o[a]=0,a-_}Module.stringToUTF8Array=stringToUTF8Array;function stringToUTF8(i,o,a){return stringToUTF8Array(i,HEAPU8,o,a)}Module.stringToUTF8=stringToUTF8;function lengthBytesUTF8(i){for(var o=0,a=0;a=55296&&c<=57343&&(c=65536+((c&1023)<<10)|i.charCodeAt(++a)&1023),c<=127?++o:c<=2047?o+=2:c<=65535?o+=3:c<=2097151?o+=4:c<=67108863?o+=5:o+=6}return o}Module.lengthBytesUTF8=lengthBytesUTF8;var UTF16Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf-16le"):void 0;function demangle(i){var o=Module.___cxa_demangle||Module.__cxa_demangle;if(o){try{var a=i.substr(1),c=lengthBytesUTF8(a)+1,_=_malloc(c);stringToUTF8(a,_,c);var t=_malloc(4),O=o(_,0,0,t);if(getValue(t,"i32")===0&&O)return Pointer_stringify(O)}catch(N){}finally{_&&_free(_),t&&_free(t),O&&_free(O)}return i}return Runtime.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling"),i}function demangleAll(i){var o=/__Z[\w\d_]+/g;return i.replace(o,function(a){var c=demangle(a);return a===c?a:a+" ["+c+"]"})}function jsStackTrace(){var i=new Error;if(!i.stack){try{throw new Error(0)}catch(o){i=o}if(!i.stack)return"(no stack trace available)"}return i.stack.toString()}function stackTrace(){var i=jsStackTrace();return Module.extraStackTrace&&(i+=` +`+Module.extraStackTrace()),demangleAll(i)}Module.stackTrace=stackTrace;var HEAP,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferViews(){Module.HEAP8=HEAP8=new Int8Array(buffer),Module.HEAP16=HEAP16=new Int16Array(buffer),Module.HEAP32=HEAP32=new Int32Array(buffer),Module.HEAPU8=HEAPU8=new Uint8Array(buffer),Module.HEAPU16=HEAPU16=new Uint16Array(buffer),Module.HEAPU32=HEAPU32=new Uint32Array(buffer),Module.HEAPF32=HEAPF32=new Float32Array(buffer),Module.HEAPF64=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed,STACK_BASE,STACKTOP,STACK_MAX,DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0,staticSealed=!1;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module.TOTAL_STACK||5242880,TOTAL_MEMORY=Module.TOTAL_MEMORY||134217728;TOTAL_MEMORY0;){var o=i.shift();if(typeof o=="function"){o();continue}var a=o.func;typeof a=="number"?o.arg===void 0?Module.dynCall_v(a):Module.dynCall_vi(a,o.arg):a(o.arg===void 0?null:o.arg)}}var __ATPRERUN__=[],__ATINIT__=[],__ATMAIN__=[],__ATEXIT__=[],__ATPOSTRUN__=[],runtimeInitialized=!1,runtimeExited=!1;function preRun(){if(Module.preRun)for(typeof Module.preRun=="function"&&(Module.preRun=[Module.preRun]);Module.preRun.length;)addOnPreRun(Module.preRun.shift());callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){runtimeInitialized||(runtimeInitialized=!0,callRuntimeCallbacks(__ATINIT__))}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__),runtimeExited=!0}function postRun(){if(Module.postRun)for(typeof Module.postRun=="function"&&(Module.postRun=[Module.postRun]);Module.postRun.length;)addOnPostRun(Module.postRun.shift());callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(i){__ATPRERUN__.unshift(i)}Module.addOnPreRun=addOnPreRun;function addOnInit(i){__ATINIT__.unshift(i)}Module.addOnInit=addOnInit;function addOnPreMain(i){__ATMAIN__.unshift(i)}Module.addOnPreMain=addOnPreMain;function addOnExit(i){__ATEXIT__.unshift(i)}Module.addOnExit=addOnExit;function addOnPostRun(i){__ATPOSTRUN__.unshift(i)}Module.addOnPostRun=addOnPostRun;function intArrayFromString(i,o,a){var c=a>0?a:lengthBytesUTF8(i)+1,_=new Array(c),t=stringToUTF8Array(i,_,0,_.length);return o&&(_.length=t),_}Module.intArrayFromString=intArrayFromString;function intArrayToString(i){for(var o=[],a=0;a255&&(c&=255),o.push(String.fromCharCode(c))}return o.join("")}Module.intArrayToString=intArrayToString;function writeStringToMemory(i,o,a){Runtime.warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!");var c,_;a&&(_=o+lengthBytesUTF8(i),c=HEAP8[_]),stringToUTF8(i,o,Infinity),a&&(HEAP8[_]=c)}Module.writeStringToMemory=writeStringToMemory;function writeArrayToMemory(i,o){HEAP8.set(i,o)}Module.writeArrayToMemory=writeArrayToMemory;function writeAsciiToMemory(i,o,a){for(var c=0;c>0]=i.charCodeAt(c);a||(HEAP8[o>>0]=0)}if(Module.writeAsciiToMemory=writeAsciiToMemory,(!Math.imul||Math.imul(4294967295,5)!==-5)&&(Math.imul=function(o,a){var c=o>>>16,_=o&65535,t=a>>>16,O=a&65535;return _*O+(c*O+_*t<<16)|0}),Math.imul=Math.imul,!Math.fround){var froundBuffer=new Float32Array(1);Math.fround=function(i){return froundBuffer[0]=i,froundBuffer[0]}}Math.fround=Math.fround,Math.clz32||(Math.clz32=function(i){i=i>>>0;for(var o=0;o<32;o++)if(i&1<<31-o)return o;return 32}),Math.clz32=Math.clz32,Math.trunc||(Math.trunc=function(i){return i<0?Math.ceil(i):Math.floor(i)}),Math.trunc=Math.trunc;var Math_abs=Math.abs,Math_cos=Math.cos,Math_sin=Math.sin,Math_tan=Math.tan,Math_acos=Math.acos,Math_asin=Math.asin,Math_atan=Math.atan,Math_atan2=Math.atan2,Math_exp=Math.exp,Math_log=Math.log,Math_sqrt=Math.sqrt,Math_ceil=Math.ceil,Math_floor=Math.floor,Math_pow=Math.pow,Math_imul=Math.imul,Math_fround=Math.fround,Math_round=Math.round,Math_min=Math.min,Math_clz32=Math.clz32,Math_trunc=Math.trunc,runDependencies=0,runDependencyWatcher=null,dependenciesFulfilled=null;function getUniqueRunDependency(i){return i}function addRunDependency(i){runDependencies++,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies)}Module.addRunDependency=addRunDependency;function removeRunDependency(i){if(runDependencies--,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies),runDependencies==0&&(runDependencyWatcher!==null&&(clearInterval(runDependencyWatcher),runDependencyWatcher=null),dependenciesFulfilled)){var o=dependenciesFulfilled;dependenciesFulfilled=null,o()}}Module.removeRunDependency=removeRunDependency,Module.preloadedImages={},Module.preloadedAudios={};var ASM_CONSTS=[function(i,o,a,c,_,t,O,N){return _nbind.callbackSignatureList[i].apply(this,arguments)}];function _emscripten_asm_const_iiiiiiii(i,o,a,c,_,t,O,N){return ASM_CONSTS[i](o,a,c,_,t,O,N)}function _emscripten_asm_const_iiiii(i,o,a,c,_){return ASM_CONSTS[i](o,a,c,_)}function _emscripten_asm_const_iiidddddd(i,o,a,c,_,t,O,N,M){return ASM_CONSTS[i](o,a,c,_,t,O,N,M)}function _emscripten_asm_const_iiididi(i,o,a,c,_,t,O){return ASM_CONSTS[i](o,a,c,_,t,O)}function _emscripten_asm_const_iiii(i,o,a,c){return ASM_CONSTS[i](o,a,c)}function _emscripten_asm_const_iiiid(i,o,a,c,_){return ASM_CONSTS[i](o,a,c,_)}function _emscripten_asm_const_iiiiii(i,o,a,c,_,t){return ASM_CONSTS[i](o,a,c,_,t)}STATIC_BASE=Runtime.GLOBAL_BASE,STATICTOP=STATIC_BASE+12800,__ATINIT__.push({func:function(){__GLOBAL__sub_I_Yoga_cpp()}},{func:function(){__GLOBAL__sub_I_nbind_cc()}},{func:function(){__GLOBAL__sub_I_common_cc()}},{func:function(){__GLOBAL__sub_I_Binding_cc()}}),allocate([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,192,127,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,128,191,0,0,128,191,0,0,192,127,0,0,0,0,0,0,0,0,0,0,128,63,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,190,12,0,0,200,12,0,0,208,12,0,0,216,12,0,0,230,12,0,0,242,12,0,0,1,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,192,127,3,0,0,0,180,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,182,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,4,0,0,0,183,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,184,45,0,0,185,45,0,0,181,45,0,0,181,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,148,4,0,0,3,0,0,0,187,45,0,0,164,4,0,0,188,45,0,0,2,0,0,0,189,45,0,0,164,4,0,0,188,45,0,0,185,45,0,0,164,4,0,0,185,45,0,0,164,4,0,0,188,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,6,0,0,0,1,0,0,0,7,0,0,0,183,45,0,0,182,45,0,0,181,45,0,0,190,45,0,0,190,45,0,0,182,45,0,0,182,45,0,0,185,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,185,45,0,0,48,5,0,0,3,0,0,0,56,5,0,0,1,0,0,0,189,45,0,0,185,45,0,0,164,4,0,0,76,5,0,0,2,0,0,0,191,45,0,0,186,45,0,0,182,45,0,0,185,45,0,0,192,45,0,0,185,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,76,5,0,0,76,5,0,0,136,5,0,0,182,45,0,0,181,45,0,0,2,0,0,0,190,45,0,0,136,5,0,0,56,19,0,0,156,5,0,0,2,0,0,0,184,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,9,0,0,0,1,0,0,0,10,0,0,0,204,5,0,0,181,45,0,0,181,45,0,0,2,0,0,0,180,45,0,0,204,5,0,0,2,0,0,0,195,45,0,0,236,5,0,0,97,19,0,0,198,45,0,0,211,45,0,0,212,45,0,0,213,45,0,0,214,45,0,0,215,45,0,0,188,45,0,0,182,45,0,0,216,45,0,0,217,45,0,0,218,45,0,0,219,45,0,0,192,45,0,0,181,45,0,0,0,0,0,0,185,45,0,0,110,19,0,0,186,45,0,0,115,19,0,0,221,45,0,0,120,19,0,0,148,4,0,0,132,19,0,0,96,6,0,0,145,19,0,0,222,45,0,0,164,19,0,0,223,45,0,0,173,19,0,0,0,0,0,0,3,0,0,0,104,6,0,0,1,0,0,0,187,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,12,0,0,0,1,0,0,0,13,0,0,0,185,45,0,0,224,45,0,0,164,6,0,0,188,45,0,0,172,6,0,0,180,6,0,0,2,0,0,0,188,6,0,0,7,0,0,0,224,45,0,0,7,0,0,0,164,6,0,0,1,0,0,0,213,45,0,0,185,45,0,0,224,45,0,0,172,6,0,0,185,45,0,0,224,45,0,0,164,6,0,0,185,45,0,0,224,45,0,0,211,45,0,0,211,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,172,6,0,0,222,45,0,0,211,45,0,0,224,45,0,0,188,45,0,0,222,45,0,0,211,45,0,0,40,7,0,0,188,45,0,0,2,0,0,0,224,45,0,0,185,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,222,45,0,0,224,45,0,0,148,4,0,0,185,45,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,185,45,0,0,164,6,0,0,148,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,148,7,0,0,2,0,0,0,225,45,0,0,183,45,0,0,188,45,0,0,168,7,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,234,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,148,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,9,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,242,45,0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,110,111,100,101,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,119,104,105,99,104,32,115,116,105,108,108,32,104,97,115,32,99,104,105,108,100,114,101,110,32,97,116,116,97,99,104,101,100,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,115,116,105,108,108,32,97,116,116,97,99,104,101,100,32,116,111,32,97,32,112,97,114,101,110,116,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,99,111,110,102,105,103,0,67,97,110,110,111,116,32,115,101,116,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,67,104,105,108,100,32,97,108,114,101,97,100,121,32,104,97,115,32,97,32,112,97,114,101,110,116,44,32,105,116,32,109,117,115,116,32,98,101,32,114,101,109,111,118,101,100,32,102,105,114,115,116,46,0,67,97,110,110,111,116,32,97,100,100,32,99,104,105,108,100,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,79,110,108,121,32,108,101,97,102,32,110,111,100,101,115,32,119,105,116,104,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,115,104,111,117,108,100,32,109,97,110,117,97,108,108,121,32,109,97,114,107,32,116,104,101,109,115,101,108,118,101,115,32,97,115,32,100,105,114,116,121,0,67,97,110,110,111,116,32,103,101,116,32,108,97,121,111,117,116,32,112,114,111,112,101,114,116,105,101,115,32,111,102,32,109,117,108,116,105,45,101,100,103,101,32,115,104,111,114,116,104,97,110,100,115,0,37,115,37,100,46,123,91,115,107,105,112,112,101,100,93,32,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,61,62,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,37,115,37,100,46,123,37,115,0,42,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,37,115,10,0,37,115,37,100,46,125,37,115,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,79,117,116,32,111,102,32,99,97,99,104,101,32,101,110,116,114,105,101,115,33,10,0,83,99,97,108,101,32,102,97,99,116,111,114,32,115,104,111,117,108,100,32,110,111,116,32,98,101,32,108,101,115,115,32,116,104,97,110,32,122,101,114,111,0,105,110,105,116,105,97,108,0,37,115,10,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,85,78,68,69,70,73,78,69,68,0,69,88,65,67,84,76,89,0,65,84,95,77,79,83,84,0,76,65,89,95,85,78,68,69,70,73,78,69,68,0,76,65,89,95,69,88,65,67,84,76,89,0,76,65,89,95,65,84,95,77,79,83,84,0,97,118,97,105,108,97,98,108,101,87,105,100,116,104,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,119,105,100,116,104,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,97,118,97,105,108,97,98,108,101,72,101,105,103,104,116,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,104,101,105,103,104,116,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,102,108,101,120,0,115,116,114,101,116,99,104,0,109,117,108,116,105,108,105,110,101,45,115,116,114,101,116,99,104,0,69,120,112,101,99,116,101,100,32,110,111,100,101,32,116,111,32,104,97,118,101,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,0,109,101,97,115,117,114,101,0,69,120,112,101,99,116,32,99,117,115,116,111,109,32,98,97,115,101,108,105,110,101,32,102,117,110,99,116,105,111,110,32,116,111,32,110,111,116,32,114,101,116,117,114,110,32,78,97,78,0,97,98,115,45,109,101,97,115,117,114,101,0,97,98,115,45,108,97,121,111,117,116,0,78,111,100,101,0,99,114,101,97,116,101,68,101,102,97,117,108,116,0,99,114,101,97,116,101,87,105,116,104,67,111,110,102,105,103,0,100,101,115,116,114,111,121,0,114,101,115,101,116,0,99,111,112,121,83,116,121,108,101,0,115,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,115,101,116,80,111,115,105,116,105,111,110,0,115,101,116,80,111,115,105,116,105,111,110,80,101,114,99,101,110,116,0,115,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,115,101,116,65,108,105,103,110,73,116,101,109,115,0,115,101,116,65,108,105,103,110,83,101,108,102,0,115,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,115,101,116,70,108,101,120,87,114,97,112,0,115,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,115,101,116,77,97,114,103,105,110,0,115,101,116,77,97,114,103,105,110,80,101,114,99,101,110,116,0,115,101,116,77,97,114,103,105,110,65,117,116,111,0,115,101,116,79,118,101,114,102,108,111,119,0,115,101,116,68,105,115,112,108,97,121,0,115,101,116,70,108,101,120,0,115,101,116,70,108,101,120,66,97,115,105,115,0,115,101,116,70,108,101,120,66,97,115,105,115,80,101,114,99,101,110,116,0,115,101,116,70,108,101,120,71,114,111,119,0,115,101,116,70,108,101,120,83,104,114,105,110,107,0,115,101,116,87,105,100,116,104,0,115,101,116,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,87,105,100,116,104,65,117,116,111,0,115,101,116,72,101,105,103,104,116,0,115,101,116,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,72,101,105,103,104,116,65,117,116,111,0,115,101,116,77,105,110,87,105,100,116,104,0,115,101,116,77,105,110,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,105,110,72,101,105,103,104,116,0,115,101,116,77,105,110,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,77,97,120,87,105,100,116,104,0,115,101,116,77,97,120,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,97,120,72,101,105,103,104,116,0,115,101,116,77,97,120,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,65,115,112,101,99,116,82,97,116,105,111,0,115,101,116,66,111,114,100,101,114,0,115,101,116,80,97,100,100,105,110,103,0,115,101,116,80,97,100,100,105,110,103,80,101,114,99,101,110,116,0,103,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,103,101,116,80,111,115,105,116,105,111,110,0,103,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,103,101,116,65,108,105,103,110,73,116,101,109,115,0,103,101,116,65,108,105,103,110,83,101,108,102,0,103,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,103,101,116,70,108,101,120,87,114,97,112,0,103,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,103,101,116,77,97,114,103,105,110,0,103,101,116,70,108,101,120,66,97,115,105,115,0,103,101,116,70,108,101,120,71,114,111,119,0,103,101,116,70,108,101,120,83,104,114,105,110,107,0,103,101,116,87,105,100,116,104,0,103,101,116,72,101,105,103,104,116,0,103,101,116,77,105,110,87,105,100,116,104,0,103,101,116,77,105,110,72,101,105,103,104,116,0,103,101,116,77,97,120,87,105,100,116,104,0,103,101,116,77,97,120,72,101,105,103,104,116,0,103,101,116,65,115,112,101,99,116,82,97,116,105,111,0,103,101,116,66,111,114,100,101,114,0,103,101,116,79,118,101,114,102,108,111,119,0,103,101,116,68,105,115,112,108,97,121,0,103,101,116,80,97,100,100,105,110,103,0,105,110,115,101,114,116,67,104,105,108,100,0,114,101,109,111,118,101,67,104,105,108,100,0,103,101,116,67,104,105,108,100,67,111,117,110,116,0,103,101,116,80,97,114,101,110,116,0,103,101,116,67,104,105,108,100,0,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,117,110,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,109,97,114,107,68,105,114,116,121,0,105,115,68,105,114,116,121,0,99,97,108,99,117,108,97,116,101,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,76,101,102,116,0,103,101,116,67,111,109,112,117,116,101,100,82,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,84,111,112,0,103,101,116,67,111,109,112,117,116,101,100,66,111,116,116,111,109,0,103,101,116,67,111,109,112,117,116,101,100,87,105,100,116,104,0,103,101,116,67,111,109,112,117,116,101,100,72,101,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,77,97,114,103,105,110,0,103,101,116,67,111,109,112,117,116,101,100,66,111,114,100,101,114,0,103,101,116,67,111,109,112,117,116,101,100,80,97,100,100,105,110,103,0,67,111,110,102,105,103,0,99,114,101,97,116,101,0,115,101,116,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,115,101,116,80,111,105,110,116,83,99,97,108,101,70,97,99,116,111,114,0,105,115,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,86,97,108,117,101,0,76,97,121,111,117,116,0,83,105,122,101,0,103,101,116,73,110,115,116,97,110,99,101,67,111,117,110,116,0,73,110,116,54,52,0,1,1,1,2,2,4,4,4,4,8,8,4,8,118,111,105,100,0,98,111,111,108,0,115,116,100,58,58,115,116,114,105,110,103,0,99,98,70,117,110,99,116,105,111,110,32,38,0,99,111,110,115,116,32,99,98,70,117,110,99,116,105,111,110,32,38,0,69,120,116,101,114,110,97,108,0,66,117,102,102,101,114,0,78,66,105,110,100,73,68,0,78,66,105,110,100,0,98,105,110,100,95,118,97,108,117,101,0,114,101,102,108,101,99,116,0,113,117,101,114,121,84,121,112,101,0,108,97,108,108,111,99,0,108,114,101,115,101,116,0,123,114,101,116,117,114,110,40,95,110,98,105,110,100,46,99,97,108,108,98,97,99,107,83,105,103,110,97,116,117,114,101,76,105,115,116,91,36,48,93,46,97,112,112,108,121,40,116,104,105,115,44,97,114,103,117,109,101,110,116,115,41,41,59,125,0,95,110,98,105,110,100,95,110,101,119,0,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,40,110,117,108,108,41,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,105,110,102,0,73,78,70,0,110,97,110,0,78,65,78,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,84,33,34,25,13,1,2,3,17,75,28,12,16,4,11,29,18,30,39,104,110,111,112,113,98,32,5,6,15,19,20,21,26,8,22,7,40,36,23,24,9,10,14,27,31,37,35,131,130,125,38,42,43,60,61,62,63,67,71,74,77,88,89,90,91,92,93,94,95,96,97,99,100,101,102,103,105,106,107,108,114,115,116,121,122,123,124,0,73,108,108,101,103,97,108,32,98,121,116,101,32,115,101,113,117,101,110,99,101,0,68,111,109,97,105,110,32,101,114,114,111,114,0,82,101,115,117,108,116,32,110,111,116,32,114,101,112,114,101,115,101,110,116,97,98,108,101,0,78,111,116,32,97,32,116,116,121,0,80,101,114,109,105,115,115,105,111,110,32,100,101,110,105,101,100,0,79,112,101,114,97,116,105,111,110,32,110,111,116,32,112,101,114,109,105,116,116,101,100,0,78,111,32,115,117,99,104,32,102,105,108,101,32,111,114,32,100,105,114,101,99,116,111,114,121,0,78,111,32,115,117,99,104,32,112,114,111,99,101,115,115,0,70,105,108,101,32,101,120,105,115,116,115,0,86,97,108,117,101,32,116,111,111,32,108,97,114,103,101,32,102,111,114,32,100,97,116,97,32,116,121,112,101,0,78,111,32,115,112,97,99,101,32,108,101,102,116,32,111,110,32,100,101,118,105,99,101,0,79,117,116,32,111,102,32,109,101,109,111,114,121,0,82,101,115,111,117,114,99,101,32,98,117,115,121,0,73,110,116,101,114,114,117,112,116,101,100,32,115,121,115,116,101,109,32,99,97,108,108,0,82,101,115,111,117,114,99,101,32,116,101,109,112,111,114,97,114,105,108,121,32,117,110,97,118,97,105,108,97,98,108,101,0,73,110,118,97,108,105,100,32,115,101,101,107,0,67,114,111,115,115,45,100,101,118,105,99,101,32,108,105,110,107,0,82,101,97,100,45,111,110,108,121,32,102,105,108,101,32,115,121,115,116,101,109,0,68,105,114,101,99,116,111,114,121,32,110,111,116,32,101,109,112,116,121,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,112,101,101,114,0,79,112,101,114,97,116,105,111,110,32,116,105,109,101,100,32,111,117,116,0,67,111,110,110,101,99,116,105,111,110,32,114,101,102,117,115,101,100,0,72,111,115,116,32,105,115,32,100,111,119,110,0,72,111,115,116,32,105,115,32,117,110,114,101,97,99,104,97,98,108,101,0,65,100,100,114,101,115,115,32,105,110,32,117,115,101,0,66,114,111,107,101,110,32,112,105,112,101,0,73,47,79,32,101,114,114,111,114,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,32,111,114,32,97,100,100,114,101,115,115,0,66,108,111,99,107,32,100,101,118,105,99,101,32,114,101,113,117,105,114,101,100,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,0,78,111,116,32,97,32,100,105,114,101,99,116,111,114,121,0,73,115,32,97,32,100,105,114,101,99,116,111,114,121,0,84,101,120,116,32,102,105,108,101,32,98,117,115,121,0,69,120,101,99,32,102,111,114,109,97,116,32,101,114,114,111,114,0,73,110,118,97,108,105,100,32,97,114,103,117,109,101,110,116,0,65,114,103,117,109,101,110,116,32,108,105,115,116,32,116,111,111,32,108,111,110,103,0,83,121,109,98,111,108,105,99,32,108,105,110,107,32,108,111,111,112,0,70,105,108,101,110,97,109,101,32,116,111,111,32,108,111,110,103,0,84,111,111,32,109,97,110,121,32,111,112,101,110,32,102,105,108,101,115,32,105,110,32,115,121,115,116,101,109,0,78,111,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,115,32,97,118,97,105,108,97,98,108,101,0,66,97,100,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,0,78,111,32,99,104,105,108,100,32,112,114,111,99,101,115,115,0,66,97,100,32,97,100,100,114,101,115,115,0,70,105,108,101,32,116,111,111,32,108,97,114,103,101,0,84,111,111,32,109,97,110,121,32,108,105,110,107,115,0,78,111,32,108,111,99,107,115,32,97,118,97,105,108,97,98,108,101,0,82,101,115,111,117,114,99,101,32,100,101,97,100,108,111,99,107,32,119,111,117,108,100,32,111,99,99,117,114,0,83,116,97,116,101,32,110,111,116,32,114,101,99,111,118,101,114,97,98,108,101,0,80,114,101,118,105,111,117,115,32,111,119,110,101,114,32,100,105,101,100,0,79,112,101,114,97,116,105,111,110,32,99,97,110,99,101,108,101,100,0,70,117,110,99,116,105,111,110,32,110,111,116,32,105,109,112,108,101,109,101,110,116,101,100,0,78,111,32,109,101,115,115,97,103,101,32,111,102,32,100,101,115,105,114,101,100,32,116,121,112,101,0,73,100,101,110,116,105,102,105,101,114,32,114,101,109,111,118,101,100,0,68,101,118,105,99,101,32,110,111,116,32,97,32,115,116,114,101,97,109,0,78,111,32,100,97,116,97,32,97,118,97,105,108,97,98,108,101,0,68,101,118,105,99,101,32,116,105,109,101,111,117,116,0,79,117,116,32,111,102,32,115,116,114,101,97,109,115,32,114,101,115,111,117,114,99,101,115,0,76,105,110,107,32,104,97,115,32,98,101,101,110,32,115,101,118,101,114,101,100,0,80,114,111,116,111,99,111,108,32,101,114,114,111,114,0,66,97,100,32,109,101,115,115,97,103,101,0,70,105,108,101,32,100,101,115,99,114,105,112,116,111,114,32,105,110,32,98,97,100,32,115,116,97,116,101,0,78,111,116,32,97,32,115,111,99,107,101,116,0,68,101,115,116,105,110,97,116,105,111,110,32,97,100,100,114,101,115,115,32,114,101,113,117,105,114,101,100,0,77,101,115,115,97,103,101,32,116,111,111,32,108,97,114,103,101,0,80,114,111,116,111,99,111,108,32,119,114,111,110,103,32,116,121,112,101,32,102,111,114,32,115,111,99,107,101,116,0,80,114,111,116,111,99,111,108,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,80,114,111,116,111,99,111,108,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,83,111,99,107,101,116,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,78,111,116,32,115,117,112,112,111,114,116,101,100,0,80,114,111,116,111,99,111,108,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,65,100,100,114,101,115,115,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,112,114,111,116,111,99,111,108,0,65,100,100,114,101,115,115,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,78,101,116,119,111,114,107,32,105,115,32,100,111,119,110,0,78,101,116,119,111,114,107,32,117,110,114,101,97,99,104,97,98,108,101,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,110,101,116,119,111,114,107,0,67,111,110,110,101,99,116,105,111,110,32,97,98,111,114,116,101,100,0,78,111,32,98,117,102,102,101,114,32,115,112,97,99,101,32,97,118,97,105,108,97,98,108,101,0,83,111,99,107,101,116,32,105,115,32,99,111,110,110,101,99,116,101,100,0,83,111,99,107,101,116,32,110,111,116,32,99,111,110,110,101,99,116,101,100,0,67,97,110,110,111,116,32,115,101,110,100,32,97,102,116,101,114,32,115,111,99,107,101,116,32,115,104,117,116,100,111,119,110,0,79,112,101,114,97,116,105,111,110,32,97,108,114,101,97,100,121,32,105,110,32,112,114,111,103,114,101,115,115,0,79,112,101,114,97,116,105,111,110,32,105,110,32,112,114,111,103,114,101,115,115,0,83,116,97,108,101,32,102,105,108,101,32,104,97,110,100,108,101,0,82,101,109,111,116,101,32,73,47,79,32,101,114,114,111,114,0,81,117,111,116,97,32,101,120,99,101,101,100,101,100,0,78,111,32,109,101,100,105,117,109,32,102,111,117,110,100,0,87,114,111,110,103,32,109,101,100,105,117,109,32,116,121,112,101,0,78,111,32,101,114,114,111,114,32,105,110,102,111,114,109,97,116,105,111,110,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=STATICTOP;STATICTOP+=16;function _atexit(i,o){__ATEXIT__.unshift({func:i,arg:o})}function ___cxa_atexit(){return _atexit.apply(null,arguments)}function _abort(){Module.abort()}function __ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj(){Module.printErr("missing function: _ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj"),abort(-1)}function __decorate(i,o,a,c){var _=arguments.length,t=_<3?o:c===null?c=Object.getOwnPropertyDescriptor(o,a):c,O;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")t=Reflect.decorate(i,o,a,c);else for(var N=i.length-1;N>=0;N--)(O=i[N])&&(t=(_<3?O(t):_>3?O(o,a,t):O(o,a))||t);return _>3&&t&&Object.defineProperty(o,a,t),t}function _defineHidden(i){return function(o,a){Object.defineProperty(o,a,{configurable:!1,enumerable:!1,value:i,writable:!0})}}var _nbind={};function __nbind_free_external(i){_nbind.externalList[i].dereference(i)}function __nbind_reference_external(i){_nbind.externalList[i].reference()}function _llvm_stackrestore(i){var o=_llvm_stacksave,a=o.LLVM_SAVEDSTACKS[i];o.LLVM_SAVEDSTACKS.splice(i,1),Runtime.stackRestore(a)}function __nbind_register_pool(i,o,a,c){_nbind.Pool.pageSize=i,_nbind.Pool.usedPtr=o/4,_nbind.Pool.rootPtr=a,_nbind.Pool.pagePtr=c/4,HEAP32[o/4]=16909060,HEAP8[o]==1&&(_nbind.bigEndian=!0),HEAP32[o/4]=0,_nbind.makeTypeKindTbl=(t={},t[1024]=_nbind.PrimitiveType,t[64]=_nbind.Int64Type,t[2048]=_nbind.BindClass,t[3072]=_nbind.BindClassPtr,t[4096]=_nbind.SharedClassPtr,t[5120]=_nbind.ArrayType,t[6144]=_nbind.ArrayType,t[7168]=_nbind.CStringType,t[9216]=_nbind.CallbackType,t[10240]=_nbind.BindType,t),_nbind.makeTypeNameTbl={Buffer:_nbind.BufferType,External:_nbind.ExternalType,Int64:_nbind.Int64Type,_nbind_new:_nbind.CreateValueType,bool:_nbind.BooleanType,"cbFunction &":_nbind.CallbackType,"const cbFunction &":_nbind.CallbackType,"const std::string &":_nbind.StringType,"std::string":_nbind.StringType},Module.toggleLightGC=_nbind.toggleLightGC,_nbind.callUpcast=Module.dynCall_ii;var _=_nbind.makeType(_nbind.constructType,{flags:2048,id:0,name:""});_.proto=Module,_nbind.BindClass.list.push(_);var t}function _emscripten_set_main_loop_timing(i,o){if(Browser.mainLoop.timingMode=i,Browser.mainLoop.timingValue=o,!Browser.mainLoop.func)return 1;if(i==0)Browser.mainLoop.scheduler=function(){var O=Math.max(0,Browser.mainLoop.tickStartTime+o-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,O)},Browser.mainLoop.method="timeout";else if(i==1)Browser.mainLoop.scheduler=function(){Browser.requestAnimationFrame(Browser.mainLoop.runner)},Browser.mainLoop.method="rAF";else if(i==2){if(!window.setImmediate){let t=function(O){O.source===window&&O.data===c&&(O.stopPropagation(),a.shift()())};var _=t,a=[],c="setimmediate";window.addEventListener("message",t,!0),window.setImmediate=function(N){a.push(N),ENVIRONMENT_IS_WORKER?(Module.setImmediates===void 0&&(Module.setImmediates=[]),Module.setImmediates.push(N),window.postMessage({target:c})):window.postMessage(c,"*")}}Browser.mainLoop.scheduler=function(){window.setImmediate(Browser.mainLoop.runner)},Browser.mainLoop.method="immediate"}return 0}function _emscripten_get_now(){abort()}function _emscripten_set_main_loop(i,o,a,c,_){Module.noExitRuntime=!0,assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters."),Browser.mainLoop.func=i,Browser.mainLoop.arg=c;var t;typeof c!="undefined"?t=function(){Module.dynCall_vi(i,c)}:t=function(){Module.dynCall_v(i)};var O=Browser.mainLoop.currentlyRunningMainloop;if(Browser.mainLoop.runner=function(){if(!ABORT){if(Browser.mainLoop.queue.length>0){var M=Date.now(),T=Browser.mainLoop.queue.shift();if(T.func(T.arg),Browser.mainLoop.remainingBlockers){var B=Browser.mainLoop.remainingBlockers,H=B%1==0?B-1:Math.floor(B);T.counted?Browser.mainLoop.remainingBlockers=H:(H=H+.5,Browser.mainLoop.remainingBlockers=(8*B+H)/9)}if(console.log('main loop blocker "'+T.name+'" took '+(Date.now()-M)+" ms"),Browser.mainLoop.updateStatus(),O1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}else Browser.mainLoop.timingMode==0&&(Browser.mainLoop.tickStartTime=_emscripten_get_now());Browser.mainLoop.method==="timeout"&&Module.ctx&&(Module.printErr("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!"),Browser.mainLoop.method=""),Browser.mainLoop.runIter(t),!(O0?_emscripten_set_main_loop_timing(0,1e3/o):_emscripten_set_main_loop_timing(1,1),Browser.mainLoop.scheduler()),a)throw"SimulateInfiniteLoop"}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function(){Browser.mainLoop.scheduler=null,Browser.mainLoop.currentlyRunningMainloop++},resume:function(){Browser.mainLoop.currentlyRunningMainloop++;var i=Browser.mainLoop.timingMode,o=Browser.mainLoop.timingValue,a=Browser.mainLoop.func;Browser.mainLoop.func=null,_emscripten_set_main_loop(a,0,!1,Browser.mainLoop.arg,!0),_emscripten_set_main_loop_timing(i,o),Browser.mainLoop.scheduler()},updateStatus:function(){if(Module.setStatus){var i=Module.statusMessage||"Please wait...",o=Browser.mainLoop.remainingBlockers,a=Browser.mainLoop.expectedBlockers;o?o=6;){var je=ie>>Oe-6&63;Oe-=6,me+=_e[je]}return Oe==2?(me+=_e[(ie&3)<<4],me+=ce+ce):Oe==4&&(me+=_e[(ie&15)<<2],me+=ce),me}m.src="data:audio/x-"+O.substr(-3)+";base64,"+se(t),B(m)},m.src=ne,Browser.safeSetTimeout(function(){B(m)},1e4)}else return H()},Module.preloadPlugins.push(o);function a(){Browser.pointerLock=document.pointerLockElement===Module.canvas||document.mozPointerLockElement===Module.canvas||document.webkitPointerLockElement===Module.canvas||document.msPointerLockElement===Module.canvas}var c=Module.canvas;c&&(c.requestPointerLock=c.requestPointerLock||c.mozRequestPointerLock||c.webkitRequestPointerLock||c.msRequestPointerLock||function(){},c.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||function(){},c.exitPointerLock=c.exitPointerLock.bind(document),document.addEventListener("pointerlockchange",a,!1),document.addEventListener("mozpointerlockchange",a,!1),document.addEventListener("webkitpointerlockchange",a,!1),document.addEventListener("mspointerlockchange",a,!1),Module.elementPointerLock&&c.addEventListener("click",function(_){!Browser.pointerLock&&Module.canvas.requestPointerLock&&(Module.canvas.requestPointerLock(),_.preventDefault())},!1))},createContext:function(i,o,a,c){if(o&&Module.ctx&&i==Module.canvas)return Module.ctx;var _,t;if(o){var O={antialias:!1,alpha:!1};if(c)for(var N in c)O[N]=c[N];t=GL.createContext(i,O),t&&(_=GL.getContext(t).GLctx)}else _=i.getContext("2d");return _?(a&&(o||assert(typeof GLctx=="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it"),Module.ctx=_,o&&GL.makeContextCurrent(t),Module.useWebGL=o,Browser.moduleContextCreatedCallbacks.forEach(function(M){M()}),Browser.init()),_):null},destroyContext:function(i,o,a){},fullscreenHandlersInstalled:!1,lockPointer:void 0,resizeCanvas:void 0,requestFullscreen:function(i,o,a){Browser.lockPointer=i,Browser.resizeCanvas=o,Browser.vrDevice=a,typeof Browser.lockPointer=="undefined"&&(Browser.lockPointer=!0),typeof Browser.resizeCanvas=="undefined"&&(Browser.resizeCanvas=!1),typeof Browser.vrDevice=="undefined"&&(Browser.vrDevice=null);var c=Module.canvas;function _(){Browser.isFullscreen=!1;var O=c.parentNode;(document.fullscreenElement||document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement||document.webkitCurrentFullScreenElement)===O?(c.exitFullscreen=document.exitFullscreen||document.cancelFullScreen||document.mozCancelFullScreen||document.msExitFullscreen||document.webkitCancelFullScreen||function(){},c.exitFullscreen=c.exitFullscreen.bind(document),Browser.lockPointer&&c.requestPointerLock(),Browser.isFullscreen=!0,Browser.resizeCanvas&&Browser.setFullscreenCanvasSize()):(O.parentNode.insertBefore(c,O),O.parentNode.removeChild(O),Browser.resizeCanvas&&Browser.setWindowedCanvasSize()),Module.onFullScreen&&Module.onFullScreen(Browser.isFullscreen),Module.onFullscreen&&Module.onFullscreen(Browser.isFullscreen),Browser.updateCanvasDimensions(c)}Browser.fullscreenHandlersInstalled||(Browser.fullscreenHandlersInstalled=!0,document.addEventListener("fullscreenchange",_,!1),document.addEventListener("mozfullscreenchange",_,!1),document.addEventListener("webkitfullscreenchange",_,!1),document.addEventListener("MSFullscreenChange",_,!1));var t=document.createElement("div");c.parentNode.insertBefore(t,c),t.appendChild(c),t.requestFullscreen=t.requestFullscreen||t.mozRequestFullScreen||t.msRequestFullscreen||(t.webkitRequestFullscreen?function(){t.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}:null)||(t.webkitRequestFullScreen?function(){t.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:null),a?t.requestFullscreen({vrDisplay:a}):t.requestFullscreen()},requestFullScreen:function(i,o,a){return Module.printErr("Browser.requestFullScreen() is deprecated. Please call Browser.requestFullscreen instead."),Browser.requestFullScreen=function(c,_,t){return Browser.requestFullscreen(c,_,t)},Browser.requestFullscreen(i,o,a)},nextRAF:0,fakeRequestAnimationFrame:function(i){var o=Date.now();if(Browser.nextRAF===0)Browser.nextRAF=o+1e3/60;else for(;o+2>=Browser.nextRAF;)Browser.nextRAF+=1e3/60;var a=Math.max(Browser.nextRAF-o,0);setTimeout(i,a)},requestAnimationFrame:function(o){typeof window=="undefined"?Browser.fakeRequestAnimationFrame(o):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||Browser.fakeRequestAnimationFrame),window.requestAnimationFrame(o))},safeCallback:function(i){return function(){if(!ABORT)return i.apply(null,arguments)}},allowAsyncCallbacks:!0,queuedAsyncCallbacks:[],pauseAsyncCallbacks:function(){Browser.allowAsyncCallbacks=!1},resumeAsyncCallbacks:function(){if(Browser.allowAsyncCallbacks=!0,Browser.queuedAsyncCallbacks.length>0){var i=Browser.queuedAsyncCallbacks;Browser.queuedAsyncCallbacks=[],i.forEach(function(o){o()})}},safeRequestAnimationFrame:function(i){return Browser.requestAnimationFrame(function(){ABORT||(Browser.allowAsyncCallbacks?i():Browser.queuedAsyncCallbacks.push(i))})},safeSetTimeout:function(i,o){return Module.noExitRuntime=!0,setTimeout(function(){ABORT||(Browser.allowAsyncCallbacks?i():Browser.queuedAsyncCallbacks.push(i))},o)},safeSetInterval:function(i,o){return Module.noExitRuntime=!0,setInterval(function(){ABORT||Browser.allowAsyncCallbacks&&i()},o)},getMimetype:function(i){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[i.substr(i.lastIndexOf(".")+1)]},getUserMedia:function(i){window.getUserMedia||(window.getUserMedia=navigator.getUserMedia||navigator.mozGetUserMedia),window.getUserMedia(i)},getMovementX:function(i){return i.movementX||i.mozMovementX||i.webkitMovementX||0},getMovementY:function(i){return i.movementY||i.mozMovementY||i.webkitMovementY||0},getMouseWheelDelta:function(i){var o=0;switch(i.type){case"DOMMouseScroll":o=i.detail;break;case"mousewheel":o=i.wheelDelta;break;case"wheel":o=i.deltaY;break;default:throw"unrecognized mouse wheel event: "+i.type}return o},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(i){if(Browser.pointerLock)i.type!="mousemove"&&"mozMovementX"in i?Browser.mouseMovementX=Browser.mouseMovementY=0:(Browser.mouseMovementX=Browser.getMovementX(i),Browser.mouseMovementY=Browser.getMovementY(i)),typeof SDL!="undefined"?(Browser.mouseX=SDL.mouseX+Browser.mouseMovementX,Browser.mouseY=SDL.mouseY+Browser.mouseMovementY):(Browser.mouseX+=Browser.mouseMovementX,Browser.mouseY+=Browser.mouseMovementY);else{var o=Module.canvas.getBoundingClientRect(),a=Module.canvas.width,c=Module.canvas.height,_=typeof window.scrollX!="undefined"?window.scrollX:window.pageXOffset,t=typeof window.scrollY!="undefined"?window.scrollY:window.pageYOffset;if(i.type==="touchstart"||i.type==="touchend"||i.type==="touchmove"){var O=i.touch;if(O===void 0)return;var N=O.pageX-(_+o.left),M=O.pageY-(t+o.top);N=N*(a/o.width),M=M*(c/o.height);var T={x:N,y:M};if(i.type==="touchstart")Browser.lastTouches[O.identifier]=T,Browser.touches[O.identifier]=T;else if(i.type==="touchend"||i.type==="touchmove"){var B=Browser.touches[O.identifier];B||(B=T),Browser.lastTouches[O.identifier]=B,Browser.touches[O.identifier]=T}return}var H=i.pageX-(_+o.left),q=i.pageY-(t+o.top);H=H*(a/o.width),q=q*(c/o.height),Browser.mouseMovementX=H-Browser.mouseX,Browser.mouseMovementY=q-Browser.mouseY,Browser.mouseX=H,Browser.mouseY=q}},asyncLoad:function(i,o,a,c){var _=c?"":getUniqueRunDependency("al "+i);Module.readAsync(i,function(t){assert(t,'Loading data file "'+i+'" failed (no arrayBuffer).'),o(new Uint8Array(t)),_&&removeRunDependency(_)},function(t){if(a)a();else throw'Loading data file "'+i+'" failed.'}),_&&addRunDependency(_)},resizeListeners:[],updateResizeListeners:function(){var i=Module.canvas;Browser.resizeListeners.forEach(function(o){o(i.width,i.height)})},setCanvasSize:function(i,o,a){var c=Module.canvas;Browser.updateCanvasDimensions(c,i,o),a||Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function(){if(typeof SDL!="undefined"){var i=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];i=i|8388608,HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=i}Browser.updateResizeListeners()},setWindowedCanvasSize:function(){if(typeof SDL!="undefined"){var i=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];i=i&~8388608,HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=i}Browser.updateResizeListeners()},updateCanvasDimensions:function(i,o,a){o&&a?(i.widthNative=o,i.heightNative=a):(o=i.widthNative,a=i.heightNative);var c=o,_=a;if(Module.forcedAspectRatio&&Module.forcedAspectRatio>0&&(c/_>2];return o},getStr:function(){var i=Pointer_stringify(SYSCALLS.get());return i},get64:function(){var i=SYSCALLS.get(),o=SYSCALLS.get();return i>=0?assert(o===0):assert(o===-1),i},getZero:function(){assert(SYSCALLS.get()===0)}};function ___syscall6(i,o){SYSCALLS.varargs=o;try{var a=SYSCALLS.getStreamFromFD();return FS.close(a),0}catch(c){return(typeof FS=="undefined"||!(c instanceof FS.ErrnoError))&&abort(c),-c.errno}}function ___syscall54(i,o){SYSCALLS.varargs=o;try{return 0}catch(a){return(typeof FS=="undefined"||!(a instanceof FS.ErrnoError))&&abort(a),-a.errno}}function _typeModule(i){var o=[[0,1,"X"],[1,1,"const X"],[128,1,"X *"],[256,1,"X &"],[384,1,"X &&"],[512,1,"std::shared_ptr"],[640,1,"std::unique_ptr"],[5120,1,"std::vector"],[6144,2,"std::array"],[9216,-1,"std::function"]];function a(M,T,B,H,q,ne){if(T==1){var m=H&896;(m==128||m==256||m==384)&&(M="X const")}var he;return ne?he=B.replace("X",M).replace("Y",q):he=M.replace("X",B).replace("Y",q),he.replace(/([*&]) (?=[*&])/g,"$1")}function c(M,T,B,H,q){throw new Error(M+" type "+B.replace("X",T+"?")+(H?" with flag "+H:"")+" in "+q)}function _(M,T,B,H,q,ne,m,he){ne===void 0&&(ne="X"),he===void 0&&(he=1);var De=B(M);if(De)return De;var se=H(M),fe=se.placeholderFlag,_e=o[fe];m&&_e&&(ne=a(m[2],m[0],ne,_e[0],"?",!0));var ce;fe==0&&(ce="Unbound"),fe>=10&&(ce="Corrupt"),he>20&&(ce="Deeply nested"),ce&&c(ce,M,ne,fe,q||"?");var me=se.paramList[0],ie=_(me,T,B,H,q,ne,_e,he+1),Oe,Ue={flags:_e[0],id:M,name:"",paramList:[ie]},je=[],at="?";switch(se.placeholderFlag){case 1:Oe=ie.spec;break;case 2:if((ie.flags&15360)==1024&&ie.spec.ptrSize==1){Ue.flags=7168;break}case 3:case 6:case 5:Oe=ie.spec,(ie.flags&15360)!=2048;break;case 8:at=""+se.paramList[1],Ue.paramList.push(se.paramList[1]);break;case 9:for(var Dt=0,Qe=se.paramList[1];Dt>2]=i),i}function _llvm_stacksave(){var i=_llvm_stacksave;return i.LLVM_SAVEDSTACKS||(i.LLVM_SAVEDSTACKS=[]),i.LLVM_SAVEDSTACKS.push(Runtime.stackSave()),i.LLVM_SAVEDSTACKS.length-1}function ___syscall140(i,o){SYSCALLS.varargs=o;try{var a=SYSCALLS.getStreamFromFD(),c=SYSCALLS.get(),_=SYSCALLS.get(),t=SYSCALLS.get(),O=SYSCALLS.get(),N=_;return FS.llseek(a,N,O),HEAP32[t>>2]=a.position,a.getdents&&N===0&&O===0&&(a.getdents=null),0}catch(M){return(typeof FS=="undefined"||!(M instanceof FS.ErrnoError))&&abort(M),-M.errno}}function ___syscall146(i,o){SYSCALLS.varargs=o;try{var a=SYSCALLS.get(),c=SYSCALLS.get(),_=SYSCALLS.get(),t=0;___syscall146.buffer||(___syscall146.buffers=[null,[],[]],___syscall146.printChar=function(B,H){var q=___syscall146.buffers[B];assert(q),H===0||H===10?((B===1?Module.print:Module.printErr)(UTF8ArrayToString(q,0)),q.length=0):q.push(H)});for(var O=0;O<_;O++){for(var N=HEAP32[c+O*8>>2],M=HEAP32[c+(O*8+4)>>2],T=0;Ti.pageSize/2||o>i.pageSize-a){var c=_nbind.typeNameTbl.NBind.proto;return c.lalloc(o)}else return HEAPU32[i.usedPtr]=a+o,i.rootPtr+a},i.lreset=function(o,a){var c=HEAPU32[i.pagePtr];if(c){var _=_nbind.typeNameTbl.NBind.proto;_.lreset(o,a)}else HEAPU32[i.usedPtr]=o},i}();_nbind.Pool=Pool;function constructType(i,o){var a=i==10240?_nbind.makeTypeNameTbl[o.name]||_nbind.BindType:_nbind.makeTypeKindTbl[i],c=new a(o);return typeIdTbl[o.id]=c,_nbind.typeNameTbl[o.name]=c,c}_nbind.constructType=constructType;function getType(i){return typeIdTbl[i]}_nbind.getType=getType;function queryType(i){var o=HEAPU8[i],a=_nbind.structureList[o][1];i/=4,a<0&&(++i,a=HEAPU32[i]+1);var c=Array.prototype.slice.call(HEAPU32.subarray(i+1,i+1+a));return o==9&&(c=[c[0],c.slice(1)]),{paramList:c,placeholderFlag:o}}_nbind.queryType=queryType;function getTypes(i,o){return i.map(function(a){return typeof a=="number"?_nbind.getComplexType(a,constructType,getType,queryType,o):_nbind.typeNameTbl[a]})}_nbind.getTypes=getTypes;function readTypeIdList(i,o){return Array.prototype.slice.call(HEAPU32,i/4,i/4+o)}_nbind.readTypeIdList=readTypeIdList;function readAsciiString(i){for(var o=i;HEAPU8[o++];);return String.fromCharCode.apply("",HEAPU8.subarray(i,o-1))}_nbind.readAsciiString=readAsciiString;function readPolicyList(i){var o={};if(i)for(;;){var a=HEAPU32[i/4];if(!a)break;o[readAsciiString(a)]=!0,i+=4}return o}_nbind.readPolicyList=readPolicyList;function getDynCall(i,o){var a={float32_t:"d",float64_t:"d",int64_t:"d",uint64_t:"d",void:"v"},c=i.map(function(t){return a[t.name]||"i"}).join(""),_=Module["dynCall_"+c];if(!_)throw new Error("dynCall_"+c+" not found for "+o+"("+i.map(function(t){return t.name}).join(", ")+")");return _}_nbind.getDynCall=getDynCall;function addMethod(i,o,a,c){var _=i[o];i.hasOwnProperty(o)&&_?((_.arity||_.arity===0)&&(_=_nbind.makeOverloader(_,_.arity),i[o]=_),_.addMethod(a,c)):(a.arity=c,i[o]=a)}_nbind.addMethod=addMethod;function throwError(i){throw new Error(i)}_nbind.throwError=throwError,_nbind.bigEndian=!1,_a=_typeModule(_typeModule),_nbind.Type=_a.Type,_nbind.makeType=_a.makeType,_nbind.getComplexType=_a.getComplexType,_nbind.structureList=_a.structureList;var BindType=function(i){__extends(o,i);function o(){var a=i!==null&&i.apply(this,arguments)||this;return a.heap=HEAPU32,a.ptrSize=4,a}return o.prototype.needsWireRead=function(a){return!!this.wireRead||!!this.makeWireRead},o.prototype.needsWireWrite=function(a){return!!this.wireWrite||!!this.makeWireWrite},o}(_nbind.Type);_nbind.BindType=BindType;var PrimitiveType=function(i){__extends(o,i);function o(a){var c=i.call(this,a)||this,_=a.flags&32?{32:HEAPF32,64:HEAPF64}:a.flags&8?{8:HEAPU8,16:HEAPU16,32:HEAPU32}:{8:HEAP8,16:HEAP16,32:HEAP32};return c.heap=_[a.ptrSize*8],c.ptrSize=a.ptrSize,c}return o.prototype.needsWireWrite=function(a){return!!a&&!!a.Strict},o.prototype.makeWireWrite=function(a,c){return c&&c.Strict&&function(_){if(typeof _=="number")return _;throw new Error("Type mismatch")}},o}(BindType);_nbind.PrimitiveType=PrimitiveType;function pushCString(i,o){if(i==null){if(o&&o.Nullable)return 0;throw new Error("Type mismatch")}if(o&&o.Strict){if(typeof i!="string")throw new Error("Type mismatch")}else i=i.toString();var a=Module.lengthBytesUTF8(i)+1,c=_nbind.Pool.lalloc(a);return Module.stringToUTF8Array(i,HEAPU8,c,a),c}_nbind.pushCString=pushCString;function popCString(i){return i===0?null:Module.Pointer_stringify(i)}_nbind.popCString=popCString;var CStringType=function(i){__extends(o,i);function o(){var a=i!==null&&i.apply(this,arguments)||this;return a.wireRead=popCString,a.wireWrite=pushCString,a.readResources=[_nbind.resources.pool],a.writeResources=[_nbind.resources.pool],a}return o.prototype.makeWireWrite=function(a,c){return function(_){return pushCString(_,c)}},o}(BindType);_nbind.CStringType=CStringType;var BooleanType=function(i){__extends(o,i);function o(){var a=i!==null&&i.apply(this,arguments)||this;return a.wireRead=function(c){return!!c},a}return o.prototype.needsWireWrite=function(a){return!!a&&!!a.Strict},o.prototype.makeWireRead=function(a){return"!!("+a+")"},o.prototype.makeWireWrite=function(a,c){return c&&c.Strict&&function(_){if(typeof _=="boolean")return _;throw new Error("Type mismatch")}||a},o}(BindType);_nbind.BooleanType=BooleanType;var Wrapper=function(){function i(){}return i.prototype.persist=function(){this.__nbindState|=1},i}();_nbind.Wrapper=Wrapper;function makeBound(i,o){var a=function(c){__extends(_,c);function _(t,O,N,M){var T=c.call(this)||this;if(!(T instanceof _))return new(Function.prototype.bind.apply(_,Array.prototype.concat.apply([null],arguments)));var B=O,H=N,q=M;if(t!==_nbind.ptrMarker){var ne=T.__nbindConstructor.apply(T,arguments);B=4096|512,q=HEAPU32[ne/4],H=HEAPU32[ne/4+1]}var m={configurable:!0,enumerable:!1,value:null,writable:!1},he={__nbindFlags:B,__nbindPtr:H};q&&(he.__nbindShared=q,_nbind.mark(T));for(var De=0,se=Object.keys(he);De>=1;var a=_nbind.valueList[i];return _nbind.valueList[i]=firstFreeValue,firstFreeValue=i,a}else{if(o)return _nbind.popShared(i,o);throw new Error("Invalid value slot "+i)}}_nbind.popValue=popValue;var valueBase=18446744073709552e3;function push64(i){return typeof i=="number"?i:pushValue(i)*4096+valueBase}function pop64(i){return i=3?O=Buffer.from(t):O=new Buffer(t),O.copy(c)}else getBuffer(c).set(t)}}_nbind.commitBuffer=commitBuffer;var dirtyList=[],gcTimer=0;function sweep(){for(var i=0,o=dirtyList;i>2]=DYNAMIC_BASE,staticSealed=!0;function invoke_viiiii(i,o,a,c,_,t){try{Module.dynCall_viiiii(i,o,a,c,_,t)}catch(O){if(typeof O!="number"&&O!=="longjmp")throw O;Module.setThrew(1,0)}}function invoke_vif(i,o,a){try{Module.dynCall_vif(i,o,a)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_vid(i,o,a){try{Module.dynCall_vid(i,o,a)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_fiff(i,o,a,c){try{return Module.dynCall_fiff(i,o,a,c)}catch(_){if(typeof _!="number"&&_!=="longjmp")throw _;Module.setThrew(1,0)}}function invoke_vi(i,o){try{Module.dynCall_vi(i,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_vii(i,o,a){try{Module.dynCall_vii(i,o,a)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_ii(i,o){try{return Module.dynCall_ii(i,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_viddi(i,o,a,c,_){try{Module.dynCall_viddi(i,o,a,c,_)}catch(t){if(typeof t!="number"&&t!=="longjmp")throw t;Module.setThrew(1,0)}}function invoke_vidd(i,o,a,c){try{Module.dynCall_vidd(i,o,a,c)}catch(_){if(typeof _!="number"&&_!=="longjmp")throw _;Module.setThrew(1,0)}}function invoke_iiii(i,o,a,c){try{return Module.dynCall_iiii(i,o,a,c)}catch(_){if(typeof _!="number"&&_!=="longjmp")throw _;Module.setThrew(1,0)}}function invoke_diii(i,o,a,c){try{return Module.dynCall_diii(i,o,a,c)}catch(_){if(typeof _!="number"&&_!=="longjmp")throw _;Module.setThrew(1,0)}}function invoke_di(i,o){try{return Module.dynCall_di(i,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_iid(i,o,a){try{return Module.dynCall_iid(i,o,a)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_iii(i,o,a){try{return Module.dynCall_iii(i,o,a)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_viiddi(i,o,a,c,_,t){try{Module.dynCall_viiddi(i,o,a,c,_,t)}catch(O){if(typeof O!="number"&&O!=="longjmp")throw O;Module.setThrew(1,0)}}function invoke_viiiiii(i,o,a,c,_,t,O){try{Module.dynCall_viiiiii(i,o,a,c,_,t,O)}catch(N){if(typeof N!="number"&&N!=="longjmp")throw N;Module.setThrew(1,0)}}function invoke_dii(i,o,a){try{return Module.dynCall_dii(i,o,a)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_i(i){try{return Module.dynCall_i(i)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_iiiiii(i,o,a,c,_,t){try{return Module.dynCall_iiiiii(i,o,a,c,_,t)}catch(O){if(typeof O!="number"&&O!=="longjmp")throw O;Module.setThrew(1,0)}}function invoke_viiid(i,o,a,c,_){try{Module.dynCall_viiid(i,o,a,c,_)}catch(t){if(typeof t!="number"&&t!=="longjmp")throw t;Module.setThrew(1,0)}}function invoke_viififi(i,o,a,c,_,t,O){try{Module.dynCall_viififi(i,o,a,c,_,t,O)}catch(N){if(typeof N!="number"&&N!=="longjmp")throw N;Module.setThrew(1,0)}}function invoke_viii(i,o,a,c){try{Module.dynCall_viii(i,o,a,c)}catch(_){if(typeof _!="number"&&_!=="longjmp")throw _;Module.setThrew(1,0)}}function invoke_v(i){try{Module.dynCall_v(i)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_viid(i,o,a,c){try{Module.dynCall_viid(i,o,a,c)}catch(_){if(typeof _!="number"&&_!=="longjmp")throw _;Module.setThrew(1,0)}}function invoke_idd(i,o,a){try{return Module.dynCall_idd(i,o,a)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_viiii(i,o,a,c,_){try{Module.dynCall_viiii(i,o,a,c,_)}catch(t){if(typeof t!="number"&&t!=="longjmp")throw t;Module.setThrew(1,0)}}Module.asmGlobalArg={Math,Int8Array,Int16Array,Int32Array,Uint8Array,Uint16Array,Uint32Array,Float32Array,Float64Array,NaN:NaN,Infinity:Infinity},Module.asmLibraryArg={abort,assert,enlargeMemory,getTotalMemory,abortOnCannotGrowMemory,invoke_viiiii,invoke_vif,invoke_vid,invoke_fiff,invoke_vi,invoke_vii,invoke_ii,invoke_viddi,invoke_vidd,invoke_iiii,invoke_diii,invoke_di,invoke_iid,invoke_iii,invoke_viiddi,invoke_viiiiii,invoke_dii,invoke_i,invoke_iiiiii,invoke_viiid,invoke_viififi,invoke_viii,invoke_v,invoke_viid,invoke_idd,invoke_viiii,_emscripten_asm_const_iiiii,_emscripten_asm_const_iiidddddd,_emscripten_asm_const_iiiid,__nbind_reference_external,_emscripten_asm_const_iiiiiiii,_removeAccessorPrefix,_typeModule,__nbind_register_pool,__decorate,_llvm_stackrestore,___cxa_atexit,__extends,__nbind_get_value_object,__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,_emscripten_set_main_loop_timing,__nbind_register_primitive,__nbind_register_type,_emscripten_memcpy_big,__nbind_register_function,___setErrNo,__nbind_register_class,__nbind_finish,_abort,_nbind_value,_llvm_stacksave,___syscall54,_defineHidden,_emscripten_set_main_loop,_emscripten_get_now,__nbind_register_callback_signature,_emscripten_asm_const_iiiiii,__nbind_free_external,_emscripten_asm_const_iiii,_emscripten_asm_const_iiididi,___syscall6,_atexit,___syscall140,___syscall146,DYNAMICTOP_PTR,tempDoublePtr,ABORT,STACKTOP,STACK_MAX,cttz_i8,___dso_handle};var asm=function(i,o,a){var c=new i.Int8Array(a),_=new i.Int16Array(a),t=new i.Int32Array(a),O=new i.Uint8Array(a),N=new i.Uint16Array(a),M=new i.Uint32Array(a),T=new i.Float32Array(a),B=new i.Float64Array(a),H=o.DYNAMICTOP_PTR|0,q=o.tempDoublePtr|0,ne=o.ABORT|0,m=o.STACKTOP|0,he=o.STACK_MAX|0,De=o.cttz_i8|0,se=o.___dso_handle|0,fe=0,_e=0,ce=0,me=0,ie=i.NaN,Oe=i.Infinity,Ue=0,je=0,at=0,Dt=0,Qe=0,ut=0,Ve=i.Math.floor,It=i.Math.abs,Xt=i.Math.sqrt,rt=i.Math.pow,X=i.Math.cos,de=i.Math.sin,Ce=i.Math.tan,oe=i.Math.acos,He=i.Math.asin,dt=i.Math.atan,At=i.Math.atan2,nn=i.Math.exp,an=i.Math.log,Mn=i.Math.ceil,lr=i.Math.imul,ln=i.Math.min,Vt=i.Math.max,Dr=i.Math.clz32,w=i.Math.fround,jt=o.abort,Xn=o.assert,vr=o.enlargeMemory,jr=o.getTotalMemory,fr=o.abortOnCannotGrowMemory,zr=o.invoke_viiiii,Qt=o.invoke_vif,wu=o.invoke_vid,d0=o.invoke_fiff,Ro=o.invoke_vi,Jo=o.invoke_vii,Ps=o.invoke_ii,Zo=o.invoke_viddi,$o=o.invoke_vidd,qt=o.invoke_iiii,Ai=o.invoke_diii,su=o.invoke_di,mi=o.invoke_iid,wr=o.invoke_iii,el=o.invoke_viiddi,Y0=o.invoke_viiiiii,Uu=o.invoke_dii,K0=o.invoke_i,Xr=o.invoke_iiiiii,Oo=o.invoke_viiid,Mo=o.invoke_viififi,F0=o.invoke_viii,au=o.invoke_v,Li=o.invoke_viid,Is=o.invoke_idd,Xl=o.invoke_viiii,P0=o._emscripten_asm_const_iiiii,p0=o._emscripten_asm_const_iiidddddd,Hr=o._emscripten_asm_const_iiiid,Ri=o.__nbind_reference_external,X0=o._emscripten_asm_const_iiiiiiii,gi=o._removeAccessorPrefix,en=o._typeModule,bn=o.__nbind_register_pool,Oi=o.__decorate,yi=o._llvm_stackrestore,Wt=o.___cxa_atexit,Ru=o.__extends,eu=o.__nbind_get_value_object,Q0=o.__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,Yi=o._emscripten_set_main_loop_timing,Ql=o.__nbind_register_primitive,ko=o.__nbind_register_type,ai=o._emscripten_memcpy_big,ao=o.__nbind_register_function,Jl=o.___setErrNo,Lo=o.__nbind_register_class,bs=o.__nbind_finish,$n=o._abort,tl=o._nbind_value,fo=o._llvm_stacksave,I0=o.___syscall54,Sl=o._defineHidden,No=o._emscripten_set_main_loop,wt=o._emscripten_get_now,bt=o.__nbind_register_callback_signature,Hn=o._emscripten_asm_const_iiiiii,qr=o.__nbind_free_external,Ki=o._emscripten_asm_const_iiii,Qr=o._emscripten_asm_const_iiididi,Ou=o.___syscall6,h0=o._atexit,Ni=o.___syscall140,v0=o.___syscall146,vs=w(0);let Tt=w(0);function co(e){e=e|0;var n=0;return n=m,m=m+e|0,m=m+15&-16,n|0}function nl(){return m|0}function Zl(e){e=e|0,m=e}function ju(e,n){e=e|0,n=n|0,m=e,he=n}function ms(e,n){e=e|0,n=n|0,fe||(fe=e,_e=n)}function b0(e){e=e|0,ut=e}function Q(){return ut|0}function we(){var e=0,n=0;_r(8104,8,400)|0,_r(8504,408,540)|0,e=9044,n=e+44|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));c[9088]=0,c[9089]=1,t[2273]=0,t[2274]=948,t[2275]=948,Wt(17,8104,se|0)|0}function Ne(e){e=e|0,fc(e+948|0)}function Le(e){return e=w(e),((mr(e)|0)&2147483647)>>>0>2139095040|0}function pt(e,n,r){e=e|0,n=n|0,r=r|0;e:do if(t[e+(n<<3)+4>>2]|0)e=e+(n<<3)|0;else{if((n|2|0)==3?t[e+60>>2]|0:0){e=e+56|0;break}switch(n|0){case 0:case 2:case 4:case 5:{if(t[e+52>>2]|0){e=e+48|0;break e}break}default:}if(t[e+68>>2]|0){e=e+64|0;break}else{e=(n|1|0)==5?948:r;break}}while(0);return e|0}function Yn(e){e=e|0;var n=0;return n=T_(1e3)|0,Cn(e,(n|0)!=0,2456),t[2276]=(t[2276]|0)+1,_r(n|0,8104,1e3)|0,c[e+2>>0]|0&&(t[n+4>>2]=2,t[n+12>>2]=4),t[n+976>>2]=e,n|0}function Cn(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;l=m,m=m+16|0,u=l,n||(t[u>>2]=r,Cl(e,5,3197,u)),m=l}function cr(){return Yn(956)|0}function Si(e){e=e|0;var n=0;return n=pn(1e3)|0,Mu(n,e),Cn(t[e+976>>2]|0,1,2456),t[2276]=(t[2276]|0)+1,t[n+944>>2]=0,n|0}function Mu(e,n){e=e|0,n=n|0;var r=0;_r(e|0,n|0,948)|0,aa(e+948|0,n+948|0),r=e+960|0,e=n+960|0,n=r+40|0;do t[r>>2]=t[e>>2],r=r+4|0,e=e+4|0;while((r|0)<(n|0))}function zu(e){e=e|0;var n=0,r=0,u=0,l=0;if(n=e+944|0,r=t[n>>2]|0,r|0&&(Hu(r+948|0,e)|0,t[n>>2]=0),r=Su(e)|0,r|0){n=0;do t[(Ti(e,n)|0)+944>>2]=0,n=n+1|0;while((n|0)!=(r|0))}r=e+948|0,u=t[r>>2]|0,l=e+952|0,n=t[l>>2]|0,(n|0)!=(u|0)&&(t[l>>2]=n+(~((n+-4-u|0)>>>2)<<2)),Fo(r),C_(e),t[2276]=(t[2276]|0)+-1}function Hu(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0;u=t[e>>2]|0,D=e+4|0,r=t[D>>2]|0,s=r;e:do if((u|0)==(r|0))l=u,h=4;else for(e=u;;){if((t[e>>2]|0)==(n|0)){l=e,h=4;break e}if(e=e+4|0,(e|0)==(r|0)){e=0;break}}while(0);return(h|0)==4&&((l|0)!=(r|0)?(u=l+4|0,e=s-u|0,n=e>>2,n&&(kg(l|0,u|0,e|0)|0,r=t[D>>2]|0),e=l+(n<<2)|0,(r|0)==(e|0)||(t[D>>2]=r+(~((r+-4-e|0)>>>2)<<2)),e=1):e=0),e|0}function Su(e){return e=e|0,(t[e+952>>2]|0)-(t[e+948>>2]|0)>>2|0}function Ti(e,n){e=e|0,n=n|0;var r=0;return r=t[e+948>>2]|0,(t[e+952>>2]|0)-r>>2>>>0>n>>>0?e=t[r+(n<<2)>>2]|0:e=0,e|0}function Fo(e){e=e|0;var n=0,r=0,u=0,l=0;u=m,m=m+32|0,n=u,l=t[e>>2]|0,r=(t[e+4>>2]|0)-l|0,((t[e+8>>2]|0)-l|0)>>>0>r>>>0&&(l=r>>2,Y(n,l,l,e+8|0),ri(e,n),ii(n)),m=u}function ku(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0;L=Su(e)|0;do if(L|0){if((t[(Ti(e,0)|0)+944>>2]|0)==(e|0)){if(!(Hu(e+948|0,n)|0))break;_r(n+400|0,8504,540)|0,t[n+944>>2]=0,Qn(e);break}h=t[(t[e+976>>2]|0)+12>>2]|0,D=e+948|0,S=(h|0)==0,r=0,s=0;do u=t[(t[D>>2]|0)+(s<<2)>>2]|0,(u|0)==(n|0)?Qn(e):(l=Si(u)|0,t[(t[D>>2]|0)+(r<<2)>>2]=l,t[l+944>>2]=e,S||tD[h&15](u,l,e,r),r=r+1|0),s=s+1|0;while((s|0)!=(L|0));if(r>>>0>>0){S=e+948|0,D=e+952|0,h=r,r=t[D>>2]|0;do s=(t[S>>2]|0)+(h<<2)|0,u=s+4|0,l=r-u|0,n=l>>2,n&&(kg(s|0,u|0,l|0)|0,r=t[D>>2]|0),l=r,u=s+(n<<2)|0,(l|0)!=(u|0)&&(r=l+(~((l+-4-u|0)>>>2)<<2)|0,t[D>>2]=r),h=h+1|0;while((h|0)!=(L|0))}}while(0)}function po(e){e=e|0;var n=0,r=0,u=0,l=0;qu(e,(Su(e)|0)==0,2491),qu(e,(t[e+944>>2]|0)==0,2545),n=e+948|0,r=t[n>>2]|0,u=e+952|0,l=t[u>>2]|0,(l|0)!=(r|0)&&(t[u>>2]=l+(~((l+-4-r|0)>>>2)<<2)),Fo(n),n=e+976|0,r=t[n>>2]|0,_r(e|0,8104,1e3)|0,c[r+2>>0]|0&&(t[e+4>>2]=2,t[e+12>>2]=4),t[n>>2]=r}function qu(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;l=m,m=m+16|0,u=l,n||(t[u>>2]=r,pr(e,5,3197,u)),m=l}function Ia(){return t[2276]|0}function m0(){var e=0;return e=T_(20)|0,ua((e|0)!=0,2592),t[2277]=(t[2277]|0)+1,t[e>>2]=t[239],t[e+4>>2]=t[240],t[e+8>>2]=t[241],t[e+12>>2]=t[242],t[e+16>>2]=t[243],e|0}function ua(e,n){e=e|0,n=n|0;var r=0,u=0;u=m,m=m+16|0,r=u,e||(t[r>>2]=n,pr(0,5,3197,r)),m=u}function J0(e){e=e|0,C_(e),t[2277]=(t[2277]|0)+-1}function oa(e,n){e=e|0,n=n|0;var r=0;n?(qu(e,(Su(e)|0)==0,2629),r=1):(r=0,n=0),t[e+964>>2]=n,t[e+988>>2]=r}function ba(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;u=m,m=m+16|0,s=u+8|0,l=u+4|0,h=u,t[l>>2]=n,qu(e,(t[n+944>>2]|0)==0,2709),qu(e,(t[e+964>>2]|0)==0,2763),gs(e),n=e+948|0,t[h>>2]=(t[n>>2]|0)+(r<<2),t[s>>2]=t[h>>2],S0(n,s,l)|0,t[(t[l>>2]|0)+944>>2]=e,Qn(e),m=u}function gs(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0;if(r=Su(e)|0,r|0?(t[(Ti(e,0)|0)+944>>2]|0)!=(e|0):0){u=t[(t[e+976>>2]|0)+12>>2]|0,l=e+948|0,s=(u|0)==0,n=0;do h=t[(t[l>>2]|0)+(n<<2)>>2]|0,D=Si(h)|0,t[(t[l>>2]|0)+(n<<2)>>2]=D,t[D+944>>2]=e,s||tD[u&15](h,D,e,n),n=n+1|0;while((n|0)!=(r|0))}}function S0(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0,Ze=0,Ge=0;Ze=m,m=m+64|0,I=Ze+52|0,D=Ze+48|0,K=Ze+28|0,be=Ze+24|0,Se=Ze+20|0,ge=Ze,u=t[e>>2]|0,s=u,n=u+((t[n>>2]|0)-s>>2<<2)|0,u=e+4|0,l=t[u>>2]|0,h=e+8|0;do if(l>>>0<(t[h>>2]|0)>>>0){if((n|0)==(l|0)){t[n>>2]=t[r>>2],t[u>>2]=(t[u>>2]|0)+4;break}Vr(e,n,l,n+4|0),n>>>0<=r>>>0&&(r=(t[u>>2]|0)>>>0>r>>>0?r+4|0:r),t[n>>2]=t[r>>2]}else{u=(l-s>>2)+1|0,l=A0(e)|0,l>>>0>>0&&hi(e),k=t[e>>2]|0,L=(t[h>>2]|0)-k|0,s=L>>1,Y(ge,L>>2>>>0>>1>>>0?s>>>0>>0?u:s:l,n-k>>2,e+8|0),k=ge+8|0,u=t[k>>2]|0,s=ge+12|0,L=t[s>>2]|0,h=L,S=u;do if((u|0)==(L|0)){if(L=ge+4|0,u=t[L>>2]|0,Ge=t[ge>>2]|0,l=Ge,u>>>0<=Ge>>>0){u=h-l>>1,u=(u|0)==0?1:u,Y(K,u,u>>>2,t[ge+16>>2]|0),t[be>>2]=t[L>>2],t[Se>>2]=t[k>>2],t[D>>2]=t[be>>2],t[I>>2]=t[Se>>2],Di(K,D,I),u=t[ge>>2]|0,t[ge>>2]=t[K>>2],t[K>>2]=u,u=K+4|0,Ge=t[L>>2]|0,t[L>>2]=t[u>>2],t[u>>2]=Ge,u=K+8|0,Ge=t[k>>2]|0,t[k>>2]=t[u>>2],t[u>>2]=Ge,u=K+12|0,Ge=t[s>>2]|0,t[s>>2]=t[u>>2],t[u>>2]=Ge,ii(K),u=t[k>>2]|0;break}s=u,h=((s-l>>2)+1|0)/-2|0,D=u+(h<<2)|0,l=S-s|0,s=l>>2,s&&(kg(D|0,u|0,l|0)|0,u=t[L>>2]|0),Ge=D+(s<<2)|0,t[k>>2]=Ge,t[L>>2]=u+(h<<2),u=Ge}while(0);t[u>>2]=t[r>>2],t[k>>2]=(t[k>>2]|0)+4,n=ft(e,ge,n)|0,ii(ge)}while(0);return m=Ze,n|0}function Qn(e){e=e|0;var n=0;do{if(n=e+984|0,c[n>>0]|0)break;c[n>>0]=1,T[e+504>>2]=w(ie),e=t[e+944>>2]|0}while((e|0)!=0)}function fc(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-4-u|0)>>>2)<<2)),yt(r))}function fi(e){return e=e|0,t[e+944>>2]|0}function $r(e){e=e|0,qu(e,(t[e+964>>2]|0)!=0,2832),Qn(e)}function $l(e){return e=e|0,(c[e+984>>0]|0)!=0|0}function la(e,n){e=e|0,n=n|0,kF(e,n,400)|0&&(_r(e|0,n|0,400)|0,Qn(e))}function hf(e){e=e|0;var n=Tt;return n=w(T[e+44>>2]),e=Le(n)|0,w(e?w(0):n)}function Bs(e){e=e|0;var n=Tt;return n=w(T[e+48>>2]),Le(n)|0&&(n=c[(t[e+976>>2]|0)+2>>0]|0?w(1):w(0)),w(n)}function Ba(e,n){e=e|0,n=n|0,t[e+980>>2]=n}function Us(e){return e=e|0,t[e+980>>2]|0}function g0(e,n){e=e|0,n=n|0;var r=0;r=e+4|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function js(e){return e=e|0,t[e+4>>2]|0}function ji(e,n){e=e|0,n=n|0;var r=0;r=e+8|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function U(e){return e=e|0,t[e+8>>2]|0}function z(e,n){e=e|0,n=n|0;var r=0;r=e+12|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function G(e){return e=e|0,t[e+12>>2]|0}function $(e,n){e=e|0,n=n|0;var r=0;r=e+16|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function Te(e){return e=e|0,t[e+16>>2]|0}function ye(e,n){e=e|0,n=n|0;var r=0;r=e+20|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function Ae(e){return e=e|0,t[e+20>>2]|0}function Z(e,n){e=e|0,n=n|0;var r=0;r=e+24|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function ke(e){return e=e|0,t[e+24>>2]|0}function Je(e,n){e=e|0,n=n|0;var r=0;r=e+28|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function vt(e){return e=e|0,t[e+28>>2]|0}function ue(e,n){e=e|0,n=n|0;var r=0;r=e+32|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function qe(e){return e=e|0,t[e+32>>2]|0}function nt(e,n){e=e|0,n=n|0;var r=0;r=e+36|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,Qn(e))}function Ct(e){return e=e|0,t[e+36>>2]|0}function Mt(e,n){e=e|0,n=w(n);var r=0;r=e+40|0,w(T[r>>2])!=n&&(T[r>>2]=n,Qn(e))}function Pt(e,n){e=e|0,n=w(n);var r=0;r=e+44|0,w(T[r>>2])!=n&&(T[r>>2]=n,Qn(e))}function sn(e,n){e=e|0,n=w(n);var r=0;r=e+48|0,w(T[r>>2])!=n&&(T[r>>2]=n,Qn(e))}function rn(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=(s^1)&1,u=e+52|0,l=e+56|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function Nt(e,n){e=e|0,n=w(n);var r=0,u=0;u=e+52|0,r=e+56|0,(w(T[u>>2])==n?(t[r>>2]|0)==2:0)||(T[u>>2]=n,u=Le(n)|0,t[r>>2]=u?3:2,Qn(e))}function Dn(e,n){e=e|0,n=n|0;var r=0,u=0;u=n+52|0,r=t[u+4>>2]|0,n=e,t[n>>2]=t[u>>2],t[n+4>>2]=r}function dr(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0,s=0;s=Le(r)|0,u=(s^1)&1,l=e+132+(n<<3)|0,n=e+132+(n<<3)+4|0,(s|w(T[l>>2])==r?(t[n>>2]|0)==(u|0):0)||(T[l>>2]=r,t[n>>2]=u,Qn(e))}function er(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0,s=0;s=Le(r)|0,u=s?0:2,l=e+132+(n<<3)|0,n=e+132+(n<<3)+4|0,(s|w(T[l>>2])==r?(t[n>>2]|0)==(u|0):0)||(T[l>>2]=r,t[n>>2]=u,Qn(e))}function Cr(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=n+132+(r<<3)|0,n=t[u+4>>2]|0,r=e,t[r>>2]=t[u>>2],t[r+4>>2]=n}function Rn(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0,s=0;s=Le(r)|0,u=(s^1)&1,l=e+60+(n<<3)|0,n=e+60+(n<<3)+4|0,(s|w(T[l>>2])==r?(t[n>>2]|0)==(u|0):0)||(T[l>>2]=r,t[n>>2]=u,Qn(e))}function Lr(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0,s=0;s=Le(r)|0,u=s?0:2,l=e+60+(n<<3)|0,n=e+60+(n<<3)+4|0,(s|w(T[l>>2])==r?(t[n>>2]|0)==(u|0):0)||(T[l>>2]=r,t[n>>2]=u,Qn(e))}function y0(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=n+60+(r<<3)|0,n=t[u+4>>2]|0,r=e,t[r>>2]=t[u>>2],t[r+4>>2]=n}function Nr(e,n){e=e|0,n=n|0;var r=0;r=e+60+(n<<3)+4|0,(t[r>>2]|0)!=3&&(T[e+60+(n<<3)>>2]=w(ie),t[r>>2]=3,Qn(e))}function it(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0,s=0;s=Le(r)|0,u=(s^1)&1,l=e+204+(n<<3)|0,n=e+204+(n<<3)+4|0,(s|w(T[l>>2])==r?(t[n>>2]|0)==(u|0):0)||(T[l>>2]=r,t[n>>2]=u,Qn(e))}function Et(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0,s=0;s=Le(r)|0,u=s?0:2,l=e+204+(n<<3)|0,n=e+204+(n<<3)+4|0,(s|w(T[l>>2])==r?(t[n>>2]|0)==(u|0):0)||(T[l>>2]=r,t[n>>2]=u,Qn(e))}function et(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=n+204+(r<<3)|0,n=t[u+4>>2]|0,r=e,t[r>>2]=t[u>>2],t[r+4>>2]=n}function Ft(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0,s=0;s=Le(r)|0,u=(s^1)&1,l=e+276+(n<<3)|0,n=e+276+(n<<3)+4|0,(s|w(T[l>>2])==r?(t[n>>2]|0)==(u|0):0)||(T[l>>2]=r,t[n>>2]=u,Qn(e))}function un(e,n){return e=e|0,n=n|0,w(T[e+276+(n<<3)>>2])}function fn(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=(s^1)&1,u=e+348|0,l=e+352|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function Jn(e,n){e=e|0,n=w(n);var r=0,u=0;u=e+348|0,r=e+352|0,(w(T[u>>2])==n?(t[r>>2]|0)==2:0)||(T[u>>2]=n,u=Le(n)|0,t[r>>2]=u?3:2,Qn(e))}function Sr(e){e=e|0;var n=0;n=e+352|0,(t[n>>2]|0)!=3&&(T[e+348>>2]=w(ie),t[n>>2]=3,Qn(e))}function fu(e,n){e=e|0,n=n|0;var r=0,u=0;u=n+348|0,r=t[u+4>>2]|0,n=e,t[n>>2]=t[u>>2],t[n+4>>2]=r}function Lu(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=(s^1)&1,u=e+356|0,l=e+360|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function T0(e,n){e=e|0,n=w(n);var r=0,u=0;u=e+356|0,r=e+360|0,(w(T[u>>2])==n?(t[r>>2]|0)==2:0)||(T[u>>2]=n,u=Le(n)|0,t[r>>2]=u?3:2,Qn(e))}function Z0(e){e=e|0;var n=0;n=e+360|0,(t[n>>2]|0)!=3&&(T[e+356>>2]=w(ie),t[n>>2]=3,Qn(e))}function Nu(e,n){e=e|0,n=n|0;var r=0,u=0;u=n+356|0,r=t[u+4>>2]|0,n=e,t[n>>2]=t[u>>2],t[n+4>>2]=r}function _i(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=(s^1)&1,u=e+364|0,l=e+368|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function Po(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=s?0:2,u=e+364|0,l=e+368|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function rl(e,n){e=e|0,n=n|0;var r=0,u=0;u=n+364|0,r=t[u+4>>2]|0,n=e,t[n>>2]=t[u>>2],t[n+4>>2]=r}function vf(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=(s^1)&1,u=e+372|0,l=e+376|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function Tl(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=s?0:2,u=e+372|0,l=e+376|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function mf(e,n){e=e|0,n=n|0;var r=0,u=0;u=n+372|0,r=t[u+4>>2]|0,n=e,t[n>>2]=t[u>>2],t[n+4>>2]=r}function Io(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=(s^1)&1,u=e+380|0,l=e+384|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function ys(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=s?0:2,u=e+380|0,l=e+384|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function zs(e,n){e=e|0,n=n|0;var r=0,u=0;u=n+380|0,r=t[u+4>>2]|0,n=e,t[n>>2]=t[u>>2],t[n+4>>2]=r}function bo(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=(s^1)&1,u=e+388|0,l=e+392|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function Bo(e,n){e=e|0,n=w(n);var r=0,u=0,l=0,s=0;s=Le(n)|0,r=s?0:2,u=e+388|0,l=e+392|0,(s|w(T[u>>2])==n?(t[l>>2]|0)==(r|0):0)||(T[u>>2]=n,t[l>>2]=r,Qn(e))}function _s(e,n){e=e|0,n=n|0;var r=0,u=0;u=n+388|0,r=t[u+4>>2]|0,n=e,t[n>>2]=t[u>>2],t[n+4>>2]=r}function Qu(e,n){e=e|0,n=w(n);var r=0;r=e+396|0,w(T[r>>2])!=n&&(T[r>>2]=n,Qn(e))}function Tu(e){return e=e|0,w(T[e+396>>2])}function Ei(e){return e=e|0,w(T[e+400>>2])}function C0(e){return e=e|0,w(T[e+404>>2])}function $0(e){return e=e|0,w(T[e+408>>2])}function Uo(e){return e=e|0,w(T[e+412>>2])}function sa(e){return e=e|0,w(T[e+416>>2])}function es(e){return e=e|0,w(T[e+420>>2])}function tu(e,n){switch(e=e|0,n=n|0,qu(e,(n|0)<6,2918),n|0){case 0:{n=(t[e+496>>2]|0)==2?5:4;break}case 2:{n=(t[e+496>>2]|0)==2?4:5;break}default:}return w(T[e+424+(n<<2)>>2])}function ei(e,n){switch(e=e|0,n=n|0,qu(e,(n|0)<6,2918),n|0){case 0:{n=(t[e+496>>2]|0)==2?5:4;break}case 2:{n=(t[e+496>>2]|0)==2?4:5;break}default:}return w(T[e+448+(n<<2)>>2])}function ho(e,n){switch(e=e|0,n=n|0,qu(e,(n|0)<6,2918),n|0){case 0:{n=(t[e+496>>2]|0)==2?5:4;break}case 2:{n=(t[e+496>>2]|0)==2?4:5;break}default:}return w(T[e+472+(n<<2)>>2])}function Bi(e,n){e=e|0,n=n|0;var r=0,u=Tt;return r=t[e+4>>2]|0,(r|0)==(t[n+4>>2]|0)?r?(u=w(T[e>>2]),e=w(It(w(u-w(T[n>>2]))))>2]=0,t[u+4>>2]=0,t[u+8>>2]=0,Q0(u|0,e|0,n|0,0),pr(e,3,(c[u+11>>0]|0)<0?t[u>>2]|0:u,r),eP(u),m=r}function eo(e,n,r,u){e=w(e),n=w(n),r=r|0,u=u|0;var l=Tt;e=w(e*n),l=w(XE(e,w(1)));do if(Ci(l,w(0))|0)e=w(e-l);else{if(e=w(e-l),Ci(l,w(1))|0){e=w(e+w(1));break}if(r){e=w(e+w(1));break}u||(l>w(.5)?l=w(1):(u=Ci(l,w(.5))|0,l=w(u?1:0)),e=w(e+l))}while(0);return w(e/n)}function to(e,n,r,u,l,s,h,D,S,L,k,I,K){e=e|0,n=w(n),r=r|0,u=w(u),l=l|0,s=w(s),h=h|0,D=w(D),S=w(S),L=w(L),k=w(k),I=w(I),K=K|0;var be=0,Se=Tt,ge=Tt,Ze=Tt,Ge=Tt,ct=Tt,Me=Tt;return S>2]),Se!=w(0)):0)?(Ze=w(eo(n,Se,0,0)),Ge=w(eo(u,Se,0,0)),ge=w(eo(s,Se,0,0)),Se=w(eo(D,Se,0,0))):(ge=s,Ze=n,Se=D,Ge=u),(l|0)==(e|0)?be=Ci(ge,Ze)|0:be=0,(h|0)==(r|0)?K=Ci(Se,Ge)|0:K=0,((be?0:(ct=w(n-k),!(xe(e,ct,S)|0)))?!(tt(e,ct,l,S)|0):0)?be=Ye(e,ct,l,s,S)|0:be=1,((K?0:(Me=w(u-I),!(xe(r,Me,L)|0)))?!(tt(r,Me,h,L)|0):0)?K=Ye(r,Me,h,D,L)|0:K=1,K=be&K),K|0}function xe(e,n,r){return e=e|0,n=w(n),r=w(r),(e|0)==1?e=Ci(n,r)|0:e=0,e|0}function tt(e,n,r,u){return e=e|0,n=w(n),r=r|0,u=w(u),(e|0)==2&(r|0)==0?n>=u?e=1:e=Ci(n,u)|0:e=0,e|0}function Ye(e,n,r,u,l){return e=e|0,n=w(n),r=r|0,u=w(u),l=w(l),(e|0)==2&(r|0)==2&u>n?l<=n?e=1:e=Ci(n,l)|0:e=0,e|0}function Yt(e,n,r,u,l,s,h,D,S,L,k){e=e|0,n=w(n),r=w(r),u=u|0,l=l|0,s=s|0,h=w(h),D=w(D),S=S|0,L=L|0,k=k|0;var I=0,K=0,be=0,Se=0,ge=Tt,Ze=Tt,Ge=0,ct=0,Me=0,Pe=0,Zt=0,Br=0,In=0,yn=0,Er=0,Pr=0,Ln=0,uu=Tt,ls=Tt,ss=Tt,as=0,ta=0;Ln=m,m=m+160|0,yn=Ln+152|0,In=Ln+120|0,Br=Ln+104|0,Me=Ln+72|0,Se=Ln+56|0,Zt=Ln+8|0,ct=Ln,Pe=(t[2279]|0)+1|0,t[2279]=Pe,Er=e+984|0,((c[Er>>0]|0)!=0?(t[e+512>>2]|0)!=(t[2278]|0):0)?Ge=4:(t[e+516>>2]|0)==(u|0)?Pr=0:Ge=4,(Ge|0)==4&&(t[e+520>>2]=0,t[e+924>>2]=-1,t[e+928>>2]=-1,T[e+932>>2]=w(-1),T[e+936>>2]=w(-1),Pr=1);e:do if(t[e+964>>2]|0)if(ge=w(Kt(e,2,h)),Ze=w(Kt(e,0,h)),I=e+916|0,ss=w(T[I>>2]),ls=w(T[e+920>>2]),uu=w(T[e+932>>2]),to(l,n,s,r,t[e+924>>2]|0,ss,t[e+928>>2]|0,ls,uu,w(T[e+936>>2]),ge,Ze,k)|0)Ge=22;else if(be=t[e+520>>2]|0,!be)Ge=21;else for(K=0;;){if(I=e+524+(K*24|0)|0,uu=w(T[I>>2]),ls=w(T[e+524+(K*24|0)+4>>2]),ss=w(T[e+524+(K*24|0)+16>>2]),to(l,n,s,r,t[e+524+(K*24|0)+8>>2]|0,uu,t[e+524+(K*24|0)+12>>2]|0,ls,ss,w(T[e+524+(K*24|0)+20>>2]),ge,Ze,k)|0){Ge=22;break e}if(K=K+1|0,K>>>0>=be>>>0){Ge=21;break}}else{if(S){if(I=e+916|0,!(Ci(w(T[I>>2]),n)|0)){Ge=21;break}if(!(Ci(w(T[e+920>>2]),r)|0)){Ge=21;break}if((t[e+924>>2]|0)!=(l|0)){Ge=21;break}I=(t[e+928>>2]|0)==(s|0)?I:0,Ge=22;break}if(be=t[e+520>>2]|0,!be)Ge=21;else for(K=0;;){if(I=e+524+(K*24|0)|0,((Ci(w(T[I>>2]),n)|0?Ci(w(T[e+524+(K*24|0)+4>>2]),r)|0:0)?(t[e+524+(K*24|0)+8>>2]|0)==(l|0):0)?(t[e+524+(K*24|0)+12>>2]|0)==(s|0):0){Ge=22;break e}if(K=K+1|0,K>>>0>=be>>>0){Ge=21;break}}}while(0);do if((Ge|0)==21)c[11697]|0?(I=0,Ge=28):(I=0,Ge=31);else if((Ge|0)==22){if(K=(c[11697]|0)!=0,!((I|0)!=0&(Pr^1)))if(K){Ge=28;break}else{Ge=31;break}Se=I+16|0,t[e+908>>2]=t[Se>>2],be=I+20|0,t[e+912>>2]=t[be>>2],(c[11698]|0)==0|K^1||(t[ct>>2]=Wr(Pe)|0,t[ct+4>>2]=Pe,pr(e,4,2972,ct),K=t[e+972>>2]|0,K|0&&P1[K&127](e),l=xn(l,S)|0,s=xn(s,S)|0,ta=+w(T[Se>>2]),as=+w(T[be>>2]),t[Zt>>2]=l,t[Zt+4>>2]=s,B[Zt+8>>3]=+n,B[Zt+16>>3]=+r,B[Zt+24>>3]=ta,B[Zt+32>>3]=as,t[Zt+40>>2]=L,pr(e,4,2989,Zt))}while(0);return(Ge|0)==28&&(K=Wr(Pe)|0,t[Se>>2]=K,t[Se+4>>2]=Pe,t[Se+8>>2]=Pr?3047:11699,pr(e,4,3038,Se),K=t[e+972>>2]|0,K|0&&P1[K&127](e),Zt=xn(l,S)|0,Ge=xn(s,S)|0,t[Me>>2]=Zt,t[Me+4>>2]=Ge,B[Me+8>>3]=+n,B[Me+16>>3]=+r,t[Me+24>>2]=L,pr(e,4,3049,Me),Ge=31),(Ge|0)==31&&(gu(e,n,r,u,l,s,h,D,S,k),c[11697]|0&&(K=t[2279]|0,Zt=Wr(K)|0,t[Br>>2]=Zt,t[Br+4>>2]=K,t[Br+8>>2]=Pr?3047:11699,pr(e,4,3083,Br),K=t[e+972>>2]|0,K|0&&P1[K&127](e),Zt=xn(l,S)|0,Br=xn(s,S)|0,as=+w(T[e+908>>2]),ta=+w(T[e+912>>2]),t[In>>2]=Zt,t[In+4>>2]=Br,B[In+8>>3]=as,B[In+16>>3]=ta,t[In+24>>2]=L,pr(e,4,3092,In)),t[e+516>>2]=u,I||(K=e+520|0,I=t[K>>2]|0,(I|0)==16&&(c[11697]|0&&pr(e,4,3124,yn),t[K>>2]=0,I=0),S?I=e+916|0:(t[K>>2]=I+1,I=e+524+(I*24|0)|0),T[I>>2]=n,T[I+4>>2]=r,t[I+8>>2]=l,t[I+12>>2]=s,t[I+16>>2]=t[e+908>>2],t[I+20>>2]=t[e+912>>2],I=0)),S&&(t[e+416>>2]=t[e+908>>2],t[e+420>>2]=t[e+912>>2],c[e+985>>0]=1,c[Er>>0]=0),t[2279]=(t[2279]|0)+-1,t[e+512>>2]=t[2278],m=Ln,Pr|(I|0)==0|0}function Kt(e,n,r){e=e|0,n=n|0,r=w(r);var u=Tt;return u=w(zi(e,n,r)),w(u+w(R0(e,n,r)))}function pr(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=m,m=m+16|0,l=s,t[l>>2]=u,e?u=t[e+976>>2]|0:u=0,Hs(u,e,n,r,l),m=s}function Wr(e){return e=e|0,(e>>>0>60?3201:3201+(60-e)|0)|0}function xn(e,n){e=e|0,n=n|0;var r=0,u=0,l=0;return l=m,m=m+32|0,r=l+12|0,u=l,t[r>>2]=t[254],t[r+4>>2]=t[255],t[r+8>>2]=t[256],t[u>>2]=t[257],t[u+4>>2]=t[258],t[u+8>>2]=t[259],(e|0)>2?e=11699:e=t[(n?u:r)+(e<<2)>>2]|0,m=l,e|0}function gu(e,n,r,u,l,s,h,D,S,L){e=e|0,n=w(n),r=w(r),u=u|0,l=l|0,s=s|0,h=w(h),D=w(D),S=S|0,L=L|0;var k=0,I=0,K=0,be=0,Se=Tt,ge=Tt,Ze=Tt,Ge=Tt,ct=Tt,Me=Tt,Pe=Tt,Zt=0,Br=0,In=0,yn=Tt,Er=Tt,Pr=0,Ln=Tt,uu=0,ls=0,ss=0,as=0,ta=0,r2=0,i2=0,of=0,u2=0,Pc=0,Ic=0,o2=0,l2=0,s2=0,vi=0,lf=0,a2=0,Kf=0,f2=Tt,c2=Tt,bc=Tt,Bc=Tt,Xf=Tt,ql=0,Fa=0,Ns=0,sf=0,b1=0,B1=Tt,Uc=Tt,U1=Tt,j1=Tt,Wl=Tt,El=Tt,af=0,vu=Tt,z1=Tt,fs=Tt,Qf=Tt,cs=Tt,Jf=Tt,H1=0,q1=0,Zf=Tt,Vl=Tt,ff=0,W1=0,V1=0,G1=0,Tr=Tt,Bu=0,Dl=0,ds=0,Gl=0,Or=0,Bn=0,cf=0,mn=Tt,Y1=0,f0=0;cf=m,m=m+16|0,ql=cf+12|0,Fa=cf+8|0,Ns=cf+4|0,sf=cf,qu(e,(l|0)==0|(Le(n)|0)^1,3326),qu(e,(s|0)==0|(Le(r)|0)^1,3406),Dl=xl(e,u)|0,t[e+496>>2]=Dl,Or=B0(2,Dl)|0,Bn=B0(0,Dl)|0,T[e+440>>2]=w(zi(e,Or,h)),T[e+444>>2]=w(R0(e,Or,h)),T[e+428>>2]=w(zi(e,Bn,h)),T[e+436>>2]=w(R0(e,Bn,h)),T[e+464>>2]=w(O0(e,Or)),T[e+468>>2]=w(vo(e,Or)),T[e+452>>2]=w(O0(e,Bn)),T[e+460>>2]=w(vo(e,Bn)),T[e+488>>2]=w(Pu(e,Or,h)),T[e+492>>2]=w(Zu(e,Or,h)),T[e+476>>2]=w(Pu(e,Bn,h)),T[e+484>>2]=w(Zu(e,Bn,h));do if(t[e+964>>2]|0)ts(e,n,r,l,s,h,D);else{if(ds=e+948|0,Gl=(t[e+952>>2]|0)-(t[ds>>2]|0)>>2,!Gl){Es(e,n,r,l,s,h,D);break}if(S?0:fa(e,n,r,l,s,h,D)|0)break;gs(e),lf=e+508|0,c[lf>>0]=0,Or=B0(t[e+4>>2]|0,Dl)|0,Bn=_f(Or,Dl)|0,Bu=Hi(Or)|0,a2=t[e+8>>2]|0,W1=e+28|0,Kf=(t[W1>>2]|0)!=0,cs=Bu?h:D,Zf=Bu?D:h,f2=w($u(e,Or,h)),c2=w(Ds(e,Or,h)),Se=w($u(e,Bn,h)),Jf=w(Ar(e,Or,h)),Vl=w(Ar(e,Bn,h)),In=Bu?l:s,ff=Bu?s:l,Tr=Bu?Jf:Vl,ct=Bu?Vl:Jf,Qf=w(Kt(e,2,h)),Ge=w(Kt(e,0,h)),ge=w(w(An(e+364|0,h))-Tr),Ze=w(w(An(e+380|0,h))-Tr),Me=w(w(An(e+372|0,D))-ct),Pe=w(w(An(e+388|0,D))-ct),bc=Bu?ge:Me,Bc=Bu?Ze:Pe,Qf=w(n-Qf),n=w(Qf-Tr),Le(n)|0?Tr=n:Tr=w(Au(w(Qp(n,Ze)),ge)),z1=w(r-Ge),n=w(z1-ct),Le(n)|0?fs=n:fs=w(Au(w(Qp(n,Pe)),Me)),ge=Bu?Tr:fs,vu=Bu?fs:Tr;e:do if((In|0)==1)for(u=0,I=0;;){if(k=Ti(e,I)|0,!u)(w(nu(k))>w(0)?w(cu(k))>w(0):0)?u=k:u=0;else if(no(k)|0){be=0;break e}if(I=I+1|0,I>>>0>=Gl>>>0){be=u;break}}else be=0;while(0);Zt=be+500|0,Br=be+504|0,u=0,k=0,n=w(0),K=0;do{if(I=t[(t[ds>>2]|0)+(K<<2)>>2]|0,(t[I+36>>2]|0)==1)Fi(I),c[I+985>>0]=1,c[I+984>>0]=0;else{Jr(I),S&&x0(I,xl(I,Dl)|0,ge,vu,Tr);do if((t[I+24>>2]|0)!=1)if((I|0)==(be|0)){t[Zt>>2]=t[2278],T[Br>>2]=w(0);break}else{ni(e,I,Tr,l,fs,Tr,fs,s,Dl,L);break}else k|0&&(t[k+960>>2]=I),t[I+960>>2]=0,k=I,u=(u|0)==0?I:u;while(0);El=w(T[I+504>>2]),n=w(n+w(El+w(Kt(I,Or,Tr))))}K=K+1|0}while((K|0)!=(Gl|0));for(ss=n>ge,af=Kf&((In|0)==2&ss)?1:In,uu=(ff|0)==1,ta=uu&(S^1),r2=(af|0)==1,i2=(af|0)==2,of=976+(Or<<2)|0,u2=(ff|2|0)==2,s2=uu&(Kf^1),Pc=1040+(Bn<<2)|0,Ic=1040+(Or<<2)|0,o2=976+(Bn<<2)|0,l2=(ff|0)!=1,ss=Kf&((In|0)!=0&ss),ls=e+976|0,uu=uu^1,n=ge,Pr=0,as=0,El=w(0),Xf=w(0);;){e:do if(Pr>>>0>>0)for(Br=t[ds>>2]|0,K=0,Pe=w(0),Me=w(0),Ze=w(0),ge=w(0),I=0,k=0,be=Pr;;){if(Zt=t[Br+(be<<2)>>2]|0,(t[Zt+36>>2]|0)!=1?(t[Zt+940>>2]=as,(t[Zt+24>>2]|0)!=1):0){if(Ge=w(Kt(Zt,Or,Tr)),vi=t[of>>2]|0,r=w(An(Zt+380+(vi<<3)|0,cs)),ct=w(T[Zt+504>>2]),r=w(Qp(r,ct)),r=w(Au(w(An(Zt+364+(vi<<3)|0,cs)),r)),Kf&(K|0)!=0&w(Ge+w(Me+r))>n){s=K,Ge=Pe,In=be;break e}Ge=w(Ge+r),r=w(Me+Ge),Ge=w(Pe+Ge),no(Zt)|0&&(Ze=w(Ze+w(nu(Zt))),ge=w(ge-w(ct*w(cu(Zt))))),k|0&&(t[k+960>>2]=Zt),t[Zt+960>>2]=0,K=K+1|0,k=Zt,I=(I|0)==0?Zt:I}else Ge=Pe,r=Me;if(be=be+1|0,be>>>0>>0)Pe=Ge,Me=r;else{s=K,In=be;break}}else s=0,Ge=w(0),Ze=w(0),ge=w(0),I=0,In=Pr;while(0);vi=Ze>w(0)&Zew(0)&geBc&((Le(Bc)|0)^1))n=Bc,vi=51;else if(c[(t[ls>>2]|0)+3>>0]|0)vi=51;else{if(yn!=w(0)?w(nu(e))!=w(0):0){vi=53;break}n=Ge,vi=53}while(0);if((vi|0)==51&&(vi=0,Le(n)|0?vi=53:(Er=w(n-Ge),Ln=n)),(vi|0)==53&&(vi=0,Ge>2]|0,be=Erw(0),Me=w(Er/yn),Ze=w(0),Ge=w(0),n=w(0),k=I;do r=w(An(k+380+(K<<3)|0,cs)),ge=w(An(k+364+(K<<3)|0,cs)),ge=w(Qp(r,w(Au(ge,w(T[k+504>>2]))))),be?(r=w(ge*w(cu(k))),(r!=w(-0)?(mn=w(ge-w(ct*r)),B1=w(Kn(k,Or,mn,Ln,Tr)),mn!=B1):0)&&(Ze=w(Ze-w(B1-ge)),n=w(n+r))):((Zt?(Uc=w(nu(k)),Uc!=w(0)):0)?(mn=w(ge+w(Me*Uc)),U1=w(Kn(k,Or,mn,Ln,Tr)),mn!=U1):0)&&(Ze=w(Ze-w(U1-ge)),Ge=w(Ge-Uc)),k=t[k+960>>2]|0;while((k|0)!=0);if(n=w(Pe+n),ge=w(Er+Ze),b1)n=w(0);else{ct=w(yn+Ge),be=t[of>>2]|0,Zt=gew(0),ct=w(ge/ct),n=w(0);do{mn=w(An(I+380+(be<<3)|0,cs)),Ze=w(An(I+364+(be<<3)|0,cs)),Ze=w(Qp(mn,w(Au(Ze,w(T[I+504>>2]))))),Zt?(mn=w(Ze*w(cu(I))),ge=w(-mn),mn!=w(-0)?(mn=w(Me*ge),ge=w(Kn(I,Or,w(Ze+(Br?ge:mn)),Ln,Tr))):ge=Ze):(K?(j1=w(nu(I)),j1!=w(0)):0)?ge=w(Kn(I,Or,w(Ze+w(ct*j1)),Ln,Tr)):ge=Ze,n=w(n-w(ge-Ze)),Ge=w(Kt(I,Or,Tr)),r=w(Kt(I,Bn,Tr)),ge=w(ge+Ge),T[Fa>>2]=ge,t[sf>>2]=1,Ze=w(T[I+396>>2]);e:do if(Le(Ze)|0){k=Le(vu)|0;do if(!k){if(ss|(Wu(I,Bn,vu)|0|uu)||(e0(e,I)|0)!=4||(t[(_0(I,Bn)|0)+4>>2]|0)==3||(t[(E0(I,Bn)|0)+4>>2]|0)==3)break;T[ql>>2]=vu,t[Ns>>2]=1;break e}while(0);if(Wu(I,Bn,vu)|0){k=t[I+992+(t[o2>>2]<<2)>>2]|0,mn=w(r+w(An(k,vu))),T[ql>>2]=mn,k=l2&(t[k+4>>2]|0)==2,t[Ns>>2]=((Le(mn)|0|k)^1)&1;break}else{T[ql>>2]=vu,t[Ns>>2]=k?0:2;break}}else mn=w(ge-Ge),yn=w(mn/Ze),mn=w(Ze*mn),t[Ns>>2]=1,T[ql>>2]=w(r+(Bu?yn:mn));while(0);Fn(I,Or,Ln,Tr,sf,Fa),Fn(I,Bn,vu,Tr,Ns,ql);do if(Wu(I,Bn,vu)|0?0:(e0(e,I)|0)==4){if((t[(_0(I,Bn)|0)+4>>2]|0)==3){k=0;break}k=(t[(E0(I,Bn)|0)+4>>2]|0)!=3}else k=0;while(0);mn=w(T[Fa>>2]),yn=w(T[ql>>2]),Y1=t[sf>>2]|0,f0=t[Ns>>2]|0,Yt(I,Bu?mn:yn,Bu?yn:mn,Dl,Bu?Y1:f0,Bu?f0:Y1,Tr,fs,S&(k^1),3488,L)|0,c[lf>>0]=c[lf>>0]|c[I+508>>0],I=t[I+960>>2]|0}while((I|0)!=0)}}else n=w(0);if(n=w(Er+n),f0=n>0]=f0|O[lf>>0],i2&n>w(0)?(k=t[of>>2]|0,((t[e+364+(k<<3)+4>>2]|0)!=0?(Wl=w(An(e+364+(k<<3)|0,cs)),Wl>=w(0)):0)?ge=w(Au(w(0),w(Wl-w(Ln-n)))):ge=w(0)):ge=n,Zt=Pr>>>0>>0,Zt){be=t[ds>>2]|0,K=Pr,k=0;do I=t[be+(K<<2)>>2]|0,t[I+24>>2]|0||(k=((t[(_0(I,Or)|0)+4>>2]|0)==3&1)+k|0,k=k+((t[(E0(I,Or)|0)+4>>2]|0)==3&1)|0),K=K+1|0;while((K|0)!=(In|0));k?(Ge=w(0),r=w(0)):vi=101}else vi=101;e:do if((vi|0)==101)switch(vi=0,a2|0){case 1:{k=0,Ge=w(ge*w(.5)),r=w(0);break e}case 2:{k=0,Ge=ge,r=w(0);break e}case 3:{if(s>>>0<=1){k=0,Ge=w(0),r=w(0);break e}r=w((s+-1|0)>>>0),k=0,Ge=w(0),r=w(w(Au(ge,w(0)))/r);break e}case 5:{r=w(ge/w((s+1|0)>>>0)),k=0,Ge=r;break e}case 4:{r=w(ge/w(s>>>0)),k=0,Ge=w(r*w(.5));break e}default:{k=0,Ge=w(0),r=w(0);break e}}while(0);if(n=w(f2+Ge),Zt){Ze=w(ge/w(k|0)),K=t[ds>>2]|0,I=Pr,ge=w(0);do{k=t[K+(I<<2)>>2]|0;e:do if((t[k+36>>2]|0)!=1){switch(t[k+24>>2]|0){case 1:{if(ae(k,Or)|0){if(!S)break e;mn=w(re(k,Or,Ln)),mn=w(mn+w(O0(e,Or))),mn=w(mn+w(zi(k,Or,Tr))),T[k+400+(t[Ic>>2]<<2)>>2]=mn;break e}break}case 0:if(f0=(t[(_0(k,Or)|0)+4>>2]|0)==3,mn=w(Ze+n),n=f0?mn:n,S&&(f0=k+400+(t[Ic>>2]<<2)|0,T[f0>>2]=w(n+w(T[f0>>2]))),f0=(t[(E0(k,Or)|0)+4>>2]|0)==3,mn=w(Ze+n),n=f0?mn:n,ta){mn=w(r+w(Kt(k,Or,Tr))),ge=vu,n=w(n+w(mn+w(T[k+504>>2])));break e}else{n=w(n+w(r+w(Fe(k,Or,Tr)))),ge=w(Au(ge,w(Fe(k,Bn,Tr))));break e}default:}S&&(mn=w(Ge+w(O0(e,Or))),f0=k+400+(t[Ic>>2]<<2)|0,T[f0>>2]=w(mn+w(T[f0>>2])))}while(0);I=I+1|0}while((I|0)!=(In|0))}else ge=w(0);if(r=w(c2+n),u2?Ge=w(w(Kn(e,Bn,w(Vl+ge),Zf,h))-Vl):Ge=vu,Ze=w(w(Kn(e,Bn,w(Vl+(s2?vu:ge)),Zf,h))-Vl),Zt&S){I=Pr;do{K=t[(t[ds>>2]|0)+(I<<2)>>2]|0;do if((t[K+36>>2]|0)!=1){if((t[K+24>>2]|0)==1){if(ae(K,Bn)|0){if(mn=w(re(K,Bn,vu)),mn=w(mn+w(O0(e,Bn))),mn=w(mn+w(zi(K,Bn,Tr))),k=t[Pc>>2]|0,T[K+400+(k<<2)>>2]=mn,!(Le(mn)|0))break}else k=t[Pc>>2]|0;mn=w(O0(e,Bn)),T[K+400+(k<<2)>>2]=w(mn+w(zi(K,Bn,Tr)));break}k=e0(e,K)|0;do if((k|0)==4){if((t[(_0(K,Bn)|0)+4>>2]|0)==3){vi=139;break}if((t[(E0(K,Bn)|0)+4>>2]|0)==3){vi=139;break}if(Wu(K,Bn,vu)|0){n=Se;break}Y1=t[K+908+(t[of>>2]<<2)>>2]|0,t[ql>>2]=Y1,n=w(T[K+396>>2]),f0=Le(n)|0,ge=(t[q>>2]=Y1,w(T[q>>2])),f0?n=Ze:(Er=w(Kt(K,Bn,Tr)),mn=w(ge/n),n=w(n*ge),n=w(Er+(Bu?mn:n))),T[Fa>>2]=n,T[ql>>2]=w(w(Kt(K,Or,Tr))+ge),t[Ns>>2]=1,t[sf>>2]=1,Fn(K,Or,Ln,Tr,Ns,ql),Fn(K,Bn,vu,Tr,sf,Fa),n=w(T[ql>>2]),Er=w(T[Fa>>2]),mn=Bu?n:Er,n=Bu?Er:n,f0=((Le(mn)|0)^1)&1,Yt(K,mn,n,Dl,f0,((Le(n)|0)^1)&1,Tr,fs,1,3493,L)|0,n=Se}else vi=139;while(0);e:do if((vi|0)==139){vi=0,n=w(Ge-w(Fe(K,Bn,Tr)));do if((t[(_0(K,Bn)|0)+4>>2]|0)==3){if((t[(E0(K,Bn)|0)+4>>2]|0)!=3)break;n=w(Se+w(Au(w(0),w(n*w(.5)))));break e}while(0);if((t[(E0(K,Bn)|0)+4>>2]|0)==3){n=Se;break}if((t[(_0(K,Bn)|0)+4>>2]|0)==3){n=w(Se+w(Au(w(0),n)));break}switch(k|0){case 1:{n=Se;break e}case 2:{n=w(Se+w(n*w(.5)));break e}default:{n=w(Se+n);break e}}}while(0);mn=w(El+n),f0=K+400+(t[Pc>>2]<<2)|0,T[f0>>2]=w(mn+w(T[f0>>2]))}while(0);I=I+1|0}while((I|0)!=(In|0))}if(El=w(El+Ze),Xf=w(Au(Xf,r)),s=as+1|0,In>>>0>=Gl>>>0)break;n=Ln,Pr=In,as=s}do if(S){if(k=s>>>0>1,k?0:!(Re(e)|0))break;if(!(Le(vu)|0)){n=w(vu-El);e:do switch(t[e+12>>2]|0){case 3:{Se=w(Se+n),Me=w(0);break}case 2:{Se=w(Se+w(n*w(.5))),Me=w(0);break}case 4:{vu>El?Me=w(n/w(s>>>0)):Me=w(0);break}case 7:if(vu>El){Se=w(Se+w(n/w(s<<1>>>0))),Me=w(n/w(s>>>0)),Me=k?Me:w(0);break e}else{Se=w(Se+w(n*w(.5))),Me=w(0);break e}case 6:{Me=w(n/w(as>>>0)),Me=vu>El&k?Me:w(0);break}default:Me=w(0)}while(0);if(s|0)for(Zt=1040+(Bn<<2)|0,Br=976+(Bn<<2)|0,be=0,I=0;;){e:do if(I>>>0>>0)for(ge=w(0),Ze=w(0),n=w(0),K=I;;){k=t[(t[ds>>2]|0)+(K<<2)>>2]|0;do if((t[k+36>>2]|0)!=1?(t[k+24>>2]|0)==0:0){if((t[k+940>>2]|0)!=(be|0))break e;if(st(k,Bn)|0&&(mn=w(T[k+908+(t[Br>>2]<<2)>>2]),n=w(Au(n,w(mn+w(Kt(k,Bn,Tr)))))),(e0(e,k)|0)!=5)break;Wl=w(mt(k)),Wl=w(Wl+w(zi(k,0,Tr))),mn=w(T[k+912>>2]),mn=w(w(mn+w(Kt(k,0,Tr)))-Wl),Wl=w(Au(Ze,Wl)),mn=w(Au(ge,mn)),ge=mn,Ze=Wl,n=w(Au(n,w(Wl+mn)))}while(0);if(k=K+1|0,k>>>0>>0)K=k;else{K=k;break}}else Ze=w(0),n=w(0),K=I;while(0);if(ct=w(Me+n),r=Se,Se=w(Se+ct),I>>>0>>0){Ge=w(r+Ze),k=I;do{I=t[(t[ds>>2]|0)+(k<<2)>>2]|0;e:do if((t[I+36>>2]|0)!=1?(t[I+24>>2]|0)==0:0)switch(e0(e,I)|0){case 1:{mn=w(r+w(zi(I,Bn,Tr))),T[I+400+(t[Zt>>2]<<2)>>2]=mn;break e}case 3:{mn=w(w(Se-w(R0(I,Bn,Tr)))-w(T[I+908+(t[Br>>2]<<2)>>2])),T[I+400+(t[Zt>>2]<<2)>>2]=mn;break e}case 2:{mn=w(r+w(w(ct-w(T[I+908+(t[Br>>2]<<2)>>2]))*w(.5))),T[I+400+(t[Zt>>2]<<2)>>2]=mn;break e}case 4:{if(mn=w(r+w(zi(I,Bn,Tr))),T[I+400+(t[Zt>>2]<<2)>>2]=mn,Wu(I,Bn,vu)|0||(Bu?(ge=w(T[I+908>>2]),n=w(ge+w(Kt(I,Or,Tr))),Ze=ct):(Ze=w(T[I+912>>2]),Ze=w(Ze+w(Kt(I,Bn,Tr))),n=ct,ge=w(T[I+908>>2])),Ci(n,ge)|0?Ci(Ze,w(T[I+912>>2]))|0:0))break e;Yt(I,n,Ze,Dl,1,1,Tr,fs,1,3501,L)|0;break e}case 5:{T[I+404>>2]=w(w(Ge-w(mt(I)))+w(re(I,0,vu)));break e}default:break e}while(0);k=k+1|0}while((k|0)!=(K|0))}if(be=be+1|0,(be|0)==(s|0))break;I=K}}}while(0);if(T[e+908>>2]=w(Kn(e,2,Qf,h,h)),T[e+912>>2]=w(Kn(e,0,z1,D,h)),((af|0)!=0?(H1=t[e+32>>2]|0,q1=(af|0)==2,!(q1&(H1|0)!=2)):0)?q1&(H1|0)==2&&(n=w(Jf+Ln),n=w(Au(w(Qp(n,w(Jt(e,Or,Xf,cs)))),Jf)),vi=198):(n=w(Kn(e,Or,Xf,cs,h)),vi=198),(vi|0)==198&&(T[e+908+(t[976+(Or<<2)>>2]<<2)>>2]=n),((ff|0)!=0?(V1=t[e+32>>2]|0,G1=(ff|0)==2,!(G1&(V1|0)!=2)):0)?G1&(V1|0)==2&&(n=w(Vl+vu),n=w(Au(w(Qp(n,w(Jt(e,Bn,w(Vl+El),Zf)))),Vl)),vi=204):(n=w(Kn(e,Bn,w(Vl+El),Zf,h)),vi=204),(vi|0)==204&&(T[e+908+(t[976+(Bn<<2)>>2]<<2)>>2]=n),S){if((t[W1>>2]|0)==2){I=976+(Bn<<2)|0,K=1040+(Bn<<2)|0,k=0;do be=Ti(e,k)|0,t[be+24>>2]|0||(Y1=t[I>>2]|0,mn=w(T[e+908+(Y1<<2)>>2]),f0=be+400+(t[K>>2]<<2)|0,mn=w(mn-w(T[f0>>2])),T[f0>>2]=w(mn-w(T[be+908+(Y1<<2)>>2]))),k=k+1|0;while((k|0)!=(Gl|0))}if(u|0){k=Bu?af:l;do On(e,u,Tr,k,fs,Dl,L),u=t[u+960>>2]|0;while((u|0)!=0)}if(k=(Or|2|0)==3,I=(Bn|2|0)==3,k|I){u=0;do K=t[(t[ds>>2]|0)+(u<<2)>>2]|0,(t[K+36>>2]|0)!=1&&(k&&Sn(e,K,Or),I&&Sn(e,K,Bn)),u=u+1|0;while((u|0)!=(Gl|0))}}}while(0);m=cf}function Ju(e,n){e=e|0,n=w(n);var r=0;Cn(e,n>=w(0),3147),r=n==w(0),T[e+4>>2]=r?w(0):n}function ti(e,n,r,u){e=e|0,n=w(n),r=w(r),u=u|0;var l=Tt,s=Tt,h=0,D=0,S=0;t[2278]=(t[2278]|0)+1,Jr(e),Wu(e,2,n)|0?(l=w(An(t[e+992>>2]|0,n)),S=1,l=w(l+w(Kt(e,2,n)))):(l=w(An(e+380|0,n)),l>=w(0)?S=2:(S=((Le(n)|0)^1)&1,l=n)),Wu(e,0,r)|0?(s=w(An(t[e+996>>2]|0,r)),D=1,s=w(s+w(Kt(e,0,n)))):(s=w(An(e+388|0,r)),s>=w(0)?D=2:(D=((Le(r)|0)^1)&1,s=r)),h=e+976|0,(Yt(e,l,s,u,S,D,n,r,1,3189,t[h>>2]|0)|0?(x0(e,t[e+496>>2]|0,n,r,n),Fu(e,w(T[(t[h>>2]|0)+4>>2]),w(0),w(0)),c[11696]|0):0)&&gf(e,7)}function Jr(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;D=m,m=m+32|0,h=D+24|0,s=D+16|0,u=D+8|0,l=D,r=0;do n=e+380+(r<<3)|0,((t[e+380+(r<<3)+4>>2]|0)!=0?(S=n,L=t[S+4>>2]|0,k=u,t[k>>2]=t[S>>2],t[k+4>>2]=L,k=e+364+(r<<3)|0,L=t[k+4>>2]|0,S=l,t[S>>2]=t[k>>2],t[S+4>>2]=L,t[s>>2]=t[u>>2],t[s+4>>2]=t[u+4>>2],t[h>>2]=t[l>>2],t[h+4>>2]=t[l+4>>2],Bi(s,h)|0):0)||(n=e+348+(r<<3)|0),t[e+992+(r<<2)>>2]=n,r=r+1|0;while((r|0)!=2);m=D}function Wu(e,n,r){e=e|0,n=n|0,r=w(r);var u=0;switch(e=t[e+992+(t[976+(n<<2)>>2]<<2)>>2]|0,t[e+4>>2]|0){case 0:case 3:{e=0;break}case 1:{w(T[e>>2])>2])>2]|0){case 2:{n=w(w(w(T[e>>2])*n)/w(100));break}case 1:{n=w(T[e>>2]);break}default:n=w(ie)}return w(n)}function x0(e,n,r,u,l){e=e|0,n=n|0,r=w(r),u=w(u),l=w(l);var s=0,h=Tt;n=t[e+944>>2]|0?n:1,s=B0(t[e+4>>2]|0,n)|0,n=_f(s,n)|0,r=w(Rr(e,s,r)),u=w(Rr(e,n,u)),h=w(r+w(zi(e,s,l))),T[e+400+(t[1040+(s<<2)>>2]<<2)>>2]=h,r=w(r+w(R0(e,s,l))),T[e+400+(t[1e3+(s<<2)>>2]<<2)>>2]=r,r=w(u+w(zi(e,n,l))),T[e+400+(t[1040+(n<<2)>>2]<<2)>>2]=r,l=w(u+w(R0(e,n,l))),T[e+400+(t[1e3+(n<<2)>>2]<<2)>>2]=l}function Fu(e,n,r,u){e=e|0,n=w(n),r=w(r),u=w(u);var l=0,s=0,h=Tt,D=Tt,S=0,L=0,k=Tt,I=0,K=Tt,be=Tt,Se=Tt,ge=Tt;if(n!=w(0)&&(l=e+400|0,ge=w(T[l>>2]),s=e+404|0,Se=w(T[s>>2]),I=e+416|0,be=w(T[I>>2]),L=e+420|0,h=w(T[L>>2]),K=w(ge+r),k=w(Se+u),u=w(K+be),D=w(k+h),S=(t[e+988>>2]|0)==1,T[l>>2]=w(eo(ge,n,0,S)),T[s>>2]=w(eo(Se,n,0,S)),r=w(XE(w(be*n),w(1))),Ci(r,w(0))|0?s=0:s=(Ci(r,w(1))|0)^1,r=w(XE(w(h*n),w(1))),Ci(r,w(0))|0?l=0:l=(Ci(r,w(1))|0)^1,ge=w(eo(u,n,S&s,S&(s^1))),T[I>>2]=w(ge-w(eo(K,n,0,S))),ge=w(eo(D,n,S&l,S&(l^1))),T[L>>2]=w(ge-w(eo(k,n,0,S))),s=(t[e+952>>2]|0)-(t[e+948>>2]|0)>>2,s|0)){l=0;do Fu(Ti(e,l)|0,n,K,k),l=l+1|0;while((l|0)!=(s|0))}}function li(e,n,r,u,l){switch(e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,r|0){case 5:case 0:{e=I8(t[489]|0,u,l)|0;break}default:e=QF(u,l)|0}return e|0}function Cl(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;l=m,m=m+16|0,s=l,t[s>>2]=u,Hs(e,0,n,r,s),m=l}function Hs(e,n,r,u,l){if(e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,e=e|0?e:956,rS[t[e+8>>2]&1](e,n,r,u,l)|0,(r|0)==5)$n();else return}function Vu(e,n,r){e=e|0,n=n|0,r=r|0,c[e+n>>0]=r&1}function aa(e,n){e=e|0,n=n|0;var r=0,u=0;t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,r=n+4|0,u=(t[r>>2]|0)-(t[n>>2]|0)>>2,u|0&&(Xi(e,u),qs(e,t[n>>2]|0,t[r>>2]|0,u))}function Xi(e,n){e=e|0,n=n|0;var r=0;if((A0(e)|0)>>>0>>0&&hi(e),n>>>0>1073741823)$n();else{r=pn(n<<2)|0,t[e+4>>2]=r,t[e>>2]=r,t[e+8>>2]=r+(n<<2);return}}function qs(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,u=e+4|0,e=r-n|0,(e|0)>0&&(_r(t[u>>2]|0,n|0,e|0)|0,t[u>>2]=(t[u>>2]|0)+(e>>>2<<2))}function A0(e){return e=e|0,1073741823}function zi(e,n,r){return e=e|0,n=n|0,r=w(r),(Hi(n)|0?(t[e+96>>2]|0)!=0:0)?e=e+92|0:e=pt(e+60|0,t[1040+(n<<2)>>2]|0,992)|0,w(il(e,r))}function R0(e,n,r){return e=e|0,n=n|0,r=w(r),(Hi(n)|0?(t[e+104>>2]|0)!=0:0)?e=e+100|0:e=pt(e+60|0,t[1e3+(n<<2)>>2]|0,992)|0,w(il(e,r))}function Hi(e){return e=e|0,(e|1|0)==3|0}function il(e,n){return e=e|0,n=w(n),(t[e+4>>2]|0)==3?n=w(0):n=w(An(e,n)),w(n)}function xl(e,n){return e=e|0,n=n|0,e=t[e>>2]|0,((e|0)==0?(n|0)>1?n:1:e)|0}function B0(e,n){e=e|0,n=n|0;var r=0;e:do if((n|0)==2){switch(e|0){case 2:{e=3;break e}case 3:break;default:{r=4;break e}}e=2}else r=4;while(0);return e|0}function O0(e,n){e=e|0,n=n|0;var r=Tt;return((Hi(n)|0?(t[e+312>>2]|0)!=0:0)?(r=w(T[e+308>>2]),r>=w(0)):0)||(r=w(Au(w(T[(pt(e+276|0,t[1040+(n<<2)>>2]|0,992)|0)>>2]),w(0)))),w(r)}function vo(e,n){e=e|0,n=n|0;var r=Tt;return((Hi(n)|0?(t[e+320>>2]|0)!=0:0)?(r=w(T[e+316>>2]),r>=w(0)):0)||(r=w(Au(w(T[(pt(e+276|0,t[1e3+(n<<2)>>2]|0,992)|0)>>2]),w(0)))),w(r)}function Pu(e,n,r){e=e|0,n=n|0,r=w(r);var u=Tt;return((Hi(n)|0?(t[e+240>>2]|0)!=0:0)?(u=w(An(e+236|0,r)),u>=w(0)):0)||(u=w(Au(w(An(pt(e+204|0,t[1040+(n<<2)>>2]|0,992)|0,r)),w(0)))),w(u)}function Zu(e,n,r){e=e|0,n=n|0,r=w(r);var u=Tt;return((Hi(n)|0?(t[e+248>>2]|0)!=0:0)?(u=w(An(e+244|0,r)),u>=w(0)):0)||(u=w(Au(w(An(pt(e+204|0,t[1e3+(n<<2)>>2]|0,992)|0,r)),w(0)))),w(u)}function ts(e,n,r,u,l,s,h){e=e|0,n=w(n),r=w(r),u=u|0,l=l|0,s=w(s),h=w(h);var D=Tt,S=Tt,L=Tt,k=Tt,I=Tt,K=Tt,be=0,Se=0,ge=0;ge=m,m=m+16|0,be=ge,Se=e+964|0,qu(e,(t[Se>>2]|0)!=0,3519),D=w(Ar(e,2,n)),S=w(Ar(e,0,n)),L=w(Kt(e,2,n)),k=w(Kt(e,0,n)),Le(n)|0?I=n:I=w(Au(w(0),w(w(n-L)-D))),Le(r)|0?K=r:K=w(Au(w(0),w(w(r-k)-S))),(u|0)==1&(l|0)==1?(T[e+908>>2]=w(Kn(e,2,w(n-L),s,s)),n=w(Kn(e,0,w(r-k),h,s))):(iS[t[Se>>2]&1](be,e,I,u,K,l),I=w(D+w(T[be>>2])),K=w(n-L),T[e+908>>2]=w(Kn(e,2,(u|2|0)==2?I:K,s,s)),K=w(S+w(T[be+4>>2])),n=w(r-k),n=w(Kn(e,0,(l|2|0)==2?K:n,h,s))),T[e+912>>2]=n,m=ge}function Es(e,n,r,u,l,s,h){e=e|0,n=w(n),r=w(r),u=u|0,l=l|0,s=w(s),h=w(h);var D=Tt,S=Tt,L=Tt,k=Tt;L=w(Ar(e,2,s)),D=w(Ar(e,0,s)),k=w(Kt(e,2,s)),S=w(Kt(e,0,s)),n=w(n-k),T[e+908>>2]=w(Kn(e,2,(u|2|0)==2?L:n,s,s)),r=w(r-S),T[e+912>>2]=w(Kn(e,0,(l|2|0)==2?D:r,h,s))}function fa(e,n,r,u,l,s,h){e=e|0,n=w(n),r=w(r),u=u|0,l=l|0,s=w(s),h=w(h);var D=0,S=Tt,L=Tt;return D=(u|0)==2,((n<=w(0)&D?0:!(r<=w(0)&(l|0)==2))?!((u|0)==1&(l|0)==1):0)?e=0:(S=w(Kt(e,0,s)),L=w(Kt(e,2,s)),D=n>2]=w(Kn(e,2,D?w(0):n,s,s)),n=w(r-S),D=r>2]=w(Kn(e,0,D?w(0):n,h,s)),e=1),e|0}function _f(e,n){return e=e|0,n=n|0,_n(e)|0?e=B0(2,n)|0:e=0,e|0}function $u(e,n,r){return e=e|0,n=n|0,r=w(r),r=w(Pu(e,n,r)),w(r+w(O0(e,n)))}function Ds(e,n,r){return e=e|0,n=n|0,r=w(r),r=w(Zu(e,n,r)),w(r+w(vo(e,n)))}function Ar(e,n,r){e=e|0,n=n|0,r=w(r);var u=Tt;return u=w($u(e,n,r)),w(u+w(Ds(e,n,r)))}function no(e){return e=e|0,t[e+24>>2]|0?e=0:w(nu(e))!=w(0)?e=1:e=w(cu(e))!=w(0),e|0}function nu(e){e=e|0;var n=Tt;if(t[e+944>>2]|0){if(n=w(T[e+44>>2]),Le(n)|0)return n=w(T[e+40>>2]),e=n>w(0)&((Le(n)|0)^1),w(e?n:w(0))}else n=w(0);return w(n)}function cu(e){e=e|0;var n=Tt,r=0,u=Tt;do if(t[e+944>>2]|0){if(n=w(T[e+48>>2]),Le(n)|0){if(r=c[(t[e+976>>2]|0)+2>>0]|0,r<<24>>24==0?(u=w(T[e+40>>2]),u>24?w(1):w(0)}}else n=w(0);while(0);return w(n)}function Fi(e){e=e|0;var n=0,r=0;if(jv(e+400|0,0,540)|0,c[e+985>>0]=1,gs(e),r=Su(e)|0,r|0){n=e+948|0,e=0;do Fi(t[(t[n>>2]|0)+(e<<2)>>2]|0),e=e+1|0;while((e|0)!=(r|0))}}function ni(e,n,r,u,l,s,h,D,S,L){e=e|0,n=n|0,r=w(r),u=u|0,l=w(l),s=w(s),h=w(h),D=D|0,S=S|0,L=L|0;var k=0,I=Tt,K=0,be=0,Se=Tt,ge=Tt,Ze=0,Ge=Tt,ct=0,Me=Tt,Pe=0,Zt=0,Br=0,In=0,yn=0,Er=0,Pr=0,Ln=0,uu=0,ls=0;uu=m,m=m+16|0,Br=uu+12|0,In=uu+8|0,yn=uu+4|0,Er=uu,Ln=B0(t[e+4>>2]|0,S)|0,Pe=Hi(Ln)|0,I=w(An(Tn(n)|0,Pe?s:h)),Zt=Wu(n,2,s)|0,Pr=Wu(n,0,h)|0;do if(Le(I)|0?0:!(Le(Pe?r:l)|0)){if(k=n+504|0,!(Le(w(T[k>>2]))|0)&&(!(ir(t[n+976>>2]|0,0)|0)||(t[n+500>>2]|0)==(t[2278]|0)))break;T[k>>2]=w(Au(I,w(Ar(n,Ln,s))))}else K=7;while(0);do if((K|0)==7){if(ct=Pe^1,!(ct|Zt^1)){h=w(An(t[n+992>>2]|0,s)),T[n+504>>2]=w(Au(h,w(Ar(n,2,s))));break}if(!(Pe|Pr^1)){h=w(An(t[n+996>>2]|0,h)),T[n+504>>2]=w(Au(h,w(Ar(n,0,s))));break}T[Br>>2]=w(ie),T[In>>2]=w(ie),t[yn>>2]=0,t[Er>>2]=0,Ge=w(Kt(n,2,s)),Me=w(Kt(n,0,s)),Zt?(Se=w(Ge+w(An(t[n+992>>2]|0,s))),T[Br>>2]=Se,t[yn>>2]=1,be=1):(be=0,Se=w(ie)),Pr?(I=w(Me+w(An(t[n+996>>2]|0,h))),T[In>>2]=I,t[Er>>2]=1,k=1):(k=0,I=w(ie)),K=t[e+32>>2]|0,Pe&(K|0)==2?K=2:(Le(Se)|0?!(Le(r)|0):0)&&(T[Br>>2]=r,t[yn>>2]=2,be=2,Se=r),(((K|0)==2&ct?0:Le(I)|0)?!(Le(l)|0):0)&&(T[In>>2]=l,t[Er>>2]=2,k=2,I=l),ge=w(T[n+396>>2]),Ze=Le(ge)|0;do if(Ze)K=be;else{if((be|0)==1&ct){T[In>>2]=w(w(Se-Ge)/ge),t[Er>>2]=1,k=1,K=1;break}Pe&(k|0)==1?(T[Br>>2]=w(ge*w(I-Me)),t[yn>>2]=1,k=1,K=1):K=be}while(0);ls=Le(r)|0,be=(e0(e,n)|0)!=4,(Pe|Zt|((u|0)!=1|ls)|(be|(K|0)==1)?0:(T[Br>>2]=r,t[yn>>2]=1,!Ze))&&(T[In>>2]=w(w(r-Ge)/ge),t[Er>>2]=1,k=1),(Pr|ct|((D|0)!=1|(Le(l)|0))|(be|(k|0)==1)?0:(T[In>>2]=l,t[Er>>2]=1,!Ze))&&(T[Br>>2]=w(ge*w(l-Me)),t[yn>>2]=1),Fn(n,2,s,s,yn,Br),Fn(n,0,h,s,Er,In),r=w(T[Br>>2]),l=w(T[In>>2]),Yt(n,r,l,S,t[yn>>2]|0,t[Er>>2]|0,s,h,0,3565,L)|0,h=w(T[n+908+(t[976+(Ln<<2)>>2]<<2)>>2]),T[n+504>>2]=w(Au(h,w(Ar(n,Ln,s))))}while(0);t[n+500>>2]=t[2278],m=uu}function Kn(e,n,r,u,l){return e=e|0,n=n|0,r=w(r),u=w(u),l=w(l),u=w(Jt(e,n,r,u)),w(Au(u,w(Ar(e,n,l))))}function e0(e,n){return e=e|0,n=n|0,n=n+20|0,n=t[((t[n>>2]|0)==0?e+16|0:n)>>2]|0,((n|0)==5?_n(t[e+4>>2]|0)|0:0)&&(n=1),n|0}function _0(e,n){return e=e|0,n=n|0,(Hi(n)|0?(t[e+96>>2]|0)!=0:0)?n=4:n=t[1040+(n<<2)>>2]|0,e+60+(n<<3)|0}function E0(e,n){return e=e|0,n=n|0,(Hi(n)|0?(t[e+104>>2]|0)!=0:0)?n=5:n=t[1e3+(n<<2)>>2]|0,e+60+(n<<3)|0}function Fn(e,n,r,u,l,s){switch(e=e|0,n=n|0,r=w(r),u=w(u),l=l|0,s=s|0,r=w(An(e+380+(t[976+(n<<2)>>2]<<3)|0,r)),r=w(r+w(Kt(e,n,u))),t[l>>2]|0){case 2:case 1:{l=Le(r)|0,u=w(T[s>>2]),T[s>>2]=l|u>2]=2,T[s>>2]=r);break}default:}}function ae(e,n){return e=e|0,n=n|0,e=e+132|0,(Hi(n)|0?(t[(pt(e,4,948)|0)+4>>2]|0)!=0:0)?e=1:e=(t[(pt(e,t[1040+(n<<2)>>2]|0,948)|0)+4>>2]|0)!=0,e|0}function re(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0;return e=e+132|0,(Hi(n)|0?(u=pt(e,4,948)|0,(t[u+4>>2]|0)!=0):0)?l=4:(u=pt(e,t[1040+(n<<2)>>2]|0,948)|0,t[u+4>>2]|0?l=4:r=w(0)),(l|0)==4&&(r=w(An(u,r))),w(r)}function Fe(e,n,r){e=e|0,n=n|0,r=w(r);var u=Tt;return u=w(T[e+908+(t[976+(n<<2)>>2]<<2)>>2]),u=w(u+w(zi(e,n,r))),w(u+w(R0(e,n,r)))}function Re(e){e=e|0;var n=0,r=0,u=0;e:do if(_n(t[e+4>>2]|0)|0)n=0;else if((t[e+16>>2]|0)!=5)if(r=Su(e)|0,!r)n=0;else for(n=0;;){if(u=Ti(e,n)|0,(t[u+24>>2]|0)==0?(t[u+20>>2]|0)==5:0){n=1;break e}if(n=n+1|0,n>>>0>=r>>>0){n=0;break}}else n=1;while(0);return n|0}function st(e,n){e=e|0,n=n|0;var r=Tt;return r=w(T[e+908+(t[976+(n<<2)>>2]<<2)>>2]),r>=w(0)&((Le(r)|0)^1)|0}function mt(e){e=e|0;var n=Tt,r=0,u=0,l=0,s=0,h=0,D=0,S=Tt;if(r=t[e+968>>2]|0,r)S=w(T[e+908>>2]),n=w(T[e+912>>2]),n=w($8[r&0](e,S,n)),qu(e,(Le(n)|0)^1,3573);else{s=Su(e)|0;do if(s|0){for(r=0,l=0;;){if(u=Ti(e,l)|0,t[u+940>>2]|0){h=8;break}if((t[u+24>>2]|0)!=1)if(D=(e0(e,u)|0)==5,D){r=u;break}else r=(r|0)==0?u:r;if(l=l+1|0,l>>>0>=s>>>0){h=8;break}}if((h|0)==8&&!r)break;return n=w(mt(r)),w(n+w(T[r+404>>2]))}while(0);n=w(T[e+912>>2])}return w(n)}function Jt(e,n,r,u){e=e|0,n=n|0,r=w(r),u=w(u);var l=Tt,s=0;return _n(n)|0?(n=1,s=3):Hi(n)|0?(n=0,s=3):(u=w(ie),l=w(ie)),(s|0)==3&&(l=w(An(e+364+(n<<3)|0,u)),u=w(An(e+380+(n<<3)|0,u))),s=u=w(0)&((Le(u)|0)^1)),r=s?u:r,s=l>=w(0)&((Le(l)|0)^1)&r>2]|0,s)|0,Se=_f(Ze,s)|0,ge=Hi(Ze)|0,I=w(Kt(n,2,r)),K=w(Kt(n,0,r)),Wu(n,2,r)|0?D=w(I+w(An(t[n+992>>2]|0,r))):(ae(n,2)|0?Bt(n,2)|0:0)?(D=w(T[e+908>>2]),S=w(O0(e,2)),S=w(D-w(S+w(vo(e,2)))),D=w(re(n,2,r)),D=w(Kn(n,2,w(S-w(D+w(Pi(n,2,r)))),r,r))):D=w(ie),Wu(n,0,l)|0?S=w(K+w(An(t[n+996>>2]|0,l))):(ae(n,0)|0?Bt(n,0)|0:0)?(S=w(T[e+912>>2]),ct=w(O0(e,0)),ct=w(S-w(ct+w(vo(e,0)))),S=w(re(n,0,l)),S=w(Kn(n,0,w(ct-w(S+w(Pi(n,0,l)))),l,r))):S=w(ie),L=Le(D)|0,k=Le(S)|0;do if(L^k?(be=w(T[n+396>>2]),!(Le(be)|0)):0)if(L){D=w(I+w(w(S-K)*be));break}else{ct=w(K+w(w(D-I)/be)),S=k?ct:S;break}while(0);k=Le(D)|0,L=Le(S)|0,k|L&&(Me=(k^1)&1,u=r>w(0)&((u|0)!=0&k),D=ge?D:u?r:D,Yt(n,D,S,s,ge?Me:u?2:Me,k&(L^1)&1,D,S,0,3623,h)|0,D=w(T[n+908>>2]),D=w(D+w(Kt(n,2,r))),S=w(T[n+912>>2]),S=w(S+w(Kt(n,0,r)))),Yt(n,D,S,s,1,1,D,S,1,3635,h)|0,(Bt(n,Ze)|0?!(ae(n,Ze)|0):0)?(Me=t[976+(Ze<<2)>>2]|0,ct=w(T[e+908+(Me<<2)>>2]),ct=w(ct-w(T[n+908+(Me<<2)>>2])),ct=w(ct-w(vo(e,Ze))),ct=w(ct-w(R0(n,Ze,r))),ct=w(ct-w(Pi(n,Ze,ge?r:l))),T[n+400+(t[1040+(Ze<<2)>>2]<<2)>>2]=ct):Ge=21;do if((Ge|0)==21){if(ae(n,Ze)|0?0:(t[e+8>>2]|0)==1){Me=t[976+(Ze<<2)>>2]|0,ct=w(T[e+908+(Me<<2)>>2]),ct=w(w(ct-w(T[n+908+(Me<<2)>>2]))*w(.5)),T[n+400+(t[1040+(Ze<<2)>>2]<<2)>>2]=ct;break}(ae(n,Ze)|0?0:(t[e+8>>2]|0)==2)&&(Me=t[976+(Ze<<2)>>2]|0,ct=w(T[e+908+(Me<<2)>>2]),ct=w(ct-w(T[n+908+(Me<<2)>>2])),T[n+400+(t[1040+(Ze<<2)>>2]<<2)>>2]=ct)}while(0);(Bt(n,Se)|0?!(ae(n,Se)|0):0)?(Me=t[976+(Se<<2)>>2]|0,ct=w(T[e+908+(Me<<2)>>2]),ct=w(ct-w(T[n+908+(Me<<2)>>2])),ct=w(ct-w(vo(e,Se))),ct=w(ct-w(R0(n,Se,r))),ct=w(ct-w(Pi(n,Se,ge?l:r))),T[n+400+(t[1040+(Se<<2)>>2]<<2)>>2]=ct):Ge=30;do if((Ge|0)==30?!(ae(n,Se)|0):0){if((e0(e,n)|0)==2){Me=t[976+(Se<<2)>>2]|0,ct=w(T[e+908+(Me<<2)>>2]),ct=w(w(ct-w(T[n+908+(Me<<2)>>2]))*w(.5)),T[n+400+(t[1040+(Se<<2)>>2]<<2)>>2]=ct;break}Me=(e0(e,n)|0)==3,Me^(t[e+28>>2]|0)==2&&(Me=t[976+(Se<<2)>>2]|0,ct=w(T[e+908+(Me<<2)>>2]),ct=w(ct-w(T[n+908+(Me<<2)>>2])),T[n+400+(t[1040+(Se<<2)>>2]<<2)>>2]=ct)}while(0)}function Sn(e,n,r){e=e|0,n=n|0,r=r|0;var u=Tt,l=0;l=t[976+(r<<2)>>2]|0,u=w(T[n+908+(l<<2)>>2]),u=w(w(T[e+908+(l<<2)>>2])-u),u=w(u-w(T[n+400+(t[1040+(r<<2)>>2]<<2)>>2])),T[n+400+(t[1e3+(r<<2)>>2]<<2)>>2]=u}function _n(e){return e=e|0,(e|1|0)==1|0}function Tn(e){e=e|0;var n=Tt;switch(t[e+56>>2]|0){case 0:case 3:{n=w(T[e+40>>2]),n>w(0)&((Le(n)|0)^1)?e=c[(t[e+976>>2]|0)+2>>0]|0?1056:992:e=1056;break}default:e=e+52|0}return e|0}function ir(e,n){return e=e|0,n=n|0,(c[e+n>>0]|0)!=0|0}function Bt(e,n){return e=e|0,n=n|0,e=e+132|0,(Hi(n)|0?(t[(pt(e,5,948)|0)+4>>2]|0)!=0:0)?e=1:e=(t[(pt(e,t[1e3+(n<<2)>>2]|0,948)|0)+4>>2]|0)!=0,e|0}function Pi(e,n,r){e=e|0,n=n|0,r=w(r);var u=0,l=0;return e=e+132|0,(Hi(n)|0?(u=pt(e,5,948)|0,(t[u+4>>2]|0)!=0):0)?l=4:(u=pt(e,t[1e3+(n<<2)>>2]|0,948)|0,t[u+4>>2]|0?l=4:r=w(0)),(l|0)==4&&(r=w(An(u,r))),w(r)}function Rr(e,n,r){return e=e|0,n=n|0,r=w(r),ae(e,n)|0?r=w(re(e,n,r)):r=w(-w(Pi(e,n,r))),w(r)}function mr(e){return e=w(e),T[q>>2]=e,t[q>>2]|0|0}function Y(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>1073741823)$n();else{l=pn(n<<2)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<2)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<2)}function ri(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>2)<<2)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function ii(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-4-n|0)>>>2)<<2)),e=t[e>>2]|0,e|0&&yt(e)}function Vr(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;if(h=e+4|0,D=t[h>>2]|0,l=D-u|0,s=l>>2,e=n+(s<<2)|0,e>>>0>>0){u=D;do t[u>>2]=t[e>>2],e=e+4|0,u=(t[h>>2]|0)+4|0,t[h>>2]=u;while(e>>>0>>0)}s|0&&kg(D+(0-s<<2)|0,n|0,l|0)|0}function ft(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0;return D=n+4|0,S=t[D>>2]|0,l=t[e>>2]|0,h=r,s=h-l|0,u=S+(0-(s>>2)<<2)|0,t[D>>2]=u,(s|0)>0&&_r(u|0,l|0,s|0)|0,l=e+4|0,s=n+8|0,u=(t[l>>2]|0)-h|0,(u|0)>0&&(_r(t[s>>2]|0,r|0,u|0)|0,t[s>>2]=(t[s>>2]|0)+(u>>>2<<2)),h=t[e>>2]|0,t[e>>2]=t[D>>2],t[D>>2]=h,h=t[l>>2]|0,t[l>>2]=t[s>>2],t[s>>2]=h,h=e+8|0,r=n+12|0,e=t[h>>2]|0,t[h>>2]=t[r>>2],t[r>>2]=e,t[n>>2]=t[D>>2],S|0}function Di(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;if(h=t[n>>2]|0,s=t[r>>2]|0,(h|0)!=(s|0)){l=e+8|0,r=((s+-4-h|0)>>>2)+1|0,e=h,u=t[l>>2]|0;do t[u>>2]=t[e>>2],u=(t[l>>2]|0)+4|0,t[l>>2]=u,e=e+4|0;while((e|0)!=(s|0));t[n>>2]=h+(r<<2)}}function ru(){we()}function D0(){var e=0;return e=pn(4)|0,Un(e),e|0}function Un(e){e=e|0,t[e>>2]=m0()|0}function t0(e){e=e|0,e|0&&(ro(e),yt(e))}function ro(e){e=e|0,J0(t[e>>2]|0)}function mo(e,n,r){e=e|0,n=n|0,r=r|0,Vu(t[e>>2]|0,n,r)}function n0(e,n){e=e|0,n=w(n),Ju(t[e>>2]|0,n)}function jo(e,n){return e=e|0,n=n|0,ir(t[e>>2]|0,n)|0}function io(){var e=0;return e=pn(8)|0,Ua(e,0),e|0}function Ua(e,n){e=e|0,n=n|0,n?n=Yn(t[n>>2]|0)|0:n=cr()|0,t[e>>2]=n,t[e+4>>2]=0,Ba(n,e)}function Ef(e){e=e|0;var n=0;return n=pn(8)|0,Ua(n,e),n|0}function cc(e){e=e|0,e|0&&(ws(e),yt(e))}function ws(e){e=e|0;var n=0;zu(t[e>>2]|0),n=e+4|0,e=t[n>>2]|0,t[n>>2]=0,e|0&&(ca(e),yt(e))}function ca(e){e=e|0,U0(e)}function U0(e){e=e|0,e=t[e>>2]|0,e|0&&qr(e|0)}function dc(e){return e=e|0,Us(e)|0}function ja(e){e=e|0;var n=0,r=0;r=e+4|0,n=t[r>>2]|0,t[r>>2]=0,n|0&&(ca(n),yt(n)),po(t[e>>2]|0)}function D2(e,n){e=e|0,n=n|0,la(t[e>>2]|0,t[n>>2]|0)}function rd(e,n){e=e|0,n=n|0,Z(t[e>>2]|0,n)}function id(e,n,r){e=e|0,n=n|0,r=+r,dr(t[e>>2]|0,n,w(r))}function go(e,n,r){e=e|0,n=n|0,r=+r,er(t[e>>2]|0,n,w(r))}function qc(e,n){e=e|0,n=n|0,z(t[e>>2]|0,n)}function Al(e,n){e=e|0,n=n|0,$(t[e>>2]|0,n)}function ul(e,n){e=e|0,n=n|0,ye(t[e>>2]|0,n)}function w2(e,n){e=e|0,n=n|0,g0(t[e>>2]|0,n)}function Ws(e,n){e=e|0,n=n|0,Je(t[e>>2]|0,n)}function Rl(e,n){e=e|0,n=n|0,ji(t[e>>2]|0,n)}function ud(e,n,r){e=e|0,n=n|0,r=+r,Rn(t[e>>2]|0,n,w(r))}function zo(e,n,r){e=e|0,n=n|0,r=+r,Lr(t[e>>2]|0,n,w(r))}function za(e,n){e=e|0,n=n|0,Nr(t[e>>2]|0,n)}function Ha(e,n){e=e|0,n=n|0,ue(t[e>>2]|0,n)}function qa(e,n){e=e|0,n=n|0,nt(t[e>>2]|0,n)}function da(e,n){e=e|0,n=+n,Mt(t[e>>2]|0,w(n))}function Ss(e,n){e=e|0,n=+n,rn(t[e>>2]|0,w(n))}function Ts(e,n){e=e|0,n=+n,Nt(t[e>>2]|0,w(n))}function ns(e,n){e=e|0,n=+n,Pt(t[e>>2]|0,w(n))}function Ho(e,n){e=e|0,n=+n,sn(t[e>>2]|0,w(n))}function Df(e,n){e=e|0,n=+n,fn(t[e>>2]|0,w(n))}function ol(e,n){e=e|0,n=+n,Jn(t[e>>2]|0,w(n))}function Gu(e){e=e|0,Sr(t[e>>2]|0)}function Wa(e,n){e=e|0,n=+n,Lu(t[e>>2]|0,w(n))}function r0(e,n){e=e|0,n=+n,T0(t[e>>2]|0,w(n))}function j0(e){e=e|0,Z0(t[e>>2]|0)}function wf(e,n){e=e|0,n=+n,_i(t[e>>2]|0,w(n))}function Wc(e,n){e=e|0,n=+n,Po(t[e>>2]|0,w(n))}function pc(e,n){e=e|0,n=+n,vf(t[e>>2]|0,w(n))}function Ol(e,n){e=e|0,n=+n,Tl(t[e>>2]|0,w(n))}function Cs(e,n){e=e|0,n=+n,Io(t[e>>2]|0,w(n))}function pa(e,n){e=e|0,n=+n,ys(t[e>>2]|0,w(n))}function od(e,n){e=e|0,n=+n,bo(t[e>>2]|0,w(n))}function ha(e,n){e=e|0,n=+n,Bo(t[e>>2]|0,w(n))}function hc(e,n){e=e|0,n=+n,Qu(t[e>>2]|0,w(n))}function Vc(e,n,r){e=e|0,n=n|0,r=+r,Ft(t[e>>2]|0,n,w(r))}function qi(e,n,r){e=e|0,n=n|0,r=+r,it(t[e>>2]|0,n,w(r))}function y(e,n,r){e=e|0,n=n|0,r=+r,Et(t[e>>2]|0,n,w(r))}function g(e){return e=e|0,ke(t[e>>2]|0)|0}function A(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;u=m,m=m+16|0,l=u,Cr(l,t[n>>2]|0,r),F(e,l),m=u}function F(e,n){e=e|0,n=n|0,b(e,t[n+4>>2]|0,+w(T[n>>2]))}function b(e,n,r){e=e|0,n=n|0,r=+r,t[e>>2]=n,B[e+8>>3]=r}function J(e){return e=e|0,G(t[e>>2]|0)|0}function pe(e){return e=e|0,Te(t[e>>2]|0)|0}function gt(e){return e=e|0,Ae(t[e>>2]|0)|0}function xt(e){return e=e|0,js(t[e>>2]|0)|0}function kt(e){return e=e|0,vt(t[e>>2]|0)|0}function xr(e){return e=e|0,U(t[e>>2]|0)|0}function i0(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;u=m,m=m+16|0,l=u,y0(l,t[n>>2]|0,r),F(e,l),m=u}function du(e){return e=e|0,qe(t[e>>2]|0)|0}function z0(e){return e=e|0,Ct(t[e>>2]|0)|0}function Ml(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,Dn(u,t[n>>2]|0),F(e,u),m=r}function u0(e){return e=e|0,+ +w(hf(t[e>>2]|0))}function We(e){return e=e|0,+ +w(Bs(t[e>>2]|0))}function ze(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,fu(u,t[n>>2]|0),F(e,u),m=r}function lt(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,Nu(u,t[n>>2]|0),F(e,u),m=r}function $t(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,rl(u,t[n>>2]|0),F(e,u),m=r}function Wn(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,mf(u,t[n>>2]|0),F(e,u),m=r}function si(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,zs(u,t[n>>2]|0),F(e,u),m=r}function ur(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,_s(u,t[n>>2]|0),F(e,u),m=r}function ci(e){return e=e|0,+ +w(Tu(t[e>>2]|0))}function Qi(e,n){return e=e|0,n=n|0,+ +w(un(t[e>>2]|0,n))}function Gr(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;u=m,m=m+16|0,l=u,et(l,t[n>>2]|0,r),F(e,l),m=u}function Cu(e,n,r){e=e|0,n=n|0,r=r|0,ba(t[e>>2]|0,t[n>>2]|0,r)}function Va(e,n){e=e|0,n=n|0,ku(t[e>>2]|0,t[n>>2]|0)}function Ga(e){return e=e|0,Su(t[e>>2]|0)|0}function ld(e){return e=e|0,e=fi(t[e>>2]|0)|0,e?e=dc(e)|0:e=0,e|0}function S2(e,n){return e=e|0,n=n|0,e=Ti(t[e>>2]|0,n)|0,e?e=dc(e)|0:e=0,e|0}function T2(e,n){e=e|0,n=n|0;var r=0,u=0;u=pn(4)|0,Sf(u,n),r=e+4|0,n=t[r>>2]|0,t[r>>2]=u,n|0&&(ca(n),yt(n)),oa(t[e>>2]|0,1)}function Sf(e,n){e=e|0,n=n|0,sl(e,n)}function sd(e,n,r,u,l,s){e=e|0,n=n|0,r=w(r),u=u|0,l=w(l),s=s|0;var h=0,D=0;h=m,m=m+16|0,D=h,hh(D,Us(n)|0,+r,u,+l,s),T[e>>2]=w(+B[D>>3]),T[e+4>>2]=w(+B[D+8>>3]),m=h}function hh(e,n,r,u,l,s){e=e|0,n=n|0,r=+r,u=u|0,l=+l,s=s|0;var h=0,D=0,S=0,L=0,k=0;h=m,m=m+32|0,k=h+8|0,L=h+20|0,S=h,D=h+16|0,B[k>>3]=r,t[L>>2]=u,B[S>>3]=l,t[D>>2]=s,Gc(e,t[n+4>>2]|0,k,L,S,D),m=h}function Gc(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0;var h=0,D=0;h=m,m=m+16|0,D=h,ka(D),n=yo(n)|0,vh(e,n,+B[r>>3],t[u>>2]|0,+B[l>>3],t[s>>2]|0),La(D),m=h}function yo(e){return e=e|0,t[e>>2]|0}function vh(e,n,r,u,l,s){e=e|0,n=n|0,r=+r,u=u|0,l=+l,s=s|0;var h=0;h=_o(mh()|0)|0,r=+kl(r),u=ad(u)|0,l=+kl(l),fd(e,Qr(0,h|0,n|0,+r,u|0,+l,ad(s)|0)|0)}function mh(){var e=0;return c[7608]|0||(Kc(9120),e=7608,t[e>>2]=1,t[e+4>>2]=0),9120}function _o(e){return e=e|0,t[e+8>>2]|0}function kl(e){return e=+e,+ +Ya(e)}function ad(e){return e=e|0,dd(e)|0}function fd(e,n){e=e|0,n=n|0;var r=0,u=0,l=0;l=m,m=m+32|0,r=l,u=n,u&1?(C2(r,0),eu(u|0,r|0)|0,Yc(e,r),Ir(r)):(t[e>>2]=t[n>>2],t[e+4>>2]=t[n+4>>2],t[e+8>>2]=t[n+8>>2],t[e+12>>2]=t[n+12>>2]),m=l}function C2(e,n){e=e|0,n=n|0,cd(e,n),t[e+8>>2]=0,c[e+24>>0]=0}function Yc(e,n){e=e|0,n=n|0,n=n+8|0,t[e>>2]=t[n>>2],t[e+4>>2]=t[n+4>>2],t[e+8>>2]=t[n+8>>2],t[e+12>>2]=t[n+12>>2]}function Ir(e){e=e|0,c[e+24>>0]=0}function cd(e,n){e=e|0,n=n|0,t[e>>2]=n}function dd(e){return e=e|0,e|0}function Ya(e){return e=+e,+e}function Kc(e){e=e|0,ll(e,x2()|0,4)}function x2(){return 1064}function ll(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r,t[e+8>>2]=bt(n|0,r+1|0)|0}function sl(e,n){e=e|0,n=n|0,n=t[n>>2]|0,t[e>>2]=n,Ri(n|0)}function gh(e){e=e|0;var n=0,r=0;r=e+4|0,n=t[r>>2]|0,t[r>>2]=0,n|0&&(ca(n),yt(n)),oa(t[e>>2]|0,0)}function Tf(e){e=e|0,$r(t[e>>2]|0)}function Xc(e){return e=e|0,$l(t[e>>2]|0)|0}function A2(e,n,r,u){e=e|0,n=+n,r=+r,u=u|0,ti(t[e>>2]|0,w(n),w(r),u)}function yh(e){return e=e|0,+ +w(Ei(t[e>>2]|0))}function al(e){return e=e|0,+ +w($0(t[e>>2]|0))}function va(e){return e=e|0,+ +w(C0(t[e>>2]|0))}function R2(e){return e=e|0,+ +w(Uo(t[e>>2]|0))}function O2(e){return e=e|0,+ +w(sa(t[e>>2]|0))}function vc(e){return e=e|0,+ +w(es(t[e>>2]|0))}function _h(e,n){e=e|0,n=n|0,B[e>>3]=+w(Ei(t[n>>2]|0)),B[e+8>>3]=+w($0(t[n>>2]|0)),B[e+16>>3]=+w(C0(t[n>>2]|0)),B[e+24>>3]=+w(Uo(t[n>>2]|0)),B[e+32>>3]=+w(sa(t[n>>2]|0)),B[e+40>>3]=+w(es(t[n>>2]|0))}function M2(e,n){return e=e|0,n=n|0,+ +w(tu(t[e>>2]|0,n))}function pd(e,n){return e=e|0,n=n|0,+ +w(ei(t[e>>2]|0,n))}function Qc(e,n){return e=e|0,n=n|0,+ +w(ho(t[e>>2]|0,n))}function Jc(){return Ia()|0}function Vs(){k2(),ma(),Zc(),mc(),gc(),hd()}function k2(){PO(11713,4938,1)}function ma(){eO(10448)}function Zc(){P7(10408)}function mc(){i7(10324)}function gc(){_E(10096)}function hd(){Eh(9132)}function Eh(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0,Ze=0,Ge=0,ct=0,Me=0,Pe=0,Zt=0,Br=0,In=0,yn=0,Er=0,Pr=0,Ln=0,uu=0,ls=0,ss=0,as=0,ta=0,r2=0,i2=0,of=0,u2=0,Pc=0,Ic=0,o2=0,l2=0,s2=0,vi=0,lf=0,a2=0,Kf=0,f2=0,c2=0,bc=0,Bc=0,Xf=0,ql=0,Fa=0,Ns=0,sf=0,b1=0,B1=0,Uc=0,U1=0,j1=0,Wl=0,El=0,af=0,vu=0,z1=0,fs=0,Qf=0,cs=0,Jf=0,H1=0,q1=0,Zf=0,Vl=0,ff=0,W1=0,V1=0,G1=0,Tr=0,Bu=0,Dl=0,ds=0,Gl=0,Or=0,Bn=0,cf=0;n=m,m=m+672|0,r=n+656|0,cf=n+648|0,Bn=n+640|0,Or=n+632|0,Gl=n+624|0,ds=n+616|0,Dl=n+608|0,Bu=n+600|0,Tr=n+592|0,G1=n+584|0,V1=n+576|0,W1=n+568|0,ff=n+560|0,Vl=n+552|0,Zf=n+544|0,q1=n+536|0,H1=n+528|0,Jf=n+520|0,cs=n+512|0,Qf=n+504|0,fs=n+496|0,z1=n+488|0,vu=n+480|0,af=n+472|0,El=n+464|0,Wl=n+456|0,j1=n+448|0,U1=n+440|0,Uc=n+432|0,B1=n+424|0,b1=n+416|0,sf=n+408|0,Ns=n+400|0,Fa=n+392|0,ql=n+384|0,Xf=n+376|0,Bc=n+368|0,bc=n+360|0,c2=n+352|0,f2=n+344|0,Kf=n+336|0,a2=n+328|0,lf=n+320|0,vi=n+312|0,s2=n+304|0,l2=n+296|0,o2=n+288|0,Ic=n+280|0,Pc=n+272|0,u2=n+264|0,of=n+256|0,i2=n+248|0,r2=n+240|0,ta=n+232|0,as=n+224|0,ss=n+216|0,ls=n+208|0,uu=n+200|0,Ln=n+192|0,Pr=n+184|0,Er=n+176|0,yn=n+168|0,In=n+160|0,Br=n+152|0,Zt=n+144|0,Pe=n+136|0,Me=n+128|0,ct=n+120|0,Ge=n+112|0,Ze=n+104|0,ge=n+96|0,Se=n+88|0,be=n+80|0,K=n+72|0,I=n+64|0,k=n+56|0,L=n+48|0,S=n+40|0,D=n+32|0,h=n+24|0,s=n+16|0,l=n+8|0,u=n,Cf(e,3646),$c(e,3651,2)|0,Dh(e,3665,2)|0,am(e,3682,18)|0,t[cf>>2]=19,t[cf+4>>2]=0,t[r>>2]=t[cf>>2],t[r+4>>2]=t[cf+4>>2],Gs(e,3690,r)|0,t[Bn>>2]=1,t[Bn+4>>2]=0,t[r>>2]=t[Bn>>2],t[r+4>>2]=t[Bn+4>>2],ga(e,3696,r)|0,t[Or>>2]=2,t[Or+4>>2]=0,t[r>>2]=t[Or>>2],t[r+4>>2]=t[Or+4>>2],iu(e,3706,r)|0,t[Gl>>2]=1,t[Gl+4>>2]=0,t[r>>2]=t[Gl>>2],t[r+4>>2]=t[Gl+4>>2],M0(e,3722,r)|0,t[ds>>2]=2,t[ds+4>>2]=0,t[r>>2]=t[ds>>2],t[r+4>>2]=t[ds+4>>2],M0(e,3734,r)|0,t[Dl>>2]=3,t[Dl+4>>2]=0,t[r>>2]=t[Dl>>2],t[r+4>>2]=t[Dl+4>>2],iu(e,3753,r)|0,t[Bu>>2]=4,t[Bu+4>>2]=0,t[r>>2]=t[Bu>>2],t[r+4>>2]=t[Bu+4>>2],iu(e,3769,r)|0,t[Tr>>2]=5,t[Tr+4>>2]=0,t[r>>2]=t[Tr>>2],t[r+4>>2]=t[Tr+4>>2],iu(e,3783,r)|0,t[G1>>2]=6,t[G1+4>>2]=0,t[r>>2]=t[G1>>2],t[r+4>>2]=t[G1+4>>2],iu(e,3796,r)|0,t[V1>>2]=7,t[V1+4>>2]=0,t[r>>2]=t[V1>>2],t[r+4>>2]=t[V1+4>>2],iu(e,3813,r)|0,t[W1>>2]=8,t[W1+4>>2]=0,t[r>>2]=t[W1>>2],t[r+4>>2]=t[W1+4>>2],iu(e,3825,r)|0,t[ff>>2]=3,t[ff+4>>2]=0,t[r>>2]=t[ff>>2],t[r+4>>2]=t[ff+4>>2],M0(e,3843,r)|0,t[Vl>>2]=4,t[Vl+4>>2]=0,t[r>>2]=t[Vl>>2],t[r+4>>2]=t[Vl+4>>2],M0(e,3853,r)|0,t[Zf>>2]=9,t[Zf+4>>2]=0,t[r>>2]=t[Zf>>2],t[r+4>>2]=t[Zf+4>>2],iu(e,3870,r)|0,t[q1>>2]=10,t[q1+4>>2]=0,t[r>>2]=t[q1>>2],t[r+4>>2]=t[q1+4>>2],iu(e,3884,r)|0,t[H1>>2]=11,t[H1+4>>2]=0,t[r>>2]=t[H1>>2],t[r+4>>2]=t[H1+4>>2],iu(e,3896,r)|0,t[Jf>>2]=1,t[Jf+4>>2]=0,t[r>>2]=t[Jf>>2],t[r+4>>2]=t[Jf+4>>2],o0(e,3907,r)|0,t[cs>>2]=2,t[cs+4>>2]=0,t[r>>2]=t[cs>>2],t[r+4>>2]=t[cs+4>>2],o0(e,3915,r)|0,t[Qf>>2]=3,t[Qf+4>>2]=0,t[r>>2]=t[Qf>>2],t[r+4>>2]=t[Qf+4>>2],o0(e,3928,r)|0,t[fs>>2]=4,t[fs+4>>2]=0,t[r>>2]=t[fs>>2],t[r+4>>2]=t[fs+4>>2],o0(e,3948,r)|0,t[z1>>2]=5,t[z1+4>>2]=0,t[r>>2]=t[z1>>2],t[r+4>>2]=t[z1+4>>2],o0(e,3960,r)|0,t[vu>>2]=6,t[vu+4>>2]=0,t[r>>2]=t[vu>>2],t[r+4>>2]=t[vu+4>>2],o0(e,3974,r)|0,t[af>>2]=7,t[af+4>>2]=0,t[r>>2]=t[af>>2],t[r+4>>2]=t[af+4>>2],o0(e,3983,r)|0,t[El>>2]=20,t[El+4>>2]=0,t[r>>2]=t[El>>2],t[r+4>>2]=t[El+4>>2],Gs(e,3999,r)|0,t[Wl>>2]=8,t[Wl+4>>2]=0,t[r>>2]=t[Wl>>2],t[r+4>>2]=t[Wl+4>>2],o0(e,4012,r)|0,t[j1>>2]=9,t[j1+4>>2]=0,t[r>>2]=t[j1>>2],t[r+4>>2]=t[j1+4>>2],o0(e,4022,r)|0,t[U1>>2]=21,t[U1+4>>2]=0,t[r>>2]=t[U1>>2],t[r+4>>2]=t[U1+4>>2],Gs(e,4039,r)|0,t[Uc>>2]=10,t[Uc+4>>2]=0,t[r>>2]=t[Uc>>2],t[r+4>>2]=t[Uc+4>>2],o0(e,4053,r)|0,t[B1>>2]=11,t[B1+4>>2]=0,t[r>>2]=t[B1>>2],t[r+4>>2]=t[B1+4>>2],o0(e,4065,r)|0,t[b1>>2]=12,t[b1+4>>2]=0,t[r>>2]=t[b1>>2],t[r+4>>2]=t[b1+4>>2],o0(e,4084,r)|0,t[sf>>2]=13,t[sf+4>>2]=0,t[r>>2]=t[sf>>2],t[r+4>>2]=t[sf+4>>2],o0(e,4097,r)|0,t[Ns>>2]=14,t[Ns+4>>2]=0,t[r>>2]=t[Ns>>2],t[r+4>>2]=t[Ns+4>>2],o0(e,4117,r)|0,t[Fa>>2]=15,t[Fa+4>>2]=0,t[r>>2]=t[Fa>>2],t[r+4>>2]=t[Fa+4>>2],o0(e,4129,r)|0,t[ql>>2]=16,t[ql+4>>2]=0,t[r>>2]=t[ql>>2],t[r+4>>2]=t[ql+4>>2],o0(e,4148,r)|0,t[Xf>>2]=17,t[Xf+4>>2]=0,t[r>>2]=t[Xf>>2],t[r+4>>2]=t[Xf+4>>2],o0(e,4161,r)|0,t[Bc>>2]=18,t[Bc+4>>2]=0,t[r>>2]=t[Bc>>2],t[r+4>>2]=t[Bc+4>>2],o0(e,4181,r)|0,t[bc>>2]=5,t[bc+4>>2]=0,t[r>>2]=t[bc>>2],t[r+4>>2]=t[bc+4>>2],M0(e,4196,r)|0,t[c2>>2]=6,t[c2+4>>2]=0,t[r>>2]=t[c2>>2],t[r+4>>2]=t[c2+4>>2],M0(e,4206,r)|0,t[f2>>2]=7,t[f2+4>>2]=0,t[r>>2]=t[f2>>2],t[r+4>>2]=t[f2+4>>2],M0(e,4217,r)|0,t[Kf>>2]=3,t[Kf+4>>2]=0,t[r>>2]=t[Kf>>2],t[r+4>>2]=t[Kf+4>>2],rs(e,4235,r)|0,t[a2>>2]=1,t[a2+4>>2]=0,t[r>>2]=t[a2>>2],t[r+4>>2]=t[a2+4>>2],Ka(e,4251,r)|0,t[lf>>2]=4,t[lf+4>>2]=0,t[r>>2]=t[lf>>2],t[r+4>>2]=t[lf+4>>2],rs(e,4263,r)|0,t[vi>>2]=5,t[vi+4>>2]=0,t[r>>2]=t[vi>>2],t[r+4>>2]=t[vi+4>>2],rs(e,4279,r)|0,t[s2>>2]=6,t[s2+4>>2]=0,t[r>>2]=t[s2>>2],t[r+4>>2]=t[s2+4>>2],rs(e,4293,r)|0,t[l2>>2]=7,t[l2+4>>2]=0,t[r>>2]=t[l2>>2],t[r+4>>2]=t[l2+4>>2],rs(e,4306,r)|0,t[o2>>2]=8,t[o2+4>>2]=0,t[r>>2]=t[o2>>2],t[r+4>>2]=t[o2+4>>2],rs(e,4323,r)|0,t[Ic>>2]=9,t[Ic+4>>2]=0,t[r>>2]=t[Ic>>2],t[r+4>>2]=t[Ic+4>>2],rs(e,4335,r)|0,t[Pc>>2]=2,t[Pc+4>>2]=0,t[r>>2]=t[Pc>>2],t[r+4>>2]=t[Pc+4>>2],Ka(e,4353,r)|0,t[u2>>2]=12,t[u2+4>>2]=0,t[r>>2]=t[u2>>2],t[r+4>>2]=t[u2+4>>2],uo(e,4363,r)|0,t[of>>2]=1,t[of+4>>2]=0,t[r>>2]=t[of>>2],t[r+4>>2]=t[of+4>>2],fl(e,4376,r)|0,t[i2>>2]=2,t[i2+4>>2]=0,t[r>>2]=t[i2>>2],t[r+4>>2]=t[i2+4>>2],fl(e,4388,r)|0,t[r2>>2]=13,t[r2+4>>2]=0,t[r>>2]=t[r2>>2],t[r+4>>2]=t[r2+4>>2],uo(e,4402,r)|0,t[ta>>2]=14,t[ta+4>>2]=0,t[r>>2]=t[ta>>2],t[r+4>>2]=t[ta+4>>2],uo(e,4411,r)|0,t[as>>2]=15,t[as+4>>2]=0,t[r>>2]=t[as>>2],t[r+4>>2]=t[as+4>>2],uo(e,4421,r)|0,t[ss>>2]=16,t[ss+4>>2]=0,t[r>>2]=t[ss>>2],t[r+4>>2]=t[ss+4>>2],uo(e,4433,r)|0,t[ls>>2]=17,t[ls+4>>2]=0,t[r>>2]=t[ls>>2],t[r+4>>2]=t[ls+4>>2],uo(e,4446,r)|0,t[uu>>2]=18,t[uu+4>>2]=0,t[r>>2]=t[uu>>2],t[r+4>>2]=t[uu+4>>2],uo(e,4458,r)|0,t[Ln>>2]=3,t[Ln+4>>2]=0,t[r>>2]=t[Ln>>2],t[r+4>>2]=t[Ln+4>>2],fl(e,4471,r)|0,t[Pr>>2]=1,t[Pr+4>>2]=0,t[r>>2]=t[Pr>>2],t[r+4>>2]=t[Pr+4>>2],yc(e,4486,r)|0,t[Er>>2]=10,t[Er+4>>2]=0,t[r>>2]=t[Er>>2],t[r+4>>2]=t[Er+4>>2],rs(e,4496,r)|0,t[yn>>2]=11,t[yn+4>>2]=0,t[r>>2]=t[yn>>2],t[r+4>>2]=t[yn+4>>2],rs(e,4508,r)|0,t[In>>2]=3,t[In+4>>2]=0,t[r>>2]=t[In>>2],t[r+4>>2]=t[In+4>>2],Ka(e,4519,r)|0,t[Br>>2]=4,t[Br+4>>2]=0,t[r>>2]=t[Br>>2],t[r+4>>2]=t[Br+4>>2],L2(e,4530,r)|0,t[Zt>>2]=19,t[Zt+4>>2]=0,t[r>>2]=t[Zt>>2],t[r+4>>2]=t[Zt+4>>2],wh(e,4542,r)|0,t[Pe>>2]=12,t[Pe+4>>2]=0,t[r>>2]=t[Pe>>2],t[r+4>>2]=t[Pe+4>>2],xf(e,4554,r)|0,t[Me>>2]=13,t[Me+4>>2]=0,t[r>>2]=t[Me>>2],t[r+4>>2]=t[Me+4>>2],Af(e,4568,r)|0,t[ct>>2]=2,t[ct+4>>2]=0,t[r>>2]=t[ct>>2],t[r+4>>2]=t[ct+4>>2],e1(e,4578,r)|0,t[Ge>>2]=20,t[Ge+4>>2]=0,t[r>>2]=t[Ge>>2],t[r+4>>2]=t[Ge+4>>2],Ll(e,4587,r)|0,t[Ze>>2]=22,t[Ze+4>>2]=0,t[r>>2]=t[Ze>>2],t[r+4>>2]=t[Ze+4>>2],Gs(e,4602,r)|0,t[ge>>2]=23,t[ge+4>>2]=0,t[r>>2]=t[ge>>2],t[r+4>>2]=t[ge+4>>2],Gs(e,4619,r)|0,t[Se>>2]=14,t[Se+4>>2]=0,t[r>>2]=t[Se>>2],t[r+4>>2]=t[Se+4>>2],t1(e,4629,r)|0,t[be>>2]=1,t[be+4>>2]=0,t[r>>2]=t[be>>2],t[r+4>>2]=t[be+4>>2],ya(e,4637,r)|0,t[K>>2]=4,t[K+4>>2]=0,t[r>>2]=t[K>>2],t[r+4>>2]=t[K+4>>2],fl(e,4653,r)|0,t[I>>2]=5,t[I+4>>2]=0,t[r>>2]=t[I>>2],t[r+4>>2]=t[I+4>>2],fl(e,4669,r)|0,t[k>>2]=6,t[k+4>>2]=0,t[r>>2]=t[k>>2],t[r+4>>2]=t[k+4>>2],fl(e,4686,r)|0,t[L>>2]=7,t[L+4>>2]=0,t[r>>2]=t[L>>2],t[r+4>>2]=t[L+4>>2],fl(e,4701,r)|0,t[S>>2]=8,t[S+4>>2]=0,t[r>>2]=t[S>>2],t[r+4>>2]=t[S+4>>2],fl(e,4719,r)|0,t[D>>2]=9,t[D+4>>2]=0,t[r>>2]=t[D>>2],t[r+4>>2]=t[D+4>>2],fl(e,4736,r)|0,t[h>>2]=21,t[h+4>>2]=0,t[r>>2]=t[h>>2],t[r+4>>2]=t[h+4>>2],vd(e,4754,r)|0,t[s>>2]=2,t[s+4>>2]=0,t[r>>2]=t[s>>2],t[r+4>>2]=t[s+4>>2],yc(e,4772,r)|0,t[l>>2]=3,t[l+4>>2]=0,t[r>>2]=t[l>>2],t[r+4>>2]=t[l+4>>2],yc(e,4790,r)|0,t[u>>2]=4,t[u+4>>2]=0,t[r>>2]=t[u>>2],t[r+4>>2]=t[u+4>>2],yc(e,4808,r)|0,m=n}function Cf(e,n){e=e|0,n=n|0;var r=0;r=uf()|0,t[e>>2]=r,Vo(r,n),e2(t[e>>2]|0)}function $c(e,n,r){return e=e|0,n=n|0,r=r|0,Ot(e,Fr(n)|0,r,0),e|0}function Dh(e,n,r){return e=e|0,n=n|0,r=r|0,d(e,Fr(n)|0,r,0),e|0}function am(e,n,r){return e=e|0,n=n|0,r=r|0,pE(e,Fr(n)|0,r,0),e|0}function Gs(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],uE(e,n,l),m=u,e|0}function ga(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],zl(e,n,l),m=u,e|0}function iu(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],p(e,n,l),m=u,e|0}function M0(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Av(e,n,l),m=u,e|0}function o0(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],ng(e,n,l),m=u,e|0}function rs(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Kd(e,n,l),m=u,e|0}function Ka(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Yd(e,n,l),m=u,e|0}function uo(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],k0(e,n,l),m=u,e|0}function fl(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Sp(e,n,l),m=u,e|0}function yc(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],bm(e,n,l),m=u,e|0}function L2(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],l0(e,n,l),m=u,e|0}function wh(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Md(e,n,l),m=u,e|0}function xf(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Rm(e,n,l),m=u,e|0}function Af(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],tp(e,n,l),m=u,e|0}function e1(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],g1(e,n,l),m=u,e|0}function Ll(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],$a(e,n,l),m=u,e|0}function t1(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],j2(e,n,l),m=u,e|0}function ya(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],P2(e,n,l),m=u,e|0}function vd(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],md(e,n,l),m=u,e|0}function md(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Ea(e,r,l,1),m=u}function Fr(e){return e=e|0,e|0}function Ea(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=N2()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=n1(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,gd(s,u)|0,u),m=l}function N2(){var e=0,n=0;if(c[7616]|0||(cl(9136),Wt(24,9136,se|0)|0,n=7616,t[n>>2]=1,t[n+4>>2]=0),!(sr(9136)|0)){e=9136,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));cl(9136)}return 9136}function n1(e){return e=e|0,0}function gd(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=N2()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Rf(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Of(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function wi(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0;var h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0;h=m,m=m+32|0,K=h+24|0,I=h+20|0,S=h+16|0,k=h+12|0,L=h+8|0,D=h+4|0,be=h,t[I>>2]=n,t[S>>2]=r,t[k>>2]=u,t[L>>2]=l,t[D>>2]=s,s=e+28|0,t[be>>2]=t[s>>2],t[K>>2]=t[be>>2],F2(e+24|0,K,I,k,L,S,D)|0,t[s>>2]=t[t[s>>2]>>2],m=h}function F2(e,n,r,u,l,s,h){return e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,h=h|0,e=fm(n)|0,n=pn(24)|0,yd(n+4|0,t[r>>2]|0,t[u>>2]|0,t[l>>2]|0,t[s>>2]|0,t[h>>2]|0),t[n>>2]=t[e>>2],t[e>>2]=n,n|0}function fm(e){return e=e|0,t[e>>2]|0}function yd(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,t[e>>2]=n,t[e+4>>2]=r,t[e+8>>2]=u,t[e+12>>2]=l,t[e+16>>2]=s}function hn(e,n){return e=e|0,n=n|0,n|e|0}function Rf(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Of(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=cm(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Mf(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Rf(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Sh(e,D),dm(D),m=L;return}}function cm(e){return e=e|0,357913941}function Mf(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Sh(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function dm(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function cl(e){e=e|0,qo(e)}function r1(e){e=e|0,qn(e+24|0)}function sr(e){return e=e|0,t[e>>2]|0}function qn(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function qo(e){e=e|0;var n=0;n=yr()|0,jn(e,2,3,n,Vn()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function yr(){return 9228}function Vn(){return 1140}function dl(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0;return r=m,m=m+16|0,u=r+8|0,l=r,s=Eo(e)|0,e=t[s+4>>2]|0,t[l>>2]=t[s>>2],t[l+4>>2]=e,t[u>>2]=t[l>>2],t[u+4>>2]=t[l+4>>2],n=_c(n,u)|0,m=r,n|0}function jn(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,t[e>>2]=n,t[e+4>>2]=r,t[e+8>>2]=u,t[e+12>>2]=l,t[e+16>>2]=s}function Eo(e){return e=e|0,(t[(N2()|0)+24>>2]|0)+(e*12|0)|0}function _c(e,n){e=e|0,n=n|0;var r=0,u=0,l=0;return l=m,m=m+48|0,u=l,r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),I1[r&31](u,e),u=oo(u)|0,m=l,u|0}function oo(e){e=e|0;var n=0,r=0,u=0,l=0;return l=m,m=m+32|0,n=l+12|0,r=l,u=Iu(Xa()|0)|0,u?(is(n,u),kf(r,n),Ec(e,r),e=xs(n)|0):e=Dc(e)|0,m=l,e|0}function Xa(){var e=0;return c[7632]|0||(Nf(9184),Wt(25,9184,se|0)|0,e=7632,t[e>>2]=1,t[e+4>>2]=0),9184}function Iu(e){return e=e|0,t[e+36>>2]|0}function is(e,n){e=e|0,n=n|0,t[e>>2]=n,t[e+4>>2]=e,t[e+8>>2]=0}function kf(e,n){e=e|0,n=n|0,t[e>>2]=t[n>>2],t[e+4>>2]=t[n+4>>2],t[e+8>>2]=0}function Ec(e,n){e=e|0,n=n|0,lo(n,e,e+8|0,e+16|0,e+24|0,e+32|0,e+40|0)|0}function xs(e){return e=e|0,t[(t[e+4>>2]|0)+8>>2]|0}function Dc(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0,S=0;S=m,m=m+16|0,r=S+4|0,u=S,l=Ma(8)|0,s=l,h=pn(48)|0,D=h,n=D+48|0;do t[D>>2]=t[e>>2],D=D+4|0,e=e+4|0;while((D|0)<(n|0));return n=s+4|0,t[n>>2]=h,D=pn(8)|0,h=t[n>>2]|0,t[u>>2]=0,t[r>>2]=t[u>>2],Th(D,h,r),t[l>>2]=D,m=S,s|0}function Th(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=pn(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1092,t[r+12>>2]=n,t[e+4>>2]=r}function cn(e){e=e|0,Uv(e),yt(e)}function us(e){e=e|0,e=t[e+12>>2]|0,e|0&&yt(e)}function Do(e){e=e|0,yt(e)}function lo(e,n,r,u,l,s,h){return e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,h=h|0,s=Ji(t[e>>2]|0,n,r,u,l,s,h)|0,h=e+4|0,t[(t[h>>2]|0)+8>>2]=s,t[(t[h>>2]|0)+8>>2]|0}function Ji(e,n,r,u,l,s,h){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,h=h|0;var D=0,S=0;return D=m,m=m+16|0,S=D,ka(S),e=yo(e)|0,h=Yr(e,+B[n>>3],+B[r>>3],+B[u>>3],+B[l>>3],+B[s>>3],+B[h>>3])|0,La(S),m=D,h|0}function Yr(e,n,r,u,l,s,h){e=e|0,n=+n,r=+r,u=+u,l=+l,s=+s,h=+h;var D=0;return D=_o(Lf()|0)|0,n=+kl(n),r=+kl(r),u=+kl(u),l=+kl(l),s=+kl(s),p0(0,D|0,e|0,+n,+r,+u,+l,+s,+ +kl(h))|0}function Lf(){var e=0;return c[7624]|0||(pm(9172),e=7624,t[e>>2]=1,t[e+4>>2]=0),9172}function pm(e){e=e|0,ll(e,Nl()|0,6)}function Nl(){return 1112}function Nf(e){e=e|0,Qa(e)}function Ff(e){e=e|0,_d(e+24|0),Ed(e+16|0)}function _d(e){e=e|0,i1(e)}function Ed(e){e=e|0,wc(e)}function wc(e){e=e|0;var n=0,r=0;if(n=t[e>>2]|0,n|0)do r=n,n=t[n>>2]|0,yt(r);while((n|0)!=0);t[e>>2]=0}function i1(e){e=e|0;var n=0,r=0;if(n=t[e>>2]|0,n|0)do r=n,n=t[n>>2]|0,yt(r);while((n|0)!=0);t[e>>2]=0}function Qa(e){e=e|0;var n=0;t[e+16>>2]=0,t[e+20>>2]=0,n=e+24|0,t[n>>2]=0,t[e+28>>2]=n,t[e+36>>2]=0,c[e+40>>0]=0,c[e+41>>0]=0}function P2(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Dd(e,r,l,0),m=u}function Dd(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=u1()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=Pf(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,o1(s,u)|0,u),m=l}function u1(){var e=0,n=0;if(c[7640]|0||(Fl(9232),Wt(26,9232,se|0)|0,n=7640,t[n>>2]=1,t[n+4>>2]=0),!(sr(9232)|0)){e=9232,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Fl(9232)}return 9232}function Pf(e){return e=e|0,0}function o1(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=u1()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Ja(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(l1(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Ja(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function l1(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=I2(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,wd(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Ja(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Sc(e,D),s1(D),m=L;return}}function I2(e){return e=e|0,357913941}function wd(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Sc(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function s1(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Fl(e){e=e|0,b2(e)}function Da(e){e=e|0,Ch(e+24|0)}function Ch(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function b2(e){e=e|0;var n=0;n=yr()|0,jn(e,2,1,n,B2()|0,3),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function B2(){return 1144}function xh(e,n,r,u,l){e=e|0,n=n|0,r=+r,u=+u,l=l|0;var s=0,h=0,D=0,S=0;s=m,m=m+16|0,h=s+8|0,D=s,S=Sd(e)|0,e=t[S+4>>2]|0,t[D>>2]=t[S>>2],t[D+4>>2]=e,t[h>>2]=t[D>>2],t[h+4>>2]=t[D+4>>2],Ah(n,h,r,u,l),m=s}function Sd(e){return e=e|0,(t[(u1()|0)+24>>2]|0)+(e*12|0)|0}function Ah(e,n,r,u,l){e=e|0,n=n|0,r=+r,u=+u,l=l|0;var s=0,h=0,D=0,S=0,L=0;L=m,m=m+16|0,h=L+2|0,D=L+1|0,S=L,s=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(s=t[(t[e>>2]|0)+s>>2]|0),Pl(h,r),r=+os(h,r),Pl(D,u),u=+os(D,u),As(S,l),S=Ys(S,l)|0,eS[s&1](e,r,u,S),m=L}function Pl(e,n){e=e|0,n=+n}function os(e,n){return e=e|0,n=+n,+ +Rh(n)}function As(e,n){e=e|0,n=n|0}function Ys(e,n){return e=e|0,n=n|0,U2(n)|0}function U2(e){return e=e|0,e|0}function Rh(e){return e=+e,+e}function j2(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],z2(e,r,l,1),m=u}function z2(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=a1()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=f1(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Oh(s,u)|0,u),m=l}function a1(){var e=0,n=0;if(c[7648]|0||(c1(9268),Wt(27,9268,se|0)|0,n=7648,t[n>>2]=1,t[n+4>>2]=0),!(sr(9268)|0)){e=9268,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));c1(9268)}return 9268}function f1(e){return e=e|0,0}function Oh(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=a1()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],H2(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(q2(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function H2(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function q2(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Rs(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Za(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],H2(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Mh(e,D),pu(D),m=L;return}}function Rs(e){return e=e|0,357913941}function Za(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Mh(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function pu(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function c1(e){e=e|0,Il(e)}function kh(e){e=e|0,d1(e+24|0)}function d1(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function Il(e){e=e|0;var n=0;n=yr()|0,jn(e,2,4,n,Lh()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Lh(){return 1160}function W2(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0;return r=m,m=m+16|0,u=r+8|0,l=r,s=Nh(e)|0,e=t[s+4>>2]|0,t[l>>2]=t[s>>2],t[l+4>>2]=e,t[u>>2]=t[l>>2],t[u+4>>2]=t[l+4>>2],n=p1(n,u)|0,m=r,n|0}function Nh(e){return e=e|0,(t[(a1()|0)+24>>2]|0)+(e*12|0)|0}function p1(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),bl(Zp[r&31](e)|0)|0}function bl(e){return e=e|0,e&1|0}function $a(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],wa(e,r,l,0),m=u}function wa(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=V2()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=G2(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,hm(s,u)|0,u),m=l}function V2(){var e=0,n=0;if(c[7656]|0||(Ih(9304),Wt(28,9304,se|0)|0,n=7656,t[n>>2]=1,t[n+4>>2]=0),!(sr(9304)|0)){e=9304,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Ih(9304)}return 9304}function G2(e){return e=e|0,0}function hm(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=V2()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Y2(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Fh(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Y2(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Fh(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Ph(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,K2(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Y2(s,u,r),t[S>>2]=(t[S>>2]|0)+12,vm(e,D),mm(D),m=L;return}}function Ph(e){return e=e|0,357913941}function K2(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function vm(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function mm(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Ih(e){e=e|0,h1(e)}function gm(e){e=e|0,X2(e+24|0)}function X2(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function h1(e){e=e|0;var n=0;n=yr()|0,jn(e,2,5,n,v1()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function v1(){return 1164}function m1(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;u=m,m=m+16|0,l=u+8|0,s=u,h=Sa(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Q2(n,l,r),m=u}function Sa(e){return e=e|0,(t[(V2()|0)+24>>2]|0)+(e*12|0)|0}function Q2(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),Ks(l,r),r=Xs(l,r)|0,I1[u&31](e,r),Qs(l),m=s}function Ks(e,n){e=e|0,n=n|0,J2(e,n)}function Xs(e,n){return e=e|0,n=n|0,e|0}function Qs(e){e=e|0,ca(e)}function J2(e,n){e=e|0,n=n|0,Ta(e,n)}function Ta(e,n){e=e|0,n=n|0,t[e>>2]=n}function g1(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Td(e,r,l,0),m=u}function Td(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=Tc()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=Z2(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,wo(s,u)|0,u),m=l}function Tc(){var e=0,n=0;if(c[7664]|0||(Hh(9340),Wt(29,9340,se|0)|0,n=7664,t[n>>2]=1,t[n+4>>2]=0),!(sr(9340)|0)){e=9340,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Hh(9340)}return 9340}function Z2(e){return e=e|0,0}function wo(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=Tc()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],bh(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Bh(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function bh(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Bh(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Uh(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,jh(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],bh(s,u,r),t[S>>2]=(t[S>>2]|0)+12,ym(e,D),zh(D),m=L;return}}function Uh(e){return e=e|0,357913941}function jh(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function ym(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function zh(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Hh(e){e=e|0,qh(e)}function y1(e){e=e|0,$2(e+24|0)}function $2(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function qh(e){e=e|0;var n=0;n=yr()|0,jn(e,2,4,n,ep()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function ep(){return 1180}function Wh(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=_m(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],r=Em(n,l,r)|0,m=u,r|0}function _m(e){return e=e|0,(t[(Tc()|0)+24>>2]|0)+(e*12|0)|0}function Em(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;return s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),If(l,r),l=bf(l,r)|0,l=Cd(eD[u&15](e,l)|0)|0,m=s,l|0}function If(e,n){e=e|0,n=n|0}function bf(e,n){return e=e|0,n=n|0,Dm(n)|0}function Cd(e){return e=e|0,e|0}function Dm(e){return e=e|0,e|0}function tp(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],xd(e,r,l,0),m=u}function xd(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=np()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=Vh(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,rp(s,u)|0,u),m=l}function np(){var e=0,n=0;if(c[7672]|0||(Kh(9376),Wt(30,9376,se|0)|0,n=7672,t[n>>2]=1,t[n+4>>2]=0),!(sr(9376)|0)){e=9376,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Kh(9376)}return 9376}function Vh(e){return e=e|0,0}function rp(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=np()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Gh(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Yh(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Gh(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Yh(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=ip(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,wm(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Gh(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Sm(e,D),Tm(D),m=L;return}}function ip(e){return e=e|0,357913941}function wm(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Sm(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Tm(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Kh(e){e=e|0,up(e)}function _1(e){e=e|0,Cm(e+24|0)}function Cm(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function up(e){e=e|0;var n=0;n=yr()|0,jn(e,2,5,n,op()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function op(){return 1196}function xm(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0;return r=m,m=m+16|0,u=r+8|0,l=r,s=Am(e)|0,e=t[s+4>>2]|0,t[l>>2]=t[s>>2],t[l+4>>2]=e,t[u>>2]=t[l>>2],t[u+4>>2]=t[l+4>>2],n=Xh(n,u)|0,m=r,n|0}function Am(e){return e=e|0,(t[(np()|0)+24>>2]|0)+(e*12|0)|0}function Xh(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),Cd(Zp[r&31](e)|0)|0}function Rm(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Om(e,r,l,1),m=u}function Om(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=lp()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=sp(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Ca(s,u)|0,u),m=l}function lp(){var e=0,n=0;if(c[7680]|0||(fp(9412),Wt(31,9412,se|0)|0,n=7680,t[n>>2]=1,t[n+4>>2]=0),!(sr(9412)|0)){e=9412,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));fp(9412)}return 9412}function sp(e){return e=e|0,0}function Ca(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=lp()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],E1(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(ap(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function E1(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function ap(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Qh(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Ad(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],E1(s,u,r),t[S>>2]=(t[S>>2]|0)+12,D1(e,D),Jh(D),m=L;return}}function Qh(e){return e=e|0,357913941}function Ad(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function D1(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Jh(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function fp(e){e=e|0,$h(e)}function Zh(e){e=e|0,cp(e+24|0)}function cp(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function $h(e){e=e|0;var n=0;n=yr()|0,jn(e,2,6,n,ev()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function ev(){return 1200}function dp(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0;return r=m,m=m+16|0,u=r+8|0,l=r,s=Rd(e)|0,e=t[s+4>>2]|0,t[l>>2]=t[s>>2],t[l+4>>2]=e,t[u>>2]=t[l>>2],t[u+4>>2]=t[l+4>>2],n=Od(n,u)|0,m=r,n|0}function Rd(e){return e=e|0,(t[(lp()|0)+24>>2]|0)+(e*12|0)|0}function Od(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),H0(Zp[r&31](e)|0)|0}function H0(e){return e=e|0,e|0}function Md(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],xa(e,r,l,0),m=u}function xa(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=ef()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=kd(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Ld(s,u)|0,u),m=l}function ef(){var e=0,n=0;if(c[7688]|0||(vp(9448),Wt(32,9448,se|0)|0,n=7688,t[n>>2]=1,t[n+4>>2]=0),!(sr(9448)|0)){e=9448,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));vp(9448)}return 9448}function kd(e){return e=e|0,0}function Ld(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=ef()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],pp(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Nd(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function pp(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Nd(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=tv(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Mm(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],pp(s,u,r),t[S>>2]=(t[S>>2]|0)+12,nv(e,D),hp(D),m=L;return}}function tv(e){return e=e|0,357913941}function Mm(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function nv(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function hp(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function vp(e){e=e|0,Lm(e)}function mp(e){e=e|0,km(e+24|0)}function km(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function Lm(e){e=e|0;var n=0;n=yr()|0,jn(e,2,6,n,So()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function So(){return 1204}function Fd(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;u=m,m=m+16|0,l=u+8|0,s=u,h=Nm(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],pl(n,l,r),m=u}function Nm(e){return e=e|0,(t[(ef()|0)+24>>2]|0)+(e*12|0)|0}function pl(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),tr(l,r),l=Js(l,r)|0,I1[u&31](e,l),m=s}function tr(e,n){e=e|0,n=n|0}function Js(e,n){return e=e|0,n=n|0,hl(n)|0}function hl(e){return e=e|0,e|0}function l0(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],rv(e,r,l,0),m=u}function rv(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=Zs()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=gp(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Fm(s,u)|0,u),m=l}function Zs(){var e=0,n=0;if(c[7696]|0||(Ep(9484),Wt(33,9484,se|0)|0,n=7696,t[n>>2]=1,t[n+4>>2]=0),!(sr(9484)|0)){e=9484,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Ep(9484)}return 9484}function gp(e){return e=e|0,0}function Fm(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=Zs()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],iv(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(yp(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function iv(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function yp(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Pm(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,_p(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],iv(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Cc(e,D),Aa(D),m=L;return}}function Pm(e){return e=e|0,357913941}function _p(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Cc(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Aa(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Ep(e){e=e|0,Yu(e)}function Pd(e){e=e|0,bu(e+24|0)}function bu(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function Yu(e){e=e|0;var n=0;n=yr()|0,jn(e,2,1,n,Dp()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Dp(){return 1212}function wp(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;l=m,m=m+16|0,s=l+8|0,h=l,D=uv(e)|0,e=t[D+4>>2]|0,t[h>>2]=t[D>>2],t[h+4>>2]=e,t[s>>2]=t[h>>2],t[s+4>>2]=t[h+4>>2],Im(n,s,r,u),m=l}function uv(e){return e=e|0,(t[(Zs()|0)+24>>2]|0)+(e*12|0)|0}function Im(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;D=m,m=m+16|0,s=D+1|0,h=D,l=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(l=t[(t[e>>2]|0)+l>>2]|0),tr(s,r),s=Js(s,r)|0,If(h,u),h=bf(h,u)|0,Fg[l&15](e,s,h),m=D}function bm(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Bm(e,r,l,1),m=u}function Bm(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=Id()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=ov(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,xc(s,u)|0,u),m=l}function Id(){var e=0,n=0;if(c[7704]|0||(lv(9520),Wt(34,9520,se|0)|0,n=7704,t[n>>2]=1,t[n+4>>2]=0),!(sr(9520)|0)){e=9520,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));lv(9520)}return 9520}function ov(e){return e=e|0,0}function xc(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=Id()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],w1(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Um(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function w1(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Um(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=bd(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,S1(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],w1(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Bl(e,D),Ra(D),m=L;return}}function bd(e){return e=e|0,357913941}function S1(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Bl(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Ra(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function lv(e){e=e|0,av(e)}function jm(e){e=e|0,sv(e+24|0)}function sv(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function av(e){e=e|0;var n=0;n=yr()|0,jn(e,2,1,n,zm()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function zm(){return 1224}function fv(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;return l=m,m=m+16|0,s=l+8|0,h=l,D=Oa(e)|0,e=t[D+4>>2]|0,t[h>>2]=t[D>>2],t[h+4>>2]=e,t[s>>2]=t[h>>2],t[s+4>>2]=t[h+4>>2],u=+Mr(n,s,r),m=l,+u}function Oa(e){return e=e|0,(t[(Id()|0)+24>>2]|0)+(e*12|0)|0}function Mr(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),As(l,r),l=Ys(l,r)|0,h=+Ya(+nS[u&7](e,l)),m=s,+h}function Sp(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],vl(e,r,l,1),m=u}function vl(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=yu()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=T1(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Ui(s,u)|0,u),m=l}function yu(){var e=0,n=0;if(c[7712]|0||(Cp(9556),Wt(35,9556,se|0)|0,n=7712,t[n>>2]=1,t[n+4>>2]=0),!(sr(9556)|0)){e=9556,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Cp(9556)}return 9556}function T1(e){return e=e|0,0}function Ui(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=yu()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Tp(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Bd(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Tp(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Bd(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=To(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Os(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Tp(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Bf(e,D),Ud(D),m=L;return}}function To(e){return e=e|0,357913941}function Os(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Bf(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Ud(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Cp(e){e=e|0,xp(e)}function C1(e){e=e|0,x1(e+24|0)}function x1(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function xp(e){e=e|0;var n=0;n=yr()|0,jn(e,2,5,n,nr()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function nr(){return 1232}function ml(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=Gn(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],r=+q0(n,l),m=u,+r}function Gn(e){return e=e|0,(t[(yu()|0)+24>>2]|0)+(e*12|0)|0}function q0(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),+ +Ya(+tS[r&15](e))}function k0(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],jd(e,r,l,1),m=u}function jd(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=Ul()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=A1(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Ac(s,u)|0,u),m=l}function Ul(){var e=0,n=0;if(c[7720]|0||(qd(9592),Wt(36,9592,se|0)|0,n=7720,t[n>>2]=1,t[n+4>>2]=0),!(sr(9592)|0)){e=9592,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));qd(9592)}return 9592}function A1(e){return e=e|0,0}function Ac(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=Ul()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Rc(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(zd(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Rc(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function zd(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Ap(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,L0(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Rc(s,u,r),t[S>>2]=(t[S>>2]|0)+12,dn(e,D),Hd(D),m=L;return}}function Ap(e){return e=e|0,357913941}function L0(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function dn(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Hd(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function qd(e){e=e|0,kc(e)}function Oc(e){e=e|0,Mc(e+24|0)}function Mc(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function kc(e){e=e|0;var n=0;n=yr()|0,jn(e,2,7,n,R1()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function R1(){return 1276}function Rp(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0;return r=m,m=m+16|0,u=r+8|0,l=r,s=tf(e)|0,e=t[s+4>>2]|0,t[l>>2]=t[s>>2],t[l+4>>2]=e,t[u>>2]=t[l>>2],t[u+4>>2]=t[l+4>>2],n=Hm(n,u)|0,m=r,n|0}function tf(e){return e=e|0,(t[(Ul()|0)+24>>2]|0)+(e*12|0)|0}function Hm(e,n){e=e|0,n=n|0;var r=0,u=0,l=0;return l=m,m=m+16|0,u=l,r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),I1[r&31](u,e),u=Lc(u)|0,m=l,u|0}function Lc(e){e=e|0;var n=0,r=0,u=0,l=0;return l=m,m=m+32|0,n=l+12|0,r=l,u=Iu(Wd()|0)|0,u?(is(n,u),kf(r,n),cv(e,r),e=xs(n)|0):e=O1(e)|0,m=l,e|0}function Wd(){var e=0;return c[7736]|0||(Wo(9640),Wt(25,9640,se|0)|0,e=7736,t[e>>2]=1,t[e+4>>2]=0),9640}function cv(e,n){e=e|0,n=n|0,Nc(n,e,e+8|0)|0}function O1(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0;return r=m,m=m+16|0,l=r+4|0,h=r,u=Ma(8)|0,n=u,D=pn(16)|0,t[D>>2]=t[e>>2],t[D+4>>2]=t[e+4>>2],t[D+8>>2]=t[e+8>>2],t[D+12>>2]=t[e+12>>2],s=n+4|0,t[s>>2]=D,e=pn(8)|0,s=t[s>>2]|0,t[h>>2]=0,t[l>>2]=t[h>>2],Uf(e,s,l),t[u>>2]=e,m=r,n|0}function Uf(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=pn(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1244,t[r+12>>2]=n,t[e+4>>2]=r}function jf(e){e=e|0,Uv(e),yt(e)}function M1(e){e=e|0,e=t[e+12>>2]|0,e|0&&yt(e)}function jl(e){e=e|0,yt(e)}function Nc(e,n,r){return e=e|0,n=n|0,r=r|0,n=zf(t[e>>2]|0,n,r)|0,r=e+4|0,t[(t[r>>2]|0)+8>>2]=n,t[(t[r>>2]|0)+8>>2]|0}function zf(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;return u=m,m=m+16|0,l=u,ka(l),e=yo(e)|0,r=qm(e,t[n>>2]|0,+B[r>>3])|0,La(l),m=u,r|0}function qm(e,n,r){e=e|0,n=n|0,r=+r;var u=0;return u=_o(gl()|0)|0,n=ad(n)|0,Hr(0,u|0,e|0,n|0,+ +kl(r))|0}function gl(){var e=0;return c[7728]|0||(Vd(9628),e=7728,t[e>>2]=1,t[e+4>>2]=0),9628}function Vd(e){e=e|0,ll(e,Gd()|0,2)}function Gd(){return 1264}function Wo(e){e=e|0,Qa(e)}function Yd(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Wm(e,r,l,1),m=u}function Wm(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=k1()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=Vm(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Gm(s,u)|0,u),m=l}function k1(){var e=0,n=0;if(c[7744]|0||(hv(9684),Wt(37,9684,se|0)|0,n=7744,t[n>>2]=1,t[n+4>>2]=0),!(sr(9684)|0)){e=9684,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));hv(9684)}return 9684}function Vm(e){return e=e|0,0}function Gm(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=k1()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],dv(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Ym(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function dv(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Ym(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=pv(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Km(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],dv(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Xm(e,D),Qm(D),m=L;return}}function pv(e){return e=e|0,357913941}function Km(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Xm(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Qm(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function hv(e){e=e|0,Zm(e)}function Jm(e){e=e|0,Op(e+24|0)}function Op(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function Zm(e){e=e|0;var n=0;n=yr()|0,jn(e,2,5,n,Hf()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Hf(){return 1280}function vv(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=mv(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],r=gv(n,l,r)|0,m=u,r|0}function mv(e){return e=e|0,(t[(k1()|0)+24>>2]|0)+(e*12|0)|0}function gv(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return h=m,m=m+32|0,l=h,s=h+16|0,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),As(s,r),s=Ys(s,r)|0,Fg[u&15](l,e,s),s=Lc(l)|0,m=h,s|0}function Kd(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Xd(e,r,l,1),m=u}function Xd(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=Mp()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=yv(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Qd(s,u)|0,u),m=l}function Mp(){var e=0,n=0;if(c[7752]|0||(Sv(9720),Wt(38,9720,se|0)|0,n=7752,t[n>>2]=1,t[n+4>>2]=0),!(sr(9720)|0)){e=9720,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Sv(9720)}return 9720}function yv(e){return e=e|0,0}function Qd(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=Mp()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],_v(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Ev(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function _v(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function Ev(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=kp(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Dv(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],_v(s,u,r),t[S>>2]=(t[S>>2]|0)+12,wv(e,D),$m(D),m=L;return}}function kp(e){return e=e|0,357913941}function Dv(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function wv(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function $m(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Sv(e){e=e|0,Tv(e)}function eg(e){e=e|0,Jd(e+24|0)}function Jd(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function Tv(e){e=e|0;var n=0;n=yr()|0,jn(e,2,8,n,Lp()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Lp(){return 1288}function tg(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0;return r=m,m=m+16|0,u=r+8|0,l=r,s=s0(e)|0,e=t[s+4>>2]|0,t[l>>2]=t[s>>2],t[l+4>>2]=e,t[u>>2]=t[l>>2],t[u+4>>2]=t[l+4>>2],n=Np(n,u)|0,m=r,n|0}function s0(e){return e=e|0,(t[(Mp()|0)+24>>2]|0)+(e*12|0)|0}function Np(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),dd(Zp[r&31](e)|0)|0}function ng(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],rg(e,r,l,0),m=u}function rg(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=Fp()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=nf(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Pp(s,u)|0,u),m=l}function Fp(){var e=0,n=0;if(c[7760]|0||(Bp(9756),Wt(39,9756,se|0)|0,n=7760,t[n>>2]=1,t[n+4>>2]=0),!(sr(9756)|0)){e=9756,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Bp(9756)}return 9756}function nf(e){return e=e|0,0}function Pp(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=Fp()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Ip(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(bp(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Ip(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function bp(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=ig(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,ug(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Ip(s,u,r),t[S>>2]=(t[S>>2]|0)+12,Cv(e,D),qf(D),m=L;return}}function ig(e){return e=e|0,357913941}function ug(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function Cv(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function qf(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Bp(e){e=e|0,lg(e)}function xv(e){e=e|0,og(e+24|0)}function og(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function lg(e){e=e|0;var n=0;n=yr()|0,jn(e,2,8,n,Up()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Up(){return 1292}function jp(e,n,r){e=e|0,n=n|0,r=+r;var u=0,l=0,s=0,h=0;u=m,m=m+16|0,l=u+8|0,s=u,h=sg(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],ag(n,l,r),m=u}function sg(e){return e=e|0,(t[(Fp()|0)+24>>2]|0)+(e*12|0)|0}function ag(e,n,r){e=e|0,n=n|0,r=+r;var u=0,l=0,s=0;s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),Pl(l,r),r=+os(l,r),Z8[u&31](e,r),m=s}function Av(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],zp(e,r,l,0),m=u}function zp(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=Hp()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=Zd(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,fg(s,u)|0,u),m=l}function Hp(){var e=0,n=0;if(c[7768]|0||(qp(9792),Wt(40,9792,se|0)|0,n=7768,t[n>>2]=1,t[n+4>>2]=0),!(sr(9792)|0)){e=9792,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));qp(9792)}return 9792}function Zd(e){return e=e|0,0}function fg(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=Hp()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],L1(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(cg(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function L1(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function cg(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Rv(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Ov(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],L1(s,u,r),t[S>>2]=(t[S>>2]|0)+12,dg(e,D),Wf(D),m=L;return}}function Rv(e){return e=e|0,357913941}function Ov(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function dg(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Wf(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function qp(e){e=e|0,hg(e)}function Mv(e){e=e|0,pg(e+24|0)}function pg(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function hg(e){e=e|0;var n=0;n=yr()|0,jn(e,2,1,n,Wp()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Wp(){return 1300}function vg(e,n,r,u){e=e|0,n=n|0,r=r|0,u=+u;var l=0,s=0,h=0,D=0;l=m,m=m+16|0,s=l+8|0,h=l,D=$s(e)|0,e=t[D+4>>2]|0,t[h>>2]=t[D>>2],t[h+4>>2]=e,t[s>>2]=t[h>>2],t[s+4>>2]=t[h+4>>2],mg(n,s,r,u),m=l}function $s(e){return e=e|0,(t[(Hp()|0)+24>>2]|0)+(e*12|0)|0}function mg(e,n,r,u){e=e|0,n=n|0,r=r|0,u=+u;var l=0,s=0,h=0,D=0;D=m,m=m+16|0,s=D+1|0,h=D,l=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(l=t[(t[e>>2]|0)+l>>2]|0),As(s,r),s=Ys(s,r)|0,Pl(h,u),u=+os(h,u),oS[l&15](e,s,u),m=D}function p(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],v(e,r,l,0),m=u}function v(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=x()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=P(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,W(s,u)|0,u),m=l}function x(){var e=0,n=0;if(c[7776]|0||(Rt(9828),Wt(41,9828,se|0)|0,n=7776,t[n>>2]=1,t[n+4>>2]=0),!(sr(9828)|0)){e=9828,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Rt(9828)}return 9828}function P(e){return e=e|0,0}function W(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=x()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],ee(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(ve(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function ee(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function ve(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Ee(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Ie(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],ee(s,u,r),t[S>>2]=(t[S>>2]|0)+12,_t(e,D),St(D),m=L;return}}function Ee(e){return e=e|0,357913941}function Ie(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function _t(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function St(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Rt(e){e=e|0,rr(e)}function on(e){e=e|0,kn(e+24|0)}function kn(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function rr(e){e=e|0;var n=0;n=yr()|0,jn(e,2,7,n,br()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function br(){return 1312}function ar(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;u=m,m=m+16|0,l=u+8|0,s=u,h=ui(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],di(n,l,r),m=u}function ui(e){return e=e|0,(t[(x()|0)+24>>2]|0)+(e*12|0)|0}function di(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),As(l,r),l=Ys(l,r)|0,I1[u&31](e,l),m=s}function zl(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],Zi(e,r,l,0),m=u}function Zi(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=so()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=a0(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,Ms(s,u)|0,u),m=l}function so(){var e=0,n=0;if(c[7784]|0||(n_(9864),Wt(42,9864,se|0)|0,n=7784,t[n>>2]=1,t[n+4>>2]=0),!(sr(9864)|0)){e=9864,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));n_(9864)}return 9864}function a0(e){return e=e|0,0}function Ms(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=so()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Co(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(kv(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Co(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function kv(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=J4(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,gg(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Co(s,u,r),t[S>>2]=(t[S>>2]|0)+12,yg(e,D),rf(D),m=L;return}}function J4(e){return e=e|0,357913941}function gg(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function yg(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function rf(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function n_(e){e=e|0,eE(e)}function Z4(e){e=e|0,$4(e+24|0)}function $4(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function eE(e){e=e|0;var n=0;n=yr()|0,jn(e,2,8,n,tE()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function tE(){return 1320}function _g(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;u=m,m=m+16|0,l=u+8|0,s=u,h=nE(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],rE(n,l,r),m=u}function nE(e){return e=e|0,(t[(so()|0)+24>>2]|0)+(e*12|0)|0}function rE(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),Eg(l,r),l=r_(l,r)|0,I1[u&31](e,l),m=s}function Eg(e,n){e=e|0,n=n|0}function r_(e,n){return e=e|0,n=n|0,iE(n)|0}function iE(e){return e=e|0,e|0}function uE(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],i_(e,r,l,0),m=u}function i_(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=Vf()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=u_(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,oE(s,u)|0,u),m=l}function Vf(){var e=0,n=0;if(c[7792]|0||(Sg(9900),Wt(43,9900,se|0)|0,n=7792,t[n>>2]=1,t[n+4>>2]=0),!(sr(9900)|0)){e=9900,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Sg(9900)}return 9900}function u_(e){return e=e|0,0}function oE(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=Vf()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Vp(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(lE(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Vp(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function lE(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=Lv(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,Dg(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Vp(s,u,r),t[S>>2]=(t[S>>2]|0)+12,wg(e,D),sE(D),m=L;return}}function Lv(e){return e=e|0,357913941}function Dg(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function wg(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function sE(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Sg(e){e=e|0,o_(e)}function aE(e){e=e|0,fE(e+24|0)}function fE(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function o_(e){e=e|0;var n=0;n=yr()|0,jn(e,2,22,n,cE()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function cE(){return 1344}function dE(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0;r=m,m=m+16|0,u=r+8|0,l=r,s=l_(e)|0,e=t[s+4>>2]|0,t[l>>2]=t[s>>2],t[l+4>>2]=e,t[u>>2]=t[l>>2],t[u+4>>2]=t[l+4>>2],Nv(n,u),m=r}function l_(e){return e=e|0,(t[(Vf()|0)+24>>2]|0)+(e*12|0)|0}function Nv(e,n){e=e|0,n=n|0;var r=0;r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),P1[r&127](e)}function pE(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=Tg()|0,e=hE(r)|0,wi(s,n,l,e,vE(r,u)|0,u)}function Tg(){var e=0,n=0;if(c[7800]|0||(xg(9936),Wt(44,9936,se|0)|0,n=7800,t[n>>2]=1,t[n+4>>2]=0),!(sr(9936)|0)){e=9936,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));xg(9936)}return 9936}function hE(e){return e=e|0,e|0}function vE(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=Tg()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(Cg(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(s_(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function Cg(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function s_(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=a_(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,f_(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,Cg(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,c_(e,l),d_(l),m=D;return}}function a_(e){return e=e|0,536870911}function f_(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function c_(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function d_(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function xg(e){e=e|0,h_(e)}function p_(e){e=e|0,mE(e+24|0)}function mE(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function h_(e){e=e|0;var n=0;n=yr()|0,jn(e,1,23,n,So()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function gE(e,n){e=e|0,n=n|0,f(t[(yE(e)|0)>>2]|0,n)}function yE(e){return e=e|0,(t[(Tg()|0)+24>>2]|0)+(e<<3)|0}function f(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,tr(u,n),n=Js(u,n)|0,P1[e&127](n),m=r}function d(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=E()|0,e=C(r)|0,wi(s,n,l,e,R(r,u)|0,u)}function E(){var e=0,n=0;if(c[7808]|0||(ht(9972),Wt(45,9972,se|0)|0,n=7808,t[n>>2]=1,t[n+4>>2]=0),!(sr(9972)|0)){e=9972,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));ht(9972)}return 9972}function C(e){return e=e|0,e|0}function R(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=E()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(j(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(V(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function j(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function V(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=te(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,le(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,j(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,Be(e,l),Xe(l),m=D;return}}function te(e){return e=e|0,536870911}function le(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function Be(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function Xe(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function ht(e){e=e|0,zt(e)}function Lt(e){e=e|0,Gt(e+24|0)}function Gt(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function zt(e){e=e|0;var n=0;n=yr()|0,jn(e,1,9,n,gn()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function gn(){return 1348}function kr(e,n){return e=e|0,n=n|0,Mi(t[(oi(e)|0)>>2]|0,n)|0}function oi(e){return e=e|0,(t[(E()|0)+24>>2]|0)+(e<<3)|0}function Mi(e,n){e=e|0,n=n|0;var r=0,u=0;return r=m,m=m+16|0,u=r,N0(u,n),n=$i(u,n)|0,n=Cd(Zp[e&31](n)|0)|0,m=r,n|0}function N0(e,n){e=e|0,n=n|0}function $i(e,n){return e=e|0,n=n|0,ot(n)|0}function ot(e){return e=e|0,e|0}function Ot(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=$e()|0,e=Ut(r)|0,wi(s,n,l,e,Pn(r,u)|0,u)}function $e(){var e=0,n=0;if(c[7816]|0||(Kr(10008),Wt(46,10008,se|0)|0,n=7816,t[n>>2]=1,t[n+4>>2]=0),!(sr(10008)|0)){e=10008,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Kr(10008)}return 10008}function Ut(e){return e=e|0,e|0}function Pn(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=$e()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(vn(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(Wi(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function vn(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function Wi(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=pi(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,Ku(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,vn(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,hr(e,l),hu(l),m=D;return}}function pi(e){return e=e|0,536870911}function Ku(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function hr(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function hu(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function Kr(e){e=e|0,W0(e)}function xu(e){e=e|0,w0(e+24|0)}function w0(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function W0(e){e=e|0;var n=0;n=yr()|0,jn(e,1,15,n,op()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function ks(e){return e=e|0,yl(t[(Xu(e)|0)>>2]|0)|0}function Xu(e){return e=e|0,(t[($e()|0)+24>>2]|0)+(e<<3)|0}function yl(e){return e=e|0,Cd(k_[e&7]()|0)|0}function uf(){var e=0;return c[7832]|0||(m_(10052),Wt(25,10052,se|0)|0,e=7832,t[e>>2]=1,t[e+4>>2]=0),10052}function Vo(e,n){e=e|0,n=n|0,t[e>>2]=Ls()|0,t[e+4>>2]=$d()|0,t[e+12>>2]=n,t[e+8>>2]=Gf()|0,t[e+32>>2]=2}function Ls(){return 11709}function $d(){return 1188}function Gf(){return N1()|0}function Fc(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(Go(r),yt(r)):n|0&&(ws(n),yt(n))}function Hl(e,n){return e=e|0,n=n|0,n&e|0}function Go(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function N1(){var e=0;return c[7824]|0||(t[2511]=v_()|0,t[2512]=0,e=7824,t[e>>2]=1,t[e+4>>2]=0),10044}function v_(){return 0}function m_(e){e=e|0,Qa(e)}function _E(e){e=e|0;var n=0,r=0,u=0,l=0,s=0;n=m,m=m+32|0,r=n+24|0,s=n+16|0,l=n+8|0,u=n,g_(e,4827),EE(e,4834,3)|0,DE(e,3682,47)|0,t[s>>2]=9,t[s+4>>2]=0,t[r>>2]=t[s>>2],t[r+4>>2]=t[s+4>>2],Ag(e,4841,r)|0,t[l>>2]=1,t[l+4>>2]=0,t[r>>2]=t[l>>2],t[r+4>>2]=t[l+4>>2],y_(e,4871,r)|0,t[u>>2]=10,t[u+4>>2]=0,t[r>>2]=t[u>>2],t[r+4>>2]=t[u+4>>2],wE(e,4891,r)|0,m=n}function g_(e,n){e=e|0,n=n|0;var r=0;r=QR()|0,t[e>>2]=r,JR(r,n),e2(t[e>>2]|0)}function EE(e,n,r){return e=e|0,n=n|0,r=r|0,FR(e,Fr(n)|0,r,0),e|0}function DE(e,n,r){return e=e|0,n=n|0,r=r|0,_R(e,Fr(n)|0,r,0),e|0}function Ag(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],eR(e,n,l),m=u,e|0}function y_(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],PA(e,n,l),m=u,e|0}function wE(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=t[r+4>>2]|0,t[s>>2]=t[r>>2],t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],SE(e,n,l),m=u,e|0}function SE(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],TE(e,r,l,1),m=u}function TE(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=CE()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=DA(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,wA(s,u)|0,u),m=l}function CE(){var e=0,n=0;if(c[7840]|0||(Pw(10100),Wt(48,10100,se|0)|0,n=7840,t[n>>2]=1,t[n+4>>2]=0),!(sr(10100)|0)){e=10100,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Pw(10100)}return 10100}function DA(e){return e=e|0,0}function wA(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=CE()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Fw(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(SA(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Fw(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function SA(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=TA(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,CA(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Fw(s,u,r),t[S>>2]=(t[S>>2]|0)+12,xA(e,D),AA(D),m=L;return}}function TA(e){return e=e|0,357913941}function CA(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function xA(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function AA(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Pw(e){e=e|0,MA(e)}function RA(e){e=e|0,OA(e+24|0)}function OA(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function MA(e){e=e|0;var n=0;n=yr()|0,jn(e,2,6,n,kA()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function kA(){return 1364}function LA(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;return u=m,m=m+16|0,l=u+8|0,s=u,h=NA(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],r=FA(n,l,r)|0,m=u,r|0}function NA(e){return e=e|0,(t[(CE()|0)+24>>2]|0)+(e*12|0)|0}function FA(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;return s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),As(l,r),l=Ys(l,r)|0,l=bl(eD[u&15](e,l)|0)|0,m=s,l|0}function PA(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],IA(e,r,l,0),m=u}function IA(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=xE()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=bA(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,BA(s,u)|0,u),m=l}function xE(){var e=0,n=0;if(c[7848]|0||(bw(10136),Wt(49,10136,se|0)|0,n=7848,t[n>>2]=1,t[n+4>>2]=0),!(sr(10136)|0)){e=10136,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));bw(10136)}return 10136}function bA(e){return e=e|0,0}function BA(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=xE()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Iw(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(UA(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Iw(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function UA(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=jA(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,zA(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Iw(s,u,r),t[S>>2]=(t[S>>2]|0)+12,HA(e,D),qA(D),m=L;return}}function jA(e){return e=e|0,357913941}function zA(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function HA(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function qA(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function bw(e){e=e|0,GA(e)}function WA(e){e=e|0,VA(e+24|0)}function VA(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function GA(e){e=e|0;var n=0;n=yr()|0,jn(e,2,9,n,YA()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function YA(){return 1372}function KA(e,n,r){e=e|0,n=n|0,r=+r;var u=0,l=0,s=0,h=0;u=m,m=m+16|0,l=u+8|0,s=u,h=XA(e)|0,e=t[h+4>>2]|0,t[s>>2]=t[h>>2],t[s+4>>2]=e,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],QA(n,l,r),m=u}function XA(e){return e=e|0,(t[(xE()|0)+24>>2]|0)+(e*12|0)|0}function QA(e,n,r){e=e|0,n=n|0,r=+r;var u=0,l=0,s=0,h=Tt;s=m,m=m+16|0,l=s,u=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(u=t[(t[e>>2]|0)+u>>2]|0),JA(l,r),h=w(ZA(l,r)),J8[u&1](e,h),m=s}function JA(e,n){e=e|0,n=+n}function ZA(e,n){return e=e|0,n=+n,w($A(n))}function $A(e){return e=+e,w(e)}function eR(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,l=u+8|0,s=u,D=t[r>>2]|0,h=t[r+4>>2]|0,r=Fr(n)|0,t[s>>2]=D,t[s+4>>2]=h,t[l>>2]=t[s>>2],t[l+4>>2]=t[s+4>>2],tR(e,r,l,0),m=u}function tR(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0,S=0,L=0,k=0;l=m,m=m+32|0,s=l+16|0,k=l+8|0,D=l,L=t[r>>2]|0,S=t[r+4>>2]|0,h=t[e>>2]|0,e=AE()|0,t[k>>2]=L,t[k+4>>2]=S,t[s>>2]=t[k>>2],t[s+4>>2]=t[k+4>>2],r=nR(s)|0,t[D>>2]=L,t[D+4>>2]=S,t[s>>2]=t[D>>2],t[s+4>>2]=t[D+4>>2],wi(h,n,e,r,rR(s,u)|0,u),m=l}function AE(){var e=0,n=0;if(c[7856]|0||(Uw(10172),Wt(50,10172,se|0)|0,n=7856,t[n>>2]=1,t[n+4>>2]=0),!(sr(10172)|0)){e=10172,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Uw(10172)}return 10172}function nR(e){return e=e|0,0}function rR(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0;return k=m,m=m+32|0,l=k+24|0,h=k+16|0,D=k,S=k+8|0,s=t[e>>2]|0,u=t[e+4>>2]|0,t[D>>2]=s,t[D+4>>2]=u,I=AE()|0,L=I+24|0,e=hn(n,4)|0,t[S>>2]=e,n=I+28|0,r=t[n>>2]|0,r>>>0<(t[I+32>>2]|0)>>>0?(t[h>>2]=s,t[h+4>>2]=u,t[l>>2]=t[h>>2],t[l+4>>2]=t[h+4>>2],Bw(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(iR(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function Bw(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=u,t[e+8>>2]=r}function iR(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;if(L=m,m=m+48|0,u=L+32|0,h=L+24|0,D=L,S=e+4|0,l=(((t[S>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,s=uR(e)|0,s>>>0>>0)hi(e);else{k=t[e>>2]|0,K=((t[e+8>>2]|0)-k|0)/12|0,I=K<<1,oR(D,K>>>0>>1>>>0?I>>>0>>0?l:I:s,((t[S>>2]|0)-k|0)/12|0,e+8|0),S=D+8|0,s=t[S>>2]|0,l=t[n+4>>2]|0,r=t[r>>2]|0,t[h>>2]=t[n>>2],t[h+4>>2]=l,t[u>>2]=t[h>>2],t[u+4>>2]=t[h+4>>2],Bw(s,u,r),t[S>>2]=(t[S>>2]|0)+12,lR(e,D),sR(D),m=L;return}}function uR(e){return e=e|0,357913941}function oR(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>357913941)$n();else{l=pn(n*12|0)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r*12|0)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n*12|0)}function lR(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(((l|0)/-12|0)*12|0)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function sR(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~(((u+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&yt(e)}function Uw(e){e=e|0,cR(e)}function aR(e){e=e|0,fR(e+24|0)}function fR(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-u|0)>>>0)/12|0)*12|0)),yt(r))}function cR(e){e=e|0;var n=0;n=yr()|0,jn(e,2,3,n,dR()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function dR(){return 1380}function pR(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;l=m,m=m+16|0,s=l+8|0,h=l,D=hR(e)|0,e=t[D+4>>2]|0,t[h>>2]=t[D>>2],t[h+4>>2]=e,t[s>>2]=t[h>>2],t[s+4>>2]=t[h+4>>2],vR(n,s,r,u),m=l}function hR(e){return e=e|0,(t[(AE()|0)+24>>2]|0)+(e*12|0)|0}function vR(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;D=m,m=m+16|0,s=D+1|0,h=D,l=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(l=t[(t[e>>2]|0)+l>>2]|0),As(s,r),s=Ys(s,r)|0,mR(h,u),h=gR(h,u)|0,Fg[l&15](e,s,h),m=D}function mR(e,n){e=e|0,n=n|0}function gR(e,n){return e=e|0,n=n|0,yR(n)|0}function yR(e){return e=e|0,(e|0)!=0|0}function _R(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=RE()|0,e=ER(r)|0,wi(s,n,l,e,DR(r,u)|0,u)}function RE(){var e=0,n=0;if(c[7864]|0||(zw(10208),Wt(51,10208,se|0)|0,n=7864,t[n>>2]=1,t[n+4>>2]=0),!(sr(10208)|0)){e=10208,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));zw(10208)}return 10208}function ER(e){return e=e|0,e|0}function DR(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=RE()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(jw(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(wR(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function jw(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function wR(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=SR(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,TR(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,jw(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,CR(e,l),xR(l),m=D;return}}function SR(e){return e=e|0,536870911}function TR(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function CR(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function xR(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function zw(e){e=e|0,OR(e)}function AR(e){e=e|0,RR(e+24|0)}function RR(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function OR(e){e=e|0;var n=0;n=yr()|0,jn(e,1,24,n,MR()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function MR(){return 1392}function kR(e,n){e=e|0,n=n|0,NR(t[(LR(e)|0)>>2]|0,n)}function LR(e){return e=e|0,(t[(RE()|0)+24>>2]|0)+(e<<3)|0}function NR(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,N0(u,n),n=$i(u,n)|0,P1[e&127](n),m=r}function FR(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=OE()|0,e=PR(r)|0,wi(s,n,l,e,IR(r,u)|0,u)}function OE(){var e=0,n=0;if(c[7872]|0||(qw(10244),Wt(52,10244,se|0)|0,n=7872,t[n>>2]=1,t[n+4>>2]=0),!(sr(10244)|0)){e=10244,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));qw(10244)}return 10244}function PR(e){return e=e|0,e|0}function IR(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=OE()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(Hw(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(bR(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function Hw(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function bR(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=BR(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,UR(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,Hw(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,jR(e,l),zR(l),m=D;return}}function BR(e){return e=e|0,536870911}function UR(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function jR(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function zR(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function qw(e){e=e|0,WR(e)}function HR(e){e=e|0,qR(e+24|0)}function qR(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function WR(e){e=e|0;var n=0;n=yr()|0,jn(e,1,16,n,VR()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function VR(){return 1400}function GR(e){return e=e|0,KR(t[(YR(e)|0)>>2]|0)|0}function YR(e){return e=e|0,(t[(OE()|0)+24>>2]|0)+(e<<3)|0}function KR(e){return e=e|0,XR(k_[e&7]()|0)|0}function XR(e){return e=e|0,e|0}function QR(){var e=0;return c[7880]|0||(r7(10280),Wt(25,10280,se|0)|0,e=7880,t[e>>2]=1,t[e+4>>2]=0),10280}function JR(e,n){e=e|0,n=n|0,t[e>>2]=ZR()|0,t[e+4>>2]=$R()|0,t[e+12>>2]=n,t[e+8>>2]=e7()|0,t[e+32>>2]=4}function ZR(){return 11711}function $R(){return 1356}function e7(){return N1()|0}function t7(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(n7(r),yt(r)):n|0&&(ro(n),yt(n))}function n7(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function r7(e){e=e|0,Qa(e)}function i7(e){e=e|0,u7(e,4920),o7(e)|0,l7(e)|0}function u7(e,n){e=e|0,n=n|0;var r=0;r=Wd()|0,t[e>>2]=r,R7(r,n),e2(t[e>>2]|0)}function o7(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,y7()|0),e|0}function l7(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,s7()|0),e|0}function s7(){var e=0;return c[7888]|0||(Ww(10328),Wt(53,10328,se|0)|0,e=7888,t[e>>2]=1,t[e+4>>2]=0),sr(10328)|0||Ww(10328),10328}function Gp(e,n){e=e|0,n=n|0,wi(e,0,n,0,0,0)}function Ww(e){e=e|0,c7(e),Yp(e,10)}function a7(e){e=e|0,f7(e+24|0)}function f7(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function c7(e){e=e|0;var n=0;n=yr()|0,jn(e,5,1,n,v7()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function d7(e,n,r){e=e|0,n=n|0,r=+r,p7(e,n,r)}function Yp(e,n){e=e|0,n=n|0,t[e+20>>2]=n}function p7(e,n,r){e=e|0,n=n|0,r=+r;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+16|0,s=u+8|0,D=u+13|0,l=u,h=u+12|0,As(D,n),t[s>>2]=Ys(D,n)|0,Pl(h,r),B[l>>3]=+os(h,r),h7(e,s,l),m=u}function h7(e,n,r){e=e|0,n=n|0,r=r|0,b(e+8|0,t[n>>2]|0,+B[r>>3]),c[e+24>>0]=1}function v7(){return 1404}function m7(e,n){return e=e|0,n=+n,g7(e,n)|0}function g7(e,n){e=e|0,n=+n;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return u=m,m=m+16|0,s=u+4|0,h=u+8|0,D=u,l=Ma(8)|0,r=l,S=pn(16)|0,As(s,e),e=Ys(s,e)|0,Pl(h,n),b(S,e,+os(h,n)),h=r+4|0,t[h>>2]=S,e=pn(8)|0,h=t[h>>2]|0,t[D>>2]=0,t[s>>2]=t[D>>2],Uf(e,h,s),t[l>>2]=e,m=u,r|0}function y7(){var e=0;return c[7896]|0||(Vw(10364),Wt(54,10364,se|0)|0,e=7896,t[e>>2]=1,t[e+4>>2]=0),sr(10364)|0||Vw(10364),10364}function Vw(e){e=e|0,D7(e),Yp(e,55)}function _7(e){e=e|0,E7(e+24|0)}function E7(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function D7(e){e=e|0;var n=0;n=yr()|0,jn(e,5,4,n,C7()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function w7(e){e=e|0,S7(e)}function S7(e){e=e|0,T7(e)}function T7(e){e=e|0,Gw(e+8|0),c[e+24>>0]=1}function Gw(e){e=e|0,t[e>>2]=0,B[e+8>>3]=0}function C7(){return 1424}function x7(){return A7()|0}function A7(){var e=0,n=0,r=0,u=0,l=0,s=0,h=0;return n=m,m=m+16|0,l=n+4|0,h=n,r=Ma(8)|0,e=r,u=pn(16)|0,Gw(u),s=e+4|0,t[s>>2]=u,u=pn(8)|0,s=t[s>>2]|0,t[h>>2]=0,t[l>>2]=t[h>>2],Uf(u,s,l),t[r>>2]=u,m=n,e|0}function R7(e,n){e=e|0,n=n|0,t[e>>2]=O7()|0,t[e+4>>2]=M7()|0,t[e+12>>2]=n,t[e+8>>2]=k7()|0,t[e+32>>2]=5}function O7(){return 11710}function M7(){return 1416}function k7(){return __()|0}function L7(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(N7(r),yt(r)):n|0&&yt(n)}function N7(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function __(){var e=0;return c[7904]|0||(t[2600]=F7()|0,t[2601]=0,e=7904,t[e>>2]=1,t[e+4>>2]=0),10400}function F7(){return t[357]|0}function P7(e){e=e|0,I7(e,4926),b7(e)|0}function I7(e,n){e=e|0,n=n|0;var r=0;r=Xa()|0,t[e>>2]=r,K7(r,n),e2(t[e>>2]|0)}function b7(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,B7()|0),e|0}function B7(){var e=0;return c[7912]|0||(Yw(10412),Wt(56,10412,se|0)|0,e=7912,t[e>>2]=1,t[e+4>>2]=0),sr(10412)|0||Yw(10412),10412}function Yw(e){e=e|0,z7(e),Yp(e,57)}function U7(e){e=e|0,j7(e+24|0)}function j7(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function z7(e){e=e|0;var n=0;n=yr()|0,jn(e,5,5,n,V7()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function H7(e){e=e|0,q7(e)}function q7(e){e=e|0,W7(e)}function W7(e){e=e|0;var n=0,r=0;n=e+8|0,r=n+48|0;do t[n>>2]=0,n=n+4|0;while((n|0)<(r|0));c[e+56>>0]=1}function V7(){return 1432}function G7(){return Y7()|0}function Y7(){var e=0,n=0,r=0,u=0,l=0,s=0,h=0,D=0;h=m,m=m+16|0,e=h+4|0,n=h,r=Ma(8)|0,u=r,l=pn(48)|0,s=l,D=s+48|0;do t[s>>2]=0,s=s+4|0;while((s|0)<(D|0));return s=u+4|0,t[s>>2]=l,D=pn(8)|0,s=t[s>>2]|0,t[n>>2]=0,t[e>>2]=t[n>>2],Th(D,s,e),t[r>>2]=D,m=h,u|0}function K7(e,n){e=e|0,n=n|0,t[e>>2]=X7()|0,t[e+4>>2]=Q7()|0,t[e+12>>2]=n,t[e+8>>2]=J7()|0,t[e+32>>2]=6}function X7(){return 11704}function Q7(){return 1436}function J7(){return __()|0}function Z7(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&($7(r),yt(r)):n|0&&yt(n)}function $7(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function eO(e){e=e|0,tO(e,4933),nO(e)|0,rO(e)|0}function tO(e,n){e=e|0,n=n|0;var r=0;r=AO()|0,t[e>>2]=r,RO(r,n),e2(t[e>>2]|0)}function nO(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,gO()|0),e|0}function rO(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,iO()|0),e|0}function iO(){var e=0;return c[7920]|0||(Kw(10452),Wt(58,10452,se|0)|0,e=7920,t[e>>2]=1,t[e+4>>2]=0),sr(10452)|0||Kw(10452),10452}function Kw(e){e=e|0,lO(e),Yp(e,1)}function uO(e){e=e|0,oO(e+24|0)}function oO(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function lO(e){e=e|0;var n=0;n=yr()|0,jn(e,5,1,n,cO()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function sO(e,n,r){e=e|0,n=+n,r=+r,aO(e,n,r)}function aO(e,n,r){e=e|0,n=+n,r=+r;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+32|0,s=u+8|0,D=u+17|0,l=u,h=u+16|0,Pl(D,n),B[s>>3]=+os(D,n),Pl(h,r),B[l>>3]=+os(h,r),fO(e,s,l),m=u}function fO(e,n,r){e=e|0,n=n|0,r=r|0,Xw(e+8|0,+B[n>>3],+B[r>>3]),c[e+24>>0]=1}function Xw(e,n,r){e=e|0,n=+n,r=+r,B[e>>3]=n,B[e+8>>3]=r}function cO(){return 1472}function dO(e,n){return e=+e,n=+n,pO(e,n)|0}function pO(e,n){e=+e,n=+n;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return u=m,m=m+16|0,h=u+4|0,D=u+8|0,S=u,l=Ma(8)|0,r=l,s=pn(16)|0,Pl(h,e),e=+os(h,e),Pl(D,n),Xw(s,e,+os(D,n)),D=r+4|0,t[D>>2]=s,s=pn(8)|0,D=t[D>>2]|0,t[S>>2]=0,t[h>>2]=t[S>>2],Qw(s,D,h),t[l>>2]=s,m=u,r|0}function Qw(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=pn(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1452,t[r+12>>2]=n,t[e+4>>2]=r}function hO(e){e=e|0,Uv(e),yt(e)}function vO(e){e=e|0,e=t[e+12>>2]|0,e|0&&yt(e)}function mO(e){e=e|0,yt(e)}function gO(){var e=0;return c[7928]|0||(Jw(10488),Wt(59,10488,se|0)|0,e=7928,t[e>>2]=1,t[e+4>>2]=0),sr(10488)|0||Jw(10488),10488}function Jw(e){e=e|0,EO(e),Yp(e,60)}function yO(e){e=e|0,_O(e+24|0)}function _O(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function EO(e){e=e|0;var n=0;n=yr()|0,jn(e,5,6,n,TO()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function DO(e){e=e|0,wO(e)}function wO(e){e=e|0,SO(e)}function SO(e){e=e|0,Zw(e+8|0),c[e+24>>0]=1}function Zw(e){e=e|0,t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,t[e+12>>2]=0}function TO(){return 1492}function CO(){return xO()|0}function xO(){var e=0,n=0,r=0,u=0,l=0,s=0,h=0;return n=m,m=m+16|0,l=n+4|0,h=n,r=Ma(8)|0,e=r,u=pn(16)|0,Zw(u),s=e+4|0,t[s>>2]=u,u=pn(8)|0,s=t[s>>2]|0,t[h>>2]=0,t[l>>2]=t[h>>2],Qw(u,s,l),t[r>>2]=u,m=n,e|0}function AO(){var e=0;return c[7936]|0||(FO(10524),Wt(25,10524,se|0)|0,e=7936,t[e>>2]=1,t[e+4>>2]=0),10524}function RO(e,n){e=e|0,n=n|0,t[e>>2]=OO()|0,t[e+4>>2]=MO()|0,t[e+12>>2]=n,t[e+8>>2]=kO()|0,t[e+32>>2]=7}function OO(){return 11700}function MO(){return 1484}function kO(){return __()|0}function LO(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(NO(r),yt(r)):n|0&&yt(n)}function NO(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function FO(e){e=e|0,Qa(e)}function PO(e,n,r){e=e|0,n=n|0,r=r|0,e=Fr(n)|0,n=IO(r)|0,r=bO(r,0)|0,pM(e,n,r,ME()|0,0)}function IO(e){return e=e|0,e|0}function bO(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=ME()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(e8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(WO(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function ME(){var e=0,n=0;if(c[7944]|0||($w(10568),Wt(61,10568,se|0)|0,n=7944,t[n>>2]=1,t[n+4>>2]=0),!(sr(10568)|0)){e=10568,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));$w(10568)}return 10568}function $w(e){e=e|0,jO(e)}function BO(e){e=e|0,UO(e+24|0)}function UO(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function jO(e){e=e|0;var n=0;n=yr()|0,jn(e,1,17,n,ev()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function zO(e){return e=e|0,qO(t[(HO(e)|0)>>2]|0)|0}function HO(e){return e=e|0,(t[(ME()|0)+24>>2]|0)+(e<<3)|0}function qO(e){return e=e|0,H0(k_[e&7]()|0)|0}function e8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function WO(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=VO(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,GO(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,e8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,YO(e,l),KO(l),m=D;return}}function VO(e){return e=e|0,536870911}function GO(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function YO(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function KO(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function XO(){QO()}function QO(){JO(10604)}function JO(e){e=e|0,ZO(e,4955)}function ZO(e,n){e=e|0,n=n|0;var r=0;r=$O()|0,t[e>>2]=r,eM(r,n),e2(t[e>>2]|0)}function $O(){var e=0;return c[7952]|0||(aM(10612),Wt(25,10612,se|0)|0,e=7952,t[e>>2]=1,t[e+4>>2]=0),10612}function eM(e,n){e=e|0,n=n|0,t[e>>2]=iM()|0,t[e+4>>2]=uM()|0,t[e+12>>2]=n,t[e+8>>2]=oM()|0,t[e+32>>2]=8}function e2(e){e=e|0;var n=0,r=0;n=m,m=m+16|0,r=n,Fv()|0,t[r>>2]=e,tM(10608,r),m=n}function Fv(){return c[11714]|0||(t[2652]=0,Wt(62,10608,se|0)|0,c[11714]=1),10608}function tM(e,n){e=e|0,n=n|0;var r=0;r=pn(8)|0,t[r+4>>2]=t[n>>2],t[r>>2]=t[e>>2],t[e>>2]=r}function nM(e){e=e|0,rM(e)}function rM(e){e=e|0;var n=0,r=0;if(n=t[e>>2]|0,n|0)do r=n,n=t[n>>2]|0,yt(r);while((n|0)!=0);t[e>>2]=0}function iM(){return 11715}function uM(){return 1496}function oM(){return N1()|0}function lM(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(sM(r),yt(r)):n|0&&yt(n)}function sM(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function aM(e){e=e|0,Qa(e)}function fM(e,n){e=e|0,n=n|0;var r=0,u=0;Fv()|0,r=t[2652]|0;e:do if(r|0){for(;u=t[r+4>>2]|0,!(u|0?(P8(kE(u)|0,e)|0)==0:0);)if(r=t[r>>2]|0,!r)break e;cM(u,n)}while(0)}function kE(e){return e=e|0,t[e+12>>2]|0}function cM(e,n){e=e|0,n=n|0;var r=0;e=e+36|0,r=t[e>>2]|0,r|0&&(ca(r),yt(r)),r=pn(4)|0,Sf(r,n),t[e>>2]=r}function LE(){return c[11716]|0||(t[2664]=0,Wt(63,10656,se|0)|0,c[11716]=1),10656}function t8(){var e=0;return c[11717]|0?e=t[2665]|0:(dM(),t[2665]=1504,c[11717]=1,e=1504),e|0}function dM(){c[11740]|0||(c[11718]=hn(hn(8,0)|0,0)|0,c[11719]=hn(hn(0,0)|0,0)|0,c[11720]=hn(hn(0,16)|0,0)|0,c[11721]=hn(hn(8,0)|0,0)|0,c[11722]=hn(hn(0,0)|0,0)|0,c[11723]=hn(hn(8,0)|0,0)|0,c[11724]=hn(hn(0,0)|0,0)|0,c[11725]=hn(hn(8,0)|0,0)|0,c[11726]=hn(hn(0,0)|0,0)|0,c[11727]=hn(hn(8,0)|0,0)|0,c[11728]=hn(hn(0,0)|0,0)|0,c[11729]=hn(hn(0,0)|0,32)|0,c[11730]=hn(hn(0,0)|0,32)|0,c[11740]=1)}function n8(){return 1572}function pM(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0,D=0,S=0,L=0,k=0;s=m,m=m+32|0,k=s+16|0,L=s+12|0,S=s+8|0,D=s+4|0,h=s,t[k>>2]=e,t[L>>2]=n,t[S>>2]=r,t[D>>2]=u,t[h>>2]=l,LE()|0,hM(10656,k,L,S,D,h),m=s}function hM(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0;var h=0;h=pn(24)|0,yd(h+4|0,t[n>>2]|0,t[r>>2]|0,t[u>>2]|0,t[l>>2]|0,t[s>>2]|0),t[h>>2]=t[e>>2],t[e>>2]=h}function r8(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0,Ze=0,Ge=0,ct=0;if(ct=m,m=m+32|0,Se=ct+20|0,ge=ct+8|0,Ze=ct+4|0,Ge=ct,n=t[n>>2]|0,n|0){be=Se+4|0,S=Se+8|0,L=ge+4|0,k=ge+8|0,I=ge+8|0,K=Se+8|0;do{if(h=n+4|0,D=NE(h)|0,D|0){if(l=Rg(D)|0,t[Se>>2]=0,t[be>>2]=0,t[S>>2]=0,u=(Og(D)|0)+1|0,vM(Se,u),u|0)for(;u=u+-1|0,Yf(ge,t[l>>2]|0),s=t[be>>2]|0,s>>>0<(t[K>>2]|0)>>>0?(t[s>>2]=t[ge>>2],t[be>>2]=(t[be>>2]|0)+4):FE(Se,ge),u;)l=l+4|0;u=Mg(D)|0,t[ge>>2]=0,t[L>>2]=0,t[k>>2]=0;e:do if(t[u>>2]|0)for(l=0,s=0;;){if((l|0)==(s|0)?mM(ge,u):(t[l>>2]=t[u>>2],t[L>>2]=(t[L>>2]|0)+4),u=u+4|0,!(t[u>>2]|0))break e;l=t[L>>2]|0,s=t[I>>2]|0}while(0);t[Ze>>2]=E_(h)|0,t[Ge>>2]=sr(D)|0,gM(r,e,Ze,Ge,Se,ge),PE(ge),F1(Se)}n=t[n>>2]|0}while((n|0)!=0)}m=ct}function NE(e){return e=e|0,t[e+12>>2]|0}function Rg(e){return e=e|0,t[e+12>>2]|0}function Og(e){return e=e|0,t[e+16>>2]|0}function vM(e,n){e=e|0,n=n|0;var r=0,u=0,l=0;l=m,m=m+32|0,r=l,u=t[e>>2]|0,(t[e+8>>2]|0)-u>>2>>>0>>0&&(c8(r,n,(t[e+4>>2]|0)-u>>2,e+8|0),d8(e,r),p8(r)),m=l}function FE(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0;if(h=m,m=m+32|0,r=h,u=e+4|0,l=((t[u>>2]|0)-(t[e>>2]|0)>>2)+1|0,s=f8(e)|0,s>>>0>>0)hi(e);else{D=t[e>>2]|0,L=(t[e+8>>2]|0)-D|0,S=L>>1,c8(r,L>>2>>>0>>1>>>0?S>>>0>>0?l:S:s,(t[u>>2]|0)-D>>2,e+8|0),s=r+8|0,t[t[s>>2]>>2]=t[n>>2],t[s>>2]=(t[s>>2]|0)+4,d8(e,r),p8(r),m=h;return}}function Mg(e){return e=e|0,t[e+8>>2]|0}function mM(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0;if(h=m,m=m+32|0,r=h,u=e+4|0,l=((t[u>>2]|0)-(t[e>>2]|0)>>2)+1|0,s=a8(e)|0,s>>>0>>0)hi(e);else{D=t[e>>2]|0,L=(t[e+8>>2]|0)-D|0,S=L>>1,IM(r,L>>2>>>0>>1>>>0?S>>>0>>0?l:S:s,(t[u>>2]|0)-D>>2,e+8|0),s=r+8|0,t[t[s>>2]>>2]=t[n>>2],t[s>>2]=(t[s>>2]|0)+4,bM(e,r),BM(r),m=h;return}}function E_(e){return e=e|0,t[e>>2]|0}function gM(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,yM(e,n,r,u,l,s)}function PE(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-4-u|0)>>>2)<<2)),yt(r))}function F1(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-4-u|0)>>>2)<<2)),yt(r))}function yM(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0;var h=0,D=0,S=0,L=0,k=0,I=0;h=m,m=m+48|0,k=h+40|0,D=h+32|0,I=h+24|0,S=h+12|0,L=h,ka(D),e=yo(e)|0,t[I>>2]=t[n>>2],r=t[r>>2]|0,u=t[u>>2]|0,IE(S,l),_M(L,s),t[k>>2]=t[I>>2],EM(e,k,r,u,S,L),PE(L),F1(S),La(D),m=h}function IE(e,n){e=e|0,n=n|0;var r=0,u=0;t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,r=n+4|0,u=(t[r>>2]|0)-(t[n>>2]|0)>>2,u|0&&(FM(e,u),PM(e,t[n>>2]|0,t[r>>2]|0,u))}function _M(e,n){e=e|0,n=n|0;var r=0,u=0;t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,r=n+4|0,u=(t[r>>2]|0)-(t[n>>2]|0)>>2,u|0&&(LM(e,u),NM(e,t[n>>2]|0,t[r>>2]|0,u))}function EM(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0;var h=0,D=0,S=0,L=0,k=0,I=0;h=m,m=m+32|0,k=h+28|0,I=h+24|0,D=h+12|0,S=h,L=_o(DM()|0)|0,t[I>>2]=t[n>>2],t[k>>2]=t[I>>2],n=Kp(k)|0,r=i8(r)|0,u=bE(u)|0,t[D>>2]=t[l>>2],k=l+4|0,t[D+4>>2]=t[k>>2],I=l+8|0,t[D+8>>2]=t[I>>2],t[I>>2]=0,t[k>>2]=0,t[l>>2]=0,l=BE(D)|0,t[S>>2]=t[s>>2],k=s+4|0,t[S+4>>2]=t[k>>2],I=s+8|0,t[S+8>>2]=t[I>>2],t[I>>2]=0,t[k>>2]=0,t[s>>2]=0,X0(0,L|0,e|0,n|0,r|0,u|0,l|0,wM(S)|0)|0,PE(S),F1(D),m=h}function DM(){var e=0;return c[7968]|0||(MM(10708),e=7968,t[e>>2]=1,t[e+4>>2]=0),10708}function Kp(e){return e=e|0,o8(e)|0}function i8(e){return e=e|0,u8(e)|0}function bE(e){return e=e|0,H0(e)|0}function BE(e){return e=e|0,TM(e)|0}function wM(e){return e=e|0,SM(e)|0}function SM(e){e=e|0;var n=0,r=0,u=0;if(u=(t[e+4>>2]|0)-(t[e>>2]|0)|0,r=u>>2,u=Ma(u+4|0)|0,t[u>>2]=r,r|0){n=0;do t[u+4+(n<<2)>>2]=u8(t[(t[e>>2]|0)+(n<<2)>>2]|0)|0,n=n+1|0;while((n|0)!=(r|0))}return u|0}function u8(e){return e=e|0,e|0}function TM(e){e=e|0;var n=0,r=0,u=0;if(u=(t[e+4>>2]|0)-(t[e>>2]|0)|0,r=u>>2,u=Ma(u+4|0)|0,t[u>>2]=r,r|0){n=0;do t[u+4+(n<<2)>>2]=o8((t[e>>2]|0)+(n<<2)|0)|0,n=n+1|0;while((n|0)!=(r|0))}return u|0}function o8(e){e=e|0;var n=0,r=0,u=0,l=0;return l=m,m=m+32|0,n=l+12|0,r=l,u=Iu(l8()|0)|0,u?(is(n,u),kf(r,n),lF(e,r),e=xs(n)|0):e=CM(e)|0,m=l,e|0}function l8(){var e=0;return c[7960]|0||(OM(10664),Wt(25,10664,se|0)|0,e=7960,t[e>>2]=1,t[e+4>>2]=0),10664}function CM(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0;return r=m,m=m+16|0,l=r+4|0,h=r,u=Ma(8)|0,n=u,D=pn(4)|0,t[D>>2]=t[e>>2],s=n+4|0,t[s>>2]=D,e=pn(8)|0,s=t[s>>2]|0,t[h>>2]=0,t[l>>2]=t[h>>2],s8(e,s,l),t[u>>2]=e,m=r,n|0}function s8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=pn(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1656,t[r+12>>2]=n,t[e+4>>2]=r}function xM(e){e=e|0,Uv(e),yt(e)}function AM(e){e=e|0,e=t[e+12>>2]|0,e|0&&yt(e)}function RM(e){e=e|0,yt(e)}function OM(e){e=e|0,Qa(e)}function MM(e){e=e|0,ll(e,kM()|0,5)}function kM(){return 1676}function LM(e,n){e=e|0,n=n|0;var r=0;if((a8(e)|0)>>>0>>0&&hi(e),n>>>0>1073741823)$n();else{r=pn(n<<2)|0,t[e+4>>2]=r,t[e>>2]=r,t[e+8>>2]=r+(n<<2);return}}function NM(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,u=e+4|0,e=r-n|0,(e|0)>0&&(_r(t[u>>2]|0,n|0,e|0)|0,t[u>>2]=(t[u>>2]|0)+(e>>>2<<2))}function a8(e){return e=e|0,1073741823}function FM(e,n){e=e|0,n=n|0;var r=0;if((f8(e)|0)>>>0>>0&&hi(e),n>>>0>1073741823)$n();else{r=pn(n<<2)|0,t[e+4>>2]=r,t[e>>2]=r,t[e+8>>2]=r+(n<<2);return}}function PM(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,u=e+4|0,e=r-n|0,(e|0)>0&&(_r(t[u>>2]|0,n|0,e|0)|0,t[u>>2]=(t[u>>2]|0)+(e>>>2<<2))}function f8(e){return e=e|0,1073741823}function IM(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>1073741823)$n();else{l=pn(n<<2)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<2)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<2)}function bM(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>2)<<2)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function BM(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-4-n|0)>>>2)<<2)),e=t[e>>2]|0,e|0&&yt(e)}function c8(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>1073741823)$n();else{l=pn(n<<2)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<2)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<2)}function d8(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>2)<<2)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function p8(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-4-n|0)>>>2)<<2)),e=t[e>>2]|0,e|0&&yt(e)}function UM(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0;if(ge=m,m=m+32|0,k=ge+20|0,I=ge+12|0,L=ge+16|0,K=ge+4|0,be=ge,Se=ge+8|0,D=t8()|0,s=t[D>>2]|0,h=t[s>>2]|0,h|0)for(S=t[D+8>>2]|0,D=t[D+4>>2]|0;Yf(k,h),jM(e,k,D,S),s=s+4|0,h=t[s>>2]|0,h;)S=S+1|0,D=D+1|0;if(s=n8()|0,h=t[s>>2]|0,h|0)do Yf(k,h),t[I>>2]=t[s+4>>2],zM(n,k,I),s=s+8|0,h=t[s>>2]|0;while((h|0)!=0);if(s=t[(Fv()|0)>>2]|0,s|0)do n=t[s+4>>2]|0,Yf(k,t[(Pv(n)|0)>>2]|0),t[I>>2]=kE(n)|0,HM(r,k,I),s=t[s>>2]|0;while((s|0)!=0);if(Yf(L,0),s=LE()|0,t[k>>2]=t[L>>2],r8(k,s,l),s=t[(Fv()|0)>>2]|0,s|0){e=k+4|0,n=k+8|0,r=k+8|0;do{if(S=t[s+4>>2]|0,Yf(I,t[(Pv(S)|0)>>2]|0),qM(K,h8(S)|0),h=t[K>>2]|0,h|0){t[k>>2]=0,t[e>>2]=0,t[n>>2]=0;do Yf(be,t[(Pv(t[h+4>>2]|0)|0)>>2]|0),D=t[e>>2]|0,D>>>0<(t[r>>2]|0)>>>0?(t[D>>2]=t[be>>2],t[e>>2]=(t[e>>2]|0)+4):FE(k,be),h=t[h>>2]|0;while((h|0)!=0);WM(u,I,k),F1(k)}t[Se>>2]=t[I>>2],L=v8(S)|0,t[k>>2]=t[Se>>2],r8(k,L,l),Ed(K),s=t[s>>2]|0}while((s|0)!=0)}m=ge}function jM(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,nk(e,n,r,u)}function zM(e,n,r){e=e|0,n=n|0,r=r|0,tk(e,n,r)}function Pv(e){return e=e|0,e|0}function HM(e,n,r){e=e|0,n=n|0,r=r|0,JM(e,n,r)}function h8(e){return e=e|0,e+16|0}function qM(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;if(s=m,m=m+16|0,l=s+8|0,r=s,t[e>>2]=0,u=t[n>>2]|0,t[l>>2]=u,t[r>>2]=e,r=QM(r)|0,u|0){if(u=pn(12)|0,h=(m8(l)|0)+4|0,e=t[h+4>>2]|0,n=u+4|0,t[n>>2]=t[h>>2],t[n+4>>2]=e,n=t[t[l>>2]>>2]|0,t[l>>2]=n,!n)e=u;else for(n=u;e=pn(12)|0,S=(m8(l)|0)+4|0,D=t[S+4>>2]|0,h=e+4|0,t[h>>2]=t[S>>2],t[h+4>>2]=D,t[n>>2]=e,h=t[t[l>>2]>>2]|0,t[l>>2]=h,h;)n=e;t[e>>2]=t[r>>2],t[r>>2]=u}m=s}function WM(e,n,r){e=e|0,n=n|0,r=r|0,VM(e,n,r)}function v8(e){return e=e|0,e+24|0}function VM(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+32|0,h=u+24|0,l=u+16|0,D=u+12|0,s=u,ka(l),e=yo(e)|0,t[D>>2]=t[n>>2],IE(s,r),t[h>>2]=t[D>>2],GM(e,h,s),F1(s),La(l),m=u}function GM(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=m,m=m+32|0,h=u+16|0,D=u+12|0,l=u,s=_o(YM()|0)|0,t[D>>2]=t[n>>2],t[h>>2]=t[D>>2],n=Kp(h)|0,t[l>>2]=t[r>>2],h=r+4|0,t[l+4>>2]=t[h>>2],D=r+8|0,t[l+8>>2]=t[D>>2],t[D>>2]=0,t[h>>2]=0,t[r>>2]=0,P0(0,s|0,e|0,n|0,BE(l)|0)|0,F1(l),m=u}function YM(){var e=0;return c[7976]|0||(KM(10720),e=7976,t[e>>2]=1,t[e+4>>2]=0),10720}function KM(e){e=e|0,ll(e,XM()|0,2)}function XM(){return 1732}function QM(e){return e=e|0,t[e>>2]|0}function m8(e){return e=e|0,t[e>>2]|0}function JM(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;u=m,m=m+32|0,s=u+16|0,l=u+8|0,h=u,ka(l),e=yo(e)|0,t[h>>2]=t[n>>2],r=t[r>>2]|0,t[s>>2]=t[h>>2],g8(e,s,r),La(l),m=u}function g8(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;u=m,m=m+16|0,s=u+4|0,h=u,l=_o(ZM()|0)|0,t[h>>2]=t[n>>2],t[s>>2]=t[h>>2],n=Kp(s)|0,P0(0,l|0,e|0,n|0,i8(r)|0)|0,m=u}function ZM(){var e=0;return c[7984]|0||($M(10732),e=7984,t[e>>2]=1,t[e+4>>2]=0),10732}function $M(e){e=e|0,ll(e,ek()|0,2)}function ek(){return 1744}function tk(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;u=m,m=m+32|0,s=u+16|0,l=u+8|0,h=u,ka(l),e=yo(e)|0,t[h>>2]=t[n>>2],r=t[r>>2]|0,t[s>>2]=t[h>>2],g8(e,s,r),La(l),m=u}function nk(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;l=m,m=m+32|0,h=l+16|0,s=l+8|0,D=l,ka(s),e=yo(e)|0,t[D>>2]=t[n>>2],r=c[r>>0]|0,u=c[u>>0]|0,t[h>>2]=t[D>>2],rk(e,h,r,u),La(s),m=l}function rk(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;l=m,m=m+16|0,h=l+4|0,D=l,s=_o(ik()|0)|0,t[D>>2]=t[n>>2],t[h>>2]=t[D>>2],n=Kp(h)|0,r=Iv(r)|0,Hn(0,s|0,e|0,n|0,r|0,Iv(u)|0)|0,m=l}function ik(){var e=0;return c[7992]|0||(ok(10744),e=7992,t[e>>2]=1,t[e+4>>2]=0),10744}function Iv(e){return e=e|0,uk(e)|0}function uk(e){return e=e|0,e&255|0}function ok(e){e=e|0,ll(e,lk()|0,3)}function lk(){return 1756}function sk(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;switch(K=m,m=m+32|0,D=K+8|0,S=K+4|0,L=K+20|0,k=K,Ta(e,0),u=oF(n)|0,t[D>>2]=0,I=D+4|0,t[I>>2]=0,t[D+8>>2]=0,u<<24>>24){case 0:{c[L>>0]=0,ak(S,r,L),D_(e,S)|0,U0(S);break}case 8:{I=WE(n)|0,c[L>>0]=8,Yf(k,t[I+4>>2]|0),fk(S,r,L,k,I+8|0),D_(e,S)|0,U0(S);break}case 9:{if(s=WE(n)|0,n=t[s+4>>2]|0,n|0)for(h=D+8|0,l=s+12|0;n=n+-1|0,Yf(S,t[l>>2]|0),u=t[I>>2]|0,u>>>0<(t[h>>2]|0)>>>0?(t[u>>2]=t[S>>2],t[I>>2]=(t[I>>2]|0)+4):FE(D,S),n;)l=l+4|0;c[L>>0]=9,Yf(k,t[s+8>>2]|0),ck(S,r,L,k,D),D_(e,S)|0,U0(S);break}default:I=WE(n)|0,c[L>>0]=u,Yf(k,t[I+4>>2]|0),dk(S,r,L,k),D_(e,S)|0,U0(S)}F1(D),m=K}function ak(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;u=m,m=m+16|0,l=u,ka(l),n=yo(n)|0,Ck(e,n,c[r>>0]|0),La(l),m=u}function D_(e,n){e=e|0,n=n|0;var r=0;return r=t[e>>2]|0,r|0&&qr(r|0),t[e>>2]=t[n>>2],t[n>>2]=0,e|0}function fk(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0,D=0,S=0;s=m,m=m+32|0,D=s+16|0,h=s+8|0,S=s,ka(h),n=yo(n)|0,r=c[r>>0]|0,t[S>>2]=t[u>>2],l=t[l>>2]|0,t[D>>2]=t[S>>2],Dk(e,n,r,D,l),La(h),m=s}function ck(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0,D=0,S=0,L=0;s=m,m=m+32|0,S=s+24|0,h=s+16|0,L=s+12|0,D=s,ka(h),n=yo(n)|0,r=c[r>>0]|0,t[L>>2]=t[u>>2],IE(D,l),t[S>>2]=t[L>>2],gk(e,n,r,S,D),F1(D),La(h),m=s}function dk(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;l=m,m=m+32|0,h=l+16|0,s=l+8|0,D=l,ka(s),n=yo(n)|0,r=c[r>>0]|0,t[D>>2]=t[u>>2],t[h>>2]=t[D>>2],pk(e,n,r,h),La(s),m=l}function pk(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0,h=0,D=0;l=m,m=m+16|0,s=l+4|0,D=l,h=_o(hk()|0)|0,r=Iv(r)|0,t[D>>2]=t[u>>2],t[s>>2]=t[D>>2],w_(e,P0(0,h|0,n|0,r|0,Kp(s)|0)|0),m=l}function hk(){var e=0;return c[8e3]|0||(vk(10756),e=8e3,t[e>>2]=1,t[e+4>>2]=0),10756}function w_(e,n){e=e|0,n=n|0,Ta(e,n)}function vk(e){e=e|0,ll(e,mk()|0,2)}function mk(){return 1772}function gk(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0,D=0,S=0,L=0;s=m,m=m+32|0,S=s+16|0,L=s+12|0,h=s,D=_o(yk()|0)|0,r=Iv(r)|0,t[L>>2]=t[u>>2],t[S>>2]=t[L>>2],u=Kp(S)|0,t[h>>2]=t[l>>2],S=l+4|0,t[h+4>>2]=t[S>>2],L=l+8|0,t[h+8>>2]=t[L>>2],t[L>>2]=0,t[S>>2]=0,t[l>>2]=0,w_(e,Hn(0,D|0,n|0,r|0,u|0,BE(h)|0)|0),F1(h),m=s}function yk(){var e=0;return c[8008]|0||(_k(10768),e=8008,t[e>>2]=1,t[e+4>>2]=0),10768}function _k(e){e=e|0,ll(e,Ek()|0,3)}function Ek(){return 1784}function Dk(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0,D=0,S=0;s=m,m=m+16|0,D=s+4|0,S=s,h=_o(wk()|0)|0,r=Iv(r)|0,t[S>>2]=t[u>>2],t[D>>2]=t[S>>2],u=Kp(D)|0,w_(e,Hn(0,h|0,n|0,r|0,u|0,bE(l)|0)|0),m=s}function wk(){var e=0;return c[8016]|0||(Sk(10780),e=8016,t[e>>2]=1,t[e+4>>2]=0),10780}function Sk(e){e=e|0,ll(e,Tk()|0,3)}function Tk(){return 1800}function Ck(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=_o(xk()|0)|0,w_(e,Ki(0,u|0,n|0,Iv(r)|0)|0)}function xk(){var e=0;return c[8024]|0||(Ak(10792),e=8024,t[e>>2]=1,t[e+4>>2]=0),10792}function Ak(e){e=e|0,ll(e,Rk()|0,1)}function Rk(){return 1816}function Ok(){Mk(),kk(),Lk()}function Mk(){t[2702]=V8(65536)|0}function kk(){Zk(10856)}function Lk(){Nk(10816)}function Nk(e){e=e|0,Fk(e,5044),Pk(e)|0}function Fk(e,n){e=e|0,n=n|0;var r=0;r=l8()|0,t[e>>2]=r,Gk(r,n),e2(t[e>>2]|0)}function Pk(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,Ik()|0),e|0}function Ik(){var e=0;return c[8032]|0||(y8(10820),Wt(64,10820,se|0)|0,e=8032,t[e>>2]=1,t[e+4>>2]=0),sr(10820)|0||y8(10820),10820}function y8(e){e=e|0,Uk(e),Yp(e,25)}function bk(e){e=e|0,Bk(e+24|0)}function Bk(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function Uk(e){e=e|0;var n=0;n=yr()|0,jn(e,5,18,n,qk()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function jk(e,n){e=e|0,n=n|0,zk(e,n)}function zk(e,n){e=e|0,n=n|0;var r=0,u=0,l=0;r=m,m=m+16|0,u=r,l=r+4|0,If(l,n),t[u>>2]=bf(l,n)|0,Hk(e,u),m=r}function Hk(e,n){e=e|0,n=n|0,_8(e+4|0,t[n>>2]|0),c[e+8>>0]=1}function _8(e,n){e=e|0,n=n|0,t[e>>2]=n}function qk(){return 1824}function Wk(e){return e=e|0,Vk(e)|0}function Vk(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0;return r=m,m=m+16|0,l=r+4|0,h=r,u=Ma(8)|0,n=u,D=pn(4)|0,If(l,e),_8(D,bf(l,e)|0),s=n+4|0,t[s>>2]=D,e=pn(8)|0,s=t[s>>2]|0,t[h>>2]=0,t[l>>2]=t[h>>2],s8(e,s,l),t[u>>2]=e,m=r,n|0}function Ma(e){e=e|0;var n=0,r=0;return e=e+7&-8,(e>>>0<=32768?(n=t[2701]|0,e>>>0<=(65536-n|0)>>>0):0)?(r=(t[2702]|0)+n|0,t[2701]=n+e,e=r):(e=V8(e+8|0)|0,t[e>>2]=t[2703],t[2703]=e,e=e+8|0),e|0}function Gk(e,n){e=e|0,n=n|0,t[e>>2]=Yk()|0,t[e+4>>2]=Kk()|0,t[e+12>>2]=n,t[e+8>>2]=Xk()|0,t[e+32>>2]=9}function Yk(){return 11744}function Kk(){return 1832}function Xk(){return __()|0}function Qk(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(Jk(r),yt(r)):n|0&&yt(n)}function Jk(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function Zk(e){e=e|0,$k(e,5052),eL(e)|0,tL(e,5058,26)|0,nL(e,5069,1)|0,rL(e,5077,10)|0,iL(e,5087,19)|0,uL(e,5094,27)|0}function $k(e,n){e=e|0,n=n|0;var r=0;r=ZN()|0,t[e>>2]=r,$N(r,n),e2(t[e>>2]|0)}function eL(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,BN()|0),e|0}function tL(e,n,r){return e=e|0,n=n|0,r=r|0,EN(e,Fr(n)|0,r,0),e|0}function nL(e,n,r){return e=e|0,n=n|0,r=r|0,uN(e,Fr(n)|0,r,0),e|0}function rL(e,n,r){return e=e|0,n=n|0,r=r|0,IL(e,Fr(n)|0,r,0),e|0}function iL(e,n,r){return e=e|0,n=n|0,r=r|0,DL(e,Fr(n)|0,r,0),e|0}function E8(e,n){e=e|0,n=n|0;var r=0,u=0;e:for(;;){for(r=t[2703]|0;;){if((r|0)==(n|0))break e;if(u=t[r>>2]|0,t[2703]=u,!r)r=u;else break}yt(r)}t[2701]=e}function uL(e,n,r){return e=e|0,n=n|0,r=r|0,oL(e,Fr(n)|0,r,0),e|0}function oL(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=UE()|0,e=lL(r)|0,wi(s,n,l,e,sL(r,u)|0,u)}function UE(){var e=0,n=0;if(c[8040]|0||(w8(10860),Wt(65,10860,se|0)|0,n=8040,t[n>>2]=1,t[n+4>>2]=0),!(sr(10860)|0)){e=10860,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));w8(10860)}return 10860}function lL(e){return e=e|0,e|0}function sL(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=UE()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(D8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(aL(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function D8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function aL(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=fL(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,cL(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,D8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,dL(e,l),pL(l),m=D;return}}function fL(e){return e=e|0,536870911}function cL(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function dL(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function pL(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function w8(e){e=e|0,mL(e)}function hL(e){e=e|0,vL(e+24|0)}function vL(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function mL(e){e=e|0;var n=0;n=yr()|0,jn(e,1,11,n,gL()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function gL(){return 1840}function yL(e,n,r){e=e|0,n=n|0,r=r|0,EL(t[(_L(e)|0)>>2]|0,n,r)}function _L(e){return e=e|0,(t[(UE()|0)+24>>2]|0)+(e<<3)|0}function EL(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;u=m,m=m+16|0,s=u+1|0,l=u,If(s,n),n=bf(s,n)|0,If(l,r),r=bf(l,r)|0,I1[e&31](n,r),m=u}function DL(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=jE()|0,e=wL(r)|0,wi(s,n,l,e,SL(r,u)|0,u)}function jE(){var e=0,n=0;if(c[8048]|0||(T8(10896),Wt(66,10896,se|0)|0,n=8048,t[n>>2]=1,t[n+4>>2]=0),!(sr(10896)|0)){e=10896,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));T8(10896)}return 10896}function wL(e){return e=e|0,e|0}function SL(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=jE()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(S8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(TL(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function S8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function TL(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=CL(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,xL(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,S8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,AL(e,l),RL(l),m=D;return}}function CL(e){return e=e|0,536870911}function xL(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function AL(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function RL(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function T8(e){e=e|0,kL(e)}function OL(e){e=e|0,ML(e+24|0)}function ML(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function kL(e){e=e|0;var n=0;n=yr()|0,jn(e,1,11,n,LL()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function LL(){return 1852}function NL(e,n){return e=e|0,n=n|0,PL(t[(FL(e)|0)>>2]|0,n)|0}function FL(e){return e=e|0,(t[(jE()|0)+24>>2]|0)+(e<<3)|0}function PL(e,n){e=e|0,n=n|0;var r=0,u=0;return r=m,m=m+16|0,u=r,If(u,n),n=bf(u,n)|0,n=H0(Zp[e&31](n)|0)|0,m=r,n|0}function IL(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=zE()|0,e=bL(r)|0,wi(s,n,l,e,BL(r,u)|0,u)}function zE(){var e=0,n=0;if(c[8056]|0||(x8(10932),Wt(67,10932,se|0)|0,n=8056,t[n>>2]=1,t[n+4>>2]=0),!(sr(10932)|0)){e=10932,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));x8(10932)}return 10932}function bL(e){return e=e|0,e|0}function BL(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=zE()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(C8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(UL(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function C8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function UL(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=jL(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,zL(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,C8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,HL(e,l),qL(l),m=D;return}}function jL(e){return e=e|0,536870911}function zL(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function HL(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function qL(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function x8(e){e=e|0,YL(e)}function WL(e){e=e|0,VL(e+24|0)}function VL(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function YL(e){e=e|0;var n=0;n=yr()|0,jn(e,1,7,n,KL()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function KL(){return 1860}function XL(e,n,r){return e=e|0,n=n|0,r=r|0,JL(t[(QL(e)|0)>>2]|0,n,r)|0}function QL(e){return e=e|0,(t[(zE()|0)+24>>2]|0)+(e<<3)|0}function JL(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0;return u=m,m=m+32|0,h=u+12|0,s=u+8|0,D=u,S=u+16|0,l=u+4|0,ZL(S,n),$L(D,S,n),Ks(l,r),r=Xs(l,r)|0,t[h>>2]=t[D>>2],Fg[e&15](s,h,r),r=eN(s)|0,U0(s),Qs(l),m=u,r|0}function ZL(e,n){e=e|0,n=n|0}function $L(e,n,r){e=e|0,n=n|0,r=r|0,tN(e,r)}function eN(e){return e=e|0,yo(e)|0}function tN(e,n){e=e|0,n=n|0;var r=0,u=0,l=0;l=m,m=m+16|0,r=l,u=n,u&1?(nN(r,0),eu(u|0,r|0)|0,rN(e,r),iN(r)):t[e>>2]=t[n>>2],m=l}function nN(e,n){e=e|0,n=n|0,cd(e,n),t[e+4>>2]=0,c[e+8>>0]=0}function rN(e,n){e=e|0,n=n|0,t[e>>2]=t[n+4>>2]}function iN(e){e=e|0,c[e+8>>0]=0}function uN(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=HE()|0,e=oN(r)|0,wi(s,n,l,e,lN(r,u)|0,u)}function HE(){var e=0,n=0;if(c[8064]|0||(R8(10968),Wt(68,10968,se|0)|0,n=8064,t[n>>2]=1,t[n+4>>2]=0),!(sr(10968)|0)){e=10968,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));R8(10968)}return 10968}function oN(e){return e=e|0,e|0}function lN(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=HE()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(A8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(sN(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function A8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function sN(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=aN(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,fN(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,A8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,cN(e,l),dN(l),m=D;return}}function aN(e){return e=e|0,536870911}function fN(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function cN(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function dN(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function R8(e){e=e|0,vN(e)}function pN(e){e=e|0,hN(e+24|0)}function hN(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function vN(e){e=e|0;var n=0;n=yr()|0,jn(e,1,1,n,mN()|0,5),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function mN(){return 1872}function gN(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,_N(t[(yN(e)|0)>>2]|0,n,r,u,l,s)}function yN(e){return e=e|0,(t[(HE()|0)+24>>2]|0)+(e<<3)|0}function _N(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0;var h=0,D=0,S=0,L=0,k=0,I=0;h=m,m=m+32|0,D=h+16|0,S=h+12|0,L=h+8|0,k=h+4|0,I=h,Ks(D,n),n=Xs(D,n)|0,Ks(S,r),r=Xs(S,r)|0,Ks(L,u),u=Xs(L,u)|0,Ks(k,l),l=Xs(k,l)|0,Ks(I,s),s=Xs(I,s)|0,Q8[e&1](n,r,u,l,s),Qs(I),Qs(k),Qs(L),Qs(S),Qs(D),m=h}function EN(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;s=t[e>>2]|0,l=qE()|0,e=DN(r)|0,wi(s,n,l,e,wN(r,u)|0,u)}function qE(){var e=0,n=0;if(c[8072]|0||(M8(11004),Wt(69,11004,se|0)|0,n=8072,t[n>>2]=1,t[n+4>>2]=0),!(sr(11004)|0)){e=11004,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));M8(11004)}return 11004}function DN(e){return e=e|0,e|0}function wN(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0,D=0,S=0;return D=m,m=m+16|0,l=D,s=D+4|0,t[l>>2]=e,S=qE()|0,h=S+24|0,n=hn(n,4)|0,t[s>>2]=n,r=S+28|0,u=t[r>>2]|0,u>>>0<(t[S+32>>2]|0)>>>0?(O8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(SN(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function O8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function SN(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0;if(D=m,m=m+32|0,l=D,s=e+4|0,h=((t[s>>2]|0)-(t[e>>2]|0)>>3)+1|0,u=TN(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,CN(l,k>>3>>>0>>1>>>0?L>>>0>>0?h:L:u,(t[s>>2]|0)-S>>3,e+8|0),h=l+8|0,O8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,xN(e,l),AN(l),m=D;return}}function TN(e){return e=e|0,536870911}function CN(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0;t[e+12>>2]=0,t[e+16>>2]=u;do if(n)if(n>>>0>536870911)$n();else{l=pn(n<<3)|0;break}else l=0;while(0);t[e>>2]=l,u=l+(r<<3)|0,t[e+8>>2]=u,t[e+4>>2]=u,t[e+12>>2]=l+(n<<3)}function xN(e,n){e=e|0,n=n|0;var r=0,u=0,l=0,s=0,h=0;u=t[e>>2]|0,h=e+4|0,s=n+4|0,l=(t[h>>2]|0)-u|0,r=(t[s>>2]|0)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(_r(r|0,u|0,l|0)|0,u=s,r=t[s>>2]|0):u=s,s=t[e>>2]|0,t[e>>2]=r,t[u>>2]=s,s=n+8|0,l=t[h>>2]|0,t[h>>2]=t[s>>2],t[s>>2]=l,s=e+8|0,h=n+12|0,e=t[s>>2]|0,t[s>>2]=t[h>>2],t[h>>2]=e,t[n>>2]=t[u>>2]}function AN(e){e=e|0;var n=0,r=0,u=0;n=t[e+4>>2]|0,r=e+8|0,u=t[r>>2]|0,(u|0)!=(n|0)&&(t[r>>2]=u+(~((u+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&yt(e)}function M8(e){e=e|0,MN(e)}function RN(e){e=e|0,ON(e+24|0)}function ON(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function MN(e){e=e|0;var n=0;n=yr()|0,jn(e,1,12,n,kN()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function kN(){return 1896}function LN(e,n,r){e=e|0,n=n|0,r=r|0,FN(t[(NN(e)|0)>>2]|0,n,r)}function NN(e){return e=e|0,(t[(qE()|0)+24>>2]|0)+(e<<3)|0}function FN(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;u=m,m=m+16|0,s=u+4|0,l=u,PN(s,n),n=IN(s,n)|0,Ks(l,r),r=Xs(l,r)|0,I1[e&31](n,r),Qs(l),m=u}function PN(e,n){e=e|0,n=n|0}function IN(e,n){return e=e|0,n=n|0,bN(n)|0}function bN(e){return e=e|0,e|0}function BN(){var e=0;return c[8080]|0||(k8(11040),Wt(70,11040,se|0)|0,e=8080,t[e>>2]=1,t[e+4>>2]=0),sr(11040)|0||k8(11040),11040}function k8(e){e=e|0,zN(e),Yp(e,71)}function UN(e){e=e|0,jN(e+24|0)}function jN(e){e=e|0;var n=0,r=0,u=0;r=t[e>>2]|0,u=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-u|0)>>>3)<<3)),yt(r))}function zN(e){e=e|0;var n=0;n=yr()|0,jn(e,5,7,n,VN()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function HN(e){e=e|0,qN(e)}function qN(e){e=e|0,WN(e)}function WN(e){e=e|0,c[e+8>>0]=1}function VN(){return 1936}function GN(){return YN()|0}function YN(){var e=0,n=0,r=0,u=0,l=0,s=0,h=0;return n=m,m=m+16|0,l=n+4|0,h=n,r=Ma(8)|0,e=r,s=e+4|0,t[s>>2]=pn(1)|0,u=pn(8)|0,s=t[s>>2]|0,t[h>>2]=0,t[l>>2]=t[h>>2],KN(u,s,l),t[r>>2]=u,m=n,e|0}function KN(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=pn(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1916,t[r+12>>2]=n,t[e+4>>2]=r}function XN(e){e=e|0,Uv(e),yt(e)}function QN(e){e=e|0,e=t[e+12>>2]|0,e|0&&yt(e)}function JN(e){e=e|0,yt(e)}function ZN(){var e=0;return c[8088]|0||(uF(11076),Wt(25,11076,se|0)|0,e=8088,t[e>>2]=1,t[e+4>>2]=0),11076}function $N(e,n){e=e|0,n=n|0,t[e>>2]=eF()|0,t[e+4>>2]=tF()|0,t[e+12>>2]=n,t[e+8>>2]=nF()|0,t[e+32>>2]=10}function eF(){return 11745}function tF(){return 1940}function nF(){return N1()|0}function rF(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(iF(r),yt(r)):n|0&&yt(n)}function iF(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function uF(e){e=e|0,Qa(e)}function Yf(e,n){e=e|0,n=n|0,t[e>>2]=n}function WE(e){return e=e|0,t[e>>2]|0}function oF(e){return e=e|0,c[t[e>>2]>>0]|0}function lF(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,t[u>>2]=t[e>>2],sF(n,u)|0,m=r}function sF(e,n){e=e|0,n=n|0;var r=0;return r=aF(t[e>>2]|0,n)|0,n=e+4|0,t[(t[n>>2]|0)+8>>2]=r,t[(t[n>>2]|0)+8>>2]|0}function aF(e,n){e=e|0,n=n|0;var r=0,u=0;return r=m,m=m+16|0,u=r,ka(u),e=yo(e)|0,n=fF(e,t[n>>2]|0)|0,La(u),m=r,n|0}function ka(e){e=e|0,t[e>>2]=t[2701],t[e+4>>2]=t[2703]}function fF(e,n){e=e|0,n=n|0;var r=0;return r=_o(cF()|0)|0,Ki(0,r|0,e|0,bE(n)|0)|0}function La(e){e=e|0,E8(t[e>>2]|0,t[e+4>>2]|0)}function cF(){var e=0;return c[8096]|0||(dF(11120),e=8096,t[e>>2]=1,t[e+4>>2]=0),11120}function dF(e){e=e|0,ll(e,pF()|0,1)}function pF(){return 1948}function hF(){vF()}function vF(){var e=0,n=0,r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0;if(Se=m,m=m+16|0,k=Se+4|0,I=Se,bn(65536,10804,t[2702]|0,10812),r=t8()|0,n=t[r>>2]|0,e=t[n>>2]|0,e|0)for(u=t[r+8>>2]|0,r=t[r+4>>2]|0;Ql(e|0,O[r>>0]|0|0,c[u>>0]|0),n=n+4|0,e=t[n>>2]|0,e;)u=u+1|0,r=r+1|0;if(e=n8()|0,n=t[e>>2]|0,n|0)do ko(n|0,t[e+4>>2]|0),e=e+8|0,n=t[e>>2]|0;while((n|0)!=0);ko(mF()|0,5167),L=Fv()|0,e=t[L>>2]|0;e:do if(e|0){do gF(t[e+4>>2]|0),e=t[e>>2]|0;while((e|0)!=0);if(e=t[L>>2]|0,e|0){S=L;do{for(;l=e,e=t[e>>2]|0,l=t[l+4>>2]|0,!!(yF(l)|0);)if(t[I>>2]=S,t[k>>2]=t[I>>2],_F(L,k)|0,!e)break e;if(EF(l),S=t[S>>2]|0,n=L8(l)|0,s=fo()|0,h=m,m=m+((1*(n<<2)|0)+15&-16)|0,D=m,m=m+((1*(n<<2)|0)+15&-16)|0,n=t[(h8(l)|0)>>2]|0,n|0)for(r=h,u=D;t[r>>2]=t[(Pv(t[n+4>>2]|0)|0)>>2],t[u>>2]=t[n+8>>2],n=t[n>>2]|0,n;)r=r+4|0,u=u+4|0;ge=Pv(l)|0,n=DF(l)|0,r=L8(l)|0,u=wF(l)|0,Lo(ge|0,n|0,h|0,D|0,r|0,u|0,kE(l)|0),yi(s|0)}while((e|0)!=0)}}while(0);if(e=t[(LE()|0)>>2]|0,e|0)do ge=e+4|0,L=NE(ge)|0,l=Mg(L)|0,s=Rg(L)|0,h=(Og(L)|0)+1|0,D=S_(L)|0,S=N8(ge)|0,L=sr(L)|0,k=E_(ge)|0,I=VE(ge)|0,ao(0,l|0,s|0,h|0,D|0,S|0,L|0,k|0,I|0,GE(ge)|0),e=t[e>>2]|0;while((e|0)!=0);e=t[(Fv()|0)>>2]|0;e:do if(e|0){t:for(;;){if(n=t[e+4>>2]|0,n|0?(K=t[(Pv(n)|0)>>2]|0,be=t[(v8(n)|0)>>2]|0,be|0):0){r=be;do{n=r+4|0,u=NE(n)|0;n:do if(u|0)switch(sr(u)|0){case 0:break t;case 4:case 3:case 2:{D=Mg(u)|0,S=Rg(u)|0,L=(Og(u)|0)+1|0,k=S_(u)|0,I=sr(u)|0,ge=E_(n)|0,ao(K|0,D|0,S|0,L|0,k|0,0,I|0,ge|0,VE(n)|0,GE(n)|0);break n}case 1:{h=Mg(u)|0,D=Rg(u)|0,S=(Og(u)|0)+1|0,L=S_(u)|0,k=N8(n)|0,I=sr(u)|0,ge=E_(n)|0,ao(K|0,h|0,D|0,S|0,L|0,k|0,I|0,ge|0,VE(n)|0,GE(n)|0);break n}case 5:{L=Mg(u)|0,k=Rg(u)|0,I=(Og(u)|0)+1|0,ge=S_(u)|0,ao(K|0,L|0,k|0,I|0,ge|0,SF(u)|0,sr(u)|0,0,0,0);break n}default:break n}while(0);r=t[r>>2]|0}while((r|0)!=0)}if(e=t[e>>2]|0,!e)break e}$n()}while(0);bs(),m=Se}function mF(){return 11703}function gF(e){e=e|0,c[e+40>>0]=0}function yF(e){return e=e|0,(c[e+40>>0]|0)!=0|0}function _F(e,n){return e=e|0,n=n|0,n=TF(n)|0,e=t[n>>2]|0,t[n>>2]=t[e>>2],yt(e),t[n>>2]|0}function EF(e){e=e|0,c[e+40>>0]=1}function L8(e){return e=e|0,t[e+20>>2]|0}function DF(e){return e=e|0,t[e+8>>2]|0}function wF(e){return e=e|0,t[e+32>>2]|0}function S_(e){return e=e|0,t[e+4>>2]|0}function N8(e){return e=e|0,t[e+4>>2]|0}function VE(e){return e=e|0,t[e+8>>2]|0}function GE(e){return e=e|0,t[e+16>>2]|0}function SF(e){return e=e|0,t[e+20>>2]|0}function TF(e){return e=e|0,t[e>>2]|0}function T_(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0,Ze=0,Ge=0,ct=0,Me=0,Pe=0,Zt=0;Zt=m,m=m+16|0,K=Zt;do if(e>>>0<245){if(L=e>>>0<11?16:e+11&-8,e=L>>>3,I=t[2783]|0,r=I>>>e,r&3|0)return n=(r&1^1)+e|0,e=11172+(n<<1<<2)|0,r=e+8|0,u=t[r>>2]|0,l=u+8|0,s=t[l>>2]|0,(e|0)==(s|0)?t[2783]=I&~(1<>2]=e,t[r>>2]=s),Pe=n<<3,t[u+4>>2]=Pe|3,Pe=u+Pe+4|0,t[Pe>>2]=t[Pe>>2]|1,Pe=l,m=Zt,Pe|0;if(k=t[2785]|0,L>>>0>k>>>0){if(r|0)return n=2<>>12&16,n=n>>>h,r=n>>>5&8,n=n>>>r,l=n>>>2&4,n=n>>>l,e=n>>>1&2,n=n>>>e,u=n>>>1&1,u=(r|h|l|e|u)+(n>>>u)|0,n=11172+(u<<1<<2)|0,e=n+8|0,l=t[e>>2]|0,h=l+8|0,r=t[h>>2]|0,(n|0)==(r|0)?(e=I&~(1<>2]=n,t[e>>2]=r,e=I),s=(u<<3)-L|0,t[l+4>>2]=L|3,u=l+L|0,t[u+4>>2]=s|1,t[u+s>>2]=s,k|0&&(l=t[2788]|0,n=k>>>3,r=11172+(n<<1<<2)|0,n=1<>2]|0):(t[2783]=e|n,n=r,e=r+8|0),t[e>>2]=l,t[n+12>>2]=l,t[l+8>>2]=n,t[l+12>>2]=r),t[2785]=s,t[2788]=u,Pe=h,m=Zt,Pe|0;if(D=t[2784]|0,D){if(r=(D&0-D)+-1|0,h=r>>>12&16,r=r>>>h,s=r>>>5&8,r=r>>>s,S=r>>>2&4,r=r>>>S,u=r>>>1&2,r=r>>>u,e=r>>>1&1,e=t[11436+((s|h|S|u|e)+(r>>>e)<<2)>>2]|0,r=(t[e+4>>2]&-8)-L|0,u=t[e+16+(((t[e+16>>2]|0)==0&1)<<2)>>2]|0,!u)S=e,s=r;else{do h=(t[u+4>>2]&-8)-L|0,S=h>>>0>>0,r=S?h:r,e=S?u:e,u=t[u+16+(((t[u+16>>2]|0)==0&1)<<2)>>2]|0;while((u|0)!=0);S=e,s=r}if(h=S+L|0,S>>>0>>0){l=t[S+24>>2]|0,n=t[S+12>>2]|0;do if((n|0)==(S|0)){if(e=S+20|0,n=t[e>>2]|0,!n&&(e=S+16|0,n=t[e>>2]|0,!n)){r=0;break}for(;;){if(r=n+20|0,u=t[r>>2]|0,u|0){n=u,e=r;continue}if(r=n+16|0,u=t[r>>2]|0,u)n=u,e=r;else break}t[e>>2]=0,r=n}else r=t[S+8>>2]|0,t[r+12>>2]=n,t[n+8>>2]=r,r=n;while(0);do if(l|0){if(n=t[S+28>>2]|0,e=11436+(n<<2)|0,(S|0)==(t[e>>2]|0)){if(t[e>>2]=r,!r){t[2784]=D&~(1<>2]|0)!=(S|0)&1)<<2)>>2]=r,!r)break;t[r+24>>2]=l,n=t[S+16>>2]|0,n|0&&(t[r+16>>2]=n,t[n+24>>2]=r),n=t[S+20>>2]|0,n|0&&(t[r+20>>2]=n,t[n+24>>2]=r)}while(0);return s>>>0<16?(Pe=s+L|0,t[S+4>>2]=Pe|3,Pe=S+Pe+4|0,t[Pe>>2]=t[Pe>>2]|1):(t[S+4>>2]=L|3,t[h+4>>2]=s|1,t[h+s>>2]=s,k|0&&(u=t[2788]|0,n=k>>>3,r=11172+(n<<1<<2)|0,n=1<>2]|0):(t[2783]=I|n,n=r,e=r+8|0),t[e>>2]=u,t[n+12>>2]=u,t[u+8>>2]=n,t[u+12>>2]=r),t[2785]=s,t[2788]=h),Pe=S+8|0,m=Zt,Pe|0}else I=L}else I=L}else I=L}else if(e>>>0<=4294967231)if(e=e+11|0,L=e&-8,S=t[2784]|0,S){u=0-L|0,e=e>>>8,e?L>>>0>16777215?D=31:(I=(e+1048320|0)>>>16&8,Me=e<>>16&4,Me=Me<>>16&2,D=14-(k|I|D)+(Me<>>15)|0,D=L>>>(D+7|0)&1|D<<1):D=0,r=t[11436+(D<<2)>>2]|0;e:do if(!r)r=0,e=0,Me=57;else for(e=0,h=L<<((D|0)==31?0:25-(D>>>1)|0),s=0;;){if(l=(t[r+4>>2]&-8)-L|0,l>>>0>>0)if(l)e=r,u=l;else{e=r,u=0,l=r,Me=61;break e}if(l=t[r+20>>2]|0,r=t[r+16+(h>>>31<<2)>>2]|0,s=(l|0)==0|(l|0)==(r|0)?s:l,l=(r|0)==0,l){r=s,Me=57;break}else h=h<<((l^1)&1)}while(0);if((Me|0)==57){if((r|0)==0&(e|0)==0){if(e=2<>>12&16,I=I>>>h,s=I>>>5&8,I=I>>>s,D=I>>>2&4,I=I>>>D,k=I>>>1&2,I=I>>>k,r=I>>>1&1,e=0,r=t[11436+((s|h|D|k|r)+(I>>>r)<<2)>>2]|0}r?(l=r,Me=61):(D=e,h=u)}if((Me|0)==61)for(;;)if(Me=0,r=(t[l+4>>2]&-8)-L|0,I=r>>>0>>0,r=I?r:u,e=I?l:e,l=t[l+16+(((t[l+16>>2]|0)==0&1)<<2)>>2]|0,l)u=r,Me=61;else{D=e,h=r;break}if((D|0)!=0?h>>>0<((t[2785]|0)-L|0)>>>0:0){if(s=D+L|0,D>>>0>=s>>>0)return Pe=0,m=Zt,Pe|0;l=t[D+24>>2]|0,n=t[D+12>>2]|0;do if((n|0)==(D|0)){if(e=D+20|0,n=t[e>>2]|0,!n&&(e=D+16|0,n=t[e>>2]|0,!n)){n=0;break}for(;;){if(r=n+20|0,u=t[r>>2]|0,u|0){n=u,e=r;continue}if(r=n+16|0,u=t[r>>2]|0,u)n=u,e=r;else break}t[e>>2]=0}else Pe=t[D+8>>2]|0,t[Pe+12>>2]=n,t[n+8>>2]=Pe;while(0);do if(l){if(e=t[D+28>>2]|0,r=11436+(e<<2)|0,(D|0)==(t[r>>2]|0)){if(t[r>>2]=n,!n){u=S&~(1<>2]|0)!=(D|0)&1)<<2)>>2]=n,!n){u=S;break}t[n+24>>2]=l,e=t[D+16>>2]|0,e|0&&(t[n+16>>2]=e,t[e+24>>2]=n),e=t[D+20>>2]|0,e&&(t[n+20>>2]=e,t[e+24>>2]=n),u=S}else u=S;while(0);do if(h>>>0>=16){if(t[D+4>>2]=L|3,t[s+4>>2]=h|1,t[s+h>>2]=h,n=h>>>3,h>>>0<256){r=11172+(n<<1<<2)|0,e=t[2783]|0,n=1<>2]|0):(t[2783]=e|n,n=r,e=r+8|0),t[e>>2]=s,t[n+12>>2]=s,t[s+8>>2]=n,t[s+12>>2]=r;break}if(n=h>>>8,n?h>>>0>16777215?n=31:(Me=(n+1048320|0)>>>16&8,Pe=n<>>16&4,Pe=Pe<>>16&2,n=14-(ct|Me|n)+(Pe<>>15)|0,n=h>>>(n+7|0)&1|n<<1):n=0,r=11436+(n<<2)|0,t[s+28>>2]=n,e=s+16|0,t[e+4>>2]=0,t[e>>2]=0,e=1<>2]=s,t[s+24>>2]=r,t[s+12>>2]=s,t[s+8>>2]=s;break}for(e=h<<((n|0)==31?0:25-(n>>>1)|0),r=t[r>>2]|0;;){if((t[r+4>>2]&-8|0)==(h|0)){Me=97;break}if(u=r+16+(e>>>31<<2)|0,n=t[u>>2]|0,n)e=e<<1,r=n;else{Me=96;break}}if((Me|0)==96){t[u>>2]=s,t[s+24>>2]=r,t[s+12>>2]=s,t[s+8>>2]=s;break}else if((Me|0)==97){Me=r+8|0,Pe=t[Me>>2]|0,t[Pe+12>>2]=s,t[Me>>2]=s,t[s+8>>2]=Pe,t[s+12>>2]=r,t[s+24>>2]=0;break}}else Pe=h+L|0,t[D+4>>2]=Pe|3,Pe=D+Pe+4|0,t[Pe>>2]=t[Pe>>2]|1;while(0);return Pe=D+8|0,m=Zt,Pe|0}else I=L}else I=L;else I=-1;while(0);if(r=t[2785]|0,r>>>0>=I>>>0)return n=r-I|0,e=t[2788]|0,n>>>0>15?(Pe=e+I|0,t[2788]=Pe,t[2785]=n,t[Pe+4>>2]=n|1,t[Pe+n>>2]=n,t[e+4>>2]=I|3):(t[2785]=0,t[2788]=0,t[e+4>>2]=r|3,Pe=e+r+4|0,t[Pe>>2]=t[Pe>>2]|1),Pe=e+8|0,m=Zt,Pe|0;if(h=t[2786]|0,h>>>0>I>>>0)return ct=h-I|0,t[2786]=ct,Pe=t[2789]|0,Me=Pe+I|0,t[2789]=Me,t[Me+4>>2]=ct|1,t[Pe+4>>2]=I|3,Pe=Pe+8|0,m=Zt,Pe|0;if(t[2901]|0?e=t[2903]|0:(t[2903]=4096,t[2902]=4096,t[2904]=-1,t[2905]=-1,t[2906]=0,t[2894]=0,e=K&-16^1431655768,t[K>>2]=e,t[2901]=e,e=4096),D=I+48|0,S=I+47|0,s=e+S|0,l=0-e|0,L=s&l,L>>>0<=I>>>0||(e=t[2893]|0,e|0?(k=t[2891]|0,K=k+L|0,K>>>0<=k>>>0|K>>>0>e>>>0):0))return Pe=0,m=Zt,Pe|0;e:do if(t[2894]&4)n=0,Me=133;else{r=t[2789]|0;t:do if(r){for(u=11580;e=t[u>>2]|0,!(e>>>0<=r>>>0?(ge=u+4|0,(e+(t[ge>>2]|0)|0)>>>0>r>>>0):0);)if(e=t[u+8>>2]|0,e)u=e;else{Me=118;break t}if(n=s-h&l,n>>>0<2147483647)if(e=n2(n|0)|0,(e|0)==((t[u>>2]|0)+(t[ge>>2]|0)|0)){if((e|0)!=(-1|0)){h=n,s=e,Me=135;break e}}else u=e,Me=126;else n=0}else Me=118;while(0);do if((Me|0)==118)if(r=n2(0)|0,(r|0)!=(-1|0)?(n=r,be=t[2902]|0,Se=be+-1|0,n=((Se&n|0)==0?0:(Se+n&0-be)-n|0)+L|0,be=t[2891]|0,Se=n+be|0,n>>>0>I>>>0&n>>>0<2147483647):0){if(ge=t[2893]|0,ge|0?Se>>>0<=be>>>0|Se>>>0>ge>>>0:0){n=0;break}if(e=n2(n|0)|0,(e|0)==(r|0)){h=n,s=r,Me=135;break e}else u=e,Me=126}else n=0;while(0);do if((Me|0)==126){if(r=0-n|0,!(D>>>0>n>>>0&(n>>>0<2147483647&(u|0)!=(-1|0))))if((u|0)==(-1|0)){n=0;break}else{h=n,s=u,Me=135;break e}if(e=t[2903]|0,e=S-n+e&0-e,e>>>0>=2147483647){h=n,s=u,Me=135;break e}if((n2(e|0)|0)==(-1|0)){n2(r|0)|0,n=0;break}else{h=e+n|0,s=u,Me=135;break e}}while(0);t[2894]=t[2894]|4,Me=133}while(0);if((((Me|0)==133?L>>>0<2147483647:0)?(ct=n2(L|0)|0,ge=n2(0)|0,Ze=ge-ct|0,Ge=Ze>>>0>(I+40|0)>>>0,!((ct|0)==(-1|0)|Ge^1|ct>>>0>>0&((ct|0)!=(-1|0)&(ge|0)!=(-1|0))^1)):0)&&(h=Ge?Ze:n,s=ct,Me=135),(Me|0)==135){n=(t[2891]|0)+h|0,t[2891]=n,n>>>0>(t[2892]|0)>>>0&&(t[2892]=n),S=t[2789]|0;do if(S){for(n=11580;;){if(e=t[n>>2]|0,r=n+4|0,u=t[r>>2]|0,(s|0)==(e+u|0)){Me=145;break}if(l=t[n+8>>2]|0,l)n=l;else break}if(((Me|0)==145?(t[n+12>>2]&8|0)==0:0)?S>>>0>>0&S>>>0>=e>>>0:0){t[r>>2]=u+h,Pe=S+8|0,Pe=(Pe&7|0)==0?0:0-Pe&7,Me=S+Pe|0,Pe=(t[2786]|0)+(h-Pe)|0,t[2789]=Me,t[2786]=Pe,t[Me+4>>2]=Pe|1,t[Me+Pe+4>>2]=40,t[2790]=t[2905];break}for(s>>>0<(t[2787]|0)>>>0&&(t[2787]=s),r=s+h|0,n=11580;;){if((t[n>>2]|0)==(r|0)){Me=153;break}if(e=t[n+8>>2]|0,e)n=e;else break}if((Me|0)==153?(t[n+12>>2]&8|0)==0:0){t[n>>2]=s,k=n+4|0,t[k>>2]=(t[k>>2]|0)+h,k=s+8|0,k=s+((k&7|0)==0?0:0-k&7)|0,n=r+8|0,n=r+((n&7|0)==0?0:0-n&7)|0,L=k+I|0,D=n-k-I|0,t[k+4>>2]=I|3;do if((n|0)!=(S|0)){if((n|0)==(t[2788]|0)){Pe=(t[2785]|0)+D|0,t[2785]=Pe,t[2788]=L,t[L+4>>2]=Pe|1,t[L+Pe>>2]=Pe;break}if(e=t[n+4>>2]|0,(e&3|0)==1){h=e&-8,u=e>>>3;e:do if(e>>>0<256)if(e=t[n+8>>2]|0,r=t[n+12>>2]|0,(r|0)==(e|0)){t[2783]=t[2783]&~(1<>2]=r,t[r+8>>2]=e;break}else{s=t[n+24>>2]|0,e=t[n+12>>2]|0;do if((e|0)==(n|0)){if(u=n+16|0,r=u+4|0,e=t[r>>2]|0,!e)if(e=t[u>>2]|0,e)r=u;else{e=0;break}for(;;){if(u=e+20|0,l=t[u>>2]|0,l|0){e=l,r=u;continue}if(u=e+16|0,l=t[u>>2]|0,l)e=l,r=u;else break}t[r>>2]=0}else Pe=t[n+8>>2]|0,t[Pe+12>>2]=e,t[e+8>>2]=Pe;while(0);if(!s)break;r=t[n+28>>2]|0,u=11436+(r<<2)|0;do if((n|0)!=(t[u>>2]|0)){if(t[s+16+(((t[s+16>>2]|0)!=(n|0)&1)<<2)>>2]=e,!e)break e}else{if(t[u>>2]=e,e|0)break;t[2784]=t[2784]&~(1<>2]=s,r=n+16|0,u=t[r>>2]|0,u|0&&(t[e+16>>2]=u,t[u+24>>2]=e),r=t[r+4>>2]|0,!r)break;t[e+20>>2]=r,t[r+24>>2]=e}while(0);n=n+h|0,l=h+D|0}else l=D;if(n=n+4|0,t[n>>2]=t[n>>2]&-2,t[L+4>>2]=l|1,t[L+l>>2]=l,n=l>>>3,l>>>0<256){r=11172+(n<<1<<2)|0,e=t[2783]|0,n=1<>2]|0):(t[2783]=e|n,n=r,e=r+8|0),t[e>>2]=L,t[n+12>>2]=L,t[L+8>>2]=n,t[L+12>>2]=r;break}n=l>>>8;do if(!n)n=0;else{if(l>>>0>16777215){n=31;break}Me=(n+1048320|0)>>>16&8,Pe=n<>>16&4,Pe=Pe<>>16&2,n=14-(ct|Me|n)+(Pe<>>15)|0,n=l>>>(n+7|0)&1|n<<1}while(0);if(u=11436+(n<<2)|0,t[L+28>>2]=n,e=L+16|0,t[e+4>>2]=0,t[e>>2]=0,e=t[2784]|0,r=1<>2]=L,t[L+24>>2]=u,t[L+12>>2]=L,t[L+8>>2]=L;break}for(e=l<<((n|0)==31?0:25-(n>>>1)|0),r=t[u>>2]|0;;){if((t[r+4>>2]&-8|0)==(l|0)){Me=194;break}if(u=r+16+(e>>>31<<2)|0,n=t[u>>2]|0,n)e=e<<1,r=n;else{Me=193;break}}if((Me|0)==193){t[u>>2]=L,t[L+24>>2]=r,t[L+12>>2]=L,t[L+8>>2]=L;break}else if((Me|0)==194){Me=r+8|0,Pe=t[Me>>2]|0,t[Pe+12>>2]=L,t[Me>>2]=L,t[L+8>>2]=Pe,t[L+12>>2]=r,t[L+24>>2]=0;break}}else Pe=(t[2786]|0)+D|0,t[2786]=Pe,t[2789]=L,t[L+4>>2]=Pe|1;while(0);return Pe=k+8|0,m=Zt,Pe|0}for(n=11580;e=t[n>>2]|0,!(e>>>0<=S>>>0?(Pe=e+(t[n+4>>2]|0)|0,Pe>>>0>S>>>0):0);)n=t[n+8>>2]|0;l=Pe+-47|0,e=l+8|0,e=l+((e&7|0)==0?0:0-e&7)|0,l=S+16|0,e=e>>>0>>0?S:e,n=e+8|0,r=s+8|0,r=(r&7|0)==0?0:0-r&7,Me=s+r|0,r=h+-40-r|0,t[2789]=Me,t[2786]=r,t[Me+4>>2]=r|1,t[Me+r+4>>2]=40,t[2790]=t[2905],r=e+4|0,t[r>>2]=27,t[n>>2]=t[2895],t[n+4>>2]=t[2896],t[n+8>>2]=t[2897],t[n+12>>2]=t[2898],t[2895]=s,t[2896]=h,t[2898]=0,t[2897]=n,n=e+24|0;do Me=n,n=n+4|0,t[n>>2]=7;while((Me+8|0)>>>0>>0);if((e|0)!=(S|0)){if(s=e-S|0,t[r>>2]=t[r>>2]&-2,t[S+4>>2]=s|1,t[e>>2]=s,n=s>>>3,s>>>0<256){r=11172+(n<<1<<2)|0,e=t[2783]|0,n=1<>2]|0):(t[2783]=e|n,n=r,e=r+8|0),t[e>>2]=S,t[n+12>>2]=S,t[S+8>>2]=n,t[S+12>>2]=r;break}if(n=s>>>8,n?s>>>0>16777215?r=31:(Me=(n+1048320|0)>>>16&8,Pe=n<>>16&4,Pe=Pe<>>16&2,r=14-(ct|Me|r)+(Pe<>>15)|0,r=s>>>(r+7|0)&1|r<<1):r=0,u=11436+(r<<2)|0,t[S+28>>2]=r,t[S+20>>2]=0,t[l>>2]=0,n=t[2784]|0,e=1<>2]=S,t[S+24>>2]=u,t[S+12>>2]=S,t[S+8>>2]=S;break}for(e=s<<((r|0)==31?0:25-(r>>>1)|0),r=t[u>>2]|0;;){if((t[r+4>>2]&-8|0)==(s|0)){Me=216;break}if(u=r+16+(e>>>31<<2)|0,n=t[u>>2]|0,n)e=e<<1,r=n;else{Me=215;break}}if((Me|0)==215){t[u>>2]=S,t[S+24>>2]=r,t[S+12>>2]=S,t[S+8>>2]=S;break}else if((Me|0)==216){Me=r+8|0,Pe=t[Me>>2]|0,t[Pe+12>>2]=S,t[Me>>2]=S,t[S+8>>2]=Pe,t[S+12>>2]=r,t[S+24>>2]=0;break}}}else{Pe=t[2787]|0,(Pe|0)==0|s>>>0>>0&&(t[2787]=s),t[2895]=s,t[2896]=h,t[2898]=0,t[2792]=t[2901],t[2791]=-1,n=0;do Pe=11172+(n<<1<<2)|0,t[Pe+12>>2]=Pe,t[Pe+8>>2]=Pe,n=n+1|0;while((n|0)!=32);Pe=s+8|0,Pe=(Pe&7|0)==0?0:0-Pe&7,Me=s+Pe|0,Pe=h+-40-Pe|0,t[2789]=Me,t[2786]=Pe,t[Me+4>>2]=Pe|1,t[Me+Pe+4>>2]=40,t[2790]=t[2905]}while(0);if(n=t[2786]|0,n>>>0>I>>>0)return ct=n-I|0,t[2786]=ct,Pe=t[2789]|0,Me=Pe+I|0,t[2789]=Me,t[Me+4>>2]=ct|1,t[Pe+4>>2]=I|3,Pe=Pe+8|0,m=Zt,Pe|0}return t[(bv()|0)>>2]=12,Pe=0,m=Zt,Pe|0}function C_(e){e=e|0;var n=0,r=0,u=0,l=0,s=0,h=0,D=0,S=0;if(!!e){r=e+-8|0,l=t[2787]|0,e=t[e+-4>>2]|0,n=e&-8,S=r+n|0;do if(e&1)D=r,h=r;else{if(u=t[r>>2]|0,!(e&3)||(h=r+(0-u)|0,s=u+n|0,h>>>0>>0))return;if((h|0)==(t[2788]|0)){if(e=S+4|0,n=t[e>>2]|0,(n&3|0)!=3){D=h,n=s;break}t[2785]=s,t[e>>2]=n&-2,t[h+4>>2]=s|1,t[h+s>>2]=s;return}if(r=u>>>3,u>>>0<256)if(e=t[h+8>>2]|0,n=t[h+12>>2]|0,(n|0)==(e|0)){t[2783]=t[2783]&~(1<>2]=n,t[n+8>>2]=e,D=h,n=s;break}l=t[h+24>>2]|0,e=t[h+12>>2]|0;do if((e|0)==(h|0)){if(r=h+16|0,n=r+4|0,e=t[n>>2]|0,!e)if(e=t[r>>2]|0,e)n=r;else{e=0;break}for(;;){if(r=e+20|0,u=t[r>>2]|0,u|0){e=u,n=r;continue}if(r=e+16|0,u=t[r>>2]|0,u)e=u,n=r;else break}t[n>>2]=0}else D=t[h+8>>2]|0,t[D+12>>2]=e,t[e+8>>2]=D;while(0);if(l){if(n=t[h+28>>2]|0,r=11436+(n<<2)|0,(h|0)==(t[r>>2]|0)){if(t[r>>2]=e,!e){t[2784]=t[2784]&~(1<>2]|0)!=(h|0)&1)<<2)>>2]=e,!e){D=h,n=s;break}t[e+24>>2]=l,n=h+16|0,r=t[n>>2]|0,r|0&&(t[e+16>>2]=r,t[r+24>>2]=e),n=t[n+4>>2]|0,n?(t[e+20>>2]=n,t[n+24>>2]=e,D=h,n=s):(D=h,n=s)}else D=h,n=s}while(0);if(!(h>>>0>=S>>>0)&&(e=S+4|0,u=t[e>>2]|0,!!(u&1))){if(u&2)t[e>>2]=u&-2,t[D+4>>2]=n|1,t[h+n>>2]=n,l=n;else{if(e=t[2788]|0,(S|0)==(t[2789]|0)){if(S=(t[2786]|0)+n|0,t[2786]=S,t[2789]=D,t[D+4>>2]=S|1,(D|0)!=(e|0))return;t[2788]=0,t[2785]=0;return}if((S|0)==(e|0)){S=(t[2785]|0)+n|0,t[2785]=S,t[2788]=h,t[D+4>>2]=S|1,t[h+S>>2]=S;return}l=(u&-8)+n|0,r=u>>>3;do if(u>>>0<256)if(n=t[S+8>>2]|0,e=t[S+12>>2]|0,(e|0)==(n|0)){t[2783]=t[2783]&~(1<>2]=e,t[e+8>>2]=n;break}else{s=t[S+24>>2]|0,e=t[S+12>>2]|0;do if((e|0)==(S|0)){if(r=S+16|0,n=r+4|0,e=t[n>>2]|0,!e)if(e=t[r>>2]|0,e)n=r;else{r=0;break}for(;;){if(r=e+20|0,u=t[r>>2]|0,u|0){e=u,n=r;continue}if(r=e+16|0,u=t[r>>2]|0,u)e=u,n=r;else break}t[n>>2]=0,r=e}else r=t[S+8>>2]|0,t[r+12>>2]=e,t[e+8>>2]=r,r=e;while(0);if(s|0){if(e=t[S+28>>2]|0,n=11436+(e<<2)|0,(S|0)==(t[n>>2]|0)){if(t[n>>2]=r,!r){t[2784]=t[2784]&~(1<>2]|0)!=(S|0)&1)<<2)>>2]=r,!r)break;t[r+24>>2]=s,e=S+16|0,n=t[e>>2]|0,n|0&&(t[r+16>>2]=n,t[n+24>>2]=r),e=t[e+4>>2]|0,e|0&&(t[r+20>>2]=e,t[e+24>>2]=r)}}while(0);if(t[D+4>>2]=l|1,t[h+l>>2]=l,(D|0)==(t[2788]|0)){t[2785]=l;return}}if(e=l>>>3,l>>>0<256){r=11172+(e<<1<<2)|0,n=t[2783]|0,e=1<>2]|0):(t[2783]=n|e,e=r,n=r+8|0),t[n>>2]=D,t[e+12>>2]=D,t[D+8>>2]=e,t[D+12>>2]=r;return}e=l>>>8,e?l>>>0>16777215?e=31:(h=(e+1048320|0)>>>16&8,S=e<>>16&4,S=S<>>16&2,e=14-(s|h|e)+(S<>>15)|0,e=l>>>(e+7|0)&1|e<<1):e=0,u=11436+(e<<2)|0,t[D+28>>2]=e,t[D+20>>2]=0,t[D+16>>2]=0,n=t[2784]|0,r=1<>>1)|0),r=t[u>>2]|0;;){if((t[r+4>>2]&-8|0)==(l|0)){e=73;break}if(u=r+16+(n>>>31<<2)|0,e=t[u>>2]|0,e)n=n<<1,r=e;else{e=72;break}}if((e|0)==72){t[u>>2]=D,t[D+24>>2]=r,t[D+12>>2]=D,t[D+8>>2]=D;break}else if((e|0)==73){h=r+8|0,S=t[h>>2]|0,t[S+12>>2]=D,t[h>>2]=D,t[D+8>>2]=S,t[D+12>>2]=r,t[D+24>>2]=0;break}}else t[2784]=n|r,t[u>>2]=D,t[D+24>>2]=u,t[D+12>>2]=D,t[D+8>>2]=D;while(0);if(S=(t[2791]|0)+-1|0,t[2791]=S,!S)e=11588;else return;for(;e=t[e>>2]|0,e;)e=e+8|0;t[2791]=-1}}}function CF(){return 11628}function xF(e){e=e|0;var n=0,r=0;return n=m,m=m+16|0,r=n,t[r>>2]=OF(t[e+60>>2]|0)|0,e=x_(Ou(6,r|0)|0)|0,m=n,e|0}function F8(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0;I=m,m=m+48|0,L=I+16|0,s=I,l=I+32|0,D=e+28|0,u=t[D>>2]|0,t[l>>2]=u,S=e+20|0,u=(t[S>>2]|0)-u|0,t[l+4>>2]=u,t[l+8>>2]=n,t[l+12>>2]=r,u=u+r|0,h=e+60|0,t[s>>2]=t[h>>2],t[s+4>>2]=l,t[s+8>>2]=2,s=x_(v0(146,s|0)|0)|0;e:do if((u|0)!=(s|0)){for(n=2;!((s|0)<0);)if(u=u-s|0,be=t[l+4>>2]|0,K=s>>>0>be>>>0,l=K?l+8|0:l,n=(K<<31>>31)+n|0,be=s-(K?be:0)|0,t[l>>2]=(t[l>>2]|0)+be,K=l+4|0,t[K>>2]=(t[K>>2]|0)-be,t[L>>2]=t[h>>2],t[L+4>>2]=l,t[L+8>>2]=n,s=x_(v0(146,L|0)|0)|0,(u|0)==(s|0)){k=3;break e}t[e+16>>2]=0,t[D>>2]=0,t[S>>2]=0,t[e>>2]=t[e>>2]|32,(n|0)==2?r=0:r=r-(t[l+4>>2]|0)|0}else k=3;while(0);return(k|0)==3&&(be=t[e+44>>2]|0,t[e+16>>2]=be+(t[e+48>>2]|0),t[D>>2]=be,t[S>>2]=be),m=I,r|0}function AF(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;return l=m,m=m+32|0,s=l,u=l+20|0,t[s>>2]=t[e+60>>2],t[s+4>>2]=0,t[s+8>>2]=n,t[s+12>>2]=u,t[s+16>>2]=r,(x_(Ni(140,s|0)|0)|0)<0?(t[u>>2]=-1,e=-1):e=t[u>>2]|0,m=l,e|0}function x_(e){return e=e|0,e>>>0>4294963200&&(t[(bv()|0)>>2]=0-e,e=-1),e|0}function bv(){return(RF()|0)+64|0}function RF(){return YE()|0}function YE(){return 2084}function OF(e){return e=e|0,e|0}function MF(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;return l=m,m=m+32|0,u=l,t[e+36>>2]=1,((t[e>>2]&64|0)==0?(t[u>>2]=t[e+60>>2],t[u+4>>2]=21523,t[u+8>>2]=l+16,I0(54,u|0)|0):0)&&(c[e+75>>0]=-1),u=F8(e,n,r)|0,m=l,u|0}function P8(e,n){e=e|0,n=n|0;var r=0,u=0;if(r=c[e>>0]|0,u=c[n>>0]|0,r<<24>>24==0?1:r<<24>>24!=u<<24>>24)e=u;else{do e=e+1|0,n=n+1|0,r=c[e>>0]|0,u=c[n>>0]|0;while(!(r<<24>>24==0?1:r<<24>>24!=u<<24>>24));e=u}return(r&255)-(e&255)|0}function kF(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0;e:do if(!r)e=0;else{for(;u=c[e>>0]|0,l=c[n>>0]|0,u<<24>>24==l<<24>>24;)if(r=r+-1|0,r)e=e+1|0,n=n+1|0;else{e=0;break e}e=(u&255)-(l&255)|0}while(0);return e|0}function I8(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0;ge=m,m=m+224|0,k=ge+120|0,I=ge+80|0,be=ge,Se=ge+136|0,u=I,l=u+40|0;do t[u>>2]=0,u=u+4|0;while((u|0)<(l|0));return t[k>>2]=t[r>>2],(KE(0,n,k,be,I)|0)<0?r=-1:((t[e+76>>2]|0)>-1?K=LF(e)|0:K=0,r=t[e>>2]|0,L=r&32,(c[e+74>>0]|0)<1&&(t[e>>2]=r&-33),u=e+48|0,t[u>>2]|0?r=KE(e,n,k,be,I)|0:(l=e+44|0,s=t[l>>2]|0,t[l>>2]=Se,h=e+28|0,t[h>>2]=Se,D=e+20|0,t[D>>2]=Se,t[u>>2]=80,S=e+16|0,t[S>>2]=Se+80,r=KE(e,n,k,be,I)|0,s&&(M_[t[e+36>>2]&7](e,0,0)|0,r=(t[D>>2]|0)==0?-1:r,t[l>>2]=s,t[u>>2]=0,t[S>>2]=0,t[h>>2]=0,t[D>>2]=0)),u=t[e>>2]|0,t[e>>2]=u|L,K|0&&NF(e),r=(u&32|0)==0?r:-1),m=ge,r|0}function KE(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0,Ze=0,Ge=0,ct=0,Me=0,Pe=0,Zt=0,Br=0,In=0,yn=0,Er=0,Pr=0,Ln=0;Ln=m,m=m+64|0,In=Ln+16|0,yn=Ln,Zt=Ln+24|0,Er=Ln+8|0,Pr=Ln+20|0,t[In>>2]=n,ct=(e|0)!=0,Me=Zt+40|0,Pe=Me,Zt=Zt+39|0,Br=Er+4|0,h=0,s=0,k=0;e:for(;;){do if((s|0)>-1)if((h|0)>(2147483647-s|0)){t[(bv()|0)>>2]=75,s=-1;break}else{s=h+s|0;break}while(0);if(h=c[n>>0]|0,h<<24>>24)D=n;else{Ge=87;break}t:for(;;){switch(h<<24>>24){case 37:{h=D,Ge=9;break t}case 0:{h=D;break t}default:}Ze=D+1|0,t[In>>2]=Ze,h=c[Ze>>0]|0,D=Ze}t:do if((Ge|0)==9)for(;;){if(Ge=0,(c[D+1>>0]|0)!=37)break t;if(h=h+1|0,D=D+2|0,t[In>>2]=D,(c[D>>0]|0)==37)Ge=9;else break}while(0);if(h=h-n|0,ct&&Yo(e,n,h),h|0){n=D;continue}S=D+1|0,h=(c[S>>0]|0)+-48|0,h>>>0<10?(Ze=(c[D+2>>0]|0)==36,ge=Ze?h:-1,k=Ze?1:k,S=Ze?D+3|0:S):ge=-1,t[In>>2]=S,h=c[S>>0]|0,D=(h<<24>>24)+-32|0;t:do if(D>>>0<32)for(L=0,I=h;;){if(h=1<>2]=S,h=c[S>>0]|0,D=(h<<24>>24)+-32|0,D>>>0>=32)break;I=h}else L=0;while(0);if(h<<24>>24==42){if(D=S+1|0,h=(c[D>>0]|0)+-48|0,h>>>0<10?(c[S+2>>0]|0)==36:0)t[l+(h<<2)>>2]=10,h=t[u+((c[D>>0]|0)+-48<<3)>>2]|0,k=1,S=S+3|0;else{if(k|0){s=-1;break}ct?(k=(t[r>>2]|0)+(4-1)&~(4-1),h=t[k>>2]|0,t[r>>2]=k+4,k=0,S=D):(h=0,k=0,S=D)}t[In>>2]=S,Ze=(h|0)<0,h=Ze?0-h|0:h,L=Ze?L|8192:L}else{if(h=b8(In)|0,(h|0)<0){s=-1;break}S=t[In>>2]|0}do if((c[S>>0]|0)==46){if((c[S+1>>0]|0)!=42){t[In>>2]=S+1,D=b8(In)|0,S=t[In>>2]|0;break}if(I=S+2|0,D=(c[I>>0]|0)+-48|0,D>>>0<10?(c[S+3>>0]|0)==36:0){t[l+(D<<2)>>2]=10,D=t[u+((c[I>>0]|0)+-48<<3)>>2]|0,S=S+4|0,t[In>>2]=S;break}if(k|0){s=-1;break e}ct?(Ze=(t[r>>2]|0)+(4-1)&~(4-1),D=t[Ze>>2]|0,t[r>>2]=Ze+4):D=0,t[In>>2]=I,S=I}else D=-1;while(0);for(Se=0;;){if(((c[S>>0]|0)+-65|0)>>>0>57){s=-1;break e}if(Ze=S+1|0,t[In>>2]=Ze,I=c[(c[S>>0]|0)+-65+(5178+(Se*58|0))>>0]|0,K=I&255,(K+-1|0)>>>0<8)Se=K,S=Ze;else break}if(!(I<<24>>24)){s=-1;break}be=(ge|0)>-1;do if(I<<24>>24==19)if(be){s=-1;break e}else Ge=49;else{if(be){t[l+(ge<<2)>>2]=K,be=u+(ge<<3)|0,ge=t[be+4>>2]|0,Ge=yn,t[Ge>>2]=t[be>>2],t[Ge+4>>2]=ge,Ge=49;break}if(!ct){s=0;break e}B8(yn,K,r)}while(0);if((Ge|0)==49?(Ge=0,!ct):0){h=0,n=Ze;continue}S=c[S>>0]|0,S=(Se|0)!=0&(S&15|0)==3?S&-33:S,be=L&-65537,ge=(L&8192|0)==0?L:be;t:do switch(S|0){case 110:switch((Se&255)<<24>>24){case 0:{t[t[yn>>2]>>2]=s,h=0,n=Ze;continue e}case 1:{t[t[yn>>2]>>2]=s,h=0,n=Ze;continue e}case 2:{h=t[yn>>2]|0,t[h>>2]=s,t[h+4>>2]=((s|0)<0)<<31>>31,h=0,n=Ze;continue e}case 3:{_[t[yn>>2]>>1]=s,h=0,n=Ze;continue e}case 4:{c[t[yn>>2]>>0]=s,h=0,n=Ze;continue e}case 6:{t[t[yn>>2]>>2]=s,h=0,n=Ze;continue e}case 7:{h=t[yn>>2]|0,t[h>>2]=s,t[h+4>>2]=((s|0)<0)<<31>>31,h=0,n=Ze;continue e}default:{h=0,n=Ze;continue e}}case 112:{S=120,D=D>>>0>8?D:8,n=ge|8,Ge=61;break}case 88:case 120:{n=ge,Ge=61;break}case 111:{S=yn,n=t[S>>2]|0,S=t[S+4>>2]|0,K=PF(n,S,Me)|0,be=Pe-K|0,L=0,I=5642,D=(ge&8|0)==0|(D|0)>(be|0)?D:be+1|0,be=ge,Ge=67;break}case 105:case 100:if(S=yn,n=t[S>>2]|0,S=t[S+4>>2]|0,(S|0)<0){n=A_(0,0,n|0,S|0)|0,S=ut,L=yn,t[L>>2]=n,t[L+4>>2]=S,L=1,I=5642,Ge=66;break t}else{L=(ge&2049|0)!=0&1,I=(ge&2048|0)==0?(ge&1|0)==0?5642:5644:5643,Ge=66;break t}case 117:{S=yn,L=0,I=5642,n=t[S>>2]|0,S=t[S+4>>2]|0,Ge=66;break}case 99:{c[Zt>>0]=t[yn>>2],n=Zt,L=0,I=5642,K=Me,S=1,D=be;break}case 109:{S=IF(t[(bv()|0)>>2]|0)|0,Ge=71;break}case 115:{S=t[yn>>2]|0,S=S|0?S:5652,Ge=71;break}case 67:{t[Er>>2]=t[yn>>2],t[Br>>2]=0,t[yn>>2]=Er,K=-1,S=Er,Ge=75;break}case 83:{n=t[yn>>2]|0,D?(K=D,S=n,Ge=75):(_l(e,32,h,0,ge),n=0,Ge=84);break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{h=BF(e,+B[yn>>3],h,D,ge,S)|0,n=Ze;continue e}default:L=0,I=5642,K=Me,S=D,D=ge}while(0);t:do if((Ge|0)==61)ge=yn,Se=t[ge>>2]|0,ge=t[ge+4>>2]|0,K=FF(Se,ge,Me,S&32)|0,I=(n&8|0)==0|(Se|0)==0&(ge|0)==0,L=I?0:2,I=I?5642:5642+(S>>4)|0,be=n,n=Se,S=ge,Ge=67;else if((Ge|0)==66)K=Bv(n,S,Me)|0,be=ge,Ge=67;else if((Ge|0)==71)Ge=0,ge=bF(S,0,D)|0,Se=(ge|0)==0,n=S,L=0,I=5642,K=Se?S+D|0:ge,S=Se?D:ge-S|0,D=be;else if((Ge|0)==75){for(Ge=0,I=S,n=0,D=0;L=t[I>>2]|0,!(!L||(D=U8(Pr,L)|0,(D|0)<0|D>>>0>(K-n|0)>>>0));)if(n=D+n|0,K>>>0>n>>>0)I=I+4|0;else break;if((D|0)<0){s=-1;break e}if(_l(e,32,h,n,ge),!n)n=0,Ge=84;else for(L=0;;){if(D=t[S>>2]|0,!D){Ge=84;break t}if(D=U8(Pr,D)|0,L=D+L|0,(L|0)>(n|0)){Ge=84;break t}if(Yo(e,Pr,D),L>>>0>=n>>>0){Ge=84;break}else S=S+4|0}}while(0);if((Ge|0)==67)Ge=0,S=(n|0)!=0|(S|0)!=0,ge=(D|0)!=0|S,S=((S^1)&1)+(Pe-K)|0,n=ge?K:Me,K=Me,S=ge?(D|0)>(S|0)?D:S:D,D=(D|0)>-1?be&-65537:be;else if((Ge|0)==84){Ge=0,_l(e,32,h,n,ge^8192),h=(h|0)>(n|0)?h:n,n=Ze;continue}Se=K-n|0,be=(S|0)<(Se|0)?Se:S,ge=be+L|0,h=(h|0)<(ge|0)?ge:h,_l(e,32,h,ge,D),Yo(e,I,L),_l(e,48,h,ge,D^65536),_l(e,48,be,Se,0),Yo(e,n,Se),_l(e,32,h,ge,D^8192),n=Ze}e:do if((Ge|0)==87&&!e)if(!k)s=0;else{for(s=1;n=t[l+(s<<2)>>2]|0,!!n;)if(B8(u+(s<<3)|0,n,r),s=s+1|0,(s|0)>=10){s=1;break e}for(;;){if(t[l+(s<<2)>>2]|0){s=-1;break e}if(s=s+1|0,(s|0)>=10){s=1;break}}}while(0);return m=Ln,s|0}function LF(e){return e=e|0,0}function NF(e){e=e|0}function Yo(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]&32||YF(n,r,e)|0}function b8(e){e=e|0;var n=0,r=0,u=0;if(r=t[e>>2]|0,u=(c[r>>0]|0)+-48|0,u>>>0<10){n=0;do n=u+(n*10|0)|0,r=r+1|0,t[e>>2]=r,u=(c[r>>0]|0)+-48|0;while(u>>>0<10)}else n=0;return n|0}function B8(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;e:do if(n>>>0<=20)do switch(n|0){case 9:{u=(t[r>>2]|0)+(4-1)&~(4-1),n=t[u>>2]|0,t[r>>2]=u+4,t[e>>2]=n;break e}case 10:{u=(t[r>>2]|0)+(4-1)&~(4-1),n=t[u>>2]|0,t[r>>2]=u+4,u=e,t[u>>2]=n,t[u+4>>2]=((n|0)<0)<<31>>31;break e}case 11:{u=(t[r>>2]|0)+(4-1)&~(4-1),n=t[u>>2]|0,t[r>>2]=u+4,u=e,t[u>>2]=n,t[u+4>>2]=0;break e}case 12:{u=(t[r>>2]|0)+(8-1)&~(8-1),n=u,l=t[n>>2]|0,n=t[n+4>>2]|0,t[r>>2]=u+8,u=e,t[u>>2]=l,t[u+4>>2]=n;break e}case 13:{l=(t[r>>2]|0)+(4-1)&~(4-1),u=t[l>>2]|0,t[r>>2]=l+4,u=(u&65535)<<16>>16,l=e,t[l>>2]=u,t[l+4>>2]=((u|0)<0)<<31>>31;break e}case 14:{l=(t[r>>2]|0)+(4-1)&~(4-1),u=t[l>>2]|0,t[r>>2]=l+4,l=e,t[l>>2]=u&65535,t[l+4>>2]=0;break e}case 15:{l=(t[r>>2]|0)+(4-1)&~(4-1),u=t[l>>2]|0,t[r>>2]=l+4,u=(u&255)<<24>>24,l=e,t[l>>2]=u,t[l+4>>2]=((u|0)<0)<<31>>31;break e}case 16:{l=(t[r>>2]|0)+(4-1)&~(4-1),u=t[l>>2]|0,t[r>>2]=l+4,l=e,t[l>>2]=u&255,t[l+4>>2]=0;break e}case 17:{l=(t[r>>2]|0)+(8-1)&~(8-1),s=+B[l>>3],t[r>>2]=l+8,B[e>>3]=s;break e}case 18:{l=(t[r>>2]|0)+(8-1)&~(8-1),s=+B[l>>3],t[r>>2]=l+8,B[e>>3]=s;break e}default:break e}while(0);while(0)}function FF(e,n,r,u){if(e=e|0,n=n|0,r=r|0,u=u|0,!((e|0)==0&(n|0)==0))do r=r+-1|0,c[r>>0]=O[5694+(e&15)>>0]|0|u,e=R_(e|0,n|0,4)|0,n=ut;while(!((e|0)==0&(n|0)==0));return r|0}function PF(e,n,r){if(e=e|0,n=n|0,r=r|0,!((e|0)==0&(n|0)==0))do r=r+-1|0,c[r>>0]=e&7|48,e=R_(e|0,n|0,3)|0,n=ut;while(!((e|0)==0&(n|0)==0));return r|0}function Bv(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;if(n>>>0>0|(n|0)==0&e>>>0>4294967295){for(;u=ZE(e|0,n|0,10,0)|0,r=r+-1|0,c[r>>0]=u&255|48,u=e,e=JE(e|0,n|0,10,0)|0,n>>>0>9|(n|0)==9&u>>>0>4294967295;)n=ut;n=e}else n=e;if(n)for(;r=r+-1|0,c[r>>0]=(n>>>0)%10|0|48,!(n>>>0<10);)n=(n>>>0)/10|0;return r|0}function IF(e){return e=e|0,qF(e,t[(HF()|0)+188>>2]|0)|0}function bF(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;s=n&255,u=(r|0)!=0;e:do if(u&(e&3|0)!=0)for(l=n&255;;){if((c[e>>0]|0)==l<<24>>24){h=6;break e}if(e=e+1|0,r=r+-1|0,u=(r|0)!=0,!(u&(e&3|0)!=0)){h=5;break}}else h=5;while(0);(h|0)==5&&(u?h=6:r=0);e:do if((h|0)==6&&(l=n&255,(c[e>>0]|0)!=l<<24>>24)){u=lr(s,16843009)|0;t:do if(r>>>0>3){for(;s=t[e>>2]^u,!((s&-2139062144^-2139062144)&s+-16843009|0);)if(e=e+4|0,r=r+-4|0,r>>>0<=3){h=11;break t}}else h=11;while(0);if((h|0)==11&&!r){r=0;break}for(;;){if((c[e>>0]|0)==l<<24>>24)break e;if(e=e+1|0,r=r+-1|0,!r){r=0;break}}}while(0);return(r|0?e:0)|0}function _l(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0;if(h=m,m=m+256|0,s=h,(r|0)>(u|0)&(l&73728|0)==0){if(l=r-u|0,jv(s|0,n|0,(l>>>0<256?l:256)|0)|0,l>>>0>255){n=r-u|0;do Yo(e,s,256),l=l+-256|0;while(l>>>0>255);l=n&255}Yo(e,s,l)}m=h}function U8(e,n){return e=e|0,n=n|0,e?e=jF(e,n,0)|0:e=0,e|0}function BF(e,n,r,u,l,s){e=e|0,n=+n,r=r|0,u=u|0,l=l|0,s=s|0;var h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0,ge=0,Ze=0,Ge=0,ct=0,Me=0,Pe=0,Zt=0,Br=0,In=0,yn=0,Er=0,Pr=0,Ln=0,uu=0;uu=m,m=m+560|0,S=uu+8|0,Ze=uu,Ln=uu+524|0,Pr=Ln,L=uu+512|0,t[Ze>>2]=0,Er=L+12|0,j8(n)|0,(ut|0)<0?(n=-n,In=1,Br=5659):(In=(l&2049|0)!=0&1,Br=(l&2048|0)==0?(l&1|0)==0?5660:5665:5662),j8(n)|0,yn=ut&2146435072;do if(yn>>>0<2146435072|(yn|0)==2146435072&0<0){if(be=+UF(n,Ze)*2,h=be!=0,h&&(t[Ze>>2]=(t[Ze>>2]|0)+-1),ct=s|32,(ct|0)==97){Se=s&32,K=(Se|0)==0?Br:Br+9|0,I=In|2,h=12-u|0;do if(u>>>0>11|(h|0)==0)n=be;else{n=8;do h=h+-1|0,n=n*16;while((h|0)!=0);if((c[K>>0]|0)==45){n=-(n+(-be-n));break}else{n=be+n-n;break}}while(0);D=t[Ze>>2]|0,h=(D|0)<0?0-D|0:D,h=Bv(h,((h|0)<0)<<31>>31,Er)|0,(h|0)==(Er|0)&&(h=L+11|0,c[h>>0]=48),c[h+-1>>0]=(D>>31&2)+43,k=h+-2|0,c[k>>0]=s+15,L=(u|0)<1,S=(l&8|0)==0,h=Ln;do yn=~~n,D=h+1|0,c[h>>0]=O[5694+yn>>0]|Se,n=(n-+(yn|0))*16,((D-Pr|0)==1?!(S&(L&n==0)):0)?(c[D>>0]=46,h=h+2|0):h=D;while(n!=0);yn=h-Pr|0,Pr=Er-k|0,Er=(u|0)!=0&(yn+-2|0)<(u|0)?u+2|0:yn,h=Pr+I+Er|0,_l(e,32,r,h,l),Yo(e,K,I),_l(e,48,r,h,l^65536),Yo(e,Ln,yn),_l(e,48,Er-yn|0,0,0),Yo(e,k,Pr),_l(e,32,r,h,l^8192);break}D=(u|0)<0?6:u,h?(h=(t[Ze>>2]|0)+-28|0,t[Ze>>2]=h,n=be*268435456):(n=be,h=t[Ze>>2]|0),yn=(h|0)<0?S:S+288|0,S=yn;do Pe=~~n>>>0,t[S>>2]=Pe,S=S+4|0,n=(n-+(Pe>>>0))*1e9;while(n!=0);if((h|0)>0)for(L=yn,I=S;;){if(k=(h|0)<29?h:29,h=I+-4|0,h>>>0>=L>>>0){S=0;do Me=G8(t[h>>2]|0,0,k|0)|0,Me=QE(Me|0,ut|0,S|0,0)|0,Pe=ut,Ge=ZE(Me|0,Pe|0,1e9,0)|0,t[h>>2]=Ge,S=JE(Me|0,Pe|0,1e9,0)|0,h=h+-4|0;while(h>>>0>=L>>>0);S&&(L=L+-4|0,t[L>>2]=S)}for(S=I;!(S>>>0<=L>>>0);)if(h=S+-4|0,!(t[h>>2]|0))S=h;else break;if(h=(t[Ze>>2]|0)-k|0,t[Ze>>2]=h,(h|0)>0)I=S;else break}else L=yn;if((h|0)<0){u=((D+25|0)/9|0)+1|0,ge=(ct|0)==102;do{if(Se=0-h|0,Se=(Se|0)<9?Se:9,L>>>0>>0){k=(1<>>Se,K=0,h=L;do Pe=t[h>>2]|0,t[h>>2]=(Pe>>>Se)+K,K=lr(Pe&k,I)|0,h=h+4|0;while(h>>>0>>0);h=(t[L>>2]|0)==0?L+4|0:L,K?(t[S>>2]=K,L=h,h=S+4|0):(L=h,h=S)}else L=(t[L>>2]|0)==0?L+4|0:L,h=S;S=ge?yn:L,S=(h-S>>2|0)>(u|0)?S+(u<<2)|0:h,h=(t[Ze>>2]|0)+Se|0,t[Ze>>2]=h}while((h|0)<0);h=L,u=S}else h=L,u=S;if(Pe=yn,h>>>0>>0){if(S=(Pe-h>>2)*9|0,k=t[h>>2]|0,k>>>0>=10){L=10;do L=L*10|0,S=S+1|0;while(k>>>0>=L>>>0)}}else S=0;if(ge=(ct|0)==103,Ge=(D|0)!=0,L=D-((ct|0)!=102?S:0)+((Ge&ge)<<31>>31)|0,(L|0)<(((u-Pe>>2)*9|0)+-9|0)){if(L=L+9216|0,Se=yn+4+(((L|0)/9|0)+-1024<<2)|0,L=((L|0)%9|0)+1|0,(L|0)<9){k=10;do k=k*10|0,L=L+1|0;while((L|0)!=9)}else k=10;if(I=t[Se>>2]|0,K=(I>>>0)%(k>>>0)|0,L=(Se+4|0)==(u|0),L&(K|0)==0)L=Se;else if(be=(((I>>>0)/(k>>>0)|0)&1|0)==0?9007199254740992:9007199254740994,Me=(k|0)/2|0,n=K>>>0>>0?.5:L&(K|0)==(Me|0)?1:1.5,In&&(Me=(c[Br>>0]|0)==45,n=Me?-n:n,be=Me?-be:be),L=I-K|0,t[Se>>2]=L,be+n!=be){if(Me=L+k|0,t[Se>>2]=Me,Me>>>0>999999999)for(S=Se;L=S+-4|0,t[S>>2]=0,L>>>0>>0&&(h=h+-4|0,t[h>>2]=0),Me=(t[L>>2]|0)+1|0,t[L>>2]=Me,Me>>>0>999999999;)S=L;else L=Se;if(S=(Pe-h>>2)*9|0,I=t[h>>2]|0,I>>>0>=10){k=10;do k=k*10|0,S=S+1|0;while(I>>>0>=k>>>0)}}else L=Se;L=L+4|0,L=u>>>0>L>>>0?L:u,Me=h}else L=u,Me=h;for(ct=L;;){if(ct>>>0<=Me>>>0){Ze=0;break}if(h=ct+-4|0,!(t[h>>2]|0))ct=h;else{Ze=1;break}}u=0-S|0;do if(ge)if(h=((Ge^1)&1)+D|0,(h|0)>(S|0)&(S|0)>-5?(k=s+-1|0,D=h+-1-S|0):(k=s+-2|0,D=h+-1|0),h=l&8,h)Se=h;else{if(Ze?(Zt=t[ct+-4>>2]|0,(Zt|0)!=0):0)if((Zt>>>0)%10|0)L=0;else{L=0,h=10;do h=h*10|0,L=L+1|0;while(!((Zt>>>0)%(h>>>0)|0|0))}else L=9;if(h=((ct-Pe>>2)*9|0)+-9|0,(k|32|0)==102){Se=h-L|0,Se=(Se|0)>0?Se:0,D=(D|0)<(Se|0)?D:Se,Se=0;break}else{Se=h+S-L|0,Se=(Se|0)>0?Se:0,D=(D|0)<(Se|0)?D:Se,Se=0;break}}else k=s,Se=l&8;while(0);if(ge=D|Se,I=(ge|0)!=0&1,K=(k|32|0)==102,K)Ge=0,h=(S|0)>0?S:0;else{if(h=(S|0)<0?u:S,h=Bv(h,((h|0)<0)<<31>>31,Er)|0,L=Er,(L-h|0)<2)do h=h+-1|0,c[h>>0]=48;while((L-h|0)<2);c[h+-1>>0]=(S>>31&2)+43,h=h+-2|0,c[h>>0]=k,Ge=h,h=L-h|0}if(h=In+1+D+I+h|0,_l(e,32,r,h,l),Yo(e,Br,In),_l(e,48,r,h,l^65536),K){k=Me>>>0>yn>>>0?yn:Me,Se=Ln+9|0,I=Se,K=Ln+8|0,L=k;do{if(S=Bv(t[L>>2]|0,0,Se)|0,(L|0)==(k|0))(S|0)==(Se|0)&&(c[K>>0]=48,S=K);else if(S>>>0>Ln>>>0){jv(Ln|0,48,S-Pr|0)|0;do S=S+-1|0;while(S>>>0>Ln>>>0)}Yo(e,S,I-S|0),L=L+4|0}while(L>>>0<=yn>>>0);if(ge|0&&Yo(e,5710,1),L>>>0>>0&(D|0)>0)for(;;){if(S=Bv(t[L>>2]|0,0,Se)|0,S>>>0>Ln>>>0){jv(Ln|0,48,S-Pr|0)|0;do S=S+-1|0;while(S>>>0>Ln>>>0)}if(Yo(e,S,(D|0)<9?D:9),L=L+4|0,S=D+-9|0,L>>>0>>0&(D|0)>9)D=S;else{D=S;break}}_l(e,48,D+9|0,9,0)}else{if(ge=Ze?ct:Me+4|0,(D|0)>-1){Ze=Ln+9|0,Se=(Se|0)==0,u=Ze,I=0-Pr|0,K=Ln+8|0,k=Me;do{S=Bv(t[k>>2]|0,0,Ze)|0,(S|0)==(Ze|0)&&(c[K>>0]=48,S=K);do if((k|0)==(Me|0)){if(L=S+1|0,Yo(e,S,1),Se&(D|0)<1){S=L;break}Yo(e,5710,1),S=L}else{if(S>>>0<=Ln>>>0)break;jv(Ln|0,48,S+I|0)|0;do S=S+-1|0;while(S>>>0>Ln>>>0)}while(0);Pr=u-S|0,Yo(e,S,(D|0)>(Pr|0)?Pr:D),D=D-Pr|0,k=k+4|0}while(k>>>0>>0&(D|0)>-1)}_l(e,48,D+18|0,18,0),Yo(e,Ge,Er-Ge|0)}_l(e,32,r,h,l^8192)}else Ln=(s&32|0)!=0,h=In+3|0,_l(e,32,r,h,l&-65537),Yo(e,Br,In),Yo(e,n!=n|!1?Ln?5686:5690:Ln?5678:5682,3),_l(e,32,r,h,l^8192);while(0);return m=uu,((h|0)<(r|0)?r:h)|0}function j8(e){e=+e;var n=0;return B[q>>3]=e,n=t[q>>2]|0,ut=t[q+4>>2]|0,n|0}function UF(e,n){return e=+e,n=n|0,+ +z8(e,n)}function z8(e,n){e=+e,n=n|0;var r=0,u=0,l=0;switch(B[q>>3]=e,r=t[q>>2]|0,u=t[q+4>>2]|0,l=R_(r|0,u|0,52)|0,l&2047){case 0:{e!=0?(e=+z8(e*18446744073709552e3,n),r=(t[n>>2]|0)+-64|0):r=0,t[n>>2]=r;break}case 2047:break;default:t[n>>2]=(l&2047)+-1022,t[q>>2]=r,t[q+4>>2]=u&-2146435073|1071644672,e=+B[q>>3]}return+e}function jF(e,n,r){e=e|0,n=n|0,r=r|0;do if(e){if(n>>>0<128){c[e>>0]=n,e=1;break}if(!(t[t[(zF()|0)+188>>2]>>2]|0))if((n&-128|0)==57216){c[e>>0]=n,e=1;break}else{t[(bv()|0)>>2]=84,e=-1;break}if(n>>>0<2048){c[e>>0]=n>>>6|192,c[e+1>>0]=n&63|128,e=2;break}if(n>>>0<55296|(n&-8192|0)==57344){c[e>>0]=n>>>12|224,c[e+1>>0]=n>>>6&63|128,c[e+2>>0]=n&63|128,e=3;break}if((n+-65536|0)>>>0<1048576){c[e>>0]=n>>>18|240,c[e+1>>0]=n>>>12&63|128,c[e+2>>0]=n>>>6&63|128,c[e+3>>0]=n&63|128,e=4;break}else{t[(bv()|0)>>2]=84,e=-1;break}}else e=1;while(0);return e|0}function zF(){return YE()|0}function HF(){return YE()|0}function qF(e,n){e=e|0,n=n|0;var r=0,u=0;for(u=0;;){if((O[5712+u>>0]|0)==(e|0)){e=2;break}if(r=u+1|0,(r|0)==87){r=5800,u=87,e=5;break}else u=r}if((e|0)==2&&(u?(r=5800,e=5):r=5800),(e|0)==5)for(;;){do e=r,r=r+1|0;while((c[e>>0]|0)!=0);if(u=u+-1|0,u)e=5;else break}return WF(r,t[n+20>>2]|0)|0}function WF(e,n){return e=e|0,n=n|0,VF(e,n)|0}function VF(e,n){return e=e|0,n=n|0,n?n=GF(t[n>>2]|0,t[n+4>>2]|0,e)|0:n=0,(n|0?n:e)|0}function GF(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0;K=(t[e>>2]|0)+1794895138|0,s=Xp(t[e+8>>2]|0,K)|0,u=Xp(t[e+12>>2]|0,K)|0,l=Xp(t[e+16>>2]|0,K)|0;e:do if((s>>>0>>2>>>0?(I=n-(s<<2)|0,u>>>0>>0&l>>>0>>0):0)?((l|u)&3|0)==0:0){for(I=u>>>2,k=l>>>2,L=0;;){if(D=s>>>1,S=L+D|0,h=S<<1,l=h+I|0,u=Xp(t[e+(l<<2)>>2]|0,K)|0,l=Xp(t[e+(l+1<<2)>>2]|0,K)|0,!(l>>>0>>0&u>>>0<(n-l|0)>>>0)){u=0;break e}if(c[e+(l+u)>>0]|0){u=0;break e}if(u=P8(r,e+l|0)|0,!u)break;if(u=(u|0)<0,(s|0)==1){u=0;break e}else L=u?L:S,s=u?D:s-D|0}u=h+k|0,l=Xp(t[e+(u<<2)>>2]|0,K)|0,u=Xp(t[e+(u+1<<2)>>2]|0,K)|0,u>>>0>>0&l>>>0<(n-u|0)>>>0?u=(c[e+(u+l)>>0]|0)==0?e+u|0:0:u=0}else u=0;while(0);return u|0}function Xp(e,n){e=e|0,n=n|0;var r=0;return r=X8(e|0)|0,((n|0)==0?e:r)|0}function YF(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0,D=0;u=r+16|0,l=t[u>>2]|0,l?s=5:KF(r)|0?u=0:(l=t[u>>2]|0,s=5);e:do if((s|0)==5){if(D=r+20|0,h=t[D>>2]|0,u=h,(l-h|0)>>>0>>0){u=M_[t[r+36>>2]&7](r,e,n)|0;break}t:do if((c[r+75>>0]|0)>-1){for(h=n;;){if(!h){s=0,l=e;break t}if(l=h+-1|0,(c[e+l>>0]|0)==10)break;h=l}if(u=M_[t[r+36>>2]&7](r,e,h)|0,u>>>0>>0)break e;s=h,l=e+h|0,n=n-h|0,u=t[D>>2]|0}else s=0,l=e;while(0);_r(u|0,l|0,n|0)|0,t[D>>2]=(t[D>>2]|0)+n,u=s+n|0}while(0);return u|0}function KF(e){e=e|0;var n=0,r=0;return n=e+74|0,r=c[n>>0]|0,c[n>>0]=r+255|r,n=t[e>>2]|0,n&8?(t[e>>2]=n|32,e=-1):(t[e+8>>2]=0,t[e+4>>2]=0,r=t[e+44>>2]|0,t[e+28>>2]=r,t[e+20>>2]=r,t[e+16>>2]=r+(t[e+48>>2]|0),e=0),e|0}function Au(e,n){e=w(e),n=w(n);var r=0,u=0;r=H8(e)|0;do if((r&2147483647)>>>0<=2139095040){if(u=H8(n)|0,(u&2147483647)>>>0<=2139095040)if((u^r|0)<0){e=(r|0)<0?n:e;break}else{e=e>2]=e,t[q>>2]|0|0}function Qp(e,n){e=w(e),n=w(n);var r=0,u=0;r=q8(e)|0;do if((r&2147483647)>>>0<=2139095040){if(u=q8(n)|0,(u&2147483647)>>>0<=2139095040)if((u^r|0)<0){e=(r|0)<0?e:n;break}else{e=e>2]=e,t[q>>2]|0|0}function XE(e,n){e=w(e),n=w(n);var r=0,u=0,l=0,s=0,h=0,D=0,S=0,L=0;s=(T[q>>2]=e,t[q>>2]|0),D=(T[q>>2]=n,t[q>>2]|0),r=s>>>23&255,h=D>>>23&255,S=s&-2147483648,l=D<<1;e:do if((l|0)!=0?!((r|0)==255|((XF(n)|0)&2147483647)>>>0>2139095040):0){if(u=s<<1,u>>>0<=l>>>0)return n=w(e*w(0)),w((u|0)==(l|0)?n:e);if(r)u=s&8388607|8388608;else{if(r=s<<9,(r|0)>-1){u=r,r=0;do r=r+-1|0,u=u<<1;while((u|0)>-1)}else r=0;u=s<<1-r}if(h)D=D&8388607|8388608;else{if(s=D<<9,(s|0)>-1){l=0;do l=l+-1|0,s=s<<1;while((s|0)>-1)}else l=0;h=l,D=D<<1-l}l=u-D|0,s=(l|0)>-1;t:do if((r|0)>(h|0)){for(;;){if(s)if(l)u=l;else break;if(u=u<<1,r=r+-1|0,l=u-D|0,s=(l|0)>-1,(r|0)<=(h|0))break t}n=w(e*w(0));break e}while(0);if(s)if(l)u=l;else{n=w(e*w(0));break}if(u>>>0<8388608)do u=u<<1,r=r+-1|0;while(u>>>0<8388608);(r|0)>0?r=u+-8388608|r<<23:r=u>>>(1-r|0),n=(t[q>>2]=r|S,w(T[q>>2]))}else L=3;while(0);return(L|0)==3&&(n=w(e*n),n=w(n/n)),w(n)}function XF(e){return e=w(e),T[q>>2]=e,t[q>>2]|0|0}function QF(e,n){return e=e|0,n=n|0,I8(t[582]|0,e,n)|0}function hi(e){e=e|0,$n()}function Uv(e){e=e|0}function JF(e,n){return e=e|0,n=n|0,0}function ZF(e){return e=e|0,(W8(e+4|0)|0)==-1?(P1[t[(t[e>>2]|0)+8>>2]&127](e),e=1):e=0,e|0}function W8(e){e=e|0;var n=0;return n=t[e>>2]|0,t[e>>2]=n+-1,n+-1|0}function t2(e){e=e|0,ZF(e)|0&&$F(e)}function $F(e){e=e|0;var n=0;n=e+8|0,((t[n>>2]|0)!=0?(W8(n)|0)!=-1:0)||P1[t[(t[e>>2]|0)+16>>2]&127](e)}function pn(e){e=e|0;var n=0;for(n=(e|0)==0?1:e;e=T_(n)|0,!(e|0);){if(e=tP()|0,!e){e=0;break}uS[e&0]()}return e|0}function V8(e){return e=e|0,pn(e)|0}function yt(e){e=e|0,C_(e)}function eP(e){e=e|0,(c[e+11>>0]|0)<0&&yt(t[e>>2]|0)}function tP(){var e=0;return e=t[2923]|0,t[2923]=e+0,e|0}function nP(){}function A_(e,n,r,u){return e=e|0,n=n|0,r=r|0,u=u|0,u=n-u-(r>>>0>e>>>0|0)>>>0,ut=u,e-r>>>0|0|0}function QE(e,n,r,u){return e=e|0,n=n|0,r=r|0,u=u|0,r=e+r>>>0,ut=n+u+(r>>>0>>0|0)>>>0,r|0|0}function jv(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0,h=0;if(s=e+r|0,n=n&255,(r|0)>=67){for(;e&3;)c[e>>0]=n,e=e+1|0;for(u=s&-4|0,l=u-64|0,h=n|n<<8|n<<16|n<<24;(e|0)<=(l|0);)t[e>>2]=h,t[e+4>>2]=h,t[e+8>>2]=h,t[e+12>>2]=h,t[e+16>>2]=h,t[e+20>>2]=h,t[e+24>>2]=h,t[e+28>>2]=h,t[e+32>>2]=h,t[e+36>>2]=h,t[e+40>>2]=h,t[e+44>>2]=h,t[e+48>>2]=h,t[e+52>>2]=h,t[e+56>>2]=h,t[e+60>>2]=h,e=e+64|0;for(;(e|0)<(u|0);)t[e>>2]=h,e=e+4|0}for(;(e|0)<(s|0);)c[e>>0]=n,e=e+1|0;return s-r|0}function G8(e,n,r){return e=e|0,n=n|0,r=r|0,(r|0)<32?(ut=n<>>32-r,e<>>r,e>>>r|(n&(1<>>r-32|0)}function _r(e,n,r){e=e|0,n=n|0,r=r|0;var u=0,l=0,s=0;if((r|0)>=8192)return ai(e|0,n|0,r|0)|0;if(s=e|0,l=e+r|0,(e&3)==(n&3)){for(;e&3;){if(!r)return s|0;c[e>>0]=c[n>>0]|0,e=e+1|0,n=n+1|0,r=r-1|0}for(r=l&-4|0,u=r-64|0;(e|0)<=(u|0);)t[e>>2]=t[n>>2],t[e+4>>2]=t[n+4>>2],t[e+8>>2]=t[n+8>>2],t[e+12>>2]=t[n+12>>2],t[e+16>>2]=t[n+16>>2],t[e+20>>2]=t[n+20>>2],t[e+24>>2]=t[n+24>>2],t[e+28>>2]=t[n+28>>2],t[e+32>>2]=t[n+32>>2],t[e+36>>2]=t[n+36>>2],t[e+40>>2]=t[n+40>>2],t[e+44>>2]=t[n+44>>2],t[e+48>>2]=t[n+48>>2],t[e+52>>2]=t[n+52>>2],t[e+56>>2]=t[n+56>>2],t[e+60>>2]=t[n+60>>2],e=e+64|0,n=n+64|0;for(;(e|0)<(r|0);)t[e>>2]=t[n>>2],e=e+4|0,n=n+4|0}else for(r=l-4|0;(e|0)<(r|0);)c[e>>0]=c[n>>0]|0,c[e+1>>0]=c[n+1>>0]|0,c[e+2>>0]=c[n+2>>0]|0,c[e+3>>0]=c[n+3>>0]|0,e=e+4|0,n=n+4|0;for(;(e|0)<(l|0);)c[e>>0]=c[n>>0]|0,e=e+1|0,n=n+1|0;return s|0}function Y8(e){e=e|0;var n=0;return n=c[De+(e&255)>>0]|0,(n|0)<8?n|0:(n=c[De+(e>>8&255)>>0]|0,(n|0)<8?n+8|0:(n=c[De+(e>>16&255)>>0]|0,(n|0)<8?n+16|0:(c[De+(e>>>24)>>0]|0)+24|0))}function K8(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0;var s=0,h=0,D=0,S=0,L=0,k=0,I=0,K=0,be=0,Se=0;if(k=e,S=n,L=S,h=r,K=u,D=K,!L)return s=(l|0)!=0,D?s?(t[l>>2]=e|0,t[l+4>>2]=n&0,K=0,l=0,ut=K,l|0):(K=0,l=0,ut=K,l|0):(s&&(t[l>>2]=(k>>>0)%(h>>>0),t[l+4>>2]=0),K=0,l=(k>>>0)/(h>>>0)>>>0,ut=K,l|0);s=(D|0)==0;do if(h){if(!s){if(s=(Dr(D|0)|0)-(Dr(L|0)|0)|0,s>>>0<=31){I=s+1|0,D=31-s|0,n=s-31>>31,h=I,e=k>>>(I>>>0)&n|L<>>(I>>>0)&n,s=0,D=k<>2]=e|0,t[l+4>>2]=S|n&0,K=0,l=0,ut=K,l|0):(K=0,l=0,ut=K,l|0)}if(s=h-1|0,s&h|0){D=(Dr(h|0)|0)+33-(Dr(L|0)|0)|0,Se=64-D|0,I=32-D|0,S=I>>31,be=D-32|0,n=be>>31,h=D,e=I-1>>31&L>>>(be>>>0)|(L<>>(D>>>0))&n,n=n&L>>>(D>>>0),s=k<>>(be>>>0))&S|k<>31;break}return l|0&&(t[l>>2]=s&k,t[l+4>>2]=0),(h|0)==1?(be=S|n&0,Se=e|0|0,ut=be,Se|0):(Se=Y8(h|0)|0,be=L>>>(Se>>>0)|0,Se=L<<32-Se|k>>>(Se>>>0)|0,ut=be,Se|0)}else{if(s)return l|0&&(t[l>>2]=(L>>>0)%(h>>>0),t[l+4>>2]=0),be=0,Se=(L>>>0)/(h>>>0)>>>0,ut=be,Se|0;if(!k)return l|0&&(t[l>>2]=0,t[l+4>>2]=(L>>>0)%(D>>>0)),be=0,Se=(L>>>0)/(D>>>0)>>>0,ut=be,Se|0;if(s=D-1|0,!(s&D))return l|0&&(t[l>>2]=e|0,t[l+4>>2]=s&L|n&0),be=0,Se=L>>>((Y8(D|0)|0)>>>0),ut=be,Se|0;if(s=(Dr(D|0)|0)-(Dr(L|0)|0)|0,s>>>0<=30){n=s+1|0,D=31-s|0,h=n,e=L<>>(n>>>0),n=L>>>(n>>>0),s=0,D=k<>2]=e|0,t[l+4>>2]=S|n&0,be=0,Se=0,ut=be,Se|0):(be=0,Se=0,ut=be,Se|0)}while(0);if(!h)L=D,S=0,D=0;else{I=r|0|0,k=K|u&0,L=QE(I|0,k|0,-1,-1)|0,r=ut,S=D,D=0;do u=S,S=s>>>31|S<<1,s=D|s<<1,u=e<<1|u>>>31|0,K=e>>>31|n<<1|0,A_(L|0,r|0,u|0,K|0)|0,Se=ut,be=Se>>31|((Se|0)<0?-1:0)<<1,D=be&1,e=A_(u|0,K|0,be&I|0,(((Se|0)<0?-1:0)>>31|((Se|0)<0?-1:0)<<1)&k|0)|0,n=ut,h=h-1|0;while((h|0)!=0);L=S,S=0}return h=0,l|0&&(t[l>>2]=e,t[l+4>>2]=n),be=(s|0)>>>31|(L|h)<<1|(h<<1|s>>>31)&0|S,Se=(s<<1|0>>>31)&-2|D,ut=be,Se|0}function JE(e,n,r,u){return e=e|0,n=n|0,r=r|0,u=u|0,K8(e,n,r,u,0)|0}function n2(e){e=e|0;var n=0,r=0;return r=e+15&-16|0,n=t[H>>2]|0,e=n+r|0,(r|0)>0&(e|0)<(n|0)|(e|0)<0?(fr()|0,Jl(12),-1):(t[H>>2]=e,((e|0)>(jr()|0)?(vr()|0)==0:0)?(t[H>>2]=n,Jl(12),-1):n|0)}function kg(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;if((n|0)<(e|0)&(e|0)<(n+r|0)){for(u=e,n=n+r|0,e=e+r|0;(r|0)>0;)e=e-1|0,n=n-1|0,r=r-1|0,c[e>>0]=c[n>>0]|0;e=u}else _r(e,n,r)|0;return e|0}function ZE(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0;var l=0,s=0;return s=m,m=m+16|0,l=s|0,K8(e,n,r,u,l)|0,m=s,ut=t[l+4>>2]|0,t[l>>2]|0|0}function X8(e){return e=e|0,(e&255)<<24|(e>>8&255)<<16|(e>>16&255)<<8|e>>>24|0}function rP(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,Q8[e&1](n|0,r|0,u|0,l|0,s|0)}function iP(e,n,r){e=e|0,n=n|0,r=w(r),J8[e&1](n|0,w(r))}function uP(e,n,r){e=e|0,n=n|0,r=+r,Z8[e&31](n|0,+r)}function oP(e,n,r,u){return e=e|0,n=n|0,r=w(r),u=w(u),w($8[e&0](n|0,w(r),w(u)))}function lP(e,n){e=e|0,n=n|0,P1[e&127](n|0)}function sP(e,n,r){e=e|0,n=n|0,r=r|0,I1[e&31](n|0,r|0)}function aP(e,n){return e=e|0,n=n|0,Zp[e&31](n|0)|0}function fP(e,n,r,u,l){e=e|0,n=n|0,r=+r,u=+u,l=l|0,eS[e&1](n|0,+r,+u,l|0)}function cP(e,n,r,u){e=e|0,n=n|0,r=+r,u=+u,VP[e&1](n|0,+r,+u)}function dP(e,n,r,u){return e=e|0,n=n|0,r=r|0,u=u|0,M_[e&7](n|0,r|0,u|0)|0}function pP(e,n,r,u){return e=e|0,n=n|0,r=r|0,u=u|0,+GP[e&1](n|0,r|0,u|0)}function hP(e,n){return e=e|0,n=n|0,+tS[e&15](n|0)}function vP(e,n,r){return e=e|0,n=n|0,r=+r,YP[e&1](n|0,+r)|0}function mP(e,n,r){return e=e|0,n=n|0,r=r|0,eD[e&15](n|0,r|0)|0}function gP(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=+u,l=+l,s=s|0,KP[e&1](n|0,r|0,+u,+l,s|0)}function yP(e,n,r,u,l,s,h){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,h=h|0,XP[e&1](n|0,r|0,u|0,l|0,s|0,h|0)}function _P(e,n,r){return e=e|0,n=n|0,r=r|0,+nS[e&7](n|0,r|0)}function EP(e){return e=e|0,k_[e&7]()|0}function DP(e,n,r,u,l,s){return e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,rS[e&1](n|0,r|0,u|0,l|0,s|0)|0}function wP(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=+l,QP[e&1](n|0,r|0,u|0,+l)}function SP(e,n,r,u,l,s,h){e=e|0,n=n|0,r=r|0,u=w(u),l=l|0,s=w(s),h=h|0,iS[e&1](n|0,r|0,w(u),l|0,w(s),h|0)}function TP(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,Fg[e&15](n|0,r|0,u|0)}function CP(e){e=e|0,uS[e&0]()}function xP(e,n,r,u){e=e|0,n=n|0,r=r|0,u=+u,oS[e&15](n|0,r|0,+u)}function AP(e,n,r){return e=e|0,n=+n,r=+r,JP[e&1](+n,+r)|0}function RP(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,tD[e&15](n|0,r|0,u|0,l|0)}function OP(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,jt(0)}function MP(e,n){e=e|0,n=w(n),jt(1)}function ea(e,n){e=e|0,n=+n,jt(2)}function kP(e,n,r){return e=e|0,n=w(n),r=w(r),jt(3),Tt}function Zn(e){e=e|0,jt(4)}function Lg(e,n){e=e|0,n=n|0,jt(5)}function Na(e){return e=e|0,jt(6),0}function LP(e,n,r,u){e=e|0,n=+n,r=+r,u=u|0,jt(7)}function NP(e,n,r){e=e|0,n=+n,r=+r,jt(8)}function FP(e,n,r){return e=e|0,n=n|0,r=r|0,jt(9),0}function PP(e,n,r){return e=e|0,n=n|0,r=r|0,jt(10),0}function Jp(e){return e=e|0,jt(11),0}function IP(e,n){return e=e|0,n=+n,jt(12),0}function Ng(e,n){return e=e|0,n=n|0,jt(13),0}function bP(e,n,r,u,l){e=e|0,n=n|0,r=+r,u=+u,l=l|0,jt(14)}function BP(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,jt(15)}function $E(e,n){return e=e|0,n=n|0,jt(16),0}function UP(){return jt(17),0}function jP(e,n,r,u,l){return e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,jt(18),0}function zP(e,n,r,u){e=e|0,n=n|0,r=r|0,u=+u,jt(19)}function HP(e,n,r,u,l,s){e=e|0,n=n|0,r=w(r),u=u|0,l=w(l),s=s|0,jt(20)}function O_(e,n,r){e=e|0,n=n|0,r=r|0,jt(21)}function qP(){jt(22)}function zv(e,n,r){e=e|0,n=n|0,r=+r,jt(23)}function WP(e,n){return e=+e,n=+n,jt(24),0}function Hv(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,jt(25)}var Q8=[OP,UM],J8=[MP,n0],Z8=[ea,da,Ss,Ts,ns,Ho,Df,ol,Wa,r0,wf,Wc,pc,Ol,Cs,pa,od,ha,hc,ea,ea,ea,ea,ea,ea,ea,ea,ea,ea,ea,ea,ea],$8=[kP],P1=[Zn,Uv,cn,us,Do,jf,M1,jl,hO,vO,mO,xM,AM,RM,XN,QN,JN,Ne,cc,ja,Gu,j0,gh,Tf,r1,Ff,Da,kh,gm,y1,_1,Zh,mp,Pd,jm,C1,Oc,Jm,eg,xv,Mv,on,Z4,aE,p_,Lt,xu,t0,RA,WA,aR,AR,HR,a7,_7,w7,U7,H7,uO,yO,DO,BO,nM,_d,bk,hL,OL,WL,pN,RN,UN,HN,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn,Zn],I1=[Lg,D2,rd,qc,Al,ul,w2,Ws,Rl,za,Ha,qa,Ml,ze,lt,$t,Wn,si,ur,Va,T2,_h,dE,gE,kR,jk,fM,E8,Lg,Lg,Lg,Lg],Zp=[Na,xF,Ef,g,J,pe,gt,xt,kt,xr,du,z0,Ga,ld,Xc,ks,GR,zO,Wk,Ma,Na,Na,Na,Na,Na,Na,Na,Na,Na,Na,Na,Na],eS=[LP,A2],VP=[NP,sO],M_=[FP,F8,AF,MF,Wh,vv,LA,XL],GP=[PP,fv],tS=[Jp,u0,We,ci,yh,al,va,R2,O2,vc,Jp,Jp,Jp,Jp,Jp,Jp],YP=[IP,m7],eD=[Ng,JF,S2,dl,W2,xm,dp,Rp,tg,kr,jo,NL,Ng,Ng,Ng,Ng],KP=[bP,xh],XP=[BP,gN],nS=[$E,Qi,M2,pd,Qc,ml,$E,$E],k_=[UP,Jc,io,D0,x7,G7,CO,GN],rS=[jP,li],QP=[zP,vg],iS=[HP,sd],Fg=[O_,A,i0,Gr,Cu,m1,Fd,ar,_g,mo,sk,yL,LN,O_,O_,O_],uS=[qP],oS=[zv,id,go,ud,zo,Vc,qi,y,jp,KA,d7,zv,zv,zv,zv,zv],JP=[WP,dO],tD=[Hv,wp,Fc,pR,t7,L7,Z7,LO,lM,Qk,rF,Hv,Hv,Hv,Hv,Hv];return{_llvm_bswap_i32:X8,dynCall_idd:AP,dynCall_i:EP,_i64Subtract:A_,___udivdi3:JE,dynCall_vif:iP,setThrew:ms,dynCall_viii:TP,_bitshift64Lshr:R_,_bitshift64Shl:G8,dynCall_vi:lP,dynCall_viiddi:gP,dynCall_diii:pP,dynCall_iii:mP,_memset:jv,_sbrk:n2,_memcpy:_r,__GLOBAL__sub_I_Yoga_cpp:ru,dynCall_vii:sP,___uremdi3:ZE,dynCall_vid:uP,stackAlloc:co,_nbind_init:hF,getTempRet0:Q,dynCall_di:hP,dynCall_iid:vP,setTempRet0:b0,_i64Add:QE,dynCall_fiff:oP,dynCall_iiii:dP,_emscripten_get_global_libc:CF,dynCall_viid:xP,dynCall_viiid:wP,dynCall_viififi:SP,dynCall_ii:aP,__GLOBAL__sub_I_Binding_cc:Ok,dynCall_viiii:RP,dynCall_iiiiii:DP,stackSave:nl,dynCall_viiiii:rP,__GLOBAL__sub_I_nbind_cc:Vs,dynCall_vidd:cP,_free:C_,runPostSets:nP,dynCall_viiiiii:yP,establishStackSpace:ju,_memmove:kg,stackRestore:Zl,_malloc:T_,__GLOBAL__sub_I_common_cc:XO,dynCall_viddi:fP,dynCall_dii:_P,dynCall_v:CP}}(Module.asmGlobalArg,Module.asmLibraryArg,buffer),_llvm_bswap_i32=Module._llvm_bswap_i32=asm._llvm_bswap_i32,getTempRet0=Module.getTempRet0=asm.getTempRet0,___udivdi3=Module.___udivdi3=asm.___udivdi3,setThrew=Module.setThrew=asm.setThrew,_bitshift64Lshr=Module._bitshift64Lshr=asm._bitshift64Lshr,_bitshift64Shl=Module._bitshift64Shl=asm._bitshift64Shl,_memset=Module._memset=asm._memset,_sbrk=Module._sbrk=asm._sbrk,_memcpy=Module._memcpy=asm._memcpy,stackAlloc=Module.stackAlloc=asm.stackAlloc,___uremdi3=Module.___uremdi3=asm.___uremdi3,_nbind_init=Module._nbind_init=asm._nbind_init,_i64Subtract=Module._i64Subtract=asm._i64Subtract,setTempRet0=Module.setTempRet0=asm.setTempRet0,_i64Add=Module._i64Add=asm._i64Add,_emscripten_get_global_libc=Module._emscripten_get_global_libc=asm._emscripten_get_global_libc,__GLOBAL__sub_I_Yoga_cpp=Module.__GLOBAL__sub_I_Yoga_cpp=asm.__GLOBAL__sub_I_Yoga_cpp,__GLOBAL__sub_I_Binding_cc=Module.__GLOBAL__sub_I_Binding_cc=asm.__GLOBAL__sub_I_Binding_cc,stackSave=Module.stackSave=asm.stackSave,__GLOBAL__sub_I_nbind_cc=Module.__GLOBAL__sub_I_nbind_cc=asm.__GLOBAL__sub_I_nbind_cc,_free=Module._free=asm._free,runPostSets=Module.runPostSets=asm.runPostSets,establishStackSpace=Module.establishStackSpace=asm.establishStackSpace,_memmove=Module._memmove=asm._memmove,stackRestore=Module.stackRestore=asm.stackRestore,_malloc=Module._malloc=asm._malloc,__GLOBAL__sub_I_common_cc=Module.__GLOBAL__sub_I_common_cc=asm.__GLOBAL__sub_I_common_cc,dynCall_viiiii=Module.dynCall_viiiii=asm.dynCall_viiiii,dynCall_vif=Module.dynCall_vif=asm.dynCall_vif,dynCall_vid=Module.dynCall_vid=asm.dynCall_vid,dynCall_fiff=Module.dynCall_fiff=asm.dynCall_fiff,dynCall_vi=Module.dynCall_vi=asm.dynCall_vi,dynCall_vii=Module.dynCall_vii=asm.dynCall_vii,dynCall_ii=Module.dynCall_ii=asm.dynCall_ii,dynCall_viddi=Module.dynCall_viddi=asm.dynCall_viddi,dynCall_vidd=Module.dynCall_vidd=asm.dynCall_vidd,dynCall_iiii=Module.dynCall_iiii=asm.dynCall_iiii,dynCall_diii=Module.dynCall_diii=asm.dynCall_diii,dynCall_di=Module.dynCall_di=asm.dynCall_di,dynCall_iid=Module.dynCall_iid=asm.dynCall_iid,dynCall_iii=Module.dynCall_iii=asm.dynCall_iii,dynCall_viiddi=Module.dynCall_viiddi=asm.dynCall_viiddi,dynCall_viiiiii=Module.dynCall_viiiiii=asm.dynCall_viiiiii,dynCall_dii=Module.dynCall_dii=asm.dynCall_dii,dynCall_i=Module.dynCall_i=asm.dynCall_i,dynCall_iiiiii=Module.dynCall_iiiiii=asm.dynCall_iiiiii,dynCall_viiid=Module.dynCall_viiid=asm.dynCall_viiid,dynCall_viififi=Module.dynCall_viififi=asm.dynCall_viififi,dynCall_viii=Module.dynCall_viii=asm.dynCall_viii,dynCall_v=Module.dynCall_v=asm.dynCall_v,dynCall_viid=Module.dynCall_viid=asm.dynCall_viid,dynCall_idd=Module.dynCall_idd=asm.dynCall_idd,dynCall_viiii=Module.dynCall_viiii=asm.dynCall_viiii;Runtime.stackAlloc=Module.stackAlloc,Runtime.stackSave=Module.stackSave,Runtime.stackRestore=Module.stackRestore,Runtime.establishStackSpace=Module.establishStackSpace,Runtime.setTempRet0=Module.setTempRet0,Runtime.getTempRet0=Module.getTempRet0,Module.asm=asm;function ExitStatus(i){this.name="ExitStatus",this.message="Program terminated with exit("+i+")",this.status=i}ExitStatus.prototype=new Error,ExitStatus.prototype.constructor=ExitStatus;var initialStackTop,preloadStartTime=null,calledMain=!1;dependenciesFulfilled=function i(){Module.calledRun||run(),Module.calledRun||(dependenciesFulfilled=i)},Module.callMain=Module.callMain=function(o){o=o||[],ensureInitRuntime();var a=o.length+1;function c(){for(var M=0;M<4-1;M++)_.push(0)}var _=[allocate(intArrayFromString(Module.thisProgram),"i8",ALLOC_NORMAL)];c();for(var t=0;t0||(preRun(),runDependencies>0)||Module.calledRun)return;function o(){Module.calledRun||(Module.calledRun=!0,!ABORT&&(ensureInitRuntime(),preMain(),Module.onRuntimeInitialized&&Module.onRuntimeInitialized(),Module._main&&shouldRunNow&&Module.callMain(i),postRun()))}Module.setStatus?(Module.setStatus("Running..."),setTimeout(function(){setTimeout(function(){Module.setStatus("")},1),o()},1)):o()}Module.run=Module.run=run;function exit(i,o){o&&Module.noExitRuntime||(Module.noExitRuntime||(ABORT=!0,EXITSTATUS=i,STACKTOP=initialStackTop,exitRuntime(),Module.onExit&&Module.onExit(i)),ENVIRONMENT_IS_NODE&&process.exit(i),Module.quit(i,new ExitStatus(i)))}Module.exit=Module.exit=exit;var abortDecorators=[];function abort(i){Module.onAbort&&Module.onAbort(i),i!==void 0?(Module.print(i),Module.printErr(i),i=JSON.stringify(i)):i="",ABORT=!0,EXITSTATUS=1;var o=` +If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.`,a="abort("+i+") at "+stackTrace()+o;throw abortDecorators&&abortDecorators.forEach(function(c){a=c(a,i)}),a}if(Module.abort=Module.abort=abort,Module.preInit)for(typeof Module.preInit=="function"&&(Module.preInit=[Module.preInit]);Module.preInit.length>0;)Module.preInit.pop()();var shouldRunNow=!0;Module.noInitialRun&&(shouldRunNow=!1),run()})});var eh=Ke((VW,wT)=>{"use strict";var qI=ET(),WI=DT(),BD=!1,UD=null;WI({},function(i,o){if(!BD){if(BD=!0,i)throw i;UD=o}});if(!BD)throw new Error("Failed to load the yoga module - it needed to be loaded synchronously, but didn't");wT.exports=qI(UD.bind,UD.lib)});var TT=Ke((GW,ST)=>{"use strict";ST.exports=({onlyFirst:i=!1}={})=>{let o=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(o,i?void 0:"g")}});var jD=Ke((YW,CT)=>{"use strict";var VI=TT();CT.exports=i=>typeof i=="string"?i.replace(VI(),""):i});var HD=Ke((KW,zD)=>{"use strict";var xT=i=>Number.isNaN(i)?!1:i>=4352&&(i<=4447||i===9001||i===9002||11904<=i&&i<=12871&&i!==12351||12880<=i&&i<=19903||19968<=i&&i<=42182||43360<=i&&i<=43388||44032<=i&&i<=55203||63744<=i&&i<=64255||65040<=i&&i<=65049||65072<=i&&i<=65131||65281<=i&&i<=65376||65504<=i&&i<=65510||110592<=i&&i<=110593||127488<=i&&i<=127569||131072<=i&&i<=262141);zD.exports=xT;zD.exports.default=xT});var RT=Ke((XW,AT)=>{"use strict";AT.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}});var Z_=Ke((QW,qD)=>{"use strict";var GI=jD(),YI=HD(),KI=RT(),OT=i=>{if(i=i.replace(KI()," "),typeof i!="string"||i.length===0)return 0;i=GI(i);let o=0;for(let a=0;a=127&&c<=159||c>=768&&c<=879||(c>65535&&a++,o+=YI(c)?2:1)}return o};qD.exports=OT;qD.exports.default=OT});var VD=Ke((JW,WD)=>{"use strict";var XI=Z_(),MT=i=>{let o=0;for(let a of i.split(` +`))o=Math.max(o,XI(a));return o};WD.exports=MT;WD.exports.default=MT});var kT=Ke(Jg=>{"use strict";var QI=Jg&&Jg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Jg,"__esModule",{value:!0});var JI=QI(VD()),GD={};Jg.default=i=>{if(i.length===0)return{width:0,height:0};if(GD[i])return GD[i];let o=JI.default(i),a=i.split(` +`).length;return GD[i]={width:o,height:a},{width:o,height:a}}});var LT=Ke(Zg=>{"use strict";var ZI=Zg&&Zg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Zg,"__esModule",{value:!0});var Vi=ZI(eh()),$I=(i,o)=>{"position"in o&&i.setPositionType(o.position==="absolute"?Vi.default.POSITION_TYPE_ABSOLUTE:Vi.default.POSITION_TYPE_RELATIVE)},eb=(i,o)=>{"marginLeft"in o&&i.setMargin(Vi.default.EDGE_START,o.marginLeft||0),"marginRight"in o&&i.setMargin(Vi.default.EDGE_END,o.marginRight||0),"marginTop"in o&&i.setMargin(Vi.default.EDGE_TOP,o.marginTop||0),"marginBottom"in o&&i.setMargin(Vi.default.EDGE_BOTTOM,o.marginBottom||0)},tb=(i,o)=>{"paddingLeft"in o&&i.setPadding(Vi.default.EDGE_LEFT,o.paddingLeft||0),"paddingRight"in o&&i.setPadding(Vi.default.EDGE_RIGHT,o.paddingRight||0),"paddingTop"in o&&i.setPadding(Vi.default.EDGE_TOP,o.paddingTop||0),"paddingBottom"in o&&i.setPadding(Vi.default.EDGE_BOTTOM,o.paddingBottom||0)},nb=(i,o)=>{var a;"flexGrow"in o&&i.setFlexGrow((a=o.flexGrow)!==null&&a!==void 0?a:0),"flexShrink"in o&&i.setFlexShrink(typeof o.flexShrink=="number"?o.flexShrink:1),"flexDirection"in o&&(o.flexDirection==="row"&&i.setFlexDirection(Vi.default.FLEX_DIRECTION_ROW),o.flexDirection==="row-reverse"&&i.setFlexDirection(Vi.default.FLEX_DIRECTION_ROW_REVERSE),o.flexDirection==="column"&&i.setFlexDirection(Vi.default.FLEX_DIRECTION_COLUMN),o.flexDirection==="column-reverse"&&i.setFlexDirection(Vi.default.FLEX_DIRECTION_COLUMN_REVERSE)),"flexBasis"in o&&(typeof o.flexBasis=="number"?i.setFlexBasis(o.flexBasis):typeof o.flexBasis=="string"?i.setFlexBasisPercent(Number.parseInt(o.flexBasis,10)):i.setFlexBasis(NaN)),"alignItems"in o&&((o.alignItems==="stretch"||!o.alignItems)&&i.setAlignItems(Vi.default.ALIGN_STRETCH),o.alignItems==="flex-start"&&i.setAlignItems(Vi.default.ALIGN_FLEX_START),o.alignItems==="center"&&i.setAlignItems(Vi.default.ALIGN_CENTER),o.alignItems==="flex-end"&&i.setAlignItems(Vi.default.ALIGN_FLEX_END)),"alignSelf"in o&&((o.alignSelf==="auto"||!o.alignSelf)&&i.setAlignSelf(Vi.default.ALIGN_AUTO),o.alignSelf==="flex-start"&&i.setAlignSelf(Vi.default.ALIGN_FLEX_START),o.alignSelf==="center"&&i.setAlignSelf(Vi.default.ALIGN_CENTER),o.alignSelf==="flex-end"&&i.setAlignSelf(Vi.default.ALIGN_FLEX_END)),"justifyContent"in o&&((o.justifyContent==="flex-start"||!o.justifyContent)&&i.setJustifyContent(Vi.default.JUSTIFY_FLEX_START),o.justifyContent==="center"&&i.setJustifyContent(Vi.default.JUSTIFY_CENTER),o.justifyContent==="flex-end"&&i.setJustifyContent(Vi.default.JUSTIFY_FLEX_END),o.justifyContent==="space-between"&&i.setJustifyContent(Vi.default.JUSTIFY_SPACE_BETWEEN),o.justifyContent==="space-around"&&i.setJustifyContent(Vi.default.JUSTIFY_SPACE_AROUND))},rb=(i,o)=>{var a,c;"width"in o&&(typeof o.width=="number"?i.setWidth(o.width):typeof o.width=="string"?i.setWidthPercent(Number.parseInt(o.width,10)):i.setWidthAuto()),"height"in o&&(typeof o.height=="number"?i.setHeight(o.height):typeof o.height=="string"?i.setHeightPercent(Number.parseInt(o.height,10)):i.setHeightAuto()),"minWidth"in o&&(typeof o.minWidth=="string"?i.setMinWidthPercent(Number.parseInt(o.minWidth,10)):i.setMinWidth((a=o.minWidth)!==null&&a!==void 0?a:0)),"minHeight"in o&&(typeof o.minHeight=="string"?i.setMinHeightPercent(Number.parseInt(o.minHeight,10)):i.setMinHeight((c=o.minHeight)!==null&&c!==void 0?c:0))},ib=(i,o)=>{"display"in o&&i.setDisplay(o.display==="flex"?Vi.default.DISPLAY_FLEX:Vi.default.DISPLAY_NONE)},ub=(i,o)=>{if("borderStyle"in o){let a=typeof o.borderStyle=="string"?1:0;i.setBorder(Vi.default.EDGE_TOP,a),i.setBorder(Vi.default.EDGE_BOTTOM,a),i.setBorder(Vi.default.EDGE_LEFT,a),i.setBorder(Vi.default.EDGE_RIGHT,a)}};Zg.default=(i,o={})=>{$I(i,o),eb(i,o),tb(i,o),nb(i,o),rb(i,o),ib(i,o),ub(i,o)}});var FT=Ke((eV,NT)=>{"use strict";NT.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var YD=Ke((tV,PT)=>{var $g=FT(),IT={};for(let i of Object.keys($g))IT[$g[i]]=i;var zn={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};PT.exports=zn;for(let i of Object.keys(zn)){if(!("channels"in zn[i]))throw new Error("missing channels property: "+i);if(!("labels"in zn[i]))throw new Error("missing channel labels property: "+i);if(zn[i].labels.length!==zn[i].channels)throw new Error("channel and label counts mismatch: "+i);let{channels:o,labels:a}=zn[i];delete zn[i].channels,delete zn[i].labels,Object.defineProperty(zn[i],"channels",{value:o}),Object.defineProperty(zn[i],"labels",{value:a})}zn.rgb.hsl=function(i){let o=i[0]/255,a=i[1]/255,c=i[2]/255,_=Math.min(o,a,c),t=Math.max(o,a,c),O=t-_,N,M;t===_?N=0:o===t?N=(a-c)/O:a===t?N=2+(c-o)/O:c===t&&(N=4+(o-a)/O),N=Math.min(N*60,360),N<0&&(N+=360);let T=(_+t)/2;return t===_?M=0:T<=.5?M=O/(t+_):M=O/(2-t-_),[N,M*100,T*100]};zn.rgb.hsv=function(i){let o,a,c,_,t,O=i[0]/255,N=i[1]/255,M=i[2]/255,T=Math.max(O,N,M),B=T-Math.min(O,N,M),H=function(q){return(T-q)/6/B+1/2};return B===0?(_=0,t=0):(t=B/T,o=H(O),a=H(N),c=H(M),O===T?_=c-a:N===T?_=1/3+o-c:M===T&&(_=2/3+a-o),_<0?_+=1:_>1&&(_-=1)),[_*360,t*100,T*100]};zn.rgb.hwb=function(i){let o=i[0],a=i[1],c=i[2],_=zn.rgb.hsl(i)[0],t=1/255*Math.min(o,Math.min(a,c));return c=1-1/255*Math.max(o,Math.max(a,c)),[_,t*100,c*100]};zn.rgb.cmyk=function(i){let o=i[0]/255,a=i[1]/255,c=i[2]/255,_=Math.min(1-o,1-a,1-c),t=(1-o-_)/(1-_)||0,O=(1-a-_)/(1-_)||0,N=(1-c-_)/(1-_)||0;return[t*100,O*100,N*100,_*100]};function ob(i,o){return(i[0]-o[0])**2+(i[1]-o[1])**2+(i[2]-o[2])**2}zn.rgb.keyword=function(i){let o=IT[i];if(o)return o;let a=Infinity,c;for(let _ of Object.keys($g)){let t=$g[_],O=ob(i,t);O.04045?((o+.055)/1.055)**2.4:o/12.92,a=a>.04045?((a+.055)/1.055)**2.4:a/12.92,c=c>.04045?((c+.055)/1.055)**2.4:c/12.92;let _=o*.4124+a*.3576+c*.1805,t=o*.2126+a*.7152+c*.0722,O=o*.0193+a*.1192+c*.9505;return[_*100,t*100,O*100]};zn.rgb.lab=function(i){let o=zn.rgb.xyz(i),a=o[0],c=o[1],_=o[2];a/=95.047,c/=100,_/=108.883,a=a>.008856?a**(1/3):7.787*a+16/116,c=c>.008856?c**(1/3):7.787*c+16/116,_=_>.008856?_**(1/3):7.787*_+16/116;let t=116*c-16,O=500*(a-c),N=200*(c-_);return[t,O,N]};zn.hsl.rgb=function(i){let o=i[0]/360,a=i[1]/100,c=i[2]/100,_,t,O;if(a===0)return O=c*255,[O,O,O];c<.5?_=c*(1+a):_=c+a-c*a;let N=2*c-_,M=[0,0,0];for(let T=0;T<3;T++)t=o+1/3*-(T-1),t<0&&t++,t>1&&t--,6*t<1?O=N+(_-N)*6*t:2*t<1?O=_:3*t<2?O=N+(_-N)*(2/3-t)*6:O=N,M[T]=O*255;return M};zn.hsl.hsv=function(i){let o=i[0],a=i[1]/100,c=i[2]/100,_=a,t=Math.max(c,.01);c*=2,a*=c<=1?c:2-c,_*=t<=1?t:2-t;let O=(c+a)/2,N=c===0?2*_/(t+_):2*a/(c+a);return[o,N*100,O*100]};zn.hsv.rgb=function(i){let o=i[0]/60,a=i[1]/100,c=i[2]/100,_=Math.floor(o)%6,t=o-Math.floor(o),O=255*c*(1-a),N=255*c*(1-a*t),M=255*c*(1-a*(1-t));switch(c*=255,_){case 0:return[c,M,O];case 1:return[N,c,O];case 2:return[O,c,M];case 3:return[O,N,c];case 4:return[M,O,c];case 5:return[c,O,N]}};zn.hsv.hsl=function(i){let o=i[0],a=i[1]/100,c=i[2]/100,_=Math.max(c,.01),t,O;O=(2-a)*c;let N=(2-a)*_;return t=a*_,t/=N<=1?N:2-N,t=t||0,O/=2,[o,t*100,O*100]};zn.hwb.rgb=function(i){let o=i[0]/360,a=i[1]/100,c=i[2]/100,_=a+c,t;_>1&&(a/=_,c/=_);let O=Math.floor(6*o),N=1-c;t=6*o-O,(O&1)!=0&&(t=1-t);let M=a+t*(N-a),T,B,H;switch(O){default:case 6:case 0:T=N,B=M,H=a;break;case 1:T=M,B=N,H=a;break;case 2:T=a,B=N,H=M;break;case 3:T=a,B=M,H=N;break;case 4:T=M,B=a,H=N;break;case 5:T=N,B=a,H=M;break}return[T*255,B*255,H*255]};zn.cmyk.rgb=function(i){let o=i[0]/100,a=i[1]/100,c=i[2]/100,_=i[3]/100,t=1-Math.min(1,o*(1-_)+_),O=1-Math.min(1,a*(1-_)+_),N=1-Math.min(1,c*(1-_)+_);return[t*255,O*255,N*255]};zn.xyz.rgb=function(i){let o=i[0]/100,a=i[1]/100,c=i[2]/100,_,t,O;return _=o*3.2406+a*-1.5372+c*-.4986,t=o*-.9689+a*1.8758+c*.0415,O=o*.0557+a*-.204+c*1.057,_=_>.0031308?1.055*_**(1/2.4)-.055:_*12.92,t=t>.0031308?1.055*t**(1/2.4)-.055:t*12.92,O=O>.0031308?1.055*O**(1/2.4)-.055:O*12.92,_=Math.min(Math.max(0,_),1),t=Math.min(Math.max(0,t),1),O=Math.min(Math.max(0,O),1),[_*255,t*255,O*255]};zn.xyz.lab=function(i){let o=i[0],a=i[1],c=i[2];o/=95.047,a/=100,c/=108.883,o=o>.008856?o**(1/3):7.787*o+16/116,a=a>.008856?a**(1/3):7.787*a+16/116,c=c>.008856?c**(1/3):7.787*c+16/116;let _=116*a-16,t=500*(o-a),O=200*(a-c);return[_,t,O]};zn.lab.xyz=function(i){let o=i[0],a=i[1],c=i[2],_,t,O;t=(o+16)/116,_=a/500+t,O=t-c/200;let N=t**3,M=_**3,T=O**3;return t=N>.008856?N:(t-16/116)/7.787,_=M>.008856?M:(_-16/116)/7.787,O=T>.008856?T:(O-16/116)/7.787,_*=95.047,t*=100,O*=108.883,[_,t,O]};zn.lab.lch=function(i){let o=i[0],a=i[1],c=i[2],_;_=Math.atan2(c,a)*360/2/Math.PI,_<0&&(_+=360);let O=Math.sqrt(a*a+c*c);return[o,O,_]};zn.lch.lab=function(i){let o=i[0],a=i[1],_=i[2]/360*2*Math.PI,t=a*Math.cos(_),O=a*Math.sin(_);return[o,t,O]};zn.rgb.ansi16=function(i,o=null){let[a,c,_]=i,t=o===null?zn.rgb.hsv(i)[2]:o;if(t=Math.round(t/50),t===0)return 30;let O=30+(Math.round(_/255)<<2|Math.round(c/255)<<1|Math.round(a/255));return t===2&&(O+=60),O};zn.hsv.ansi16=function(i){return zn.rgb.ansi16(zn.hsv.rgb(i),i[2])};zn.rgb.ansi256=function(i){let o=i[0],a=i[1],c=i[2];return o===a&&a===c?o<8?16:o>248?231:Math.round((o-8)/247*24)+232:16+36*Math.round(o/255*5)+6*Math.round(a/255*5)+Math.round(c/255*5)};zn.ansi16.rgb=function(i){let o=i%10;if(o===0||o===7)return i>50&&(o+=3.5),o=o/10.5*255,[o,o,o];let a=(~~(i>50)+1)*.5,c=(o&1)*a*255,_=(o>>1&1)*a*255,t=(o>>2&1)*a*255;return[c,_,t]};zn.ansi256.rgb=function(i){if(i>=232){let t=(i-232)*10+8;return[t,t,t]}i-=16;let o,a=Math.floor(i/36)/5*255,c=Math.floor((o=i%36)/6)/5*255,_=o%6/5*255;return[a,c,_]};zn.rgb.hex=function(i){let a=(((Math.round(i[0])&255)<<16)+((Math.round(i[1])&255)<<8)+(Math.round(i[2])&255)).toString(16).toUpperCase();return"000000".substring(a.length)+a};zn.hex.rgb=function(i){let o=i.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!o)return[0,0,0];let a=o[0];o[0].length===3&&(a=a.split("").map(N=>N+N).join(""));let c=parseInt(a,16),_=c>>16&255,t=c>>8&255,O=c&255;return[_,t,O]};zn.rgb.hcg=function(i){let o=i[0]/255,a=i[1]/255,c=i[2]/255,_=Math.max(Math.max(o,a),c),t=Math.min(Math.min(o,a),c),O=_-t,N,M;return O<1?N=t/(1-O):N=0,O<=0?M=0:_===o?M=(a-c)/O%6:_===a?M=2+(c-o)/O:M=4+(o-a)/O,M/=6,M%=1,[M*360,O*100,N*100]};zn.hsl.hcg=function(i){let o=i[1]/100,a=i[2]/100,c=a<.5?2*o*a:2*o*(1-a),_=0;return c<1&&(_=(a-.5*c)/(1-c)),[i[0],c*100,_*100]};zn.hsv.hcg=function(i){let o=i[1]/100,a=i[2]/100,c=o*a,_=0;return c<1&&(_=(a-c)/(1-c)),[i[0],c*100,_*100]};zn.hcg.rgb=function(i){let o=i[0]/360,a=i[1]/100,c=i[2]/100;if(a===0)return[c*255,c*255,c*255];let _=[0,0,0],t=o%1*6,O=t%1,N=1-O,M=0;switch(Math.floor(t)){case 0:_[0]=1,_[1]=O,_[2]=0;break;case 1:_[0]=N,_[1]=1,_[2]=0;break;case 2:_[0]=0,_[1]=1,_[2]=O;break;case 3:_[0]=0,_[1]=N,_[2]=1;break;case 4:_[0]=O,_[1]=0,_[2]=1;break;default:_[0]=1,_[1]=0,_[2]=N}return M=(1-a)*c,[(a*_[0]+M)*255,(a*_[1]+M)*255,(a*_[2]+M)*255]};zn.hcg.hsv=function(i){let o=i[1]/100,a=i[2]/100,c=o+a*(1-o),_=0;return c>0&&(_=o/c),[i[0],_*100,c*100]};zn.hcg.hsl=function(i){let o=i[1]/100,c=i[2]/100*(1-o)+.5*o,_=0;return c>0&&c<.5?_=o/(2*c):c>=.5&&c<1&&(_=o/(2*(1-c))),[i[0],_*100,c*100]};zn.hcg.hwb=function(i){let o=i[1]/100,a=i[2]/100,c=o+a*(1-o);return[i[0],(c-o)*100,(1-c)*100]};zn.hwb.hcg=function(i){let o=i[1]/100,a=i[2]/100,c=1-a,_=c-o,t=0;return _<1&&(t=(c-_)/(1-_)),[i[0],_*100,t*100]};zn.apple.rgb=function(i){return[i[0]/65535*255,i[1]/65535*255,i[2]/65535*255]};zn.rgb.apple=function(i){return[i[0]/255*65535,i[1]/255*65535,i[2]/255*65535]};zn.gray.rgb=function(i){return[i[0]/100*255,i[0]/100*255,i[0]/100*255]};zn.gray.hsl=function(i){return[0,0,i[0]]};zn.gray.hsv=zn.gray.hsl;zn.gray.hwb=function(i){return[0,100,i[0]]};zn.gray.cmyk=function(i){return[0,0,0,i[0]]};zn.gray.lab=function(i){return[i[0],0,0]};zn.gray.hex=function(i){let o=Math.round(i[0]/100*255)&255,c=((o<<16)+(o<<8)+o).toString(16).toUpperCase();return"000000".substring(c.length)+c};zn.rgb.gray=function(i){return[(i[0]+i[1]+i[2])/3/255*100]}});var BT=Ke((nV,bT)=>{var $_=YD();function lb(){let i={},o=Object.keys($_);for(let a=o.length,c=0;c{var KD=YD(),cb=BT(),Qv={},db=Object.keys(KD);function pb(i){let o=function(...a){let c=a[0];return c==null?c:(c.length>1&&(a=c),i(a))};return"conversion"in i&&(o.conversion=i.conversion),o}function hb(i){let o=function(...a){let c=a[0];if(c==null)return c;c.length>1&&(a=c);let _=i(a);if(typeof _=="object")for(let t=_.length,O=0;O{Qv[i]={},Object.defineProperty(Qv[i],"channels",{value:KD[i].channels}),Object.defineProperty(Qv[i],"labels",{value:KD[i].labels});let o=cb(i);Object.keys(o).forEach(c=>{let _=o[c];Qv[i][c]=hb(_),Qv[i][c].raw=pb(_)})});UT.exports=Qv});var t4=Ke((iV,zT)=>{"use strict";var HT=(i,o)=>(...a)=>`[${i(...a)+o}m`,qT=(i,o)=>(...a)=>{let c=i(...a);return`[${38+o};5;${c}m`},WT=(i,o)=>(...a)=>{let c=i(...a);return`[${38+o};2;${c[0]};${c[1]};${c[2]}m`},e4=i=>i,VT=(i,o,a)=>[i,o,a],Jv=(i,o,a)=>{Object.defineProperty(i,o,{get:()=>{let c=a();return Object.defineProperty(i,o,{value:c,enumerable:!0,configurable:!0}),c},enumerable:!0,configurable:!0})},XD,Zv=(i,o,a,c)=>{XD===void 0&&(XD=jT());let _=c?10:0,t={};for(let[O,N]of Object.entries(XD)){let M=O==="ansi16"?"ansi":O;O===o?t[M]=i(a,_):typeof N=="object"&&(t[M]=i(N[o],_))}return t};function vb(){let i=new Map,o={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};o.color.gray=o.color.blackBright,o.bgColor.bgGray=o.bgColor.bgBlackBright,o.color.grey=o.color.blackBright,o.bgColor.bgGrey=o.bgColor.bgBlackBright;for(let[a,c]of Object.entries(o)){for(let[_,t]of Object.entries(c))o[_]={open:`[${t[0]}m`,close:`[${t[1]}m`},c[_]=o[_],i.set(t[0],t[1]);Object.defineProperty(o,a,{value:c,enumerable:!1})}return Object.defineProperty(o,"codes",{value:i,enumerable:!1}),o.color.close="",o.bgColor.close="",Jv(o.color,"ansi",()=>Zv(HT,"ansi16",e4,!1)),Jv(o.color,"ansi256",()=>Zv(qT,"ansi256",e4,!1)),Jv(o.color,"ansi16m",()=>Zv(WT,"rgb",VT,!1)),Jv(o.bgColor,"ansi",()=>Zv(HT,"ansi16",e4,!0)),Jv(o.bgColor,"ansi256",()=>Zv(qT,"ansi256",e4,!0)),Jv(o.bgColor,"ansi16m",()=>Zv(WT,"rgb",VT,!0)),o}Object.defineProperty(zT,"exports",{enumerable:!0,get:vb})});var KT=Ke((uV,GT)=>{"use strict";var ey=Z_(),mb=jD(),gb=t4(),QD=new Set(["","\x9B"]),yb=39,YT=i=>`${QD.values().next().value}[${i}m`,_b=i=>i.split(" ").map(o=>ey(o)),JD=(i,o,a)=>{let c=[...o],_=!1,t=ey(mb(i[i.length-1]));for(let[O,N]of c.entries()){let M=ey(N);if(t+M<=a?i[i.length-1]+=N:(i.push(N),t=0),QD.has(N))_=!0;else if(_&&N==="m"){_=!1;continue}_||(t+=M,t===a&&O0&&i.length>1&&(i[i.length-2]+=i.pop())},Eb=i=>{let o=i.split(" "),a=o.length;for(;a>0&&!(ey(o[a-1])>0);)a--;return a===o.length?i:o.slice(0,a).join(" ")+o.slice(a).join("")},Db=(i,o,a={})=>{if(a.trim!==!1&&i.trim()==="")return"";let c="",_="",t,O=_b(i),N=[""];for(let[M,T]of i.split(" ").entries()){a.trim!==!1&&(N[N.length-1]=N[N.length-1].trimLeft());let B=ey(N[N.length-1]);if(M!==0&&(B>=o&&(a.wordWrap===!1||a.trim===!1)&&(N.push(""),B=0),(B>0||a.trim===!1)&&(N[N.length-1]+=" ",B++)),a.hard&&O[M]>o){let H=o-B,q=1+Math.floor((O[M]-H-1)/o);Math.floor((O[M]-1)/o)o&&B>0&&O[M]>0){if(a.wordWrap===!1&&Bo&&a.wordWrap===!1){JD(N,T,o);continue}N[N.length-1]+=T}a.trim!==!1&&(N=N.map(Eb)),c=N.join(` +`);for(let[M,T]of[...c].entries()){if(_+=T,QD.has(T)){let H=parseFloat(/\d[^m]*/.exec(c.slice(M,M+4)));t=H===yb?null:H}let B=gb.codes.get(Number(t));t&&B&&(c[M+1]===` +`?_+=YT(B):T===` +`&&(_+=YT(t)))}return _};GT.exports=(i,o,a)=>String(i).normalize().replace(/\r\n/g,` +`).split(` +`).map(c=>Db(c,o,a)).join(` +`)});var JT=Ke((oV,XT)=>{"use strict";var QT="[\uD800-\uDBFF][\uDC00-\uDFFF]",wb=i=>i&&i.exact?new RegExp(`^${QT}$`):new RegExp(QT,"g");XT.exports=wb});var ZD=Ke((lV,ZT)=>{"use strict";var Sb=HD(),Tb=JT(),$T=t4(),eC=["","\x9B"],n4=i=>`${eC[0]}[${i}m`,tC=(i,o,a)=>{let c=[];i=[...i];for(let _ of i){let t=_;_.match(";")&&(_=_.split(";")[0][0]+"0");let O=$T.codes.get(parseInt(_,10));if(O){let N=i.indexOf(O.toString());N>=0?i.splice(N,1):c.push(n4(o?O:t))}else if(o){c.push(n4(0));break}else c.push(n4(t))}if(o&&(c=c.filter((_,t)=>c.indexOf(_)===t),a!==void 0)){let _=n4($T.codes.get(parseInt(a,10)));c=c.reduce((t,O)=>O===_?[O,...t]:[...t,O],[])}return c.join("")};ZT.exports=(i,o,a)=>{let c=[...i.normalize()],_=[];a=typeof a=="number"?a:c.length;let t=!1,O,N=0,M="";for(let[T,B]of c.entries()){let H=!1;if(eC.includes(B)){let q=/\d[^m]*/.exec(i.slice(T,T+18));O=q&&q.length>0?q[0]:void 0,No&&N<=a)M+=B;else if(N===o&&!t&&O!==void 0)M=tC(_);else if(N>=a){M+=tC(_,!0,O);break}}return M}});var rC=Ke((sV,nC)=>{"use strict";var p2=ZD(),Cb=Z_();function r4(i,o,a){if(i.charAt(o)===" ")return o;for(let c=1;c<=3;c++)if(a){if(i.charAt(o+c)===" ")return o+c}else if(i.charAt(o-c)===" ")return o-c;return o}nC.exports=(i,o,a)=>{a=Ht({position:"end",preferTruncationOnSpace:!1},a);let{position:c,space:_,preferTruncationOnSpace:t}=a,O="\u2026",N=1;if(typeof i!="string")throw new TypeError(`Expected \`input\` to be a string, got ${typeof i}`);if(typeof o!="number")throw new TypeError(`Expected \`columns\` to be a number, got ${typeof o}`);if(o<1)return"";if(o===1)return O;let M=Cb(i);if(M<=o)return i;if(c==="start"){if(t){let T=r4(i,M-o+1,!0);return O+p2(i,T,M).trim()}return _===!0&&(O+=" ",N=2),O+p2(i,M-o+N,M)}if(c==="middle"){_===!0&&(O=" "+O+" ",N=3);let T=Math.floor(o/2);if(t){let B=r4(i,T),H=r4(i,M-(o-T)+1,!0);return p2(i,0,B)+O+p2(i,H,M).trim()}return p2(i,0,T)+O+p2(i,M-(o-T)+N,M)}if(c==="end"){if(t){let T=r4(i,o-1);return p2(i,0,T)+O}return _===!0&&(O=" "+O,N=2),p2(i,0,o-N)+O}throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${c}`)}});var e3=Ke(ty=>{"use strict";var iC=ty&&ty.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(ty,"__esModule",{value:!0});var xb=iC(KT()),Ab=iC(rC()),$D={};ty.default=(i,o,a)=>{let c=i+String(o)+String(a);if($D[c])return $D[c];let _=i;if(a==="wrap"&&(_=xb.default(i,o,{trim:!1,hard:!0})),a.startsWith("truncate")){let t="end";a==="truncate-middle"&&(t="middle"),a==="truncate-start"&&(t="start"),_=Ab.default(i,o,{position:t})}return $D[c]=_,_}});var n3=Ke(t3=>{"use strict";Object.defineProperty(t3,"__esModule",{value:!0});var uC=i=>{let o="";if(i.childNodes.length>0)for(let a of i.childNodes){let c="";a.nodeName==="#text"?c=a.nodeValue:((a.nodeName==="ink-text"||a.nodeName==="ink-virtual-text")&&(c=uC(a)),c.length>0&&typeof a.internal_transform=="function"&&(c=a.internal_transform(c))),o+=c}return o};t3.default=uC});var r3=Ke(c0=>{"use strict";var ny=c0&&c0.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(c0,"__esModule",{value:!0});c0.setTextNodeValue=c0.createTextNode=c0.setStyle=c0.setAttribute=c0.removeChildNode=c0.insertBeforeNode=c0.appendChildNode=c0.createNode=c0.TEXT_NAME=void 0;var Rb=ny(eh()),oC=ny(kT()),Ob=ny(LT()),Mb=ny(e3()),kb=ny(n3());c0.TEXT_NAME="#text";c0.createNode=i=>{var o;let a={nodeName:i,style:{},attributes:{},childNodes:[],parentNode:null,yogaNode:i==="ink-virtual-text"?void 0:Rb.default.Node.create()};return i==="ink-text"&&((o=a.yogaNode)===null||o===void 0||o.setMeasureFunc(Lb.bind(null,a))),a};c0.appendChildNode=(i,o)=>{var a;o.parentNode&&c0.removeChildNode(o.parentNode,o),o.parentNode=i,i.childNodes.push(o),o.yogaNode&&((a=i.yogaNode)===null||a===void 0||a.insertChild(o.yogaNode,i.yogaNode.getChildCount())),(i.nodeName==="ink-text"||i.nodeName==="ink-virtual-text")&&i4(i)};c0.insertBeforeNode=(i,o,a)=>{var c,_;o.parentNode&&c0.removeChildNode(o.parentNode,o),o.parentNode=i;let t=i.childNodes.indexOf(a);if(t>=0){i.childNodes.splice(t,0,o),o.yogaNode&&((c=i.yogaNode)===null||c===void 0||c.insertChild(o.yogaNode,t));return}i.childNodes.push(o),o.yogaNode&&((_=i.yogaNode)===null||_===void 0||_.insertChild(o.yogaNode,i.yogaNode.getChildCount())),(i.nodeName==="ink-text"||i.nodeName==="ink-virtual-text")&&i4(i)};c0.removeChildNode=(i,o)=>{var a,c;o.yogaNode&&((c=(a=o.parentNode)===null||a===void 0?void 0:a.yogaNode)===null||c===void 0||c.removeChild(o.yogaNode)),o.parentNode=null;let _=i.childNodes.indexOf(o);_>=0&&i.childNodes.splice(_,1),(i.nodeName==="ink-text"||i.nodeName==="ink-virtual-text")&&i4(i)};c0.setAttribute=(i,o,a)=>{i.attributes[o]=a};c0.setStyle=(i,o)=>{i.style=o,i.yogaNode&&Ob.default(i.yogaNode,o)};c0.createTextNode=i=>{let o={nodeName:"#text",nodeValue:i,yogaNode:void 0,parentNode:null,style:{}};return c0.setTextNodeValue(o,i),o};var Lb=function(i,o){var a,c;let _=i.nodeName==="#text"?i.nodeValue:kb.default(i),t=oC.default(_);if(t.width<=o||t.width>=1&&o>0&&o<1)return t;let O=(c=(a=i.style)===null||a===void 0?void 0:a.textWrap)!==null&&c!==void 0?c:"wrap",N=Mb.default(_,o,O);return oC.default(N)},lC=i=>{var o;if(!(!i||!i.parentNode))return(o=i.yogaNode)!==null&&o!==void 0?o:lC(i.parentNode)},i4=i=>{let o=lC(i);o==null||o.markDirty()};c0.setTextNodeValue=(i,o)=>{typeof o!="string"&&(o=String(o)),i.nodeValue=o,i4(i)}});var th=Ke((dV,sC)=>{"use strict";sC.exports={BINARY_TYPES:["nodebuffer","arraybuffer","fragments"],GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),EMPTY_BUFFER:Buffer.alloc(0),NOOP:()=>{}}});var ry=Ke((pV,i3)=>{"use strict";var{EMPTY_BUFFER:Nb}=th();function aC(i,o){if(i.length===0)return Nb;if(i.length===1)return i[0];let a=Buffer.allocUnsafe(o),c=0;for(let _=0;_{"use strict";var hC=Symbol("kDone"),u3=Symbol("kRun"),vC=class{constructor(o){this[hC]=()=>{this.pending--,this[u3]()},this.concurrency=o||Infinity,this.jobs=[],this.pending=0}add(o){this.jobs.push(o),this[u3]()}[u3](){if(this.pending!==this.concurrency&&this.jobs.length){let o=this.jobs.shift();this.pending++,o(this[hC])}}};pC.exports=vC});var oy=Ke((vV,gC)=>{"use strict";var iy=require("zlib"),yC=ry(),Fb=mC(),{kStatusCode:_C,NOOP:Pb}=th(),Ib=Buffer.from([0,0,255,255]),o4=Symbol("permessage-deflate"),X1=Symbol("total-length"),uy=Symbol("callback"),h2=Symbol("buffers"),o3=Symbol("error"),l4,EC=class{constructor(o,a,c){if(this._maxPayload=c|0,this._options=o||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._isServer=!!a,this._deflate=null,this._inflate=null,this.params=null,!l4){let _=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;l4=new Fb(_)}}static get extensionName(){return"permessage-deflate"}offer(){let o={};return this._options.serverNoContextTakeover&&(o.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(o.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(o.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?o.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(o.client_max_window_bits=!0),o}accept(o){return o=this.normalizeParams(o),this.params=this._isServer?this.acceptAsServer(o):this.acceptAsClient(o),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){let o=this._deflate[uy];this._deflate.close(),this._deflate=null,o&&o(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(o){let a=this._options,c=o.find(_=>!(a.serverNoContextTakeover===!1&&_.server_no_context_takeover||_.server_max_window_bits&&(a.serverMaxWindowBits===!1||typeof a.serverMaxWindowBits=="number"&&a.serverMaxWindowBits>_.server_max_window_bits)||typeof a.clientMaxWindowBits=="number"&&!_.client_max_window_bits));if(!c)throw new Error("None of the extension offers can be accepted");return a.serverNoContextTakeover&&(c.server_no_context_takeover=!0),a.clientNoContextTakeover&&(c.client_no_context_takeover=!0),typeof a.serverMaxWindowBits=="number"&&(c.server_max_window_bits=a.serverMaxWindowBits),typeof a.clientMaxWindowBits=="number"?c.client_max_window_bits=a.clientMaxWindowBits:(c.client_max_window_bits===!0||a.clientMaxWindowBits===!1)&&delete c.client_max_window_bits,c}acceptAsClient(o){let a=o[0];if(this._options.clientNoContextTakeover===!1&&a.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!a.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(a.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&a.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return a}normalizeParams(o){return o.forEach(a=>{Object.keys(a).forEach(c=>{let _=a[c];if(_.length>1)throw new Error(`Parameter "${c}" must have only a single value`);if(_=_[0],c==="client_max_window_bits"){if(_!==!0){let t=+_;if(!Number.isInteger(t)||t<8||t>15)throw new TypeError(`Invalid value for parameter "${c}": ${_}`);_=t}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${c}": ${_}`)}else if(c==="server_max_window_bits"){let t=+_;if(!Number.isInteger(t)||t<8||t>15)throw new TypeError(`Invalid value for parameter "${c}": ${_}`);_=t}else if(c==="client_no_context_takeover"||c==="server_no_context_takeover"){if(_!==!0)throw new TypeError(`Invalid value for parameter "${c}": ${_}`)}else throw new Error(`Unknown parameter "${c}"`);a[c]=_})}),o}decompress(o,a,c){l4.add(_=>{this._decompress(o,a,(t,O)=>{_(),c(t,O)})})}compress(o,a,c){l4.add(_=>{this._compress(o,a,(t,O)=>{_(),c(t,O)})})}_decompress(o,a,c){let _=this._isServer?"client":"server";if(!this._inflate){let t=`${_}_max_window_bits`,O=typeof this.params[t]!="number"?iy.Z_DEFAULT_WINDOWBITS:this.params[t];this._inflate=iy.createInflateRaw(Zr(Ht({},this._options.zlibInflateOptions),{windowBits:O})),this._inflate[o4]=this,this._inflate[X1]=0,this._inflate[h2]=[],this._inflate.on("error",Bb),this._inflate.on("data",DC)}this._inflate[uy]=c,this._inflate.write(o),a&&this._inflate.write(Ib),this._inflate.flush(()=>{let t=this._inflate[o3];if(t){this._inflate.close(),this._inflate=null,c(t);return}let O=yC.concat(this._inflate[h2],this._inflate[X1]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[X1]=0,this._inflate[h2]=[],a&&this.params[`${_}_no_context_takeover`]&&this._inflate.reset()),c(null,O)})}_compress(o,a,c){let _=this._isServer?"server":"client";if(!this._deflate){let t=`${_}_max_window_bits`,O=typeof this.params[t]!="number"?iy.Z_DEFAULT_WINDOWBITS:this.params[t];this._deflate=iy.createDeflateRaw(Zr(Ht({},this._options.zlibDeflateOptions),{windowBits:O})),this._deflate[X1]=0,this._deflate[h2]=[],this._deflate.on("error",Pb),this._deflate.on("data",bb)}this._deflate[uy]=c,this._deflate.write(o),this._deflate.flush(iy.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let t=yC.concat(this._deflate[h2],this._deflate[X1]);a&&(t=t.slice(0,t.length-4)),this._deflate[uy]=null,this._deflate[X1]=0,this._deflate[h2]=[],a&&this.params[`${_}_no_context_takeover`]&&this._deflate.reset(),c(null,t)})}};gC.exports=EC;function bb(i){this[h2].push(i),this[X1]+=i.length}function DC(i){if(this[X1]+=i.length,this[o4]._maxPayload<1||this[X1]<=this[o4]._maxPayload){this[h2].push(i);return}this[o3]=new RangeError("Max payload size exceeded"),this[o3][_C]=1009,this.removeListener("data",DC),this.reset()}function Bb(i){this[o4]._inflate=null,i[_C]=1007,this[uy](i)}});var s3=Ke((mV,l3)=>{"use strict";function wC(i){return i>=1e3&&i<=1014&&i!==1004&&i!==1005&&i!==1006||i>=3e3&&i<=4999}function SC(i){let o=i.length,a=0;for(;a=o||(i[a+1]&192)!=128||(i[a+2]&192)!=128||i[a]===224&&(i[a+1]&224)==128||i[a]===237&&(i[a+1]&224)==160)return!1;a+=3}else if((i[a]&248)==240){if(a+3>=o||(i[a+1]&192)!=128||(i[a+2]&192)!=128||(i[a+3]&192)!=128||i[a]===240&&(i[a+1]&240)==128||i[a]===244&&i[a+1]>143||i[a]>244)return!1;a+=4}else return!1;return!0}try{let i=require("utf-8-validate");typeof i=="object"&&(i=i.Validation.isValidUTF8),l3.exports={isValidStatusCode:wC,isValidUTF8(o){return o.length<150?SC(o):i(o)}}}catch(i){l3.exports={isValidStatusCode:wC,isValidUTF8:SC}}});var c3=Ke((gV,TC)=>{"use strict";var{Writable:Ub}=require("stream"),CC=oy(),{BINARY_TYPES:jb,EMPTY_BUFFER:zb,kStatusCode:Hb,kWebSocket:qb}=th(),{concat:a3,toArrayBuffer:Wb,unmask:Vb}=ry(),{isValidStatusCode:Gb,isValidUTF8:xC}=s3(),ly=0,AC=1,RC=2,OC=3,f3=4,Yb=5,MC=class extends Ub{constructor(o,a,c,_){super();this._binaryType=o||jb[0],this[qb]=void 0,this._extensions=a||{},this._isServer=!!c,this._maxPayload=_|0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._state=ly,this._loop=!1}_write(o,a,c){if(this._opcode===8&&this._state==ly)return c();this._bufferedBytes+=o.length,this._buffers.push(o),this.startLoop(c)}consume(o){if(this._bufferedBytes-=o,o===this._buffers[0].length)return this._buffers.shift();if(o=c.length?a.set(this._buffers.shift(),_):(a.set(new Uint8Array(c.buffer,c.byteOffset,o),_),this._buffers[0]=c.slice(o)),o-=c.length}while(o>0);return a}startLoop(o){let a;this._loop=!0;do switch(this._state){case ly:a=this.getInfo();break;case AC:a=this.getPayloadLength16();break;case RC:a=this.getPayloadLength64();break;case OC:this.getMask();break;case f3:a=this.getData(o);break;default:this._loop=!1;return}while(this._loop);o(a)}getInfo(){if(this._bufferedBytes<2){this._loop=!1;return}let o=this.consume(2);if((o[0]&48)!=0)return this._loop=!1,Ko(RangeError,"RSV2 and RSV3 must be clear",!0,1002);let a=(o[0]&64)==64;if(a&&!this._extensions[CC.extensionName])return this._loop=!1,Ko(RangeError,"RSV1 must be clear",!0,1002);if(this._fin=(o[0]&128)==128,this._opcode=o[0]&15,this._payloadLength=o[1]&127,this._opcode===0){if(a)return this._loop=!1,Ko(RangeError,"RSV1 must be clear",!0,1002);if(!this._fragmented)return this._loop=!1,Ko(RangeError,"invalid opcode 0",!0,1002);this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented)return this._loop=!1,Ko(RangeError,`invalid opcode ${this._opcode}`,!0,1002);this._compressed=a}else if(this._opcode>7&&this._opcode<11){if(!this._fin)return this._loop=!1,Ko(RangeError,"FIN must be set",!0,1002);if(a)return this._loop=!1,Ko(RangeError,"RSV1 must be clear",!0,1002);if(this._payloadLength>125)return this._loop=!1,Ko(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002)}else return this._loop=!1,Ko(RangeError,`invalid opcode ${this._opcode}`,!0,1002);if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(o[1]&128)==128,this._isServer){if(!this._masked)return this._loop=!1,Ko(RangeError,"MASK must be set",!0,1002)}else if(this._masked)return this._loop=!1,Ko(RangeError,"MASK must be clear",!0,1002);if(this._payloadLength===126)this._state=AC;else if(this._payloadLength===127)this._state=RC;else return this.haveLength()}getPayloadLength16(){if(this._bufferedBytes<2){this._loop=!1;return}return this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength()}getPayloadLength64(){if(this._bufferedBytes<8){this._loop=!1;return}let o=this.consume(8),a=o.readUInt32BE(0);return a>Math.pow(2,53-32)-1?(this._loop=!1,Ko(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009)):(this._payloadLength=a*Math.pow(2,32)+o.readUInt32BE(4),this.haveLength())}haveLength(){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0))return this._loop=!1,Ko(RangeError,"Max payload size exceeded",!1,1009);this._masked?this._state=OC:this._state=f3}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=f3}getData(o){let a=zb;if(this._payloadLength){if(this._bufferedBytes7)return this.controlMessage(a);if(this._compressed){this._state=Yb,this.decompress(a,o);return}return a.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(a)),this.dataMessage()}decompress(o,a){this._extensions[CC.extensionName].decompress(o,this._fin,(_,t)=>{if(_)return a(_);if(t.length){if(this._messageLength+=t.length,this._messageLength>this._maxPayload&&this._maxPayload>0)return a(Ko(RangeError,"Max payload size exceeded",!1,1009));this._fragments.push(t)}let O=this.dataMessage();if(O)return a(O);this.startLoop(a)})}dataMessage(){if(this._fin){let o=this._messageLength,a=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let c;this._binaryType==="nodebuffer"?c=a3(a,o):this._binaryType==="arraybuffer"?c=Wb(a3(a,o)):c=a,this.emit("message",c)}else{let c=a3(a,o);if(!xC(c))return this._loop=!1,Ko(Error,"invalid UTF-8 sequence",!0,1007);this.emit("message",c.toString())}}this._state=ly}controlMessage(o){if(this._opcode===8)if(this._loop=!1,o.length===0)this.emit("conclude",1005,""),this.end();else{if(o.length===1)return Ko(RangeError,"invalid payload length 1",!0,1002);{let a=o.readUInt16BE(0);if(!Gb(a))return Ko(RangeError,`invalid status code ${a}`,!0,1002);let c=o.slice(2);if(!xC(c))return Ko(Error,"invalid UTF-8 sequence",!0,1007);this.emit("conclude",a,c.toString()),this.end()}}else this._opcode===9?this.emit("ping",o):this.emit("pong",o);this._state=ly}};TC.exports=MC;function Ko(i,o,a,c){let _=new i(a?`Invalid WebSocket frame: ${o}`:o);return Error.captureStackTrace(_,Ko),_[Hb]=c,_}});var d3=Ke((yV,kC)=>{"use strict";var{randomFillSync:Kb}=require("crypto"),LC=oy(),{EMPTY_BUFFER:Xb}=th(),{isValidStatusCode:Qb}=s3(),{mask:NC,toBuffer:Q1}=ry(),nh=Buffer.alloc(4),J1=class{constructor(o,a){this._extensions=a||{},this._socket=o,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._deflating=!1,this._queue=[]}static frame(o,a){let c=a.mask&&a.readOnly,_=a.mask?6:2,t=o.length;o.length>=65536?(_+=8,t=127):o.length>125&&(_+=2,t=126);let O=Buffer.allocUnsafe(c?o.length+_:_);return O[0]=a.fin?a.opcode|128:a.opcode,a.rsv1&&(O[0]|=64),O[1]=t,t===126?O.writeUInt16BE(o.length,2):t===127&&(O.writeUInt32BE(0,2),O.writeUInt32BE(o.length,6)),a.mask?(Kb(nh,0,4),O[1]|=128,O[_-4]=nh[0],O[_-3]=nh[1],O[_-2]=nh[2],O[_-1]=nh[3],c?(NC(o,nh,O,_,o.length),[O]):(NC(o,nh,o,0,o.length),[O,o])):[O,o]}close(o,a,c,_){let t;if(o===void 0)t=Xb;else{if(typeof o!="number"||!Qb(o))throw new TypeError("First argument must be a valid error code number");if(a===void 0||a==="")t=Buffer.allocUnsafe(2),t.writeUInt16BE(o,0);else{let O=Buffer.byteLength(a);if(O>123)throw new RangeError("The message must not be greater than 123 bytes");t=Buffer.allocUnsafe(2+O),t.writeUInt16BE(o,0),t.write(a,2)}}this._deflating?this.enqueue([this.doClose,t,c,_]):this.doClose(t,c,_)}doClose(o,a,c){this.sendFrame(J1.frame(o,{fin:!0,rsv1:!1,opcode:8,mask:a,readOnly:!1}),c)}ping(o,a,c){let _=Q1(o);if(_.length>125)throw new RangeError("The data size must not be greater than 125 bytes");this._deflating?this.enqueue([this.doPing,_,a,Q1.readOnly,c]):this.doPing(_,a,Q1.readOnly,c)}doPing(o,a,c,_){this.sendFrame(J1.frame(o,{fin:!0,rsv1:!1,opcode:9,mask:a,readOnly:c}),_)}pong(o,a,c){let _=Q1(o);if(_.length>125)throw new RangeError("The data size must not be greater than 125 bytes");this._deflating?this.enqueue([this.doPong,_,a,Q1.readOnly,c]):this.doPong(_,a,Q1.readOnly,c)}doPong(o,a,c,_){this.sendFrame(J1.frame(o,{fin:!0,rsv1:!1,opcode:10,mask:a,readOnly:c}),_)}send(o,a,c){let _=Q1(o),t=this._extensions[LC.extensionName],O=a.binary?2:1,N=a.compress;if(this._firstFragment?(this._firstFragment=!1,N&&t&&(N=_.length>=t._threshold),this._compress=N):(N=!1,O=0),a.fin&&(this._firstFragment=!0),t){let M={fin:a.fin,rsv1:N,opcode:O,mask:a.mask,readOnly:Q1.readOnly};this._deflating?this.enqueue([this.dispatch,_,this._compress,M,c]):this.dispatch(_,this._compress,M,c)}else this.sendFrame(J1.frame(_,{fin:a.fin,rsv1:!1,opcode:O,mask:a.mask,readOnly:Q1.readOnly}),c)}dispatch(o,a,c,_){if(!a){this.sendFrame(J1.frame(o,c),_);return}let t=this._extensions[LC.extensionName];this._bufferedBytes+=o.length,this._deflating=!0,t.compress(o,c.fin,(O,N)=>{if(this._socket.destroyed){let M=new Error("The socket was closed while data was being compressed");typeof _=="function"&&_(M);for(let T=0;T{"use strict";var sy=class{constructor(o,a){this.target=a,this.type=o}},PC=class extends sy{constructor(o,a){super("message",a);this.data=o}},IC=class extends sy{constructor(o,a,c){super("close",c);this.wasClean=c._closeFrameReceived&&c._closeFrameSent,this.reason=a,this.code=o}},bC=class extends sy{constructor(o){super("open",o)}},BC=class extends sy{constructor(o,a){super("error",a);this.message=o.message,this.error=o}},Jb={addEventListener(i,o,a){if(typeof o!="function")return;function c(M){o.call(this,new PC(M,this))}function _(M,T){o.call(this,new IC(M,T,this))}function t(M){o.call(this,new BC(M,this))}function O(){o.call(this,new bC(this))}let N=a&&a.once?"once":"on";i==="message"?(c._listener=o,this[N](i,c)):i==="close"?(_._listener=o,this[N](i,_)):i==="error"?(t._listener=o,this[N](i,t)):i==="open"?(O._listener=o,this[N](i,O)):this[N](i,o)},removeEventListener(i,o){let a=this.listeners(i);for(let c=0;c{"use strict";var ay=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function zc(i,o,a){i[o]===void 0?i[o]=[a]:i[o].push(a)}function Zb(i){let o=Object.create(null);if(i===void 0||i==="")return o;let a=Object.create(null),c=!1,_=!1,t=!1,O,N,M=-1,T=-1,B=0;for(;B{let a=i[o];return Array.isArray(a)||(a=[a]),a.map(c=>[o].concat(Object.keys(c).map(_=>{let t=c[_];return Array.isArray(t)||(t=[t]),t.map(O=>O===!0?_:`${_}=${O}`).join("; ")})).join("; ")).join(", ")}).join(", ")}jC.exports={format:$b,parse:Zb}});var y3=Ke((DV,zC)=>{"use strict";var eB=require("events"),tB=require("https"),nB=require("http"),HC=require("net"),rB=require("tls"),{randomBytes:iB,createHash:uB}=require("crypto"),{URL:h3}=require("url"),v2=oy(),oB=c3(),lB=d3(),{BINARY_TYPES:qC,EMPTY_BUFFER:v3,GUID:sB,kStatusCode:aB,kWebSocket:na,NOOP:WC}=th(),{addEventListener:fB,removeEventListener:cB}=UC(),{format:dB,parse:pB}=p3(),{toBuffer:hB}=ry(),VC=["CONNECTING","OPEN","CLOSING","CLOSED"],m3=[8,13],vB=30*1e3,Gi=class extends eB{constructor(o,a,c){super();this._binaryType=qC[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage="",this._closeTimer=null,this._extensions={},this._protocol="",this._readyState=Gi.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,o!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,Array.isArray(a)?a=a.join(", "):typeof a=="object"&&a!==null&&(c=a,a=void 0),GC(this,o,a,c)):this._isServer=!0}get binaryType(){return this._binaryType}set binaryType(o){!qC.includes(o)||(this._binaryType=o,this._receiver&&(this._receiver._binaryType=o))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(o,a,c){let _=new oB(this.binaryType,this._extensions,this._isServer,c);this._sender=new lB(o,this._extensions),this._receiver=_,this._socket=o,_[na]=this,o[na]=this,_.on("conclude",mB),_.on("drain",gB),_.on("error",yB),_.on("message",_B),_.on("ping",EB),_.on("pong",DB),o.setTimeout(0),o.setNoDelay(),a.length>0&&o.unshift(a),o.on("close",YC),o.on("data",s4),o.on("end",KC),o.on("error",XC),this._readyState=Gi.OPEN,this.emit("open")}emitClose(){if(!this._socket){this._readyState=Gi.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[v2.extensionName]&&this._extensions[v2.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=Gi.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(o,a){if(this.readyState!==Gi.CLOSED){if(this.readyState===Gi.CONNECTING){let c="WebSocket was closed before the connection was established";return Z1(this,this._req,c)}if(this.readyState===Gi.CLOSING){this._closeFrameSent&&this._closeFrameReceived&&this._socket.end();return}this._readyState=Gi.CLOSING,this._sender.close(o,a,!this._isServer,c=>{c||(this._closeFrameSent=!0,this._closeFrameReceived&&this._socket.end())}),this._closeTimer=setTimeout(this._socket.destroy.bind(this._socket),vB)}}ping(o,a,c){if(this.readyState===Gi.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof o=="function"?(c=o,o=a=void 0):typeof a=="function"&&(c=a,a=void 0),typeof o=="number"&&(o=o.toString()),this.readyState!==Gi.OPEN){g3(this,o,c);return}a===void 0&&(a=!this._isServer),this._sender.ping(o||v3,a,c)}pong(o,a,c){if(this.readyState===Gi.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof o=="function"?(c=o,o=a=void 0):typeof a=="function"&&(c=a,a=void 0),typeof o=="number"&&(o=o.toString()),this.readyState!==Gi.OPEN){g3(this,o,c);return}a===void 0&&(a=!this._isServer),this._sender.pong(o||v3,a,c)}send(o,a,c){if(this.readyState===Gi.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof a=="function"&&(c=a,a={}),typeof o=="number"&&(o=o.toString()),this.readyState!==Gi.OPEN){g3(this,o,c);return}let _=Ht({binary:typeof o!="string",mask:!this._isServer,compress:!0,fin:!0},a);this._extensions[v2.extensionName]||(_.compress=!1),this._sender.send(o||v3,_,c)}terminate(){if(this.readyState!==Gi.CLOSED){if(this.readyState===Gi.CONNECTING){let o="WebSocket was closed before the connection was established";return Z1(this,this._req,o)}this._socket&&(this._readyState=Gi.CLOSING,this._socket.destroy())}}};VC.forEach((i,o)=>{let a={enumerable:!0,value:o};Object.defineProperty(Gi.prototype,i,a),Object.defineProperty(Gi,i,a)});["binaryType","bufferedAmount","extensions","protocol","readyState","url"].forEach(i=>{Object.defineProperty(Gi.prototype,i,{enumerable:!0})});["open","error","close","message"].forEach(i=>{Object.defineProperty(Gi.prototype,`on${i}`,{configurable:!0,enumerable:!0,get(){let o=this.listeners(i);for(let a=0;a{Z1(i,q,"Opening handshake has timed out")}),q.on("error",ne=>{q===null||q.aborted||(q=i._req=null,i._readyState=Gi.CLOSING,i.emit("error",ne),i.emitClose())}),q.on("response",ne=>{let m=ne.headers.location,he=ne.statusCode;if(m&&_.followRedirects&&he>=300&&he<400){if(++i._redirects>_.maxRedirects){Z1(i,q,"Maximum redirects exceeded");return}q.abort();let De=new h3(m,o);GC(i,De,a,c)}else i.emit("unexpected-response",q,ne)||Z1(i,q,`Unexpected server response: ${ne.statusCode}`)}),q.on("upgrade",(ne,m,he)=>{if(i.emit("upgrade",ne),i.readyState!==Gi.CONNECTING)return;q=i._req=null;let De=uB("sha1").update(T+sB).digest("base64");if(ne.headers["sec-websocket-accept"]!==De){Z1(i,m,"Invalid Sec-WebSocket-Accept header");return}let se=ne.headers["sec-websocket-protocol"],fe=(a||"").split(/, */),_e;if(!a&&se?_e="Server sent a subprotocol but none was requested":a&&!se?_e="Server sent no subprotocol":se&&!fe.includes(se)&&(_e="Server sent an invalid subprotocol"),_e){Z1(i,m,_e);return}if(se&&(i._protocol=se),H)try{let ce=pB(ne.headers["sec-websocket-extensions"]);ce[v2.extensionName]&&(H.accept(ce[v2.extensionName]),i._extensions[v2.extensionName]=H)}catch(ce){Z1(i,m,"Invalid Sec-WebSocket-Extensions header");return}i.setSocket(m,he,_.maxPayload)})}function wB(i){return i.path=i.socketPath,HC.connect(i)}function SB(i){return i.path=void 0,!i.servername&&i.servername!==""&&(i.servername=HC.isIP(i.host)?"":i.host),rB.connect(i)}function Z1(i,o,a){i._readyState=Gi.CLOSING;let c=new Error(a);Error.captureStackTrace(c,Z1),o.setHeader?(o.abort(),o.socket&&!o.socket.destroyed&&o.socket.destroy(),o.once("abort",i.emitClose.bind(i)),i.emit("error",c)):(o.destroy(c),o.once("error",i.emit.bind(i,"error")),o.once("close",i.emitClose.bind(i)))}function g3(i,o,a){if(o){let c=hB(o).length;i._socket?i._sender._bufferedBytes+=c:i._bufferedAmount+=c}if(a){let c=new Error(`WebSocket is not open: readyState ${i.readyState} (${VC[i.readyState]})`);a(c)}}function mB(i,o){let a=this[na];a._socket.removeListener("data",s4),a._socket.resume(),a._closeFrameReceived=!0,a._closeMessage=o,a._closeCode=i,i===1005?a.close():a.close(i,o)}function gB(){this[na]._socket.resume()}function yB(i){let o=this[na];o._socket.removeListener("data",s4),o._readyState=Gi.CLOSING,o._closeCode=i[aB],o.emit("error",i),o._socket.destroy()}function QC(){this[na].emitClose()}function _B(i){this[na].emit("message",i)}function EB(i){let o=this[na];o.pong(i,!o._isServer,WC),o.emit("ping",i)}function DB(i){this[na].emit("pong",i)}function YC(){let i=this[na];this.removeListener("close",YC),this.removeListener("end",KC),i._readyState=Gi.CLOSING,i._socket.read(),i._receiver.end(),this.removeListener("data",s4),this[na]=void 0,clearTimeout(i._closeTimer),i._receiver._writableState.finished||i._receiver._writableState.errorEmitted?i.emitClose():(i._receiver.on("error",QC),i._receiver.on("finish",QC))}function s4(i){this[na]._receiver.write(i)||this.pause()}function KC(){let i=this[na];i._readyState=Gi.CLOSING,i._receiver.end(),this.end()}function XC(){let i=this[na];this.removeListener("error",XC),this.on("error",WC),i&&(i._readyState=Gi.CLOSING,this.destroy())}});var e6=Ke((wV,JC)=>{"use strict";var{Duplex:TB}=require("stream");function ZC(i){i.emit("close")}function CB(){!this.destroyed&&this._writableState.finished&&this.destroy()}function $C(i){this.removeListener("error",$C),this.destroy(),this.listenerCount("error")===0&&this.emit("error",i)}function xB(i,o){let a=!0;function c(){a&&i._socket.resume()}i.readyState===i.CONNECTING?i.once("open",function(){i._receiver.removeAllListeners("drain"),i._receiver.on("drain",c)}):(i._receiver.removeAllListeners("drain"),i._receiver.on("drain",c));let _=new TB(Zr(Ht({},o),{autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1}));return i.on("message",function(O){_.push(O)||(a=!1,i._socket.pause())}),i.once("error",function(O){_.destroyed||_.destroy(O)}),i.once("close",function(){_.destroyed||_.push(null)}),_._destroy=function(t,O){if(i.readyState===i.CLOSED){O(t),process.nextTick(ZC,_);return}let N=!1;i.once("error",function(T){N=!0,O(T)}),i.once("close",function(){N||O(t),process.nextTick(ZC,_)}),i.terminate()},_._final=function(t){if(i.readyState===i.CONNECTING){i.once("open",function(){_._final(t)});return}i._socket!==null&&(i._socket._writableState.finished?(t(),_._readableState.endEmitted&&_.destroy()):(i._socket.once("finish",function(){t()}),i.close()))},_._read=function(){i.readyState===i.OPEN&&!a&&(a=!0,i._receiver._writableState.needDrain||i._socket.resume())},_._write=function(t,O,N){if(i.readyState===i.CONNECTING){i.once("open",function(){_._write(t,O,N)});return}i.send(t,N)},_.on("end",CB),_.on("error",$C),_}JC.exports=xB});var r6=Ke((SV,t6)=>{"use strict";var AB=require("events"),{createHash:RB}=require("crypto"),{createServer:OB,STATUS_CODES:_3}=require("http"),rh=oy(),MB=y3(),{format:kB,parse:LB}=p3(),{GUID:NB,kWebSocket:FB}=th(),PB=/^[+/0-9A-Za-z]{22}==$/,n6=class extends AB{constructor(o,a){super();if(o=Ht({maxPayload:100*1024*1024,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null},o),o.port==null&&!o.server&&!o.noServer)throw new TypeError('One of the "port", "server", or "noServer" options must be specified');if(o.port!=null?(this._server=OB((c,_)=>{let t=_3[426];_.writeHead(426,{"Content-Length":t.length,"Content-Type":"text/plain"}),_.end(t)}),this._server.listen(o.port,o.host,o.backlog,a)):o.server&&(this._server=o.server),this._server){let c=this.emit.bind(this,"connection");this._removeListeners=IB(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(_,t,O)=>{this.handleUpgrade(_,t,O,c)}})}o.perMessageDeflate===!0&&(o.perMessageDeflate={}),o.clientTracking&&(this.clients=new Set),this.options=o}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(o){if(o&&this.once("close",o),this.clients)for(let c of this.clients)c.terminate();let a=this._server;if(a&&(this._removeListeners(),this._removeListeners=this._server=null,this.options.port!=null)){a.close(()=>this.emit("close"));return}process.nextTick(bB,this)}shouldHandle(o){if(this.options.path){let a=o.url.indexOf("?");if((a!==-1?o.url.slice(0,a):o.url)!==this.options.path)return!1}return!0}handleUpgrade(o,a,c,_){a.on("error",E3);let t=o.headers["sec-websocket-key"]!==void 0?o.headers["sec-websocket-key"].trim():!1,O=+o.headers["sec-websocket-version"],N={};if(o.method!=="GET"||o.headers.upgrade.toLowerCase()!=="websocket"||!t||!PB.test(t)||O!==8&&O!==13||!this.shouldHandle(o))return a4(a,400);if(this.options.perMessageDeflate){let M=new rh(this.options.perMessageDeflate,!0,this.options.maxPayload);try{let T=LB(o.headers["sec-websocket-extensions"]);T[rh.extensionName]&&(M.accept(T[rh.extensionName]),N[rh.extensionName]=M)}catch(T){return a4(a,400)}}if(this.options.verifyClient){let M={origin:o.headers[`${O===8?"sec-websocket-origin":"origin"}`],secure:!!(o.socket.authorized||o.socket.encrypted),req:o};if(this.options.verifyClient.length===2){this.options.verifyClient(M,(T,B,H,q)=>{if(!T)return a4(a,B||401,H,q);this.completeUpgrade(t,N,o,a,c,_)});return}if(!this.options.verifyClient(M))return a4(a,401)}this.completeUpgrade(t,N,o,a,c,_)}completeUpgrade(o,a,c,_,t,O){if(!_.readable||!_.writable)return _.destroy();if(_[FB])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");let N=RB("sha1").update(o+NB).digest("base64"),M=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${N}`],T=new MB(null),B=c.headers["sec-websocket-protocol"];if(B&&(B=B.split(",").map(BB),this.options.handleProtocols?B=this.options.handleProtocols(B,c):B=B[0],B&&(M.push(`Sec-WebSocket-Protocol: ${B}`),T._protocol=B)),a[rh.extensionName]){let H=a[rh.extensionName].params,q=kB({[rh.extensionName]:[H]});M.push(`Sec-WebSocket-Extensions: ${q}`),T._extensions=a}this.emit("headers",M,c),_.write(M.concat(`\r +`).join(`\r +`)),_.removeListener("error",E3),T.setSocket(_,t,this.options.maxPayload),this.clients&&(this.clients.add(T),T.on("close",()=>this.clients.delete(T))),O(T,c)}};t6.exports=n6;function IB(i,o){for(let a of Object.keys(o))i.on(a,o[a]);return function(){for(let c of Object.keys(o))i.removeListener(c,o[c])}}function bB(i){i.emit("close")}function E3(){this.destroy()}function a4(i,o,a,c){i.writable&&(a=a||_3[o],c=Ht({Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(a)},c),i.write(`HTTP/1.1 ${o} ${_3[o]}\r +`+Object.keys(c).map(_=>`${_}: ${c[_]}`).join(`\r +`)+`\r +\r +`+a)),i.removeListener("error",E3),i.destroy()}function BB(i){return i.trim()}});var u6=Ke((TV,i6)=>{"use strict";var fy=y3();fy.createWebSocketStream=e6();fy.Server=r6();fy.Receiver=c3();fy.Sender=d3();i6.exports=fy});var o6=Ke(f4=>{"use strict";var UB=f4&&f4.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(f4,"__esModule",{value:!0});var jB=UB(u6()),cy=global;cy.WebSocket||(cy.WebSocket=jB.default);cy.window||(cy.window=global);cy.window.__REACT_DEVTOOLS_COMPONENT_FILTERS__=[{type:1,value:7,isEnabled:!0},{type:2,value:"InternalApp",isEnabled:!0,isValid:!0},{type:2,value:"InternalAppContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStdoutContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStderrContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStdinContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalFocusContext",isEnabled:!0,isValid:!0}]});var l6=Ke((c4,D3)=>{(function(i,o){typeof c4=="object"&&typeof D3=="object"?D3.exports=o():typeof define=="function"&&define.amd?define([],o):typeof c4=="object"?c4.ReactDevToolsBackend=o():i.ReactDevToolsBackend=o()})(window,function(){return function(i){var o={};function a(c){if(o[c])return o[c].exports;var _=o[c]={i:c,l:!1,exports:{}};return i[c].call(_.exports,_,_.exports,a),_.l=!0,_.exports}return a.m=i,a.c=o,a.d=function(c,_,t){a.o(c,_)||Object.defineProperty(c,_,{enumerable:!0,get:t})},a.r=function(c){typeof Symbol!="undefined"&&Symbol.toStringTag&&Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(c,"__esModule",{value:!0})},a.t=function(c,_){if(1&_&&(c=a(c)),8&_||4&_&&typeof c=="object"&&c&&c.__esModule)return c;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:c}),2&_&&typeof c!="string")for(var O in c)a.d(t,O,function(N){return c[N]}.bind(null,O));return t},a.n=function(c){var _=c&&c.__esModule?function(){return c.default}:function(){return c};return a.d(_,"a",_),_},a.o=function(c,_){return Object.prototype.hasOwnProperty.call(c,_)},a.p="",a(a.s=20)}([function(i,o,a){"use strict";i.exports=a(12)},function(i,o,a){"use strict";var c=Object.getOwnPropertySymbols,_=Object.prototype.hasOwnProperty,t=Object.prototype.propertyIsEnumerable;function O(N){if(N==null)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(N)}i.exports=function(){try{if(!Object.assign)return!1;var N=new String("abc");if(N[5]="de",Object.getOwnPropertyNames(N)[0]==="5")return!1;for(var M={},T=0;T<10;T++)M["_"+String.fromCharCode(T)]=T;if(Object.getOwnPropertyNames(M).map(function(H){return M[H]}).join("")!=="0123456789")return!1;var B={};return"abcdefghijklmnopqrst".split("").forEach(function(H){B[H]=H}),Object.keys(Object.assign({},B)).join("")==="abcdefghijklmnopqrst"}catch(H){return!1}}()?Object.assign:function(N,M){for(var T,B,H=O(N),q=1;q=ie||nn<0||Xt&&At-Ve>=at}function oe(){var At=De();if(Ce(At))return He(At);Qe=setTimeout(oe,function(nn){var an=ie-(nn-ut);return Xt?he(an,at-(nn-Ve)):an}(At))}function He(At){return Qe=void 0,rt&&Ue?X(At):(Ue=je=void 0,Dt)}function dt(){var At=De(),nn=Ce(At);if(Ue=arguments,je=this,ut=At,nn){if(Qe===void 0)return de(ut);if(Xt)return Qe=setTimeout(oe,ie),X(ut)}return Qe===void 0&&(Qe=setTimeout(oe,ie)),Dt}return ie=ce(ie)||0,fe(Oe)&&(It=!!Oe.leading,at=(Xt="maxWait"in Oe)?m(ce(Oe.maxWait)||0,ie):at,rt="trailing"in Oe?!!Oe.trailing:rt),dt.cancel=function(){Qe!==void 0&&clearTimeout(Qe),Ve=0,Ue=ut=je=Qe=void 0},dt.flush=function(){return Qe===void 0?Dt:He(De())},dt}function fe(me){var ie=_(me);return!!me&&(ie=="object"||ie=="function")}function _e(me){return _(me)=="symbol"||function(ie){return!!ie&&_(ie)=="object"}(me)&&ne.call(me)=="[object Symbol]"}function ce(me){if(typeof me=="number")return me;if(_e(me))return NaN;if(fe(me)){var ie=typeof me.valueOf=="function"?me.valueOf():me;me=fe(ie)?ie+"":ie}if(typeof me!="string")return me===0?me:+me;me=me.replace(t,"");var Oe=N.test(me);return Oe||M.test(me)?T(me.slice(2),Oe?2:8):O.test(me)?NaN:+me}i.exports=function(me,ie,Oe){var Ue=!0,je=!0;if(typeof me!="function")throw new TypeError("Expected a function");return fe(Oe)&&(Ue="leading"in Oe?!!Oe.leading:Ue,je="trailing"in Oe?!!Oe.trailing:je),se(me,ie,{leading:Ue,maxWait:ie,trailing:je})}}).call(this,a(4))},function(i,o,a){(function(c){function _(X){return(_=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(de){return typeof de}:function(de){return de&&typeof Symbol=="function"&&de.constructor===Symbol&&de!==Symbol.prototype?"symbol":typeof de})(X)}var t;o=i.exports=m,t=(c===void 0?"undefined":_(c))==="object"&&c.env&&c.env.NODE_DEBUG&&/\bsemver\b/i.test(c.env.NODE_DEBUG)?function(){var X=Array.prototype.slice.call(arguments,0);X.unshift("SEMVER"),console.log.apply(console,X)}:function(){},o.SEMVER_SPEC_VERSION="2.0.0";var O=Number.MAX_SAFE_INTEGER||9007199254740991,N=o.re=[],M=o.src=[],T=o.tokens={},B=0;function H(X){T[X]=B++}H("NUMERICIDENTIFIER"),M[T.NUMERICIDENTIFIER]="0|[1-9]\\d*",H("NUMERICIDENTIFIERLOOSE"),M[T.NUMERICIDENTIFIERLOOSE]="[0-9]+",H("NONNUMERICIDENTIFIER"),M[T.NONNUMERICIDENTIFIER]="\\d*[a-zA-Z-][a-zA-Z0-9-]*",H("MAINVERSION"),M[T.MAINVERSION]="("+M[T.NUMERICIDENTIFIER]+")\\.("+M[T.NUMERICIDENTIFIER]+")\\.("+M[T.NUMERICIDENTIFIER]+")",H("MAINVERSIONLOOSE"),M[T.MAINVERSIONLOOSE]="("+M[T.NUMERICIDENTIFIERLOOSE]+")\\.("+M[T.NUMERICIDENTIFIERLOOSE]+")\\.("+M[T.NUMERICIDENTIFIERLOOSE]+")",H("PRERELEASEIDENTIFIER"),M[T.PRERELEASEIDENTIFIER]="(?:"+M[T.NUMERICIDENTIFIER]+"|"+M[T.NONNUMERICIDENTIFIER]+")",H("PRERELEASEIDENTIFIERLOOSE"),M[T.PRERELEASEIDENTIFIERLOOSE]="(?:"+M[T.NUMERICIDENTIFIERLOOSE]+"|"+M[T.NONNUMERICIDENTIFIER]+")",H("PRERELEASE"),M[T.PRERELEASE]="(?:-("+M[T.PRERELEASEIDENTIFIER]+"(?:\\."+M[T.PRERELEASEIDENTIFIER]+")*))",H("PRERELEASELOOSE"),M[T.PRERELEASELOOSE]="(?:-?("+M[T.PRERELEASEIDENTIFIERLOOSE]+"(?:\\."+M[T.PRERELEASEIDENTIFIERLOOSE]+")*))",H("BUILDIDENTIFIER"),M[T.BUILDIDENTIFIER]="[0-9A-Za-z-]+",H("BUILD"),M[T.BUILD]="(?:\\+("+M[T.BUILDIDENTIFIER]+"(?:\\."+M[T.BUILDIDENTIFIER]+")*))",H("FULL"),H("FULLPLAIN"),M[T.FULLPLAIN]="v?"+M[T.MAINVERSION]+M[T.PRERELEASE]+"?"+M[T.BUILD]+"?",M[T.FULL]="^"+M[T.FULLPLAIN]+"$",H("LOOSEPLAIN"),M[T.LOOSEPLAIN]="[v=\\s]*"+M[T.MAINVERSIONLOOSE]+M[T.PRERELEASELOOSE]+"?"+M[T.BUILD]+"?",H("LOOSE"),M[T.LOOSE]="^"+M[T.LOOSEPLAIN]+"$",H("GTLT"),M[T.GTLT]="((?:<|>)?=?)",H("XRANGEIDENTIFIERLOOSE"),M[T.XRANGEIDENTIFIERLOOSE]=M[T.NUMERICIDENTIFIERLOOSE]+"|x|X|\\*",H("XRANGEIDENTIFIER"),M[T.XRANGEIDENTIFIER]=M[T.NUMERICIDENTIFIER]+"|x|X|\\*",H("XRANGEPLAIN"),M[T.XRANGEPLAIN]="[v=\\s]*("+M[T.XRANGEIDENTIFIER]+")(?:\\.("+M[T.XRANGEIDENTIFIER]+")(?:\\.("+M[T.XRANGEIDENTIFIER]+")(?:"+M[T.PRERELEASE]+")?"+M[T.BUILD]+"?)?)?",H("XRANGEPLAINLOOSE"),M[T.XRANGEPLAINLOOSE]="[v=\\s]*("+M[T.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+M[T.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+M[T.XRANGEIDENTIFIERLOOSE]+")(?:"+M[T.PRERELEASELOOSE]+")?"+M[T.BUILD]+"?)?)?",H("XRANGE"),M[T.XRANGE]="^"+M[T.GTLT]+"\\s*"+M[T.XRANGEPLAIN]+"$",H("XRANGELOOSE"),M[T.XRANGELOOSE]="^"+M[T.GTLT]+"\\s*"+M[T.XRANGEPLAINLOOSE]+"$",H("COERCE"),M[T.COERCE]="(^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])",H("COERCERTL"),N[T.COERCERTL]=new RegExp(M[T.COERCE],"g"),H("LONETILDE"),M[T.LONETILDE]="(?:~>?)",H("TILDETRIM"),M[T.TILDETRIM]="(\\s*)"+M[T.LONETILDE]+"\\s+",N[T.TILDETRIM]=new RegExp(M[T.TILDETRIM],"g"),H("TILDE"),M[T.TILDE]="^"+M[T.LONETILDE]+M[T.XRANGEPLAIN]+"$",H("TILDELOOSE"),M[T.TILDELOOSE]="^"+M[T.LONETILDE]+M[T.XRANGEPLAINLOOSE]+"$",H("LONECARET"),M[T.LONECARET]="(?:\\^)",H("CARETTRIM"),M[T.CARETTRIM]="(\\s*)"+M[T.LONECARET]+"\\s+",N[T.CARETTRIM]=new RegExp(M[T.CARETTRIM],"g"),H("CARET"),M[T.CARET]="^"+M[T.LONECARET]+M[T.XRANGEPLAIN]+"$",H("CARETLOOSE"),M[T.CARETLOOSE]="^"+M[T.LONECARET]+M[T.XRANGEPLAINLOOSE]+"$",H("COMPARATORLOOSE"),M[T.COMPARATORLOOSE]="^"+M[T.GTLT]+"\\s*("+M[T.LOOSEPLAIN]+")$|^$",H("COMPARATOR"),M[T.COMPARATOR]="^"+M[T.GTLT]+"\\s*("+M[T.FULLPLAIN]+")$|^$",H("COMPARATORTRIM"),M[T.COMPARATORTRIM]="(\\s*)"+M[T.GTLT]+"\\s*("+M[T.LOOSEPLAIN]+"|"+M[T.XRANGEPLAIN]+")",N[T.COMPARATORTRIM]=new RegExp(M[T.COMPARATORTRIM],"g"),H("HYPHENRANGE"),M[T.HYPHENRANGE]="^\\s*("+M[T.XRANGEPLAIN]+")\\s+-\\s+("+M[T.XRANGEPLAIN]+")\\s*$",H("HYPHENRANGELOOSE"),M[T.HYPHENRANGELOOSE]="^\\s*("+M[T.XRANGEPLAINLOOSE]+")\\s+-\\s+("+M[T.XRANGEPLAINLOOSE]+")\\s*$",H("STAR"),M[T.STAR]="(<|>)?=?\\s*\\*";for(var q=0;q256||!(de.loose?N[T.LOOSE]:N[T.FULL]).test(X))return null;try{return new m(X,de)}catch(Ce){return null}}function m(X,de){if(de&&_(de)==="object"||(de={loose:!!de,includePrerelease:!1}),X instanceof m){if(X.loose===de.loose)return X;X=X.version}else if(typeof X!="string")throw new TypeError("Invalid Version: "+X);if(X.length>256)throw new TypeError("version is longer than 256 characters");if(!(this instanceof m))return new m(X,de);t("SemVer",X,de),this.options=de,this.loose=!!de.loose;var Ce=X.trim().match(de.loose?N[T.LOOSE]:N[T.FULL]);if(!Ce)throw new TypeError("Invalid Version: "+X);if(this.raw=X,this.major=+Ce[1],this.minor=+Ce[2],this.patch=+Ce[3],this.major>O||this.major<0)throw new TypeError("Invalid major version");if(this.minor>O||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>O||this.patch<0)throw new TypeError("Invalid patch version");Ce[4]?this.prerelease=Ce[4].split(".").map(function(oe){if(/^[0-9]+$/.test(oe)){var He=+oe;if(He>=0&&He=0;)typeof this.prerelease[Ce]=="number"&&(this.prerelease[Ce]++,Ce=-2);Ce===-1&&this.prerelease.push(0)}de&&(this.prerelease[0]===de?isNaN(this.prerelease[1])&&(this.prerelease=[de,0]):this.prerelease=[de,0]);break;default:throw new Error("invalid increment argument: "+X)}return this.format(),this.raw=this.version,this},o.inc=function(X,de,Ce,oe){typeof Ce=="string"&&(oe=Ce,Ce=void 0);try{return new m(X,Ce).inc(de,oe).version}catch(He){return null}},o.diff=function(X,de){if(ce(X,de))return null;var Ce=ne(X),oe=ne(de),He="";if(Ce.prerelease.length||oe.prerelease.length){He="pre";var dt="prerelease"}for(var At in Ce)if((At==="major"||At==="minor"||At==="patch")&&Ce[At]!==oe[At])return He+At;return dt},o.compareIdentifiers=De;var he=/^[0-9]+$/;function De(X,de){var Ce=he.test(X),oe=he.test(de);return Ce&&oe&&(X=+X,de=+de),X===de?0:Ce&&!oe?-1:oe&&!Ce?1:X0}function _e(X,de,Ce){return se(X,de,Ce)<0}function ce(X,de,Ce){return se(X,de,Ce)===0}function me(X,de,Ce){return se(X,de,Ce)!==0}function ie(X,de,Ce){return se(X,de,Ce)>=0}function Oe(X,de,Ce){return se(X,de,Ce)<=0}function Ue(X,de,Ce,oe){switch(de){case"===":return _(X)==="object"&&(X=X.version),_(Ce)==="object"&&(Ce=Ce.version),X===Ce;case"!==":return _(X)==="object"&&(X=X.version),_(Ce)==="object"&&(Ce=Ce.version),X!==Ce;case"":case"=":case"==":return ce(X,Ce,oe);case"!=":return me(X,Ce,oe);case">":return fe(X,Ce,oe);case">=":return ie(X,Ce,oe);case"<":return _e(X,Ce,oe);case"<=":return Oe(X,Ce,oe);default:throw new TypeError("Invalid operator: "+de)}}function je(X,de){if(de&&_(de)==="object"||(de={loose:!!de,includePrerelease:!1}),X instanceof je){if(X.loose===!!de.loose)return X;X=X.value}if(!(this instanceof je))return new je(X,de);t("comparator",X,de),this.options=de,this.loose=!!de.loose,this.parse(X),this.semver===at?this.value="":this.value=this.operator+this.semver.version,t("comp",this)}o.rcompareIdentifiers=function(X,de){return De(de,X)},o.major=function(X,de){return new m(X,de).major},o.minor=function(X,de){return new m(X,de).minor},o.patch=function(X,de){return new m(X,de).patch},o.compare=se,o.compareLoose=function(X,de){return se(X,de,!0)},o.compareBuild=function(X,de,Ce){var oe=new m(X,Ce),He=new m(de,Ce);return oe.compare(He)||oe.compareBuild(He)},o.rcompare=function(X,de,Ce){return se(de,X,Ce)},o.sort=function(X,de){return X.sort(function(Ce,oe){return o.compareBuild(Ce,oe,de)})},o.rsort=function(X,de){return X.sort(function(Ce,oe){return o.compareBuild(oe,Ce,de)})},o.gt=fe,o.lt=_e,o.eq=ce,o.neq=me,o.gte=ie,o.lte=Oe,o.cmp=Ue,o.Comparator=je;var at={};function Dt(X,de){if(de&&_(de)==="object"||(de={loose:!!de,includePrerelease:!1}),X instanceof Dt)return X.loose===!!de.loose&&X.includePrerelease===!!de.includePrerelease?X:new Dt(X.raw,de);if(X instanceof je)return new Dt(X.value,de);if(!(this instanceof Dt))return new Dt(X,de);if(this.options=de,this.loose=!!de.loose,this.includePrerelease=!!de.includePrerelease,this.raw=X,this.set=X.split(/\s*\|\|\s*/).map(function(Ce){return this.parseRange(Ce.trim())},this).filter(function(Ce){return Ce.length}),!this.set.length)throw new TypeError("Invalid SemVer Range: "+X);this.format()}function Qe(X,de){for(var Ce=!0,oe=X.slice(),He=oe.pop();Ce&&oe.length;)Ce=oe.every(function(dt){return He.intersects(dt,de)}),He=oe.pop();return Ce}function ut(X){return!X||X.toLowerCase()==="x"||X==="*"}function Ve(X,de,Ce,oe,He,dt,At,nn,an,Mn,lr,ln,Vt){return((de=ut(Ce)?"":ut(oe)?">="+Ce+".0.0":ut(He)?">="+Ce+"."+oe+".0":">="+de)+" "+(nn=ut(an)?"":ut(Mn)?"<"+(+an+1)+".0.0":ut(lr)?"<"+an+"."+(+Mn+1)+".0":ln?"<="+an+"."+Mn+"."+lr+"-"+ln:"<="+nn)).trim()}function It(X,de,Ce){for(var oe=0;oe0){var He=X[oe].semver;if(He.major===de.major&&He.minor===de.minor&&He.patch===de.patch)return!0}return!1}return!0}function Xt(X,de,Ce){try{de=new Dt(de,Ce)}catch(oe){return!1}return de.test(X)}function rt(X,de,Ce,oe){var He,dt,At,nn,an;switch(X=new m(X,oe),de=new Dt(de,oe),Ce){case">":He=fe,dt=Oe,At=_e,nn=">",an=">=";break;case"<":He=_e,dt=ie,At=fe,nn="<",an="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(Xt(X,de,oe))return!1;for(var Mn=0;Mn=0.0.0")),ln=ln||Dr,Vt=Vt||Dr,He(Dr.semver,ln.semver,oe)?ln=Dr:At(Dr.semver,Vt.semver,oe)&&(Vt=Dr)}),ln.operator===nn||ln.operator===an||(!Vt.operator||Vt.operator===nn)&&dt(X,Vt.semver)||Vt.operator===an&&At(X,Vt.semver))return!1}return!0}je.prototype.parse=function(X){var de=this.options.loose?N[T.COMPARATORLOOSE]:N[T.COMPARATOR],Ce=X.match(de);if(!Ce)throw new TypeError("Invalid comparator: "+X);this.operator=Ce[1]!==void 0?Ce[1]:"",this.operator==="="&&(this.operator=""),Ce[2]?this.semver=new m(Ce[2],this.options.loose):this.semver=at},je.prototype.toString=function(){return this.value},je.prototype.test=function(X){if(t("Comparator.test",X,this.options.loose),this.semver===at||X===at)return!0;if(typeof X=="string")try{X=new m(X,this.options)}catch(de){return!1}return Ue(X,this.operator,this.semver,this.options)},je.prototype.intersects=function(X,de){if(!(X instanceof je))throw new TypeError("a Comparator is required");var Ce;if(de&&_(de)==="object"||(de={loose:!!de,includePrerelease:!1}),this.operator==="")return this.value===""||(Ce=new Dt(X.value,de),Xt(this.value,Ce,de));if(X.operator==="")return X.value===""||(Ce=new Dt(this.value,de),Xt(X.semver,Ce,de));var oe=!(this.operator!==">="&&this.operator!==">"||X.operator!==">="&&X.operator!==">"),He=!(this.operator!=="<="&&this.operator!=="<"||X.operator!=="<="&&X.operator!=="<"),dt=this.semver.version===X.semver.version,At=!(this.operator!==">="&&this.operator!=="<="||X.operator!==">="&&X.operator!=="<="),nn=Ue(this.semver,"<",X.semver,de)&&(this.operator===">="||this.operator===">")&&(X.operator==="<="||X.operator==="<"),an=Ue(this.semver,">",X.semver,de)&&(this.operator==="<="||this.operator==="<")&&(X.operator===">="||X.operator===">");return oe||He||dt&&At||nn||an},o.Range=Dt,Dt.prototype.format=function(){return this.range=this.set.map(function(X){return X.join(" ").trim()}).join("||").trim(),this.range},Dt.prototype.toString=function(){return this.range},Dt.prototype.parseRange=function(X){var de=this.options.loose;X=X.trim();var Ce=de?N[T.HYPHENRANGELOOSE]:N[T.HYPHENRANGE];X=X.replace(Ce,Ve),t("hyphen replace",X),X=X.replace(N[T.COMPARATORTRIM],"$1$2$3"),t("comparator trim",X,N[T.COMPARATORTRIM]),X=(X=(X=X.replace(N[T.TILDETRIM],"$1~")).replace(N[T.CARETTRIM],"$1^")).split(/\s+/).join(" ");var oe=de?N[T.COMPARATORLOOSE]:N[T.COMPARATOR],He=X.split(" ").map(function(dt){return function(At,nn){return t("comp",At,nn),At=function(an,Mn){return an.trim().split(/\s+/).map(function(lr){return function(ln,Vt){t("caret",ln,Vt);var Dr=Vt.loose?N[T.CARETLOOSE]:N[T.CARET];return ln.replace(Dr,function(w,jt,Xn,vr,jr){var fr;return t("caret",ln,w,jt,Xn,vr,jr),ut(jt)?fr="":ut(Xn)?fr=">="+jt+".0.0 <"+(+jt+1)+".0.0":ut(vr)?fr=jt==="0"?">="+jt+"."+Xn+".0 <"+jt+"."+(+Xn+1)+".0":">="+jt+"."+Xn+".0 <"+(+jt+1)+".0.0":jr?(t("replaceCaret pr",jr),fr=jt==="0"?Xn==="0"?">="+jt+"."+Xn+"."+vr+"-"+jr+" <"+jt+"."+Xn+"."+(+vr+1):">="+jt+"."+Xn+"."+vr+"-"+jr+" <"+jt+"."+(+Xn+1)+".0":">="+jt+"."+Xn+"."+vr+"-"+jr+" <"+(+jt+1)+".0.0"):(t("no pr"),fr=jt==="0"?Xn==="0"?">="+jt+"."+Xn+"."+vr+" <"+jt+"."+Xn+"."+(+vr+1):">="+jt+"."+Xn+"."+vr+" <"+jt+"."+(+Xn+1)+".0":">="+jt+"."+Xn+"."+vr+" <"+(+jt+1)+".0.0"),t("caret return",fr),fr})}(lr,Mn)}).join(" ")}(At,nn),t("caret",At),At=function(an,Mn){return an.trim().split(/\s+/).map(function(lr){return function(ln,Vt){var Dr=Vt.loose?N[T.TILDELOOSE]:N[T.TILDE];return ln.replace(Dr,function(w,jt,Xn,vr,jr){var fr;return t("tilde",ln,w,jt,Xn,vr,jr),ut(jt)?fr="":ut(Xn)?fr=">="+jt+".0.0 <"+(+jt+1)+".0.0":ut(vr)?fr=">="+jt+"."+Xn+".0 <"+jt+"."+(+Xn+1)+".0":jr?(t("replaceTilde pr",jr),fr=">="+jt+"."+Xn+"."+vr+"-"+jr+" <"+jt+"."+(+Xn+1)+".0"):fr=">="+jt+"."+Xn+"."+vr+" <"+jt+"."+(+Xn+1)+".0",t("tilde return",fr),fr})}(lr,Mn)}).join(" ")}(At,nn),t("tildes",At),At=function(an,Mn){return t("replaceXRanges",an,Mn),an.split(/\s+/).map(function(lr){return function(ln,Vt){ln=ln.trim();var Dr=Vt.loose?N[T.XRANGELOOSE]:N[T.XRANGE];return ln.replace(Dr,function(w,jt,Xn,vr,jr,fr){t("xRange",ln,w,jt,Xn,vr,jr,fr);var zr=ut(Xn),Qt=zr||ut(vr),wu=Qt||ut(jr),d0=wu;return jt==="="&&d0&&(jt=""),fr=Vt.includePrerelease?"-0":"",zr?w=jt===">"||jt==="<"?"<0.0.0-0":"*":jt&&d0?(Qt&&(vr=0),jr=0,jt===">"?(jt=">=",Qt?(Xn=+Xn+1,vr=0,jr=0):(vr=+vr+1,jr=0)):jt==="<="&&(jt="<",Qt?Xn=+Xn+1:vr=+vr+1),w=jt+Xn+"."+vr+"."+jr+fr):Qt?w=">="+Xn+".0.0"+fr+" <"+(+Xn+1)+".0.0"+fr:wu&&(w=">="+Xn+"."+vr+".0"+fr+" <"+Xn+"."+(+vr+1)+".0"+fr),t("xRange return",w),w})}(lr,Mn)}).join(" ")}(At,nn),t("xrange",At),At=function(an,Mn){return t("replaceStars",an,Mn),an.trim().replace(N[T.STAR],"")}(At,nn),t("stars",At),At}(dt,this.options)},this).join(" ").split(/\s+/);return this.options.loose&&(He=He.filter(function(dt){return!!dt.match(oe)})),He=He.map(function(dt){return new je(dt,this.options)},this)},Dt.prototype.intersects=function(X,de){if(!(X instanceof Dt))throw new TypeError("a Range is required");return this.set.some(function(Ce){return Qe(Ce,de)&&X.set.some(function(oe){return Qe(oe,de)&&Ce.every(function(He){return oe.every(function(dt){return He.intersects(dt,de)})})})})},o.toComparators=function(X,de){return new Dt(X,de).set.map(function(Ce){return Ce.map(function(oe){return oe.value}).join(" ").trim().split(" ")})},Dt.prototype.test=function(X){if(!X)return!1;if(typeof X=="string")try{X=new m(X,this.options)}catch(Ce){return!1}for(var de=0;de":dt.prerelease.length===0?dt.patch++:dt.prerelease.push(0),dt.raw=dt.format();case"":case">=":Ce&&!fe(Ce,dt)||(Ce=dt);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+He.operator)}});return Ce&&X.test(Ce)?Ce:null},o.validRange=function(X,de){try{return new Dt(X,de).range||"*"}catch(Ce){return null}},o.ltr=function(X,de,Ce){return rt(X,de,"<",Ce)},o.gtr=function(X,de,Ce){return rt(X,de,">",Ce)},o.outside=rt,o.prerelease=function(X,de){var Ce=ne(X,de);return Ce&&Ce.prerelease.length?Ce.prerelease:null},o.intersects=function(X,de,Ce){return X=new Dt(X,Ce),de=new Dt(de,Ce),X.intersects(de)},o.coerce=function(X,de){if(X instanceof m)return X;if(typeof X=="number"&&(X=String(X)),typeof X!="string")return null;var Ce=null;if((de=de||{}).rtl){for(var oe;(oe=N[T.COERCERTL].exec(X))&&(!Ce||Ce.index+Ce[0].length!==X.length);)Ce&&oe.index+oe[0].length===Ce.index+Ce[0].length||(Ce=oe),N[T.COERCERTL].lastIndex=oe.index+oe[1].length+oe[2].length;N[T.COERCERTL].lastIndex=-1}else Ce=X.match(N[T.COERCE]);return Ce===null?null:ne(Ce[2]+"."+(Ce[3]||"0")+"."+(Ce[4]||"0"),de)}}).call(this,a(5))},function(i,o){function a(_){return(a=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(_)}var c;c=function(){return this}();try{c=c||new Function("return this")()}catch(_){(typeof window=="undefined"?"undefined":a(window))==="object"&&(c=window)}i.exports=c},function(i,o){var a,c,_=i.exports={};function t(){throw new Error("setTimeout has not been defined")}function O(){throw new Error("clearTimeout has not been defined")}function N(De){if(a===setTimeout)return setTimeout(De,0);if((a===t||!a)&&setTimeout)return a=setTimeout,setTimeout(De,0);try{return a(De,0)}catch(se){try{return a.call(null,De,0)}catch(fe){return a.call(this,De,0)}}}(function(){try{a=typeof setTimeout=="function"?setTimeout:t}catch(De){a=t}try{c=typeof clearTimeout=="function"?clearTimeout:O}catch(De){c=O}})();var M,T=[],B=!1,H=-1;function q(){B&&M&&(B=!1,M.length?T=M.concat(T):H=-1,T.length&&ne())}function ne(){if(!B){var De=N(q);B=!0;for(var se=T.length;se;){for(M=T,T=[];++H1)for(var fe=1;fethis[O])return me(this,this[m].get(Qe)),!1;var rt=this[m].get(Qe).value;return this[H]&&(this[q]||this[H](Qe,rt.value)),rt.now=It,rt.maxAge=Ve,rt.value=ut,this[N]+=Xt-rt.length,rt.length=Xt,this.get(Qe),ce(this),!0}var X=new ie(Qe,ut,Xt,It,Ve);return X.length>this[O]?(this[H]&&this[H](Qe,ut),!1):(this[N]+=X.length,this[ne].unshift(X),this[m].set(Qe,this[ne].head),ce(this),!0)}},{key:"has",value:function(Qe){if(!this[m].has(Qe))return!1;var ut=this[m].get(Qe).value;return!_e(this,ut)}},{key:"get",value:function(Qe){return fe(this,Qe,!0)}},{key:"peek",value:function(Qe){return fe(this,Qe,!1)}},{key:"pop",value:function(){var Qe=this[ne].tail;return Qe?(me(this,Qe),Qe.value):null}},{key:"del",value:function(Qe){me(this,this[m].get(Qe))}},{key:"load",value:function(Qe){this.reset();for(var ut=Date.now(),Ve=Qe.length-1;Ve>=0;Ve--){var It=Qe[Ve],Xt=It.e||0;if(Xt===0)this.set(It.k,It.v);else{var rt=Xt-ut;rt>0&&this.set(It.k,It.v,rt)}}}},{key:"prune",value:function(){var Qe=this;this[m].forEach(function(ut,Ve){return fe(Qe,Ve,!1)})}},{key:"max",set:function(Qe){if(typeof Qe!="number"||Qe<0)throw new TypeError("max must be a non-negative number");this[O]=Qe||1/0,ce(this)},get:function(){return this[O]}},{key:"allowStale",set:function(Qe){this[T]=!!Qe},get:function(){return this[T]}},{key:"maxAge",set:function(Qe){if(typeof Qe!="number")throw new TypeError("maxAge must be a non-negative number");this[B]=Qe,ce(this)},get:function(){return this[B]}},{key:"lengthCalculator",set:function(Qe){var ut=this;typeof Qe!="function"&&(Qe=De),Qe!==this[M]&&(this[M]=Qe,this[N]=0,this[ne].forEach(function(Ve){Ve.length=ut[M](Ve.value,Ve.key),ut[N]+=Ve.length})),ce(this)},get:function(){return this[M]}},{key:"length",get:function(){return this[N]}},{key:"itemCount",get:function(){return this[ne].length}}])&&_(je.prototype,at),Dt&&_(je,Dt),Ue}(),fe=function(Ue,je,at){var Dt=Ue[m].get(je);if(Dt){var Qe=Dt.value;if(_e(Ue,Qe)){if(me(Ue,Dt),!Ue[T])return}else at&&(Ue[he]&&(Dt.value.now=Date.now()),Ue[ne].unshiftNode(Dt));return Qe.value}},_e=function(Ue,je){if(!je||!je.maxAge&&!Ue[B])return!1;var at=Date.now()-je.now;return je.maxAge?at>je.maxAge:Ue[B]&&at>Ue[B]},ce=function(Ue){if(Ue[N]>Ue[O])for(var je=Ue[ne].tail;Ue[N]>Ue[O]&&je!==null;){var at=je.prev;me(Ue,je),je=at}},me=function(Ue,je){if(je){var at=je.value;Ue[H]&&Ue[H](at.key,at.value),Ue[N]-=at.length,Ue[m].delete(at.key),Ue[ne].removeNode(je)}},ie=function Ue(je,at,Dt,Qe,ut){c(this,Ue),this.key=je,this.value=at,this.length=Dt,this.now=Qe,this.maxAge=ut||0},Oe=function(Ue,je,at,Dt){var Qe=at.value;_e(Ue,Qe)&&(me(Ue,at),Ue[T]||(Qe=void 0)),Qe&&je.call(Dt,Qe.value,Qe.key,Ue)};i.exports=se},function(i,o,a){(function(c){function _(t){return(_=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(O){return typeof O}:function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O})(t)}i.exports=function(){if(typeof document=="undefined"||!document.addEventListener)return null;var t,O,N,M={};return M.copy=function(){var T=!1,B=null,H=!1;function q(){T=!1,B=null,H&&window.getSelection().removeAllRanges(),H=!1}return document.addEventListener("copy",function(ne){if(T){for(var m in B)ne.clipboardData.setData(m,B[m]);ne.preventDefault()}}),function(ne){return new Promise(function(m,he){T=!0,typeof ne=="string"?B={"text/plain":ne}:ne instanceof Node?B={"text/html":new XMLSerializer().serializeToString(ne)}:ne instanceof Object?B=ne:he("Invalid data type. Must be string, DOM node, or an object mapping MIME types to strings."),function De(se){try{if(document.execCommand("copy"))q(),m();else{if(se)throw q(),new Error("Unable to copy. Perhaps it's not available in your browser?");(function(){var fe=document.getSelection();if(!document.queryCommandEnabled("copy")&&fe.isCollapsed){var _e=document.createRange();_e.selectNodeContents(document.body),fe.removeAllRanges(),fe.addRange(_e),H=!0}})(),De(!0)}}catch(fe){q(),he(fe)}}(!1)})}}(),M.paste=(N=!1,document.addEventListener("paste",function(T){if(N){N=!1,T.preventDefault();var B=t;t=null,B(T.clipboardData.getData(O))}}),function(T){return new Promise(function(B,H){N=!0,t=B,O=T||"text/plain";try{document.execCommand("paste")||(N=!1,H(new Error("Unable to paste. Pasting only works in Internet Explorer at the moment.")))}catch(q){N=!1,H(new Error(q))}})}),typeof ClipboardEvent=="undefined"&&window.clipboardData!==void 0&&window.clipboardData.setData!==void 0&&(function(T){function B(ce,me){return function(){ce.apply(me,arguments)}}function H(ce){if(_(this)!="object")throw new TypeError("Promises must be constructed via new");if(typeof ce!="function")throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],se(ce,B(ne,this),B(m,this))}function q(ce){var me=this;return this._state===null?void this._deferreds.push(ce):void fe(function(){var ie=me._state?ce.onFulfilled:ce.onRejected;if(ie!==null){var Oe;try{Oe=ie(me._value)}catch(Ue){return void ce.reject(Ue)}ce.resolve(Oe)}else(me._state?ce.resolve:ce.reject)(me._value)})}function ne(ce){try{if(ce===this)throw new TypeError("A promise cannot be resolved with itself.");if(ce&&(_(ce)=="object"||typeof ce=="function")){var me=ce.then;if(typeof me=="function")return void se(B(me,ce),B(ne,this),B(m,this))}this._state=!0,this._value=ce,he.call(this)}catch(ie){m.call(this,ie)}}function m(ce){this._state=!1,this._value=ce,he.call(this)}function he(){for(var ce=0,me=this._deferreds.length;me>ce;ce++)q.call(this,this._deferreds[ce]);this._deferreds=null}function De(ce,me,ie,Oe){this.onFulfilled=typeof ce=="function"?ce:null,this.onRejected=typeof me=="function"?me:null,this.resolve=ie,this.reject=Oe}function se(ce,me,ie){var Oe=!1;try{ce(function(Ue){Oe||(Oe=!0,me(Ue))},function(Ue){Oe||(Oe=!0,ie(Ue))})}catch(Ue){if(Oe)return;Oe=!0,ie(Ue)}}var fe=H.immediateFn||typeof c=="function"&&c||function(ce){setTimeout(ce,1)},_e=Array.isArray||function(ce){return Object.prototype.toString.call(ce)==="[object Array]"};H.prototype.catch=function(ce){return this.then(null,ce)},H.prototype.then=function(ce,me){var ie=this;return new H(function(Oe,Ue){q.call(ie,new De(ce,me,Oe,Ue))})},H.all=function(){var ce=Array.prototype.slice.call(arguments.length===1&&_e(arguments[0])?arguments[0]:arguments);return new H(function(me,ie){function Oe(at,Dt){try{if(Dt&&(_(Dt)=="object"||typeof Dt=="function")){var Qe=Dt.then;if(typeof Qe=="function")return void Qe.call(Dt,function(ut){Oe(at,ut)},ie)}ce[at]=Dt,--Ue==0&&me(ce)}catch(ut){ie(ut)}}if(ce.length===0)return me([]);for(var Ue=ce.length,je=0;jeOe;Oe++)ce[Oe].then(me,ie)})},i.exports?i.exports=H:T.Promise||(T.Promise=H)}(this),M.copy=function(T){return new Promise(function(B,H){if(typeof T!="string"&&!("text/plain"in T))throw new Error("You must provide a text/plain type.");var q=typeof T=="string"?T:T["text/plain"];window.clipboardData.setData("Text",q)?B():H(new Error("Copying was rejected."))})},M.paste=function(){return new Promise(function(T,B){var H=window.clipboardData.getData("Text");H?T(H):B(new Error("Pasting was rejected."))})}),M}()}).call(this,a(13).setImmediate)},function(i,o,a){"use strict";i.exports=a(15)},function(i,o,a){"use strict";a.r(o),o.default=`:root { + /** + * IMPORTANT: When new theme variables are added below\u2013 also add them to SettingsContext updateThemeVariables() + */ + + /* Light theme */ + --light-color-attribute-name: #ef6632; + --light-color-attribute-name-not-editable: #23272f; + --light-color-attribute-name-inverted: rgba(255, 255, 255, 0.7); + --light-color-attribute-value: #1a1aa6; + --light-color-attribute-value-inverted: #ffffff; + --light-color-attribute-editable-value: #1a1aa6; + --light-color-background: #ffffff; + --light-color-background-hover: rgba(0, 136, 250, 0.1); + --light-color-background-inactive: #e5e5e5; + --light-color-background-invalid: #fff0f0; + --light-color-background-selected: #0088fa; + --light-color-button-background: #ffffff; + --light-color-button-background-focus: #ededed; + --light-color-button: #5f6673; + --light-color-button-disabled: #cfd1d5; + --light-color-button-active: #0088fa; + --light-color-button-focus: #23272f; + --light-color-button-hover: #23272f; + --light-color-border: #eeeeee; + --light-color-commit-did-not-render-fill: #cfd1d5; + --light-color-commit-did-not-render-fill-text: #000000; + --light-color-commit-did-not-render-pattern: #cfd1d5; + --light-color-commit-did-not-render-pattern-text: #333333; + --light-color-commit-gradient-0: #37afa9; + --light-color-commit-gradient-1: #63b19e; + --light-color-commit-gradient-2: #80b393; + --light-color-commit-gradient-3: #97b488; + --light-color-commit-gradient-4: #abb67d; + --light-color-commit-gradient-5: #beb771; + --light-color-commit-gradient-6: #cfb965; + --light-color-commit-gradient-7: #dfba57; + --light-color-commit-gradient-8: #efbb49; + --light-color-commit-gradient-9: #febc38; + --light-color-commit-gradient-text: #000000; + --light-color-component-name: #6a51b2; + --light-color-component-name-inverted: #ffffff; + --light-color-component-badge-background: rgba(0, 0, 0, 0.1); + --light-color-component-badge-background-inverted: rgba(255, 255, 255, 0.25); + --light-color-component-badge-count: #777d88; + --light-color-component-badge-count-inverted: rgba(255, 255, 255, 0.7); + --light-color-context-background: rgba(0,0,0,.9); + --light-color-context-background-hover: rgba(255, 255, 255, 0.1); + --light-color-context-background-selected: #178fb9; + --light-color-context-border: #3d424a; + --light-color-context-text: #ffffff; + --light-color-context-text-selected: #ffffff; + --light-color-dim: #777d88; + --light-color-dimmer: #cfd1d5; + --light-color-dimmest: #eff0f1; + --light-color-error-background: hsl(0, 100%, 97%); + --light-color-error-border: hsl(0, 100%, 92%); + --light-color-error-text: #ff0000; + --light-color-expand-collapse-toggle: #777d88; + --light-color-link: #0000ff; + --light-color-modal-background: rgba(255, 255, 255, 0.75); + --light-color-record-active: #fc3a4b; + --light-color-record-hover: #3578e5; + --light-color-record-inactive: #0088fa; + --light-color-scroll-thumb: #c2c2c2; + --light-color-scroll-track: #fafafa; + --light-color-search-match: yellow; + --light-color-search-match-current: #f7923b; + --light-color-selected-tree-highlight-active: rgba(0, 136, 250, 0.1); + --light-color-selected-tree-highlight-inactive: rgba(0, 0, 0, 0.05); + --light-color-shadow: rgba(0, 0, 0, 0.25); + --light-color-tab-selected-border: #0088fa; + --light-color-text: #000000; + --light-color-text-invalid: #ff0000; + --light-color-text-selected: #ffffff; + --light-color-toggle-background-invalid: #fc3a4b; + --light-color-toggle-background-on: #0088fa; + --light-color-toggle-background-off: #cfd1d5; + --light-color-toggle-text: #ffffff; + --light-color-tooltip-background: rgba(0, 0, 0, 0.9); + --light-color-tooltip-text: #ffffff; + + /* Dark theme */ + --dark-color-attribute-name: #9d87d2; + --dark-color-attribute-name-not-editable: #ededed; + --dark-color-attribute-name-inverted: #282828; + --dark-color-attribute-value: #cedae0; + --dark-color-attribute-value-inverted: #ffffff; + --dark-color-attribute-editable-value: yellow; + --dark-color-background: #282c34; + --dark-color-background-hover: rgba(255, 255, 255, 0.1); + --dark-color-background-inactive: #3d424a; + --dark-color-background-invalid: #5c0000; + --dark-color-background-selected: #178fb9; + --dark-color-button-background: #282c34; + --dark-color-button-background-focus: #3d424a; + --dark-color-button: #afb3b9; + --dark-color-button-active: #61dafb; + --dark-color-button-disabled: #4f5766; + --dark-color-button-focus: #a2e9fc; + --dark-color-button-hover: #ededed; + --dark-color-border: #3d424a; + --dark-color-commit-did-not-render-fill: #777d88; + --dark-color-commit-did-not-render-fill-text: #000000; + --dark-color-commit-did-not-render-pattern: #666c77; + --dark-color-commit-did-not-render-pattern-text: #ffffff; + --dark-color-commit-gradient-0: #37afa9; + --dark-color-commit-gradient-1: #63b19e; + --dark-color-commit-gradient-2: #80b393; + --dark-color-commit-gradient-3: #97b488; + --dark-color-commit-gradient-4: #abb67d; + --dark-color-commit-gradient-5: #beb771; + --dark-color-commit-gradient-6: #cfb965; + --dark-color-commit-gradient-7: #dfba57; + --dark-color-commit-gradient-8: #efbb49; + --dark-color-commit-gradient-9: #febc38; + --dark-color-commit-gradient-text: #000000; + --dark-color-component-name: #61dafb; + --dark-color-component-name-inverted: #282828; + --dark-color-component-badge-background: rgba(255, 255, 255, 0.25); + --dark-color-component-badge-background-inverted: rgba(0, 0, 0, 0.25); + --dark-color-component-badge-count: #8f949d; + --dark-color-component-badge-count-inverted: rgba(255, 255, 255, 0.7); + --dark-color-context-background: rgba(255,255,255,.9); + --dark-color-context-background-hover: rgba(0, 136, 250, 0.1); + --dark-color-context-background-selected: #0088fa; + --dark-color-context-border: #eeeeee; + --dark-color-context-text: #000000; + --dark-color-context-text-selected: #ffffff; + --dark-color-dim: #8f949d; + --dark-color-dimmer: #777d88; + --dark-color-dimmest: #4f5766; + --dark-color-error-background: #200; + --dark-color-error-border: #900; + --dark-color-error-text: #f55; + --dark-color-expand-collapse-toggle: #8f949d; + --dark-color-link: #61dafb; + --dark-color-modal-background: rgba(0, 0, 0, 0.75); + --dark-color-record-active: #fc3a4b; + --dark-color-record-hover: #a2e9fc; + --dark-color-record-inactive: #61dafb; + --dark-color-scroll-thumb: #afb3b9; + --dark-color-scroll-track: #313640; + --dark-color-search-match: yellow; + --dark-color-search-match-current: #f7923b; + --dark-color-selected-tree-highlight-active: rgba(23, 143, 185, 0.15); + --dark-color-selected-tree-highlight-inactive: rgba(255, 255, 255, 0.05); + --dark-color-shadow: rgba(0, 0, 0, 0.5); + --dark-color-tab-selected-border: #178fb9; + --dark-color-text: #ffffff; + --dark-color-text-invalid: #ff8080; + --dark-color-text-selected: #ffffff; + --dark-color-toggle-background-invalid: #fc3a4b; + --dark-color-toggle-background-on: #178fb9; + --dark-color-toggle-background-off: #777d88; + --dark-color-toggle-text: #ffffff; + --dark-color-tooltip-background: rgba(255, 255, 255, 0.9); + --dark-color-tooltip-text: #000000; + + /* Font smoothing */ + --light-font-smoothing: auto; + --dark-font-smoothing: antialiased; + --font-smoothing: auto; + + /* Compact density */ + --compact-font-size-monospace-small: 9px; + --compact-font-size-monospace-normal: 11px; + --compact-font-size-monospace-large: 15px; + --compact-font-size-sans-small: 10px; + --compact-font-size-sans-normal: 12px; + --compact-font-size-sans-large: 14px; + --compact-line-height-data: 18px; + --compact-root-font-size: 16px; + + /* Comfortable density */ + --comfortable-font-size-monospace-small: 10px; + --comfortable-font-size-monospace-normal: 13px; + --comfortable-font-size-monospace-large: 17px; + --comfortable-font-size-sans-small: 12px; + --comfortable-font-size-sans-normal: 14px; + --comfortable-font-size-sans-large: 16px; + --comfortable-line-height-data: 22px; + --comfortable-root-font-size: 20px; + + /* GitHub.com system fonts */ + --font-family-monospace: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, + Courier, monospace; + --font-family-sans: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, + Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; + + /* Constant values shared between JS and CSS */ + --interaction-commit-size: 10px; + --interaction-label-width: 200px; +} +`},function(i,o,a){"use strict";function c(M){var T=this;if(T instanceof c||(T=new c),T.tail=null,T.head=null,T.length=0,M&&typeof M.forEach=="function")M.forEach(function(q){T.push(q)});else if(arguments.length>0)for(var B=0,H=arguments.length;B1)B=T;else{if(!this.head)throw new TypeError("Reduce of empty list with no initial value");H=this.head.next,B=this.head.value}for(var q=0;H!==null;q++)B=M(B,H.value,q),H=H.next;return B},c.prototype.reduceReverse=function(M,T){var B,H=this.tail;if(arguments.length>1)B=T;else{if(!this.tail)throw new TypeError("Reduce of empty list with no initial value");H=this.tail.prev,B=this.tail.value}for(var q=this.length-1;H!==null;q--)B=M(B,H.value,q),H=H.prev;return B},c.prototype.toArray=function(){for(var M=new Array(this.length),T=0,B=this.head;B!==null;T++)M[T]=B.value,B=B.next;return M},c.prototype.toArrayReverse=function(){for(var M=new Array(this.length),T=0,B=this.tail;B!==null;T++)M[T]=B.value,B=B.prev;return M},c.prototype.slice=function(M,T){(T=T||this.length)<0&&(T+=this.length),(M=M||0)<0&&(M+=this.length);var B=new c;if(Tthis.length&&(T=this.length);for(var H=0,q=this.head;q!==null&&Hthis.length&&(T=this.length);for(var H=this.length,q=this.tail;q!==null&&H>T;H--)q=q.prev;for(;q!==null&&H>M;H--,q=q.prev)B.push(q.value);return B},c.prototype.splice=function(M,T){M>this.length&&(M=this.length-1),M<0&&(M=this.length+M);for(var B=0,H=this.head;H!==null&&B=0&&(N._idleTimeoutId=setTimeout(function(){N._onTimeout&&N._onTimeout()},M))},a(14),o.setImmediate=typeof self!="undefined"&&self.setImmediate||c!==void 0&&c.setImmediate||this&&this.setImmediate,o.clearImmediate=typeof self!="undefined"&&self.clearImmediate||c!==void 0&&c.clearImmediate||this&&this.clearImmediate}).call(this,a(4))},function(i,o,a){(function(c,_){(function(t,O){"use strict";if(!t.setImmediate){var N,M,T,B,H,q=1,ne={},m=!1,he=t.document,De=Object.getPrototypeOf&&Object.getPrototypeOf(t);De=De&&De.setTimeout?De:t,{}.toString.call(t.process)==="[object process]"?N=function(_e){_.nextTick(function(){fe(_e)})}:function(){if(t.postMessage&&!t.importScripts){var _e=!0,ce=t.onmessage;return t.onmessage=function(){_e=!1},t.postMessage("","*"),t.onmessage=ce,_e}}()?(B="setImmediate$"+Math.random()+"$",H=function(_e){_e.source===t&&typeof _e.data=="string"&&_e.data.indexOf(B)===0&&fe(+_e.data.slice(B.length))},t.addEventListener?t.addEventListener("message",H,!1):t.attachEvent("onmessage",H),N=function(_e){t.postMessage(B+_e,"*")}):t.MessageChannel?((T=new MessageChannel).port1.onmessage=function(_e){fe(_e.data)},N=function(_e){T.port2.postMessage(_e)}):he&&"onreadystatechange"in he.createElement("script")?(M=he.documentElement,N=function(_e){var ce=he.createElement("script");ce.onreadystatechange=function(){fe(_e),ce.onreadystatechange=null,M.removeChild(ce),ce=null},M.appendChild(ce)}):N=function(_e){setTimeout(fe,0,_e)},De.setImmediate=function(_e){typeof _e!="function"&&(_e=new Function(""+_e));for(var ce=new Array(arguments.length-1),me=0;mede;de++)if((X=se(rt,It,de))!==-1){De=de,It=X;break e}It=-1}}e:{if(rt=Xt,(X=q().get(Ve.primitive))!==void 0){for(de=0;deIt-rt?null:Xt.slice(rt,It-1))!==null){if(It=0,je!==null){for(;ItIt;je--)at=Qe.pop()}for(je=Xt.length-It-1;1<=je;je--)It=[],at.push({id:null,isStateEditable:!1,name:_e(Xt[je-1].functionName),value:void 0,subHooks:It}),Qe.push(at),at=It;je=Xt}It=(Xt=Ve.primitive)==="Context"||Xt==="DebugValue"?null:Dt++,at.push({id:It,isStateEditable:Xt==="Reducer"||Xt==="State",name:Xt,value:Ve.value,subHooks:[]})}return function Ce(oe,He){for(var dt=[],At=0;At-1&&(ne=ne.replace(/eval code/g,"eval").replace(/(\(eval at [^()]*)|(\),.*$)/g,""));var m=ne.replace(/^\s+/,"").replace(/\(eval code/g,"("),he=m.match(/ (\((.+):(\d+):(\d+)\)$)/),De=(m=he?m.replace(he[0],""):m).split(/\s+/).slice(1),se=this.extractLocation(he?he[1]:De.pop()),fe=De.join(" ")||void 0,_e=["eval",""].indexOf(se[0])>-1?void 0:se[0];return new M({functionName:fe,fileName:_e,lineNumber:se[1],columnNumber:se[2],source:ne})},this)},parseFFOrSafari:function(q){return q.stack.split(` +`).filter(function(ne){return!ne.match(H)},this).map(function(ne){if(ne.indexOf(" > eval")>-1&&(ne=ne.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,":$1")),ne.indexOf("@")===-1&&ne.indexOf(":")===-1)return new M({functionName:ne});var m=/((.*".+"[^@]*)?[^@]*)(?:@)/,he=ne.match(m),De=he&&he[1]?he[1]:void 0,se=this.extractLocation(ne.replace(m,""));return new M({functionName:De,fileName:se[0],lineNumber:se[1],columnNumber:se[2],source:ne})},this)},parseOpera:function(q){return!q.stacktrace||q.message.indexOf(` +`)>-1&&q.message.split(` +`).length>q.stacktrace.split(` +`).length?this.parseOpera9(q):q.stack?this.parseOpera11(q):this.parseOpera10(q)},parseOpera9:function(q){for(var ne=/Line (\d+).*script (?:in )?(\S+)/i,m=q.message.split(` +`),he=[],De=2,se=m.length;De/,"$2").replace(/\([^)]*\)/g,"")||void 0;se.match(/\(([^)]*)\)/)&&(m=se.replace(/^[^(]+\(([^)]*)\)$/,"$1"));var _e=m===void 0||m==="[arguments not available]"?void 0:m.split(",");return new M({functionName:fe,args:_e,fileName:De[0],lineNumber:De[1],columnNumber:De[2],source:ne})},this)}}})=="function"?c.apply(o,_):c)===void 0||(i.exports=t)})()},function(i,o,a){var c,_,t;(function(O,N){"use strict";_=[],(t=typeof(c=function(){function M(fe){return fe.charAt(0).toUpperCase()+fe.substring(1)}function T(fe){return function(){return this[fe]}}var B=["isConstructor","isEval","isNative","isToplevel"],H=["columnNumber","lineNumber"],q=["fileName","functionName","source"],ne=B.concat(H,q,["args"]);function m(fe){if(fe)for(var _e=0;_e1?Ae-1:0),ke=1;ke=0&&Ae.splice(Z,1)}}}])&&c(z.prototype,G),$&&c(z,$),U}(),t=a(2),O=a.n(t);try{var N=a(9).default,M=function(U){var z=new RegExp("".concat(U,": ([0-9]+)")),G=N.match(z);return parseInt(G[1],10)};M("comfortable-line-height-data"),M("compact-line-height-data")}catch(U){}function T(U){try{return sessionStorage.getItem(U)}catch(z){return null}}function B(U){try{sessionStorage.removeItem(U)}catch(z){}}function H(U,z){try{return sessionStorage.setItem(U,z)}catch(G){}}var q=function(U,z){return U===z},ne=a(1),m=a.n(ne);function he(U){return U.ownerDocument?U.ownerDocument.defaultView:null}function De(U){var z=he(U);return z?z.frameElement:null}function se(U){var z=ce(U);return fe([U.getBoundingClientRect(),{top:z.borderTop,left:z.borderLeft,bottom:z.borderBottom,right:z.borderRight,width:0,height:0}])}function fe(U){return U.reduce(function(z,G){return z==null?G:{top:z.top+G.top,left:z.left+G.left,width:z.width,height:z.height,bottom:z.bottom+G.bottom,right:z.right+G.right}})}function _e(U,z){var G=De(U);if(G&&G!==z){for(var $=[U.getBoundingClientRect()],Te=G,ye=!1;Te;){var Ae=se(Te);if($.push(Ae),Te=De(Te),ye)break;Te&&he(Te)===z&&(ye=!0)}return fe($)}return U.getBoundingClientRect()}function ce(U){var z=window.getComputedStyle(U);return{borderLeft:parseInt(z.borderLeftWidth,10),borderRight:parseInt(z.borderRightWidth,10),borderTop:parseInt(z.borderTopWidth,10),borderBottom:parseInt(z.borderBottomWidth,10),marginLeft:parseInt(z.marginLeft,10),marginRight:parseInt(z.marginRight,10),marginTop:parseInt(z.marginTop,10),marginBottom:parseInt(z.marginBottom,10),paddingLeft:parseInt(z.paddingLeft,10),paddingRight:parseInt(z.paddingRight,10),paddingTop:parseInt(z.paddingTop,10),paddingBottom:parseInt(z.paddingBottom,10)}}function me(U,z){var G;if(typeof Symbol=="undefined"||U[Symbol.iterator]==null){if(Array.isArray(U)||(G=function(ke,Je){if(!!ke){if(typeof ke=="string")return ie(ke,Je);var vt=Object.prototype.toString.call(ke).slice(8,-1);if(vt==="Object"&&ke.constructor&&(vt=ke.constructor.name),vt==="Map"||vt==="Set")return Array.from(ke);if(vt==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(vt))return ie(ke,Je)}}(U))||z&&U&&typeof U.length=="number"){G&&(U=G);var $=0,Te=function(){};return{s:Te,n:function(){return $>=U.length?{done:!0}:{done:!1,value:U[$++]}},e:function(ke){throw ke},f:Te}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var ye,Ae=!0,Z=!1;return{s:function(){G=U[Symbol.iterator]()},n:function(){var ke=G.next();return Ae=ke.done,ke},e:function(ke){Z=!0,ye=ke},f:function(){try{Ae||G.return==null||G.return()}finally{if(Z)throw ye}}}}function ie(U,z){(z==null||z>U.length)&&(z=U.length);for(var G=0,$=new Array(z);GAe.left+Ae.width&&(ue=Ae.left+Ae.width-vt-5),{style:{top:ke+="px",left:ue+="px"}}}(z,G,{width:$.width,height:$.height});m()(this.tip.style,Te.style)}}]),U}(),Qe=function(){function U(){Oe(this,U);var z=window.__REACT_DEVTOOLS_TARGET_WINDOW__||window;this.window=z;var G=window.__REACT_DEVTOOLS_TARGET_WINDOW__||window;this.tipBoundsWindow=G;var $=z.document;this.container=$.createElement("div"),this.container.style.zIndex="10000000",this.tip=new Dt($,this.container),this.rects=[],$.body.appendChild(this.container)}return je(U,[{key:"remove",value:function(){this.tip.remove(),this.rects.forEach(function(z){z.remove()}),this.rects.length=0,this.container.parentNode&&this.container.parentNode.removeChild(this.container)}},{key:"inspect",value:function(z,G){for(var $=this,Te=z.filter(function(Ct){return Ct.nodeType===Node.ELEMENT_NODE});this.rects.length>Te.length;)this.rects.pop().remove();if(Te.length!==0){for(;this.rects.length1&&arguments[1]!==void 0?arguments[1]:q,nt=void 0,Ct=[],Mt=void 0,Pt=!1,sn=function(Nt,Dn){return qe(Nt,Ct[Dn])},rn=function(){for(var Nt=arguments.length,Dn=Array(Nt),dr=0;dr5&&arguments[5]!==void 0?arguments[5]:0,Z=Mo(U);switch(Z){case"html_element":return z.push($),{inspectable:!1,preview_short:Li(U,!1),preview_long:Li(U,!0),name:U.tagName,type:Z};case"function":return z.push($),{inspectable:!1,preview_short:Li(U,!1),preview_long:Li(U,!0),name:typeof U.name!="function"&&U.name?U.name:"function",type:Z};case"string":return U.length<=500?U:U.slice(0,500)+"...";case"bigint":case"symbol":return z.push($),{inspectable:!1,preview_short:Li(U,!1),preview_long:Li(U,!0),name:U.toString(),type:Z};case"react_element":return z.push($),{inspectable:!1,preview_short:Li(U,!1),preview_long:Li(U,!0),name:F0(U)||"Unknown",type:Z};case"array_buffer":case"data_view":return z.push($),{inspectable:!1,preview_short:Li(U,!1),preview_long:Li(U,!0),name:Z==="data_view"?"DataView":"ArrayBuffer",size:U.byteLength,type:Z};case"array":return ye=Te($),Ae>=2&&!ye?d0(Z,!0,U,z,$):U.map(function(vt,ue){return Ro(vt,z,G,$.concat([ue]),Te,ye?1:Ae+1)});case"html_all_collection":case"typed_array":case"iterator":if(ye=Te($),Ae>=2&&!ye)return d0(Z,!0,U,z,$);var ke={unserializable:!0,type:Z,readonly:!0,size:Z==="typed_array"?U.length:void 0,preview_short:Li(U,!1),preview_long:Li(U,!0),name:U.constructor&&U.constructor.name!=="Object"?U.constructor.name:""};return Qt(U[Symbol.iterator])&&Array.from(U).forEach(function(vt,ue){return ke[ue]=Ro(vt,z,G,$.concat([ue]),Te,ye?1:Ae+1)}),G.push($),ke;case"opaque_iterator":return z.push($),{inspectable:!1,preview_short:Li(U,!1),preview_long:Li(U,!0),name:U[Symbol.toStringTag],type:Z};case"date":case"regexp":return z.push($),{inspectable:!1,preview_short:Li(U,!1),preview_long:Li(U,!0),name:U.toString(),type:Z};case"object":if(ye=Te($),Ae>=2&&!ye)return d0(Z,!0,U,z,$);var Je={};return su(U).forEach(function(vt){var ue=vt.toString();Je[ue]=Ro(U[vt],z,G,$.concat([ue]),Te,ye?1:Ae+1)}),Je;case"infinity":case"nan":case"undefined":return z.push($),{type:Z};default:return U}}function Jo(U){return(Jo=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(z){return typeof z}:function(z){return z&&typeof Symbol=="function"&&z.constructor===Symbol&&z!==Symbol.prototype?"symbol":typeof z})(U)}function Ps(U){return function(z){if(Array.isArray(z))return Zo(z)}(U)||function(z){if(typeof Symbol!="undefined"&&Symbol.iterator in Object(z))return Array.from(z)}(U)||function(z,G){if(!!z){if(typeof z=="string")return Zo(z,G);var $=Object.prototype.toString.call(z).slice(8,-1);if($==="Object"&&z.constructor&&($=z.constructor.name),$==="Map"||$==="Set")return Array.from(z);if($==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test($))return Zo(z,G)}}(U)||function(){throw new TypeError(`Invalid attempt to spread non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}()}function Zo(U,z){(z==null||z>U.length)&&(z=U.length);for(var G=0,$=new Array(z);Gz.toString()?1:z.toString()>U.toString()?-1:0}function su(U){for(var z=[],G=U,$=function(){var Te=[].concat(Ps(Object.keys(G)),Ps(Object.getOwnPropertySymbols(G))),ye=Object.getOwnPropertyDescriptors(G);Te.forEach(function(Ae){ye[Ae].enumerable&&z.push(Ae)}),G=Object.getPrototypeOf(G)};G!=null;)$();return z}function mi(U){var z=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"Anonymous",G=$o.get(U);if(G!=null)return G;var $=z;return typeof U.displayName=="string"?$=U.displayName:typeof U.name=="string"&&U.name!==""&&($=U.name),$o.set(U,$),$}var wr=0;function el(){return++wr}function Y0(U){var z=qt.get(U);if(z!==void 0)return z;for(var G=new Array(U.length),$=0;$1&&arguments[1]!==void 0?arguments[1]:50;return U.length>z?U.substr(0,z)+"\u2026":U}function Li(U,z){if(U!=null&&hasOwnProperty.call(U,wu.type))return z?U[wu.preview_long]:U[wu.preview_short];switch(Mo(U)){case"html_element":return"<".concat(au(U.tagName.toLowerCase())," />");case"function":return au("\u0192 ".concat(typeof U.name=="function"?"":U.name,"() {}"));case"string":return'"'.concat(U,'"');case"bigint":return au(U.toString()+"n");case"regexp":case"symbol":return au(U.toString());case"react_element":return"<".concat(au(F0(U)||"Unknown")," />");case"array_buffer":return"ArrayBuffer(".concat(U.byteLength,")");case"data_view":return"DataView(".concat(U.buffer.byteLength,")");case"array":if(z){for(var G="",$=0;$0&&(G+=", "),!((G+=Li(U[$],!1)).length>50));$++);return"[".concat(au(G),"]")}var Te=hasOwnProperty.call(U,wu.size)?U[wu.size]:U.length;return"Array(".concat(Te,")");case"typed_array":var ye="".concat(U.constructor.name,"(").concat(U.length,")");if(z){for(var Ae="",Z=0;Z0&&(Ae+=", "),!((Ae+=U[Z]).length>50));Z++);return"".concat(ye," [").concat(au(Ae),"]")}return ye;case"iterator":var ke=U.constructor.name;if(z){for(var Je=Array.from(U),vt="",ue=0;ue0&&(vt+=", "),Array.isArray(qe)){var nt=Li(qe[0],!0),Ct=Li(qe[1],!1);vt+="".concat(nt," => ").concat(Ct)}else vt+=Li(qe,!1);if(vt.length>50)break}return"".concat(ke,"(").concat(U.size,") {").concat(au(vt),"}")}return"".concat(ke,"(").concat(U.size,")");case"opaque_iterator":return U[Symbol.toStringTag];case"date":return U.toString();case"object":if(z){for(var Mt=su(U).sort(Ai),Pt="",sn=0;sn0&&(Pt+=", "),(Pt+="".concat(rn.toString(),": ").concat(Li(U[rn],!1))).length>50)break}return"{".concat(au(Pt),"}")}return"{\u2026}";case"boolean":case"number":case"infinity":case"nan":case"null":case"undefined":return U;default:try{return au(""+U)}catch(Nt){return"unserializable"}}}var Is=a(7);function Xl(U){return(Xl=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(z){return typeof z}:function(z){return z&&typeof Symbol=="function"&&z.constructor===Symbol&&z!==Symbol.prototype?"symbol":typeof z})(U)}function P0(U,z){var G=Object.keys(U);if(Object.getOwnPropertySymbols){var $=Object.getOwnPropertySymbols(U);z&&($=$.filter(function(Te){return Object.getOwnPropertyDescriptor(U,Te).enumerable})),G.push.apply(G,$)}return G}function p0(U){for(var z=1;z2&&arguments[2]!==void 0?arguments[2]:[];if(U!==null){var $=[],Te=[],ye=Ro(U,$,Te,G,z);return{data:ye,cleaned:$,unserializable:Te}}return null}function X0(U){var z,G,$=(z=U,G=new Set,JSON.stringify(z,function(Ae,Z){if(Xl(Z)==="object"&&Z!==null){if(G.has(Z))return;G.add(Z)}return typeof Z=="bigint"?Z.toString()+"n":Z})),Te=$===void 0?"undefined":$,ye=window.__REACT_DEVTOOLS_GLOBAL_HOOK__.clipboardCopyText;typeof ye=="function"?ye(Te).catch(function(Ae){}):Object(Is.copy)(Te)}function gi(U,z){var G=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,$=z[G],Te=Array.isArray(U)?U.slice():p0({},U);return G+1===z.length?Array.isArray(Te)?Te.splice($,1):delete Te[$]:Te[$]=gi(U[$],z,G+1),Te}function en(U,z,G){var $=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0,Te=z[$],ye=Array.isArray(U)?U.slice():p0({},U);if($+1===z.length){var Ae=G[$];ye[Ae]=ye[Te],Array.isArray(ye)?ye.splice(Te,1):delete ye[Te]}else ye[Te]=en(U[Te],z,G,$+1);return ye}function bn(U,z,G){var $=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0;if($>=z.length)return G;var Te=z[$],ye=Array.isArray(U)?U.slice():p0({},U);return ye[Te]=bn(U[Te],z,G,$+1),ye}var Oi=a(8);function yi(U,z){var G=Object.keys(U);if(Object.getOwnPropertySymbols){var $=Object.getOwnPropertySymbols(U);z&&($=$.filter(function(Te){return Object.getOwnPropertyDescriptor(U,Te).enumerable})),G.push.apply(G,$)}return G}function Wt(U){for(var z=1;z=U.length?{done:!0}:{done:!1,value:U[$++]}},e:function(ke){throw ke},f:Te}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var ye,Ae=!0,Z=!1;return{s:function(){G=U[Symbol.iterator]()},n:function(){var ke=G.next();return Ae=ke.done,ke},e:function(ke){Z=!0,ye=ke},f:function(){try{Ae||G.return==null||G.return()}finally{if(Z)throw ye}}}}function Ql(U,z){if(U){if(typeof U=="string")return ko(U,z);var G=Object.prototype.toString.call(U).slice(8,-1);return G==="Object"&&U.constructor&&(G=U.constructor.name),G==="Map"||G==="Set"?Array.from(U):G==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(G)?ko(U,z):void 0}}function ko(U,z){(z==null||z>U.length)&&(z=U.length);for(var G=0,$=new Array(z);G0){var mt=ye(ae);if(mt!=null){var Jt,On=Yi(Io);try{for(On.s();!(Jt=On.n()).done;)if(Jt.value.test(mt))return!0}catch(ir){On.e(ir)}finally{On.f()}}}if(re!=null&&ys.size>0){var Sn,_n=re.fileName,Tn=Yi(ys);try{for(Tn.s();!(Sn=Tn.n()).done;)if(Sn.value.test(_n))return!0}catch(ir){Tn.e(ir)}finally{Tn.f()}}return!1}function Tu(ae){var re=ae.type;switch(ae.tag){case Ct:case Cr:return 1;case nt:case Rn:return 5;case rn:return 6;case Nt:return 11;case dr:return 7;case Dn:case er:case sn:return 9;case Lr:case Nr:return 8;case it:return 12;case Et:return 13;default:switch(Ae(re)){case 60111:case"Symbol(react.concurrent_mode)":case"Symbol(react.async_mode)":return 9;case 60109:case"Symbol(react.provider)":return 2;case 60110:case"Symbol(react.context)":return 2;case 60108:case"Symbol(react.strict_mode)":return 9;case 60114:case"Symbol(react.profiler)":return 10;default:return 9}}}function Ei(ae){if(Uo.has(ae))return ae;var re=ae.alternate;return re!=null&&Uo.has(re)?re:(Uo.add(ae),ae)}window.__REACT_DEVTOOLS_COMPONENT_FILTERS__!=null?_s(window.__REACT_DEVTOOLS_COMPONENT_FILTERS__):_s([{type:1,value:7,isEnabled:!0}]);var C0=new Map,$0=new Map,Uo=new Set,sa=new Map,es=new Map,tu=-1;function ei(ae){if(!C0.has(ae)){var re=el();C0.set(ae,re),$0.set(re,ae)}return C0.get(ae)}function ho(ae){switch(Tu(ae)){case 1:if(B0!==null){var re=ei(Ei(ae)),Fe=Ci(ae);Fe!==null&&B0.set(re,Fe)}}}var Bi={};function Ci(ae){switch(Tu(ae)){case 1:var re=ae.stateNode,Fe=Bi,Re=Bi;return re!=null&&(re.constructor&&re.constructor.contextType!=null?Re=re.context:(Fe=re.context)&&Object.keys(Fe).length===0&&(Fe=Bi)),[Fe,Re];default:return null}}function gf(ae){switch(Tu(ae)){case 1:if(B0!==null){var re=ei(Ei(ae)),Fe=B0.has(re)?B0.get(re):null,Re=Ci(ae);if(Fe==null||Re==null)return null;var st=Q0(Fe,2),mt=st[0],Jt=st[1],On=Q0(Re,2),Sn=On[0],_n=On[1];if(Sn!==Bi)return eo(mt,Sn);if(_n!==Bi)return Jt!==_n}}return null}function yf(ae,re){if(ae==null||re==null)return!1;if(re.hasOwnProperty("baseState")&&re.hasOwnProperty("memoizedState")&&re.hasOwnProperty("next")&&re.hasOwnProperty("queue"))for(;re!==null;){if(re.memoizedState!==ae.memoizedState)return!0;re=re.next,ae=ae.next}return!1}function eo(ae,re){if(ae==null||re==null||re.hasOwnProperty("baseState")&&re.hasOwnProperty("memoizedState")&&re.hasOwnProperty("next")&&re.hasOwnProperty("queue"))return null;var Fe,Re=[],st=Yi(new Set([].concat(eu(Object.keys(ae)),eu(Object.keys(re)))));try{for(st.s();!(Fe=st.n()).done;){var mt=Fe.value;ae[mt]!==re[mt]&&Re.push(mt)}}catch(Jt){st.e(Jt)}finally{st.f()}return Re}function to(ae,re){switch(re.tag){case Ct:case nt:case Mt:case Lr:case Nr:return(ao(re)&ue)===ue;default:return ae.memoizedProps!==re.memoizedProps||ae.memoizedState!==re.memoizedState||ae.ref!==re.ref}}var xe=[],tt=[],Ye=[],Yt=[],Kt=new Map,pr=0,Wr=null;function xn(ae){xe.push(ae)}function gu(ae){if(xe.length!==0||tt.length!==0||Ye.length!==0||Wr!==null||Pu){var re=tt.length+Ye.length+(Wr===null?0:1),Fe=new Array(3+pr+(re>0?2+re:0)+xe.length),Re=0;if(Fe[Re++]=z,Fe[Re++]=tu,Fe[Re++]=pr,Kt.forEach(function(On,Sn){Fe[Re++]=Sn.length;for(var _n=Y0(Sn),Tn=0;Tn<_n.length;Tn++)Fe[Re+Tn]=_n[Tn];Re+=Sn.length}),re>0){Fe[Re++]=2,Fe[Re++]=re;for(var st=tt.length-1;st>=0;st--)Fe[Re++]=tt[st];for(var mt=0;mt0?ae.forEach(function(re){U.emit("operations",re)}):(Ar!==null&&(cu=!0),U.getFiberRoots(z).forEach(function(re){e0(tu=ei(Ei(re.current)),re.current),Pu&&re.memoizedInteractions!=null&&(il={changeDescriptions:ts?new Map:null,durations:[],commitTime:Jl()-Zu,interactions:Array.from(re.memoizedInteractions).map(function(Fe){return Wt(Wt({},Fe),{},{timestamp:Fe.timestamp-Zu})}),maxActualDuration:0,priorityLevel:null}),Jr(re.current,null,!1,!1),gu(),tu=-1}))},getBestMatchForTrackedPath:function(){if(Ar===null||no===null)return null;for(var ae=no;ae!==null&&Qu(ae);)ae=ae.return;return ae===null?null:{id:ei(Ei(ae)),isFullMatch:nu===Ar.length-1}},getDisplayNameForFiberID:function(ae){var re=$0.get(ae);return re!=null?ye(re):null},getFiberIDForNative:function(ae){var re=arguments.length>1&&arguments[1]!==void 0&&arguments[1],Fe=G.findFiberByHostInstance(ae);if(Fe!=null){if(re)for(;Fe!==null&&Qu(Fe);)Fe=Fe.return;return ei(Ei(Fe))}return null},getInstanceAndStyle:function(ae){var re=null,Fe=null,Re=Vu(ae);return Re!==null&&(re=Re.stateNode,Re.memoizedProps!==null&&(Fe=Re.memoizedProps.style)),{instance:re,style:Fe}},getOwnersList:function(ae){var re=Vu(ae);if(re==null)return null;var Fe=re._debugOwner,Re=[{displayName:ye(re)||"Anonymous",id:ae,type:Tu(re)}];if(Fe)for(var st=Fe;st!==null;)Re.unshift({displayName:ye(st)||"Anonymous",id:ei(Ei(st)),type:Tu(st)}),st=st._debugOwner||null;return Re},getPathForElement:function(ae){var re=$0.get(ae);if(re==null)return null;for(var Fe=[];re!==null;)Fe.push(E0(re)),re=re.return;return Fe.reverse(),Fe},getProfilingData:function(){var ae=[];if(Es===null)throw Error("getProfilingData() called before any profiling data was recorded");return Es.forEach(function(re,Fe){var Re=[],st=[],mt=new Map,Jt=new Map,On=xl!==null&&xl.get(Fe)||"Unknown";O0!=null&&O0.forEach(function(Sn,_n){vo!=null&&vo.get(_n)===Fe&&st.push([_n,Sn])}),re.forEach(function(Sn,_n){var Tn=Sn.changeDescriptions,ir=Sn.durations,Bt=Sn.interactions,Pi=Sn.maxActualDuration,Rr=Sn.priorityLevel,mr=Sn.commitTime,Y=[];Bt.forEach(function(Di){mt.has(Di.id)||mt.set(Di.id,Di),Y.push(Di.id);var ru=Jt.get(Di.id);ru!=null?ru.push(_n):Jt.set(Di.id,[_n])});for(var ri=[],ii=[],Vr=0;Vr1?Kn.set(Tn,ir-1):Kn.delete(Tn),ni.delete(Sn)}(tu),ti(Fe,!1))}else e0(tu,Fe),Jr(Fe,null,!1,!1);if(Pu&&st){var On=Es.get(tu);On!=null?On.push(il):Es.set(tu,[il])}gu(),bo&&U.emit("traceUpdates",Bo),tu=-1},handleCommitFiberUnmount:function(ae){ti(ae,!1)},inspectElement:function(ae,re){if(zi(ae)){if(re!=null){R0(re);var Fe=null;return re[0]==="hooks"&&(Fe="hooks"),{id:ae,type:"hydrated-path",path:re,value:Ri(Uu(Xi,re),Hi(null,Fe),re)}}return{id:ae,type:"no-change"}}if(qs=!1,Xi!==null&&Xi.id===ae||(A0={}),(Xi=aa(ae))===null)return{id:ae,type:"not-found"};re!=null&&R0(re),function(st){var mt=st.hooks,Jt=st.id,On=st.props,Sn=$0.get(Jt);if(Sn!=null){var _n=Sn.elementType,Tn=Sn.stateNode,ir=Sn.tag,Bt=Sn.type;switch(ir){case Ct:case Cr:case Rn:$.$r=Tn;break;case nt:$.$r={hooks:mt,props:On,type:Bt};break;case rn:$.$r={props:On,type:Bt.render};break;case Lr:case Nr:$.$r={props:On,type:_n!=null&&_n.type!=null?_n.type:Bt};break;default:$.$r=null}}else console.warn('Could not find Fiber with id "'.concat(Jt,'"'))}(Xi);var Re=Wt({},Xi);return Re.context=Ri(Re.context,Hi("context",null)),Re.hooks=Ri(Re.hooks,Hi("hooks","hooks")),Re.props=Ri(Re.props,Hi("props",null)),Re.state=Ri(Re.state,Hi("state",null)),{id:ae,type:"full-data",value:Re}},logElementToConsole:function(ae){var re=zi(ae)?Xi:aa(ae);if(re!==null){var Fe=typeof console.groupCollapsed=="function";Fe&&console.groupCollapsed("[Click to expand] %c<".concat(re.displayName||"Component"," />"),"color: var(--dom-tag-name-color); font-weight: normal;"),re.props!==null&&console.log("Props:",re.props),re.state!==null&&console.log("State:",re.state),re.hooks!==null&&console.log("Hooks:",re.hooks);var Re=Cl(ae);Re!==null&&console.log("Nodes:",Re),re.source!==null&&console.log("Location:",re.source),(window.chrome||/firefox/i.test(navigator.userAgent))&&console.log("Right-click any value to save it as a global variable for further inspection."),Fe&&console.groupEnd()}else console.warn('Could not find Fiber with id "'.concat(ae,'"'))},prepareViewAttributeSource:function(ae,re){zi(ae)&&(window.$attribute=Uu(Xi,re))},prepareViewElementSource:function(ae){var re=$0.get(ae);if(re!=null){var Fe=re.elementType,Re=re.tag,st=re.type;switch(Re){case Ct:case Cr:case Rn:case nt:$.$type=st;break;case rn:$.$type=st.render;break;case Lr:case Nr:$.$type=Fe!=null&&Fe.type!=null?Fe.type:st;break;default:$.$type=null}}else console.warn('Could not find Fiber with id "'.concat(ae,'"'))},overrideSuspense:function(ae,re){if(typeof Po!="function"||typeof rl!="function")throw new Error("Expected overrideSuspense() to not get called for earlier React versions.");re?($u.add(ae),$u.size===1&&Po(Ds)):($u.delete(ae),$u.size===0&&Po(_f));var Fe=$0.get(ae);Fe!=null&&rl(Fe)},overrideValueAtPath:function(ae,re,Fe,Re,st){var mt=Vu(re);if(mt!==null){var Jt=mt.stateNode;switch(ae){case"context":switch(Re=Re.slice(1),mt.tag){case Ct:Re.length===0?Jt.context=st:Oo(Jt.context,Re,st),Jt.forceUpdate()}break;case"hooks":typeof fu=="function"&&fu(mt,Fe,Re,st);break;case"props":switch(mt.tag){case Ct:mt.pendingProps=bn(Jt.props,Re,st),Jt.forceUpdate();break;default:typeof Z0=="function"&&Z0(mt,Re,st)}break;case"state":switch(mt.tag){case Ct:Oo(Jt.state,Re,st),Jt.forceUpdate()}}}},renamePath:function(ae,re,Fe,Re,st){var mt=Vu(re);if(mt!==null){var Jt=mt.stateNode;switch(ae){case"context":switch(Re=Re.slice(1),st=st.slice(1),mt.tag){case Ct:Re.length===0||Xr(Jt.context,Re,st),Jt.forceUpdate()}break;case"hooks":typeof T0=="function"&&T0(mt,Fe,Re,st);break;case"props":Jt===null?typeof _i=="function"&&_i(mt,Re,st):(mt.pendingProps=en(Jt.props,Re,st),Jt.forceUpdate());break;case"state":Xr(Jt.state,Re,st),Jt.forceUpdate()}}},renderer:G,setTraceUpdatesEnabled:function(ae){bo=ae},setTrackedPath:Fi,startProfiling:fa,stopProfiling:function(){Pu=!1,ts=!1},storeAsGlobal:function(ae,re,Fe){if(zi(ae)){var Re=Uu(Xi,re),st="$reactTemp".concat(Fe);window[st]=Re,console.log(st),console.log(Re)}},updateComponentFilters:function(ae){if(Pu)throw Error("Cannot modify filter preferences while profiling");U.getFiberRoots(z).forEach(function(re){tu=ei(Ei(re.current)),Wu(re.current),ti(re.current,!1),tu=-1}),_s(ae),Kn.clear(),U.getFiberRoots(z).forEach(function(re){e0(tu=ei(Ei(re.current)),re.current),Jr(re.current,null,!1,!1),gu(re),tu=-1})}}}var $n;function tl(U){return(tl=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(z){return typeof z}:function(z){return z&&typeof Symbol=="function"&&z.constructor===Symbol&&z!==Symbol.prototype?"symbol":typeof z})(U)}function fo(U,z,G){if($n===void 0)try{throw Error()}catch(Te){var $=Te.stack.trim().match(/\n( *(at )?)/);$n=$&&$[1]||""}return` +`+$n+U}var I0=!1;function Sl(U,z,G){if(!U||I0)return"";var $,Te=Error.prepareStackTrace;Error.prepareStackTrace=void 0,I0=!0;var ye=G.current;G.current=null;try{if(z){var Ae=function(){throw Error()};if(Object.defineProperty(Ae.prototype,"props",{set:function(){throw Error()}}),(typeof Reflect=="undefined"?"undefined":tl(Reflect))==="object"&&Reflect.construct){try{Reflect.construct(Ae,[])}catch(qe){$=qe}Reflect.construct(U,[],Ae)}else{try{Ae.call()}catch(qe){$=qe}U.call(Ae.prototype)}}else{try{throw Error()}catch(qe){$=qe}U()}}catch(qe){if(qe&&$&&typeof qe.stack=="string"){for(var Z=qe.stack.split(` +`),ke=$.stack.split(` +`),Je=Z.length-1,vt=ke.length-1;Je>=1&&vt>=0&&Z[Je]!==ke[vt];)vt--;for(;Je>=1&&vt>=0;Je--,vt--)if(Z[Je]!==ke[vt]){if(Je!==1||vt!==1)do if(Je--,--vt<0||Z[Je]!==ke[vt])return` +`+Z[Je].replace(" at new "," at ");while(Je>=1&&vt>=0);break}}}finally{I0=!1,Error.prepareStackTrace=Te,G.current=ye}var ue=U?U.displayName||U.name:"";return ue?fo(ue):""}function No(U,z,G,$){return Sl(U,!1,$)}function wt(U,z,G){var $=U.HostComponent,Te=U.LazyComponent,ye=U.SuspenseComponent,Ae=U.SuspenseListComponent,Z=U.FunctionComponent,ke=U.IndeterminateComponent,Je=U.SimpleMemoComponent,vt=U.ForwardRef,ue=U.Block,qe=U.ClassComponent;switch(z.tag){case $:return fo(z.type);case Te:return fo("Lazy");case ye:return fo("Suspense");case Ae:return fo("SuspenseList");case Z:case ke:case Je:return No(z.type,0,0,G);case vt:return No(z.type.render,0,0,G);case ue:return No(z.type._render,0,0,G);case qe:return function(nt,Ct,Mt,Pt){return Sl(nt,!0,Pt)}(z.type,0,0,G);default:return""}}function bt(U,z,G){try{var $="",Te=z;do $+=wt(U,Te,G),Te=Te.return;while(Te);return $}catch(ye){return` +Error generating stack: `+ye.message+` +`+ye.stack}}function Hn(U,z){var G;if(typeof Symbol=="undefined"||U[Symbol.iterator]==null){if(Array.isArray(U)||(G=function(ke,Je){if(!!ke){if(typeof ke=="string")return qr(ke,Je);var vt=Object.prototype.toString.call(ke).slice(8,-1);if(vt==="Object"&&ke.constructor&&(vt=ke.constructor.name),vt==="Map"||vt==="Set")return Array.from(ke);if(vt==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(vt))return qr(ke,Je)}}(U))||z&&U&&typeof U.length=="number"){G&&(U=G);var $=0,Te=function(){};return{s:Te,n:function(){return $>=U.length?{done:!0}:{done:!1,value:U[$++]}},e:function(ke){throw ke},f:Te}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var ye,Ae=!0,Z=!1;return{s:function(){G=U[Symbol.iterator]()},n:function(){var ke=G.next();return Ae=ke.done,ke},e:function(ke){Z=!0,ye=ke},f:function(){try{Ae||G.return==null||G.return()}finally{if(Z)throw ye}}}}function qr(U,z){(z==null||z>U.length)&&(z=U.length);for(var G=0,$=new Array(z);G0?Je[Je.length-1]:null,qe=ue!==null&&(Qr.test(ue)||Ou.test(ue));if(!qe){var nt,Ct=Hn(h0.values());try{for(Ct.s();!(nt=Ct.n()).done;){var Mt=nt.value,Pt=Mt.currentDispatcherRef,sn=Mt.getCurrentFiber,rn=Mt.workTagMap,Nt=sn();if(Nt!=null){var Dn=bt(rn,Nt,Pt);Dn!==""&&Je.push(Dn);break}}}catch(dr){Ct.e(dr)}finally{Ct.f()}}}catch(dr){}ye.apply(void 0,Je)};Ae.__REACT_DEVTOOLS_ORIGINAL_METHOD__=ye,Ni[Te]=Ae}catch(Z){}})}}function ju(U){return(ju=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(z){return typeof z}:function(z){return z&&typeof Symbol=="function"&&z.constructor===Symbol&&z!==Symbol.prototype?"symbol":typeof z})(U)}function ms(U,z){for(var G=0;GU.length)&&(z=U.length);for(var G=0,$=new Array(z);G1?Z-1:0),Je=1;Je0?ue[ue.length-1]:0),ue.push(un),Z.set(et,Je(Ft._topLevelWrapper));try{var fn=it.apply(this,Et);return ue.pop(),fn}catch(Sr){throw ue=[],Sr}finally{if(ue.length===0){var Jn=Z.get(et);if(Jn===void 0)throw new Error("Expected to find root ID.");dr(Jn)}}},performUpdateIfNecessary:function(it,Et){var et=Et[0];if(S0(et)===9)return it.apply(this,Et);var Ft=Je(et);ue.push(Ft);var un=Qn(et);try{var fn=it.apply(this,Et),Jn=Qn(et);return vt(un,Jn)||Ct(et,Ft,Jn),ue.pop(),fn}catch(fu){throw ue=[],fu}finally{if(ue.length===0){var Sr=Z.get(et);if(Sr===void 0)throw new Error("Expected to find root ID.");dr(Sr)}}},receiveComponent:function(it,Et){var et=Et[0];if(S0(et)===9)return it.apply(this,Et);var Ft=Je(et);ue.push(Ft);var un=Qn(et);try{var fn=it.apply(this,Et),Jn=Qn(et);return vt(un,Jn)||Ct(et,Ft,Jn),ue.pop(),fn}catch(fu){throw ue=[],fu}finally{if(ue.length===0){var Sr=Z.get(et);if(Sr===void 0)throw new Error("Expected to find root ID.");dr(Sr)}}},unmountComponent:function(it,Et){var et=Et[0];if(S0(et)===9)return it.apply(this,Et);var Ft=Je(et);ue.push(Ft);try{var un=it.apply(this,Et);return ue.pop(),function(Jn,Sr){rn.push(Sr),ye.delete(Sr)}(0,Ft),un}catch(Jn){throw ue=[],Jn}finally{if(ue.length===0){var fn=Z.get(et);if(fn===void 0)throw new Error("Expected to find root ID.");dr(fn)}}}}));var Pt=[],sn=new Map,rn=[],Nt=0,Dn=null;function dr(it){if(Pt.length!==0||rn.length!==0||Dn!==null){var Et=rn.length+(Dn===null?0:1),et=new Array(3+Nt+(Et>0?2+Et:0)+Pt.length),Ft=0;if(et[Ft++]=z,et[Ft++]=it,et[Ft++]=Nt,sn.forEach(function(Jn,Sr){et[Ft++]=Sr.length;for(var fu=Y0(Sr),Lu=0;Lu0){et[Ft++]=2,et[Ft++]=Et;for(var un=0;un"),"color: var(--dom-tag-name-color); font-weight: normal;"),Et.props!==null&&console.log("Props:",Et.props),Et.state!==null&&console.log("State:",Et.state),Et.context!==null&&console.log("Context:",Et.context);var Ft=Te(it);Ft!==null&&console.log("Node:",Ft),(window.chrome||/firefox/i.test(navigator.userAgent))&&console.log("Right-click any value to save it as a global variable for further inspection."),et&&console.groupEnd()}else console.warn('Could not find element with id "'.concat(it,'"'))},overrideSuspense:function(){throw new Error("overrideSuspense not supported by this renderer")},overrideValueAtPath:function(it,Et,et,Ft,un){var fn=ye.get(Et);if(fn!=null){var Jn=fn._instance;if(Jn!=null)switch(it){case"context":Oo(Jn.context,Ft,un),m0(Jn);break;case"hooks":throw new Error("Hooks not supported by this renderer");case"props":var Sr=fn._currentElement;fn._currentElement=J0(J0({},Sr),{},{props:bn(Sr.props,Ft,un)}),m0(Jn);break;case"state":Oo(Jn.state,Ft,un),m0(Jn)}}},renamePath:function(it,Et,et,Ft,un){var fn=ye.get(Et);if(fn!=null){var Jn=fn._instance;if(Jn!=null)switch(it){case"context":Xr(Jn.context,Ft,un),m0(Jn);break;case"hooks":throw new Error("Hooks not supported by this renderer");case"props":var Sr=fn._currentElement;fn._currentElement=J0(J0({},Sr),{},{props:en(Sr.props,Ft,un)}),m0(Jn);break;case"state":Xr(Jn.state,Ft,un),m0(Jn)}}},prepareViewAttributeSource:function(it,Et){var et=Nr(it);et!==null&&(window.$attribute=Uu(et,Et))},prepareViewElementSource:function(it){var Et=ye.get(it);if(Et!=null){var et=Et._currentElement;et!=null?$.$type=et.type:console.warn('Could not find element with id "'.concat(it,'"'))}else console.warn('Could not find instance with id "'.concat(it,'"'))},renderer:G,setTraceUpdatesEnabled:function(it){},setTrackedPath:function(it){},startProfiling:function(){},stopProfiling:function(){},storeAsGlobal:function(it,Et,et){var Ft=Nr(it);if(Ft!==null){var un=Uu(Ft,Et),fn="$reactTemp".concat(et);window[fn]=un,console.log(fn),console.log(un)}},updateComponentFilters:function(it){}}}function fi(U,z){var G=!1,$={bottom:0,left:0,right:0,top:0},Te=z[U];if(Te!=null){for(var ye=0,Ae=Object.keys($);ye0?"development":"production";var Pt=Function.prototype.toString;if(Mt.Mount&&Mt.Mount._renderNewRootComponent){var sn=Pt.call(Mt.Mount._renderNewRootComponent);return sn.indexOf("function")!==0?"production":sn.indexOf("storedMeasure")!==-1?"development":sn.indexOf("should be a pure function")!==-1?sn.indexOf("NODE_ENV")!==-1||sn.indexOf("development")!==-1||sn.indexOf("true")!==-1?"development":sn.indexOf("nextElement")!==-1||sn.indexOf("nextComponent")!==-1?"unminified":"development":sn.indexOf("nextElement")!==-1||sn.indexOf("nextComponent")!==-1?"unminified":"outdated"}}catch(rn){}return"production"}(ke);try{var ue=window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__!==!1,qe=window.__REACT_DEVTOOLS_BREAK_ON_CONSOLE_ERRORS__===!0;(ue||qe)&&(co(ke),Zl({appendComponentStack:ue,breakOnConsoleErrors:qe}))}catch(Mt){}var nt=U.__REACT_DEVTOOLS_ATTACH__;if(typeof nt=="function"){var Ct=nt(Z,Je,ke,U);Z.rendererInterfaces.set(Je,Ct)}return Z.emit("renderer",{id:Je,renderer:ke,reactBuildType:vt}),Je},on:function(ke,Je){ye[ke]||(ye[ke]=[]),ye[ke].push(Je)},off:function(ke,Je){if(ye[ke]){var vt=ye[ke].indexOf(Je);vt!==-1&&ye[ke].splice(vt,1),ye[ke].length||delete ye[ke]}},sub:function(ke,Je){return Z.on(ke,Je),function(){return Z.off(ke,Je)}},supportsFiber:!0,checkDCE:function(ke){try{Function.prototype.toString.call(ke).indexOf("^_^")>-1&&(G=!0,setTimeout(function(){throw new Error("React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build")}))}catch(Je){}},onCommitFiberUnmount:function(ke,Je){var vt=Te.get(ke);vt!=null&&vt.handleCommitFiberUnmount(Je)},onCommitFiberRoot:function(ke,Je,vt){var ue=Z.getFiberRoots(ke),qe=Je.current,nt=ue.has(Je),Ct=qe.memoizedState==null||qe.memoizedState.element==null;nt||Ct?nt&&Ct&&ue.delete(Je):ue.add(Je);var Mt=Te.get(ke);Mt!=null&&Mt.handleCommitFiberRoot(Je,vt)}};Object.defineProperty(U,"__REACT_DEVTOOLS_GLOBAL_HOOK__",{configurable:!1,enumerable:!1,get:function(){return Z}})})(window);var g0=window.__REACT_DEVTOOLS_GLOBAL_HOOK__,js=[{type:1,value:7,isEnabled:!0}];function ji(U){if(g0!=null){var z=U||{},G=z.host,$=G===void 0?"localhost":G,Te=z.nativeStyleEditorValidAttributes,ye=z.useHttps,Ae=ye!==void 0&&ye,Z=z.port,ke=Z===void 0?8097:Z,Je=z.websocket,vt=z.resolveRNStyle,ue=vt===void 0?null:vt,qe=z.isAppActive,nt=Ae?"wss":"ws",Ct=null;if((qe===void 0?function(){return!0}:qe)()){var Mt=null,Pt=[],sn=nt+"://"+$+":"+ke,rn=Je||new window.WebSocket(sn);rn.onclose=function(){Mt!==null&&Mt.emit("shutdown"),Nt()},rn.onerror=function(){Nt()},rn.onmessage=function(Dn){var dr;try{if(typeof Dn.data!="string")throw Error();dr=JSON.parse(Dn.data)}catch(er){return void console.error("[React DevTools] Failed to parse JSON: "+Dn.data)}Pt.forEach(function(er){try{er(dr)}catch(Cr){throw console.log("[React DevTools] Error calling listener",dr),console.log("error:",Cr),Cr}})},rn.onopen=function(){(Mt=new po({listen:function(Rn){return Pt.push(Rn),function(){var Lr=Pt.indexOf(Rn);Lr>=0&&Pt.splice(Lr,1)}},send:function(Rn,Lr,y0){rn.readyState===rn.OPEN?rn.send(JSON.stringify({event:Rn,payload:Lr})):(Mt!==null&&Mt.shutdown(),Nt())}})).addListener("inspectElement",function(Rn){var Lr=Rn.id,y0=Rn.rendererID,Nr=Dn.rendererInterfaces[y0];if(Nr!=null){var it=Nr.findNativeNodesForFiberID(Lr);it!=null&&it[0]!=null&&Dn.emit("showNativeHighlight",it[0])}}),Mt.addListener("updateComponentFilters",function(Rn){js=Rn}),window.__REACT_DEVTOOLS_COMPONENT_FILTERS__==null&&Mt.send("overrideComponentFilters",js);var Dn=new Yn(Mt);if(Dn.addListener("shutdown",function(){g0.emit("shutdown")}),function(Rn,Lr,y0){if(Rn==null)return function(){};var Nr=[Rn.sub("renderer-attached",function(et){var Ft=et.id,un=(et.renderer,et.rendererInterface);Lr.setRendererInterface(Ft,un),un.flushInitialOperations()}),Rn.sub("unsupported-renderer-version",function(et){Lr.onUnsupportedRenderer(et)}),Rn.sub("operations",Lr.onHookOperations),Rn.sub("traceUpdates",Lr.onTraceUpdates)],it=function(et,Ft){var un=Rn.rendererInterfaces.get(et);un==null&&(typeof Ft.findFiberByHostInstance=="function"?un=bs(Rn,et,Ft,y0):Ft.ComponentTree&&(un=fc(Rn,et,Ft,y0)),un!=null&&Rn.rendererInterfaces.set(et,un)),un!=null?Rn.emit("renderer-attached",{id:et,renderer:Ft,rendererInterface:un}):Rn.emit("unsupported-renderer-version",et)};Rn.renderers.forEach(function(et,Ft){it(Ft,et)}),Nr.push(Rn.sub("renderer",function(et){var Ft=et.id,un=et.renderer;it(Ft,un)})),Rn.emit("react-devtools",Lr),Rn.reactDevtoolsAgent=Lr;var Et=function(){Nr.forEach(function(et){return et()}),Rn.rendererInterfaces.forEach(function(et){et.cleanup()}),Rn.reactDevtoolsAgent=null};Lr.addListener("shutdown",Et),Nr.push(function(){Lr.removeListener("shutdown",Et)})}(g0,Dn,window),ue!=null||g0.resolveRNStyle!=null)la(Mt,Dn,ue||g0.resolveRNStyle,Te||g0.nativeStyleEditorValidAttributes||null);else{var dr,er,Cr=function(){Mt!==null&&la(Mt,Dn,dr,er)};g0.hasOwnProperty("resolveRNStyle")||Object.defineProperty(g0,"resolveRNStyle",{enumerable:!1,get:function(){return dr},set:function(Rn){dr=Rn,Cr()}}),g0.hasOwnProperty("nativeStyleEditorValidAttributes")||Object.defineProperty(g0,"nativeStyleEditorValidAttributes",{enumerable:!1,get:function(){return er},set:function(Rn){er=Rn,Cr()}})}}}else Nt()}function Nt(){Ct===null&&(Ct=setTimeout(function(){return ji(U)},2e3))}}}])})});var a6=Ke(s6=>{"use strict";Object.defineProperty(s6,"__esModule",{value:!0});o6();var zB=l6();zB.connectToDevTools()});var h6=Ke(dy=>{"use strict";var f6=dy&&dy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(dy,"__esModule",{value:!0});var c6=Q_(),HB=f6(hT()),d6=f6(eh()),hs=r3();process.env.DEV==="true"&&a6();var p6=i=>{i==null||i.unsetMeasureFunc(),i==null||i.freeRecursive()};dy.default=HB.default({schedulePassiveEffects:c6.unstable_scheduleCallback,cancelPassiveEffects:c6.unstable_cancelCallback,now:Date.now,getRootHostContext:()=>({isInsideText:!1}),prepareForCommit:()=>{},resetAfterCommit:i=>{if(i.isStaticDirty){i.isStaticDirty=!1,typeof i.onImmediateRender=="function"&&i.onImmediateRender();return}typeof i.onRender=="function"&&i.onRender()},getChildHostContext:(i,o)=>{let a=i.isInsideText,c=o==="ink-text"||o==="ink-virtual-text";return a===c?i:{isInsideText:c}},shouldSetTextContent:()=>!1,createInstance:(i,o,a,c)=>{if(c.isInsideText&&i==="ink-box")throw new Error(" can\u2019t be nested inside component");let _=i==="ink-text"&&c.isInsideText?"ink-virtual-text":i,t=hs.createNode(_);for(let[O,N]of Object.entries(o))O!=="children"&&(O==="style"?hs.setStyle(t,N):O==="internal_transform"?t.internal_transform=N:O==="internal_static"?t.internal_static=!0:hs.setAttribute(t,O,N));return t},createTextInstance:(i,o,a)=>{if(!a.isInsideText)throw new Error(`Text string "${i}" must be rendered inside component`);return hs.createTextNode(i)},resetTextContent:()=>{},hideTextInstance:i=>{hs.setTextNodeValue(i,"")},unhideTextInstance:(i,o)=>{hs.setTextNodeValue(i,o)},getPublicInstance:i=>i,hideInstance:i=>{var o;(o=i.yogaNode)===null||o===void 0||o.setDisplay(d6.default.DISPLAY_NONE)},unhideInstance:i=>{var o;(o=i.yogaNode)===null||o===void 0||o.setDisplay(d6.default.DISPLAY_FLEX)},appendInitialChild:hs.appendChildNode,appendChild:hs.appendChildNode,insertBefore:hs.insertBeforeNode,finalizeInitialChildren:(i,o,a,c)=>(i.internal_static&&(c.isStaticDirty=!0,c.staticNode=i),!1),supportsMutation:!0,appendChildToContainer:hs.appendChildNode,insertInContainerBefore:hs.insertBeforeNode,removeChildFromContainer:(i,o)=>{hs.removeChildNode(i,o),p6(o.yogaNode)},prepareUpdate:(i,o,a,c,_)=>{i.internal_static&&(_.isStaticDirty=!0);let t={},O=Object.keys(c);for(let N of O)if(c[N]!==a[N]){if(N==="style"&&typeof c.style=="object"&&typeof a.style=="object"){let T=c.style,B=a.style,H=Object.keys(T);for(let q of H){if(q==="borderStyle"||q==="borderColor"){if(typeof t.style!="object"){let ne={};t.style=ne}t.style.borderStyle=T.borderStyle,t.style.borderColor=T.borderColor}if(T[q]!==B[q]){if(typeof t.style!="object"){let ne={};t.style=ne}t.style[q]=T[q]}}continue}t[N]=c[N]}return t},commitUpdate:(i,o)=>{for(let[a,c]of Object.entries(o))a!=="children"&&(a==="style"?hs.setStyle(i,c):a==="internal_transform"?i.internal_transform=c:a==="internal_static"?i.internal_static=!0:hs.setAttribute(i,a,c))},commitTextUpdate:(i,o,a)=>{hs.setTextNodeValue(i,a)},removeChild:(i,o)=>{hs.removeChildNode(i,o),p6(o.yogaNode)}})});var m6=Ke((RV,v6)=>{"use strict";v6.exports=(i,o=1,a)=>{if(a=Ht({indent:" ",includeEmptyLines:!1},a),typeof i!="string")throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof i}\``);if(typeof o!="number")throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof o}\``);if(typeof a.indent!="string")throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof a.indent}\``);if(o===0)return i;let c=a.includeEmptyLines?/^/gm:/^(?!\s*$)/gm;return i.replace(c,a.indent.repeat(o))}});var g6=Ke(py=>{"use strict";var qB=py&&py.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(py,"__esModule",{value:!0});var d4=qB(eh());py.default=i=>i.getComputedWidth()-i.getComputedPadding(d4.default.EDGE_LEFT)-i.getComputedPadding(d4.default.EDGE_RIGHT)-i.getComputedBorder(d4.default.EDGE_LEFT)-i.getComputedBorder(d4.default.EDGE_RIGHT)});var _6=Ke((MV,y6)=>{y6.exports={single:{topLeft:"\u250C",topRight:"\u2510",bottomRight:"\u2518",bottomLeft:"\u2514",vertical:"\u2502",horizontal:"\u2500"},double:{topLeft:"\u2554",topRight:"\u2557",bottomRight:"\u255D",bottomLeft:"\u255A",vertical:"\u2551",horizontal:"\u2550"},round:{topLeft:"\u256D",topRight:"\u256E",bottomRight:"\u256F",bottomLeft:"\u2570",vertical:"\u2502",horizontal:"\u2500"},bold:{topLeft:"\u250F",topRight:"\u2513",bottomRight:"\u251B",bottomLeft:"\u2517",vertical:"\u2503",horizontal:"\u2501"},singleDouble:{topLeft:"\u2553",topRight:"\u2556",bottomRight:"\u255C",bottomLeft:"\u2559",vertical:"\u2551",horizontal:"\u2500"},doubleSingle:{topLeft:"\u2552",topRight:"\u2555",bottomRight:"\u255B",bottomLeft:"\u2558",vertical:"\u2502",horizontal:"\u2550"},classic:{topLeft:"+",topRight:"+",bottomRight:"+",bottomLeft:"+",vertical:"|",horizontal:"-"}}});var D6=Ke((kV,w3)=>{"use strict";var E6=_6();w3.exports=E6;w3.exports.default=E6});var S6=Ke((LV,w6)=>{"use strict";w6.exports=(i,o=process.argv)=>{let a=i.startsWith("-")?"":i.length===1?"-":"--",c=o.indexOf(a+i),_=o.indexOf("--");return c!==-1&&(_===-1||c<_)}});var x6=Ke((NV,T6)=>{"use strict";var WB=require("os"),C6=require("tty"),pf=S6(),{env:Xo}=process,m2;pf("no-color")||pf("no-colors")||pf("color=false")||pf("color=never")?m2=0:(pf("color")||pf("colors")||pf("color=true")||pf("color=always"))&&(m2=1);"FORCE_COLOR"in Xo&&(Xo.FORCE_COLOR==="true"?m2=1:Xo.FORCE_COLOR==="false"?m2=0:m2=Xo.FORCE_COLOR.length===0?1:Math.min(parseInt(Xo.FORCE_COLOR,10),3));function S3(i){return i===0?!1:{level:i,hasBasic:!0,has256:i>=2,has16m:i>=3}}function T3(i,o){if(m2===0)return 0;if(pf("color=16m")||pf("color=full")||pf("color=truecolor"))return 3;if(pf("color=256"))return 2;if(i&&!o&&m2===void 0)return 0;let a=m2||0;if(Xo.TERM==="dumb")return a;if(process.platform==="win32"){let c=WB.release().split(".");return Number(c[0])>=10&&Number(c[2])>=10586?Number(c[2])>=14931?3:2:1}if("CI"in Xo)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(c=>c in Xo)||Xo.CI_NAME==="codeship"?1:a;if("TEAMCITY_VERSION"in Xo)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(Xo.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in Xo)return 1;if(Xo.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in Xo){let c=parseInt((Xo.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(Xo.TERM_PROGRAM){case"iTerm.app":return c>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(Xo.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(Xo.TERM)||"COLORTERM"in Xo?1:a}function VB(i){let o=T3(i,i&&i.isTTY);return S3(o)}T6.exports={supportsColor:VB,stdout:S3(T3(!0,C6.isatty(1))),stderr:S3(T3(!0,C6.isatty(2)))}});var R6=Ke((FV,A6)=>{"use strict";var GB=(i,o,a)=>{let c=i.indexOf(o);if(c===-1)return i;let _=o.length,t=0,O="";do O+=i.substr(t,c-t)+o+a,t=c+_,c=i.indexOf(o,t);while(c!==-1);return O+=i.substr(t),O},YB=(i,o,a,c)=>{let _=0,t="";do{let O=i[c-1]==="\r";t+=i.substr(_,(O?c-1:c)-_)+o+(O?`\r +`:` +`)+a,_=c+1,c=i.indexOf(` +`,_)}while(c!==-1);return t+=i.substr(_),t};A6.exports={stringReplaceAll:GB,stringEncaseCRLFWithFirstIndex:YB}});var N6=Ke((PV,O6)=>{"use strict";var KB=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,M6=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,XB=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,QB=/\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi,JB=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a","\x07"]]);function k6(i){let o=i[0]==="u",a=i[1]==="{";return o&&!a&&i.length===5||i[0]==="x"&&i.length===3?String.fromCharCode(parseInt(i.slice(1),16)):o&&a?String.fromCodePoint(parseInt(i.slice(2,-1),16)):JB.get(i)||i}function ZB(i,o){let a=[],c=o.trim().split(/\s*,\s*/g),_;for(let t of c){let O=Number(t);if(!Number.isNaN(O))a.push(O);else if(_=t.match(XB))a.push(_[2].replace(QB,(N,M,T)=>M?k6(M):T));else throw new Error(`Invalid Chalk template style argument: ${t} (in style '${i}')`)}return a}function $B(i){M6.lastIndex=0;let o=[],a;for(;(a=M6.exec(i))!==null;){let c=a[1];if(a[2]){let _=ZB(c,a[2]);o.push([c].concat(_))}else o.push([c])}return o}function L6(i,o){let a={};for(let _ of o)for(let t of _.styles)a[t[0]]=_.inverse?null:t.slice(1);let c=i;for(let[_,t]of Object.entries(a))if(!!Array.isArray(t)){if(!(_ in c))throw new Error(`Unknown Chalk style: ${_}`);c=t.length>0?c[_](...t):c[_]}return c}O6.exports=(i,o)=>{let a=[],c=[],_=[];if(o.replace(KB,(t,O,N,M,T,B)=>{if(O)_.push(k6(O));else if(M){let H=_.join("");_=[],c.push(a.length===0?H:L6(i,a)(H)),a.push({inverse:N,styles:$B(M)})}else if(T){if(a.length===0)throw new Error("Found extraneous } in Chalk template literal");c.push(L6(i,a)(_.join(""))),_=[],a.pop()}else _.push(B)}),c.push(_.join("")),a.length>0){let t=`Chalk template literal is missing ${a.length} closing bracket${a.length===1?"":"s"} (\`}\`)`;throw new Error(t)}return c.join("")}});var g4=Ke((IV,F6)=>{"use strict";var hy=t4(),{stdout:C3,stderr:x3}=x6(),{stringReplaceAll:eU,stringEncaseCRLFWithFirstIndex:tU}=R6(),{isArray:p4}=Array,P6=["ansi","ansi","ansi256","ansi16m"],$v=Object.create(null),nU=(i,o={})=>{if(o.level&&!(Number.isInteger(o.level)&&o.level>=0&&o.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");let a=C3?C3.level:0;i.level=o.level===void 0?a:o.level},I6=class{constructor(o){return b6(o)}},b6=i=>{let o={};return nU(o,i),o.template=(...a)=>B6(o.template,...a),Object.setPrototypeOf(o,h4.prototype),Object.setPrototypeOf(o.template,o),o.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},o.template.Instance=I6,o.template};function h4(i){return b6(i)}for(let[i,o]of Object.entries(hy))$v[i]={get(){let a=v4(this,A3(o.open,o.close,this._styler),this._isEmpty);return Object.defineProperty(this,i,{value:a}),a}};$v.visible={get(){let i=v4(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:i}),i}};var U6=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let i of U6)$v[i]={get(){let{level:o}=this;return function(...a){let c=A3(hy.color[P6[o]][i](...a),hy.color.close,this._styler);return v4(this,c,this._isEmpty)}}};for(let i of U6){let o="bg"+i[0].toUpperCase()+i.slice(1);$v[o]={get(){let{level:a}=this;return function(...c){let _=A3(hy.bgColor[P6[a]][i](...c),hy.bgColor.close,this._styler);return v4(this,_,this._isEmpty)}}}}var rU=Object.defineProperties(()=>{},Zr(Ht({},$v),{level:{enumerable:!0,get(){return this._generator.level},set(i){this._generator.level=i}}})),A3=(i,o,a)=>{let c,_;return a===void 0?(c=i,_=o):(c=a.openAll+i,_=o+a.closeAll),{open:i,close:o,openAll:c,closeAll:_,parent:a}},v4=(i,o,a)=>{let c=(..._)=>p4(_[0])&&p4(_[0].raw)?j6(c,B6(c,..._)):j6(c,_.length===1?""+_[0]:_.join(" "));return Object.setPrototypeOf(c,rU),c._generator=i,c._styler=o,c._isEmpty=a,c},j6=(i,o)=>{if(i.level<=0||!o)return i._isEmpty?"":o;let a=i._styler;if(a===void 0)return o;let{openAll:c,closeAll:_}=a;if(o.indexOf("")!==-1)for(;a!==void 0;)o=eU(o,a.close,a.open),a=a.parent;let t=o.indexOf(` +`);return t!==-1&&(o=tU(o,_,c,t)),c+o+_},R3,B6=(i,...o)=>{let[a]=o;if(!p4(a)||!p4(a.raw))return o.join(" ");let c=o.slice(1),_=[a.raw[0]];for(let t=1;t{"use strict";var iU=vy&&vy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(vy,"__esModule",{value:!0});var my=iU(g4()),uU=/^(rgb|hsl|hsv|hwb)\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/,oU=/^(ansi|ansi256)\(\s?(\d+)\s?\)$/,y4=(i,o)=>o==="foreground"?i:"bg"+i[0].toUpperCase()+i.slice(1);vy.default=(i,o,a)=>{if(!o)return i;if(o in my.default){let _=y4(o,a);return my.default[_](i)}if(o.startsWith("#")){let _=y4("hex",a);return my.default[_](o)(i)}if(o.startsWith("ansi")){let _=oU.exec(o);if(!_)return i;let t=y4(_[1],a),O=Number(_[2]);return my.default[t](O)(i)}if(o.startsWith("rgb")||o.startsWith("hsl")||o.startsWith("hsv")||o.startsWith("hwb")){let _=uU.exec(o);if(!_)return i;let t=y4(_[1],a),O=Number(_[2]),N=Number(_[3]),M=Number(_[4]);return my.default[t](O,N,M)(i)}return i}});var H6=Ke(gy=>{"use strict";var z6=gy&&gy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(gy,"__esModule",{value:!0});var lU=z6(D6()),M3=z6(O3());gy.default=(i,o,a,c)=>{if(typeof a.style.borderStyle=="string"){let _=a.yogaNode.getComputedWidth(),t=a.yogaNode.getComputedHeight(),O=a.style.borderColor,N=lU.default[a.style.borderStyle],M=M3.default(N.topLeft+N.horizontal.repeat(_-2)+N.topRight,O,"foreground"),T=(M3.default(N.vertical,O,"foreground")+` +`).repeat(t-2),B=M3.default(N.bottomLeft+N.horizontal.repeat(_-2)+N.bottomRight,O,"foreground");c.write(i,o,M,{transformers:[]}),c.write(i,o+1,T,{transformers:[]}),c.write(i+_-1,o+1,T,{transformers:[]}),c.write(i,o+t-1,B,{transformers:[]})}}});var W6=Ke(yy=>{"use strict";var ih=yy&&yy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(yy,"__esModule",{value:!0});var sU=ih(eh()),aU=ih(VD()),fU=ih(m6()),cU=ih(e3()),dU=ih(g6()),pU=ih(n3()),hU=ih(H6()),vU=(i,o)=>{var a;let c=(a=i.childNodes[0])===null||a===void 0?void 0:a.yogaNode;if(c){let _=c.getComputedLeft(),t=c.getComputedTop();o=` +`.repeat(t)+fU.default(o,_)}return o},q6=(i,o,a)=>{var c;let{offsetX:_=0,offsetY:t=0,transformers:O=[],skipStaticElements:N}=a;if(N&&i.internal_static)return;let{yogaNode:M}=i;if(M){if(M.getDisplay()===sU.default.DISPLAY_NONE)return;let T=_+M.getComputedLeft(),B=t+M.getComputedTop(),H=O;if(typeof i.internal_transform=="function"&&(H=[i.internal_transform,...O]),i.nodeName==="ink-text"){let q=pU.default(i);if(q.length>0){let ne=aU.default(q),m=dU.default(M);if(ne>m){let he=(c=i.style.textWrap)!==null&&c!==void 0?c:"wrap";q=cU.default(q,m,he)}q=vU(i,q),o.write(T,B,q,{transformers:H})}return}if(i.nodeName==="ink-box"&&hU.default(T,B,i,o),i.nodeName==="ink-root"||i.nodeName==="ink-box")for(let q of i.childNodes)q6(q,o,{offsetX:T,offsetY:B,transformers:H,skipStaticElements:N})}};yy.default=q6});var G6=Ke((jV,V6)=>{"use strict";V6.exports=i=>{i=Object.assign({onlyFirst:!1},i);let o=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(o,i.onlyFirst?void 0:"g")}});var K6=Ke((zV,k3)=>{"use strict";var mU=G6(),Y6=i=>typeof i=="string"?i.replace(mU(),""):i;k3.exports=Y6;k3.exports.default=Y6});var J6=Ke((HV,X6)=>{"use strict";var Q6="[\uD800-\uDBFF][\uDC00-\uDFFF]";X6.exports=i=>i&&i.exact?new RegExp(`^${Q6}$`):new RegExp(Q6,"g")});var $6=Ke((qV,L3)=>{"use strict";var gU=K6(),yU=J6(),Z6=i=>gU(i).replace(yU()," ").length;L3.exports=Z6;L3.exports.default=Z6});var rx=Ke(_y=>{"use strict";var ex=_y&&_y.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(_y,"__esModule",{value:!0});var tx=ex(ZD()),_U=ex($6()),nx=class{constructor(o){this.writes=[];let{width:a,height:c}=o;this.width=a,this.height=c}write(o,a,c,_){let{transformers:t}=_;!c||this.writes.push({x:o,y:a,text:c,transformers:t})}get(){let o=[];for(let c=0;cc.trimRight()).join(` +`),height:o.length}}};_y.default=nx});var ox=Ke(Ey=>{"use strict";var N3=Ey&&Ey.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Ey,"__esModule",{value:!0});var EU=N3(eh()),ix=N3(W6()),ux=N3(rx());Ey.default=(i,o)=>{var a;if(i.yogaNode.setWidth(o),i.yogaNode){i.yogaNode.calculateLayout(void 0,void 0,EU.default.DIRECTION_LTR);let c=new ux.default({width:i.yogaNode.getComputedWidth(),height:i.yogaNode.getComputedHeight()});ix.default(i,c,{skipStaticElements:!0});let _;((a=i.staticNode)===null||a===void 0?void 0:a.yogaNode)&&(_=new ux.default({width:i.staticNode.yogaNode.getComputedWidth(),height:i.staticNode.yogaNode.getComputedHeight()}),ix.default(i.staticNode,_,{skipStaticElements:!1}));let{output:t,height:O}=c.get();return{output:t,outputHeight:O,staticOutput:_?`${_.get().output} +`:""}}return{output:"",outputHeight:0,staticOutput:""}}});var fx=Ke((GV,lx)=>{"use strict";var sx=require("stream"),ax=["assert","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"],F3={},DU=i=>{let o=new sx.PassThrough,a=new sx.PassThrough;o.write=_=>i("stdout",_),a.write=_=>i("stderr",_);let c=new console.Console(o,a);for(let _ of ax)F3[_]=console[_],console[_]=c[_];return()=>{for(let _ of ax)console[_]=F3[_];F3={}}};lx.exports=DU});var I3=Ke(P3=>{"use strict";Object.defineProperty(P3,"__esModule",{value:!0});P3.default=new WeakMap});var B3=Ke(b3=>{"use strict";Object.defineProperty(b3,"__esModule",{value:!0});var wU=ki(),cx=wU.createContext({exit:()=>{}});cx.displayName="InternalAppContext";b3.default=cx});var j3=Ke(U3=>{"use strict";Object.defineProperty(U3,"__esModule",{value:!0});var SU=ki(),dx=SU.createContext({stdin:void 0,setRawMode:()=>{},isRawModeSupported:!1,internal_exitOnCtrlC:!0});dx.displayName="InternalStdinContext";U3.default=dx});var H3=Ke(z3=>{"use strict";Object.defineProperty(z3,"__esModule",{value:!0});var TU=ki(),px=TU.createContext({stdout:void 0,write:()=>{}});px.displayName="InternalStdoutContext";z3.default=px});var W3=Ke(q3=>{"use strict";Object.defineProperty(q3,"__esModule",{value:!0});var CU=ki(),hx=CU.createContext({stderr:void 0,write:()=>{}});hx.displayName="InternalStderrContext";q3.default=hx});var _4=Ke(V3=>{"use strict";Object.defineProperty(V3,"__esModule",{value:!0});var xU=ki(),vx=xU.createContext({activeId:void 0,add:()=>{},remove:()=>{},activate:()=>{},deactivate:()=>{},enableFocus:()=>{},disableFocus:()=>{},focusNext:()=>{},focusPrevious:()=>{}});vx.displayName="InternalFocusContext";V3.default=vx});var gx=Ke(($V,mx)=>{"use strict";var AU=/[|\\{}()[\]^$+*?.-]/g;mx.exports=i=>{if(typeof i!="string")throw new TypeError("Expected a string");return i.replace(AU,"\\$&")}});var Dx=Ke((eG,yx)=>{"use strict";var RU=gx(),_x=[].concat(require("module").builtinModules,"bootstrap_node","node").map(i=>new RegExp(`(?:\\(${i}\\.js:\\d+:\\d+\\)$|^\\s*at ${i}\\.js:\\d+:\\d+$)`));_x.push(/\(internal\/[^:]+:\d+:\d+\)$/,/\s*at internal\/[^:]+:\d+:\d+$/,/\/\.node-spawn-wrap-\w+-\w+\/node:\d+:\d+\)?$/);var E4=class{constructor(o){o=Ht({ignoredPackages:[]},o),"internals"in o||(o.internals=E4.nodeInternals()),"cwd"in o||(o.cwd=process.cwd()),this._cwd=o.cwd.replace(/\\/g,"/"),this._internals=[].concat(o.internals,OU(o.ignoredPackages)),this._wrapCallSite=o.wrapCallSite||!1}static nodeInternals(){return[..._x]}clean(o,a=0){a=" ".repeat(a),Array.isArray(o)||(o=o.split(` +`)),!/^\s*at /.test(o[0])&&/^\s*at /.test(o[1])&&(o=o.slice(1));let c=!1,_=null,t=[];return o.forEach(O=>{if(O=O.replace(/\\/g,"/"),this._internals.some(M=>M.test(O)))return;let N=/^\s*at /.test(O);c?O=O.trimEnd().replace(/^(\s+)at /,"$1"):(O=O.trim(),N&&(O=O.slice(3))),O=O.replace(`${this._cwd}/`,""),O&&(N?(_&&(t.push(_),_=null),t.push(O)):(c=!0,_=O))}),t.map(O=>`${a}${O} +`).join("")}captureString(o,a=this.captureString){typeof o=="function"&&(a=o,o=Infinity);let{stackTraceLimit:c}=Error;o&&(Error.stackTraceLimit=o);let _={};Error.captureStackTrace(_,a);let{stack:t}=_;return Error.stackTraceLimit=c,this.clean(t)}capture(o,a=this.capture){typeof o=="function"&&(a=o,o=Infinity);let{prepareStackTrace:c,stackTraceLimit:_}=Error;Error.prepareStackTrace=(N,M)=>this._wrapCallSite?M.map(this._wrapCallSite):M,o&&(Error.stackTraceLimit=o);let t={};Error.captureStackTrace(t,a);let{stack:O}=t;return Object.assign(Error,{prepareStackTrace:c,stackTraceLimit:_}),O}at(o=this.at){let[a]=this.capture(1,o);if(!a)return{};let c={line:a.getLineNumber(),column:a.getColumnNumber()};Ex(c,a.getFileName(),this._cwd),a.isConstructor()&&(c.constructor=!0),a.isEval()&&(c.evalOrigin=a.getEvalOrigin()),a.isNative()&&(c.native=!0);let _;try{_=a.getTypeName()}catch(N){}_&&_!=="Object"&&_!=="[object Object]"&&(c.type=_);let t=a.getFunctionName();t&&(c.function=t);let O=a.getMethodName();return O&&t!==O&&(c.method=O),c}parseLine(o){let a=o&&o.match(MU);if(!a)return null;let c=a[1]==="new",_=a[2],t=a[3],O=a[4],N=Number(a[5]),M=Number(a[6]),T=a[7],B=a[8],H=a[9],q=a[10]==="native",ne=a[11]===")",m,he={};if(B&&(he.line=Number(B)),H&&(he.column=Number(H)),ne&&T){let De=0;for(let se=T.length-1;se>0;se--)if(T.charAt(se)===")")De++;else if(T.charAt(se)==="("&&T.charAt(se-1)===" "&&(De--,De===-1&&T.charAt(se-1)===" ")){let fe=T.slice(0,se-1);T=T.slice(se+1),_+=` (${fe}`;break}}if(_){let De=_.match(kU);De&&(_=De[1],m=De[2])}return Ex(he,T,this._cwd),c&&(he.constructor=!0),t&&(he.evalOrigin=t,he.evalLine=N,he.evalColumn=M,he.evalFile=O&&O.replace(/\\/g,"/")),q&&(he.native=!0),_&&(he.function=_),m&&_!==m&&(he.method=m),he}};function Ex(i,o,a){o&&(o=o.replace(/\\/g,"/"),o.startsWith(`${a}/`)&&(o=o.slice(a.length+1)),i.file=o)}function OU(i){if(i.length===0)return[];let o=i.map(a=>RU(a));return new RegExp(`[/\\\\]node_modules[/\\\\](?:${o.join("|")})[/\\\\][^:]+:\\d+:\\d+`)}var MU=new RegExp("^(?:\\s*at )?(?:(new) )?(?:(.*?) \\()?(?:eval at ([^ ]+) \\((.+?):(\\d+):(\\d+)\\), )?(?:(.+?):(\\d+):(\\d+)|(native))(\\)?)$"),kU=/^(.*?) \[as (.*?)\]$/;yx.exports=E4});var Sx=Ke((tG,wx)=>{"use strict";wx.exports=(i,o)=>i.replace(/^\t+/gm,a=>" ".repeat(a.length*(o||2)))});var Cx=Ke((nG,Tx)=>{"use strict";var LU=Sx(),NU=(i,o)=>{let a=[],c=i-o,_=i+o;for(let t=c;t<=_;t++)a.push(t);return a};Tx.exports=(i,o,a)=>{if(typeof i!="string")throw new TypeError("Source code is missing.");if(!o||o<1)throw new TypeError("Line number must start from `1`.");if(i=LU(i).split(/\r?\n/),!(o>i.length))return a=Ht({around:3},a),NU(o,a.around).filter(c=>i[c-1]!==void 0).map(c=>({line:c,value:i[c-1]}))}});var D4=Ke(rc=>{"use strict";var FU=rc&&rc.__createBinding||(Object.create?function(i,o,a,c){c===void 0&&(c=a),Object.defineProperty(i,c,{enumerable:!0,get:function(){return o[a]}})}:function(i,o,a,c){c===void 0&&(c=a),i[c]=o[a]}),PU=rc&&rc.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),IU=rc&&rc.__importStar||function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var a in i)a!=="default"&&Object.hasOwnProperty.call(i,a)&&FU(o,i,a);return PU(o,i),o},bU=rc&&rc.__rest||function(i,o){var a={};for(var c in i)Object.prototype.hasOwnProperty.call(i,c)&&o.indexOf(c)<0&&(a[c]=i[c]);if(i!=null&&typeof Object.getOwnPropertySymbols=="function")for(var _=0,c=Object.getOwnPropertySymbols(i);_{var{children:a}=i,c=bU(i,["children"]);let _=Object.assign(Object.assign({},c),{marginLeft:c.marginLeft||c.marginX||c.margin||0,marginRight:c.marginRight||c.marginX||c.margin||0,marginTop:c.marginTop||c.marginY||c.margin||0,marginBottom:c.marginBottom||c.marginY||c.margin||0,paddingLeft:c.paddingLeft||c.paddingX||c.padding||0,paddingRight:c.paddingRight||c.paddingX||c.padding||0,paddingTop:c.paddingTop||c.paddingY||c.padding||0,paddingBottom:c.paddingBottom||c.paddingY||c.padding||0});return xx.default.createElement("ink-box",{ref:o,style:_},a)});G3.displayName="Box";G3.defaultProps={flexDirection:"row",flexGrow:0,flexShrink:1};rc.default=G3});var X3=Ke(Dy=>{"use strict";var Y3=Dy&&Dy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Dy,"__esModule",{value:!0});var BU=Y3(ki()),em=Y3(g4()),Ax=Y3(O3()),K3=({color:i,backgroundColor:o,dimColor:a,bold:c,italic:_,underline:t,strikethrough:O,inverse:N,wrap:M,children:T})=>{if(T==null)return null;let B=H=>(a&&(H=em.default.dim(H)),i&&(H=Ax.default(H,i,"foreground")),o&&(H=Ax.default(H,o,"background")),c&&(H=em.default.bold(H)),_&&(H=em.default.italic(H)),t&&(H=em.default.underline(H)),O&&(H=em.default.strikethrough(H)),N&&(H=em.default.inverse(H)),H);return BU.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row",textWrap:M},internal_transform:B},T)};K3.displayName="Text";K3.defaultProps={dimColor:!1,bold:!1,italic:!1,underline:!1,strikethrough:!1,wrap:"wrap"};Dy.default=K3});var kx=Ke(ic=>{"use strict";var UU=ic&&ic.__createBinding||(Object.create?function(i,o,a,c){c===void 0&&(c=a),Object.defineProperty(i,c,{enumerable:!0,get:function(){return o[a]}})}:function(i,o,a,c){c===void 0&&(c=a),i[c]=o[a]}),jU=ic&&ic.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),zU=ic&&ic.__importStar||function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var a in i)a!=="default"&&Object.hasOwnProperty.call(i,a)&&UU(o,i,a);return jU(o,i),o},wy=ic&&ic.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(ic,"__esModule",{value:!0});var Rx=zU(require("fs")),Qo=wy(ki()),Ox=wy(Dx()),HU=wy(Cx()),$1=wy(D4()),Hc=wy(X3()),Mx=new Ox.default({cwd:process.cwd(),internals:Ox.default.nodeInternals()}),qU=({error:i})=>{let o=i.stack?i.stack.split(` +`).slice(1):void 0,a=o?Mx.parseLine(o[0]):void 0,c,_=0;if((a==null?void 0:a.file)&&(a==null?void 0:a.line)&&Rx.existsSync(a.file)){let t=Rx.readFileSync(a.file,"utf8");if(c=HU.default(t,a.line),c)for(let{line:O}of c)_=Math.max(_,String(O).length)}return Qo.default.createElement($1.default,{flexDirection:"column",padding:1},Qo.default.createElement($1.default,null,Qo.default.createElement(Hc.default,{backgroundColor:"red",color:"white"}," ","ERROR"," "),Qo.default.createElement(Hc.default,null," ",i.message)),a&&Qo.default.createElement($1.default,{marginTop:1},Qo.default.createElement(Hc.default,{dimColor:!0},a.file,":",a.line,":",a.column)),a&&c&&Qo.default.createElement($1.default,{marginTop:1,flexDirection:"column"},c.map(({line:t,value:O})=>Qo.default.createElement($1.default,{key:t},Qo.default.createElement($1.default,{width:_+1},Qo.default.createElement(Hc.default,{dimColor:t!==a.line,backgroundColor:t===a.line?"red":void 0,color:t===a.line?"white":void 0},String(t).padStart(_," "),":")),Qo.default.createElement(Hc.default,{key:t,backgroundColor:t===a.line?"red":void 0,color:t===a.line?"white":void 0}," "+O)))),i.stack&&Qo.default.createElement($1.default,{marginTop:1,flexDirection:"column"},i.stack.split(` +`).slice(1).map(t=>{let O=Mx.parseLine(t);return O?Qo.default.createElement($1.default,{key:t},Qo.default.createElement(Hc.default,{dimColor:!0},"- "),Qo.default.createElement(Hc.default,{dimColor:!0,bold:!0},O.function),Qo.default.createElement(Hc.default,{dimColor:!0,color:"gray"}," ","(",O.file,":",O.line,":",O.column,")")):Qo.default.createElement($1.default,{key:t},Qo.default.createElement(Hc.default,{dimColor:!0},"- "),Qo.default.createElement(Hc.default,{dimColor:!0,bold:!0},t))})))};ic.default=qU});var Nx=Ke(uc=>{"use strict";var WU=uc&&uc.__createBinding||(Object.create?function(i,o,a,c){c===void 0&&(c=a),Object.defineProperty(i,c,{enumerable:!0,get:function(){return o[a]}})}:function(i,o,a,c){c===void 0&&(c=a),i[c]=o[a]}),VU=uc&&uc.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),GU=uc&&uc.__importStar||function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var a in i)a!=="default"&&Object.hasOwnProperty.call(i,a)&&WU(o,i,a);return VU(o,i),o},uh=uc&&uc.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(uc,"__esModule",{value:!0});var oh=GU(ki()),Lx=uh(wD()),YU=uh(B3()),KU=uh(j3()),XU=uh(H3()),QU=uh(W3()),JU=uh(_4()),ZU=uh(kx()),$U=" ",ej="",tj="",Q3=class extends oh.PureComponent{constructor(){super(...arguments);this.state={isFocusEnabled:!0,activeFocusId:void 0,focusables:[],error:void 0},this.rawModeEnabledCount=0,this.handleSetRawMode=o=>{let{stdin:a}=this.props;if(!this.isRawModeSupported())throw a===process.stdin?new Error(`Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default. +Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`):new Error(`Raw mode is not supported on the stdin provided to Ink. +Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`);if(a.setEncoding("utf8"),o){this.rawModeEnabledCount===0&&(a.addListener("data",this.handleInput),a.resume(),a.setRawMode(!0)),this.rawModeEnabledCount++;return}--this.rawModeEnabledCount==0&&(a.setRawMode(!1),a.removeListener("data",this.handleInput),a.pause())},this.handleInput=o=>{o===""&&this.props.exitOnCtrlC&&this.handleExit(),o===tj&&this.state.activeFocusId&&this.setState({activeFocusId:void 0}),this.state.isFocusEnabled&&this.state.focusables.length>0&&(o===$U&&this.focusNext(),o===ej&&this.focusPrevious())},this.handleExit=o=>{this.isRawModeSupported()&&this.handleSetRawMode(!1),this.props.onExit(o)},this.enableFocus=()=>{this.setState({isFocusEnabled:!0})},this.disableFocus=()=>{this.setState({isFocusEnabled:!1})},this.focusNext=()=>{this.setState(o=>{let a=o.focusables[0].id;return{activeFocusId:this.findNextFocusable(o)||a}})},this.focusPrevious=()=>{this.setState(o=>{let a=o.focusables[o.focusables.length-1].id;return{activeFocusId:this.findPreviousFocusable(o)||a}})},this.addFocusable=(o,{autoFocus:a})=>{this.setState(c=>{let _=c.activeFocusId;return!_&&a&&(_=o),{activeFocusId:_,focusables:[...c.focusables,{id:o,isActive:!0}]}})},this.removeFocusable=o=>{this.setState(a=>({activeFocusId:a.activeFocusId===o?void 0:a.activeFocusId,focusables:a.focusables.filter(c=>c.id!==o)}))},this.activateFocusable=o=>{this.setState(a=>({focusables:a.focusables.map(c=>c.id!==o?c:{id:o,isActive:!0})}))},this.deactivateFocusable=o=>{this.setState(a=>({activeFocusId:a.activeFocusId===o?void 0:a.activeFocusId,focusables:a.focusables.map(c=>c.id!==o?c:{id:o,isActive:!1})}))},this.findNextFocusable=o=>{let a=o.focusables.findIndex(c=>c.id===o.activeFocusId);for(let c=a+1;c{let a=o.focusables.findIndex(c=>c.id===o.activeFocusId);for(let c=a-1;c>=0;c--)if(o.focusables[c].isActive)return o.focusables[c].id}}static getDerivedStateFromError(o){return{error:o}}isRawModeSupported(){return this.props.stdin.isTTY}render(){return oh.default.createElement(YU.default.Provider,{value:{exit:this.handleExit}},oh.default.createElement(KU.default.Provider,{value:{stdin:this.props.stdin,setRawMode:this.handleSetRawMode,isRawModeSupported:this.isRawModeSupported(),internal_exitOnCtrlC:this.props.exitOnCtrlC}},oh.default.createElement(XU.default.Provider,{value:{stdout:this.props.stdout,write:this.props.writeToStdout}},oh.default.createElement(QU.default.Provider,{value:{stderr:this.props.stderr,write:this.props.writeToStderr}},oh.default.createElement(JU.default.Provider,{value:{activeId:this.state.activeFocusId,add:this.addFocusable,remove:this.removeFocusable,activate:this.activateFocusable,deactivate:this.deactivateFocusable,enableFocus:this.enableFocus,disableFocus:this.disableFocus,focusNext:this.focusNext,focusPrevious:this.focusPrevious}},this.state.error?oh.default.createElement(ZU.default,{error:this.state.error}):this.props.children)))))}componentDidMount(){Lx.default.hide(this.props.stdout)}componentWillUnmount(){Lx.default.show(this.props.stdout),this.isRawModeSupported()&&this.handleSetRawMode(!1)}componentDidCatch(o){this.handleExit(o)}};uc.default=Q3;Q3.displayName="InternalApp"});var bx=Ke(oc=>{"use strict";var nj=oc&&oc.__createBinding||(Object.create?function(i,o,a,c){c===void 0&&(c=a),Object.defineProperty(i,c,{enumerable:!0,get:function(){return o[a]}})}:function(i,o,a,c){c===void 0&&(c=a),i[c]=o[a]}),rj=oc&&oc.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),ij=oc&&oc.__importStar||function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var a in i)a!=="default"&&Object.hasOwnProperty.call(i,a)&&nj(o,i,a);return rj(o,i),o},lc=oc&&oc.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(oc,"__esModule",{value:!0});var uj=lc(ki()),Fx=MS(),oj=lc(VS()),lj=lc(mD()),sj=lc(ZS()),aj=lc(eT()),w4=lc(h6()),fj=lc(ox()),cj=lc(DD()),dj=lc(fx()),pj=ij(r3()),hj=lc(I3()),vj=lc(Nx()),tm=process.env.CI==="false"?!1:sj.default,Px=()=>{},Ix=class{constructor(o){this.resolveExitPromise=()=>{},this.rejectExitPromise=()=>{},this.unsubscribeExit=()=>{},this.onRender=()=>{if(this.isUnmounted)return;let{output:a,outputHeight:c,staticOutput:_}=fj.default(this.rootNode,this.options.stdout.columns||80),t=_&&_!==` +`;if(this.options.debug){t&&(this.fullStaticOutput+=_),this.options.stdout.write(this.fullStaticOutput+a);return}if(tm){t&&this.options.stdout.write(_),this.lastOutput=a;return}if(t&&(this.fullStaticOutput+=_),c>=this.options.stdout.rows){this.options.stdout.write(lj.default.clearTerminal+this.fullStaticOutput+a),this.lastOutput=a;return}t&&(this.log.clear(),this.options.stdout.write(_),this.log(a)),!t&&a!==this.lastOutput&&this.throttledLog(a),this.lastOutput=a},aj.default(this),this.options=o,this.rootNode=pj.createNode("ink-root"),this.rootNode.onRender=o.debug?this.onRender:Fx.throttle(this.onRender,32,{leading:!0,trailing:!0}),this.rootNode.onImmediateRender=this.onRender,this.log=oj.default.create(o.stdout),this.throttledLog=o.debug?this.log:Fx.throttle(this.log,void 0,{leading:!0,trailing:!0}),this.isUnmounted=!1,this.lastOutput="",this.fullStaticOutput="",this.container=w4.default.createContainer(this.rootNode,!1,!1),this.unsubscribeExit=cj.default(this.unmount,{alwaysLast:!1}),process.env.DEV==="true"&&w4.default.injectIntoDevTools({bundleType:0,version:"16.13.1",rendererPackageName:"ink"}),o.patchConsole&&this.patchConsole(),tm||(o.stdout.on("resize",this.onRender),this.unsubscribeResize=()=>{o.stdout.off("resize",this.onRender)})}render(o){let a=uj.default.createElement(vj.default,{stdin:this.options.stdin,stdout:this.options.stdout,stderr:this.options.stderr,writeToStdout:this.writeToStdout,writeToStderr:this.writeToStderr,exitOnCtrlC:this.options.exitOnCtrlC,onExit:this.unmount},o);w4.default.updateContainer(a,this.container,null,Px)}writeToStdout(o){if(!this.isUnmounted){if(this.options.debug){this.options.stdout.write(o+this.fullStaticOutput+this.lastOutput);return}if(tm){this.options.stdout.write(o);return}this.log.clear(),this.options.stdout.write(o),this.log(this.lastOutput)}}writeToStderr(o){if(!this.isUnmounted){if(this.options.debug){this.options.stderr.write(o),this.options.stdout.write(this.fullStaticOutput+this.lastOutput);return}if(tm){this.options.stderr.write(o);return}this.log.clear(),this.options.stderr.write(o),this.log(this.lastOutput)}}unmount(o){this.isUnmounted||(this.onRender(),this.unsubscribeExit(),typeof this.restoreConsole=="function"&&this.restoreConsole(),typeof this.unsubscribeResize=="function"&&this.unsubscribeResize(),tm?this.options.stdout.write(this.lastOutput+` +`):this.options.debug||this.log.done(),this.isUnmounted=!0,w4.default.updateContainer(null,this.container,null,Px),hj.default.delete(this.options.stdout),o instanceof Error?this.rejectExitPromise(o):this.resolveExitPromise())}waitUntilExit(){return this.exitPromise||(this.exitPromise=new Promise((o,a)=>{this.resolveExitPromise=o,this.rejectExitPromise=a})),this.exitPromise}clear(){!tm&&!this.options.debug&&this.log.clear()}patchConsole(){this.options.debug||(this.restoreConsole=dj.default((o,a)=>{o==="stdout"&&this.writeToStdout(a),o==="stderr"&&(a.startsWith("The above error occurred")||this.writeToStderr(a))}))}};oc.default=Ix});var Ux=Ke(Sy=>{"use strict";var Bx=Sy&&Sy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Sy,"__esModule",{value:!0});var mj=Bx(bx()),S4=Bx(I3()),gj=require("stream"),Ej=(i,o)=>{let a=Object.assign({stdout:process.stdout,stdin:process.stdin,stderr:process.stderr,debug:!1,exitOnCtrlC:!0,patchConsole:!0},yj(o)),c=_j(a.stdout,()=>new mj.default(a));return c.render(i),{rerender:c.render,unmount:()=>c.unmount(),waitUntilExit:c.waitUntilExit,cleanup:()=>S4.default.delete(a.stdout),clear:c.clear}};Sy.default=Ej;var yj=(i={})=>i instanceof gj.Stream?{stdout:i,stdin:process.stdin}:i,_j=(i,o)=>{let a;return S4.default.has(i)?a=S4.default.get(i):(a=o(),S4.default.set(i,a)),a}});var zx=Ke(ed=>{"use strict";var Dj=ed&&ed.__createBinding||(Object.create?function(i,o,a,c){c===void 0&&(c=a),Object.defineProperty(i,c,{enumerable:!0,get:function(){return o[a]}})}:function(i,o,a,c){c===void 0&&(c=a),i[c]=o[a]}),wj=ed&&ed.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),Sj=ed&&ed.__importStar||function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var a in i)a!=="default"&&Object.hasOwnProperty.call(i,a)&&Dj(o,i,a);return wj(o,i),o};Object.defineProperty(ed,"__esModule",{value:!0});var Ty=Sj(ki()),jx=i=>{let{items:o,children:a,style:c}=i,[_,t]=Ty.useState(0),O=Ty.useMemo(()=>o.slice(_),[o,_]);Ty.useLayoutEffect(()=>{t(o.length)},[o.length]);let N=O.map((T,B)=>a(T,_+B)),M=Ty.useMemo(()=>Object.assign({position:"absolute",flexDirection:"column"},c),[c]);return Ty.default.createElement("ink-box",{internal_static:!0,style:M},N)};jx.displayName="Static";ed.default=jx});var qx=Ke(Cy=>{"use strict";var Tj=Cy&&Cy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Cy,"__esModule",{value:!0});var Cj=Tj(ki()),Hx=({children:i,transform:o})=>i==null?null:Cj.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row"},internal_transform:o},i);Hx.displayName="Transform";Cy.default=Hx});var Vx=Ke(xy=>{"use strict";var xj=xy&&xy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(xy,"__esModule",{value:!0});var Aj=xj(ki()),Wx=({count:i=1})=>Aj.default.createElement("ink-text",null,` +`.repeat(i));Wx.displayName="Newline";xy.default=Wx});var Kx=Ke(Ay=>{"use strict";var Gx=Ay&&Ay.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Ay,"__esModule",{value:!0});var Rj=Gx(ki()),Oj=Gx(D4()),Yx=()=>Rj.default.createElement(Oj.default,{flexGrow:1});Yx.displayName="Spacer";Ay.default=Yx});var T4=Ke(Ry=>{"use strict";var Mj=Ry&&Ry.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Ry,"__esModule",{value:!0});var kj=ki(),Lj=Mj(j3()),Nj=()=>kj.useContext(Lj.default);Ry.default=Nj});var Qx=Ke(Oy=>{"use strict";var Fj=Oy&&Oy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Oy,"__esModule",{value:!0});var Xx=ki(),Pj=Fj(T4()),Ij=(i,o={})=>{let{stdin:a,setRawMode:c,internal_exitOnCtrlC:_}=Pj.default();Xx.useEffect(()=>{if(o.isActive!==!1)return c(!0),()=>{c(!1)}},[o.isActive,c]),Xx.useEffect(()=>{if(o.isActive===!1)return;let t=O=>{let N=String(O),M={upArrow:N==="",downArrow:N==="",leftArrow:N==="",rightArrow:N==="",pageDown:N==="[6~",pageUp:N==="[5~",return:N==="\r",escape:N==="",ctrl:!1,shift:!1,tab:N===" "||N==="",backspace:N==="\b",delete:N==="\x7F"||N==="[3~",meta:!1};N<=""&&!M.return&&(N=String.fromCharCode(N.charCodeAt(0)+"a".charCodeAt(0)-1),M.ctrl=!0),N.startsWith("")&&(N=N.slice(1),M.meta=!0);let T=N>="A"&&N<="Z",B=N>="\u0410"&&N<="\u042F";N.length===1&&(T||B)&&(M.shift=!0),M.tab&&N==="[Z"&&(M.shift=!0),(M.tab||M.backspace||M.delete)&&(N=""),(!(N==="c"&&M.ctrl)||!_)&&i(N,M)};return a==null||a.on("data",t),()=>{a==null||a.off("data",t)}},[o.isActive,a,_,i])};Oy.default=Ij});var Jx=Ke(My=>{"use strict";var bj=My&&My.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(My,"__esModule",{value:!0});var Bj=ki(),Uj=bj(B3()),jj=()=>Bj.useContext(Uj.default);My.default=jj});var Zx=Ke(ky=>{"use strict";var zj=ky&&ky.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(ky,"__esModule",{value:!0});var Hj=ki(),qj=zj(H3()),Wj=()=>Hj.useContext(qj.default);ky.default=Wj});var $x=Ke(Ly=>{"use strict";var Vj=Ly&&Ly.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Ly,"__esModule",{value:!0});var Gj=ki(),Yj=Vj(W3()),Kj=()=>Gj.useContext(Yj.default);Ly.default=Kj});var t5=Ke(Ny=>{"use strict";var e5=Ny&&Ny.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Ny,"__esModule",{value:!0});var Fy=ki(),Xj=e5(_4()),Qj=e5(T4()),Jj=({isActive:i=!0,autoFocus:o=!1}={})=>{let{isRawModeSupported:a,setRawMode:c}=Qj.default(),{activeId:_,add:t,remove:O,activate:N,deactivate:M}=Fy.useContext(Xj.default),T=Fy.useMemo(()=>Math.random().toString().slice(2,7),[]);return Fy.useEffect(()=>(t(T,{autoFocus:o}),()=>{O(T)}),[T,o]),Fy.useEffect(()=>{i?N(T):M(T)},[i,T]),Fy.useEffect(()=>{if(!(!a||!i))return c(!0),()=>{c(!1)}},[i]),{isFocused:Boolean(T)&&_===T}};Ny.default=Jj});var n5=Ke(Py=>{"use strict";var Zj=Py&&Py.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Py,"__esModule",{value:!0});var $j=ki(),ez=Zj(_4()),tz=()=>{let i=$j.useContext(ez.default);return{enableFocus:i.enableFocus,disableFocus:i.disableFocus,focusNext:i.focusNext,focusPrevious:i.focusPrevious}};Py.default=tz});var r5=Ke(J3=>{"use strict";Object.defineProperty(J3,"__esModule",{value:!0});J3.default=i=>{var o,a,c,_;return{width:(a=(o=i.yogaNode)===null||o===void 0?void 0:o.getComputedWidth())!==null&&a!==void 0?a:0,height:(_=(c=i.yogaNode)===null||c===void 0?void 0:c.getComputedHeight())!==null&&_!==void 0?_:0}}});var sc=Ke(Kl=>{"use strict";Object.defineProperty(Kl,"__esModule",{value:!0});var nz=Ux();Object.defineProperty(Kl,"render",{enumerable:!0,get:function(){return nz.default}});var rz=D4();Object.defineProperty(Kl,"Box",{enumerable:!0,get:function(){return rz.default}});var iz=X3();Object.defineProperty(Kl,"Text",{enumerable:!0,get:function(){return iz.default}});var uz=zx();Object.defineProperty(Kl,"Static",{enumerable:!0,get:function(){return uz.default}});var oz=qx();Object.defineProperty(Kl,"Transform",{enumerable:!0,get:function(){return oz.default}});var lz=Vx();Object.defineProperty(Kl,"Newline",{enumerable:!0,get:function(){return lz.default}});var sz=Kx();Object.defineProperty(Kl,"Spacer",{enumerable:!0,get:function(){return sz.default}});var az=Qx();Object.defineProperty(Kl,"useInput",{enumerable:!0,get:function(){return az.default}});var fz=Jx();Object.defineProperty(Kl,"useApp",{enumerable:!0,get:function(){return fz.default}});var cz=T4();Object.defineProperty(Kl,"useStdin",{enumerable:!0,get:function(){return cz.default}});var dz=Zx();Object.defineProperty(Kl,"useStdout",{enumerable:!0,get:function(){return dz.default}});var pz=$x();Object.defineProperty(Kl,"useStderr",{enumerable:!0,get:function(){return pz.default}});var hz=t5();Object.defineProperty(Kl,"useFocus",{enumerable:!0,get:function(){return hz.default}});var vz=n5();Object.defineProperty(Kl,"useFocusManager",{enumerable:!0,get:function(){return vz.default}});var mz=r5();Object.defineProperty(Kl,"measureElement",{enumerable:!0,get:function(){return mz.default}})});var p5=Ke(Iy=>{"use strict";Object.defineProperty(Iy,"__esModule",{value:!0});Iy.UncontrolledTextInput=void 0;var f5=ki(),ew=ki(),c5=sc(),ah=g4(),d5=({value:i,placeholder:o="",focus:a=!0,mask:c,highlightPastedText:_=!1,showCursor:t=!0,onChange:O,onSubmit:N})=>{let[{cursorOffset:M,cursorWidth:T},B]=ew.useState({cursorOffset:(i||"").length,cursorWidth:0});ew.useEffect(()=>{B(he=>{if(!a||!t)return he;let De=i||"";return he.cursorOffset>De.length-1?{cursorOffset:De.length,cursorWidth:0}:he})},[i,a,t]);let H=_?T:0,q=c?c.repeat(i.length):i,ne=q,m=o?ah.grey(o):void 0;if(t&&a){m=o.length>0?ah.inverse(o[0])+ah.grey(o.slice(1)):ah.inverse(" "),ne=q.length>0?"":ah.inverse(" ");let he=0;for(let De of q)he>=M-H&&he<=M?ne+=ah.inverse(De):ne+=De,he++;q.length>0&&M===q.length&&(ne+=ah.inverse(" "))}return c5.useInput((he,De)=>{if(De.upArrow||De.downArrow||De.ctrl&&he==="c"||De.tab||De.shift&&De.tab)return;if(De.return){N&&N(i);return}let se=M,fe=i,_e=0;De.leftArrow?t&&se--:De.rightArrow?t&&se++:De.backspace||De.delete?M>0&&(fe=i.slice(0,M-1)+i.slice(M,i.length),se--):(fe=i.slice(0,M)+he+i.slice(M,i.length),se+=he.length,he.length>1&&(_e=he.length)),M<0&&(se=0),M>i.length&&(se=i.length),B({cursorOffset:se,cursorWidth:_e}),fe!==i&&O(fe)},{isActive:a}),f5.createElement(c5.Text,null,o?q.length>0?ne:m:ne)};Iy.default=d5;Iy.UncontrolledTextInput=i=>{let[o,a]=ew.useState("");return f5.createElement(d5,Object.assign({},i,{value:o,onChange:a}))}});var v5=Ke(N4=>{"use strict";Object.defineProperty(N4,"__esModule",{value:!0});function by(i){let o=[...i.caches],a=o.shift();return a===void 0?h5():{get(c,_,t={miss:()=>Promise.resolve()}){return a.get(c,_,t).catch(()=>by({caches:o}).get(c,_,t))},set(c,_){return a.set(c,_).catch(()=>by({caches:o}).set(c,_))},delete(c){return a.delete(c).catch(()=>by({caches:o}).delete(c))},clear(){return a.clear().catch(()=>by({caches:o}).clear())}}}function h5(){return{get(i,o,a={miss:()=>Promise.resolve()}){return o().then(_=>Promise.all([_,a.miss(_)])).then(([_])=>_)},set(i,o){return Promise.resolve(o)},delete(i){return Promise.resolve()},clear(){return Promise.resolve()}}}N4.createFallbackableCache=by;N4.createNullCache=h5});var g5=Ke((jG,m5)=>{m5.exports=v5()});var y5=Ke(tw=>{"use strict";Object.defineProperty(tw,"__esModule",{value:!0});function gz(i={serializable:!0}){let o={};return{get(a,c,_={miss:()=>Promise.resolve()}){let t=JSON.stringify(a);if(t in o)return Promise.resolve(i.serializable?JSON.parse(o[t]):o[t]);let O=c(),N=_&&_.miss||(()=>Promise.resolve());return O.then(M=>N(M)).then(()=>O)},set(a,c){return o[JSON.stringify(a)]=i.serializable?JSON.stringify(c):c,Promise.resolve(c)},delete(a){return delete o[JSON.stringify(a)],Promise.resolve()},clear(){return o={},Promise.resolve()}}}tw.createInMemoryCache=gz});var E5=Ke((HG,_5)=>{_5.exports=y5()});var w5=Ke(ac=>{"use strict";Object.defineProperty(ac,"__esModule",{value:!0});function yz(i,o,a){let c={"x-algolia-api-key":a,"x-algolia-application-id":o};return{headers(){return i===nw.WithinHeaders?c:{}},queryParameters(){return i===nw.WithinQueryParameters?c:{}}}}function _z(i){let o=0,a=()=>(o++,new Promise(c=>{setTimeout(()=>{c(i(a))},Math.min(100*o,1e3))}));return i(a)}function D5(i,o=(a,c)=>Promise.resolve()){return Object.assign(i,{wait(a){return D5(i.then(c=>Promise.all([o(c,a),c])).then(c=>c[1]))}})}function Ez(i){let o=i.length-1;for(o;o>0;o--){let a=Math.floor(Math.random()*(o+1)),c=i[o];i[o]=i[a],i[a]=c}return i}function Dz(i,o){return Object.keys(o!==void 0?o:{}).forEach(a=>{i[a]=o[a](i)}),i}function wz(i,...o){let a=0;return i.replace(/%s/g,()=>encodeURIComponent(o[a++]))}var Sz="4.2.0",Tz=i=>()=>i.transporter.requester.destroy(),nw={WithinQueryParameters:0,WithinHeaders:1};ac.AuthMode=nw;ac.addMethods=Dz;ac.createAuth=yz;ac.createRetryablePromise=_z;ac.createWaitablePromise=D5;ac.destroy=Tz;ac.encode=wz;ac.shuffle=Ez;ac.version=Sz});var By=Ke((WG,S5)=>{S5.exports=w5()});var T5=Ke(rw=>{"use strict";Object.defineProperty(rw,"__esModule",{value:!0});var Cz={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};rw.MethodEnum=Cz});var Uy=Ke((GG,C5)=>{C5.exports=T5()});var j5=Ke(V0=>{"use strict";Object.defineProperty(V0,"__esModule",{value:!0});var x5=Uy();function iw(i,o){let a=i||{},c=a.data||{};return Object.keys(a).forEach(_=>{["timeout","headers","queryParameters","data","cacheable"].indexOf(_)===-1&&(c[_]=a[_])}),{data:Object.entries(c).length>0?c:void 0,timeout:a.timeout||o,headers:a.headers||{},queryParameters:a.queryParameters||{},cacheable:a.cacheable}}var F4={Read:1,Write:2,Any:3},nm={Up:1,Down:2,Timeouted:3},A5=2*60*1e3;function uw(i,o=nm.Up){return Zr(Ht({},i),{status:o,lastUpdate:Date.now()})}function R5(i){return i.status===nm.Up||Date.now()-i.lastUpdate>A5}function O5(i){return i.status===nm.Timeouted&&Date.now()-i.lastUpdate<=A5}function ow(i){return{protocol:i.protocol||"https",url:i.url,accept:i.accept||F4.Any}}function xz(i,o){return Promise.all(o.map(a=>i.get(a,()=>Promise.resolve(uw(a))))).then(a=>{let c=a.filter(N=>R5(N)),_=a.filter(N=>O5(N)),t=[...c,..._],O=t.length>0?t.map(N=>ow(N)):o;return{getTimeout(N,M){return(_.length===0&&N===0?1:_.length+3+N)*M},statelessHosts:O}})}var Az=({isTimedOut:i,status:o})=>!i&&~~o==0,Rz=i=>{let o=i.status;return i.isTimedOut||Az(i)||~~(o/100)!=2&&~~(o/100)!=4},Oz=({status:i})=>~~(i/100)==2,Mz=(i,o)=>Rz(i)?o.onRetry(i):Oz(i)?o.onSucess(i):o.onFail(i);function I5(i,o,a,c){let _=[],t=N5(a,c),O=F5(i,c),N=a.method,M=a.method!==x5.MethodEnum.Get?{}:Ht(Ht({},a.data),c.data),T=Ht(Ht(Ht({"x-algolia-agent":i.userAgent.value},i.queryParameters),M),c.queryParameters),B=0,H=(q,ne)=>{let m=q.pop();if(m===void 0)throw P5(lw(_));let he={data:t,headers:O,method:N,url:L5(m,a.path,T),connectTimeout:ne(B,i.timeouts.connect),responseTimeout:ne(B,c.timeout)},De=fe=>{let _e={request:he,response:fe,host:m,triesLeft:q.length};return _.push(_e),_e},se={onSucess:fe=>M5(fe),onRetry(fe){let _e=De(fe);return fe.isTimedOut&&B++,Promise.all([i.logger.info("Retryable failure",sw(_e)),i.hostsCache.set(m,uw(m,fe.isTimedOut?nm.Timeouted:nm.Down))]).then(()=>H(q,ne))},onFail(fe){throw De(fe),k5(fe,lw(_))}};return i.requester.send(he).then(fe=>Mz(fe,se))};return xz(i.hostsCache,o).then(q=>H([...q.statelessHosts].reverse(),q.getTimeout))}function kz(i){let{hostsCache:o,logger:a,requester:c,requestsCache:_,responsesCache:t,timeouts:O,userAgent:N,hosts:M,queryParameters:T,headers:B}=i,H={hostsCache:o,logger:a,requester:c,requestsCache:_,responsesCache:t,timeouts:O,userAgent:N,headers:B,queryParameters:T,hosts:M.map(q=>ow(q)),read(q,ne){let m=iw(ne,H.timeouts.read),he=()=>I5(H,H.hosts.filter(fe=>(fe.accept&F4.Read)!=0),q,m);if((m.cacheable!==void 0?m.cacheable:q.cacheable)!==!0)return he();let se={request:q,mappedRequestOptions:m,transporter:{queryParameters:H.queryParameters,headers:H.headers}};return H.responsesCache.get(se,()=>H.requestsCache.get(se,()=>H.requestsCache.set(se,he()).then(fe=>Promise.all([H.requestsCache.delete(se),fe]),fe=>Promise.all([H.requestsCache.delete(se),Promise.reject(fe)])).then(([fe,_e])=>_e)),{miss:fe=>H.responsesCache.set(se,fe)})},write(q,ne){return I5(H,H.hosts.filter(m=>(m.accept&F4.Write)!=0),q,iw(ne,H.timeouts.write))}};return H}function Lz(i){let o={value:`Algolia for JavaScript (${i})`,add(a){let c=`; ${a.segment}${a.version!==void 0?` (${a.version})`:""}`;return o.value.indexOf(c)===-1&&(o.value=`${o.value}${c}`),o}};return o}function M5(i){try{return JSON.parse(i.content)}catch(o){throw b5(o.message,i)}}function k5({content:i,status:o},a){let c=i;try{c=JSON.parse(i).message}catch(_){}return B5(c,o,a)}function Nz(i,...o){let a=0;return i.replace(/%s/g,()=>encodeURIComponent(o[a++]))}function L5(i,o,a){let c=U5(a),_=`${i.protocol}://${i.url}/${o.charAt(0)==="/"?o.substr(1):o}`;return c.length&&(_+=`?${c}`),_}function U5(i){let o=a=>Object.prototype.toString.call(a)==="[object Object]"||Object.prototype.toString.call(a)==="[object Array]";return Object.keys(i).map(a=>Nz("%s=%s",a,o(i[a])?JSON.stringify(i[a]):i[a])).join("&")}function N5(i,o){if(i.method===x5.MethodEnum.Get||i.data===void 0&&o.data===void 0)return;let a=Array.isArray(i.data)?i.data:Ht(Ht({},i.data),o.data);return JSON.stringify(a)}function F5(i,o){let a=Ht(Ht({},i.headers),o.headers),c={};return Object.keys(a).forEach(_=>{let t=a[_];c[_.toLowerCase()]=t}),c}function lw(i){return i.map(o=>sw(o))}function sw(i){let o=i.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return Zr(Ht({},i),{request:Zr(Ht({},i.request),{headers:Ht(Ht({},i.request.headers),o)})})}function B5(i,o,a){return{name:"ApiError",message:i,status:o,transporterStackTrace:a}}function b5(i,o){return{name:"DeserializationError",message:i,response:o}}function P5(i){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:i}}V0.CallEnum=F4;V0.HostStatusEnum=nm;V0.createApiError=B5;V0.createDeserializationError=b5;V0.createMappedRequestOptions=iw;V0.createRetryError=P5;V0.createStatefulHost=uw;V0.createStatelessHost=ow;V0.createTransporter=kz;V0.createUserAgent=Lz;V0.deserializeFailure=k5;V0.deserializeSuccess=M5;V0.isStatefulHostTimeouted=O5;V0.isStatefulHostUp=R5;V0.serializeData=N5;V0.serializeHeaders=F5;V0.serializeQueryParameters=U5;V0.serializeUrl=L5;V0.stackFrameWithoutCredentials=sw;V0.stackTraceWithoutCredentials=lw});var jy=Ke((KG,z5)=>{z5.exports=j5()});var H5=Ke(_2=>{"use strict";Object.defineProperty(_2,"__esModule",{value:!0});var rm=By(),Fz=jy(),zy=Uy(),Pz=i=>{let o=i.region||"us",a=rm.createAuth(rm.AuthMode.WithinHeaders,i.appId,i.apiKey),c=Fz.createTransporter(Zr(Ht({hosts:[{url:`analytics.${o}.algolia.com`}]},i),{headers:Ht(Zr(Ht({},a.headers()),{"content-type":"application/json"}),i.headers),queryParameters:Ht(Ht({},a.queryParameters()),i.queryParameters)})),_=i.appId;return rm.addMethods({appId:_,transporter:c},i.methods)},Iz=i=>(o,a)=>i.transporter.write({method:zy.MethodEnum.Post,path:"2/abtests",data:o},a),bz=i=>(o,a)=>i.transporter.write({method:zy.MethodEnum.Delete,path:rm.encode("2/abtests/%s",o)},a),Bz=i=>(o,a)=>i.transporter.read({method:zy.MethodEnum.Get,path:rm.encode("2/abtests/%s",o)},a),Uz=i=>o=>i.transporter.read({method:zy.MethodEnum.Get,path:"2/abtests"},o),jz=i=>(o,a)=>i.transporter.write({method:zy.MethodEnum.Post,path:rm.encode("2/abtests/%s/stop",o)},a);_2.addABTest=Iz;_2.createAnalyticsClient=Pz;_2.deleteABTest=bz;_2.getABTest=Bz;_2.getABTests=Uz;_2.stopABTest=jz});var W5=Ke((QG,q5)=>{q5.exports=H5()});var G5=Ke(Hy=>{"use strict";Object.defineProperty(Hy,"__esModule",{value:!0});var aw=By(),zz=jy(),V5=Uy(),Hz=i=>{let o=i.region||"us",a=aw.createAuth(aw.AuthMode.WithinHeaders,i.appId,i.apiKey),c=zz.createTransporter(Zr(Ht({hosts:[{url:`recommendation.${o}.algolia.com`}]},i),{headers:Ht(Zr(Ht({},a.headers()),{"content-type":"application/json"}),i.headers),queryParameters:Ht(Ht({},a.queryParameters()),i.queryParameters)}));return aw.addMethods({appId:i.appId,transporter:c},i.methods)},qz=i=>o=>i.transporter.read({method:V5.MethodEnum.Get,path:"1/strategies/personalization"},o),Wz=i=>(o,a)=>i.transporter.write({method:V5.MethodEnum.Post,path:"1/strategies/personalization",data:o},a);Hy.createRecommendationClient=Hz;Hy.getPersonalizationStrategy=qz;Hy.setPersonalizationStrategy=Wz});var K5=Ke((ZG,Y5)=>{Y5.exports=G5()});var l9=Ke(tn=>{"use strict";Object.defineProperty(tn,"__esModule",{value:!0});var Nn=By(),ia=jy(),Ur=Uy(),Vz=require("crypto");function P4(i){let o=a=>i.request(a).then(c=>{if(i.batch!==void 0&&i.batch(c.hits),!i.shouldStop(c))return c.cursor?o({cursor:c.cursor}):o({page:(a.page||0)+1})});return o({})}var Gz=i=>{let o=i.appId,a=Nn.createAuth(i.authMode!==void 0?i.authMode:Nn.AuthMode.WithinHeaders,o,i.apiKey),c=ia.createTransporter(Zr(Ht({hosts:[{url:`${o}-dsn.algolia.net`,accept:ia.CallEnum.Read},{url:`${o}.algolia.net`,accept:ia.CallEnum.Write}].concat(Nn.shuffle([{url:`${o}-1.algolianet.com`},{url:`${o}-2.algolianet.com`},{url:`${o}-3.algolianet.com`}]))},i),{headers:Ht(Zr(Ht({},a.headers()),{"content-type":"application/x-www-form-urlencoded"}),i.headers),queryParameters:Ht(Ht({},a.queryParameters()),i.queryParameters)})),_={transporter:c,appId:o,addAlgoliaAgent(t,O){c.userAgent.add({segment:t,version:O})},clearCache(){return Promise.all([c.requestsCache.clear(),c.responsesCache.clear()]).then(()=>{})}};return Nn.addMethods(_,i.methods)};function X5(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function Q5(){return{name:"ObjectNotFoundError",message:"Object not found."}}function J5(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Yz=i=>(o,a)=>{let N=a||{},{queryParameters:c}=N,_=wl(N,["queryParameters"]),t=Ht({acl:o},c!==void 0?{queryParameters:c}:{}),O=(M,T)=>Nn.createRetryablePromise(B=>qy(i)(M.key,T).catch(H=>{if(H.status!==404)throw H;return B()}));return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:"1/keys",data:t},_),O)},Kz=i=>(o,a,c)=>{let _=ia.createMappedRequestOptions(c);return _.queryParameters["X-Algolia-User-ID"]=o,i.transporter.write({method:Ur.MethodEnum.Post,path:"1/clusters/mapping",data:{cluster:a}},_)},Xz=i=>(o,a,c)=>i.transporter.write({method:Ur.MethodEnum.Post,path:"1/clusters/mapping/batch",data:{users:o,cluster:a}},c),I4=i=>(o,a,c)=>{let _=(t,O)=>Wy(i)(o,{methods:{waitTask:xo}}).waitTask(t.taskID,O);return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/operation",o),data:{operation:"copy",destination:a}},c),_)},Qz=i=>(o,a,c)=>I4(i)(o,a,Zr(Ht({},c),{scope:[b4.Rules]})),Jz=i=>(o,a,c)=>I4(i)(o,a,Zr(Ht({},c),{scope:[b4.Settings]})),Zz=i=>(o,a,c)=>I4(i)(o,a,Zr(Ht({},c),{scope:[b4.Synonyms]})),$z=i=>(o,a)=>{let c=(_,t)=>Nn.createRetryablePromise(O=>qy(i)(o,t).then(O).catch(N=>{if(N.status!==404)throw N}));return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Delete,path:Nn.encode("1/keys/%s",o)},a),c)},eH=()=>(i,o)=>{let a=ia.serializeQueryParameters(o),c=Vz.createHmac("sha256",i).update(a).digest("hex");return Buffer.from(c+a).toString("base64")},qy=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/keys/%s",o)},a),tH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/logs"},o),nH=()=>i=>{let o=Buffer.from(i,"base64").toString("ascii"),a=/validUntil=(\d+)/,c=o.match(a);if(c===null)throw J5();return parseInt(c[1],10)-Math.round(new Date().getTime()/1e3)},rH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/clusters/mapping/top"},o),iH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/clusters/mapping/%s",o)},a),uH=i=>o=>{let _=o||{},{retrieveMappings:a}=_,c=wl(_,["retrieveMappings"]);return a===!0&&(c.getClusters=!0),i.transporter.read({method:Ur.MethodEnum.Get,path:"1/clusters/mapping/pending"},c)},Wy=i=>(o,a={})=>{let c={transporter:i.transporter,appId:i.appId,indexName:o};return Nn.addMethods(c,a.methods)},oH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/keys"},o),lH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/clusters"},o),sH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/indexes"},o),aH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/clusters/mapping"},o),fH=i=>(o,a,c)=>{let _=(t,O)=>Wy(i)(o,{methods:{waitTask:xo}}).waitTask(t.taskID,O);return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/operation",o),data:{operation:"move",destination:a}},c),_)},cH=i=>(o,a)=>{let c=(_,t)=>Promise.all(Object.keys(_.taskID).map(O=>Wy(i)(O,{methods:{waitTask:xo}}).waitTask(_.taskID[O],t)));return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:o}},a),c)},dH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:o}},a),pH=i=>(o,a)=>{let c=o.map(_=>Zr(Ht({},_),{params:ia.serializeQueryParameters(_.params||{})}));return i.transporter.read({method:Ur.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:c},cacheable:!0},a)},hH=i=>(o,a)=>Promise.all(o.map(c=>{let N=c.params,{facetName:_,facetQuery:t}=N,O=wl(N,["facetName","facetQuery"]);return Wy(i)(c.indexName,{methods:{searchForFacetValues:Z5}}).searchForFacetValues(_,t,Ht(Ht({},a),O))})),vH=i=>(o,a)=>{let c=ia.createMappedRequestOptions(a);return c.queryParameters["X-Algolia-User-ID"]=o,i.transporter.write({method:Ur.MethodEnum.Delete,path:"1/clusters/mapping"},c)},mH=i=>(o,a)=>{let c=(_,t)=>Nn.createRetryablePromise(O=>qy(i)(o,t).catch(N=>{if(N.status!==404)throw N;return O()}));return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/keys/%s/restore",o)},a),c)},gH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Post,path:"1/clusters/mapping/search",data:{query:o}},a),yH=i=>(o,a)=>{let c=Object.assign({},a),B=a||{},{queryParameters:_}=B,t=wl(B,["queryParameters"]),O=_?{queryParameters:_}:{},N=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],M=H=>Object.keys(c).filter(q=>N.indexOf(q)!==-1).every(q=>H[q]===c[q]),T=(H,q)=>Nn.createRetryablePromise(ne=>qy(i)(o,q).then(m=>M(m)?Promise.resolve():ne()));return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Put,path:Nn.encode("1/keys/%s",o),data:O},t),T)},$5=i=>(o,a)=>{let c=(_,t)=>xo(i)(_.taskID,t);return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/batch",i.indexName),data:{requests:o}},a),c)},_H=i=>o=>P4(Zr(Ht({},o),{shouldStop:a=>a.cursor===void 0,request:a=>i.transporter.read({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/browse",i.indexName),data:a},o)})),EH=i=>o=>{let a=Ht({hitsPerPage:1e3},o);return P4(Zr(Ht({},a),{shouldStop:c=>c.hits.lengthZr(Ht({},_),{hits:_.hits.map(t=>(delete t._highlightResult,t))}))}}))},DH=i=>o=>{let a=Ht({hitsPerPage:1e3},o);return P4(Zr(Ht({},a),{shouldStop:c=>c.hits.lengthZr(Ht({},_),{hits:_.hits.map(t=>(delete t._highlightResult,t))}))}}))},B4=i=>(o,a,c)=>{let M=c||{},{batchSize:_}=M,t=wl(M,["batchSize"]),O={taskIDs:[],objectIDs:[]},N=(T=0)=>{let B=[],H;for(H=T;H({action:a,body:q})),t).then(q=>(O.objectIDs=O.objectIDs.concat(q.objectIDs),O.taskIDs.push(q.taskID),H++,N(H)))};return Nn.createWaitablePromise(N(),(T,B)=>Promise.all(T.taskIDs.map(H=>xo(i)(H,B))))},wH=i=>o=>Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/clear",i.indexName)},o),(a,c)=>xo(i)(a.taskID,c)),SH=i=>o=>{let t=o||{},{forwardToReplicas:a}=t,c=wl(t,["forwardToReplicas"]),_=ia.createMappedRequestOptions(c);return a&&(_.queryParameters.forwardToReplicas=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/rules/clear",i.indexName)},_),(O,N)=>xo(i)(O.taskID,N))},TH=i=>o=>{let t=o||{},{forwardToReplicas:a}=t,c=wl(t,["forwardToReplicas"]),_=ia.createMappedRequestOptions(c);return a&&(_.queryParameters.forwardToReplicas=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/synonyms/clear",i.indexName)},_),(O,N)=>xo(i)(O.taskID,N))},CH=i=>(o,a)=>Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/deleteByQuery",i.indexName),data:o},a),(c,_)=>xo(i)(c.taskID,_)),xH=i=>o=>Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Delete,path:Nn.encode("1/indexes/%s",i.indexName)},o),(a,c)=>xo(i)(a.taskID,c)),AH=i=>(o,a)=>Nn.createWaitablePromise(n9(i)([o],a).then(c=>({taskID:c.taskIDs[0]})),(c,_)=>xo(i)(c.taskID,_)),n9=i=>(o,a)=>{let c=o.map(_=>({objectID:_}));return B4(i)(c,fh.DeleteObject,a)},RH=i=>(o,a)=>{let O=a||{},{forwardToReplicas:c}=O,_=wl(O,["forwardToReplicas"]),t=ia.createMappedRequestOptions(_);return c&&(t.queryParameters.forwardToReplicas=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Delete,path:Nn.encode("1/indexes/%s/rules/%s",i.indexName,o)},t),(N,M)=>xo(i)(N.taskID,M))},OH=i=>(o,a)=>{let O=a||{},{forwardToReplicas:c}=O,_=wl(O,["forwardToReplicas"]),t=ia.createMappedRequestOptions(_);return c&&(t.queryParameters.forwardToReplicas=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Delete,path:Nn.encode("1/indexes/%s/synonyms/%s",i.indexName,o)},t),(N,M)=>xo(i)(N.taskID,M))},MH=i=>o=>r9(i)(o).then(()=>!0).catch(a=>{if(a.status!==404)throw a;return!1}),kH=i=>(o,a)=>{let M=a||{},{query:c,paginate:_}=M,t=wl(M,["query","paginate"]),O=0,N=()=>i9(i)(c||"",Zr(Ht({},t),{page:O})).then(T=>{for(let[B,H]of Object.entries(T.hits))if(o(H))return{object:H,position:parseInt(B,10),page:O};if(O++,_===!1||O>=T.nbPages)throw Q5();return N()});return N()},LH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/%s",i.indexName,o)},a),NH=()=>(i,o)=>{for(let[a,c]of Object.entries(i.hits))if(c.objectID===o)return parseInt(a,10);return-1},FH=i=>(o,a)=>{let O=a||{},{attributesToRetrieve:c}=O,_=wl(O,["attributesToRetrieve"]),t=o.map(N=>Ht({indexName:i.indexName,objectID:N},c?{attributesToRetrieve:c}:{}));return i.transporter.read({method:Ur.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:t}},_)},PH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/rules/%s",i.indexName,o)},a),r9=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/settings",i.indexName),data:{getVersion:2}},o),IH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/synonyms/%s",i.indexName,o)},a),u9=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/task/%s",i.indexName,o.toString())},a),bH=i=>(o,a)=>Nn.createWaitablePromise(o9(i)([o],a).then(c=>({objectID:c.objectIDs[0],taskID:c.taskIDs[0]})),(c,_)=>xo(i)(c.taskID,_)),o9=i=>(o,a)=>{let O=a||{},{createIfNotExists:c}=O,_=wl(O,["createIfNotExists"]),t=c?fh.PartialUpdateObject:fh.PartialUpdateObjectNoCreate;return B4(i)(o,t,_)},BH=i=>(o,a)=>{let m=a||{},{safe:c,autoGenerateObjectIDIfNotExist:_,batchSize:t}=m,O=wl(m,["safe","autoGenerateObjectIDIfNotExist","batchSize"]),N=(he,De,se,fe)=>Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/operation",he),data:{operation:se,destination:De}},fe),(_e,ce)=>xo(i)(_e.taskID,ce)),M=Math.random().toString(36).substring(7),T=`${i.indexName}_tmp_${M}`,B=fw({appId:i.appId,transporter:i.transporter,indexName:T}),H=[],q=N(i.indexName,T,"copy",Zr(Ht({},O),{scope:["settings","synonyms","rules"]}));H.push(q);let ne=(c?q.wait(O):q).then(()=>{let he=B(o,Zr(Ht({},O),{autoGenerateObjectIDIfNotExist:_,batchSize:t}));return H.push(he),c?he.wait(O):he}).then(()=>{let he=N(T,i.indexName,"move",O);return H.push(he),c?he.wait(O):he}).then(()=>Promise.all(H)).then(([he,De,se])=>({objectIDs:De.objectIDs,taskIDs:[he.taskID,...De.taskIDs,se.taskID]}));return Nn.createWaitablePromise(ne,(he,De)=>Promise.all(H.map(se=>se.wait(De))))},UH=i=>(o,a)=>cw(i)(o,Zr(Ht({},a),{clearExistingRules:!0})),jH=i=>(o,a)=>dw(i)(o,Zr(Ht({},a),{replaceExistingSynonyms:!0})),zH=i=>(o,a)=>Nn.createWaitablePromise(fw(i)([o],a).then(c=>({objectID:c.objectIDs[0],taskID:c.taskIDs[0]})),(c,_)=>xo(i)(c.taskID,_)),fw=i=>(o,a)=>{let O=a||{},{autoGenerateObjectIDIfNotExist:c}=O,_=wl(O,["autoGenerateObjectIDIfNotExist"]),t=c?fh.AddObject:fh.UpdateObject;if(t===fh.UpdateObject){for(let N of o)if(N.objectID===void 0)return Nn.createWaitablePromise(Promise.reject(X5()))}return B4(i)(o,t,_)},HH=i=>(o,a)=>cw(i)([o],a),cw=i=>(o,a)=>{let N=a||{},{forwardToReplicas:c,clearExistingRules:_}=N,t=wl(N,["forwardToReplicas","clearExistingRules"]),O=ia.createMappedRequestOptions(t);return c&&(O.queryParameters.forwardToReplicas=1),_&&(O.queryParameters.clearExistingRules=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/rules/batch",i.indexName),data:o},O),(M,T)=>xo(i)(M.taskID,T))},qH=i=>(o,a)=>dw(i)([o],a),dw=i=>(o,a)=>{let N=a||{},{forwardToReplicas:c,replaceExistingSynonyms:_}=N,t=wl(N,["forwardToReplicas","replaceExistingSynonyms"]),O=ia.createMappedRequestOptions(t);return c&&(O.queryParameters.forwardToReplicas=1),_&&(O.queryParameters.replaceExistingSynonyms=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/synonyms/batch",i.indexName),data:o},O),(M,T)=>xo(i)(M.taskID,T))},i9=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/query",i.indexName),data:{query:o},cacheable:!0},a),Z5=i=>(o,a,c)=>i.transporter.read({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/facets/%s/query",i.indexName,o),data:{facetQuery:a},cacheable:!0},c),e9=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/rules/search",i.indexName),data:{query:o}},a),t9=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/synonyms/search",i.indexName),data:{query:o}},a),WH=i=>(o,a)=>{let O=a||{},{forwardToReplicas:c}=O,_=wl(O,["forwardToReplicas"]),t=ia.createMappedRequestOptions(_);return c&&(t.queryParameters.forwardToReplicas=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Put,path:Nn.encode("1/indexes/%s/settings",i.indexName),data:o},t),(N,M)=>xo(i)(N.taskID,M))},xo=i=>(o,a)=>Nn.createRetryablePromise(c=>u9(i)(o,a).then(_=>_.status!=="published"?c():void 0)),VH={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",ListIndexes:"listIndexes",Logs:"logs",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},fh={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject"},b4={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},GH={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},YH={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};tn.ApiKeyACLEnum=VH;tn.BatchActionEnum=fh;tn.ScopeEnum=b4;tn.StrategyEnum=GH;tn.SynonymEnum=YH;tn.addApiKey=Yz;tn.assignUserID=Kz;tn.assignUserIDs=Xz;tn.batch=$5;tn.browseObjects=_H;tn.browseRules=EH;tn.browseSynonyms=DH;tn.chunkedBatch=B4;tn.clearObjects=wH;tn.clearRules=SH;tn.clearSynonyms=TH;tn.copyIndex=I4;tn.copyRules=Qz;tn.copySettings=Jz;tn.copySynonyms=Zz;tn.createBrowsablePromise=P4;tn.createMissingObjectIDError=X5;tn.createObjectNotFoundError=Q5;tn.createSearchClient=Gz;tn.createValidUntilNotFoundError=J5;tn.deleteApiKey=$z;tn.deleteBy=CH;tn.deleteIndex=xH;tn.deleteObject=AH;tn.deleteObjects=n9;tn.deleteRule=RH;tn.deleteSynonym=OH;tn.exists=MH;tn.findObject=kH;tn.generateSecuredApiKey=eH;tn.getApiKey=qy;tn.getLogs=tH;tn.getObject=LH;tn.getObjectPosition=NH;tn.getObjects=FH;tn.getRule=PH;tn.getSecuredApiKeyRemainingValidity=nH;tn.getSettings=r9;tn.getSynonym=IH;tn.getTask=u9;tn.getTopUserIDs=rH;tn.getUserID=iH;tn.hasPendingMappings=uH;tn.initIndex=Wy;tn.listApiKeys=oH;tn.listClusters=lH;tn.listIndices=sH;tn.listUserIDs=aH;tn.moveIndex=fH;tn.multipleBatch=cH;tn.multipleGetObjects=dH;tn.multipleQueries=pH;tn.multipleSearchForFacetValues=hH;tn.partialUpdateObject=bH;tn.partialUpdateObjects=o9;tn.removeUserID=vH;tn.replaceAllObjects=BH;tn.replaceAllRules=UH;tn.replaceAllSynonyms=jH;tn.restoreApiKey=mH;tn.saveObject=zH;tn.saveObjects=fw;tn.saveRule=HH;tn.saveRules=cw;tn.saveSynonym=qH;tn.saveSynonyms=dw;tn.search=i9;tn.searchForFacetValues=Z5;tn.searchRules=e9;tn.searchSynonyms=t9;tn.searchUserIDs=gH;tn.setSettings=WH;tn.updateApiKey=yH;tn.waitTask=xo});var a9=Ke((eY,s9)=>{s9.exports=l9()});var f9=Ke(U4=>{"use strict";Object.defineProperty(U4,"__esModule",{value:!0});function KH(){return{debug(i,o){return Promise.resolve()},info(i,o){return Promise.resolve()},error(i,o){return Promise.resolve()}}}var XH={Debug:1,Info:2,Error:3};U4.LogLevelEnum=XH;U4.createNullLogger=KH});var d9=Ke((nY,c9)=>{c9.exports=f9()});var v9=Ke(pw=>{"use strict";Object.defineProperty(pw,"__esModule",{value:!0});var p9=require("http"),h9=require("https"),QH=require("url");function JH(){let i={keepAlive:!0},o=new p9.Agent(i),a=new h9.Agent(i);return{send(c){return new Promise(_=>{let t=QH.parse(c.url),O=t.query===null?t.pathname:`${t.pathname}?${t.query}`,N=Ht({agent:t.protocol==="https:"?a:o,hostname:t.hostname,path:O,method:c.method,headers:c.headers},t.port!==void 0?{port:t.port||""}:{}),M=(t.protocol==="https:"?h9:p9).request(N,q=>{let ne="";q.on("data",m=>ne+=m),q.on("end",()=>{clearTimeout(B),clearTimeout(H),_({status:q.statusCode||0,content:ne,isTimedOut:!1})})}),T=(q,ne)=>setTimeout(()=>{M.abort(),_({status:0,content:ne,isTimedOut:!0})},q*1e3),B=T(c.connectTimeout,"Connection timeout"),H;M.on("error",q=>{clearTimeout(B),clearTimeout(H),_({status:0,content:q.message,isTimedOut:!1})}),M.once("response",()=>{clearTimeout(B),H=T(c.responseTimeout,"Socket timeout")}),c.data!==void 0&&M.write(c.data),M.end()})},destroy(){return o.destroy(),a.destroy(),Promise.resolve()}}}pw.createNodeHttpRequester=JH});var g9=Ke((iY,m9)=>{m9.exports=v9()});var D9=Ke((uY,y9)=>{"use strict";var _9=g5(),ZH=E5(),im=W5(),hw=By(),vw=K5(),wn=a9(),$H=d9(),eq=g9(),tq=jy();function E9(i,o,a){let c={appId:i,apiKey:o,timeouts:{connect:2,read:5,write:30},requester:eq.createNodeHttpRequester(),logger:$H.createNullLogger(),responsesCache:_9.createNullCache(),requestsCache:_9.createNullCache(),hostsCache:ZH.createInMemoryCache(),userAgent:tq.createUserAgent(hw.version).add({segment:"Node.js",version:process.versions.node})};return wn.createSearchClient(Zr(Ht(Ht({},c),a),{methods:{search:wn.multipleQueries,searchForFacetValues:wn.multipleSearchForFacetValues,multipleBatch:wn.multipleBatch,multipleGetObjects:wn.multipleGetObjects,multipleQueries:wn.multipleQueries,copyIndex:wn.copyIndex,copySettings:wn.copySettings,copyRules:wn.copyRules,copySynonyms:wn.copySynonyms,moveIndex:wn.moveIndex,listIndices:wn.listIndices,getLogs:wn.getLogs,listClusters:wn.listClusters,multipleSearchForFacetValues:wn.multipleSearchForFacetValues,getApiKey:wn.getApiKey,addApiKey:wn.addApiKey,listApiKeys:wn.listApiKeys,updateApiKey:wn.updateApiKey,deleteApiKey:wn.deleteApiKey,restoreApiKey:wn.restoreApiKey,assignUserID:wn.assignUserID,assignUserIDs:wn.assignUserIDs,getUserID:wn.getUserID,searchUserIDs:wn.searchUserIDs,listUserIDs:wn.listUserIDs,getTopUserIDs:wn.getTopUserIDs,removeUserID:wn.removeUserID,hasPendingMappings:wn.hasPendingMappings,generateSecuredApiKey:wn.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:wn.getSecuredApiKeyRemainingValidity,destroy:hw.destroy,initIndex:_=>t=>wn.initIndex(_)(t,{methods:{batch:wn.batch,delete:wn.deleteIndex,getObject:wn.getObject,getObjects:wn.getObjects,saveObject:wn.saveObject,saveObjects:wn.saveObjects,search:wn.search,searchForFacetValues:wn.searchForFacetValues,waitTask:wn.waitTask,setSettings:wn.setSettings,getSettings:wn.getSettings,partialUpdateObject:wn.partialUpdateObject,partialUpdateObjects:wn.partialUpdateObjects,deleteObject:wn.deleteObject,deleteObjects:wn.deleteObjects,deleteBy:wn.deleteBy,clearObjects:wn.clearObjects,browseObjects:wn.browseObjects,getObjectPosition:wn.getObjectPosition,findObject:wn.findObject,exists:wn.exists,saveSynonym:wn.saveSynonym,saveSynonyms:wn.saveSynonyms,getSynonym:wn.getSynonym,searchSynonyms:wn.searchSynonyms,browseSynonyms:wn.browseSynonyms,deleteSynonym:wn.deleteSynonym,clearSynonyms:wn.clearSynonyms,replaceAllObjects:wn.replaceAllObjects,replaceAllSynonyms:wn.replaceAllSynonyms,searchRules:wn.searchRules,getRule:wn.getRule,deleteRule:wn.deleteRule,saveRule:wn.saveRule,saveRules:wn.saveRules,replaceAllRules:wn.replaceAllRules,browseRules:wn.browseRules,clearRules:wn.clearRules}}),initAnalytics:()=>_=>im.createAnalyticsClient(Zr(Ht(Ht({},c),_),{methods:{addABTest:im.addABTest,getABTest:im.getABTest,getABTests:im.getABTests,stopABTest:im.stopABTest,deleteABTest:im.deleteABTest}})),initRecommendation:()=>_=>vw.createRecommendationClient(Zr(Ht(Ht({},c),_),{methods:{getPersonalizationStrategy:vw.getPersonalizationStrategy,setPersonalizationStrategy:vw.setPersonalizationStrategy}}))}}))}E9.version=hw.version;y9.exports=E9});var S9=Ke((oY,mw)=>{var w9=D9();mw.exports=w9;mw.exports.default=w9});var nd=Ke(_w=>{"use strict";Object.defineProperty(_w,"__esModule",{value:!0});_w.default=L9;function L9(){}L9.prototype={diff:function(o,a){var c=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},_=c.callback;typeof c=="function"&&(_=c,c={}),this.options=c;var t=this;function O(he){return _?(setTimeout(function(){_(void 0,he)},0),!0):he}o=this.castInput(o),a=this.castInput(a),o=this.removeEmpty(this.tokenize(o)),a=this.removeEmpty(this.tokenize(a));var N=a.length,M=o.length,T=1,B=N+M,H=[{newPos:-1,components:[]}],q=this.extractCommon(H[0],a,o,0);if(H[0].newPos+1>=N&&q+1>=M)return O([{value:this.join(a),count:a.length}]);function ne(){for(var he=-1*T;he<=T;he+=2){var De=void 0,se=H[he-1],fe=H[he+1],_e=(fe?fe.newPos:0)-he;se&&(H[he-1]=void 0);var ce=se&&se.newPos+1=N&&_e+1>=M)return O(rq(t,De.components,a,o,t.useLongestToken));H[he]=De}T++}if(_)(function he(){setTimeout(function(){if(T>B)return _();ne()||he()},0)})();else for(;T<=B;){var m=ne();if(m)return m}},pushComponent:function(o,a,c){var _=o[o.length-1];_&&_.added===a&&_.removed===c?o[o.length-1]={count:_.count+1,added:a,removed:c}:o.push({count:1,added:a,removed:c})},extractCommon:function(o,a,c,_){for(var t=a.length,O=c.length,N=o.newPos,M=N-_,T=0;N+1ne.length?he:ne}),T.value=i.join(B)}else T.value=i.join(a.slice(N,N+T.count));N+=T.count,T.added||(M+=T.count)}}var q=o[O-1];return O>1&&typeof q.value=="string"&&(q.added||q.removed)&&i.equals("",q.value)&&(o[O-2].value+=q.value,o.pop()),o}function iq(i){return{newPos:i.newPos,components:i.components.slice(0)}}});var F9=Ke(Ky=>{"use strict";Object.defineProperty(Ky,"__esModule",{value:!0});Ky.diffChars=uq;Ky.characterDiff=void 0;var lq=oq(nd());function oq(i){return i&&i.__esModule?i:{default:i}}var N9=new lq.default;Ky.characterDiff=N9;function uq(i,o,a){return N9.diff(i,o,a)}});var Dw=Ke(Ew=>{"use strict";Object.defineProperty(Ew,"__esModule",{value:!0});Ew.generateOptions=sq;function sq(i,o){if(typeof i=="function")o.callback=i;else if(i)for(var a in i)i.hasOwnProperty(a)&&(o[a]=i[a]);return o}});var b9=Ke(um=>{"use strict";Object.defineProperty(um,"__esModule",{value:!0});um.diffWords=aq;um.diffWordsWithSpace=fq;um.wordDiff=void 0;var dq=cq(nd()),pq=Dw();function cq(i){return i&&i.__esModule?i:{default:i}}var P9=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,I9=/\S/,Xy=new dq.default;um.wordDiff=Xy;Xy.equals=function(i,o){return this.options.ignoreCase&&(i=i.toLowerCase(),o=o.toLowerCase()),i===o||this.options.ignoreWhitespace&&!I9.test(i)&&!I9.test(o)};Xy.tokenize=function(i){for(var o=i.split(/(\s+|[()[\]{}'"]|\b)/),a=0;a{"use strict";Object.defineProperty(om,"__esModule",{value:!0});om.diffLines=hq;om.diffTrimmedLines=vq;om.lineDiff=void 0;var gq=mq(nd()),yq=Dw();function mq(i){return i&&i.__esModule?i:{default:i}}var z4=new gq.default;om.lineDiff=z4;z4.tokenize=function(i){var o=[],a=i.split(/(\n|\r\n)/);a[a.length-1]||a.pop();for(var c=0;c{"use strict";Object.defineProperty(Qy,"__esModule",{value:!0});Qy.diffSentences=_q;Qy.sentenceDiff=void 0;var Dq=Eq(nd());function Eq(i){return i&&i.__esModule?i:{default:i}}var ww=new Dq.default;Qy.sentenceDiff=ww;ww.tokenize=function(i){return i.split(/(\S.+?[.!?])(?=\s+|$)/)};function _q(i,o,a){return ww.diff(i,o,a)}});var U9=Ke(Jy=>{"use strict";Object.defineProperty(Jy,"__esModule",{value:!0});Jy.diffCss=wq;Jy.cssDiff=void 0;var Tq=Sq(nd());function Sq(i){return i&&i.__esModule?i:{default:i}}var Sw=new Tq.default;Jy.cssDiff=Sw;Sw.tokenize=function(i){return i.split(/([{}:;,]|\s+)/)};function wq(i,o,a){return Sw.diff(i,o,a)}});var z9=Ke(lm=>{"use strict";Object.defineProperty(lm,"__esModule",{value:!0});lm.diffJson=Cq;lm.canonicalize=q4;lm.jsonDiff=void 0;var j9=xq(nd()),Aq=H4();function xq(i){return i&&i.__esModule?i:{default:i}}function W4(i){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?W4=function(a){return typeof a}:W4=function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},W4(i)}var Rq=Object.prototype.toString,dh=new j9.default;lm.jsonDiff=dh;dh.useLongestToken=!0;dh.tokenize=Aq.lineDiff.tokenize;dh.castInput=function(i){var o=this.options,a=o.undefinedReplacement,c=o.stringifyReplacer,_=c===void 0?function(t,O){return typeof O=="undefined"?a:O}:c;return typeof i=="string"?i:JSON.stringify(q4(i,null,null,_),_," ")};dh.equals=function(i,o){return j9.default.prototype.equals.call(dh,i.replace(/,([\r\n])/g,"$1"),o.replace(/,([\r\n])/g,"$1"))};function Cq(i,o,a){return dh.diff(i,o,a)}function q4(i,o,a,c,_){o=o||[],a=a||[],c&&(i=c(_,i));var t;for(t=0;t{"use strict";Object.defineProperty(Zy,"__esModule",{value:!0});Zy.diffArrays=Oq;Zy.arrayDiff=void 0;var kq=Mq(nd());function Mq(i){return i&&i.__esModule?i:{default:i}}var $y=new kq.default;Zy.arrayDiff=$y;$y.tokenize=function(i){return i.slice()};$y.join=$y.removeEmpty=function(i){return i};function Oq(i,o,a){return $y.diff(i,o,a)}});var V4=Ke(Tw=>{"use strict";Object.defineProperty(Tw,"__esModule",{value:!0});Tw.parsePatch=Lq;function Lq(i){var o=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i.split(/\r\n|[\n\v\f\r\x85]/),c=i.match(/\r\n|[\n\v\f\r\x85]/g)||[],_=[],t=0;function O(){var T={};for(_.push(T);t{"use strict";Object.defineProperty(Cw,"__esModule",{value:!0});Cw.default=Nq;function Nq(i,o,a){var c=!0,_=!1,t=!1,O=1;return function N(){if(c&&!t){if(_?O++:c=!1,i+O<=a)return O;t=!0}if(!_)return t||(c=!0),o<=i-O?-O++:(_=!0,N())}}});var G9=Ke(G4=>{"use strict";Object.defineProperty(G4,"__esModule",{value:!0});G4.applyPatch=W9;G4.applyPatches=Fq;var V9=V4(),Iq=Pq(q9());function Pq(i){return i&&i.__esModule?i:{default:i}}function W9(i,o){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(typeof o=="string"&&(o=(0,V9.parsePatch)(o)),Array.isArray(o)){if(o.length>1)throw new Error("applyPatch only works with a single input.");o=o[0]}var c=i.split(/\r\n|[\n\v\f\r\x85]/),_=i.match(/\r\n|[\n\v\f\r\x85]/g)||[],t=o.hunks,O=a.compareLine||function(It,Xt,rt,X){return Xt===X},N=0,M=a.fuzzFactor||0,T=0,B=0,H,q;function ne(It,Xt){for(var rt=0;rt0?X[0]:" ",Ce=X.length>0?X.substr(1):X;if(de===" "||de==="-"){if(!O(Xt+1,c[Xt],de,Ce)&&(N++,N>M))return!1;Xt++}}return!0}for(var m=0;m0?je[0]:" ",Dt=je.length>0?je.substr(1):je,Qe=ie.linedelimiters[Ue];if(at===" ")Oe++;else if(at==="-")c.splice(Oe,1),_.splice(Oe,1);else if(at==="+")c.splice(Oe,0,Dt),_.splice(Oe,0,Qe),Oe++;else if(at==="\\"){var ut=ie.lines[Ue-1]?ie.lines[Ue-1][0]:null;ut==="+"?H=!0:ut==="-"&&(q=!0)}}}if(H)for(;!c[c.length-1];)c.pop(),_.pop();else q&&(c.push(""),_.push(` +`));for(var Ve=0;Ve{"use strict";Object.defineProperty(e_,"__esModule",{value:!0});e_.structuredPatch=Y9;e_.createTwoFilesPatch=K9;e_.createPatch=bq;var Bq=H4();function xw(i){return zq(i)||jq(i)||Uq()}function Uq(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function jq(i){if(Symbol.iterator in Object(i)||Object.prototype.toString.call(i)==="[object Arguments]")return Array.from(i)}function zq(i){if(Array.isArray(i)){for(var o=0,a=new Array(i.length);o0?M(ie.lines.slice(-O.context)):[],B-=q.length,H-=q.length)}(me=q).push.apply(me,xw(ce.map(function(Ve){return(_e.added?"+":"-")+Ve}))),_e.added?m+=ce.length:ne+=ce.length}else{if(B)if(ce.length<=O.context*2&&fe=N.length-2&&ce.length<=O.context){var Dt=/\n$/.test(a),Qe=/\n$/.test(c),ut=ce.length==0&&q.length>at.oldLines;!Dt&&ut&&q.splice(at.oldLines,0,"\\ No newline at end of file"),(!Dt&&!ut||!Qe)&&q.push("\\ No newline at end of file")}T.push(at),B=0,H=0,q=[]}ne+=ce.length,m+=ce.length}},De=0;De{"use strict";Object.defineProperty(Y4,"__esModule",{value:!0});Y4.arrayEqual=Hq;Y4.arrayStartsWith=X9;function Hq(i,o){return i.length!==o.length?!1:X9(i,o)}function X9(i,o){if(o.length>i.length)return!1;for(var a=0;a{"use strict";Object.defineProperty(K4,"__esModule",{value:!0});K4.calcLineCount=J9;K4.merge=qq;var Wq=Aw(),Vq=V4(),Rw=Q9();function sm(i){return Kq(i)||Yq(i)||Gq()}function Gq(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function Yq(i){if(Symbol.iterator in Object(i)||Object.prototype.toString.call(i)==="[object Arguments]")return Array.from(i)}function Kq(i){if(Array.isArray(i)){for(var o=0,a=new Array(i.length);o{"use strict";Object.defineProperty(kw,"__esModule",{value:!0});kw.convertChangesToDMP=Zq;function Zq(i){for(var o=[],a,c,_=0;_{"use strict";Object.defineProperty(Lw,"__esModule",{value:!0});Lw.convertChangesToXML=$q;function $q(i){for(var o=[],a=0;a"):c.removed&&o.push(""),o.push(eW(c.value)),c.added?o.push(""):c.removed&&o.push("")}return o.join("")}function eW(i){var o=i;return o=o.replace(/&/g,"&"),o=o.replace(//g,">"),o=o.replace(/"/g,"""),o}});var hA=Ke(G0=>{"use strict";Object.defineProperty(G0,"__esModule",{value:!0});Object.defineProperty(G0,"Diff",{enumerable:!0,get:function(){return tW.default}});Object.defineProperty(G0,"diffChars",{enumerable:!0,get:function(){return nW.diffChars}});Object.defineProperty(G0,"diffWords",{enumerable:!0,get:function(){return fA.diffWords}});Object.defineProperty(G0,"diffWordsWithSpace",{enumerable:!0,get:function(){return fA.diffWordsWithSpace}});Object.defineProperty(G0,"diffLines",{enumerable:!0,get:function(){return cA.diffLines}});Object.defineProperty(G0,"diffTrimmedLines",{enumerable:!0,get:function(){return cA.diffTrimmedLines}});Object.defineProperty(G0,"diffSentences",{enumerable:!0,get:function(){return rW.diffSentences}});Object.defineProperty(G0,"diffCss",{enumerable:!0,get:function(){return iW.diffCss}});Object.defineProperty(G0,"diffJson",{enumerable:!0,get:function(){return dA.diffJson}});Object.defineProperty(G0,"canonicalize",{enumerable:!0,get:function(){return dA.canonicalize}});Object.defineProperty(G0,"diffArrays",{enumerable:!0,get:function(){return uW.diffArrays}});Object.defineProperty(G0,"applyPatch",{enumerable:!0,get:function(){return pA.applyPatch}});Object.defineProperty(G0,"applyPatches",{enumerable:!0,get:function(){return pA.applyPatches}});Object.defineProperty(G0,"parsePatch",{enumerable:!0,get:function(){return oW.parsePatch}});Object.defineProperty(G0,"merge",{enumerable:!0,get:function(){return lW.merge}});Object.defineProperty(G0,"structuredPatch",{enumerable:!0,get:function(){return Nw.structuredPatch}});Object.defineProperty(G0,"createTwoFilesPatch",{enumerable:!0,get:function(){return Nw.createTwoFilesPatch}});Object.defineProperty(G0,"createPatch",{enumerable:!0,get:function(){return Nw.createPatch}});Object.defineProperty(G0,"convertChangesToDMP",{enumerable:!0,get:function(){return sW.convertChangesToDMP}});Object.defineProperty(G0,"convertChangesToXML",{enumerable:!0,get:function(){return aW.convertChangesToXML}});var tW=fW(nd()),nW=F9(),fA=b9(),cA=H4(),rW=B9(),iW=U9(),dA=z9(),uW=H9(),pA=G9(),oW=V4(),lW=lA(),Nw=Aw(),sW=sA(),aW=aA();function fW(i){return i&&i.__esModule?i:{default:i}}});var dW={};uI(dW,{default:()=>hW});var C9=ou(require("@yarnpkg/cli")),ch=ou(require("@yarnpkg/core"));var i5=ou(sc()),lh=ou(ki()),C4=(0,lh.memo)(({active:i})=>{let o=(0,lh.useMemo)(()=>i?"\u25C9":"\u25EF",[i]),a=(0,lh.useMemo)(()=>i?"green":"yellow",[i]);return lh.default.createElement(i5.Text,{color:a},o)});var y2=ou(sc()),ra=ou(ki());var u5=ou(sc()),x4=ou(ki());function g2({active:i},o,a){let{stdin:c}=(0,u5.useStdin)(),_=(0,x4.useCallback)((t,O)=>o(t,O),a);(0,x4.useEffect)(()=>{if(!(!i||!c))return c.on("keypress",_),()=>{c.off("keypress",_)}},[i,_,c])}var A4;(function(a){a.BEFORE="before",a.AFTER="after"})(A4||(A4={}));var o5=function({active:i},o,a){g2({active:i},(c,_)=>{_.name==="tab"&&(_.shift?o(A4.BEFORE):o(A4.AFTER))},a)};var R4=function(i,o,{active:a,minus:c,plus:_,set:t,loop:O=!0}){g2({active:a},(N,M)=>{let T=o.indexOf(i);switch(M.name){case c:{let B=T-1;if(O){t(o[(o.length+B)%o.length]);return}if(B<0)return;t(o[B])}break;case _:{let B=T+1;if(O){t(o[B%o.length]);return}if(B>=o.length)return;t(o[B])}break}},[o,i,_,t,O])};var O4=({active:i=!0,children:o=[],radius:a=10,size:c=1,loop:_=!0,onFocusRequest:t,willReachEnd:O})=>{let N=De=>{if(De.key===null)throw new Error("Expected all children to have a key");return De.key},M=ra.default.Children.map(o,De=>N(De)),T=M[0],[B,H]=(0,ra.useState)(T),q=M.indexOf(B);(0,ra.useEffect)(()=>{M.includes(B)||H(T)},[o]),(0,ra.useEffect)(()=>{O&&q>=M.length-2&&O()},[q]),o5({active:i&&!!t},De=>{t==null||t(De)},[t]),R4(B,M,{active:i,minus:"up",plus:"down",set:H,loop:_});let ne=q-a,m=q+a;m>M.length&&(ne-=m-M.length,m=M.length),ne<0&&(m+=-ne,ne=0),m>=M.length&&(m=M.length-1);let he=[];for(let De=ne;De<=m;++De){let se=M[De],fe=i&&se===B;he.push(ra.default.createElement(y2.Box,{key:se,height:c},ra.default.createElement(y2.Box,{marginLeft:1,marginRight:1},ra.default.createElement(y2.Text,null,fe?ra.default.createElement(y2.Text,{color:"cyan",bold:!0},">"):" ")),ra.default.createElement(y2.Box,null,ra.default.cloneElement(o[De],{active:fe}))))}return ra.default.createElement(y2.Box,{flexDirection:"column",width:"100%"},he)};var M4=ou(ki());var l5=ou(sc()),td=ou(ki()),s5=ou(require("readline")),Z3=td.default.createContext(null),a5=({children:i})=>{let{stdin:o,setRawMode:a}=(0,l5.useStdin)();(0,td.useEffect)(()=>{a&&a(!0),o&&(0,s5.emitKeypressEvents)(o)},[o,a]);let[c,_]=(0,td.useState)(new Map),t=(0,td.useMemo)(()=>({getAll:()=>c,get:O=>c.get(O),set:(O,N)=>_(new Map([...c,[O,N]]))}),[c,_]);return td.default.createElement(Z3.Provider,{value:t,children:i})};function sh(i,o){let a=(0,M4.useContext)(Z3);if(a===null)throw new Error("Expected this hook to run with a ministore context attached");if(typeof i=="undefined")return a.getAll();let c=(0,M4.useCallback)(t=>{a.set(i,t)},[i,a.set]),_=a.get(i);return typeof _=="undefined"&&(_=o),[_,c]}var k4=ou(sc()),$3=ou(ki());async function L4(i,o){let a,c=t=>{let{exit:O}=(0,k4.useApp)();g2({active:!0},(N,M)=>{M.name==="return"&&(a=t,O())},[O,t])},{waitUntilExit:_}=(0,k4.render)($3.default.createElement(a5,null,$3.default.createElement(i,Zr(Ht({},o),{useSubmit:c}))));return await _(),a}var x9=ou(require("clipanion")),A9=ou(p5()),or=ou(sc()),En=ou(ki());var T9=ou(S9()),gw={appId:"OFCNCOG2CU",apiKey:"6fe4476ee5a1832882e326b506d14126",indexName:"npm-search"},nq=(0,T9.default)(gw.appId,gw.apiKey).initIndex(gw.indexName),yw=async(i,o=0)=>await nq.search(i,{analyticsTags:["yarn-plugin-interactive-tools"],attributesToRetrieve:["name","version","owner","repository","humanDownloadsLast30Days"],page:o,hitsPerPage:10});var Vy=["regular","dev","peer"],Gy=class extends C9.BaseCommand{async execute(){let o=await ch.Configuration.find(this.context.cwd,this.context.plugins),a=()=>En.default.createElement(or.Box,{flexDirection:"row"},En.default.createElement(or.Box,{flexDirection:"column",width:48},En.default.createElement(or.Box,null,En.default.createElement(or.Text,null,"Press ",En.default.createElement(or.Text,{bold:!0,color:"cyanBright"},""),"/",En.default.createElement(or.Text,{bold:!0,color:"cyanBright"},"")," to move between packages.")),En.default.createElement(or.Box,null,En.default.createElement(or.Text,null,"Press ",En.default.createElement(or.Text,{bold:!0,color:"cyanBright"},"")," to select a package.")),En.default.createElement(or.Box,null,En.default.createElement(or.Text,null,"Press ",En.default.createElement(or.Text,{bold:!0,color:"cyanBright"},"")," again to change the target."))),En.default.createElement(or.Box,{flexDirection:"column"},En.default.createElement(or.Box,{marginLeft:1},En.default.createElement(or.Text,null,"Press ",En.default.createElement(or.Text,{bold:!0,color:"cyanBright"},"")," to install the selected packages.")),En.default.createElement(or.Box,{marginLeft:1},En.default.createElement(or.Text,null,"Press ",En.default.createElement(or.Text,{bold:!0,color:"cyanBright"},"")," to abort.")))),c=()=>En.default.createElement(En.default.Fragment,null,En.default.createElement(or.Box,{width:15},En.default.createElement(or.Text,{bold:!0,underline:!0,color:"gray"},"Owner")),En.default.createElement(or.Box,{width:11},En.default.createElement(or.Text,{bold:!0,underline:!0,color:"gray"},"Version")),En.default.createElement(or.Box,{width:10},En.default.createElement(or.Text,{bold:!0,underline:!0,color:"gray"},"Downloads"))),_=()=>En.default.createElement(or.Box,{width:17},En.default.createElement(or.Text,{bold:!0,underline:!0,color:"gray"},"Target")),t=({hit:ne,active:m})=>{let[he,De]=sh(ne.name,null);g2({active:m},(_e,ce)=>{if(ce.name!=="space")return;if(!he){De(Vy[0]);return}let me=Vy.indexOf(he)+1;me===Vy.length?De(null):De(Vy[me])},[he,De]);let se=ch.structUtils.parseIdent(ne.name),fe=ch.structUtils.prettyIdent(o,se);return En.default.createElement(or.Box,null,En.default.createElement(or.Box,{width:45},En.default.createElement(or.Text,{bold:!0,wrap:"wrap"},fe)),En.default.createElement(or.Box,{width:14,marginLeft:1},En.default.createElement(or.Text,{bold:!0,wrap:"truncate"},ne.owner.name)),En.default.createElement(or.Box,{width:10,marginLeft:1},En.default.createElement(or.Text,{italic:!0,wrap:"truncate"},ne.version)),En.default.createElement(or.Box,{width:16,marginLeft:1},En.default.createElement(or.Text,null,ne.humanDownloadsLast30Days)))},O=({name:ne,active:m})=>{let[he]=sh(ne,null),De=ch.structUtils.parseIdent(ne);return En.default.createElement(or.Box,null,En.default.createElement(or.Box,{width:47},En.default.createElement(or.Text,{bold:!0}," - ",ch.structUtils.prettyIdent(o,De))),Vy.map(se=>En.default.createElement(or.Box,{key:se,width:14,marginLeft:1},En.default.createElement(or.Text,null," ",En.default.createElement(C4,{active:he===se})," ",En.default.createElement(or.Text,{bold:!0},se)))))},N=()=>En.default.createElement(or.Box,{marginTop:1},En.default.createElement(or.Text,null,"Powered by Algolia.")),T=await L4(({useSubmit:ne})=>{let m=sh();ne(m);let he=Array.from(m.keys()).filter(je=>m.get(je)!==null),[De,se]=(0,En.useState)(""),[fe,_e]=(0,En.useState)(0),[ce,me]=(0,En.useState)([]),ie=je=>{je.match(/\t| /)||se(je)},Oe=async()=>{_e(0);let je=await yw(De);je.query===De&&me(je.hits)},Ue=async()=>{let je=await yw(De,fe+1);je.query===De&&je.page-1===fe&&(_e(je.page),me([...ce,...je.hits]))};return(0,En.useEffect)(()=>{De?Oe():me([])},[De]),En.default.createElement(or.Box,{flexDirection:"column"},En.default.createElement(a,null),En.default.createElement(or.Box,{flexDirection:"row",marginTop:1},En.default.createElement(or.Text,{bold:!0},"Search: "),En.default.createElement(or.Box,{width:41},En.default.createElement(A9.default,{value:De,onChange:ie,placeholder:"i.e. babel, webpack, react...",showCursor:!1})),En.default.createElement(c,null)),ce.length?En.default.createElement(O4,{radius:2,loop:!1,children:ce.map(je=>En.default.createElement(t,{key:je.name,hit:je,active:!1})),willReachEnd:Ue}):En.default.createElement(or.Text,{color:"gray"},"Start typing..."),En.default.createElement(or.Box,{flexDirection:"row",marginTop:1},En.default.createElement(or.Box,{width:49},En.default.createElement(or.Text,{bold:!0},"Selected:")),En.default.createElement(_,null)),he.length?he.map(je=>En.default.createElement(O,{key:je,name:je,active:!1})):En.default.createElement(or.Text,{color:"gray"},"No selected packages..."),En.default.createElement(N,null))},{});if(typeof T=="undefined")return 1;let B=Array.from(T.keys()).filter(ne=>T.get(ne)==="regular"),H=Array.from(T.keys()).filter(ne=>T.get(ne)==="dev"),q=Array.from(T.keys()).filter(ne=>T.get(ne)==="peer");return B.length&&await this.cli.run(["add",...B]),H.length&&await this.cli.run(["add","--dev",...H]),q&&await this.cli.run(["add","--peer",...q]),0}};Gy.paths=[["search"]],Gy.usage=x9.Command.Usage({category:"Interactive commands",description:"open the search interface",details:` + This command opens a fullscreen terminal interface where you can search for and install packages from the npm registry. + `,examples:[["Open the search window","yarn search"]]});var R9=Gy;var Q4=ou(require("@yarnpkg/cli")),Ao=ou(require("@yarnpkg/core"));var Yy=ou(sc()),E2=ou(ki());var O9=ou(sc()),M9=ou(ki()),j4=({length:i,active:o})=>{if(i===0)return null;let a=i>1?` ${"-".repeat(i-1)}`:" ";return M9.default.createElement(O9.Text,{dimColor:!o},a)};var k9=function({active:i,skewer:o,options:a,value:c,onChange:_,sizes:t=[]}){let O=a.filter(({label:M})=>!!M).map(({value:M})=>M),N=a.findIndex(M=>M.value===c&&M.label!="");return R4(c,O,{active:i,minus:"left",plus:"right",set:_}),E2.default.createElement(E2.default.Fragment,null,a.map(({label:M},T)=>{let B=T===N,H=t[T]-1||0,q=M.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,""),ne=Math.max(0,H-q.length-2);return M?E2.default.createElement(Yy.Box,{key:M,width:H,marginLeft:1},E2.default.createElement(Yy.Text,{wrap:"truncate"},E2.default.createElement(C4,{active:B})," ",M),o?E2.default.createElement(j4,{active:i,length:ne}):null):E2.default.createElement(Yy.Box,{key:`spacer-${T}`,width:H,marginLeft:1})}))};var vA=ou(require("@yarnpkg/plugin-essentials")),mA=ou(require("clipanion")),gA=ou(hA()),xi=ou(sc()),gr=ou(ki()),yA=ou(require("semver")),_A=/^((?:[\^~]|>=?)?)([0-9]+)(\.[0-9]+)(\.[0-9]+)((?:-\S+)?)$/,cW=10,t_=class extends Q4.BaseCommand{async execute(){let o=await Ao.Configuration.find(this.context.cwd,this.context.plugins),{project:a,workspace:c}=await Ao.Project.find(o,this.context.cwd),_=await Ao.Cache.find(o);if(!c)throw new Q4.WorkspaceRequiredError(a.cwd,this.context.cwd);await a.restoreInstallState({restoreResolutions:!1});let t=(se,fe)=>{let _e=(0,gA.diffWords)(se,fe),ce="";for(let me of _e)me.added?ce+=Ao.formatUtils.pretty(o,me.value,"green"):me.removed||(ce+=me.value);return ce},O=(se,fe)=>{if(se===fe)return fe;let _e=Ao.structUtils.parseRange(se),ce=Ao.structUtils.parseRange(fe),me=_e.selector.match(_A),ie=ce.selector.match(_A);if(!me||!ie)return t(se,fe);let Oe=["gray","red","yellow","green","magenta"],Ue=null,je="";for(let at=1;at{let ce=await vA.suggestUtils.fetchDescriptorFrom(se,_e,{project:a,cache:_,preserveModifier:fe,workspace:c});return ce!==null?ce.range:se.range},M=async se=>{let fe=yA.default.valid(se.range)?`^${se.range}`:se.range,[_e,ce]=await Promise.all([N(se,se.range,fe).catch(()=>null),N(se,se.range,"latest").catch(()=>null)]),me=[{value:null,label:se.range}];return _e&&_e!==se.range?me.push({value:_e,label:O(se.range,_e)}):me.push({value:null,label:""}),ce&&ce!==_e&&ce!==se.range?me.push({value:ce,label:O(se.range,ce)}):me.push({value:null,label:""}),me},T=()=>gr.default.createElement(xi.Box,{flexDirection:"row"},gr.default.createElement(xi.Box,{flexDirection:"column",width:49},gr.default.createElement(xi.Box,{marginLeft:1},gr.default.createElement(xi.Text,null,"Press ",gr.default.createElement(xi.Text,{bold:!0,color:"cyanBright"},""),"/",gr.default.createElement(xi.Text,{bold:!0,color:"cyanBright"},"")," to select packages.")),gr.default.createElement(xi.Box,{marginLeft:1},gr.default.createElement(xi.Text,null,"Press ",gr.default.createElement(xi.Text,{bold:!0,color:"cyanBright"},""),"/",gr.default.createElement(xi.Text,{bold:!0,color:"cyanBright"},"")," to select versions."))),gr.default.createElement(xi.Box,{flexDirection:"column"},gr.default.createElement(xi.Box,{marginLeft:1},gr.default.createElement(xi.Text,null,"Press ",gr.default.createElement(xi.Text,{bold:!0,color:"cyanBright"},"")," to install.")),gr.default.createElement(xi.Box,{marginLeft:1},gr.default.createElement(xi.Text,null,"Press ",gr.default.createElement(xi.Text,{bold:!0,color:"cyanBright"},"")," to abort.")))),B=()=>gr.default.createElement(xi.Box,{flexDirection:"row",paddingTop:1,paddingBottom:1},gr.default.createElement(xi.Box,{width:50},gr.default.createElement(xi.Text,{bold:!0},gr.default.createElement(xi.Text,{color:"greenBright"},"?")," Pick the packages you want to upgrade.")),gr.default.createElement(xi.Box,{width:17},gr.default.createElement(xi.Text,{bold:!0,underline:!0,color:"gray"},"Current")),gr.default.createElement(xi.Box,{width:17},gr.default.createElement(xi.Text,{bold:!0,underline:!0,color:"gray"},"Range")),gr.default.createElement(xi.Box,{width:17},gr.default.createElement(xi.Text,{bold:!0,underline:!0,color:"gray"},"Latest"))),H=({active:se,descriptor:fe,suggestions:_e})=>{let[ce,me]=sh(fe.descriptorHash,null),ie=Ao.structUtils.stringifyIdent(fe),Oe=Math.max(0,45-ie.length);return gr.default.createElement(gr.default.Fragment,null,gr.default.createElement(xi.Box,null,gr.default.createElement(xi.Box,{width:45},gr.default.createElement(xi.Text,{bold:!0},Ao.structUtils.prettyIdent(o,fe)),gr.default.createElement(j4,{active:se,length:Oe})),_e!==null?gr.default.createElement(k9,{active:se,options:_e,value:ce,skewer:!0,onChange:me,sizes:[17,17,17]}):gr.default.createElement(xi.Box,{marginLeft:2},gr.default.createElement(xi.Text,{color:"gray"},"Fetching suggestions..."))))},q=({dependencies:se})=>{let[fe,_e]=(0,gr.useState)(null),ce=(0,gr.useRef)(!0);return(0,gr.useEffect)(()=>()=>{ce.current=!1}),(0,gr.useEffect)(()=>{Promise.all(se.map(me=>M(me))).then(me=>{let ie=se.map((Oe,Ue)=>{let je=me[Ue];return[Oe,je]}).filter(([Oe,Ue])=>Ue.filter(je=>je.label!=="").length>1);ce.current&&_e(ie)})},[]),fe?fe.length?gr.default.createElement(O4,{radius:cW,children:fe.map(([me,ie])=>gr.default.createElement(H,{key:me.descriptorHash,active:!1,descriptor:me,suggestions:ie}))}):gr.default.createElement(xi.Text,null,"No upgrades found"):gr.default.createElement(xi.Text,null,"Fetching suggestions...")},m=await L4(({useSubmit:se})=>{se(sh());let fe=new Map;for(let ce of a.workspaces)for(let me of["dependencies","devDependencies"])for(let ie of ce.manifest[me].values())a.tryWorkspaceByDescriptor(ie)===null&&fe.set(ie.descriptorHash,ie);let _e=Ao.miscUtils.sortMap(fe.values(),ce=>Ao.structUtils.stringifyDescriptor(ce));return gr.default.createElement(xi.Box,{flexDirection:"column"},gr.default.createElement(T,null),gr.default.createElement(B,null),gr.default.createElement(q,{dependencies:_e}))},{});if(typeof m=="undefined")return 1;let he=!1;for(let se of a.workspaces)for(let fe of["dependencies","devDependencies"]){let _e=se.manifest[fe];for(let ce of _e.values()){let me=m.get(ce.descriptorHash);typeof me!="undefined"&&me!==null&&(_e.set(ce.identHash,Ao.structUtils.makeDescriptor(ce,me)),he=!0)}}return he?(await Ao.StreamReport.start({configuration:o,stdout:this.context.stdout,includeLogs:!this.context.quiet},async se=>{await a.install({cache:_,report:se})})).exitCode():0}};t_.paths=[["upgrade-interactive"]],t_.usage=mA.Command.Usage({category:"Interactive commands",description:"open the upgrade interface",details:` + This command opens a fullscreen terminal interface where you can see any out of date packages used by your application, their status compared to the latest versions available on the remote registry, and select packages to upgrade. + `,examples:[["Open the upgrade window","yarn upgrade-interactive"]]});var EA=t_;var pW={commands:[R9,EA]},hW=pW;return dW;})(); +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ +/** + * @license + * Lodash + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ +/** @license React v0.0.0-experimental-51a3aa6af + * react-debug-tools.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.0.0-experimental-51a3aa6af + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.0.0-experimental-51a3aa6af + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.18.0 + * scheduler-tracing.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.18.0 + * scheduler-tracing.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.18.0 + * scheduler.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.18.0 + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.24.0 + * react-reconciler.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.24.0 + * react-reconciler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v16.13.1 + * react.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v16.13.1 + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +return plugin; +} +}; diff --git a/.yarn/plugins/@yarnpkg/plugin-outdated.cjs b/.yarn/plugins/@yarnpkg/plugin-outdated.cjs new file mode 100644 index 00000000..75d378c0 --- /dev/null +++ b/.yarn/plugins/@yarnpkg/plugin-outdated.cjs @@ -0,0 +1,33 @@ +/* eslint-disable */ +//prettier-ignore +module.exports = { +name: "@yarnpkg/plugin-outdated", +factory: function (require) { +var plugin=(()=>{var Cr=Object.create,ge=Object.defineProperty,Er=Object.defineProperties,_r=Object.getOwnPropertyDescriptor,xr=Object.getOwnPropertyDescriptors,br=Object.getOwnPropertyNames,et=Object.getOwnPropertySymbols,Sr=Object.getPrototypeOf,tt=Object.prototype.hasOwnProperty,vr=Object.prototype.propertyIsEnumerable;var rt=(e,t,r)=>t in e?ge(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,k=(e,t)=>{for(var r in t||(t={}))tt.call(t,r)&&rt(e,r,t[r]);if(et)for(var r of et(t))vr.call(t,r)&&rt(e,r,t[r]);return e},q=(e,t)=>Er(e,xr(t)),Hr=e=>ge(e,"__esModule",{value:!0});var W=e=>{if(typeof require!="undefined")return require(e);throw new Error('Dynamic require of "'+e+'" is not supported')};var U=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),wr=(e,t)=>{for(var r in t)ge(e,r,{get:t[r],enumerable:!0})},Tr=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of br(t))!tt.call(e,n)&&n!=="default"&&ge(e,n,{get:()=>t[n],enumerable:!(r=_r(t,n))||r.enumerable});return e},re=e=>Tr(Hr(ge(e!=null?Cr(Sr(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var ve=U(V=>{"use strict";V.isInteger=e=>typeof e=="number"?Number.isInteger(e):typeof e=="string"&&e.trim()!==""?Number.isInteger(Number(e)):!1;V.find=(e,t)=>e.nodes.find(r=>r.type===t);V.exceedsLimit=(e,t,r=1,n)=>n===!1||!V.isInteger(e)||!V.isInteger(t)?!1:(Number(t)-Number(e))/Number(r)>=n;V.escapeNode=(e,t=0,r)=>{let n=e.nodes[t];!n||(r&&n.type===r||n.type==="open"||n.type==="close")&&n.escaped!==!0&&(n.value="\\"+n.value,n.escaped=!0)};V.encloseBrace=e=>e.type!=="brace"?!1:e.commas>>0+e.ranges>>0==0?(e.invalid=!0,!0):!1;V.isInvalidBrace=e=>e.type!=="brace"?!1:e.invalid===!0||e.dollar?!0:e.commas>>0+e.ranges>>0==0||e.open!==!0||e.close!==!0?(e.invalid=!0,!0):!1;V.isOpenOrClose=e=>e.type==="open"||e.type==="close"?!0:e.open===!0||e.close===!0;V.reduce=e=>e.reduce((t,r)=>(r.type==="text"&&t.push(r.value),r.type==="range"&&(r.type="text"),t),[]);V.flatten=(...e)=>{let t=[],r=n=>{for(let s=0;s{"use strict";var nt=ve();st.exports=(e,t={})=>{let r=(n,s={})=>{let a=t.escapeInvalid&&nt.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o="";if(n.value)return(a||i)&&nt.isOpenOrClose(n)?"\\"+n.value:n.value;if(n.value)return n.value;if(n.nodes)for(let d of n.nodes)o+=r(d);return o};return r(e)}});var it=U((es,at)=>{"use strict";at.exports=function(e){return typeof e=="number"?e-e==0:typeof e=="string"&&e.trim()!==""?Number.isFinite?Number.isFinite(+e):isFinite(+e):!1}});var gt=U((ts,dt)=>{"use strict";var ot=it(),ce=(e,t,r)=>{if(ot(e)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(t===void 0||e===t)return String(e);if(ot(t)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let n=k({relaxZeros:!0},r);typeof n.strictZeros=="boolean"&&(n.relaxZeros=n.strictZeros===!1);let s=String(n.relaxZeros),a=String(n.shorthand),i=String(n.capture),o=String(n.wrap),d=e+":"+t+"="+s+a+i+o;if(ce.cache.hasOwnProperty(d))return ce.cache[d].result;let y=Math.min(e,t),f=Math.max(e,t);if(Math.abs(y-f)===1){let A=e+"|"+t;return n.capture?`(${A})`:n.wrap===!1?A:`(?:${A})`}let R=ht(e)||ht(t),p={min:e,max:t,a:y,b:f},H=[],m=[];if(R&&(p.isPadded=R,p.maxLen=String(p.max).length),y<0){let A=f<0?Math.abs(f):1;m=ut(A,Math.abs(y),p,n),y=p.a=0}return f>=0&&(H=ut(y,f,p,n)),p.negatives=m,p.positives=H,p.result=$r(m,H,n),n.capture===!0?p.result=`(${p.result})`:n.wrap!==!1&&H.length+m.length>1&&(p.result=`(?:${p.result})`),ce.cache[d]=p,p.result};function $r(e,t,r){let n=Ne(e,t,"-",!1,r)||[],s=Ne(t,e,"",!1,r)||[],a=Ne(e,t,"-?",!0,r)||[];return n.concat(a).concat(s).join("|")}function Lr(e,t){let r=1,n=1,s=lt(e,r),a=new Set([t]);for(;e<=s&&s<=t;)a.add(s),r+=1,s=lt(e,r);for(s=pt(t+1,n)-1;e1&&o.count.pop(),o.count.push(f.count[0]),o.string=o.pattern+ft(o.count),i=y+1;continue}r.isPadded&&(R=Dr(y,r,n)),f.string=R+f.pattern+ft(f.count),a.push(f),i=y+1,o=f}return a}function Ne(e,t,r,n,s){let a=[];for(let i of e){let{string:o}=i;!n&&!ct(t,"string",o)&&a.push(r+o),n&&ct(t,"string",o)&&a.push(r+o)}return a}function kr(e,t){let r=[];for(let n=0;nt?1:t>e?-1:0}function ct(e,t,r){return e.some(n=>n[t]===r)}function lt(e,t){return Number(String(e).slice(0,-t)+"9".repeat(t))}function pt(e,t){return e-e%Math.pow(10,t)}function ft(e){let[t=0,r=""]=e;return r||t>1?`{${t+(r?","+r:"")}}`:""}function Ir(e,t,r){return`[${e}${t-e==1?"":"-"}${t}]`}function ht(e){return/^-?(0+)\d/.test(e)}function Dr(e,t,r){if(!t.isPadded)return e;let n=Math.abs(t.maxLen-String(e).length),s=r.relaxZeros!==!1;switch(n){case 0:return"";case 1:return s?"0?":"0";case 2:return s?"0{0,2}":"00";default:return s?`0{0,${n}}`:`0{${n}}`}}ce.cache={};ce.clearCache=()=>ce.cache={};dt.exports=ce});var Pe=U((rs,xt)=>{"use strict";var Pr=W("util"),yt=gt(),Rt=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Mr=e=>t=>e===!0?Number(t):String(t),Ie=e=>typeof e=="number"||typeof e=="string"&&e!=="",ye=e=>Number.isInteger(+e),De=e=>{let t=`${e}`,r=-1;if(t[0]==="-"&&(t=t.slice(1)),t==="0")return!1;for(;t[++r]==="0";);return r>0},Br=(e,t,r)=>typeof e=="string"||typeof t=="string"?!0:r.stringify===!0,Ur=(e,t,r)=>{if(t>0){let n=e[0]==="-"?"-":"";n&&(e=e.slice(1)),e=n+e.padStart(n?t-1:t,"0")}return r===!1?String(e):e},At=(e,t)=>{let r=e[0]==="-"?"-":"";for(r&&(e=e.slice(1),t--);e.length{e.negatives.sort((i,o)=>io?1:0),e.positives.sort((i,o)=>io?1:0);let r=t.capture?"":"?:",n="",s="",a;return e.positives.length&&(n=e.positives.join("|")),e.negatives.length&&(s=`-(${r}${e.negatives.join("|")})`),n&&s?a=`${n}|${s}`:a=n||s,t.wrap?`(${r}${a})`:a},mt=(e,t,r,n)=>{if(r)return yt(e,t,k({wrap:!1},n));let s=String.fromCharCode(e);if(e===t)return s;let a=String.fromCharCode(t);return`[${s}-${a}]`},Ct=(e,t,r)=>{if(Array.isArray(e)){let n=r.wrap===!0,s=r.capture?"":"?:";return n?`(${s}${e.join("|")})`:e.join("|")}return yt(e,t,r)},Et=(...e)=>new RangeError("Invalid range arguments: "+Pr.inspect(...e)),_t=(e,t,r)=>{if(r.strictRanges===!0)throw Et([e,t]);return[]},Fr=(e,t)=>{if(t.strictRanges===!0)throw new TypeError(`Expected step "${e}" to be a number`);return[]},Kr=(e,t,r=1,n={})=>{let s=Number(e),a=Number(t);if(!Number.isInteger(s)||!Number.isInteger(a)){if(n.strictRanges===!0)throw Et([e,t]);return[]}s===0&&(s=0),a===0&&(a=0);let i=s>a,o=String(e),d=String(t),y=String(r);r=Math.max(Math.abs(r),1);let f=De(o)||De(d)||De(y),R=f?Math.max(o.length,d.length,y.length):0,p=f===!1&&Br(e,t,n)===!1,H=n.transform||Mr(p);if(n.toRegex&&r===1)return mt(At(e,R),At(t,R),!0,n);let m={negatives:[],positives:[]},A=O=>m[O<0?"negatives":"positives"].push(Math.abs(O)),E=[],b=0;for(;i?s>=a:s<=a;)n.toRegex===!0&&r>1?A(s):E.push(Ur(H(s,b),R,p)),s=i?s-r:s+r,b++;return n.toRegex===!0?r>1?Gr(m,n):Ct(E,null,k({wrap:!1},n)):E},jr=(e,t,r=1,n={})=>{if(!ye(e)&&e.length>1||!ye(t)&&t.length>1)return _t(e,t,n);let s=n.transform||(p=>String.fromCharCode(p)),a=`${e}`.charCodeAt(0),i=`${t}`.charCodeAt(0),o=a>i,d=Math.min(a,i),y=Math.max(a,i);if(n.toRegex&&r===1)return mt(d,y,!1,n);let f=[],R=0;for(;o?a>=i:a<=i;)f.push(s(a,R)),a=o?a-r:a+r,R++;return n.toRegex===!0?Ct(f,null,{wrap:!1,options:n}):f},we=(e,t,r,n={})=>{if(t==null&&Ie(e))return[e];if(!Ie(e)||!Ie(t))return _t(e,t,n);if(typeof r=="function")return we(e,t,1,{transform:r});if(Rt(r))return we(e,t,0,r);let s=k({},n);return s.capture===!0&&(s.wrap=!0),r=r||s.step||1,ye(r)?ye(e)&&ye(t)?Kr(e,t,r,s):jr(e,t,Math.max(Math.abs(r),1),s):r!=null&&!Rt(r)?Fr(r,s):we(e,t,1,r)};xt.exports=we});var vt=U((ns,St)=>{"use strict";var qr=Pe(),bt=ve(),Wr=(e,t={})=>{let r=(n,s={})=>{let a=bt.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o=a===!0||i===!0,d=t.escapeInvalid===!0?"\\":"",y="";if(n.isOpen===!0||n.isClose===!0)return d+n.value;if(n.type==="open")return o?d+n.value:"(";if(n.type==="close")return o?d+n.value:")";if(n.type==="comma")return n.prev.type==="comma"?"":o?n.value:"|";if(n.value)return n.value;if(n.nodes&&n.ranges>0){let f=bt.reduce(n.nodes),R=qr(...f,q(k({},t),{wrap:!1,toRegex:!0}));if(R.length!==0)return f.length>1&&R.length>1?`(${R})`:R}if(n.nodes)for(let f of n.nodes)y+=r(f,n);return y};return r(e)};St.exports=Wr});var Tt=U((ss,wt)=>{"use strict";var Qr=Pe(),Ht=He(),pe=ve(),le=(e="",t="",r=!1)=>{let n=[];if(e=[].concat(e),t=[].concat(t),!t.length)return e;if(!e.length)return r?pe.flatten(t).map(s=>`{${s}}`):t;for(let s of e)if(Array.isArray(s))for(let a of s)n.push(le(a,t,r));else for(let a of t)r===!0&&typeof a=="string"&&(a=`{${a}}`),n.push(Array.isArray(a)?le(s,a,r):s+a);return pe.flatten(n)},Xr=(e,t={})=>{let r=t.rangeLimit===void 0?1e3:t.rangeLimit,n=(s,a={})=>{s.queue=[];let i=a,o=a.queue;for(;i.type!=="brace"&&i.type!=="root"&&i.parent;)i=i.parent,o=i.queue;if(s.invalid||s.dollar){o.push(le(o.pop(),Ht(s,t)));return}if(s.type==="brace"&&s.invalid!==!0&&s.nodes.length===2){o.push(le(o.pop(),["{}"]));return}if(s.nodes&&s.ranges>0){let R=pe.reduce(s.nodes);if(pe.exceedsLimit(...R,t.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let p=Qr(...R,t);p.length===0&&(p=Ht(s,t)),o.push(le(o.pop(),p)),s.nodes=[];return}let d=pe.encloseBrace(s),y=s.queue,f=s;for(;f.type!=="brace"&&f.type!=="root"&&f.parent;)f=f.parent,y=f.queue;for(let R=0;R{"use strict";$t.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` +`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var Dt=U((is,It)=>{"use strict";var zr=He(),{MAX_LENGTH:Ot,CHAR_BACKSLASH:Me,CHAR_BACKTICK:Zr,CHAR_COMMA:Vr,CHAR_DOT:Yr,CHAR_LEFT_PARENTHESES:Jr,CHAR_RIGHT_PARENTHESES:en,CHAR_LEFT_CURLY_BRACE:tn,CHAR_RIGHT_CURLY_BRACE:rn,CHAR_LEFT_SQUARE_BRACKET:kt,CHAR_RIGHT_SQUARE_BRACKET:Nt,CHAR_DOUBLE_QUOTE:nn,CHAR_SINGLE_QUOTE:sn,CHAR_NO_BREAK_SPACE:an,CHAR_ZERO_WIDTH_NOBREAK_SPACE:on}=Lt(),un=(e,t={})=>{if(typeof e!="string")throw new TypeError("Expected a string");let r=t||{},n=typeof r.maxLength=="number"?Math.min(Ot,r.maxLength):Ot;if(e.length>n)throw new SyntaxError(`Input length (${e.length}), exceeds max characters (${n})`);let s={type:"root",input:e,nodes:[]},a=[s],i=s,o=s,d=0,y=e.length,f=0,R=0,p,H={},m=()=>e[f++],A=E=>{if(E.type==="text"&&o.type==="dot"&&(o.type="text"),o&&o.type==="text"&&E.type==="text"){o.value+=E.value;return}return i.nodes.push(E),E.parent=i,E.prev=o,o=E,E};for(A({type:"bos"});f0){if(i.ranges>0){i.ranges=0;let E=i.nodes.shift();i.nodes=[E,{type:"text",value:zr(i)}]}A({type:"comma",value:p}),i.commas++;continue}if(p===Yr&&R>0&&i.commas===0){let E=i.nodes;if(R===0||E.length===0){A({type:"text",value:p});continue}if(o.type==="dot"){if(i.range=[],o.value+=p,o.type="range",i.nodes.length!==3&&i.nodes.length!==5){i.invalid=!0,i.ranges=0,o.type="text";continue}i.ranges++,i.args=[];continue}if(o.type==="range"){E.pop();let b=E[E.length-1];b.value+=o.value+p,o=b,i.ranges--;continue}A({type:"dot",value:p});continue}A({type:"text",value:p})}do if(i=a.pop(),i.type!=="root"){i.nodes.forEach(O=>{O.nodes||(O.type==="open"&&(O.isOpen=!0),O.type==="close"&&(O.isClose=!0),O.nodes||(O.type="text"),O.invalid=!0)});let E=a[a.length-1],b=E.nodes.indexOf(i);E.nodes.splice(b,1,...i.nodes)}while(a.length>0);return A({type:"eos"}),s};It.exports=un});var Bt=U((os,Mt)=>{"use strict";var Pt=He(),cn=vt(),ln=Tt(),pn=Dt(),z=(e,t={})=>{let r=[];if(Array.isArray(e))for(let n of e){let s=z.create(n,t);Array.isArray(s)?r.push(...s):r.push(s)}else r=[].concat(z.create(e,t));return t&&t.expand===!0&&t.nodupes===!0&&(r=[...new Set(r)]),r};z.parse=(e,t={})=>pn(e,t);z.stringify=(e,t={})=>typeof e=="string"?Pt(z.parse(e,t),t):Pt(e,t);z.compile=(e,t={})=>(typeof e=="string"&&(e=z.parse(e,t)),cn(e,t));z.expand=(e,t={})=>{typeof e=="string"&&(e=z.parse(e,t));let r=ln(e,t);return t.noempty===!0&&(r=r.filter(Boolean)),t.nodupes===!0&&(r=[...new Set(r)]),r};z.create=(e,t={})=>e===""||e.length<3?[e]:t.expand!==!0?z.compile(e,t):z.expand(e,t);Mt.exports=z});var Re=U((us,jt)=>{"use strict";var fn=W("path"),ne="\\\\/",Ut=`[^${ne}]`,ae="\\.",hn="\\+",dn="\\?",Te="\\/",gn="(?=.)",Gt="[^/]",Be=`(?:${Te}|$)`,Ft=`(?:^|${Te})`,Ue=`${ae}{1,2}${Be}`,yn=`(?!${ae})`,Rn=`(?!${Ft}${Ue})`,An=`(?!${ae}{0,1}${Be})`,mn=`(?!${Ue})`,Cn=`[^.${Te}]`,En=`${Gt}*?`,Kt={DOT_LITERAL:ae,PLUS_LITERAL:hn,QMARK_LITERAL:dn,SLASH_LITERAL:Te,ONE_CHAR:gn,QMARK:Gt,END_ANCHOR:Be,DOTS_SLASH:Ue,NO_DOT:yn,NO_DOTS:Rn,NO_DOT_SLASH:An,NO_DOTS_SLASH:mn,QMARK_NO_DOT:Cn,STAR:En,START_ANCHOR:Ft},_n=q(k({},Kt),{SLASH_LITERAL:`[${ne}]`,QMARK:Ut,STAR:`${Ut}*?`,DOTS_SLASH:`${ae}{1,2}(?:[${ne}]|$)`,NO_DOT:`(?!${ae})`,NO_DOTS:`(?!(?:^|[${ne}])${ae}{1,2}(?:[${ne}]|$))`,NO_DOT_SLASH:`(?!${ae}{0,1}(?:[${ne}]|$))`,NO_DOTS_SLASH:`(?!${ae}{1,2}(?:[${ne}]|$))`,QMARK_NO_DOT:`[^.${ne}]`,START_ANCHOR:`(?:^|[${ne}])`,END_ANCHOR:`(?:[${ne}]|$)`}),xn={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};jt.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:xn,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:fn.sep,extglobChars(e){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(e){return e===!0?_n:Kt}}});var Ae=U(Q=>{"use strict";var bn=W("path"),Sn=process.platform==="win32",{REGEX_BACKSLASH:vn,REGEX_REMOVE_BACKSLASH:Hn,REGEX_SPECIAL_CHARS:wn,REGEX_SPECIAL_CHARS_GLOBAL:Tn}=Re();Q.isObject=e=>e!==null&&typeof e=="object"&&!Array.isArray(e);Q.hasRegexChars=e=>wn.test(e);Q.isRegexChar=e=>e.length===1&&Q.hasRegexChars(e);Q.escapeRegex=e=>e.replace(Tn,"\\$1");Q.toPosixSlashes=e=>e.replace(vn,"/");Q.removeBackslashes=e=>e.replace(Hn,t=>t==="\\"?"":t);Q.supportsLookbehinds=()=>{let e=process.version.slice(1).split(".").map(Number);return e.length===3&&e[0]>=9||e[0]===8&&e[1]>=10};Q.isWindows=e=>e&&typeof e.windows=="boolean"?e.windows:Sn===!0||bn.sep==="\\";Q.escapeLast=(e,t,r)=>{let n=e.lastIndexOf(t,r);return n===-1?e:e[n-1]==="\\"?Q.escapeLast(e,t,n-1):`${e.slice(0,n)}\\${e.slice(n)}`};Q.removePrefix=(e,t={})=>{let r=e;return r.startsWith("./")&&(r=r.slice(2),t.prefix="./"),r};Q.wrapOutput=(e,t={},r={})=>{let n=r.contains?"":"^",s=r.contains?"":"$",a=`${n}(?:${e})${s}`;return t.negated===!0&&(a=`(?:^(?!${a}).*$)`),a}});var Yt=U((ls,Vt)=>{"use strict";var qt=Ae(),{CHAR_ASTERISK:Ge,CHAR_AT:$n,CHAR_BACKWARD_SLASH:me,CHAR_COMMA:Ln,CHAR_DOT:Fe,CHAR_EXCLAMATION_MARK:Ke,CHAR_FORWARD_SLASH:Wt,CHAR_LEFT_CURLY_BRACE:je,CHAR_LEFT_PARENTHESES:qe,CHAR_LEFT_SQUARE_BRACKET:On,CHAR_PLUS:kn,CHAR_QUESTION_MARK:Qt,CHAR_RIGHT_CURLY_BRACE:Nn,CHAR_RIGHT_PARENTHESES:Xt,CHAR_RIGHT_SQUARE_BRACKET:In}=Re(),zt=e=>e===Wt||e===me,Zt=e=>{e.isPrefix!==!0&&(e.depth=e.isGlobstar?Infinity:1)},Dn=(e,t)=>{let r=t||{},n=e.length-1,s=r.parts===!0||r.scanToEnd===!0,a=[],i=[],o=[],d=e,y=-1,f=0,R=0,p=!1,H=!1,m=!1,A=!1,E=!1,b=!1,O=!1,N=!1,J=!1,G=!1,ie=0,F,C,v={value:"",depth:0,isGlob:!1},B=()=>y>=n,l=()=>d.charCodeAt(y+1),$=()=>(F=C,d.charCodeAt(++y));for(;y0&&(oe=d.slice(0,f),d=d.slice(f),R-=f),w&&m===!0&&R>0?(w=d.slice(0,R),u=d.slice(R)):m===!0?(w="",u=d):w=d,w&&w!==""&&w!=="/"&&w!==d&&zt(w.charCodeAt(w.length-1))&&(w=w.slice(0,-1)),r.unescape===!0&&(u&&(u=qt.removeBackslashes(u)),w&&O===!0&&(w=qt.removeBackslashes(w)));let c={prefix:oe,input:e,start:f,base:w,glob:u,isBrace:p,isBracket:H,isGlob:m,isExtglob:A,isGlobstar:E,negated:N,negatedExtglob:J};if(r.tokens===!0&&(c.maxDepth=0,zt(C)||i.push(v),c.tokens=i),r.parts===!0||r.tokens===!0){let K;for(let S=0;S{"use strict";var $e=Re(),Z=Ae(),{MAX_LENGTH:Le,POSIX_REGEX_SOURCE:Pn,REGEX_NON_SPECIAL_CHARS:Mn,REGEX_SPECIAL_CHARS_BACKREF:Bn,REPLACEMENTS:Jt}=$e,Un=(e,t)=>{if(typeof t.expandRange=="function")return t.expandRange(...e,t);e.sort();let r=`[${e.join("-")}]`;try{new RegExp(r)}catch(n){return e.map(s=>Z.escapeRegex(s)).join("..")}return r},fe=(e,t)=>`Missing ${e}: "${t}" - use "\\\\${t}" to match literal characters`,er=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");e=Jt[e]||e;let r=k({},t),n=typeof r.maxLength=="number"?Math.min(Le,r.maxLength):Le,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);let a={type:"bos",value:"",output:r.prepend||""},i=[a],o=r.capture?"":"?:",d=Z.isWindows(t),y=$e.globChars(d),f=$e.extglobChars(y),{DOT_LITERAL:R,PLUS_LITERAL:p,SLASH_LITERAL:H,ONE_CHAR:m,DOTS_SLASH:A,NO_DOT:E,NO_DOT_SLASH:b,NO_DOTS_SLASH:O,QMARK:N,QMARK_NO_DOT:J,STAR:G,START_ANCHOR:ie}=y,F=g=>`(${o}(?:(?!${ie}${g.dot?A:R}).)*?)`,C=r.dot?"":E,v=r.dot?N:J,B=r.bash===!0?F(r):G;r.capture&&(B=`(${B})`),typeof r.noext=="boolean"&&(r.noextglob=r.noext);let l={input:e,index:-1,start:0,dot:r.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:i};e=Z.removePrefix(e,l),s=e.length;let $=[],w=[],oe=[],u=a,c,K=()=>l.index===s-1,S=l.peek=(g=1)=>e[l.index+g],ee=l.advance=()=>e[++l.index]||"",te=()=>e.slice(l.index+1),X=(g="",T=0)=>{l.consumed+=g,l.index+=T},_e=g=>{l.output+=g.output!=null?g.output:g.value,X(g.value)},Ar=()=>{let g=1;for(;S()==="!"&&(S(2)!=="("||S(3)==="?");)ee(),l.start++,g++;return g%2==0?!1:(l.negated=!0,l.start++,!0)},xe=g=>{l[g]++,oe.push(g)},ue=g=>{l[g]--,oe.pop()},x=g=>{if(u.type==="globstar"){let T=l.braces>0&&(g.type==="comma"||g.type==="brace"),h=g.extglob===!0||$.length&&(g.type==="pipe"||g.type==="paren");g.type!=="slash"&&g.type!=="paren"&&!T&&!h&&(l.output=l.output.slice(0,-u.output.length),u.type="star",u.value="*",u.output=B,l.output+=u.output)}if($.length&&g.type!=="paren"&&($[$.length-1].inner+=g.value),(g.value||g.output)&&_e(g),u&&u.type==="text"&&g.type==="text"){u.value+=g.value,u.output=(u.output||"")+g.value;return}g.prev=u,i.push(g),u=g},be=(g,T)=>{let h=q(k({},f[T]),{conditions:1,inner:""});h.prev=u,h.parens=l.parens,h.output=l.output;let _=(r.capture?"(":"")+h.open;xe("parens"),x({type:g,value:T,output:l.output?"":m}),x({type:"paren",extglob:!0,value:ee(),output:_}),$.push(h)},mr=g=>{let T=g.close+(r.capture?")":""),h;if(g.type==="negate"){let _=B;g.inner&&g.inner.length>1&&g.inner.includes("/")&&(_=F(r)),(_!==B||K()||/^\)+$/.test(te()))&&(T=g.close=`)$))${_}`),g.inner.includes("*")&&(h=te())&&/^\.[^\\/.]+$/.test(h)&&(T=g.close=`)${h})${_})`),g.prev.type==="bos"&&(l.negatedExtglob=!0)}x({type:"paren",extglob:!0,value:c,output:T}),ue("parens")};if(r.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(e)){let g=!1,T=e.replace(Bn,(h,_,I,j,M,ke)=>j==="\\"?(g=!0,h):j==="?"?_?_+j+(M?N.repeat(M.length):""):ke===0?v+(M?N.repeat(M.length):""):N.repeat(I.length):j==="."?R.repeat(I.length):j==="*"?_?_+j+(M?B:""):B:_?h:`\\${h}`);return g===!0&&(r.unescape===!0?T=T.replace(/\\/g,""):T=T.replace(/\\+/g,h=>h.length%2==0?"\\\\":h?"\\":"")),T===e&&r.contains===!0?(l.output=e,l):(l.output=Z.wrapOutput(T,l,t),l)}for(;!K();){if(c=ee(),c==="\0")continue;if(c==="\\"){let h=S();if(h==="/"&&r.bash!==!0||h==="."||h===";")continue;if(!h){c+="\\",x({type:"text",value:c});continue}let _=/^\\+/.exec(te()),I=0;if(_&&_[0].length>2&&(I=_[0].length,l.index+=I,I%2!=0&&(c+="\\")),r.unescape===!0?c=ee():c+=ee(),l.brackets===0){x({type:"text",value:c});continue}}if(l.brackets>0&&(c!=="]"||u.value==="["||u.value==="[^")){if(r.posix!==!1&&c===":"){let h=u.value.slice(1);if(h.includes("[")&&(u.posix=!0,h.includes(":"))){let _=u.value.lastIndexOf("["),I=u.value.slice(0,_),j=u.value.slice(_+2),M=Pn[j];if(M){u.value=I+M,l.backtrack=!0,ee(),!a.output&&i.indexOf(u)===1&&(a.output=m);continue}}}(c==="["&&S()!==":"||c==="-"&&S()==="]")&&(c=`\\${c}`),c==="]"&&(u.value==="["||u.value==="[^")&&(c=`\\${c}`),r.posix===!0&&c==="!"&&u.value==="["&&(c="^"),u.value+=c,_e({value:c});continue}if(l.quotes===1&&c!=='"'){c=Z.escapeRegex(c),u.value+=c,_e({value:c});continue}if(c==='"'){l.quotes=l.quotes===1?0:1,r.keepQuotes===!0&&x({type:"text",value:c});continue}if(c==="("){xe("parens"),x({type:"paren",value:c});continue}if(c===")"){if(l.parens===0&&r.strictBrackets===!0)throw new SyntaxError(fe("opening","("));let h=$[$.length-1];if(h&&l.parens===h.parens+1){mr($.pop());continue}x({type:"paren",value:c,output:l.parens?")":"\\)"}),ue("parens");continue}if(c==="["){if(r.nobracket===!0||!te().includes("]")){if(r.nobracket!==!0&&r.strictBrackets===!0)throw new SyntaxError(fe("closing","]"));c=`\\${c}`}else xe("brackets");x({type:"bracket",value:c});continue}if(c==="]"){if(r.nobracket===!0||u&&u.type==="bracket"&&u.value.length===1){x({type:"text",value:c,output:`\\${c}`});continue}if(l.brackets===0){if(r.strictBrackets===!0)throw new SyntaxError(fe("opening","["));x({type:"text",value:c,output:`\\${c}`});continue}ue("brackets");let h=u.value.slice(1);if(u.posix!==!0&&h[0]==="^"&&!h.includes("/")&&(c=`/${c}`),u.value+=c,_e({value:c}),r.literalBrackets===!1||Z.hasRegexChars(h))continue;let _=Z.escapeRegex(u.value);if(l.output=l.output.slice(0,-u.value.length),r.literalBrackets===!0){l.output+=_,u.value=_;continue}u.value=`(${o}${_}|${u.value})`,l.output+=u.value;continue}if(c==="{"&&r.nobrace!==!0){xe("braces");let h={type:"brace",value:c,output:"(",outputIndex:l.output.length,tokensIndex:l.tokens.length};w.push(h),x(h);continue}if(c==="}"){let h=w[w.length-1];if(r.nobrace===!0||!h){x({type:"text",value:c,output:c});continue}let _=")";if(h.dots===!0){let I=i.slice(),j=[];for(let M=I.length-1;M>=0&&(i.pop(),I[M].type!=="brace");M--)I[M].type!=="dots"&&j.unshift(I[M].value);_=Un(j,r),l.backtrack=!0}if(h.comma!==!0&&h.dots!==!0){let I=l.output.slice(0,h.outputIndex),j=l.tokens.slice(h.tokensIndex);h.value=h.output="\\{",c=_="\\}",l.output=I;for(let M of j)l.output+=M.output||M.value}x({type:"brace",value:c,output:_}),ue("braces"),w.pop();continue}if(c==="|"){$.length>0&&$[$.length-1].conditions++,x({type:"text",value:c});continue}if(c===","){let h=c,_=w[w.length-1];_&&oe[oe.length-1]==="braces"&&(_.comma=!0,h="|"),x({type:"comma",value:c,output:h});continue}if(c==="/"){if(u.type==="dot"&&l.index===l.start+1){l.start=l.index+1,l.consumed="",l.output="",i.pop(),u=a;continue}x({type:"slash",value:c,output:H});continue}if(c==="."){if(l.braces>0&&u.type==="dot"){u.value==="."&&(u.output=R);let h=w[w.length-1];u.type="dots",u.output+=c,u.value+=c,h.dots=!0;continue}if(l.braces+l.parens===0&&u.type!=="bos"&&u.type!=="slash"){x({type:"text",value:c,output:R});continue}x({type:"dot",value:c,output:R});continue}if(c==="?"){if(!(u&&u.value==="(")&&r.noextglob!==!0&&S()==="("&&S(2)!=="?"){be("qmark",c);continue}if(u&&u.type==="paren"){let _=S(),I=c;if(_==="<"&&!Z.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(u.value==="("&&!/[!=<:]/.test(_)||_==="<"&&!/<([!=]|\w+>)/.test(te()))&&(I=`\\${c}`),x({type:"text",value:c,output:I});continue}if(r.dot!==!0&&(u.type==="slash"||u.type==="bos")){x({type:"qmark",value:c,output:J});continue}x({type:"qmark",value:c,output:N});continue}if(c==="!"){if(r.noextglob!==!0&&S()==="("&&(S(2)!=="?"||!/[!=<:]/.test(S(3)))){be("negate",c);continue}if(r.nonegate!==!0&&l.index===0){Ar();continue}}if(c==="+"){if(r.noextglob!==!0&&S()==="("&&S(2)!=="?"){be("plus",c);continue}if(u&&u.value==="("||r.regex===!1){x({type:"plus",value:c,output:p});continue}if(u&&(u.type==="bracket"||u.type==="paren"||u.type==="brace")||l.parens>0){x({type:"plus",value:c});continue}x({type:"plus",value:p});continue}if(c==="@"){if(r.noextglob!==!0&&S()==="("&&S(2)!=="?"){x({type:"at",extglob:!0,value:c,output:""});continue}x({type:"text",value:c});continue}if(c!=="*"){(c==="$"||c==="^")&&(c=`\\${c}`);let h=Mn.exec(te());h&&(c+=h[0],l.index+=h[0].length),x({type:"text",value:c});continue}if(u&&(u.type==="globstar"||u.star===!0)){u.type="star",u.star=!0,u.value+=c,u.output=B,l.backtrack=!0,l.globstar=!0,X(c);continue}let g=te();if(r.noextglob!==!0&&/^\([^?]/.test(g)){be("star",c);continue}if(u.type==="star"){if(r.noglobstar===!0){X(c);continue}let h=u.prev,_=h.prev,I=h.type==="slash"||h.type==="bos",j=_&&(_.type==="star"||_.type==="globstar");if(r.bash===!0&&(!I||g[0]&&g[0]!=="/")){x({type:"star",value:c,output:""});continue}let M=l.braces>0&&(h.type==="comma"||h.type==="brace"),ke=$.length&&(h.type==="pipe"||h.type==="paren");if(!I&&h.type!=="paren"&&!M&&!ke){x({type:"star",value:c,output:""});continue}for(;g.slice(0,3)==="/**";){let Se=e[l.index+4];if(Se&&Se!=="/")break;g=g.slice(3),X("/**",3)}if(h.type==="bos"&&K()){u.type="globstar",u.value+=c,u.output=F(r),l.output=u.output,l.globstar=!0,X(c);continue}if(h.type==="slash"&&h.prev.type!=="bos"&&!j&&K()){l.output=l.output.slice(0,-(h.output+u.output).length),h.output=`(?:${h.output}`,u.type="globstar",u.output=F(r)+(r.strictSlashes?")":"|$)"),u.value+=c,l.globstar=!0,l.output+=h.output+u.output,X(c);continue}if(h.type==="slash"&&h.prev.type!=="bos"&&g[0]==="/"){let Se=g[1]!==void 0?"|$":"";l.output=l.output.slice(0,-(h.output+u.output).length),h.output=`(?:${h.output}`,u.type="globstar",u.output=`${F(r)}${H}|${H}${Se})`,u.value+=c,l.output+=h.output+u.output,l.globstar=!0,X(c+ee()),x({type:"slash",value:"/",output:""});continue}if(h.type==="bos"&&g[0]==="/"){u.type="globstar",u.value+=c,u.output=`(?:^|${H}|${F(r)}${H})`,l.output=u.output,l.globstar=!0,X(c+ee()),x({type:"slash",value:"/",output:""});continue}l.output=l.output.slice(0,-u.output.length),u.type="globstar",u.output=F(r),u.value+=c,l.output+=u.output,l.globstar=!0,X(c);continue}let T={type:"star",value:c,output:B};if(r.bash===!0){T.output=".*?",(u.type==="bos"||u.type==="slash")&&(T.output=C+T.output),x(T);continue}if(u&&(u.type==="bracket"||u.type==="paren")&&r.regex===!0){T.output=c,x(T);continue}(l.index===l.start||u.type==="slash"||u.type==="dot")&&(u.type==="dot"?(l.output+=b,u.output+=b):r.dot===!0?(l.output+=O,u.output+=O):(l.output+=C,u.output+=C),S()!=="*"&&(l.output+=m,u.output+=m)),x(T)}for(;l.brackets>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing","]"));l.output=Z.escapeLast(l.output,"["),ue("brackets")}for(;l.parens>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing",")"));l.output=Z.escapeLast(l.output,"("),ue("parens")}for(;l.braces>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing","}"));l.output=Z.escapeLast(l.output,"{"),ue("braces")}if(r.strictSlashes!==!0&&(u.type==="star"||u.type==="bracket")&&x({type:"maybe_slash",value:"",output:`${H}?`}),l.backtrack===!0){l.output="";for(let g of l.tokens)l.output+=g.output!=null?g.output:g.value,g.suffix&&(l.output+=g.suffix)}return l};er.fastpaths=(e,t)=>{let r=k({},t),n=typeof r.maxLength=="number"?Math.min(Le,r.maxLength):Le,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);e=Jt[e]||e;let a=Z.isWindows(t),{DOT_LITERAL:i,SLASH_LITERAL:o,ONE_CHAR:d,DOTS_SLASH:y,NO_DOT:f,NO_DOTS:R,NO_DOTS_SLASH:p,STAR:H,START_ANCHOR:m}=$e.globChars(a),A=r.dot?R:f,E=r.dot?p:f,b=r.capture?"":"?:",O={negated:!1,prefix:""},N=r.bash===!0?".*?":H;r.capture&&(N=`(${N})`);let J=C=>C.noglobstar===!0?N:`(${b}(?:(?!${m}${C.dot?y:i}).)*?)`,G=C=>{switch(C){case"*":return`${A}${d}${N}`;case".*":return`${i}${d}${N}`;case"*.*":return`${A}${N}${i}${d}${N}`;case"*/*":return`${A}${N}${o}${d}${E}${N}`;case"**":return A+J(r);case"**/*":return`(?:${A}${J(r)}${o})?${E}${d}${N}`;case"**/*.*":return`(?:${A}${J(r)}${o})?${E}${N}${i}${d}${N}`;case"**/.*":return`(?:${A}${J(r)}${o})?${i}${d}${N}`;default:{let v=/^(.*?)\.(\w+)$/.exec(C);if(!v)return;let B=G(v[1]);return B?B+i+v[2]:void 0}}},ie=Z.removePrefix(e,O),F=G(ie);return F&&r.strictSlashes!==!0&&(F+=`${o}?`),F};tr.exports=er});var sr=U((fs,nr)=>{"use strict";var Gn=W("path"),Fn=Yt(),We=rr(),Qe=Ae(),Kn=Re(),jn=e=>e&&typeof e=="object"&&!Array.isArray(e),D=(e,t,r=!1)=>{if(Array.isArray(e)){let f=e.map(p=>D(p,t,r));return p=>{for(let H of f){let m=H(p);if(m)return m}return!1}}let n=jn(e)&&e.tokens&&e.input;if(e===""||typeof e!="string"&&!n)throw new TypeError("Expected pattern to be a non-empty string");let s=t||{},a=Qe.isWindows(t),i=n?D.compileRe(e,t):D.makeRe(e,t,!1,!0),o=i.state;delete i.state;let d=()=>!1;if(s.ignore){let f=q(k({},t),{ignore:null,onMatch:null,onResult:null});d=D(s.ignore,f,r)}let y=(f,R=!1)=>{let{isMatch:p,match:H,output:m}=D.test(f,i,t,{glob:e,posix:a}),A={glob:e,state:o,regex:i,posix:a,input:f,output:m,match:H,isMatch:p};return typeof s.onResult=="function"&&s.onResult(A),p===!1?(A.isMatch=!1,R?A:!1):d(f)?(typeof s.onIgnore=="function"&&s.onIgnore(A),A.isMatch=!1,R?A:!1):(typeof s.onMatch=="function"&&s.onMatch(A),R?A:!0)};return r&&(y.state=o),y};D.test=(e,t,r,{glob:n,posix:s}={})=>{if(typeof e!="string")throw new TypeError("Expected input to be a string");if(e==="")return{isMatch:!1,output:""};let a=r||{},i=a.format||(s?Qe.toPosixSlashes:null),o=e===n,d=o&&i?i(e):e;return o===!1&&(d=i?i(e):e,o=d===n),(o===!1||a.capture===!0)&&(a.matchBase===!0||a.basename===!0?o=D.matchBase(e,t,r,s):o=t.exec(d)),{isMatch:Boolean(o),match:o,output:d}};D.matchBase=(e,t,r,n=Qe.isWindows(r))=>(t instanceof RegExp?t:D.makeRe(t,r)).test(Gn.basename(e));D.isMatch=(e,t,r)=>D(t,r)(e);D.parse=(e,t)=>Array.isArray(e)?e.map(r=>D.parse(r,t)):We(e,q(k({},t),{fastpaths:!1}));D.scan=(e,t)=>Fn(e,t);D.compileRe=(e,t,r=!1,n=!1)=>{if(r===!0)return e.output;let s=t||{},a=s.contains?"":"^",i=s.contains?"":"$",o=`${a}(?:${e.output})${i}`;e&&e.negated===!0&&(o=`^(?!${o}).*$`);let d=D.toRegex(o,t);return n===!0&&(d.state=e),d};D.makeRe=(e,t={},r=!1,n=!1)=>{if(!e||typeof e!="string")throw new TypeError("Expected a non-empty string");let s={negated:!1,fastpaths:!0};return t.fastpaths!==!1&&(e[0]==="."||e[0]==="*")&&(s.output=We.fastpaths(e,t)),s.output||(s=We(e,t)),D.compileRe(s,t,r,n)};D.toRegex=(e,t)=>{try{let r=t||{};return new RegExp(e,r.flags||(r.nocase?"i":""))}catch(r){if(t&&t.debug===!0)throw r;return/$^/}};D.constants=Kn;nr.exports=D});var ir=U((hs,ar)=>{"use strict";ar.exports=sr()});var pr=U((ds,lr)=>{"use strict";var or=W("util"),ur=Bt(),se=ir(),Xe=Ae(),cr=e=>e===""||e==="./",L=(e,t,r)=>{t=[].concat(t),e=[].concat(e);let n=new Set,s=new Set,a=new Set,i=0,o=f=>{a.add(f.output),r&&r.onResult&&r.onResult(f)};for(let f=0;f!n.has(f));if(r&&y.length===0){if(r.failglob===!0)throw new Error(`No matches found for "${t.join(", ")}"`);if(r.nonull===!0||r.nullglob===!0)return r.unescape?t.map(f=>f.replace(/\\/g,"")):t}return y};L.match=L;L.matcher=(e,t)=>se(e,t);L.isMatch=(e,t,r)=>se(t,r)(e);L.any=L.isMatch;L.not=(e,t,r={})=>{t=[].concat(t).map(String);let n=new Set,s=[],a=o=>{r.onResult&&r.onResult(o),s.push(o.output)},i=L(e,t,q(k({},r),{onResult:a}));for(let o of s)i.includes(o)||n.add(o);return[...n]};L.contains=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${or.inspect(e)}"`);if(Array.isArray(t))return t.some(n=>L.contains(e,n,r));if(typeof t=="string"){if(cr(e)||cr(t))return!1;if(e.includes(t)||e.startsWith("./")&&e.slice(2).includes(t))return!0}return L.isMatch(e,t,q(k({},r),{contains:!0}))};L.matchKeys=(e,t,r)=>{if(!Xe.isObject(e))throw new TypeError("Expected the first argument to be an object");let n=L(Object.keys(e),t,r),s={};for(let a of n)s[a]=e[a];return s};L.some=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=se(String(s),r);if(n.some(i=>a(i)))return!0}return!1};L.every=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=se(String(s),r);if(!n.every(i=>a(i)))return!1}return!0};L.all=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${or.inspect(e)}"`);return[].concat(t).every(n=>se(n,r)(e))};L.capture=(e,t,r)=>{let n=Xe.isWindows(r),a=se.makeRe(String(e),q(k({},r),{capture:!0})).exec(n?Xe.toPosixSlashes(t):t);if(a)return a.slice(1).map(i=>i===void 0?"":i)};L.makeRe=(...e)=>se.makeRe(...e);L.scan=(...e)=>se.scan(...e);L.parse=(e,t)=>{let r=[];for(let n of[].concat(e||[]))for(let s of ur(String(n),t))r.push(se.parse(s,t));return r};L.braces=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return t&&t.nobrace===!0||!/\{.*\}/.test(e)?[e]:ur(e,t)};L.braceExpand=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return L.braces(e,q(k({},t),{expand:!0}))};lr.exports=L});var Zn={};wr(Zn,{default:()=>zn});var Oe=re(W("@yarnpkg/cli")),P=re(W("@yarnpkg/core")),Y=re(W("clipanion")),Rr=re(pr()),Ye=re(W("semver")),Je=re(W("typanion"));var he=re(W("@yarnpkg/core")),gr=re(W("@yarnpkg/plugin-essentials"));var Ce=re(W("semver")),fr=Boolean;function qn(e){var s;let[t,r,n]=(s=e.match(/(github|bitbucket|gitlab):(.+)/))!=null?s:[];return r?`https://${r}.${r==="bitbucket"?"org":"com"}/${n}`:`https://github.com/${e}`}function hr(e){let{homepage:t,repository:r}=e.raw;return t||(typeof r=="string"?qn(r):r==null?void 0:r.url)}function dr(e,t){return Ce.default.parse(t).prerelease.length?Ce.default.lt(e,t):Ce.default.lt(Ce.default.coerce(e),t)}var ze=class{constructor(t,r,n,s){this.configuration=t;this.project=r;this.workspace=n;this.cache=s}async fetch({pkg:t,range:r,url:n}){let s=gr.suggestUtils.fetchDescriptorFrom(t,r,{cache:this.cache,preserveModifier:!1,project:this.project,workspace:this.workspace}),a=n?this.fetchURL(t):Promise.resolve(void 0),[i,o]=await Promise.all([s,a]);if(!i){let d=he.structUtils.prettyIdent(this.configuration,t);throw new Error(`Could not fetch candidate for ${d}.`)}return{url:o,version:i.range}}async fetchURL(t){var a;let r=this.configuration.makeFetcher(),n=await r.fetch(t,{cache:this.cache,checksums:this.project.storedChecksums,fetcher:r,project:this.project,report:new he.ThrowReport,skipIntegrityCheck:!0}),s;try{s=await he.Manifest.find(n.prefixPath,{baseFs:n.packageFs})}finally{(a=n.releaseFs)==null||a.call(n)}return hr(s)}};var de=re(W("@yarnpkg/core")),Wn=/^([0-9]+\.)([0-9]+\.)(.+)$/,Qn=["name","current","latest","workspace","type","url"],Ze=class{constructor(t,r,n,s){this.report=t;this.configuration=r;this.dependencies=n;this.extraColumns=s;this.sizes=null;this.headers={current:"Current",latest:"Latest",name:"Package",type:"Package Type",url:"URL",workspace:"Workspace"}}print(){this.sizes=this.getColumnSizes(),this.printHeader(),this.dependencies.forEach(t=>{var n,s;let r=this.getDiffColor(t);this.printRow({current:t.current.padEnd(this.sizes.current),latest:this.formatVersion(t,"latest",r),name:this.applyColor(t.name.padEnd(this.sizes.name),r),type:t.type.padEnd(this.sizes.type),url:(n=t.url)==null?void 0:n.padEnd(this.sizes.url),workspace:(s=t.workspace)==null?void 0:s.padEnd(this.sizes.workspace)})})}applyColor(t,r){return de.formatUtils.pretty(this.configuration,t,r)}formatVersion(t,r,n){let s=t[r].padEnd(this.sizes[r]),a=s.match(Wn);if(!a)return s;let i=["red","yellow","green"].indexOf(n)+1,o=a.slice(1,i).join(""),d=a.slice(i).join("");return o+de.formatUtils.pretty(this.configuration,this.applyColor(d,n),"bold")}getDiffColor(t){return{major:"red",minor:"yellow",patch:"green"}[t.severity]}getColumnSizes(){let t={current:this.headers.current.length,latest:this.headers.latest.length,name:this.headers.name.length,type:this.headers.type.length,url:this.headers.url.length,workspace:this.headers.workspace.length};for(let r of this.dependencies)for(let[n,s]of Object.entries(r)){let a=t[n],i=(s||"").length;t[n]=a>i?a:i}return t}formatColumnHeader(t){return de.formatUtils.pretty(this.configuration,this.headers[t].padEnd(this.sizes[t]),"bold")}printHeader(){this.printRow({current:this.formatColumnHeader("current"),latest:this.formatColumnHeader("latest"),name:this.formatColumnHeader("name"),type:this.formatColumnHeader("type"),url:this.formatColumnHeader("url"),workspace:this.formatColumnHeader("workspace")})}printRow(t){let r=Qn.filter(n=>{var s;return(s=this.extraColumns[n])!=null?s:!0}).map(n=>t[n]).join(" ").trim();this.report.reportInfo(de.MessageName.UNNAMED,r)}};var Ve=["dependencies","devDependencies"],yr=["major","minor","patch"];var Ee=class extends Oe.BaseCommand{constructor(){super(...arguments);this.patterns=Y.Option.Rest();this.all=Y.Option.Boolean("-a,--all",!1,{description:"Include outdated dependencies from all workspaces"});this.check=Y.Option.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when outdated dependencies are found"});this.json=Y.Option.Boolean("--json",!1,{description:"Format the output as JSON"});this.severity=Y.Option.String("-s,--severity",{description:"Filter results based on the severity of the update",validator:Je.default.isEnum(yr)});this.type=Y.Option.String("-t,--type",{description:"Filter results based on the dependency type",validator:Je.default.isEnum(Ve)});this.url=Y.Option.Boolean("--url",!1,{description:"Include the homepage URL of each package in the output"})}async execute(){let{cache:t,configuration:r,project:n,workspace:s}=await this.loadProject(),a=new ze(r,n,s,t),i=this.getWorkspaces(n,s),o=this.getDependencies(r,i);if(this.json){let y=await this.getOutdatedDependencies(a,o);this.context.stdout.write(JSON.stringify(y)+` +`);return}return(await P.StreamReport.start({configuration:r,stdout:this.context.stdout},async y=>{await this.checkOutdatedDependencies(r,o,a,y)})).exitCode()}async checkOutdatedDependencies(t,r,n,s){let a=null;await s.startTimerPromise("Checking for outdated dependencies",async()=>{let i=r.length,o=P.StreamReport.progressViaCounter(i);s.reportProgress(o),a=await this.getOutdatedDependencies(n,r,o)}),s.reportSeparator(),a.length?(new Ze(s,t,a,{url:this.url,workspace:this.all}).print(),s.reportSeparator(),this.printOutdatedCount(s,a.length)):this.printUpToDate(t,s)}async loadProject(){let t=await P.Configuration.find(this.context.cwd,this.context.plugins),[r,{project:n,workspace:s}]=await Promise.all([P.Cache.find(t),P.Project.find(t,this.context.cwd)]);if(await n.restoreInstallState(),!s)throw new Oe.WorkspaceRequiredError(n.cwd,this.context.cwd);return{cache:r,configuration:t,project:n,workspace:s}}getWorkspaces(t,r){return this.all?t.workspaces:[r]}get dependencyTypes(){return this.type?[this.type]:Ve}getDependencies(t,r){let n=[];for(let a of r){let{anchoredLocator:i,project:o}=a,d=o.storedPackages.get(i.locatorHash);d||this.throw(t,i);for(let y of this.dependencyTypes)for(let f of a.manifest[y].values()){let{range:R}=f;if(R.includes(":")&&!R.startsWith("npm:"))continue;let p=d.dependencies.get(f.identHash);p||this.throw(t,f);let H=o.storedResolutions.get(p.descriptorHash);H||this.throw(t,p);let m=o.storedPackages.get(H);m||this.throw(t,p),n.push({dependencyType:y,name:P.structUtils.stringifyIdent(f),pkg:m,workspace:a})}}if(!this.patterns.length)return n;let s=n.filter(({name:a})=>Rr.default.isMatch(a,this.patterns));if(!s.length)throw new Y.UsageError(`Pattern ${P.formatUtils.prettyList(t,this.patterns,P.FormatType.CODE)} doesn't match any packages referenced by any workspace`);return s}throw(t,r){let n=P.structUtils.prettyIdent(t,r);throw new Error(`Package for ${n} not found in the project`)}getSeverity(t,r){let n=Ye.default.coerce(t),s=Ye.default.coerce(r);return s.major>n.major?"major":s.minor>n.minor?"minor":"patch"}async getOutdatedDependencies(t,r,n){let s=r.map(async({dependencyType:a,name:i,pkg:o,workspace:d})=>{if(d.project.tryWorkspaceByLocator(o))return;let{url:y,version:f}=await t.fetch({pkg:o,range:"latest",url:this.url});if(n==null||n.tick(),dr(o.version,f))return{current:o.version,latest:f,name:i,severity:this.getSeverity(o.version,f),type:a,url:y,workspace:this.all?this.getWorkspaceName(d):void 0}});return(await Promise.all(s)).filter(fr).filter(({severity:a})=>!this.severity||a===this.severity).sort((a,i)=>a.name.localeCompare(i.name))}getWorkspaceName(t){return t.manifest.name?P.structUtils.stringifyIdent(t.manifest.name):t.computeCandidateName()}printOutdatedCount(t,r){let n=[P.MessageName.UNNAMED,r===1?"1 dependency is out of date":`${r} dependencies are out of date`];this.check?t.reportError(...n):t.reportWarning(...n)}printUpToDate(t,r){let n="\u2728 All your dependencies are up to date!";r.reportInfo(P.MessageName.UNNAMED,P.formatUtils.pretty(t,n,"green"))}};Ee.paths=[["outdated"]],Ee.usage=Y.Command.Usage({description:"view outdated dependencies",details:` + This command finds outdated dependencies in a project and prints the result in a table or JSON format. + + This command accepts glob patterns as arguments to filter the output. Make sure to escape the patterns, to prevent your own shell from trying to expand them. + `,examples:[["View outdated dependencies","yarn outdated"],["View outdated dependencies with the `@babel` scope","yarn outdated '@babel/*'"],["Filter results to only include devDependencies","yarn outdated --type devDependencies"],["Filter results to only include major version updates","yarn outdated --severity major"]]});var Xn={commands:[Ee]},zn=Xn;return Zn;})(); +/*! + * fill-range + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + */ +/*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * to-regex-range + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ +return plugin; +} +}; diff --git a/.yarn/plugins/@yarnpkg/plugin-typescript.cjs b/.yarn/plugins/@yarnpkg/plugin-typescript.cjs new file mode 100644 index 00000000..5c1859e0 --- /dev/null +++ b/.yarn/plugins/@yarnpkg/plugin-typescript.cjs @@ -0,0 +1,9 @@ +/* eslint-disable */ +//prettier-ignore +module.exports = { +name: "@yarnpkg/plugin-typescript", +factory: function (require) { +var plugin=(()=>{var Ft=Object.create,H=Object.defineProperty,Bt=Object.defineProperties,Kt=Object.getOwnPropertyDescriptor,zt=Object.getOwnPropertyDescriptors,Gt=Object.getOwnPropertyNames,Q=Object.getOwnPropertySymbols,$t=Object.getPrototypeOf,ne=Object.prototype.hasOwnProperty,De=Object.prototype.propertyIsEnumerable;var Re=(e,t,r)=>t in e?H(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,u=(e,t)=>{for(var r in t||(t={}))ne.call(t,r)&&Re(e,r,t[r]);if(Q)for(var r of Q(t))De.call(t,r)&&Re(e,r,t[r]);return e},g=(e,t)=>Bt(e,zt(t)),Lt=e=>H(e,"__esModule",{value:!0});var R=(e,t)=>{var r={};for(var s in e)ne.call(e,s)&&t.indexOf(s)<0&&(r[s]=e[s]);if(e!=null&&Q)for(var s of Q(e))t.indexOf(s)<0&&De.call(e,s)&&(r[s]=e[s]);return r};var I=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Vt=(e,t)=>{for(var r in t)H(e,r,{get:t[r],enumerable:!0})},Qt=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Gt(t))!ne.call(e,s)&&s!=="default"&&H(e,s,{get:()=>t[s],enumerable:!(r=Kt(t,s))||r.enumerable});return e},C=e=>Qt(Lt(H(e!=null?Ft($t(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var xe=I(J=>{"use strict";Object.defineProperty(J,"__esModule",{value:!0});function _(e){let t=[...e.caches],r=t.shift();return r===void 0?ve():{get(s,n,a={miss:()=>Promise.resolve()}){return r.get(s,n,a).catch(()=>_({caches:t}).get(s,n,a))},set(s,n){return r.set(s,n).catch(()=>_({caches:t}).set(s,n))},delete(s){return r.delete(s).catch(()=>_({caches:t}).delete(s))},clear(){return r.clear().catch(()=>_({caches:t}).clear())}}}function ve(){return{get(e,t,r={miss:()=>Promise.resolve()}){return t().then(n=>Promise.all([n,r.miss(n)])).then(([n])=>n)},set(e,t){return Promise.resolve(t)},delete(e){return Promise.resolve()},clear(){return Promise.resolve()}}}J.createFallbackableCache=_;J.createNullCache=ve});var Ee=I(($s,qe)=>{qe.exports=xe()});var Te=I(ae=>{"use strict";Object.defineProperty(ae,"__esModule",{value:!0});function Jt(e={serializable:!0}){let t={};return{get(r,s,n={miss:()=>Promise.resolve()}){let a=JSON.stringify(r);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);let o=s(),d=n&&n.miss||(()=>Promise.resolve());return o.then(y=>d(y)).then(()=>o)},set(r,s){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(s):s,Promise.resolve(s)},delete(r){return delete t[JSON.stringify(r)],Promise.resolve()},clear(){return t={},Promise.resolve()}}}ae.createInMemoryCache=Jt});var we=I((Vs,Me)=>{Me.exports=Te()});var Ce=I(M=>{"use strict";Object.defineProperty(M,"__esModule",{value:!0});function Xt(e,t,r){let s={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers(){return e===oe.WithinHeaders?s:{}},queryParameters(){return e===oe.WithinQueryParameters?s:{}}}}function Yt(e){let t=0,r=()=>(t++,new Promise(s=>{setTimeout(()=>{s(e(r))},Math.min(100*t,1e3))}));return e(r)}function ke(e,t=(r,s)=>Promise.resolve()){return Object.assign(e,{wait(r){return ke(e.then(s=>Promise.all([t(s,r),s])).then(s=>s[1]))}})}function Zt(e){let t=e.length-1;for(t;t>0;t--){let r=Math.floor(Math.random()*(t+1)),s=e[t];e[t]=e[r],e[r]=s}return e}function er(e,t){return Object.keys(t!==void 0?t:{}).forEach(r=>{e[r]=t[r](e)}),e}function tr(e,...t){let r=0;return e.replace(/%s/g,()=>encodeURIComponent(t[r++]))}var rr="4.2.0",sr=e=>()=>e.transporter.requester.destroy(),oe={WithinQueryParameters:0,WithinHeaders:1};M.AuthMode=oe;M.addMethods=er;M.createAuth=Xt;M.createRetryablePromise=Yt;M.createWaitablePromise=ke;M.destroy=sr;M.encode=tr;M.shuffle=Zt;M.version=rr});var F=I((Js,Ue)=>{Ue.exports=Ce()});var Ne=I(ie=>{"use strict";Object.defineProperty(ie,"__esModule",{value:!0});var nr={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};ie.MethodEnum=nr});var B=I((Ys,We)=>{We.exports=Ne()});var Ze=I(A=>{"use strict";Object.defineProperty(A,"__esModule",{value:!0});var He=B();function ce(e,t){let r=e||{},s=r.data||{};return Object.keys(r).forEach(n=>{["timeout","headers","queryParameters","data","cacheable"].indexOf(n)===-1&&(s[n]=r[n])}),{data:Object.entries(s).length>0?s:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var X={Read:1,Write:2,Any:3},U={Up:1,Down:2,Timeouted:3},_e=2*60*1e3;function ue(e,t=U.Up){return g(u({},e),{status:t,lastUpdate:Date.now()})}function Fe(e){return e.status===U.Up||Date.now()-e.lastUpdate>_e}function Be(e){return e.status===U.Timeouted&&Date.now()-e.lastUpdate<=_e}function le(e){return{protocol:e.protocol||"https",url:e.url,accept:e.accept||X.Any}}function ar(e,t){return Promise.all(t.map(r=>e.get(r,()=>Promise.resolve(ue(r))))).then(r=>{let s=r.filter(d=>Fe(d)),n=r.filter(d=>Be(d)),a=[...s,...n],o=a.length>0?a.map(d=>le(d)):t;return{getTimeout(d,y){return(n.length===0&&d===0?1:n.length+3+d)*y},statelessHosts:o}})}var or=({isTimedOut:e,status:t})=>!e&&~~t==0,ir=e=>{let t=e.status;return e.isTimedOut||or(e)||~~(t/100)!=2&&~~(t/100)!=4},cr=({status:e})=>~~(e/100)==2,ur=(e,t)=>ir(e)?t.onRetry(e):cr(e)?t.onSucess(e):t.onFail(e);function Qe(e,t,r,s){let n=[],a=$e(r,s),o=Le(e,s),d=r.method,y=r.method!==He.MethodEnum.Get?{}:u(u({},r.data),s.data),b=u(u(u({"x-algolia-agent":e.userAgent.value},e.queryParameters),y),s.queryParameters),f=0,p=(h,S)=>{let O=h.pop();if(O===void 0)throw Ve(de(n));let P={data:a,headers:o,method:d,url:Ge(O,r.path,b),connectTimeout:S(f,e.timeouts.connect),responseTimeout:S(f,s.timeout)},x=j=>{let T={request:P,response:j,host:O,triesLeft:h.length};return n.push(T),T},v={onSucess:j=>Ke(j),onRetry(j){let T=x(j);return j.isTimedOut&&f++,Promise.all([e.logger.info("Retryable failure",pe(T)),e.hostsCache.set(O,ue(O,j.isTimedOut?U.Timeouted:U.Down))]).then(()=>p(h,S))},onFail(j){throw x(j),ze(j,de(n))}};return e.requester.send(P).then(j=>ur(j,v))};return ar(e.hostsCache,t).then(h=>p([...h.statelessHosts].reverse(),h.getTimeout))}function lr(e){let{hostsCache:t,logger:r,requester:s,requestsCache:n,responsesCache:a,timeouts:o,userAgent:d,hosts:y,queryParameters:b,headers:f}=e,p={hostsCache:t,logger:r,requester:s,requestsCache:n,responsesCache:a,timeouts:o,userAgent:d,headers:f,queryParameters:b,hosts:y.map(h=>le(h)),read(h,S){let O=ce(S,p.timeouts.read),P=()=>Qe(p,p.hosts.filter(j=>(j.accept&X.Read)!=0),h,O);if((O.cacheable!==void 0?O.cacheable:h.cacheable)!==!0)return P();let v={request:h,mappedRequestOptions:O,transporter:{queryParameters:p.queryParameters,headers:p.headers}};return p.responsesCache.get(v,()=>p.requestsCache.get(v,()=>p.requestsCache.set(v,P()).then(j=>Promise.all([p.requestsCache.delete(v),j]),j=>Promise.all([p.requestsCache.delete(v),Promise.reject(j)])).then(([j,T])=>T)),{miss:j=>p.responsesCache.set(v,j)})},write(h,S){return Qe(p,p.hosts.filter(O=>(O.accept&X.Write)!=0),h,ce(S,p.timeouts.write))}};return p}function dr(e){let t={value:`Algolia for JavaScript (${e})`,add(r){let s=`; ${r.segment}${r.version!==void 0?` (${r.version})`:""}`;return t.value.indexOf(s)===-1&&(t.value=`${t.value}${s}`),t}};return t}function Ke(e){try{return JSON.parse(e.content)}catch(t){throw Je(t.message,e)}}function ze({content:e,status:t},r){let s=e;try{s=JSON.parse(e).message}catch(n){}return Xe(s,t,r)}function pr(e,...t){let r=0;return e.replace(/%s/g,()=>encodeURIComponent(t[r++]))}function Ge(e,t,r){let s=Ye(r),n=`${e.protocol}://${e.url}/${t.charAt(0)==="/"?t.substr(1):t}`;return s.length&&(n+=`?${s}`),n}function Ye(e){let t=r=>Object.prototype.toString.call(r)==="[object Object]"||Object.prototype.toString.call(r)==="[object Array]";return Object.keys(e).map(r=>pr("%s=%s",r,t(e[r])?JSON.stringify(e[r]):e[r])).join("&")}function $e(e,t){if(e.method===He.MethodEnum.Get||e.data===void 0&&t.data===void 0)return;let r=Array.isArray(e.data)?e.data:u(u({},e.data),t.data);return JSON.stringify(r)}function Le(e,t){let r=u(u({},e.headers),t.headers),s={};return Object.keys(r).forEach(n=>{let a=r[n];s[n.toLowerCase()]=a}),s}function de(e){return e.map(t=>pe(t))}function pe(e){let t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return g(u({},e),{request:g(u({},e.request),{headers:u(u({},e.request.headers),t)})})}function Xe(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}function Je(e,t){return{name:"DeserializationError",message:e,response:t}}function Ve(e){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:e}}A.CallEnum=X;A.HostStatusEnum=U;A.createApiError=Xe;A.createDeserializationError=Je;A.createMappedRequestOptions=ce;A.createRetryError=Ve;A.createStatefulHost=ue;A.createStatelessHost=le;A.createTransporter=lr;A.createUserAgent=dr;A.deserializeFailure=ze;A.deserializeSuccess=Ke;A.isStatefulHostTimeouted=Be;A.isStatefulHostUp=Fe;A.serializeData=$e;A.serializeHeaders=Le;A.serializeQueryParameters=Ye;A.serializeUrl=Ge;A.stackFrameWithoutCredentials=pe;A.stackTraceWithoutCredentials=de});var K=I((en,et)=>{et.exports=Ze()});var tt=I(w=>{"use strict";Object.defineProperty(w,"__esModule",{value:!0});var N=F(),mr=K(),z=B(),hr=e=>{let t=e.region||"us",r=N.createAuth(N.AuthMode.WithinHeaders,e.appId,e.apiKey),s=mr.createTransporter(g(u({hosts:[{url:`analytics.${t}.algolia.com`}]},e),{headers:u(g(u({},r.headers()),{"content-type":"application/json"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)})),n=e.appId;return N.addMethods({appId:n,transporter:s},e.methods)},yr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Post,path:"2/abtests",data:t},r),gr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Delete,path:N.encode("2/abtests/%s",t)},r),fr=e=>(t,r)=>e.transporter.read({method:z.MethodEnum.Get,path:N.encode("2/abtests/%s",t)},r),br=e=>t=>e.transporter.read({method:z.MethodEnum.Get,path:"2/abtests"},t),Pr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Post,path:N.encode("2/abtests/%s/stop",t)},r);w.addABTest=yr;w.createAnalyticsClient=hr;w.deleteABTest=gr;w.getABTest=fr;w.getABTests=br;w.stopABTest=Pr});var st=I((rn,rt)=>{rt.exports=tt()});var at=I(G=>{"use strict";Object.defineProperty(G,"__esModule",{value:!0});var me=F(),jr=K(),nt=B(),Or=e=>{let t=e.region||"us",r=me.createAuth(me.AuthMode.WithinHeaders,e.appId,e.apiKey),s=jr.createTransporter(g(u({hosts:[{url:`recommendation.${t}.algolia.com`}]},e),{headers:u(g(u({},r.headers()),{"content-type":"application/json"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)}));return me.addMethods({appId:e.appId,transporter:s},e.methods)},Ir=e=>t=>e.transporter.read({method:nt.MethodEnum.Get,path:"1/strategies/personalization"},t),Ar=e=>(t,r)=>e.transporter.write({method:nt.MethodEnum.Post,path:"1/strategies/personalization",data:t},r);G.createRecommendationClient=Or;G.getPersonalizationStrategy=Ir;G.setPersonalizationStrategy=Ar});var it=I((nn,ot)=>{ot.exports=at()});var jt=I(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});var l=F(),q=K(),m=B(),Sr=require("crypto");function Y(e){let t=r=>e.request(r).then(s=>{if(e.batch!==void 0&&e.batch(s.hits),!e.shouldStop(s))return s.cursor?t({cursor:s.cursor}):t({page:(r.page||0)+1})});return t({})}var Dr=e=>{let t=e.appId,r=l.createAuth(e.authMode!==void 0?e.authMode:l.AuthMode.WithinHeaders,t,e.apiKey),s=q.createTransporter(g(u({hosts:[{url:`${t}-dsn.algolia.net`,accept:q.CallEnum.Read},{url:`${t}.algolia.net`,accept:q.CallEnum.Write}].concat(l.shuffle([{url:`${t}-1.algolianet.com`},{url:`${t}-2.algolianet.com`},{url:`${t}-3.algolianet.com`}]))},e),{headers:u(g(u({},r.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)})),n={transporter:s,appId:t,addAlgoliaAgent(a,o){s.userAgent.add({segment:a,version:o})},clearCache(){return Promise.all([s.requestsCache.clear(),s.responsesCache.clear()]).then(()=>{})}};return l.addMethods(n,e.methods)};function ct(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function ut(){return{name:"ObjectNotFoundError",message:"Object not found."}}function lt(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Rr=e=>(t,r)=>{let d=r||{},{queryParameters:s}=d,n=R(d,["queryParameters"]),a=u({acl:t},s!==void 0?{queryParameters:s}:{}),o=(y,b)=>l.createRetryablePromise(f=>$(e)(y.key,b).catch(p=>{if(p.status!==404)throw p;return f()}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:"1/keys",data:a},n),o)},vr=e=>(t,r,s)=>{let n=q.createMappedRequestOptions(s);return n.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:m.MethodEnum.Post,path:"1/clusters/mapping",data:{cluster:r}},n)},xr=e=>(t,r,s)=>e.transporter.write({method:m.MethodEnum.Post,path:"1/clusters/mapping/batch",data:{users:t,cluster:r}},s),Z=e=>(t,r,s)=>{let n=(a,o)=>L(e)(t,{methods:{waitTask:D}}).waitTask(a.taskID,o);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",t),data:{operation:"copy",destination:r}},s),n)},qr=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Rules]})),Er=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Settings]})),Tr=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Synonyms]})),Mr=e=>(t,r)=>{let s=(n,a)=>l.createRetryablePromise(o=>$(e)(t,a).then(o).catch(d=>{if(d.status!==404)throw d}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/keys/%s",t)},r),s)},wr=()=>(e,t)=>{let r=q.serializeQueryParameters(t),s=Sr.createHmac("sha256",e).update(r).digest("hex");return Buffer.from(s+r).toString("base64")},$=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/keys/%s",t)},r),kr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/logs"},t),Cr=()=>e=>{let t=Buffer.from(e,"base64").toString("ascii"),r=/validUntil=(\d+)/,s=t.match(r);if(s===null)throw lt();return parseInt(s[1],10)-Math.round(new Date().getTime()/1e3)},Ur=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping/top"},t),Nr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/clusters/mapping/%s",t)},r),Wr=e=>t=>{let n=t||{},{retrieveMappings:r}=n,s=R(n,["retrieveMappings"]);return r===!0&&(s.getClusters=!0),e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping/pending"},s)},L=e=>(t,r={})=>{let s={transporter:e.transporter,appId:e.appId,indexName:t};return l.addMethods(s,r.methods)},Hr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/keys"},t),_r=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters"},t),Fr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/indexes"},t),Br=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping"},t),Kr=e=>(t,r,s)=>{let n=(a,o)=>L(e)(t,{methods:{waitTask:D}}).waitTask(a.taskID,o);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",t),data:{operation:"move",destination:r}},s),n)},zr=e=>(t,r)=>{let s=(n,a)=>Promise.all(Object.keys(n.taskID).map(o=>L(e)(o,{methods:{waitTask:D}}).waitTask(n.taskID[o],a)));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:t}},r),s)},Gr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:t}},r),$r=e=>(t,r)=>{let s=t.map(n=>g(u({},n),{params:q.serializeQueryParameters(n.params||{})}));return e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:s},cacheable:!0},r)},Lr=e=>(t,r)=>Promise.all(t.map(s=>{let d=s.params,{facetName:n,facetQuery:a}=d,o=R(d,["facetName","facetQuery"]);return L(e)(s.indexName,{methods:{searchForFacetValues:dt}}).searchForFacetValues(n,a,u(u({},r),o))})),Vr=e=>(t,r)=>{let s=q.createMappedRequestOptions(r);return s.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:m.MethodEnum.Delete,path:"1/clusters/mapping"},s)},Qr=e=>(t,r)=>{let s=(n,a)=>l.createRetryablePromise(o=>$(e)(t,a).catch(d=>{if(d.status!==404)throw d;return o()}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/keys/%s/restore",t)},r),s)},Jr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:"1/clusters/mapping/search",data:{query:t}},r),Xr=e=>(t,r)=>{let s=Object.assign({},r),f=r||{},{queryParameters:n}=f,a=R(f,["queryParameters"]),o=n?{queryParameters:n}:{},d=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],y=p=>Object.keys(s).filter(h=>d.indexOf(h)!==-1).every(h=>p[h]===s[h]),b=(p,h)=>l.createRetryablePromise(S=>$(e)(t,h).then(O=>y(O)?Promise.resolve():S()));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Put,path:l.encode("1/keys/%s",t),data:o},a),b)},pt=e=>(t,r)=>{let s=(n,a)=>D(e)(n.taskID,a);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/batch",e.indexName),data:{requests:t}},r),s)},Yr=e=>t=>Y(g(u({},t),{shouldStop:r=>r.cursor===void 0,request:r=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/browse",e.indexName),data:r},t)})),Zr=e=>t=>{let r=u({hitsPerPage:1e3},t);return Y(g(u({},r),{shouldStop:s=>s.hits.lengthg(u({},n),{hits:n.hits.map(a=>(delete a._highlightResult,a))}))}}))},es=e=>t=>{let r=u({hitsPerPage:1e3},t);return Y(g(u({},r),{shouldStop:s=>s.hits.lengthg(u({},n),{hits:n.hits.map(a=>(delete a._highlightResult,a))}))}}))},te=e=>(t,r,s)=>{let y=s||{},{batchSize:n}=y,a=R(y,["batchSize"]),o={taskIDs:[],objectIDs:[]},d=(b=0)=>{let f=[],p;for(p=b;p({action:r,body:h})),a).then(h=>(o.objectIDs=o.objectIDs.concat(h.objectIDs),o.taskIDs.push(h.taskID),p++,d(p)))};return l.createWaitablePromise(d(),(b,f)=>Promise.all(b.taskIDs.map(p=>D(e)(p,f))))},ts=e=>t=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/clear",e.indexName)},t),(r,s)=>D(e)(r.taskID,s)),rs=e=>t=>{let a=t||{},{forwardToReplicas:r}=a,s=R(a,["forwardToReplicas"]),n=q.createMappedRequestOptions(s);return r&&(n.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/clear",e.indexName)},n),(o,d)=>D(e)(o.taskID,d))},ss=e=>t=>{let a=t||{},{forwardToReplicas:r}=a,s=R(a,["forwardToReplicas"]),n=q.createMappedRequestOptions(s);return r&&(n.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/clear",e.indexName)},n),(o,d)=>D(e)(o.taskID,d))},ns=e=>(t,r)=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/deleteByQuery",e.indexName),data:t},r),(s,n)=>D(e)(s.taskID,n)),as=e=>t=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s",e.indexName)},t),(r,s)=>D(e)(r.taskID,s)),os=e=>(t,r)=>l.createWaitablePromise(yt(e)([t],r).then(s=>({taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),yt=e=>(t,r)=>{let s=t.map(n=>({objectID:n}));return te(e)(s,k.DeleteObject,r)},is=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s/rules/%s",e.indexName,t)},a),(d,y)=>D(e)(d.taskID,y))},cs=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s/synonyms/%s",e.indexName,t)},a),(d,y)=>D(e)(d.taskID,y))},us=e=>t=>gt(e)(t).then(()=>!0).catch(r=>{if(r.status!==404)throw r;return!1}),ls=e=>(t,r)=>{let y=r||{},{query:s,paginate:n}=y,a=R(y,["query","paginate"]),o=0,d=()=>ft(e)(s||"",g(u({},a),{page:o})).then(b=>{for(let[f,p]of Object.entries(b.hits))if(t(p))return{object:p,position:parseInt(f,10),page:o};if(o++,n===!1||o>=b.nbPages)throw ut();return d()});return d()},ds=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/%s",e.indexName,t)},r),ps=()=>(e,t)=>{for(let[r,s]of Object.entries(e.hits))if(s.objectID===t)return parseInt(r,10);return-1},ms=e=>(t,r)=>{let o=r||{},{attributesToRetrieve:s}=o,n=R(o,["attributesToRetrieve"]),a=t.map(d=>u({indexName:e.indexName,objectID:d},s?{attributesToRetrieve:s}:{}));return e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:a}},n)},hs=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/rules/%s",e.indexName,t)},r),gt=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/settings",e.indexName),data:{getVersion:2}},t),ys=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/synonyms/%s",e.indexName,t)},r),bt=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/task/%s",e.indexName,t.toString())},r),gs=e=>(t,r)=>l.createWaitablePromise(Pt(e)([t],r).then(s=>({objectID:s.objectIDs[0],taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),Pt=e=>(t,r)=>{let o=r||{},{createIfNotExists:s}=o,n=R(o,["createIfNotExists"]),a=s?k.PartialUpdateObject:k.PartialUpdateObjectNoCreate;return te(e)(t,a,n)},fs=e=>(t,r)=>{let O=r||{},{safe:s,autoGenerateObjectIDIfNotExist:n,batchSize:a}=O,o=R(O,["safe","autoGenerateObjectIDIfNotExist","batchSize"]),d=(P,x,v,j)=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",P),data:{operation:v,destination:x}},j),(T,V)=>D(e)(T.taskID,V)),y=Math.random().toString(36).substring(7),b=`${e.indexName}_tmp_${y}`,f=he({appId:e.appId,transporter:e.transporter,indexName:b}),p=[],h=d(e.indexName,b,"copy",g(u({},o),{scope:["settings","synonyms","rules"]}));p.push(h);let S=(s?h.wait(o):h).then(()=>{let P=f(t,g(u({},o),{autoGenerateObjectIDIfNotExist:n,batchSize:a}));return p.push(P),s?P.wait(o):P}).then(()=>{let P=d(b,e.indexName,"move",o);return p.push(P),s?P.wait(o):P}).then(()=>Promise.all(p)).then(([P,x,v])=>({objectIDs:x.objectIDs,taskIDs:[P.taskID,...x.taskIDs,v.taskID]}));return l.createWaitablePromise(S,(P,x)=>Promise.all(p.map(v=>v.wait(x))))},bs=e=>(t,r)=>ye(e)(t,g(u({},r),{clearExistingRules:!0})),Ps=e=>(t,r)=>ge(e)(t,g(u({},r),{replaceExistingSynonyms:!0})),js=e=>(t,r)=>l.createWaitablePromise(he(e)([t],r).then(s=>({objectID:s.objectIDs[0],taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),he=e=>(t,r)=>{let o=r||{},{autoGenerateObjectIDIfNotExist:s}=o,n=R(o,["autoGenerateObjectIDIfNotExist"]),a=s?k.AddObject:k.UpdateObject;if(a===k.UpdateObject){for(let d of t)if(d.objectID===void 0)return l.createWaitablePromise(Promise.reject(ct()))}return te(e)(t,a,n)},Os=e=>(t,r)=>ye(e)([t],r),ye=e=>(t,r)=>{let d=r||{},{forwardToReplicas:s,clearExistingRules:n}=d,a=R(d,["forwardToReplicas","clearExistingRules"]),o=q.createMappedRequestOptions(a);return s&&(o.queryParameters.forwardToReplicas=1),n&&(o.queryParameters.clearExistingRules=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/batch",e.indexName),data:t},o),(y,b)=>D(e)(y.taskID,b))},Is=e=>(t,r)=>ge(e)([t],r),ge=e=>(t,r)=>{let d=r||{},{forwardToReplicas:s,replaceExistingSynonyms:n}=d,a=R(d,["forwardToReplicas","replaceExistingSynonyms"]),o=q.createMappedRequestOptions(a);return s&&(o.queryParameters.forwardToReplicas=1),n&&(o.queryParameters.replaceExistingSynonyms=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/batch",e.indexName),data:t},o),(y,b)=>D(e)(y.taskID,b))},ft=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r),dt=e=>(t,r,s)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},s),mt=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/search",e.indexName),data:{query:t}},r),ht=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/search",e.indexName),data:{query:t}},r),As=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Put,path:l.encode("1/indexes/%s/settings",e.indexName),data:t},a),(d,y)=>D(e)(d.taskID,y))},D=e=>(t,r)=>l.createRetryablePromise(s=>bt(e)(t,r).then(n=>n.status!=="published"?s():void 0)),Ss={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",ListIndexes:"listIndexes",Logs:"logs",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},k={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject"},ee={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},Ds={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},Rs={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};i.ApiKeyACLEnum=Ss;i.BatchActionEnum=k;i.ScopeEnum=ee;i.StrategyEnum=Ds;i.SynonymEnum=Rs;i.addApiKey=Rr;i.assignUserID=vr;i.assignUserIDs=xr;i.batch=pt;i.browseObjects=Yr;i.browseRules=Zr;i.browseSynonyms=es;i.chunkedBatch=te;i.clearObjects=ts;i.clearRules=rs;i.clearSynonyms=ss;i.copyIndex=Z;i.copyRules=qr;i.copySettings=Er;i.copySynonyms=Tr;i.createBrowsablePromise=Y;i.createMissingObjectIDError=ct;i.createObjectNotFoundError=ut;i.createSearchClient=Dr;i.createValidUntilNotFoundError=lt;i.deleteApiKey=Mr;i.deleteBy=ns;i.deleteIndex=as;i.deleteObject=os;i.deleteObjects=yt;i.deleteRule=is;i.deleteSynonym=cs;i.exists=us;i.findObject=ls;i.generateSecuredApiKey=wr;i.getApiKey=$;i.getLogs=kr;i.getObject=ds;i.getObjectPosition=ps;i.getObjects=ms;i.getRule=hs;i.getSecuredApiKeyRemainingValidity=Cr;i.getSettings=gt;i.getSynonym=ys;i.getTask=bt;i.getTopUserIDs=Ur;i.getUserID=Nr;i.hasPendingMappings=Wr;i.initIndex=L;i.listApiKeys=Hr;i.listClusters=_r;i.listIndices=Fr;i.listUserIDs=Br;i.moveIndex=Kr;i.multipleBatch=zr;i.multipleGetObjects=Gr;i.multipleQueries=$r;i.multipleSearchForFacetValues=Lr;i.partialUpdateObject=gs;i.partialUpdateObjects=Pt;i.removeUserID=Vr;i.replaceAllObjects=fs;i.replaceAllRules=bs;i.replaceAllSynonyms=Ps;i.restoreApiKey=Qr;i.saveObject=js;i.saveObjects=he;i.saveRule=Os;i.saveRules=ye;i.saveSynonym=Is;i.saveSynonyms=ge;i.search=ft;i.searchForFacetValues=dt;i.searchRules=mt;i.searchSynonyms=ht;i.searchUserIDs=Jr;i.setSettings=As;i.updateApiKey=Xr;i.waitTask=D});var It=I((on,Ot)=>{Ot.exports=jt()});var At=I(re=>{"use strict";Object.defineProperty(re,"__esModule",{value:!0});function vs(){return{debug(e,t){return Promise.resolve()},info(e,t){return Promise.resolve()},error(e,t){return Promise.resolve()}}}var xs={Debug:1,Info:2,Error:3};re.LogLevelEnum=xs;re.createNullLogger=vs});var Dt=I((un,St)=>{St.exports=At()});var xt=I(fe=>{"use strict";Object.defineProperty(fe,"__esModule",{value:!0});var Rt=require("http"),vt=require("https"),qs=require("url");function Es(){let e={keepAlive:!0},t=new Rt.Agent(e),r=new vt.Agent(e);return{send(s){return new Promise(n=>{let a=qs.parse(s.url),o=a.query===null?a.pathname:`${a.pathname}?${a.query}`,d=u({agent:a.protocol==="https:"?r:t,hostname:a.hostname,path:o,method:s.method,headers:s.headers},a.port!==void 0?{port:a.port||""}:{}),y=(a.protocol==="https:"?vt:Rt).request(d,h=>{let S="";h.on("data",O=>S+=O),h.on("end",()=>{clearTimeout(f),clearTimeout(p),n({status:h.statusCode||0,content:S,isTimedOut:!1})})}),b=(h,S)=>setTimeout(()=>{y.abort(),n({status:0,content:S,isTimedOut:!0})},h*1e3),f=b(s.connectTimeout,"Connection timeout"),p;y.on("error",h=>{clearTimeout(f),clearTimeout(p),n({status:0,content:h.message,isTimedOut:!1})}),y.once("response",()=>{clearTimeout(f),p=b(s.responseTimeout,"Socket timeout")}),s.data!==void 0&&y.write(s.data),y.end()})},destroy(){return t.destroy(),r.destroy(),Promise.resolve()}}}fe.createNodeHttpRequester=Es});var Et=I((dn,qt)=>{qt.exports=xt()});var kt=I((pn,Tt)=>{"use strict";var Mt=Ee(),Ts=we(),W=st(),be=F(),Pe=it(),c=It(),Ms=Dt(),ws=Et(),ks=K();function wt(e,t,r){let s={appId:e,apiKey:t,timeouts:{connect:2,read:5,write:30},requester:ws.createNodeHttpRequester(),logger:Ms.createNullLogger(),responsesCache:Mt.createNullCache(),requestsCache:Mt.createNullCache(),hostsCache:Ts.createInMemoryCache(),userAgent:ks.createUserAgent(be.version).add({segment:"Node.js",version:process.versions.node})};return c.createSearchClient(g(u(u({},s),r),{methods:{search:c.multipleQueries,searchForFacetValues:c.multipleSearchForFacetValues,multipleBatch:c.multipleBatch,multipleGetObjects:c.multipleGetObjects,multipleQueries:c.multipleQueries,copyIndex:c.copyIndex,copySettings:c.copySettings,copyRules:c.copyRules,copySynonyms:c.copySynonyms,moveIndex:c.moveIndex,listIndices:c.listIndices,getLogs:c.getLogs,listClusters:c.listClusters,multipleSearchForFacetValues:c.multipleSearchForFacetValues,getApiKey:c.getApiKey,addApiKey:c.addApiKey,listApiKeys:c.listApiKeys,updateApiKey:c.updateApiKey,deleteApiKey:c.deleteApiKey,restoreApiKey:c.restoreApiKey,assignUserID:c.assignUserID,assignUserIDs:c.assignUserIDs,getUserID:c.getUserID,searchUserIDs:c.searchUserIDs,listUserIDs:c.listUserIDs,getTopUserIDs:c.getTopUserIDs,removeUserID:c.removeUserID,hasPendingMappings:c.hasPendingMappings,generateSecuredApiKey:c.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:c.getSecuredApiKeyRemainingValidity,destroy:be.destroy,initIndex:n=>a=>c.initIndex(n)(a,{methods:{batch:c.batch,delete:c.deleteIndex,getObject:c.getObject,getObjects:c.getObjects,saveObject:c.saveObject,saveObjects:c.saveObjects,search:c.search,searchForFacetValues:c.searchForFacetValues,waitTask:c.waitTask,setSettings:c.setSettings,getSettings:c.getSettings,partialUpdateObject:c.partialUpdateObject,partialUpdateObjects:c.partialUpdateObjects,deleteObject:c.deleteObject,deleteObjects:c.deleteObjects,deleteBy:c.deleteBy,clearObjects:c.clearObjects,browseObjects:c.browseObjects,getObjectPosition:c.getObjectPosition,findObject:c.findObject,exists:c.exists,saveSynonym:c.saveSynonym,saveSynonyms:c.saveSynonyms,getSynonym:c.getSynonym,searchSynonyms:c.searchSynonyms,browseSynonyms:c.browseSynonyms,deleteSynonym:c.deleteSynonym,clearSynonyms:c.clearSynonyms,replaceAllObjects:c.replaceAllObjects,replaceAllSynonyms:c.replaceAllSynonyms,searchRules:c.searchRules,getRule:c.getRule,deleteRule:c.deleteRule,saveRule:c.saveRule,saveRules:c.saveRules,replaceAllRules:c.replaceAllRules,browseRules:c.browseRules,clearRules:c.clearRules}}),initAnalytics:()=>n=>W.createAnalyticsClient(g(u(u({},s),n),{methods:{addABTest:W.addABTest,getABTest:W.getABTest,getABTests:W.getABTests,stopABTest:W.stopABTest,deleteABTest:W.deleteABTest}})),initRecommendation:()=>n=>Pe.createRecommendationClient(g(u(u({},s),n),{methods:{getPersonalizationStrategy:Pe.getPersonalizationStrategy,setPersonalizationStrategy:Pe.setPersonalizationStrategy}}))}}))}wt.version=be.version;Tt.exports=wt});var Ut=I((mn,je)=>{var Ct=kt();je.exports=Ct;je.exports.default=Ct});var Ws={};Vt(Ws,{default:()=>Ks});var Oe=C(require("@yarnpkg/core")),E=C(require("@yarnpkg/core")),Ie=C(require("@yarnpkg/plugin-essentials")),Ht=C(require("semver"));var se=C(require("@yarnpkg/core")),Nt=C(Ut()),Cs="e8e1bd300d860104bb8c58453ffa1eb4",Us="OFCNCOG2CU",Wt=async(e,t)=>{var a;let r=se.structUtils.stringifyIdent(e),n=Ns(t).initIndex("npm-search");try{return((a=(await n.getObject(r,{attributesToRetrieve:["types"]})).types)==null?void 0:a.ts)==="definitely-typed"}catch(o){return!1}},Ns=e=>(0,Nt.default)(Us,Cs,{requester:{async send(r){try{let s=await se.httpUtils.request(r.url,r.data||null,{configuration:e,headers:r.headers});return{content:s.body,isTimedOut:!1,status:s.statusCode}}catch(s){return{content:s.response.body,isTimedOut:!1,status:s.response.statusCode}}}}});var _t=e=>e.scope?`${e.scope}__${e.name}`:`${e.name}`,Hs=async(e,t,r,s)=>{if(r.scope==="types")return;let{project:n}=e,{configuration:a}=n,o=a.makeResolver(),d={project:n,resolver:o,report:new E.ThrowReport};if(!await Wt(r,a))return;let b=_t(r),f=E.structUtils.parseRange(r.range).selector;if(!E.semverUtils.validRange(f)){let P=await o.getCandidates(r,new Map,d);f=E.structUtils.parseRange(P[0].reference).selector}let p=Ht.default.coerce(f);if(p===null)return;let h=`${Ie.suggestUtils.Modifier.CARET}${p.major}`,S=E.structUtils.makeDescriptor(E.structUtils.makeIdent("types",b),h),O=E.miscUtils.mapAndFind(n.workspaces,P=>{var T,V;let x=(T=P.manifest.dependencies.get(r.identHash))==null?void 0:T.descriptorHash,v=(V=P.manifest.devDependencies.get(r.identHash))==null?void 0:V.descriptorHash;if(x!==r.descriptorHash&&v!==r.descriptorHash)return E.miscUtils.mapAndFind.skip;let j=[];for(let Ae of Oe.Manifest.allDependencies){let Se=P.manifest[Ae].get(S.identHash);typeof Se!="undefined"&&j.push([Ae,Se])}return j.length===0?E.miscUtils.mapAndFind.skip:j});if(typeof O!="undefined")for(let[P,x]of O)e.manifest[P].set(x.identHash,x);else{try{if((await o.getCandidates(S,new Map,d)).length===0)return}catch{return}e.manifest[Ie.suggestUtils.Target.DEVELOPMENT].set(S.identHash,S)}},_s=async(e,t,r)=>{if(r.scope==="types")return;let s=_t(r),n=E.structUtils.makeIdent("types",s);for(let a of Oe.Manifest.allDependencies)typeof e.manifest[a].get(n.identHash)!="undefined"&&e.manifest[a].delete(n.identHash)},Fs=(e,t)=>{t.publishConfig&&t.publishConfig.typings&&(t.typings=t.publishConfig.typings),t.publishConfig&&t.publishConfig.types&&(t.types=t.publishConfig.types)},Bs={hooks:{afterWorkspaceDependencyAddition:Hs,afterWorkspaceDependencyRemoval:_s,beforeWorkspacePacking:Fs}},Ks=Bs;return Ws;})(); +return plugin; +} +}; diff --git a/.yarn/releases/yarn-3.1.1.cjs b/.yarn/releases/yarn-3.1.1.cjs new file mode 100755 index 00000000..f5f2adca --- /dev/null +++ b/.yarn/releases/yarn-3.1.1.cjs @@ -0,0 +1,768 @@ +#!/usr/bin/env node +/* eslint-disable */ +//prettier-ignore +(()=>{var Mfe=Object.create,Vf=Object.defineProperty,Ofe=Object.defineProperties,Kfe=Object.getOwnPropertyDescriptor,Ufe=Object.getOwnPropertyDescriptors,Hfe=Object.getOwnPropertyNames,hE=Object.getOwnPropertySymbols,Gfe=Object.getPrototypeOf,eb=Object.prototype.hasOwnProperty,lO=Object.prototype.propertyIsEnumerable;var cO=(t,e,r)=>e in t?Vf(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,P=(t,e)=>{for(var r in e||(e={}))eb.call(e,r)&&cO(t,r,e[r]);if(hE)for(var r of hE(e))lO.call(e,r)&&cO(t,r,e[r]);return t},_=(t,e)=>Ofe(t,Ufe(e)),jfe=t=>Vf(t,"__esModule",{value:!0});var qr=(t,e)=>{var r={};for(var i in t)eb.call(t,i)&&e.indexOf(i)<0&&(r[i]=t[i]);if(t!=null&&hE)for(var i of hE(t))e.indexOf(i)<0&&lO.call(t,i)&&(r[i]=t[i]);return r},Yfe=(t,e)=>()=>(t&&(e=t(t=0)),e),E=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),it=(t,e)=>{for(var r in e)Vf(t,r,{get:e[r],enumerable:!0})},qfe=(t,e,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Hfe(e))!eb.call(t,i)&&i!=="default"&&Vf(t,i,{get:()=>e[i],enumerable:!(r=Kfe(e,i))||r.enumerable});return t},ie=t=>qfe(jfe(Vf(t!=null?Mfe(Gfe(t)):{},"default",t&&t.__esModule&&"default"in t?{get:()=>t.default,enumerable:!0}:{value:t,enumerable:!0})),t);var MO=E((i$e,FO)=>{FO.exports=NO;NO.sync=Ahe;var LO=require("fs");function lhe(t,e){var r=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!r||(r=r.split(";"),r.indexOf("")!==-1))return!0;for(var i=0;i{OO.exports=KO;KO.sync=che;var UO=require("fs");function KO(t,e,r){UO.stat(t,function(i,n){r(i,i?!1:HO(n,e))})}function che(t,e){return HO(UO.statSync(t),e)}function HO(t,e){return t.isFile()&&uhe(t,e)}function uhe(t,e){var r=t.mode,i=t.uid,n=t.gid,s=e.uid!==void 0?e.uid:process.getuid&&process.getuid(),o=e.gid!==void 0?e.gid:process.getgid&&process.getgid(),a=parseInt("100",8),l=parseInt("010",8),c=parseInt("001",8),u=a|l,g=r&c||r&l&&n===o||r&a&&i===s||r&u&&s===0;return g}});var YO=E((o$e,jO)=>{var s$e=require("fs"),xE;process.platform==="win32"||global.TESTING_WINDOWS?xE=MO():xE=GO();jO.exports=db;db.sync=ghe;function db(t,e,r){if(typeof e=="function"&&(r=e,e={}),!r){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(i,n){db(t,e||{},function(s,o){s?n(s):i(o)})})}xE(t,e||{},function(i,n){i&&(i.code==="EACCES"||e&&e.ignoreErrors)&&(i=null,n=!1),r(i,n)})}function ghe(t,e){try{return xE.sync(t,e||{})}catch(r){if(e&&e.ignoreErrors||r.code==="EACCES")return!1;throw r}}});var XO=E((a$e,qO)=>{var eu=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",JO=require("path"),fhe=eu?";":":",WO=YO(),zO=t=>Object.assign(new Error(`not found: ${t}`),{code:"ENOENT"}),VO=(t,e)=>{let r=e.colon||fhe,i=t.match(/\//)||eu&&t.match(/\\/)?[""]:[...eu?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(r)],n=eu?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=eu?n.split(r):[""];return eu&&t.indexOf(".")!==-1&&s[0]!==""&&s.unshift(""),{pathEnv:i,pathExt:s,pathExtExe:n}},_O=(t,e,r)=>{typeof e=="function"&&(r=e,e={}),e||(e={});let{pathEnv:i,pathExt:n,pathExtExe:s}=VO(t,e),o=[],a=c=>new Promise((u,g)=>{if(c===i.length)return e.all&&o.length?u(o):g(zO(t));let f=i[c],h=/^".*"$/.test(f)?f.slice(1,-1):f,p=JO.join(h,t),d=!h&&/^\.[\\\/]/.test(t)?t.slice(0,2)+p:p;u(l(d,c,0))}),l=(c,u,g)=>new Promise((f,h)=>{if(g===n.length)return f(a(u+1));let p=n[g];WO(c+p,{pathExt:s},(d,m)=>{if(!d&&m)if(e.all)o.push(c+p);else return f(c+p);return f(l(c,u,g+1))})});return r?a(0).then(c=>r(null,c),r):a(0)},hhe=(t,e)=>{e=e||{};let{pathEnv:r,pathExt:i,pathExtExe:n}=VO(t,e),s=[];for(let o=0;o{"use strict";var ZO=(t={})=>{let e=t.env||process.env;return(t.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(i=>i.toUpperCase()==="PATH")||"Path"};Cb.exports=ZO;Cb.exports.default=ZO});var iK=E((l$e,eK)=>{"use strict";var tK=require("path"),phe=XO(),dhe=$O();function rK(t,e){let r=t.options.env||process.env,i=process.cwd(),n=t.options.cwd!=null,s=n&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(t.options.cwd)}catch(a){}let o;try{o=phe.sync(t.command,{path:r[dhe({env:r})],pathExt:e?tK.delimiter:void 0})}catch(a){}finally{s&&process.chdir(i)}return o&&(o=tK.resolve(n?t.options.cwd:"",o)),o}function Che(t){return rK(t)||rK(t,!0)}eK.exports=Che});var nK=E((c$e,mb)=>{"use strict";var Eb=/([()\][%!^"`<>&|;, *?])/g;function mhe(t){return t=t.replace(Eb,"^$1"),t}function Ehe(t,e){return t=`${t}`,t=t.replace(/(\\*)"/g,'$1$1\\"'),t=t.replace(/(\\*)$/,"$1$1"),t=`"${t}"`,t=t.replace(Eb,"^$1"),e&&(t=t.replace(Eb,"^$1")),t}mb.exports.command=mhe;mb.exports.argument=Ehe});var oK=E((u$e,sK)=>{"use strict";sK.exports=/^#!(.*)/});var AK=E((g$e,aK)=>{"use strict";var Ihe=oK();aK.exports=(t="")=>{let e=t.match(Ihe);if(!e)return null;let[r,i]=e[0].replace(/#! ?/,"").split(" "),n=r.split("/").pop();return n==="env"?i:i?`${n} ${i}`:n}});var cK=E((f$e,lK)=>{"use strict";var Ib=require("fs"),yhe=AK();function whe(t){let e=150,r=Buffer.alloc(e),i;try{i=Ib.openSync(t,"r"),Ib.readSync(i,r,0,e,0),Ib.closeSync(i)}catch(n){}return yhe(r.toString())}lK.exports=whe});var hK=E((h$e,uK)=>{"use strict";var Bhe=require("path"),gK=iK(),fK=nK(),Qhe=cK(),bhe=process.platform==="win32",vhe=/\.(?:com|exe)$/i,She=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function xhe(t){t.file=gK(t);let e=t.file&&Qhe(t.file);return e?(t.args.unshift(t.file),t.command=e,gK(t)):t.file}function khe(t){if(!bhe)return t;let e=xhe(t),r=!vhe.test(e);if(t.options.forceShell||r){let i=She.test(e);t.command=Bhe.normalize(t.command),t.command=fK.command(t.command),t.args=t.args.map(s=>fK.argument(s,i));let n=[t.command].concat(t.args).join(" ");t.args=["/d","/s","/c",`"${n}"`],t.command=process.env.comspec||"cmd.exe",t.options.windowsVerbatimArguments=!0}return t}function Phe(t,e,r){e&&!Array.isArray(e)&&(r=e,e=null),e=e?e.slice(0):[],r=Object.assign({},r);let i={command:t,args:e,options:r,file:void 0,original:{command:t,args:e}};return r.shell?i:khe(i)}uK.exports=Phe});var CK=E((p$e,pK)=>{"use strict";var yb=process.platform==="win32";function wb(t,e){return Object.assign(new Error(`${e} ${t.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${t.command}`,path:t.command,spawnargs:t.args})}function Dhe(t,e){if(!yb)return;let r=t.emit;t.emit=function(i,n){if(i==="exit"){let s=dK(n,e,"spawn");if(s)return r.call(t,"error",s)}return r.apply(t,arguments)}}function dK(t,e){return yb&&t===1&&!e.file?wb(e.original,"spawn"):null}function Rhe(t,e){return yb&&t===1&&!e.file?wb(e.original,"spawnSync"):null}pK.exports={hookChildProcess:Dhe,verifyENOENT:dK,verifyENOENTSync:Rhe,notFoundError:wb}});var bb=E((d$e,tu)=>{"use strict";var mK=require("child_process"),Bb=hK(),Qb=CK();function EK(t,e,r){let i=Bb(t,e,r),n=mK.spawn(i.command,i.args,i.options);return Qb.hookChildProcess(n,i),n}function Fhe(t,e,r){let i=Bb(t,e,r),n=mK.spawnSync(i.command,i.args,i.options);return n.error=n.error||Qb.verifyENOENTSync(n.status,i),n}tu.exports=EK;tu.exports.spawn=EK;tu.exports.sync=Fhe;tu.exports._parse=Bb;tu.exports._enoent=Qb});var yK=E((y$e,IK)=>{"use strict";IK.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var Nb=E((w$e,wK)=>{var gh=yK(),BK={};for(let t of Object.keys(gh))BK[gh[t]]=t;var Xe={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};wK.exports=Xe;for(let t of Object.keys(Xe)){if(!("channels"in Xe[t]))throw new Error("missing channels property: "+t);if(!("labels"in Xe[t]))throw new Error("missing channel labels property: "+t);if(Xe[t].labels.length!==Xe[t].channels)throw new Error("channel and label counts mismatch: "+t);let{channels:e,labels:r}=Xe[t];delete Xe[t].channels,delete Xe[t].labels,Object.defineProperty(Xe[t],"channels",{value:e}),Object.defineProperty(Xe[t],"labels",{value:r})}Xe.rgb.hsl=function(t){let e=t[0]/255,r=t[1]/255,i=t[2]/255,n=Math.min(e,r,i),s=Math.max(e,r,i),o=s-n,a,l;s===n?a=0:e===s?a=(r-i)/o:r===s?a=2+(i-e)/o:i===s&&(a=4+(e-r)/o),a=Math.min(a*60,360),a<0&&(a+=360);let c=(n+s)/2;return s===n?l=0:c<=.5?l=o/(s+n):l=o/(2-s-n),[a,l*100,c*100]};Xe.rgb.hsv=function(t){let e,r,i,n,s,o=t[0]/255,a=t[1]/255,l=t[2]/255,c=Math.max(o,a,l),u=c-Math.min(o,a,l),g=function(f){return(c-f)/6/u+1/2};return u===0?(n=0,s=0):(s=u/c,e=g(o),r=g(a),i=g(l),o===c?n=i-r:a===c?n=1/3+e-i:l===c&&(n=2/3+r-e),n<0?n+=1:n>1&&(n-=1)),[n*360,s*100,c*100]};Xe.rgb.hwb=function(t){let e=t[0],r=t[1],i=t[2],n=Xe.rgb.hsl(t)[0],s=1/255*Math.min(e,Math.min(r,i));return i=1-1/255*Math.max(e,Math.max(r,i)),[n,s*100,i*100]};Xe.rgb.cmyk=function(t){let e=t[0]/255,r=t[1]/255,i=t[2]/255,n=Math.min(1-e,1-r,1-i),s=(1-e-n)/(1-n)||0,o=(1-r-n)/(1-n)||0,a=(1-i-n)/(1-n)||0;return[s*100,o*100,a*100,n*100]};function The(t,e){return(t[0]-e[0])**2+(t[1]-e[1])**2+(t[2]-e[2])**2}Xe.rgb.keyword=function(t){let e=BK[t];if(e)return e;let r=Infinity,i;for(let n of Object.keys(gh)){let s=gh[n],o=The(t,s);o.04045?((e+.055)/1.055)**2.4:e/12.92,r=r>.04045?((r+.055)/1.055)**2.4:r/12.92,i=i>.04045?((i+.055)/1.055)**2.4:i/12.92;let n=e*.4124+r*.3576+i*.1805,s=e*.2126+r*.7152+i*.0722,o=e*.0193+r*.1192+i*.9505;return[n*100,s*100,o*100]};Xe.rgb.lab=function(t){let e=Xe.rgb.xyz(t),r=e[0],i=e[1],n=e[2];r/=95.047,i/=100,n/=108.883,r=r>.008856?r**(1/3):7.787*r+16/116,i=i>.008856?i**(1/3):7.787*i+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;let s=116*i-16,o=500*(r-i),a=200*(i-n);return[s,o,a]};Xe.hsl.rgb=function(t){let e=t[0]/360,r=t[1]/100,i=t[2]/100,n,s,o;if(r===0)return o=i*255,[o,o,o];i<.5?n=i*(1+r):n=i+r-i*r;let a=2*i-n,l=[0,0,0];for(let c=0;c<3;c++)s=e+1/3*-(c-1),s<0&&s++,s>1&&s--,6*s<1?o=a+(n-a)*6*s:2*s<1?o=n:3*s<2?o=a+(n-a)*(2/3-s)*6:o=a,l[c]=o*255;return l};Xe.hsl.hsv=function(t){let e=t[0],r=t[1]/100,i=t[2]/100,n=r,s=Math.max(i,.01);i*=2,r*=i<=1?i:2-i,n*=s<=1?s:2-s;let o=(i+r)/2,a=i===0?2*n/(s+n):2*r/(i+r);return[e,a*100,o*100]};Xe.hsv.rgb=function(t){let e=t[0]/60,r=t[1]/100,i=t[2]/100,n=Math.floor(e)%6,s=e-Math.floor(e),o=255*i*(1-r),a=255*i*(1-r*s),l=255*i*(1-r*(1-s));switch(i*=255,n){case 0:return[i,l,o];case 1:return[a,i,o];case 2:return[o,i,l];case 3:return[o,a,i];case 4:return[l,o,i];case 5:return[i,o,a]}};Xe.hsv.hsl=function(t){let e=t[0],r=t[1]/100,i=t[2]/100,n=Math.max(i,.01),s,o;o=(2-r)*i;let a=(2-r)*n;return s=r*n,s/=a<=1?a:2-a,s=s||0,o/=2,[e,s*100,o*100]};Xe.hwb.rgb=function(t){let e=t[0]/360,r=t[1]/100,i=t[2]/100,n=r+i,s;n>1&&(r/=n,i/=n);let o=Math.floor(6*e),a=1-i;s=6*e-o,(o&1)!=0&&(s=1-s);let l=r+s*(a-r),c,u,g;switch(o){default:case 6:case 0:c=a,u=l,g=r;break;case 1:c=l,u=a,g=r;break;case 2:c=r,u=a,g=l;break;case 3:c=r,u=l,g=a;break;case 4:c=l,u=r,g=a;break;case 5:c=a,u=r,g=l;break}return[c*255,u*255,g*255]};Xe.cmyk.rgb=function(t){let e=t[0]/100,r=t[1]/100,i=t[2]/100,n=t[3]/100,s=1-Math.min(1,e*(1-n)+n),o=1-Math.min(1,r*(1-n)+n),a=1-Math.min(1,i*(1-n)+n);return[s*255,o*255,a*255]};Xe.xyz.rgb=function(t){let e=t[0]/100,r=t[1]/100,i=t[2]/100,n,s,o;return n=e*3.2406+r*-1.5372+i*-.4986,s=e*-.9689+r*1.8758+i*.0415,o=e*.0557+r*-.204+i*1.057,n=n>.0031308?1.055*n**(1/2.4)-.055:n*12.92,s=s>.0031308?1.055*s**(1/2.4)-.055:s*12.92,o=o>.0031308?1.055*o**(1/2.4)-.055:o*12.92,n=Math.min(Math.max(0,n),1),s=Math.min(Math.max(0,s),1),o=Math.min(Math.max(0,o),1),[n*255,s*255,o*255]};Xe.xyz.lab=function(t){let e=t[0],r=t[1],i=t[2];e/=95.047,r/=100,i/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,r=r>.008856?r**(1/3):7.787*r+16/116,i=i>.008856?i**(1/3):7.787*i+16/116;let n=116*r-16,s=500*(e-r),o=200*(r-i);return[n,s,o]};Xe.lab.xyz=function(t){let e=t[0],r=t[1],i=t[2],n,s,o;s=(e+16)/116,n=r/500+s,o=s-i/200;let a=s**3,l=n**3,c=o**3;return s=a>.008856?a:(s-16/116)/7.787,n=l>.008856?l:(n-16/116)/7.787,o=c>.008856?c:(o-16/116)/7.787,n*=95.047,s*=100,o*=108.883,[n,s,o]};Xe.lab.lch=function(t){let e=t[0],r=t[1],i=t[2],n;n=Math.atan2(i,r)*360/2/Math.PI,n<0&&(n+=360);let o=Math.sqrt(r*r+i*i);return[e,o,n]};Xe.lch.lab=function(t){let e=t[0],r=t[1],n=t[2]/360*2*Math.PI,s=r*Math.cos(n),o=r*Math.sin(n);return[e,s,o]};Xe.rgb.ansi16=function(t,e=null){let[r,i,n]=t,s=e===null?Xe.rgb.hsv(t)[2]:e;if(s=Math.round(s/50),s===0)return 30;let o=30+(Math.round(n/255)<<2|Math.round(i/255)<<1|Math.round(r/255));return s===2&&(o+=60),o};Xe.hsv.ansi16=function(t){return Xe.rgb.ansi16(Xe.hsv.rgb(t),t[2])};Xe.rgb.ansi256=function(t){let e=t[0],r=t[1],i=t[2];return e===r&&r===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(r/255*5)+Math.round(i/255*5)};Xe.ansi16.rgb=function(t){let e=t%10;if(e===0||e===7)return t>50&&(e+=3.5),e=e/10.5*255,[e,e,e];let r=(~~(t>50)+1)*.5,i=(e&1)*r*255,n=(e>>1&1)*r*255,s=(e>>2&1)*r*255;return[i,n,s]};Xe.ansi256.rgb=function(t){if(t>=232){let s=(t-232)*10+8;return[s,s,s]}t-=16;let e,r=Math.floor(t/36)/5*255,i=Math.floor((e=t%36)/6)/5*255,n=e%6/5*255;return[r,i,n]};Xe.rgb.hex=function(t){let r=(((Math.round(t[0])&255)<<16)+((Math.round(t[1])&255)<<8)+(Math.round(t[2])&255)).toString(16).toUpperCase();return"000000".substring(r.length)+r};Xe.hex.rgb=function(t){let e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];let r=e[0];e[0].length===3&&(r=r.split("").map(a=>a+a).join(""));let i=parseInt(r,16),n=i>>16&255,s=i>>8&255,o=i&255;return[n,s,o]};Xe.rgb.hcg=function(t){let e=t[0]/255,r=t[1]/255,i=t[2]/255,n=Math.max(Math.max(e,r),i),s=Math.min(Math.min(e,r),i),o=n-s,a,l;return o<1?a=s/(1-o):a=0,o<=0?l=0:n===e?l=(r-i)/o%6:n===r?l=2+(i-e)/o:l=4+(e-r)/o,l/=6,l%=1,[l*360,o*100,a*100]};Xe.hsl.hcg=function(t){let e=t[1]/100,r=t[2]/100,i=r<.5?2*e*r:2*e*(1-r),n=0;return i<1&&(n=(r-.5*i)/(1-i)),[t[0],i*100,n*100]};Xe.hsv.hcg=function(t){let e=t[1]/100,r=t[2]/100,i=e*r,n=0;return i<1&&(n=(r-i)/(1-i)),[t[0],i*100,n*100]};Xe.hcg.rgb=function(t){let e=t[0]/360,r=t[1]/100,i=t[2]/100;if(r===0)return[i*255,i*255,i*255];let n=[0,0,0],s=e%1*6,o=s%1,a=1-o,l=0;switch(Math.floor(s)){case 0:n[0]=1,n[1]=o,n[2]=0;break;case 1:n[0]=a,n[1]=1,n[2]=0;break;case 2:n[0]=0,n[1]=1,n[2]=o;break;case 3:n[0]=0,n[1]=a,n[2]=1;break;case 4:n[0]=o,n[1]=0,n[2]=1;break;default:n[0]=1,n[1]=0,n[2]=a}return l=(1-r)*i,[(r*n[0]+l)*255,(r*n[1]+l)*255,(r*n[2]+l)*255]};Xe.hcg.hsv=function(t){let e=t[1]/100,r=t[2]/100,i=e+r*(1-e),n=0;return i>0&&(n=e/i),[t[0],n*100,i*100]};Xe.hcg.hsl=function(t){let e=t[1]/100,i=t[2]/100*(1-e)+.5*e,n=0;return i>0&&i<.5?n=e/(2*i):i>=.5&&i<1&&(n=e/(2*(1-i))),[t[0],n*100,i*100]};Xe.hcg.hwb=function(t){let e=t[1]/100,r=t[2]/100,i=e+r*(1-e);return[t[0],(i-e)*100,(1-i)*100]};Xe.hwb.hcg=function(t){let e=t[1]/100,r=t[2]/100,i=1-r,n=i-e,s=0;return n<1&&(s=(i-n)/(1-n)),[t[0],n*100,s*100]};Xe.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]};Xe.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]};Xe.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]};Xe.gray.hsl=function(t){return[0,0,t[0]]};Xe.gray.hsv=Xe.gray.hsl;Xe.gray.hwb=function(t){return[0,100,t[0]]};Xe.gray.cmyk=function(t){return[0,0,0,t[0]]};Xe.gray.lab=function(t){return[t[0],0,0]};Xe.gray.hex=function(t){let e=Math.round(t[0]/100*255)&255,i=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(i.length)+i};Xe.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}});var bK=E((B$e,QK)=>{var kE=Nb();function Mhe(){let t={},e=Object.keys(kE);for(let r=e.length,i=0;i{var Lb=Nb(),Hhe=bK(),ru={},Ghe=Object.keys(Lb);function jhe(t){let e=function(...r){let i=r[0];return i==null?i:(i.length>1&&(r=i),t(r))};return"conversion"in t&&(e.conversion=t.conversion),e}function Yhe(t){let e=function(...r){let i=r[0];if(i==null)return i;i.length>1&&(r=i);let n=t(r);if(typeof n=="object")for(let s=n.length,o=0;o{ru[t]={},Object.defineProperty(ru[t],"channels",{value:Lb[t].channels}),Object.defineProperty(ru[t],"labels",{value:Lb[t].labels});let e=Hhe(t);Object.keys(e).forEach(i=>{let n=e[i];ru[t][i]=Yhe(n),ru[t][i].raw=jhe(n)})});vK.exports=ru});var FK=E((b$e,xK)=>{"use strict";var kK=(t,e)=>(...r)=>`[${t(...r)+e}m`,PK=(t,e)=>(...r)=>{let i=t(...r);return`[${38+e};5;${i}m`},DK=(t,e)=>(...r)=>{let i=t(...r);return`[${38+e};2;${i[0]};${i[1]};${i[2]}m`},PE=t=>t,RK=(t,e,r)=>[t,e,r],iu=(t,e,r)=>{Object.defineProperty(t,e,{get:()=>{let i=r();return Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0}),i},enumerable:!0,configurable:!0})},Tb,nu=(t,e,r,i)=>{Tb===void 0&&(Tb=SK());let n=i?10:0,s={};for(let[o,a]of Object.entries(Tb)){let l=o==="ansi16"?"ansi":o;o===e?s[l]=t(r,n):typeof a=="object"&&(s[l]=t(a[e],n))}return s};function qhe(){let t=new Map,e={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};e.color.gray=e.color.blackBright,e.bgColor.bgGray=e.bgColor.bgBlackBright,e.color.grey=e.color.blackBright,e.bgColor.bgGrey=e.bgColor.bgBlackBright;for(let[r,i]of Object.entries(e)){for(let[n,s]of Object.entries(i))e[n]={open:`[${s[0]}m`,close:`[${s[1]}m`},i[n]=e[n],t.set(s[0],s[1]);Object.defineProperty(e,r,{value:i,enumerable:!1})}return Object.defineProperty(e,"codes",{value:t,enumerable:!1}),e.color.close="",e.bgColor.close="",iu(e.color,"ansi",()=>nu(kK,"ansi16",PE,!1)),iu(e.color,"ansi256",()=>nu(PK,"ansi256",PE,!1)),iu(e.color,"ansi16m",()=>nu(DK,"rgb",RK,!1)),iu(e.bgColor,"ansi",()=>nu(kK,"ansi16",PE,!0)),iu(e.bgColor,"ansi256",()=>nu(PK,"ansi256",PE,!0)),iu(e.bgColor,"ansi16m",()=>nu(DK,"rgb",RK,!0)),e}Object.defineProperty(xK,"exports",{enumerable:!0,get:qhe})});var LK=E((v$e,NK)=>{"use strict";NK.exports=(t,e=process.argv)=>{let r=t.startsWith("-")?"":t.length===1?"-":"--",i=e.indexOf(r+t),n=e.indexOf("--");return i!==-1&&(n===-1||i{"use strict";var Jhe=require("os"),MK=require("tty"),Wn=LK(),{env:Wr}=process,tA;Wn("no-color")||Wn("no-colors")||Wn("color=false")||Wn("color=never")?tA=0:(Wn("color")||Wn("colors")||Wn("color=true")||Wn("color=always"))&&(tA=1);"FORCE_COLOR"in Wr&&(Wr.FORCE_COLOR==="true"?tA=1:Wr.FORCE_COLOR==="false"?tA=0:tA=Wr.FORCE_COLOR.length===0?1:Math.min(parseInt(Wr.FORCE_COLOR,10),3));function Mb(t){return t===0?!1:{level:t,hasBasic:!0,has256:t>=2,has16m:t>=3}}function Ob(t,e){if(tA===0)return 0;if(Wn("color=16m")||Wn("color=full")||Wn("color=truecolor"))return 3;if(Wn("color=256"))return 2;if(t&&!e&&tA===void 0)return 0;let r=tA||0;if(Wr.TERM==="dumb")return r;if(process.platform==="win32"){let i=Jhe.release().split(".");return Number(i[0])>=10&&Number(i[2])>=10586?Number(i[2])>=14931?3:2:1}if("CI"in Wr)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(i=>i in Wr)||Wr.CI_NAME==="codeship"?1:r;if("TEAMCITY_VERSION"in Wr)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(Wr.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in Wr)return 1;if(Wr.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in Wr){let i=parseInt((Wr.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(Wr.TERM_PROGRAM){case"iTerm.app":return i>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(Wr.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(Wr.TERM)||"COLORTERM"in Wr?1:r}function Whe(t){let e=Ob(t,t&&t.isTTY);return Mb(e)}TK.exports={supportsColor:Whe,stdout:Mb(Ob(!0,MK.isatty(1))),stderr:Mb(Ob(!0,MK.isatty(2)))}});var UK=E((x$e,KK)=>{"use strict";var zhe=(t,e,r)=>{let i=t.indexOf(e);if(i===-1)return t;let n=e.length,s=0,o="";do o+=t.substr(s,i-s)+e+r,s=i+n,i=t.indexOf(e,s);while(i!==-1);return o+=t.substr(s),o},Vhe=(t,e,r,i)=>{let n=0,s="";do{let o=t[i-1]==="\r";s+=t.substr(n,(o?i-1:i)-n)+e+(o?`\r +`:` +`)+r,n=i+1,i=t.indexOf(` +`,n)}while(i!==-1);return s+=t.substr(n),s};KK.exports={stringReplaceAll:zhe,stringEncaseCRLFWithFirstIndex:Vhe}});var qK=E((k$e,HK)=>{"use strict";var _he=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,GK=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,Xhe=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,Zhe=/\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi,$he=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a","\x07"]]);function jK(t){let e=t[0]==="u",r=t[1]==="{";return e&&!r&&t.length===5||t[0]==="x"&&t.length===3?String.fromCharCode(parseInt(t.slice(1),16)):e&&r?String.fromCodePoint(parseInt(t.slice(2,-1),16)):$he.get(t)||t}function epe(t,e){let r=[],i=e.trim().split(/\s*,\s*/g),n;for(let s of i){let o=Number(s);if(!Number.isNaN(o))r.push(o);else if(n=s.match(Xhe))r.push(n[2].replace(Zhe,(a,l,c)=>l?jK(l):c));else throw new Error(`Invalid Chalk template style argument: ${s} (in style '${t}')`)}return r}function tpe(t){GK.lastIndex=0;let e=[],r;for(;(r=GK.exec(t))!==null;){let i=r[1];if(r[2]){let n=epe(i,r[2]);e.push([i].concat(n))}else e.push([i])}return e}function YK(t,e){let r={};for(let n of e)for(let s of n.styles)r[s[0]]=n.inverse?null:s.slice(1);let i=t;for(let[n,s]of Object.entries(r))if(!!Array.isArray(s)){if(!(n in i))throw new Error(`Unknown Chalk style: ${n}`);i=s.length>0?i[n](...s):i[n]}return i}HK.exports=(t,e)=>{let r=[],i=[],n=[];if(e.replace(_he,(s,o,a,l,c,u)=>{if(o)n.push(jK(o));else if(l){let g=n.join("");n=[],i.push(r.length===0?g:YK(t,r)(g)),r.push({inverse:a,styles:tpe(l)})}else if(c){if(r.length===0)throw new Error("Found extraneous } in Chalk template literal");i.push(YK(t,r)(n.join(""))),n=[],r.pop()}else n.push(u)}),i.push(n.join("")),r.length>0){let s=`Chalk template literal is missing ${r.length} closing bracket${r.length===1?"":"s"} (\`}\`)`;throw new Error(s)}return i.join("")}});var jb=E((P$e,JK)=>{"use strict";var fh=FK(),{stdout:Kb,stderr:Ub}=OK(),{stringReplaceAll:rpe,stringEncaseCRLFWithFirstIndex:ipe}=UK(),WK=["ansi","ansi","ansi256","ansi16m"],su=Object.create(null),npe=(t,e={})=>{if(e.level>3||e.level<0)throw new Error("The `level` option should be an integer from 0 to 3");let r=Kb?Kb.level:0;t.level=e.level===void 0?r:e.level},zK=class{constructor(e){return VK(e)}},VK=t=>{let e={};return npe(e,t),e.template=(...r)=>spe(e.template,...r),Object.setPrototypeOf(e,DE.prototype),Object.setPrototypeOf(e.template,e),e.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},e.template.Instance=zK,e.template};function DE(t){return VK(t)}for(let[t,e]of Object.entries(fh))su[t]={get(){let r=RE(this,Hb(e.open,e.close,this._styler),this._isEmpty);return Object.defineProperty(this,t,{value:r}),r}};su.visible={get(){let t=RE(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:t}),t}};var _K=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let t of _K)su[t]={get(){let{level:e}=this;return function(...r){let i=Hb(fh.color[WK[e]][t](...r),fh.color.close,this._styler);return RE(this,i,this._isEmpty)}}};for(let t of _K){let e="bg"+t[0].toUpperCase()+t.slice(1);su[e]={get(){let{level:r}=this;return function(...i){let n=Hb(fh.bgColor[WK[r]][t](...i),fh.bgColor.close,this._styler);return RE(this,n,this._isEmpty)}}}}var ope=Object.defineProperties(()=>{},_(P({},su),{level:{enumerable:!0,get(){return this._generator.level},set(t){this._generator.level=t}}})),Hb=(t,e,r)=>{let i,n;return r===void 0?(i=t,n=e):(i=r.openAll+t,n=e+r.closeAll),{open:t,close:e,openAll:i,closeAll:n,parent:r}},RE=(t,e,r)=>{let i=(...n)=>ape(i,n.length===1?""+n[0]:n.join(" "));return i.__proto__=ope,i._generator=t,i._styler=e,i._isEmpty=r,i},ape=(t,e)=>{if(t.level<=0||!e)return t._isEmpty?"":e;let r=t._styler;if(r===void 0)return e;let{openAll:i,closeAll:n}=r;if(e.indexOf("")!==-1)for(;r!==void 0;)e=rpe(e,r.close,r.open),r=r.parent;let s=e.indexOf(` +`);return s!==-1&&(e=ipe(e,n,i,s)),i+e+n},Gb,spe=(t,...e)=>{let[r]=e;if(!Array.isArray(r))return e.join(" ");let i=e.slice(1),n=[r.raw[0]];for(let s=1;s{XK.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vercel",constant:"VERCEL",env:"NOW_BUILDER"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"}]});var ml=E(Dn=>{"use strict";var $K=ZK(),ro=process.env;Object.defineProperty(Dn,"_vendors",{value:$K.map(function(t){return t.constant})});Dn.name=null;Dn.isPR=null;$K.forEach(function(t){let r=(Array.isArray(t.env)?t.env:[t.env]).every(function(i){return e1(i)});if(Dn[t.constant]=r,r)switch(Dn.name=t.name,typeof t.pr){case"string":Dn.isPR=!!ro[t.pr];break;case"object":"env"in t.pr?Dn.isPR=t.pr.env in ro&&ro[t.pr.env]!==t.pr.ne:"any"in t.pr?Dn.isPR=t.pr.any.some(function(i){return!!ro[i]}):Dn.isPR=e1(t.pr);break;default:Dn.isPR=null}});Dn.isCI=!!(ro.CI||ro.CONTINUOUS_INTEGRATION||ro.BUILD_NUMBER||ro.RUN_ID||Dn.name);function e1(t){return typeof t=="string"?!!ro[t]:Object.keys(t).every(function(e){return ro[e]===t[e]})}});var FE=E(zn=>{"use strict";zn.isInteger=t=>typeof t=="number"?Number.isInteger(t):typeof t=="string"&&t.trim()!==""?Number.isInteger(Number(t)):!1;zn.find=(t,e)=>t.nodes.find(r=>r.type===e);zn.exceedsLimit=(t,e,r=1,i)=>i===!1||!zn.isInteger(t)||!zn.isInteger(e)?!1:(Number(e)-Number(t))/Number(r)>=i;zn.escapeNode=(t,e=0,r)=>{let i=t.nodes[e];!i||(r&&i.type===r||i.type==="open"||i.type==="close")&&i.escaped!==!0&&(i.value="\\"+i.value,i.escaped=!0)};zn.encloseBrace=t=>t.type!=="brace"?!1:t.commas>>0+t.ranges>>0==0?(t.invalid=!0,!0):!1;zn.isInvalidBrace=t=>t.type!=="brace"?!1:t.invalid===!0||t.dollar?!0:t.commas>>0+t.ranges>>0==0||t.open!==!0||t.close!==!0?(t.invalid=!0,!0):!1;zn.isOpenOrClose=t=>t.type==="open"||t.type==="close"?!0:t.open===!0||t.close===!0;zn.reduce=t=>t.reduce((e,r)=>(r.type==="text"&&e.push(r.value),r.type==="range"&&(r.type="text"),e),[]);zn.flatten=(...t)=>{let e=[],r=i=>{for(let n=0;n{"use strict";var r1=FE();t1.exports=(t,e={})=>{let r=(i,n={})=>{let s=e.escapeInvalid&&r1.isInvalidBrace(n),o=i.invalid===!0&&e.escapeInvalid===!0,a="";if(i.value)return(s||o)&&r1.isOpenOrClose(i)?"\\"+i.value:i.value;if(i.value)return i.value;if(i.nodes)for(let l of i.nodes)a+=r(l);return a};return r(t)}});var n1=E((L$e,i1)=>{"use strict";i1.exports=function(t){return typeof t=="number"?t-t==0:typeof t=="string"&&t.trim()!==""?Number.isFinite?Number.isFinite(+t):isFinite(+t):!1}});var f1=E((T$e,s1)=>{"use strict";var o1=n1(),El=(t,e,r)=>{if(o1(t)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(e===void 0||t===e)return String(t);if(o1(e)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let i=P({relaxZeros:!0},r);typeof i.strictZeros=="boolean"&&(i.relaxZeros=i.strictZeros===!1);let n=String(i.relaxZeros),s=String(i.shorthand),o=String(i.capture),a=String(i.wrap),l=t+":"+e+"="+n+s+o+a;if(El.cache.hasOwnProperty(l))return El.cache[l].result;let c=Math.min(t,e),u=Math.max(t,e);if(Math.abs(c-u)===1){let d=t+"|"+e;return i.capture?`(${d})`:i.wrap===!1?d:`(?:${d})`}let g=A1(t)||A1(e),f={min:t,max:e,a:c,b:u},h=[],p=[];if(g&&(f.isPadded=g,f.maxLen=String(f.max).length),c<0){let d=u<0?Math.abs(u):1;p=a1(d,Math.abs(c),f,i),c=f.a=0}return u>=0&&(h=a1(c,u,f,i)),f.negatives=p,f.positives=h,f.result=Ape(p,h,i),i.capture===!0?f.result=`(${f.result})`:i.wrap!==!1&&h.length+p.length>1&&(f.result=`(?:${f.result})`),El.cache[l]=f,f.result};function Ape(t,e,r){let i=Yb(t,e,"-",!1,r)||[],n=Yb(e,t,"",!1,r)||[],s=Yb(t,e,"-?",!0,r)||[];return i.concat(s).concat(n).join("|")}function cpe(t,e){let r=1,i=1,n=l1(t,r),s=new Set([e]);for(;t<=n&&n<=e;)s.add(n),r+=1,n=l1(t,r);for(n=c1(e+1,i)-1;t1&&a.count.pop(),a.count.push(u.count[0]),a.string=a.pattern+u1(a.count),o=c+1;continue}r.isPadded&&(g=hpe(c,r,i)),u.string=g+u.pattern+u1(u.count),s.push(u),o=c+1,a=u}return s}function Yb(t,e,r,i,n){let s=[];for(let o of t){let{string:a}=o;!i&&!g1(e,"string",a)&&s.push(r+a),i&&g1(e,"string",a)&&s.push(r+a)}return s}function upe(t,e){let r=[];for(let i=0;ie?1:e>t?-1:0}function g1(t,e,r){return t.some(i=>i[e]===r)}function l1(t,e){return Number(String(t).slice(0,-e)+"9".repeat(e))}function c1(t,e){return t-t%Math.pow(10,e)}function u1(t){let[e=0,r=""]=t;return r||e>1?`{${e+(r?","+r:"")}}`:""}function gpe(t,e,r){return`[${t}${e-t==1?"":"-"}${e}]`}function A1(t){return/^-?(0+)\d/.test(t)}function hpe(t,e,r){if(!e.isPadded)return t;let i=Math.abs(e.maxLen-String(t).length),n=r.relaxZeros!==!1;switch(i){case 0:return"";case 1:return n?"0?":"0";case 2:return n?"0{0,2}":"00";default:return n?`0{0,${i}}`:`0{${i}}`}}El.cache={};El.clearCache=()=>El.cache={};s1.exports=El});var Wb=E((M$e,h1)=>{"use strict";var ppe=require("util"),p1=f1(),d1=t=>t!==null&&typeof t=="object"&&!Array.isArray(t),dpe=t=>e=>t===!0?Number(e):String(e),qb=t=>typeof t=="number"||typeof t=="string"&&t!=="",ph=t=>Number.isInteger(+t),Jb=t=>{let e=`${t}`,r=-1;if(e[0]==="-"&&(e=e.slice(1)),e==="0")return!1;for(;e[++r]==="0";);return r>0},Cpe=(t,e,r)=>typeof t=="string"||typeof e=="string"?!0:r.stringify===!0,mpe=(t,e,r)=>{if(e>0){let i=t[0]==="-"?"-":"";i&&(t=t.slice(1)),t=i+t.padStart(i?e-1:e,"0")}return r===!1?String(t):t},C1=(t,e)=>{let r=t[0]==="-"?"-":"";for(r&&(t=t.slice(1),e--);t.length{t.negatives.sort((o,a)=>oa?1:0),t.positives.sort((o,a)=>oa?1:0);let r=e.capture?"":"?:",i="",n="",s;return t.positives.length&&(i=t.positives.join("|")),t.negatives.length&&(n=`-(${r}${t.negatives.join("|")})`),i&&n?s=`${i}|${n}`:s=i||n,e.wrap?`(${r}${s})`:s},m1=(t,e,r,i)=>{if(r)return p1(t,e,P({wrap:!1},i));let n=String.fromCharCode(t);if(t===e)return n;let s=String.fromCharCode(e);return`[${n}-${s}]`},E1=(t,e,r)=>{if(Array.isArray(t)){let i=r.wrap===!0,n=r.capture?"":"?:";return i?`(${n}${t.join("|")})`:t.join("|")}return p1(t,e,r)},I1=(...t)=>new RangeError("Invalid range arguments: "+ppe.inspect(...t)),y1=(t,e,r)=>{if(r.strictRanges===!0)throw I1([t,e]);return[]},Ipe=(t,e)=>{if(e.strictRanges===!0)throw new TypeError(`Expected step "${t}" to be a number`);return[]},ype=(t,e,r=1,i={})=>{let n=Number(t),s=Number(e);if(!Number.isInteger(n)||!Number.isInteger(s)){if(i.strictRanges===!0)throw I1([t,e]);return[]}n===0&&(n=0),s===0&&(s=0);let o=n>s,a=String(t),l=String(e),c=String(r);r=Math.max(Math.abs(r),1);let u=Jb(a)||Jb(l)||Jb(c),g=u?Math.max(a.length,l.length,c.length):0,f=u===!1&&Cpe(t,e,i)===!1,h=i.transform||dpe(f);if(i.toRegex&&r===1)return m1(C1(t,g),C1(e,g),!0,i);let p={negatives:[],positives:[]},d=B=>p[B<0?"negatives":"positives"].push(Math.abs(B)),m=[],I=0;for(;o?n>=s:n<=s;)i.toRegex===!0&&r>1?d(n):m.push(mpe(h(n,I),g,f)),n=o?n-r:n+r,I++;return i.toRegex===!0?r>1?Epe(p,i):E1(m,null,P({wrap:!1},i)):m},wpe=(t,e,r=1,i={})=>{if(!ph(t)&&t.length>1||!ph(e)&&e.length>1)return y1(t,e,i);let n=i.transform||(f=>String.fromCharCode(f)),s=`${t}`.charCodeAt(0),o=`${e}`.charCodeAt(0),a=s>o,l=Math.min(s,o),c=Math.max(s,o);if(i.toRegex&&r===1)return m1(l,c,!1,i);let u=[],g=0;for(;a?s>=o:s<=o;)u.push(n(s,g)),s=a?s-r:s+r,g++;return i.toRegex===!0?E1(u,null,{wrap:!1,options:i}):u},LE=(t,e,r,i={})=>{if(e==null&&qb(t))return[t];if(!qb(t)||!qb(e))return y1(t,e,i);if(typeof r=="function")return LE(t,e,1,{transform:r});if(d1(r))return LE(t,e,0,r);let n=P({},i);return n.capture===!0&&(n.wrap=!0),r=r||n.step||1,ph(r)?ph(t)&&ph(e)?ype(t,e,r,n):wpe(t,e,Math.max(Math.abs(r),1),n):r!=null&&!d1(r)?Ipe(r,n):LE(t,e,1,r)};h1.exports=LE});var Q1=E((O$e,w1)=>{"use strict";var Bpe=Wb(),B1=FE(),Qpe=(t,e={})=>{let r=(i,n={})=>{let s=B1.isInvalidBrace(n),o=i.invalid===!0&&e.escapeInvalid===!0,a=s===!0||o===!0,l=e.escapeInvalid===!0?"\\":"",c="";if(i.isOpen===!0||i.isClose===!0)return l+i.value;if(i.type==="open")return a?l+i.value:"(";if(i.type==="close")return a?l+i.value:")";if(i.type==="comma")return i.prev.type==="comma"?"":a?i.value:"|";if(i.value)return i.value;if(i.nodes&&i.ranges>0){let u=B1.reduce(i.nodes),g=Bpe(...u,_(P({},e),{wrap:!1,toRegex:!0}));if(g.length!==0)return u.length>1&&g.length>1?`(${g})`:g}if(i.nodes)for(let u of i.nodes)c+=r(u,i);return c};return r(t)};w1.exports=Qpe});var S1=E((K$e,b1)=>{"use strict";var bpe=Wb(),v1=NE(),ou=FE(),Il=(t="",e="",r=!1)=>{let i=[];if(t=[].concat(t),e=[].concat(e),!e.length)return t;if(!t.length)return r?ou.flatten(e).map(n=>`{${n}}`):e;for(let n of t)if(Array.isArray(n))for(let s of n)i.push(Il(s,e,r));else for(let s of e)r===!0&&typeof s=="string"&&(s=`{${s}}`),i.push(Array.isArray(s)?Il(n,s,r):n+s);return ou.flatten(i)},vpe=(t,e={})=>{let r=e.rangeLimit===void 0?1e3:e.rangeLimit,i=(n,s={})=>{n.queue=[];let o=s,a=s.queue;for(;o.type!=="brace"&&o.type!=="root"&&o.parent;)o=o.parent,a=o.queue;if(n.invalid||n.dollar){a.push(Il(a.pop(),v1(n,e)));return}if(n.type==="brace"&&n.invalid!==!0&&n.nodes.length===2){a.push(Il(a.pop(),["{}"]));return}if(n.nodes&&n.ranges>0){let g=ou.reduce(n.nodes);if(ou.exceedsLimit(...g,e.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let f=bpe(...g,e);f.length===0&&(f=v1(n,e)),a.push(Il(a.pop(),f)),n.nodes=[];return}let l=ou.encloseBrace(n),c=n.queue,u=n;for(;u.type!=="brace"&&u.type!=="root"&&u.parent;)u=u.parent,c=u.queue;for(let g=0;g{"use strict";x1.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` +`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var N1=E((H$e,P1)=>{"use strict";var Spe=NE(),{MAX_LENGTH:D1,CHAR_BACKSLASH:zb,CHAR_BACKTICK:xpe,CHAR_COMMA:kpe,CHAR_DOT:Ppe,CHAR_LEFT_PARENTHESES:Dpe,CHAR_RIGHT_PARENTHESES:Rpe,CHAR_LEFT_CURLY_BRACE:Fpe,CHAR_RIGHT_CURLY_BRACE:Npe,CHAR_LEFT_SQUARE_BRACKET:R1,CHAR_RIGHT_SQUARE_BRACKET:F1,CHAR_DOUBLE_QUOTE:Lpe,CHAR_SINGLE_QUOTE:Tpe,CHAR_NO_BREAK_SPACE:Mpe,CHAR_ZERO_WIDTH_NOBREAK_SPACE:Ope}=k1(),Kpe=(t,e={})=>{if(typeof t!="string")throw new TypeError("Expected a string");let r=e||{},i=typeof r.maxLength=="number"?Math.min(D1,r.maxLength):D1;if(t.length>i)throw new SyntaxError(`Input length (${t.length}), exceeds max characters (${i})`);let n={type:"root",input:t,nodes:[]},s=[n],o=n,a=n,l=0,c=t.length,u=0,g=0,f,h={},p=()=>t[u++],d=m=>{if(m.type==="text"&&a.type==="dot"&&(a.type="text"),a&&a.type==="text"&&m.type==="text"){a.value+=m.value;return}return o.nodes.push(m),m.parent=o,m.prev=a,a=m,m};for(d({type:"bos"});u0){if(o.ranges>0){o.ranges=0;let m=o.nodes.shift();o.nodes=[m,{type:"text",value:Spe(o)}]}d({type:"comma",value:f}),o.commas++;continue}if(f===Ppe&&g>0&&o.commas===0){let m=o.nodes;if(g===0||m.length===0){d({type:"text",value:f});continue}if(a.type==="dot"){if(o.range=[],a.value+=f,a.type="range",o.nodes.length!==3&&o.nodes.length!==5){o.invalid=!0,o.ranges=0,a.type="text";continue}o.ranges++,o.args=[];continue}if(a.type==="range"){m.pop();let I=m[m.length-1];I.value+=a.value+f,a=I,o.ranges--;continue}d({type:"dot",value:f});continue}d({type:"text",value:f})}do if(o=s.pop(),o.type!=="root"){o.nodes.forEach(B=>{B.nodes||(B.type==="open"&&(B.isOpen=!0),B.type==="close"&&(B.isClose=!0),B.nodes||(B.type="text"),B.invalid=!0)});let m=s[s.length-1],I=m.nodes.indexOf(o);m.nodes.splice(I,1,...o.nodes)}while(s.length>0);return d({type:"eos"}),n};P1.exports=Kpe});var M1=E((G$e,L1)=>{"use strict";var T1=NE(),Upe=Q1(),Hpe=S1(),Gpe=N1(),Rn=(t,e={})=>{let r=[];if(Array.isArray(t))for(let i of t){let n=Rn.create(i,e);Array.isArray(n)?r.push(...n):r.push(n)}else r=[].concat(Rn.create(t,e));return e&&e.expand===!0&&e.nodupes===!0&&(r=[...new Set(r)]),r};Rn.parse=(t,e={})=>Gpe(t,e);Rn.stringify=(t,e={})=>typeof t=="string"?T1(Rn.parse(t,e),e):T1(t,e);Rn.compile=(t,e={})=>(typeof t=="string"&&(t=Rn.parse(t,e)),Upe(t,e));Rn.expand=(t,e={})=>{typeof t=="string"&&(t=Rn.parse(t,e));let r=Hpe(t,e);return e.noempty===!0&&(r=r.filter(Boolean)),e.nodupes===!0&&(r=[...new Set(r)]),r};Rn.create=(t,e={})=>t===""||t.length<3?[t]:e.expand!==!0?Rn.compile(t,e):Rn.expand(t,e);L1.exports=Rn});var dh=E((j$e,O1)=>{"use strict";var jpe=require("path"),io="\\\\/",K1=`[^${io}]`,ea="\\.",Ype="\\+",qpe="\\?",TE="\\/",Jpe="(?=.)",U1="[^/]",Vb=`(?:${TE}|$)`,H1=`(?:^|${TE})`,_b=`${ea}{1,2}${Vb}`,Wpe=`(?!${ea})`,zpe=`(?!${H1}${_b})`,Vpe=`(?!${ea}{0,1}${Vb})`,_pe=`(?!${_b})`,Xpe=`[^.${TE}]`,Zpe=`${U1}*?`,G1={DOT_LITERAL:ea,PLUS_LITERAL:Ype,QMARK_LITERAL:qpe,SLASH_LITERAL:TE,ONE_CHAR:Jpe,QMARK:U1,END_ANCHOR:Vb,DOTS_SLASH:_b,NO_DOT:Wpe,NO_DOTS:zpe,NO_DOT_SLASH:Vpe,NO_DOTS_SLASH:_pe,QMARK_NO_DOT:Xpe,STAR:Zpe,START_ANCHOR:H1},$pe=_(P({},G1),{SLASH_LITERAL:`[${io}]`,QMARK:K1,STAR:`${K1}*?`,DOTS_SLASH:`${ea}{1,2}(?:[${io}]|$)`,NO_DOT:`(?!${ea})`,NO_DOTS:`(?!(?:^|[${io}])${ea}{1,2}(?:[${io}]|$))`,NO_DOT_SLASH:`(?!${ea}{0,1}(?:[${io}]|$))`,NO_DOTS_SLASH:`(?!${ea}{1,2}(?:[${io}]|$))`,QMARK_NO_DOT:`[^.${io}]`,START_ANCHOR:`(?:^|[${io}])`,END_ANCHOR:`(?:[${io}]|$)`}),ede={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};O1.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:ede,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:jpe.sep,extglobChars(t){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${t.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(t){return t===!0?$pe:G1}}});var Ch=E(cn=>{"use strict";var tde=require("path"),rde=process.platform==="win32",{REGEX_BACKSLASH:ide,REGEX_REMOVE_BACKSLASH:nde,REGEX_SPECIAL_CHARS:sde,REGEX_SPECIAL_CHARS_GLOBAL:ode}=dh();cn.isObject=t=>t!==null&&typeof t=="object"&&!Array.isArray(t);cn.hasRegexChars=t=>sde.test(t);cn.isRegexChar=t=>t.length===1&&cn.hasRegexChars(t);cn.escapeRegex=t=>t.replace(ode,"\\$1");cn.toPosixSlashes=t=>t.replace(ide,"/");cn.removeBackslashes=t=>t.replace(nde,e=>e==="\\"?"":e);cn.supportsLookbehinds=()=>{let t=process.version.slice(1).split(".").map(Number);return t.length===3&&t[0]>=9||t[0]===8&&t[1]>=10};cn.isWindows=t=>t&&typeof t.windows=="boolean"?t.windows:rde===!0||tde.sep==="\\";cn.escapeLast=(t,e,r)=>{let i=t.lastIndexOf(e,r);return i===-1?t:t[i-1]==="\\"?cn.escapeLast(t,e,i-1):`${t.slice(0,i)}\\${t.slice(i)}`};cn.removePrefix=(t,e={})=>{let r=t;return r.startsWith("./")&&(r=r.slice(2),e.prefix="./"),r};cn.wrapOutput=(t,e={},r={})=>{let i=r.contains?"":"^",n=r.contains?"":"$",s=`${i}(?:${t})${n}`;return e.negated===!0&&(s=`(?:^(?!${s}).*$)`),s}});var X1=E((q$e,j1)=>{"use strict";var Y1=Ch(),{CHAR_ASTERISK:Xb,CHAR_AT:ade,CHAR_BACKWARD_SLASH:mh,CHAR_COMMA:Ade,CHAR_DOT:Zb,CHAR_EXCLAMATION_MARK:q1,CHAR_FORWARD_SLASH:J1,CHAR_LEFT_CURLY_BRACE:$b,CHAR_LEFT_PARENTHESES:ev,CHAR_LEFT_SQUARE_BRACKET:lde,CHAR_PLUS:cde,CHAR_QUESTION_MARK:W1,CHAR_RIGHT_CURLY_BRACE:ude,CHAR_RIGHT_PARENTHESES:z1,CHAR_RIGHT_SQUARE_BRACKET:gde}=dh(),V1=t=>t===J1||t===mh,_1=t=>{t.isPrefix!==!0&&(t.depth=t.isGlobstar?Infinity:1)},fde=(t,e)=>{let r=e||{},i=t.length-1,n=r.parts===!0||r.scanToEnd===!0,s=[],o=[],a=[],l=t,c=-1,u=0,g=0,f=!1,h=!1,p=!1,d=!1,m=!1,I=!1,B=!1,b=!1,R=!1,H=0,L,K,J={value:"",depth:0,isGlob:!1},ne=()=>c>=i,q=()=>l.charCodeAt(c+1),A=()=>(L=K,l.charCodeAt(++c));for(;c0&&(W=l.slice(0,u),l=l.slice(u),g-=u),V&&p===!0&&g>0?(V=l.slice(0,g),X=l.slice(g)):p===!0?(V="",X=l):V=l,V&&V!==""&&V!=="/"&&V!==l&&V1(V.charCodeAt(V.length-1))&&(V=V.slice(0,-1)),r.unescape===!0&&(X&&(X=Y1.removeBackslashes(X)),V&&B===!0&&(V=Y1.removeBackslashes(V)));let F={prefix:W,input:t,start:u,base:V,glob:X,isBrace:f,isBracket:h,isGlob:p,isExtglob:d,isGlobstar:m,negated:b};if(r.tokens===!0&&(F.maxDepth=0,V1(K)||o.push(J),F.tokens=o),r.parts===!0||r.tokens===!0){let D;for(let he=0;he{"use strict";var ME=dh(),Fn=Ch(),{MAX_LENGTH:OE,POSIX_REGEX_SOURCE:hde,REGEX_NON_SPECIAL_CHARS:pde,REGEX_SPECIAL_CHARS_BACKREF:dde,REPLACEMENTS:$1}=ME,Cde=(t,e)=>{if(typeof e.expandRange=="function")return e.expandRange(...t,e);t.sort();let r=`[${t.join("-")}]`;try{new RegExp(r)}catch(i){return t.map(n=>Fn.escapeRegex(n)).join("..")}return r},au=(t,e)=>`Missing ${t}: "${e}" - use "\\\\${e}" to match literal characters`,eU=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");t=$1[t]||t;let r=P({},e),i=typeof r.maxLength=="number"?Math.min(OE,r.maxLength):OE,n=t.length;if(n>i)throw new SyntaxError(`Input length: ${n}, exceeds maximum allowed length: ${i}`);let s={type:"bos",value:"",output:r.prepend||""},o=[s],a=r.capture?"":"?:",l=Fn.isWindows(e),c=ME.globChars(l),u=ME.extglobChars(c),{DOT_LITERAL:g,PLUS_LITERAL:f,SLASH_LITERAL:h,ONE_CHAR:p,DOTS_SLASH:d,NO_DOT:m,NO_DOT_SLASH:I,NO_DOTS_SLASH:B,QMARK:b,QMARK_NO_DOT:R,STAR:H,START_ANCHOR:L}=c,K=G=>`(${a}(?:(?!${L}${G.dot?d:g}).)*?)`,J=r.dot?"":m,ne=r.dot?b:R,q=r.bash===!0?K(r):H;r.capture&&(q=`(${q})`),typeof r.noext=="boolean"&&(r.noextglob=r.noext);let A={input:t,index:-1,start:0,dot:r.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:o};t=Fn.removePrefix(t,A),n=t.length;let V=[],W=[],X=[],F=s,D,he=()=>A.index===n-1,pe=A.peek=(G=1)=>t[A.index+G],Ne=A.advance=()=>t[++A.index],Pe=()=>t.slice(A.index+1),qe=(G="",Ce=0)=>{A.consumed+=G,A.index+=Ce},re=G=>{A.output+=G.output!=null?G.output:G.value,qe(G.value)},se=()=>{let G=1;for(;pe()==="!"&&(pe(2)!=="("||pe(3)==="?");)Ne(),A.start++,G++;return G%2==0?!1:(A.negated=!0,A.start++,!0)},be=G=>{A[G]++,X.push(G)},ae=G=>{A[G]--,X.pop()},Ae=G=>{if(F.type==="globstar"){let Ce=A.braces>0&&(G.type==="comma"||G.type==="brace"),ee=G.extglob===!0||V.length&&(G.type==="pipe"||G.type==="paren");G.type!=="slash"&&G.type!=="paren"&&!Ce&&!ee&&(A.output=A.output.slice(0,-F.output.length),F.type="star",F.value="*",F.output=q,A.output+=F.output)}if(V.length&&G.type!=="paren"&&!u[G.value]&&(V[V.length-1].inner+=G.value),(G.value||G.output)&&re(G),F&&F.type==="text"&&G.type==="text"){F.value+=G.value,F.output=(F.output||"")+G.value;return}G.prev=F,o.push(G),F=G},De=(G,Ce)=>{let ee=_(P({},u[Ce]),{conditions:1,inner:""});ee.prev=F,ee.parens=A.parens,ee.output=A.output;let Ue=(r.capture?"(":"")+ee.open;be("parens"),Ae({type:G,value:Ce,output:A.output?"":p}),Ae({type:"paren",extglob:!0,value:Ne(),output:Ue}),V.push(ee)},$=G=>{let Ce=G.close+(r.capture?")":"");if(G.type==="negate"){let ee=q;G.inner&&G.inner.length>1&&G.inner.includes("/")&&(ee=K(r)),(ee!==q||he()||/^\)+$/.test(Pe()))&&(Ce=G.close=`)$))${ee}`),G.prev.type==="bos"&&(A.negatedExtglob=!0)}Ae({type:"paren",extglob:!0,value:D,output:Ce}),ae("parens")};if(r.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(t)){let G=!1,Ce=t.replace(dde,(ee,Ue,Oe,vt,dt,ri)=>vt==="\\"?(G=!0,ee):vt==="?"?Ue?Ue+vt+(dt?b.repeat(dt.length):""):ri===0?ne+(dt?b.repeat(dt.length):""):b.repeat(Oe.length):vt==="."?g.repeat(Oe.length):vt==="*"?Ue?Ue+vt+(dt?q:""):q:Ue?ee:`\\${ee}`);return G===!0&&(r.unescape===!0?Ce=Ce.replace(/\\/g,""):Ce=Ce.replace(/\\+/g,ee=>ee.length%2==0?"\\\\":ee?"\\":"")),Ce===t&&r.contains===!0?(A.output=t,A):(A.output=Fn.wrapOutput(Ce,A,e),A)}for(;!he();){if(D=Ne(),D==="\0")continue;if(D==="\\"){let ee=pe();if(ee==="/"&&r.bash!==!0||ee==="."||ee===";")continue;if(!ee){D+="\\",Ae({type:"text",value:D});continue}let Ue=/^\\+/.exec(Pe()),Oe=0;if(Ue&&Ue[0].length>2&&(Oe=Ue[0].length,A.index+=Oe,Oe%2!=0&&(D+="\\")),r.unescape===!0?D=Ne()||"":D+=Ne()||"",A.brackets===0){Ae({type:"text",value:D});continue}}if(A.brackets>0&&(D!=="]"||F.value==="["||F.value==="[^")){if(r.posix!==!1&&D===":"){let ee=F.value.slice(1);if(ee.includes("[")&&(F.posix=!0,ee.includes(":"))){let Ue=F.value.lastIndexOf("["),Oe=F.value.slice(0,Ue),vt=F.value.slice(Ue+2),dt=hde[vt];if(dt){F.value=Oe+dt,A.backtrack=!0,Ne(),!s.output&&o.indexOf(F)===1&&(s.output=p);continue}}}(D==="["&&pe()!==":"||D==="-"&&pe()==="]")&&(D=`\\${D}`),D==="]"&&(F.value==="["||F.value==="[^")&&(D=`\\${D}`),r.posix===!0&&D==="!"&&F.value==="["&&(D="^"),F.value+=D,re({value:D});continue}if(A.quotes===1&&D!=='"'){D=Fn.escapeRegex(D),F.value+=D,re({value:D});continue}if(D==='"'){A.quotes=A.quotes===1?0:1,r.keepQuotes===!0&&Ae({type:"text",value:D});continue}if(D==="("){be("parens"),Ae({type:"paren",value:D});continue}if(D===")"){if(A.parens===0&&r.strictBrackets===!0)throw new SyntaxError(au("opening","("));let ee=V[V.length-1];if(ee&&A.parens===ee.parens+1){$(V.pop());continue}Ae({type:"paren",value:D,output:A.parens?")":"\\)"}),ae("parens");continue}if(D==="["){if(r.nobracket===!0||!Pe().includes("]")){if(r.nobracket!==!0&&r.strictBrackets===!0)throw new SyntaxError(au("closing","]"));D=`\\${D}`}else be("brackets");Ae({type:"bracket",value:D});continue}if(D==="]"){if(r.nobracket===!0||F&&F.type==="bracket"&&F.value.length===1){Ae({type:"text",value:D,output:`\\${D}`});continue}if(A.brackets===0){if(r.strictBrackets===!0)throw new SyntaxError(au("opening","["));Ae({type:"text",value:D,output:`\\${D}`});continue}ae("brackets");let ee=F.value.slice(1);if(F.posix!==!0&&ee[0]==="^"&&!ee.includes("/")&&(D=`/${D}`),F.value+=D,re({value:D}),r.literalBrackets===!1||Fn.hasRegexChars(ee))continue;let Ue=Fn.escapeRegex(F.value);if(A.output=A.output.slice(0,-F.value.length),r.literalBrackets===!0){A.output+=Ue,F.value=Ue;continue}F.value=`(${a}${Ue}|${F.value})`,A.output+=F.value;continue}if(D==="{"&&r.nobrace!==!0){be("braces");let ee={type:"brace",value:D,output:"(",outputIndex:A.output.length,tokensIndex:A.tokens.length};W.push(ee),Ae(ee);continue}if(D==="}"){let ee=W[W.length-1];if(r.nobrace===!0||!ee){Ae({type:"text",value:D,output:D});continue}let Ue=")";if(ee.dots===!0){let Oe=o.slice(),vt=[];for(let dt=Oe.length-1;dt>=0&&(o.pop(),Oe[dt].type!=="brace");dt--)Oe[dt].type!=="dots"&&vt.unshift(Oe[dt].value);Ue=Cde(vt,r),A.backtrack=!0}if(ee.comma!==!0&&ee.dots!==!0){let Oe=A.output.slice(0,ee.outputIndex),vt=A.tokens.slice(ee.tokensIndex);ee.value=ee.output="\\{",D=Ue="\\}",A.output=Oe;for(let dt of vt)A.output+=dt.output||dt.value}Ae({type:"brace",value:D,output:Ue}),ae("braces"),W.pop();continue}if(D==="|"){V.length>0&&V[V.length-1].conditions++,Ae({type:"text",value:D});continue}if(D===","){let ee=D,Ue=W[W.length-1];Ue&&X[X.length-1]==="braces"&&(Ue.comma=!0,ee="|"),Ae({type:"comma",value:D,output:ee});continue}if(D==="/"){if(F.type==="dot"&&A.index===A.start+1){A.start=A.index+1,A.consumed="",A.output="",o.pop(),F=s;continue}Ae({type:"slash",value:D,output:h});continue}if(D==="."){if(A.braces>0&&F.type==="dot"){F.value==="."&&(F.output=g);let ee=W[W.length-1];F.type="dots",F.output+=D,F.value+=D,ee.dots=!0;continue}if(A.braces+A.parens===0&&F.type!=="bos"&&F.type!=="slash"){Ae({type:"text",value:D,output:g});continue}Ae({type:"dot",value:D,output:g});continue}if(D==="?"){if(!(F&&F.value==="(")&&r.noextglob!==!0&&pe()==="("&&pe(2)!=="?"){De("qmark",D);continue}if(F&&F.type==="paren"){let Ue=pe(),Oe=D;if(Ue==="<"&&!Fn.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(F.value==="("&&!/[!=<:]/.test(Ue)||Ue==="<"&&!/<([!=]|\w+>)/.test(Pe()))&&(Oe=`\\${D}`),Ae({type:"text",value:D,output:Oe});continue}if(r.dot!==!0&&(F.type==="slash"||F.type==="bos")){Ae({type:"qmark",value:D,output:R});continue}Ae({type:"qmark",value:D,output:b});continue}if(D==="!"){if(r.noextglob!==!0&&pe()==="("&&(pe(2)!=="?"||!/[!=<:]/.test(pe(3)))){De("negate",D);continue}if(r.nonegate!==!0&&A.index===0){se();continue}}if(D==="+"){if(r.noextglob!==!0&&pe()==="("&&pe(2)!=="?"){De("plus",D);continue}if(F&&F.value==="("||r.regex===!1){Ae({type:"plus",value:D,output:f});continue}if(F&&(F.type==="bracket"||F.type==="paren"||F.type==="brace")||A.parens>0){Ae({type:"plus",value:D});continue}Ae({type:"plus",value:f});continue}if(D==="@"){if(r.noextglob!==!0&&pe()==="("&&pe(2)!=="?"){Ae({type:"at",extglob:!0,value:D,output:""});continue}Ae({type:"text",value:D});continue}if(D!=="*"){(D==="$"||D==="^")&&(D=`\\${D}`);let ee=pde.exec(Pe());ee&&(D+=ee[0],A.index+=ee[0].length),Ae({type:"text",value:D});continue}if(F&&(F.type==="globstar"||F.star===!0)){F.type="star",F.star=!0,F.value+=D,F.output=q,A.backtrack=!0,A.globstar=!0,qe(D);continue}let G=Pe();if(r.noextglob!==!0&&/^\([^?]/.test(G)){De("star",D);continue}if(F.type==="star"){if(r.noglobstar===!0){qe(D);continue}let ee=F.prev,Ue=ee.prev,Oe=ee.type==="slash"||ee.type==="bos",vt=Ue&&(Ue.type==="star"||Ue.type==="globstar");if(r.bash===!0&&(!Oe||G[0]&&G[0]!=="/")){Ae({type:"star",value:D,output:""});continue}let dt=A.braces>0&&(ee.type==="comma"||ee.type==="brace"),ri=V.length&&(ee.type==="pipe"||ee.type==="paren");if(!Oe&&ee.type!=="paren"&&!dt&&!ri){Ae({type:"star",value:D,output:""});continue}for(;G.slice(0,3)==="/**";){let ii=t[A.index+4];if(ii&&ii!=="/")break;G=G.slice(3),qe("/**",3)}if(ee.type==="bos"&&he()){F.type="globstar",F.value+=D,F.output=K(r),A.output=F.output,A.globstar=!0,qe(D);continue}if(ee.type==="slash"&&ee.prev.type!=="bos"&&!vt&&he()){A.output=A.output.slice(0,-(ee.output+F.output).length),ee.output=`(?:${ee.output}`,F.type="globstar",F.output=K(r)+(r.strictSlashes?")":"|$)"),F.value+=D,A.globstar=!0,A.output+=ee.output+F.output,qe(D);continue}if(ee.type==="slash"&&ee.prev.type!=="bos"&&G[0]==="/"){let ii=G[1]!==void 0?"|$":"";A.output=A.output.slice(0,-(ee.output+F.output).length),ee.output=`(?:${ee.output}`,F.type="globstar",F.output=`${K(r)}${h}|${h}${ii})`,F.value+=D,A.output+=ee.output+F.output,A.globstar=!0,qe(D+Ne()),Ae({type:"slash",value:"/",output:""});continue}if(ee.type==="bos"&&G[0]==="/"){F.type="globstar",F.value+=D,F.output=`(?:^|${h}|${K(r)}${h})`,A.output=F.output,A.globstar=!0,qe(D+Ne()),Ae({type:"slash",value:"/",output:""});continue}A.output=A.output.slice(0,-F.output.length),F.type="globstar",F.output=K(r),F.value+=D,A.output+=F.output,A.globstar=!0,qe(D);continue}let Ce={type:"star",value:D,output:q};if(r.bash===!0){Ce.output=".*?",(F.type==="bos"||F.type==="slash")&&(Ce.output=J+Ce.output),Ae(Ce);continue}if(F&&(F.type==="bracket"||F.type==="paren")&&r.regex===!0){Ce.output=D,Ae(Ce);continue}(A.index===A.start||F.type==="slash"||F.type==="dot")&&(F.type==="dot"?(A.output+=I,F.output+=I):r.dot===!0?(A.output+=B,F.output+=B):(A.output+=J,F.output+=J),pe()!=="*"&&(A.output+=p,F.output+=p)),Ae(Ce)}for(;A.brackets>0;){if(r.strictBrackets===!0)throw new SyntaxError(au("closing","]"));A.output=Fn.escapeLast(A.output,"["),ae("brackets")}for(;A.parens>0;){if(r.strictBrackets===!0)throw new SyntaxError(au("closing",")"));A.output=Fn.escapeLast(A.output,"("),ae("parens")}for(;A.braces>0;){if(r.strictBrackets===!0)throw new SyntaxError(au("closing","}"));A.output=Fn.escapeLast(A.output,"{"),ae("braces")}if(r.strictSlashes!==!0&&(F.type==="star"||F.type==="bracket")&&Ae({type:"maybe_slash",value:"",output:`${h}?`}),A.backtrack===!0){A.output="";for(let G of A.tokens)A.output+=G.output!=null?G.output:G.value,G.suffix&&(A.output+=G.suffix)}return A};eU.fastpaths=(t,e)=>{let r=P({},e),i=typeof r.maxLength=="number"?Math.min(OE,r.maxLength):OE,n=t.length;if(n>i)throw new SyntaxError(`Input length: ${n}, exceeds maximum allowed length: ${i}`);t=$1[t]||t;let s=Fn.isWindows(e),{DOT_LITERAL:o,SLASH_LITERAL:a,ONE_CHAR:l,DOTS_SLASH:c,NO_DOT:u,NO_DOTS:g,NO_DOTS_SLASH:f,STAR:h,START_ANCHOR:p}=ME.globChars(s),d=r.dot?g:u,m=r.dot?f:u,I=r.capture?"":"?:",B={negated:!1,prefix:""},b=r.bash===!0?".*?":h;r.capture&&(b=`(${b})`);let R=J=>J.noglobstar===!0?b:`(${I}(?:(?!${p}${J.dot?c:o}).)*?)`,H=J=>{switch(J){case"*":return`${d}${l}${b}`;case".*":return`${o}${l}${b}`;case"*.*":return`${d}${b}${o}${l}${b}`;case"*/*":return`${d}${b}${a}${l}${m}${b}`;case"**":return d+R(r);case"**/*":return`(?:${d}${R(r)}${a})?${m}${l}${b}`;case"**/*.*":return`(?:${d}${R(r)}${a})?${m}${b}${o}${l}${b}`;case"**/.*":return`(?:${d}${R(r)}${a})?${o}${l}${b}`;default:{let ne=/^(.*?)\.(\w+)$/.exec(J);if(!ne)return;let q=H(ne[1]);return q?q+o+ne[2]:void 0}}},L=Fn.removePrefix(t,B),K=H(L);return K&&r.strictSlashes!==!0&&(K+=`${a}?`),K};Z1.exports=eU});var iU=E((W$e,rU)=>{"use strict";var mde=require("path"),Ede=X1(),tv=tU(),rv=Ch(),Ide=dh(),yde=t=>t&&typeof t=="object"&&!Array.isArray(t),Dr=(t,e,r=!1)=>{if(Array.isArray(t)){let u=t.map(f=>Dr(f,e,r));return f=>{for(let h of u){let p=h(f);if(p)return p}return!1}}let i=yde(t)&&t.tokens&&t.input;if(t===""||typeof t!="string"&&!i)throw new TypeError("Expected pattern to be a non-empty string");let n=e||{},s=rv.isWindows(e),o=i?Dr.compileRe(t,e):Dr.makeRe(t,e,!1,!0),a=o.state;delete o.state;let l=()=>!1;if(n.ignore){let u=_(P({},e),{ignore:null,onMatch:null,onResult:null});l=Dr(n.ignore,u,r)}let c=(u,g=!1)=>{let{isMatch:f,match:h,output:p}=Dr.test(u,o,e,{glob:t,posix:s}),d={glob:t,state:a,regex:o,posix:s,input:u,output:p,match:h,isMatch:f};return typeof n.onResult=="function"&&n.onResult(d),f===!1?(d.isMatch=!1,g?d:!1):l(u)?(typeof n.onIgnore=="function"&&n.onIgnore(d),d.isMatch=!1,g?d:!1):(typeof n.onMatch=="function"&&n.onMatch(d),g?d:!0)};return r&&(c.state=a),c};Dr.test=(t,e,r,{glob:i,posix:n}={})=>{if(typeof t!="string")throw new TypeError("Expected input to be a string");if(t==="")return{isMatch:!1,output:""};let s=r||{},o=s.format||(n?rv.toPosixSlashes:null),a=t===i,l=a&&o?o(t):t;return a===!1&&(l=o?o(t):t,a=l===i),(a===!1||s.capture===!0)&&(s.matchBase===!0||s.basename===!0?a=Dr.matchBase(t,e,r,n):a=e.exec(l)),{isMatch:Boolean(a),match:a,output:l}};Dr.matchBase=(t,e,r,i=rv.isWindows(r))=>(e instanceof RegExp?e:Dr.makeRe(e,r)).test(mde.basename(t));Dr.isMatch=(t,e,r)=>Dr(e,r)(t);Dr.parse=(t,e)=>Array.isArray(t)?t.map(r=>Dr.parse(r,e)):tv(t,_(P({},e),{fastpaths:!1}));Dr.scan=(t,e)=>Ede(t,e);Dr.compileRe=(t,e,r=!1,i=!1)=>{if(r===!0)return t.output;let n=e||{},s=n.contains?"":"^",o=n.contains?"":"$",a=`${s}(?:${t.output})${o}`;t&&t.negated===!0&&(a=`^(?!${a}).*$`);let l=Dr.toRegex(a,e);return i===!0&&(l.state=t),l};Dr.makeRe=(t,e,r=!1,i=!1)=>{if(!t||typeof t!="string")throw new TypeError("Expected a non-empty string");let n=e||{},s={negated:!1,fastpaths:!0},o="",a;return t.startsWith("./")&&(t=t.slice(2),o=s.prefix="./"),n.fastpaths!==!1&&(t[0]==="."||t[0]==="*")&&(a=tv.fastpaths(t,e)),a===void 0?(s=tv(t,e),s.prefix=o+(s.prefix||"")):s.output=a,Dr.compileRe(s,e,r,i)};Dr.toRegex=(t,e)=>{try{let r=e||{};return new RegExp(t,r.flags||(r.nocase?"i":""))}catch(r){if(e&&e.debug===!0)throw r;return/$^/}};Dr.constants=Ide;rU.exports=Dr});var iv=E((z$e,nU)=>{"use strict";nU.exports=iU()});var Nn=E((V$e,sU)=>{"use strict";var oU=require("util"),aU=M1(),no=iv(),nv=Ch(),AU=t=>typeof t=="string"&&(t===""||t==="./"),pr=(t,e,r)=>{e=[].concat(e),t=[].concat(t);let i=new Set,n=new Set,s=new Set,o=0,a=u=>{s.add(u.output),r&&r.onResult&&r.onResult(u)};for(let u=0;u!i.has(u));if(r&&c.length===0){if(r.failglob===!0)throw new Error(`No matches found for "${e.join(", ")}"`);if(r.nonull===!0||r.nullglob===!0)return r.unescape?e.map(u=>u.replace(/\\/g,"")):e}return c};pr.match=pr;pr.matcher=(t,e)=>no(t,e);pr.isMatch=(t,e,r)=>no(e,r)(t);pr.any=pr.isMatch;pr.not=(t,e,r={})=>{e=[].concat(e).map(String);let i=new Set,n=[],s=a=>{r.onResult&&r.onResult(a),n.push(a.output)},o=pr(t,e,_(P({},r),{onResult:s}));for(let a of n)o.includes(a)||i.add(a);return[...i]};pr.contains=(t,e,r)=>{if(typeof t!="string")throw new TypeError(`Expected a string: "${oU.inspect(t)}"`);if(Array.isArray(e))return e.some(i=>pr.contains(t,i,r));if(typeof e=="string"){if(AU(t)||AU(e))return!1;if(t.includes(e)||t.startsWith("./")&&t.slice(2).includes(e))return!0}return pr.isMatch(t,e,_(P({},r),{contains:!0}))};pr.matchKeys=(t,e,r)=>{if(!nv.isObject(t))throw new TypeError("Expected the first argument to be an object");let i=pr(Object.keys(t),e,r),n={};for(let s of i)n[s]=t[s];return n};pr.some=(t,e,r)=>{let i=[].concat(t);for(let n of[].concat(e)){let s=no(String(n),r);if(i.some(o=>s(o)))return!0}return!1};pr.every=(t,e,r)=>{let i=[].concat(t);for(let n of[].concat(e)){let s=no(String(n),r);if(!i.every(o=>s(o)))return!1}return!0};pr.all=(t,e,r)=>{if(typeof t!="string")throw new TypeError(`Expected a string: "${oU.inspect(t)}"`);return[].concat(e).every(i=>no(i,r)(t))};pr.capture=(t,e,r)=>{let i=nv.isWindows(r),s=no.makeRe(String(t),_(P({},r),{capture:!0})).exec(i?nv.toPosixSlashes(e):e);if(s)return s.slice(1).map(o=>o===void 0?"":o)};pr.makeRe=(...t)=>no.makeRe(...t);pr.scan=(...t)=>no.scan(...t);pr.parse=(t,e)=>{let r=[];for(let i of[].concat(t||[]))for(let n of aU(String(i),e))r.push(no.parse(n,e));return r};pr.braces=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");return e&&e.nobrace===!0||!/\{.*\}/.test(t)?[t]:aU(t,e)};pr.braceExpand=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");return pr.braces(t,_(P({},e),{expand:!0}))};sU.exports=pr});var cU=E((_$e,lU)=>{"use strict";lU.exports=({onlyFirst:t=!1}={})=>{let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,t?void 0:"g")}});var gU=E((X$e,uU)=>{"use strict";var wde=cU();uU.exports=t=>typeof t=="string"?t.replace(wde(),""):t});var lu={};it(lu,{KeyRelationship:()=>Bl,applyCascade:()=>fv,base64RegExp:()=>CU,colorStringAlphaRegExp:()=>dU,colorStringRegExp:()=>pU,computeKey:()=>rA,getPrintable:()=>Mr,hasExactLength:()=>wU,hasForbiddenKeys:()=>eCe,hasKeyRelationship:()=>pv,hasMaxLength:()=>Mde,hasMinLength:()=>Tde,hasMutuallyExclusiveKeys:()=>tCe,hasRequiredKeys:()=>$de,hasUniqueItems:()=>Ode,isArray:()=>xde,isAtLeast:()=>Hde,isAtMost:()=>Gde,isBase64:()=>Xde,isBoolean:()=>bde,isDate:()=>Sde,isDict:()=>Pde,isEnum:()=>Yi,isHexColor:()=>_de,isISO8601:()=>Vde,isInExclusiveRange:()=>Yde,isInInclusiveRange:()=>jde,isInstanceOf:()=>Rde,isInteger:()=>qde,isJSON:()=>Zde,isLiteral:()=>Bde,isLowerCase:()=>Jde,isNegative:()=>Kde,isNullable:()=>Lde,isNumber:()=>vde,isObject:()=>Dde,isOneOf:()=>Fde,isOptional:()=>Nde,isPositive:()=>Ude,isString:()=>gv,isTuple:()=>kde,isUUID4:()=>zde,isUnknown:()=>yU,isUpperCase:()=>Wde,iso8601RegExp:()=>uv,makeCoercionFn:()=>wl,makeSetter:()=>IU,makeTrait:()=>EU,makeValidator:()=>Ct,matchesRegExp:()=>hv,plural:()=>GE,pushError:()=>at,simpleKeyRegExp:()=>hU,uuid4RegExp:()=>mU});function Ct({test:t}){return EU(t)()}function Mr(t){return t===null?"null":t===void 0?"undefined":t===""?"an empty string":JSON.stringify(t)}function rA(t,e){var r,i,n;return typeof e=="number"?`${(r=t==null?void 0:t.p)!==null&&r!==void 0?r:"."}[${e}]`:hU.test(e)?`${(i=t==null?void 0:t.p)!==null&&i!==void 0?i:""}.${e}`:`${(n=t==null?void 0:t.p)!==null&&n!==void 0?n:"."}[${JSON.stringify(e)}]`}function wl(t,e){return r=>{let i=t[e];return t[e]=r,wl(t,e).bind(null,i)}}function IU(t,e){return r=>{t[e]=r}}function GE(t,e,r){return t===1?e:r}function at({errors:t,p:e}={},r){return t==null||t.push(`${e!=null?e:"."}: ${r}`),!1}function Bde(t){return Ct({test:(e,r)=>e!==t?at(r,`Expected a literal (got ${Mr(t)})`):!0})}function Yi(t){let e=Array.isArray(t)?t:Object.values(t),r=new Set(e);return Ct({test:(i,n)=>r.has(i)?!0:at(n,`Expected a valid enumeration value (got ${Mr(i)})`)})}var hU,pU,dU,CU,mU,uv,EU,yU,gv,Qde,bde,vde,Sde,xde,kde,Pde,Dde,Rde,Fde,fv,Nde,Lde,Tde,Mde,wU,Ode,Kde,Ude,Hde,Gde,jde,Yde,qde,hv,Jde,Wde,zde,Vde,_de,Xde,Zde,$de,eCe,tCe,Bl,rCe,pv,Ss=Yfe(()=>{hU=/^[a-zA-Z_][a-zA-Z0-9_]*$/,pU=/^#[0-9a-f]{6}$/i,dU=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,CU=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,mU=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,uv=/^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/,EU=t=>()=>t;yU=()=>Ct({test:(t,e)=>!0});gv=()=>Ct({test:(t,e)=>typeof t!="string"?at(e,`Expected a string (got ${Mr(t)})`):!0});Qde=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]),bde=()=>Ct({test:(t,e)=>{var r;if(typeof t!="boolean"){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return at(e,"Unbound coercion result");let i=Qde.get(t);if(typeof i!="undefined")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,i)]),!0}return at(e,`Expected a boolean (got ${Mr(t)})`)}return!0}}),vde=()=>Ct({test:(t,e)=>{var r;if(typeof t!="number"){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return at(e,"Unbound coercion result");let i;if(typeof t=="string"){let n;try{n=JSON.parse(t)}catch(s){}if(typeof n=="number")if(JSON.stringify(n)===t)i=n;else return at(e,`Received a number that can't be safely represented by the runtime (${t})`)}if(typeof i!="undefined")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,i)]),!0}return at(e,`Expected a number (got ${Mr(t)})`)}return!0}}),Sde=()=>Ct({test:(t,e)=>{var r;if(!(t instanceof Date)){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return at(e,"Unbound coercion result");let i;if(typeof t=="string"&&uv.test(t))i=new Date(t);else{let n;if(typeof t=="string"){let s;try{s=JSON.parse(t)}catch(o){}typeof s=="number"&&(n=s)}else typeof t=="number"&&(n=t);if(typeof n!="undefined")if(Number.isSafeInteger(n)||!Number.isSafeInteger(n*1e3))i=new Date(n*1e3);else return at(e,`Received a timestamp that can't be safely represented by the runtime (${t})`)}if(typeof i!="undefined")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,i)]),!0}return at(e,`Expected a date (got ${Mr(t)})`)}return!0}}),xde=(t,{delimiter:e}={})=>Ct({test:(r,i)=>{var n;if(typeof r=="string"&&typeof e!="undefined"&&typeof(i==null?void 0:i.coercions)!="undefined"){if(typeof(i==null?void 0:i.coercion)=="undefined")return at(i,"Unbound coercion result");r=r.split(e),i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,r)])}if(!Array.isArray(r))return at(i,`Expected an array (got ${Mr(r)})`);let s=!0;for(let o=0,a=r.length;o{let r=wU(t.length);return Ct({test:(i,n)=>{var s;if(typeof i=="string"&&typeof e!="undefined"&&typeof(n==null?void 0:n.coercions)!="undefined"){if(typeof(n==null?void 0:n.coercion)=="undefined")return at(n,"Unbound coercion result");i=i.split(e),n.coercions.push([(s=n.p)!==null&&s!==void 0?s:".",n.coercion.bind(null,i)])}if(!Array.isArray(i))return at(n,`Expected a tuple (got ${Mr(i)})`);let o=r(i,Object.assign({},n));for(let a=0,l=i.length;aCt({test:(r,i)=>{if(typeof r!="object"||r===null)return at(i,`Expected an object (got ${Mr(r)})`);let n=Object.keys(r),s=!0;for(let o=0,a=n.length;o{let r=Object.keys(t);return Ct({test:(i,n)=>{if(typeof i!="object"||i===null)return at(n,`Expected an object (got ${Mr(i)})`);let s=new Set([...r,...Object.keys(i)]),o={},a=!0;for(let l of s){if(l==="constructor"||l==="__proto__")a=at(Object.assign(Object.assign({},n),{p:rA(n,l)}),"Unsafe property name");else{let c=Object.prototype.hasOwnProperty.call(t,l)?t[l]:void 0,u=Object.prototype.hasOwnProperty.call(i,l)?i[l]:void 0;typeof c!="undefined"?a=c(u,Object.assign(Object.assign({},n),{p:rA(n,l),coercion:wl(i,l)}))&&a:e===null?a=at(Object.assign(Object.assign({},n),{p:rA(n,l)}),`Extraneous property (got ${Mr(u)})`):Object.defineProperty(o,l,{enumerable:!0,get:()=>u,set:IU(i,l)})}if(!a&&(n==null?void 0:n.errors)==null)break}return e!==null&&(a||(n==null?void 0:n.errors)!=null)&&(a=e(o,n)&&a),a}})},Rde=t=>Ct({test:(e,r)=>e instanceof t?!0:at(r,`Expected an instance of ${t.name} (got ${Mr(e)})`)}),Fde=(t,{exclusive:e=!1}={})=>Ct({test:(r,i)=>{var n,s,o;let a=[],l=typeof(i==null?void 0:i.errors)!="undefined"?[]:void 0;for(let c=0,u=t.length;c1?at(i,`Expected to match exactly a single predicate (matched ${a.join(", ")})`):(o=i==null?void 0:i.errors)===null||o===void 0||o.push(...l),!1}}),fv=(t,e)=>Ct({test:(r,i)=>{var n,s;let o={value:r},a=typeof(i==null?void 0:i.coercions)!="undefined"?wl(o,"value"):void 0,l=typeof(i==null?void 0:i.coercions)!="undefined"?[]:void 0;if(!t(r,Object.assign(Object.assign({},i),{coercion:a,coercions:l})))return!1;let c=[];if(typeof l!="undefined")for(let[,u]of l)c.push(u());try{if(typeof(i==null?void 0:i.coercions)!="undefined"){if(o.value!==r){if(typeof(i==null?void 0:i.coercion)=="undefined")return at(i,"Unbound coercion result");i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,o.value)])}(s=i==null?void 0:i.coercions)===null||s===void 0||s.push(...l)}return e.every(u=>u(o.value,i))}finally{for(let u of c)u()}}}),Nde=t=>Ct({test:(e,r)=>typeof e=="undefined"?!0:t(e,r)}),Lde=t=>Ct({test:(e,r)=>e===null?!0:t(e,r)}),Tde=t=>Ct({test:(e,r)=>e.length>=t?!0:at(r,`Expected to have a length of at least ${t} elements (got ${e.length})`)}),Mde=t=>Ct({test:(e,r)=>e.length<=t?!0:at(r,`Expected to have a length of at most ${t} elements (got ${e.length})`)}),wU=t=>Ct({test:(e,r)=>e.length!==t?at(r,`Expected to have a length of exactly ${t} elements (got ${e.length})`):!0}),Ode=({map:t}={})=>Ct({test:(e,r)=>{let i=new Set,n=new Set;for(let s=0,o=e.length;sCt({test:(t,e)=>t<=0?!0:at(e,`Expected to be negative (got ${t})`)}),Ude=()=>Ct({test:(t,e)=>t>=0?!0:at(e,`Expected to be positive (got ${t})`)}),Hde=t=>Ct({test:(e,r)=>e>=t?!0:at(r,`Expected to be at least ${t} (got ${e})`)}),Gde=t=>Ct({test:(e,r)=>e<=t?!0:at(r,`Expected to be at most ${t} (got ${e})`)}),jde=(t,e)=>Ct({test:(r,i)=>r>=t&&r<=e?!0:at(i,`Expected to be in the [${t}; ${e}] range (got ${r})`)}),Yde=(t,e)=>Ct({test:(r,i)=>r>=t&&rCt({test:(e,r)=>e!==Math.round(e)?at(r,`Expected to be an integer (got ${e})`):Number.isSafeInteger(e)?!0:at(r,`Expected to be a safe integer (got ${e})`)}),hv=t=>Ct({test:(e,r)=>t.test(e)?!0:at(r,`Expected to match the pattern ${t.toString()} (got ${Mr(e)})`)}),Jde=()=>Ct({test:(t,e)=>t!==t.toLowerCase()?at(e,`Expected to be all-lowercase (got ${t})`):!0}),Wde=()=>Ct({test:(t,e)=>t!==t.toUpperCase()?at(e,`Expected to be all-uppercase (got ${t})`):!0}),zde=()=>Ct({test:(t,e)=>mU.test(t)?!0:at(e,`Expected to be a valid UUID v4 (got ${Mr(t)})`)}),Vde=()=>Ct({test:(t,e)=>uv.test(t)?!1:at(e,`Expected to be a valid ISO 8601 date string (got ${Mr(t)})`)}),_de=({alpha:t=!1})=>Ct({test:(e,r)=>(t?pU.test(e):dU.test(e))?!0:at(r,`Expected to be a valid hexadecimal color string (got ${Mr(e)})`)}),Xde=()=>Ct({test:(t,e)=>CU.test(t)?!0:at(e,`Expected to be a valid base 64 string (got ${Mr(t)})`)}),Zde=(t=yU())=>Ct({test:(e,r)=>{let i;try{i=JSON.parse(e)}catch(n){return at(r,`Expected to be a valid JSON string (got ${Mr(e)})`)}return t(i,r)}}),$de=t=>{let e=new Set(t);return Ct({test:(r,i)=>{let n=new Set(Object.keys(r)),s=[];for(let o of e)n.has(o)||s.push(o);return s.length>0?at(i,`Missing required ${GE(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},eCe=t=>{let e=new Set(t);return Ct({test:(r,i)=>{let n=new Set(Object.keys(r)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>0?at(i,`Forbidden ${GE(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},tCe=t=>{let e=new Set(t);return Ct({test:(r,i)=>{let n=new Set(Object.keys(r)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>1?at(i,`Mutually exclusive properties ${s.map(o=>`"${o}"`).join(", ")}`):!0}})};(function(t){t.Forbids="Forbids",t.Requires="Requires"})(Bl||(Bl={}));rCe={[Bl.Forbids]:{expect:!1,message:"forbids using"},[Bl.Requires]:{expect:!0,message:"requires using"}},pv=(t,e,r,{ignore:i=[]}={})=>{let n=new Set(i),s=new Set(r),o=rCe[e];return Ct({test:(a,l)=>{let c=new Set(Object.keys(a));if(!c.has(t)||n.has(a[t]))return!0;let u=[];for(let g of s)(c.has(g)&&!n.has(a[g]))!==o.expect&&u.push(g);return u.length>=1?at(l,`Property "${t}" ${o.message} ${GE(u.length,"property","properties")} ${u.map(g=>`"${g}"`).join(", ")}`):!0}})}});var Sh=E(($et,OU)=>{var mCe="2.0.0",ECe=256,ICe=Number.MAX_SAFE_INTEGER||9007199254740991,yCe=16;OU.exports={SEMVER_SPEC_VERSION:mCe,MAX_LENGTH:ECe,MAX_SAFE_INTEGER:ICe,MAX_SAFE_COMPONENT_LENGTH:yCe}});var xh=E((ett,KU)=>{var wCe=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...t)=>console.error("SEMVER",...t):()=>{};KU.exports=wCe});var Ql=E((iA,UU)=>{var{MAX_SAFE_COMPONENT_LENGTH:yv}=Sh(),BCe=xh();iA=UU.exports={};var QCe=iA.re=[],Je=iA.src=[],We=iA.t={},bCe=0,mt=(t,e,r)=>{let i=bCe++;BCe(i,e),We[t]=i,Je[i]=e,QCe[i]=new RegExp(e,r?"g":void 0)};mt("NUMERICIDENTIFIER","0|[1-9]\\d*");mt("NUMERICIDENTIFIERLOOSE","[0-9]+");mt("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*");mt("MAINVERSION",`(${Je[We.NUMERICIDENTIFIER]})\\.(${Je[We.NUMERICIDENTIFIER]})\\.(${Je[We.NUMERICIDENTIFIER]})`);mt("MAINVERSIONLOOSE",`(${Je[We.NUMERICIDENTIFIERLOOSE]})\\.(${Je[We.NUMERICIDENTIFIERLOOSE]})\\.(${Je[We.NUMERICIDENTIFIERLOOSE]})`);mt("PRERELEASEIDENTIFIER",`(?:${Je[We.NUMERICIDENTIFIER]}|${Je[We.NONNUMERICIDENTIFIER]})`);mt("PRERELEASEIDENTIFIERLOOSE",`(?:${Je[We.NUMERICIDENTIFIERLOOSE]}|${Je[We.NONNUMERICIDENTIFIER]})`);mt("PRERELEASE",`(?:-(${Je[We.PRERELEASEIDENTIFIER]}(?:\\.${Je[We.PRERELEASEIDENTIFIER]})*))`);mt("PRERELEASELOOSE",`(?:-?(${Je[We.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${Je[We.PRERELEASEIDENTIFIERLOOSE]})*))`);mt("BUILDIDENTIFIER","[0-9A-Za-z-]+");mt("BUILD",`(?:\\+(${Je[We.BUILDIDENTIFIER]}(?:\\.${Je[We.BUILDIDENTIFIER]})*))`);mt("FULLPLAIN",`v?${Je[We.MAINVERSION]}${Je[We.PRERELEASE]}?${Je[We.BUILD]}?`);mt("FULL",`^${Je[We.FULLPLAIN]}$`);mt("LOOSEPLAIN",`[v=\\s]*${Je[We.MAINVERSIONLOOSE]}${Je[We.PRERELEASELOOSE]}?${Je[We.BUILD]}?`);mt("LOOSE",`^${Je[We.LOOSEPLAIN]}$`);mt("GTLT","((?:<|>)?=?)");mt("XRANGEIDENTIFIERLOOSE",`${Je[We.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);mt("XRANGEIDENTIFIER",`${Je[We.NUMERICIDENTIFIER]}|x|X|\\*`);mt("XRANGEPLAIN",`[v=\\s]*(${Je[We.XRANGEIDENTIFIER]})(?:\\.(${Je[We.XRANGEIDENTIFIER]})(?:\\.(${Je[We.XRANGEIDENTIFIER]})(?:${Je[We.PRERELEASE]})?${Je[We.BUILD]}?)?)?`);mt("XRANGEPLAINLOOSE",`[v=\\s]*(${Je[We.XRANGEIDENTIFIERLOOSE]})(?:\\.(${Je[We.XRANGEIDENTIFIERLOOSE]})(?:\\.(${Je[We.XRANGEIDENTIFIERLOOSE]})(?:${Je[We.PRERELEASELOOSE]})?${Je[We.BUILD]}?)?)?`);mt("XRANGE",`^${Je[We.GTLT]}\\s*${Je[We.XRANGEPLAIN]}$`);mt("XRANGELOOSE",`^${Je[We.GTLT]}\\s*${Je[We.XRANGEPLAINLOOSE]}$`);mt("COERCE",`(^|[^\\d])(\\d{1,${yv}})(?:\\.(\\d{1,${yv}}))?(?:\\.(\\d{1,${yv}}))?(?:$|[^\\d])`);mt("COERCERTL",Je[We.COERCE],!0);mt("LONETILDE","(?:~>?)");mt("TILDETRIM",`(\\s*)${Je[We.LONETILDE]}\\s+`,!0);iA.tildeTrimReplace="$1~";mt("TILDE",`^${Je[We.LONETILDE]}${Je[We.XRANGEPLAIN]}$`);mt("TILDELOOSE",`^${Je[We.LONETILDE]}${Je[We.XRANGEPLAINLOOSE]}$`);mt("LONECARET","(?:\\^)");mt("CARETTRIM",`(\\s*)${Je[We.LONECARET]}\\s+`,!0);iA.caretTrimReplace="$1^";mt("CARET",`^${Je[We.LONECARET]}${Je[We.XRANGEPLAIN]}$`);mt("CARETLOOSE",`^${Je[We.LONECARET]}${Je[We.XRANGEPLAINLOOSE]}$`);mt("COMPARATORLOOSE",`^${Je[We.GTLT]}\\s*(${Je[We.LOOSEPLAIN]})$|^$`);mt("COMPARATOR",`^${Je[We.GTLT]}\\s*(${Je[We.FULLPLAIN]})$|^$`);mt("COMPARATORTRIM",`(\\s*)${Je[We.GTLT]}\\s*(${Je[We.LOOSEPLAIN]}|${Je[We.XRANGEPLAIN]})`,!0);iA.comparatorTrimReplace="$1$2$3";mt("HYPHENRANGE",`^\\s*(${Je[We.XRANGEPLAIN]})\\s+-\\s+(${Je[We.XRANGEPLAIN]})\\s*$`);mt("HYPHENRANGELOOSE",`^\\s*(${Je[We.XRANGEPLAINLOOSE]})\\s+-\\s+(${Je[We.XRANGEPLAINLOOSE]})\\s*$`);mt("STAR","(<|>)?=?\\s*\\*");mt("GTE0","^\\s*>=\\s*0.0.0\\s*$");mt("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")});var kh=E((ttt,HU)=>{var vCe=["includePrerelease","loose","rtl"],SCe=t=>t?typeof t!="object"?{loose:!0}:vCe.filter(e=>t[e]).reduce((e,r)=>(e[r]=!0,e),{}):{};HU.exports=SCe});var zE=E((rtt,GU)=>{var jU=/^[0-9]+$/,YU=(t,e)=>{let r=jU.test(t),i=jU.test(e);return r&&i&&(t=+t,e=+e),t===e?0:r&&!i?-1:i&&!r?1:tYU(e,t);GU.exports={compareIdentifiers:YU,rcompareIdentifiers:xCe}});var bi=E((itt,qU)=>{var VE=xh(),{MAX_LENGTH:JU,MAX_SAFE_INTEGER:_E}=Sh(),{re:WU,t:zU}=Ql(),kCe=kh(),{compareIdentifiers:Ph}=zE(),_n=class{constructor(e,r){if(r=kCe(r),e instanceof _n){if(e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid Version: ${e}`);if(e.length>JU)throw new TypeError(`version is longer than ${JU} characters`);VE("SemVer",e,r),this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease;let i=e.trim().match(r.loose?WU[zU.LOOSE]:WU[zU.FULL]);if(!i)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>_E||this.major<0)throw new TypeError("Invalid major version");if(this.minor>_E||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>_E||this.patch<0)throw new TypeError("Invalid patch version");i[4]?this.prerelease=i[4].split(".").map(n=>{if(/^[0-9]+$/.test(n)){let s=+n;if(s>=0&&s<_E)return s}return n}):this.prerelease=[],this.build=i[5]?i[5].split("."):[],this.format()}format(){return this.version=`${this.major}.${this.minor}.${this.patch}`,this.prerelease.length&&(this.version+=`-${this.prerelease.join(".")}`),this.version}toString(){return this.version}compare(e){if(VE("SemVer.compare",this.version,this.options,e),!(e instanceof _n)){if(typeof e=="string"&&e===this.version)return 0;e=new _n(e,this.options)}return e.version===this.version?0:this.compareMain(e)||this.comparePre(e)}compareMain(e){return e instanceof _n||(e=new _n(e,this.options)),Ph(this.major,e.major)||Ph(this.minor,e.minor)||Ph(this.patch,e.patch)}comparePre(e){if(e instanceof _n||(e=new _n(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;let r=0;do{let i=this.prerelease[r],n=e.prerelease[r];if(VE("prerelease compare",r,i,n),i===void 0&&n===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;if(i===n)continue;return Ph(i,n)}while(++r)}compareBuild(e){e instanceof _n||(e=new _n(e,this.options));let r=0;do{let i=this.build[r],n=e.build[r];if(VE("prerelease compare",r,i,n),i===void 0&&n===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;if(i===n)continue;return Ph(i,n)}while(++r)}inc(e,r){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",r);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",r);break;case"prepatch":this.prerelease.length=0,this.inc("patch",r),this.inc("pre",r);break;case"prerelease":this.prerelease.length===0&&this.inc("patch",r),this.inc("pre",r);break;case"major":(this.minor!==0||this.patch!==0||this.prerelease.length===0)&&this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":(this.patch!==0||this.prerelease.length===0)&&this.minor++,this.patch=0,this.prerelease=[];break;case"patch":this.prerelease.length===0&&this.patch++,this.prerelease=[];break;case"pre":if(this.prerelease.length===0)this.prerelease=[0];else{let i=this.prerelease.length;for(;--i>=0;)typeof this.prerelease[i]=="number"&&(this.prerelease[i]++,i=-2);i===-1&&this.prerelease.push(0)}r&&(this.prerelease[0]===r?isNaN(this.prerelease[1])&&(this.prerelease=[r,0]):this.prerelease=[r,0]);break;default:throw new Error(`invalid increment argument: ${e}`)}return this.format(),this.raw=this.version,this}};qU.exports=_n});var bl=E((ntt,VU)=>{var{MAX_LENGTH:PCe}=Sh(),{re:_U,t:XU}=Ql(),ZU=bi(),DCe=kh(),RCe=(t,e)=>{if(e=DCe(e),t instanceof ZU)return t;if(typeof t!="string"||t.length>PCe||!(e.loose?_U[XU.LOOSE]:_U[XU.FULL]).test(t))return null;try{return new ZU(t,e)}catch(i){return null}};VU.exports=RCe});var e2=E((stt,$U)=>{var FCe=bl(),NCe=(t,e)=>{let r=FCe(t,e);return r?r.version:null};$U.exports=NCe});var r2=E((ott,t2)=>{var LCe=bl(),TCe=(t,e)=>{let r=LCe(t.trim().replace(/^[=v]+/,""),e);return r?r.version:null};t2.exports=TCe});var n2=E((att,i2)=>{var MCe=bi(),OCe=(t,e,r,i)=>{typeof r=="string"&&(i=r,r=void 0);try{return new MCe(t,r).inc(e,i).version}catch(n){return null}};i2.exports=OCe});var Xn=E((Att,s2)=>{var o2=bi(),KCe=(t,e,r)=>new o2(t,r).compare(new o2(e,r));s2.exports=KCe});var XE=E((ltt,a2)=>{var UCe=Xn(),HCe=(t,e,r)=>UCe(t,e,r)===0;a2.exports=HCe});var c2=E((ctt,A2)=>{var l2=bl(),GCe=XE(),jCe=(t,e)=>{if(GCe(t,e))return null;{let r=l2(t),i=l2(e),n=r.prerelease.length||i.prerelease.length,s=n?"pre":"",o=n?"prerelease":"";for(let a in r)if((a==="major"||a==="minor"||a==="patch")&&r[a]!==i[a])return s+a;return o}};A2.exports=jCe});var g2=E((utt,u2)=>{var YCe=bi(),qCe=(t,e)=>new YCe(t,e).major;u2.exports=qCe});var h2=E((gtt,f2)=>{var JCe=bi(),WCe=(t,e)=>new JCe(t,e).minor;f2.exports=WCe});var d2=E((ftt,p2)=>{var zCe=bi(),VCe=(t,e)=>new zCe(t,e).patch;p2.exports=VCe});var m2=E((htt,C2)=>{var _Ce=bl(),XCe=(t,e)=>{let r=_Ce(t,e);return r&&r.prerelease.length?r.prerelease:null};C2.exports=XCe});var I2=E((ptt,E2)=>{var ZCe=Xn(),$Ce=(t,e,r)=>ZCe(e,t,r);E2.exports=$Ce});var w2=E((dtt,y2)=>{var eme=Xn(),tme=(t,e)=>eme(t,e,!0);y2.exports=tme});var ZE=E((Ctt,B2)=>{var Q2=bi(),rme=(t,e,r)=>{let i=new Q2(t,r),n=new Q2(e,r);return i.compare(n)||i.compareBuild(n)};B2.exports=rme});var v2=E((mtt,b2)=>{var ime=ZE(),nme=(t,e)=>t.sort((r,i)=>ime(r,i,e));b2.exports=nme});var x2=E((Ett,S2)=>{var sme=ZE(),ome=(t,e)=>t.sort((r,i)=>sme(i,r,e));S2.exports=ome});var Dh=E((Itt,k2)=>{var ame=Xn(),Ame=(t,e,r)=>ame(t,e,r)>0;k2.exports=Ame});var $E=E((ytt,P2)=>{var lme=Xn(),cme=(t,e,r)=>lme(t,e,r)<0;P2.exports=cme});var wv=E((wtt,D2)=>{var ume=Xn(),gme=(t,e,r)=>ume(t,e,r)!==0;D2.exports=gme});var eI=E((Btt,R2)=>{var fme=Xn(),hme=(t,e,r)=>fme(t,e,r)>=0;R2.exports=hme});var tI=E((Qtt,F2)=>{var pme=Xn(),dme=(t,e,r)=>pme(t,e,r)<=0;F2.exports=dme});var Bv=E((btt,N2)=>{var Cme=XE(),mme=wv(),Eme=Dh(),Ime=eI(),yme=$E(),wme=tI(),Bme=(t,e,r,i)=>{switch(e){case"===":return typeof t=="object"&&(t=t.version),typeof r=="object"&&(r=r.version),t===r;case"!==":return typeof t=="object"&&(t=t.version),typeof r=="object"&&(r=r.version),t!==r;case"":case"=":case"==":return Cme(t,r,i);case"!=":return mme(t,r,i);case">":return Eme(t,r,i);case">=":return Ime(t,r,i);case"<":return yme(t,r,i);case"<=":return wme(t,r,i);default:throw new TypeError(`Invalid operator: ${e}`)}};N2.exports=Bme});var T2=E((vtt,L2)=>{var Qme=bi(),bme=bl(),{re:rI,t:iI}=Ql(),vme=(t,e)=>{if(t instanceof Qme)return t;if(typeof t=="number"&&(t=String(t)),typeof t!="string")return null;e=e||{};let r=null;if(!e.rtl)r=t.match(rI[iI.COERCE]);else{let i;for(;(i=rI[iI.COERCERTL].exec(t))&&(!r||r.index+r[0].length!==t.length);)(!r||i.index+i[0].length!==r.index+r[0].length)&&(r=i),rI[iI.COERCERTL].lastIndex=i.index+i[1].length+i[2].length;rI[iI.COERCERTL].lastIndex=-1}return r===null?null:bme(`${r[2]}.${r[3]||"0"}.${r[4]||"0"}`,e)};L2.exports=vme});var O2=E((Stt,M2)=>{"use strict";M2.exports=function(t){t.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var Rh=E((xtt,K2)=>{"use strict";K2.exports=Pt;Pt.Node=vl;Pt.create=Pt;function Pt(t){var e=this;if(e instanceof Pt||(e=new Pt),e.tail=null,e.head=null,e.length=0,t&&typeof t.forEach=="function")t.forEach(function(n){e.push(n)});else if(arguments.length>0)for(var r=0,i=arguments.length;r1)r=e;else if(this.head)i=this.head.next,r=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;i!==null;n++)r=t(r,i.value,n),i=i.next;return r};Pt.prototype.reduceReverse=function(t,e){var r,i=this.tail;if(arguments.length>1)r=e;else if(this.tail)i=this.tail.prev,r=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=this.length-1;i!==null;n--)r=t(r,i.value,n),i=i.prev;return r};Pt.prototype.toArray=function(){for(var t=new Array(this.length),e=0,r=this.head;r!==null;e++)t[e]=r.value,r=r.next;return t};Pt.prototype.toArrayReverse=function(){for(var t=new Array(this.length),e=0,r=this.tail;r!==null;e++)t[e]=r.value,r=r.prev;return t};Pt.prototype.slice=function(t,e){e=e||this.length,e<0&&(e+=this.length),t=t||0,t<0&&(t+=this.length);var r=new Pt;if(ethis.length&&(e=this.length);for(var i=0,n=this.head;n!==null&&ithis.length&&(e=this.length);for(var i=this.length,n=this.tail;n!==null&&i>e;i--)n=n.prev;for(;n!==null&&i>t;i--,n=n.prev)r.push(n.value);return r};Pt.prototype.splice=function(t,e,...r){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);for(var i=0,n=this.head;n!==null&&i{"use strict";var Pme=Rh(),Sl=Symbol("max"),ra=Symbol("length"),uu=Symbol("lengthCalculator"),Fh=Symbol("allowStale"),xl=Symbol("maxAge"),ia=Symbol("dispose"),H2=Symbol("noDisposeOnSet"),si=Symbol("lruList"),ks=Symbol("cache"),G2=Symbol("updateAgeOnGet"),Qv=()=>1,j2=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let r=this[Sl]=e.max||Infinity,i=e.length||Qv;if(this[uu]=typeof i!="function"?Qv:i,this[Fh]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[xl]=e.maxAge||0,this[ia]=e.dispose,this[H2]=e.noDisposeOnSet||!1,this[G2]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[Sl]=e||Infinity,Nh(this)}get max(){return this[Sl]}set allowStale(e){this[Fh]=!!e}get allowStale(){return this[Fh]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[xl]=e,Nh(this)}get maxAge(){return this[xl]}set lengthCalculator(e){typeof e!="function"&&(e=Qv),e!==this[uu]&&(this[uu]=e,this[ra]=0,this[si].forEach(r=>{r.length=this[uu](r.value,r.key),this[ra]+=r.length})),Nh(this)}get lengthCalculator(){return this[uu]}get length(){return this[ra]}get itemCount(){return this[si].length}rforEach(e,r){r=r||this;for(let i=this[si].tail;i!==null;){let n=i.prev;q2(this,e,i,r),i=n}}forEach(e,r){r=r||this;for(let i=this[si].head;i!==null;){let n=i.next;q2(this,e,i,r),i=n}}keys(){return this[si].toArray().map(e=>e.key)}values(){return this[si].toArray().map(e=>e.value)}reset(){this[ia]&&this[si]&&this[si].length&&this[si].forEach(e=>this[ia](e.key,e.value)),this[ks]=new Map,this[si]=new Pme,this[ra]=0}dump(){return this[si].map(e=>nI(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[si]}set(e,r,i){if(i=i||this[xl],i&&typeof i!="number")throw new TypeError("maxAge must be a number");let n=i?Date.now():0,s=this[uu](r,e);if(this[ks].has(e)){if(s>this[Sl])return gu(this,this[ks].get(e)),!1;let l=this[ks].get(e).value;return this[ia]&&(this[H2]||this[ia](e,l.value)),l.now=n,l.maxAge=i,l.value=r,this[ra]+=s-l.length,l.length=s,this.get(e),Nh(this),!0}let o=new Y2(e,r,s,n,i);return o.length>this[Sl]?(this[ia]&&this[ia](e,r),!1):(this[ra]+=o.length,this[si].unshift(o),this[ks].set(e,this[si].head),Nh(this),!0)}has(e){if(!this[ks].has(e))return!1;let r=this[ks].get(e).value;return!nI(this,r)}get(e){return bv(this,e,!0)}peek(e){return bv(this,e,!1)}pop(){let e=this[si].tail;return e?(gu(this,e),e.value):null}del(e){gu(this,this[ks].get(e))}load(e){this.reset();let r=Date.now();for(let i=e.length-1;i>=0;i--){let n=e[i],s=n.e||0;if(s===0)this.set(n.k,n.v);else{let o=s-r;o>0&&this.set(n.k,n.v,o)}}}prune(){this[ks].forEach((e,r)=>bv(this,r,!1))}},bv=(t,e,r)=>{let i=t[ks].get(e);if(i){let n=i.value;if(nI(t,n)){if(gu(t,i),!t[Fh])return}else r&&(t[G2]&&(i.value.now=Date.now()),t[si].unshiftNode(i));return n.value}},nI=(t,e)=>{if(!e||!e.maxAge&&!t[xl])return!1;let r=Date.now()-e.now;return e.maxAge?r>e.maxAge:t[xl]&&r>t[xl]},Nh=t=>{if(t[ra]>t[Sl])for(let e=t[si].tail;t[ra]>t[Sl]&&e!==null;){let r=e.prev;gu(t,e),e=r}},gu=(t,e)=>{if(e){let r=e.value;t[ia]&&t[ia](r.key,r.value),t[ra]-=r.length,t[ks].delete(r.key),t[si].removeNode(e)}},Y2=class{constructor(e,r,i,n,s){this.key=e,this.value=r,this.length=i,this.now=n,this.maxAge=s||0}},q2=(t,e,r,i)=>{let n=r.value;nI(t,n)&&(gu(t,r),t[Fh]||(n=void 0)),n&&e.call(i,n.value,n.key,t)};U2.exports=j2});var Zn=E((Ptt,W2)=>{var fu=class{constructor(e,r){if(r=Dme(r),e instanceof fu)return e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease?e:new fu(e.raw,r);if(e instanceof vv)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(i=>this.parseRange(i.trim())).filter(i=>i.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${e}`);if(this.set.length>1){let i=this.set[0];if(this.set=this.set.filter(n=>!V2(n[0])),this.set.length===0)this.set=[i];else if(this.set.length>1){for(let n of this.set)if(n.length===1&&Tme(n[0])){this.set=[n];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){e=e.trim();let i=`parseRange:${Object.keys(this.options).join(",")}:${e}`,n=z2.get(i);if(n)return n;let s=this.options.loose,o=s?vi[di.HYPHENRANGELOOSE]:vi[di.HYPHENRANGE];e=e.replace(o,Kme(this.options.includePrerelease)),Rr("hyphen replace",e),e=e.replace(vi[di.COMPARATORTRIM],Fme),Rr("comparator trim",e,vi[di.COMPARATORTRIM]),e=e.replace(vi[di.TILDETRIM],Nme),e=e.replace(vi[di.CARETTRIM],Lme),e=e.split(/\s+/).join(" ");let a=s?vi[di.COMPARATORLOOSE]:vi[di.COMPARATOR],l=e.split(" ").map(f=>Mme(f,this.options)).join(" ").split(/\s+/).map(f=>Ome(f,this.options)).filter(this.options.loose?f=>!!f.match(a):()=>!0).map(f=>new vv(f,this.options)),c=l.length,u=new Map;for(let f of l){if(V2(f))return[f];u.set(f.value,f)}u.size>1&&u.has("")&&u.delete("");let g=[...u.values()];return z2.set(i,g),g}intersects(e,r){if(!(e instanceof fu))throw new TypeError("a Range is required");return this.set.some(i=>_2(i,r)&&e.set.some(n=>_2(n,r)&&i.every(s=>n.every(o=>s.intersects(o,r)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new Rme(e,this.options)}catch(r){return!1}for(let r=0;rt.value==="<0.0.0-0",Tme=t=>t.value==="",_2=(t,e)=>{let r=!0,i=t.slice(),n=i.pop();for(;r&&i.length;)r=i.every(s=>n.intersects(s,e)),n=i.pop();return r},Mme=(t,e)=>(Rr("comp",t,e),t=jme(t,e),Rr("caret",t),t=Gme(t,e),Rr("tildes",t),t=Yme(t,e),Rr("xrange",t),t=qme(t,e),Rr("stars",t),t),Ji=t=>!t||t.toLowerCase()==="x"||t==="*",Gme=(t,e)=>t.trim().split(/\s+/).map(r=>Jme(r,e)).join(" "),Jme=(t,e)=>{let r=e.loose?vi[di.TILDELOOSE]:vi[di.TILDE];return t.replace(r,(i,n,s,o,a)=>{Rr("tilde",t,i,n,s,o,a);let l;return Ji(n)?l="":Ji(s)?l=`>=${n}.0.0 <${+n+1}.0.0-0`:Ji(o)?l=`>=${n}.${s}.0 <${n}.${+s+1}.0-0`:a?(Rr("replaceTilde pr",a),l=`>=${n}.${s}.${o}-${a} <${n}.${+s+1}.0-0`):l=`>=${n}.${s}.${o} <${n}.${+s+1}.0-0`,Rr("tilde return",l),l})},jme=(t,e)=>t.trim().split(/\s+/).map(r=>Wme(r,e)).join(" "),Wme=(t,e)=>{Rr("caret",t,e);let r=e.loose?vi[di.CARETLOOSE]:vi[di.CARET],i=e.includePrerelease?"-0":"";return t.replace(r,(n,s,o,a,l)=>{Rr("caret",t,n,s,o,a,l);let c;return Ji(s)?c="":Ji(o)?c=`>=${s}.0.0${i} <${+s+1}.0.0-0`:Ji(a)?s==="0"?c=`>=${s}.${o}.0${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.0${i} <${+s+1}.0.0-0`:l?(Rr("replaceCaret pr",l),s==="0"?o==="0"?c=`>=${s}.${o}.${a}-${l} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}-${l} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a}-${l} <${+s+1}.0.0-0`):(Rr("no pr"),s==="0"?o==="0"?c=`>=${s}.${o}.${a}${i} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a} <${+s+1}.0.0-0`),Rr("caret return",c),c})},Yme=(t,e)=>(Rr("replaceXRanges",t,e),t.split(/\s+/).map(r=>zme(r,e)).join(" ")),zme=(t,e)=>{t=t.trim();let r=e.loose?vi[di.XRANGELOOSE]:vi[di.XRANGE];return t.replace(r,(i,n,s,o,a,l)=>{Rr("xRange",t,i,n,s,o,a,l);let c=Ji(s),u=c||Ji(o),g=u||Ji(a),f=g;return n==="="&&f&&(n=""),l=e.includePrerelease?"-0":"",c?n===">"||n==="<"?i="<0.0.0-0":i="*":n&&f?(u&&(o=0),a=0,n===">"?(n=">=",u?(s=+s+1,o=0,a=0):(o=+o+1,a=0)):n==="<="&&(n="<",u?s=+s+1:o=+o+1),n==="<"&&(l="-0"),i=`${n+s}.${o}.${a}${l}`):u?i=`>=${s}.0.0${l} <${+s+1}.0.0-0`:g&&(i=`>=${s}.${o}.0${l} <${s}.${+o+1}.0-0`),Rr("xRange return",i),i})},qme=(t,e)=>(Rr("replaceStars",t,e),t.trim().replace(vi[di.STAR],"")),Ome=(t,e)=>(Rr("replaceGTE0",t,e),t.trim().replace(vi[e.includePrerelease?di.GTE0PRE:di.GTE0],"")),Kme=t=>(e,r,i,n,s,o,a,l,c,u,g,f,h)=>(Ji(i)?r="":Ji(n)?r=`>=${i}.0.0${t?"-0":""}`:Ji(s)?r=`>=${i}.${n}.0${t?"-0":""}`:o?r=`>=${r}`:r=`>=${r}${t?"-0":""}`,Ji(c)?l="":Ji(u)?l=`<${+c+1}.0.0-0`:Ji(g)?l=`<${c}.${+u+1}.0-0`:f?l=`<=${c}.${u}.${g}-${f}`:t?l=`<${c}.${u}.${+g+1}-0`:l=`<=${l}`,`${r} ${l}`.trim()),Ume=(t,e,r)=>{for(let i=0;i0){let n=t[i].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0}});var Lh=E((Dtt,X2)=>{var Th=Symbol("SemVer ANY"),Mh=class{static get ANY(){return Th}constructor(e,r){if(r=Vme(r),e instanceof Mh){if(e.loose===!!r.loose)return e;e=e.value}xv("comparator",e,r),this.options=r,this.loose=!!r.loose,this.parse(e),this.semver===Th?this.value="":this.value=this.operator+this.semver.version,xv("comp",this)}parse(e){let r=this.options.loose?Z2[$2.COMPARATORLOOSE]:Z2[$2.COMPARATOR],i=e.match(r);if(!i)throw new TypeError(`Invalid comparator: ${e}`);this.operator=i[1]!==void 0?i[1]:"",this.operator==="="&&(this.operator=""),i[2]?this.semver=new eH(i[2],this.options.loose):this.semver=Th}toString(){return this.value}test(e){if(xv("Comparator.test",e,this.options.loose),this.semver===Th||e===Th)return!0;if(typeof e=="string")try{e=new eH(e,this.options)}catch(r){return!1}return Sv(e,this.operator,this.semver,this.options)}intersects(e,r){if(!(e instanceof Mh))throw new TypeError("a Comparator is required");if((!r||typeof r!="object")&&(r={loose:!!r,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new tH(e.value,r).test(this.value);if(e.operator==="")return e.value===""?!0:new tH(this.value,r).test(e.semver);let i=(this.operator===">="||this.operator===">")&&(e.operator===">="||e.operator===">"),n=(this.operator==="<="||this.operator==="<")&&(e.operator==="<="||e.operator==="<"),s=this.semver.version===e.semver.version,o=(this.operator===">="||this.operator==="<=")&&(e.operator===">="||e.operator==="<="),a=Sv(this.semver,"<",e.semver,r)&&(this.operator===">="||this.operator===">")&&(e.operator==="<="||e.operator==="<"),l=Sv(this.semver,">",e.semver,r)&&(this.operator==="<="||this.operator==="<")&&(e.operator===">="||e.operator===">");return i||n||s&&o||a||l}};X2.exports=Mh;var Vme=kh(),{re:Z2,t:$2}=Ql(),Sv=Bv(),xv=xh(),eH=bi(),tH=Zn()});var Oh=E((Rtt,rH)=>{var _me=Zn(),Xme=(t,e,r)=>{try{e=new _me(e,r)}catch(i){return!1}return e.test(t)};rH.exports=Xme});var nH=E((Ftt,iH)=>{var Zme=Zn(),$me=(t,e)=>new Zme(t,e).set.map(r=>r.map(i=>i.value).join(" ").trim().split(" "));iH.exports=$me});var oH=E((Ntt,sH)=>{var eEe=bi(),tEe=Zn(),rEe=(t,e,r)=>{let i=null,n=null,s=null;try{s=new tEe(e,r)}catch(o){return null}return t.forEach(o=>{s.test(o)&&(!i||n.compare(o)===-1)&&(i=o,n=new eEe(i,r))}),i};sH.exports=rEe});var AH=E((Ltt,aH)=>{var iEe=bi(),nEe=Zn(),sEe=(t,e,r)=>{let i=null,n=null,s=null;try{s=new nEe(e,r)}catch(o){return null}return t.forEach(o=>{s.test(o)&&(!i||n.compare(o)===1)&&(i=o,n=new iEe(i,r))}),i};aH.exports=sEe});var uH=E((Ttt,lH)=>{var kv=bi(),oEe=Zn(),cH=Dh(),aEe=(t,e)=>{t=new oEe(t,e);let r=new kv("0.0.0");if(t.test(r)||(r=new kv("0.0.0-0"),t.test(r)))return r;r=null;for(let i=0;i{let a=new kv(o.semver.version);switch(o.operator){case">":a.prerelease.length===0?a.patch++:a.prerelease.push(0),a.raw=a.format();case"":case">=":(!s||cH(a,s))&&(s=a);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${o.operator}`)}}),s&&(!r||cH(r,s))&&(r=s)}return r&&t.test(r)?r:null};lH.exports=aEe});var fH=E((Mtt,gH)=>{var AEe=Zn(),lEe=(t,e)=>{try{return new AEe(t,e).range||"*"}catch(r){return null}};gH.exports=lEe});var sI=E((Ott,hH)=>{var cEe=bi(),pH=Lh(),{ANY:uEe}=pH,gEe=Zn(),fEe=Oh(),dH=Dh(),CH=$E(),hEe=tI(),pEe=eI(),dEe=(t,e,r,i)=>{t=new cEe(t,i),e=new gEe(e,i);let n,s,o,a,l;switch(r){case">":n=dH,s=hEe,o=CH,a=">",l=">=";break;case"<":n=CH,s=pEe,o=dH,a="<",l="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(fEe(t,e,i))return!1;for(let c=0;c{h.semver===uEe&&(h=new pH(">=0.0.0")),g=g||h,f=f||h,n(h.semver,g.semver,i)?g=h:o(h.semver,f.semver,i)&&(f=h)}),g.operator===a||g.operator===l||(!f.operator||f.operator===a)&&s(t,f.semver))return!1;if(f.operator===l&&o(t,f.semver))return!1}return!0};hH.exports=dEe});var EH=E((Ktt,mH)=>{var CEe=sI(),mEe=(t,e,r)=>CEe(t,e,">",r);mH.exports=mEe});var yH=E((Utt,IH)=>{var EEe=sI(),IEe=(t,e,r)=>EEe(t,e,"<",r);IH.exports=IEe});var QH=E((Htt,wH)=>{var BH=Zn(),yEe=(t,e,r)=>(t=new BH(t,r),e=new BH(e,r),t.intersects(e));wH.exports=yEe});var vH=E((Gtt,bH)=>{var wEe=Oh(),BEe=Xn();bH.exports=(t,e,r)=>{let i=[],n=null,s=null,o=t.sort((u,g)=>BEe(u,g,r));for(let u of o)wEe(u,e,r)?(s=u,n||(n=u)):(s&&i.push([n,s]),s=null,n=null);n&&i.push([n,null]);let a=[];for(let[u,g]of i)u===g?a.push(u):!g&&u===o[0]?a.push("*"):g?u===o[0]?a.push(`<=${g}`):a.push(`${u} - ${g}`):a.push(`>=${u}`);let l=a.join(" || "),c=typeof e.raw=="string"?e.raw:String(e);return l.length{var xH=Zn(),oI=Lh(),{ANY:Pv}=oI,Kh=Oh(),Dv=Xn(),bEe=(t,e,r={})=>{if(t===e)return!0;t=new xH(t,r),e=new xH(e,r);let i=!1;e:for(let n of t.set){for(let s of e.set){let o=QEe(n,s,r);if(i=i||o!==null,o)continue e}if(i)return!1}return!0},QEe=(t,e,r)=>{if(t===e)return!0;if(t.length===1&&t[0].semver===Pv){if(e.length===1&&e[0].semver===Pv)return!0;r.includePrerelease?t=[new oI(">=0.0.0-0")]:t=[new oI(">=0.0.0")]}if(e.length===1&&e[0].semver===Pv){if(r.includePrerelease)return!0;e=[new oI(">=0.0.0")]}let i=new Set,n,s;for(let h of t)h.operator===">"||h.operator===">="?n=kH(n,h,r):h.operator==="<"||h.operator==="<="?s=PH(s,h,r):i.add(h.semver);if(i.size>1)return null;let o;if(n&&s){if(o=Dv(n.semver,s.semver,r),o>0)return null;if(o===0&&(n.operator!==">="||s.operator!=="<="))return null}for(let h of i){if(n&&!Kh(h,String(n),r)||s&&!Kh(h,String(s),r))return null;for(let p of e)if(!Kh(h,String(p),r))return!1;return!0}let a,l,c,u,g=s&&!r.includePrerelease&&s.semver.prerelease.length?s.semver:!1,f=n&&!r.includePrerelease&&n.semver.prerelease.length?n.semver:!1;g&&g.prerelease.length===1&&s.operator==="<"&&g.prerelease[0]===0&&(g=!1);for(let h of e){if(u=u||h.operator===">"||h.operator===">=",c=c||h.operator==="<"||h.operator==="<=",n){if(f&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===f.major&&h.semver.minor===f.minor&&h.semver.patch===f.patch&&(f=!1),h.operator===">"||h.operator===">="){if(a=kH(n,h,r),a===h&&a!==n)return!1}else if(n.operator===">="&&!Kh(n.semver,String(h),r))return!1}if(s){if(g&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===g.major&&h.semver.minor===g.minor&&h.semver.patch===g.patch&&(g=!1),h.operator==="<"||h.operator==="<="){if(l=PH(s,h,r),l===h&&l!==s)return!1}else if(s.operator==="<="&&!Kh(s.semver,String(h),r))return!1}if(!h.operator&&(s||n)&&o!==0)return!1}return!(n&&c&&!s&&o!==0||s&&u&&!n&&o!==0||f||g)},kH=(t,e,r)=>{if(!t)return e;let i=Dv(t.semver,e.semver,r);return i>0?t:i<0||e.operator===">"&&t.operator===">="?e:t},PH=(t,e,r)=>{if(!t)return e;let i=Dv(t.semver,e.semver,r);return i<0?t:i>0||e.operator==="<"&&t.operator==="<="?e:t};SH.exports=bEe});var Or=E((Ytt,RH)=>{var Rv=Ql();RH.exports={re:Rv.re,src:Rv.src,tokens:Rv.t,SEMVER_SPEC_VERSION:Sh().SEMVER_SPEC_VERSION,SemVer:bi(),compareIdentifiers:zE().compareIdentifiers,rcompareIdentifiers:zE().rcompareIdentifiers,parse:bl(),valid:e2(),clean:r2(),inc:n2(),diff:c2(),major:g2(),minor:h2(),patch:d2(),prerelease:m2(),compare:Xn(),rcompare:I2(),compareLoose:w2(),compareBuild:ZE(),sort:v2(),rsort:x2(),gt:Dh(),lt:$E(),eq:XE(),neq:wv(),gte:eI(),lte:tI(),cmp:Bv(),coerce:T2(),Comparator:Lh(),Range:Zn(),satisfies:Oh(),toComparators:nH(),maxSatisfying:oH(),minSatisfying:AH(),minVersion:uH(),validRange:fH(),outside:sI(),gtr:EH(),ltr:yH(),intersects:QH(),simplifyRange:vH(),subset:DH()}});var Uv=E(AI=>{"use strict";Object.defineProperty(AI,"__esModule",{value:!0});AI.VERSION=void 0;AI.VERSION="9.1.0"});var Dt=E((exports,module)=>{"use strict";var __spreadArray=exports&&exports.__spreadArray||function(t,e,r){if(r||arguments.length===2)for(var i=0,n=e.length,s;i{(function(t,e){typeof define=="function"&&define.amd?define([],e):typeof lI=="object"&&lI.exports?lI.exports=e():t.regexpToAst=e()})(typeof self!="undefined"?self:YH,function(){function t(){}t.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},t.prototype.restoreState=function(p){this.idx=p.idx,this.input=p.input,this.groupIdx=p.groupIdx},t.prototype.pattern=function(p){this.idx=0,this.input=p,this.groupIdx=0,this.consumeChar("/");var d=this.disjunction();this.consumeChar("/");for(var m={type:"Flags",loc:{begin:this.idx,end:p.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};this.isRegExpFlag();)switch(this.popChar()){case"g":o(m,"global");break;case"i":o(m,"ignoreCase");break;case"m":o(m,"multiLine");break;case"u":o(m,"unicode");break;case"y":o(m,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:m,value:d,loc:this.loc(0)}},t.prototype.disjunction=function(){var p=[],d=this.idx;for(p.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),p.push(this.alternative());return{type:"Disjunction",value:p,loc:this.loc(d)}},t.prototype.alternative=function(){for(var p=[],d=this.idx;this.isTerm();)p.push(this.term());return{type:"Alternative",value:p,loc:this.loc(d)}},t.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},t.prototype.assertion=function(){var p=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(p)};case"$":return{type:"EndAnchor",loc:this.loc(p)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(p)};case"B":return{type:"NonWordBoundary",loc:this.loc(p)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");var d;switch(this.popChar()){case"=":d="Lookahead";break;case"!":d="NegativeLookahead";break}a(d);var m=this.disjunction();return this.consumeChar(")"),{type:d,value:m,loc:this.loc(p)}}l()},t.prototype.quantifier=function(p){var d,m=this.idx;switch(this.popChar()){case"*":d={atLeast:0,atMost:Infinity};break;case"+":d={atLeast:1,atMost:Infinity};break;case"?":d={atLeast:0,atMost:1};break;case"{":var I=this.integerIncludingZero();switch(this.popChar()){case"}":d={atLeast:I,atMost:I};break;case",":var B;this.isDigit()?(B=this.integerIncludingZero(),d={atLeast:I,atMost:B}):d={atLeast:I,atMost:Infinity},this.consumeChar("}");break}if(p===!0&&d===void 0)return;a(d);break}if(!(p===!0&&d===void 0))return a(d),this.peekChar(0)==="?"?(this.consumeChar("?"),d.greedy=!1):d.greedy=!0,d.type="Quantifier",d.loc=this.loc(m),d},t.prototype.atom=function(){var p,d=this.idx;switch(this.peekChar()){case".":p=this.dotAll();break;case"\\":p=this.atomEscape();break;case"[":p=this.characterClass();break;case"(":p=this.group();break}return p===void 0&&this.isPatternCharacter()&&(p=this.patternCharacter()),a(p),p.loc=this.loc(d),this.isQuantifier()&&(p.quantifier=this.quantifier()),p},t.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[n(` +`),n("\r"),n("\u2028"),n("\u2029")]}},t.prototype.atomEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},t.prototype.decimalEscapeAtom=function(){var p=this.positiveInteger();return{type:"GroupBackReference",value:p}},t.prototype.characterClassEscape=function(){var p,d=!1;switch(this.popChar()){case"d":p=u;break;case"D":p=u,d=!0;break;case"s":p=f;break;case"S":p=f,d=!0;break;case"w":p=g;break;case"W":p=g,d=!0;break}return a(p),{type:"Set",value:p,complement:d}},t.prototype.controlEscapeAtom=function(){var p;switch(this.popChar()){case"f":p=n("\f");break;case"n":p=n(` +`);break;case"r":p=n("\r");break;case"t":p=n(" ");break;case"v":p=n("\v");break}return a(p),{type:"Character",value:p}},t.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var p=this.popChar();if(/[a-zA-Z]/.test(p)===!1)throw Error("Invalid ");var d=p.toUpperCase().charCodeAt(0)-64;return{type:"Character",value:d}},t.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:n("\0")}},t.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},t.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},t.prototype.identityEscapeAtom=function(){var p=this.popChar();return{type:"Character",value:n(p)}},t.prototype.classPatternCharacterAtom=function(){switch(this.peekChar()){case` +`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:var p=this.popChar();return{type:"Character",value:n(p)}}},t.prototype.characterClass=function(){var p=[],d=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),d=!0);this.isClassAtom();){var m=this.classAtom(),I=m.type==="Character";if(I&&this.isRangeDash()){this.consumeChar("-");var B=this.classAtom(),b=B.type==="Character";if(b){if(B.value=this.input.length)throw Error("Unexpected end of input");this.idx++},t.prototype.loc=function(p){return{begin:p,end:this.idx}};var e=/[0-9a-fA-F]/,r=/[0-9]/,i=/[1-9]/;function n(p){return p.charCodeAt(0)}function s(p,d){p.length!==void 0?p.forEach(function(m){d.push(m)}):d.push(p)}function o(p,d){if(p[d]===!0)throw"duplicate flag "+d;p[d]=!0}function a(p){if(p===void 0)throw Error("Internal Error - Should never get here!")}function l(){throw Error("Internal Error - Should never get here!")}var c,u=[];for(c=n("0");c<=n("9");c++)u.push(c);var g=[n("_")].concat(u);for(c=n("a");c<=n("z");c++)g.push(c);for(c=n("A");c<=n("Z");c++)g.push(c);var f=[n(" "),n("\f"),n(` +`),n("\r"),n(" "),n("\v"),n(" "),n("\xA0"),n("\u1680"),n("\u2000"),n("\u2001"),n("\u2002"),n("\u2003"),n("\u2004"),n("\u2005"),n("\u2006"),n("\u2007"),n("\u2008"),n("\u2009"),n("\u200A"),n("\u2028"),n("\u2029"),n("\u202F"),n("\u205F"),n("\u3000"),n("\uFEFF")];function h(){}return h.prototype.visitChildren=function(p){for(var d in p){var m=p[d];p.hasOwnProperty(d)&&(m.type!==void 0?this.visit(m):Array.isArray(m)&&m.forEach(function(I){this.visit(I)},this))}},h.prototype.visit=function(p){switch(p.type){case"Pattern":this.visitPattern(p);break;case"Flags":this.visitFlags(p);break;case"Disjunction":this.visitDisjunction(p);break;case"Alternative":this.visitAlternative(p);break;case"StartAnchor":this.visitStartAnchor(p);break;case"EndAnchor":this.visitEndAnchor(p);break;case"WordBoundary":this.visitWordBoundary(p);break;case"NonWordBoundary":this.visitNonWordBoundary(p);break;case"Lookahead":this.visitLookahead(p);break;case"NegativeLookahead":this.visitNegativeLookahead(p);break;case"Character":this.visitCharacter(p);break;case"Set":this.visitSet(p);break;case"Group":this.visitGroup(p);break;case"GroupBackReference":this.visitGroupBackReference(p);break;case"Quantifier":this.visitQuantifier(p);break}this.visitChildren(p)},h.prototype.visitPattern=function(p){},h.prototype.visitFlags=function(p){},h.prototype.visitDisjunction=function(p){},h.prototype.visitAlternative=function(p){},h.prototype.visitStartAnchor=function(p){},h.prototype.visitEndAnchor=function(p){},h.prototype.visitWordBoundary=function(p){},h.prototype.visitNonWordBoundary=function(p){},h.prototype.visitLookahead=function(p){},h.prototype.visitNegativeLookahead=function(p){},h.prototype.visitCharacter=function(p){},h.prototype.visitSet=function(p){},h.prototype.visitGroup=function(p){},h.prototype.visitGroupBackReference=function(p){},h.prototype.visitQuantifier=function(p){},{RegExpParser:t,BaseRegExpVisitor:h,VERSION:"0.5.0"}})});var gI=E(Eu=>{"use strict";Object.defineProperty(Eu,"__esModule",{value:!0});Eu.clearRegExpParserCache=Eu.getRegExpAst=void 0;var FEe=cI(),uI={},NEe=new FEe.RegExpParser;function LEe(t){var e=t.toString();if(uI.hasOwnProperty(e))return uI[e];var r=NEe.pattern(e);return uI[e]=r,r}Eu.getRegExpAst=LEe;function TEe(){uI={}}Eu.clearRegExpParserCache=TEe});var VH=E(fn=>{"use strict";var MEe=fn&&fn.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(fn,"__esModule",{value:!0});fn.canMatchCharCode=fn.firstCharOptimizedIndices=fn.getOptimizedStartCodesIndices=fn.failedOptimizationPrefixMsg=void 0;var qH=cI(),$n=Dt(),JH=gI(),sa=Hv(),WH="Complement Sets are not supported for first char optimization";fn.failedOptimizationPrefixMsg=`Unable to use "first char" lexer optimizations: +`;function OEe(t,e){e===void 0&&(e=!1);try{var r=(0,JH.getRegExpAst)(t),i=fI(r.value,{},r.flags.ignoreCase);return i}catch(s){if(s.message===WH)e&&(0,$n.PRINT_WARNING)(""+fn.failedOptimizationPrefixMsg+(" Unable to optimize: < "+t.toString()+` > +`)+` Complement Sets cannot be automatically optimized. + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{var n="";e&&(n=` + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),(0,$n.PRINT_ERROR)(fn.failedOptimizationPrefixMsg+` +`+(" Failed parsing: < "+t.toString()+` > +`)+(" Using the regexp-to-ast library version: "+qH.VERSION+` +`)+" Please open an issue at: https://github.com/bd82/regexp-to-ast/issues"+n)}}return[]}fn.getOptimizedStartCodesIndices=OEe;function fI(t,e,r){switch(t.type){case"Disjunction":for(var i=0;i=sa.minOptimizationVal)for(var f=u.from>=sa.minOptimizationVal?u.from:sa.minOptimizationVal,h=u.to,p=(0,sa.charCodeToOptimizedIndex)(f),d=(0,sa.charCodeToOptimizedIndex)(h),m=p;m<=d;m++)e[m]=m}}});break;case"Group":fI(o.value,e,r);break;default:throw Error("Non Exhaustive Match")}var a=o.quantifier!==void 0&&o.quantifier.atLeast===0;if(o.type==="Group"&&Gv(o)===!1||o.type!=="Group"&&a===!1)break}break;default:throw Error("non exhaustive match!")}return(0,$n.values)(e)}fn.firstCharOptimizedIndices=fI;function hI(t,e,r){var i=(0,sa.charCodeToOptimizedIndex)(t);e[i]=i,r===!0&&KEe(t,e)}function KEe(t,e){var r=String.fromCharCode(t),i=r.toUpperCase();if(i!==r){var n=(0,sa.charCodeToOptimizedIndex)(i.charCodeAt(0));e[n]=n}else{var s=r.toLowerCase();if(s!==r){var n=(0,sa.charCodeToOptimizedIndex)(s.charCodeAt(0));e[n]=n}}}function zH(t,e){return(0,$n.find)(t.value,function(r){if(typeof r=="number")return(0,$n.contains)(e,r);var i=r;return(0,$n.find)(e,function(n){return i.from<=n&&n<=i.to})!==void 0})}function Gv(t){return t.quantifier&&t.quantifier.atLeast===0?!0:t.value?(0,$n.isArray)(t.value)?(0,$n.every)(t.value,Gv):Gv(t.value):!1}var UEe=function(t){MEe(e,t);function e(r){var i=t.call(this)||this;return i.targetCharCodes=r,i.found=!1,i}return e.prototype.visitChildren=function(r){if(this.found!==!0){switch(r.type){case"Lookahead":this.visitLookahead(r);return;case"NegativeLookahead":this.visitNegativeLookahead(r);return}t.prototype.visitChildren.call(this,r)}},e.prototype.visitCharacter=function(r){(0,$n.contains)(this.targetCharCodes,r.value)&&(this.found=!0)},e.prototype.visitSet=function(r){r.complement?zH(r,this.targetCharCodes)===void 0&&(this.found=!0):zH(r,this.targetCharCodes)!==void 0&&(this.found=!0)},e}(qH.BaseRegExpVisitor);function HEe(t,e){if(e instanceof RegExp){var r=(0,JH.getRegExpAst)(e),i=new UEe(t);return i.visit(r),i.found}else return(0,$n.find)(e,function(n){return(0,$n.contains)(t,n.charCodeAt(0))})!==void 0}fn.canMatchCharCode=HEe});var Hv=E(je=>{"use strict";var _H=je&&je.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(je,"__esModule",{value:!0});je.charCodeToOptimizedIndex=je.minOptimizationVal=je.buildLineBreakIssueMessage=je.LineTerminatorOptimizedTester=je.isShortPattern=je.isCustomPattern=je.cloneEmptyGroups=je.performWarningRuntimeChecks=je.performRuntimeChecks=je.addStickyFlag=je.addStartOfInput=je.findUnreachablePatterns=je.findModesThatDoNotExist=je.findInvalidGroupType=je.findDuplicatePatterns=je.findUnsupportedFlags=je.findStartOfInputAnchor=je.findEmptyMatchRegExps=je.findEndOfInputAnchor=je.findInvalidPatterns=je.findMissingPatterns=je.validatePatterns=je.analyzeTokenTypes=je.enableSticky=je.disableSticky=je.SUPPORT_STICKY=je.MODES=je.DEFAULT_MODE=void 0;var XH=cI(),zt=Gh(),Ie=Dt(),Iu=VH(),ZH=gI(),ao="PATTERN";je.DEFAULT_MODE="defaultMode";je.MODES="modes";je.SUPPORT_STICKY=typeof new RegExp("(?:)").sticky=="boolean";function GEe(){je.SUPPORT_STICKY=!1}je.disableSticky=GEe;function jEe(){je.SUPPORT_STICKY=!0}je.enableSticky=jEe;function qEe(t,e){e=(0,Ie.defaults)(e,{useSticky:je.SUPPORT_STICKY,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` +`],tracer:function(B,b){return b()}});var r=e.tracer;r("initCharCodeToOptimizedIndexMap",function(){YEe()});var i;r("Reject Lexer.NA",function(){i=(0,Ie.reject)(t,function(B){return B[ao]===zt.Lexer.NA})});var n=!1,s;r("Transform Patterns",function(){n=!1,s=(0,Ie.map)(i,function(B){var b=B[ao];if((0,Ie.isRegExp)(b)){var R=b.source;return R.length===1&&R!=="^"&&R!=="$"&&R!=="."&&!b.ignoreCase?R:R.length===2&&R[0]==="\\"&&!(0,Ie.contains)(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],R[1])?R[1]:e.useSticky?Yv(b):jv(b)}else{if((0,Ie.isFunction)(b))return n=!0,{exec:b};if((0,Ie.has)(b,"exec"))return n=!0,b;if(typeof b=="string"){if(b.length===1)return b;var H=b.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),L=new RegExp(H);return e.useSticky?Yv(L):jv(L)}else throw Error("non exhaustive match")}})});var o,a,l,c,u;r("misc mapping",function(){o=(0,Ie.map)(i,function(B){return B.tokenTypeIdx}),a=(0,Ie.map)(i,function(B){var b=B.GROUP;if(b!==zt.Lexer.SKIPPED){if((0,Ie.isString)(b))return b;if((0,Ie.isUndefined)(b))return!1;throw Error("non exhaustive match")}}),l=(0,Ie.map)(i,function(B){var b=B.LONGER_ALT;if(b){var R=(0,Ie.isArray)(b)?(0,Ie.map)(b,function(H){return(0,Ie.indexOf)(i,H)}):[(0,Ie.indexOf)(i,b)];return R}}),c=(0,Ie.map)(i,function(B){return B.PUSH_MODE}),u=(0,Ie.map)(i,function(B){return(0,Ie.has)(B,"POP_MODE")})});var g;r("Line Terminator Handling",function(){var B=tG(e.lineTerminatorCharacters);g=(0,Ie.map)(i,function(b){return!1}),e.positionTracking!=="onlyOffset"&&(g=(0,Ie.map)(i,function(b){if((0,Ie.has)(b,"LINE_BREAKS"))return b.LINE_BREAKS;if(eG(b,B)===!1)return(0,Iu.canMatchCharCode)(B,b.PATTERN)}))});var f,h,p,d;r("Misc Mapping #2",function(){f=(0,Ie.map)(i,qv),h=(0,Ie.map)(s,$H),p=(0,Ie.reduce)(i,function(B,b){var R=b.GROUP;return(0,Ie.isString)(R)&&R!==zt.Lexer.SKIPPED&&(B[R]=[]),B},{}),d=(0,Ie.map)(s,function(B,b){return{pattern:s[b],longerAlt:l[b],canLineTerminator:g[b],isCustom:f[b],short:h[b],group:a[b],push:c[b],pop:u[b],tokenTypeIdx:o[b],tokenType:i[b]}})});var m=!0,I=[];return e.safeMode||r("First Char Optimization",function(){I=(0,Ie.reduce)(i,function(B,b,R){if(typeof b.PATTERN=="string"){var H=b.PATTERN.charCodeAt(0),L=Wv(H);Jv(B,L,d[R])}else if((0,Ie.isArray)(b.START_CHARS_HINT)){var K;(0,Ie.forEach)(b.START_CHARS_HINT,function(ne){var q=typeof ne=="string"?ne.charCodeAt(0):ne,A=Wv(q);K!==A&&(K=A,Jv(B,A,d[R]))})}else if((0,Ie.isRegExp)(b.PATTERN))if(b.PATTERN.unicode)m=!1,e.ensureOptimizations&&(0,Ie.PRINT_ERROR)(""+Iu.failedOptimizationPrefixMsg+(" Unable to analyze < "+b.PATTERN.toString()+` > pattern. +`)+` The regexp unicode flag is not currently supported by the regexp-to-ast library. + This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{var J=(0,Iu.getOptimizedStartCodesIndices)(b.PATTERN,e.ensureOptimizations);(0,Ie.isEmpty)(J)&&(m=!1),(0,Ie.forEach)(J,function(ne){Jv(B,ne,d[R])})}else e.ensureOptimizations&&(0,Ie.PRINT_ERROR)(""+Iu.failedOptimizationPrefixMsg+(" TokenType: <"+b.name+`> is using a custom token pattern without providing parameter. +`)+` This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),m=!1;return B},[])}),r("ArrayPacking",function(){I=(0,Ie.packArray)(I)}),{emptyGroups:p,patternIdxToConfig:d,charCodeToPatternIdxToConfig:I,hasCustom:n,canBeOptimized:m}}je.analyzeTokenTypes=qEe;function WEe(t,e){var r=[],i=rG(t);r=r.concat(i.errors);var n=iG(i.valid),s=n.valid;return r=r.concat(n.errors),r=r.concat(JEe(s)),r=r.concat(nG(s)),r=r.concat(sG(s,e)),r=r.concat(oG(s)),r}je.validatePatterns=WEe;function JEe(t){var e=[],r=(0,Ie.filter)(t,function(i){return(0,Ie.isRegExp)(i[ao])});return e=e.concat(aG(r)),e=e.concat(lG(r)),e=e.concat(cG(r)),e=e.concat(uG(r)),e=e.concat(AG(r)),e}function rG(t){var e=(0,Ie.filter)(t,function(n){return!(0,Ie.has)(n,ao)}),r=(0,Ie.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- missing static 'PATTERN' property",type:zt.LexerDefinitionErrorType.MISSING_PATTERN,tokenTypes:[n]}}),i=(0,Ie.difference)(t,e);return{errors:r,valid:i}}je.findMissingPatterns=rG;function iG(t){var e=(0,Ie.filter)(t,function(n){var s=n[ao];return!(0,Ie.isRegExp)(s)&&!(0,Ie.isFunction)(s)&&!(0,Ie.has)(s,"exec")&&!(0,Ie.isString)(s)}),r=(0,Ie.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:zt.LexerDefinitionErrorType.INVALID_PATTERN,tokenTypes:[n]}}),i=(0,Ie.difference)(t,e);return{errors:r,valid:i}}je.findInvalidPatterns=iG;var zEe=/[^\\][\$]/;function aG(t){var e=function(n){_H(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitEndAnchor=function(o){this.found=!0},s}(XH.BaseRegExpVisitor),r=(0,Ie.filter)(t,function(n){var s=n[ao];try{var o=(0,ZH.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch(l){return zEe.test(s.source)}}),i=(0,Ie.map)(r,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain end of input anchor '$' + See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:zt.LexerDefinitionErrorType.EOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}je.findEndOfInputAnchor=aG;function AG(t){var e=(0,Ie.filter)(t,function(i){var n=i[ao];return n.test("")}),r=(0,Ie.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' must not match an empty string",type:zt.LexerDefinitionErrorType.EMPTY_MATCH_PATTERN,tokenTypes:[i]}});return r}je.findEmptyMatchRegExps=AG;var VEe=/[^\\[][\^]|^\^/;function lG(t){var e=function(n){_H(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitStartAnchor=function(o){this.found=!0},s}(XH.BaseRegExpVisitor),r=(0,Ie.filter)(t,function(n){var s=n[ao];try{var o=(0,ZH.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch(l){return VEe.test(s.source)}}),i=(0,Ie.map)(r,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain start of input anchor '^' + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:zt.LexerDefinitionErrorType.SOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}je.findStartOfInputAnchor=lG;function cG(t){var e=(0,Ie.filter)(t,function(i){var n=i[ao];return n instanceof RegExp&&(n.multiline||n.global)}),r=(0,Ie.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:zt.LexerDefinitionErrorType.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[i]}});return r}je.findUnsupportedFlags=cG;function uG(t){var e=[],r=(0,Ie.map)(t,function(s){return(0,Ie.reduce)(t,function(o,a){return s.PATTERN.source===a.PATTERN.source&&!(0,Ie.contains)(e,a)&&a.PATTERN!==zt.Lexer.NA&&(e.push(a),o.push(a)),o},[])});r=(0,Ie.compact)(r);var i=(0,Ie.filter)(r,function(s){return s.length>1}),n=(0,Ie.map)(i,function(s){var o=(0,Ie.map)(s,function(l){return l.name}),a=(0,Ie.first)(s).PATTERN;return{message:"The same RegExp pattern ->"+a+"<-"+("has been used in all of the following Token Types: "+o.join(", ")+" <-"),type:zt.LexerDefinitionErrorType.DUPLICATE_PATTERNS_FOUND,tokenTypes:s}});return n}je.findDuplicatePatterns=uG;function nG(t){var e=(0,Ie.filter)(t,function(i){if(!(0,Ie.has)(i,"GROUP"))return!1;var n=i.GROUP;return n!==zt.Lexer.SKIPPED&&n!==zt.Lexer.NA&&!(0,Ie.isString)(n)}),r=(0,Ie.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:zt.LexerDefinitionErrorType.INVALID_GROUP_TYPE_FOUND,tokenTypes:[i]}});return r}je.findInvalidGroupType=nG;function sG(t,e){var r=(0,Ie.filter)(t,function(n){return n.PUSH_MODE!==void 0&&!(0,Ie.contains)(e,n.PUSH_MODE)}),i=(0,Ie.map)(r,function(n){var s="Token Type: ->"+n.name+"<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->"+n.PUSH_MODE+"<-which does not exist";return{message:s,type:zt.LexerDefinitionErrorType.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[n]}});return i}je.findModesThatDoNotExist=sG;function oG(t){var e=[],r=(0,Ie.reduce)(t,function(i,n,s){var o=n.PATTERN;return o===zt.Lexer.NA||((0,Ie.isString)(o)?i.push({str:o,idx:s,tokenType:n}):(0,Ie.isRegExp)(o)&&XEe(o)&&i.push({str:o.source,idx:s,tokenType:n})),i},[]);return(0,Ie.forEach)(t,function(i,n){(0,Ie.forEach)(r,function(s){var o=s.str,a=s.idx,l=s.tokenType;if(n"+i.name+"<-")+`in the lexer's definition. +See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:c,type:zt.LexerDefinitionErrorType.UNREACHABLE_PATTERN,tokenTypes:[i,l]})}})}),e}je.findUnreachablePatterns=oG;function _Ee(t,e){if((0,Ie.isRegExp)(e)){var r=e.exec(t);return r!==null&&r.index===0}else{if((0,Ie.isFunction)(e))return e(t,0,[],{});if((0,Ie.has)(e,"exec"))return e.exec(t,0,[],{});if(typeof e=="string")return e===t;throw Error("non exhaustive match")}}function XEe(t){var e=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return(0,Ie.find)(e,function(r){return t.source.indexOf(r)!==-1})===void 0}function jv(t){var e=t.ignoreCase?"i":"";return new RegExp("^(?:"+t.source+")",e)}je.addStartOfInput=jv;function Yv(t){var e=t.ignoreCase?"iy":"y";return new RegExp(""+t.source,e)}je.addStickyFlag=Yv;function ZEe(t,e,r){var i=[];return(0,Ie.has)(t,je.DEFAULT_MODE)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+je.DEFAULT_MODE+`> property in its definition +`,type:zt.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,Ie.has)(t,je.MODES)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+je.MODES+`> property in its definition +`,type:zt.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,Ie.has)(t,je.MODES)&&(0,Ie.has)(t,je.DEFAULT_MODE)&&!(0,Ie.has)(t.modes,t.defaultMode)&&i.push({message:"A MultiMode Lexer cannot be initialized with a "+je.DEFAULT_MODE+": <"+t.defaultMode+`>which does not exist +`,type:zt.LexerDefinitionErrorType.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,Ie.has)(t,je.MODES)&&(0,Ie.forEach)(t.modes,function(n,s){(0,Ie.forEach)(n,function(o,a){(0,Ie.isUndefined)(o)&&i.push({message:"A Lexer cannot be initialized using an undefined Token Type. Mode:"+("<"+s+"> at index: <"+a+`> +`),type:zt.LexerDefinitionErrorType.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED})})}),i}je.performRuntimeChecks=ZEe;function $Ee(t,e,r){var i=[],n=!1,s=(0,Ie.compact)((0,Ie.flatten)((0,Ie.mapValues)(t.modes,function(l){return l}))),o=(0,Ie.reject)(s,function(l){return l[ao]===zt.Lexer.NA}),a=tG(r);return e&&(0,Ie.forEach)(o,function(l){var c=eG(l,a);if(c!==!1){var u=gG(l,c),g={message:u,type:c.issue,tokenType:l};i.push(g)}else(0,Ie.has)(l,"LINE_BREAKS")?l.LINE_BREAKS===!0&&(n=!0):(0,Iu.canMatchCharCode)(a,l.PATTERN)&&(n=!0)}),e&&!n&&i.push({message:`Warning: No LINE_BREAKS Found. + This Lexer has been defined to track line and column information, + But none of the Token Types can be identified as matching a line terminator. + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS + for details.`,type:zt.LexerDefinitionErrorType.NO_LINE_BREAKS_FLAGS}),i}je.performWarningRuntimeChecks=$Ee;function eIe(t){var e={},r=(0,Ie.keys)(t);return(0,Ie.forEach)(r,function(i){var n=t[i];if((0,Ie.isArray)(n))e[i]=[];else throw Error("non exhaustive match")}),e}je.cloneEmptyGroups=eIe;function qv(t){var e=t.PATTERN;if((0,Ie.isRegExp)(e))return!1;if((0,Ie.isFunction)(e))return!0;if((0,Ie.has)(e,"exec"))return!0;if((0,Ie.isString)(e))return!1;throw Error("non exhaustive match")}je.isCustomPattern=qv;function $H(t){return(0,Ie.isString)(t)&&t.length===1?t.charCodeAt(0):!1}je.isShortPattern=$H;je.LineTerminatorOptimizedTester={test:function(t){for(var e=t.length,r=this.lastIndex;r Token Type +`)+(" Root cause: "+e.errMsg+`. +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR";if(e.issue===zt.LexerDefinitionErrorType.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the option. +`+(" The problem is in the <"+t.name+`> Token Type +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK";throw Error("non exhaustive match")}je.buildLineBreakIssueMessage=gG;function tG(t){var e=(0,Ie.map)(t,function(r){return(0,Ie.isString)(r)&&r.length>0?r.charCodeAt(0):r});return e}function Jv(t,e,r){t[e]===void 0?t[e]=[r]:t[e].push(r)}je.minOptimizationVal=256;var pI=[];function Wv(t){return t255?255+~~(t/255):t}}});var yu=E(Bt=>{"use strict";Object.defineProperty(Bt,"__esModule",{value:!0});Bt.isTokenType=Bt.hasExtendingTokensTypesMapProperty=Bt.hasExtendingTokensTypesProperty=Bt.hasCategoriesProperty=Bt.hasShortKeyProperty=Bt.singleAssignCategoriesToksMap=Bt.assignCategoriesMapProp=Bt.assignCategoriesTokensProp=Bt.assignTokenDefaultProps=Bt.expandCategories=Bt.augmentTokenTypes=Bt.tokenIdxToClass=Bt.tokenShortNameIdx=Bt.tokenStructuredMatcherNoCategories=Bt.tokenStructuredMatcher=void 0;var Kr=Dt();function tIe(t,e){var r=t.tokenTypeIdx;return r===e.tokenTypeIdx?!0:e.isParent===!0&&e.categoryMatchesMap[r]===!0}Bt.tokenStructuredMatcher=tIe;function rIe(t,e){return t.tokenTypeIdx===e.tokenTypeIdx}Bt.tokenStructuredMatcherNoCategories=rIe;Bt.tokenShortNameIdx=1;Bt.tokenIdxToClass={};function iIe(t){var e=fG(t);hG(e),dG(e),pG(e),(0,Kr.forEach)(e,function(r){r.isParent=r.categoryMatches.length>0})}Bt.augmentTokenTypes=iIe;function fG(t){for(var e=(0,Kr.cloneArr)(t),r=t,i=!0;i;){r=(0,Kr.compact)((0,Kr.flatten)((0,Kr.map)(r,function(s){return s.CATEGORIES})));var n=(0,Kr.difference)(r,e);e=e.concat(n),(0,Kr.isEmpty)(n)?i=!1:r=n}return e}Bt.expandCategories=fG;function hG(t){(0,Kr.forEach)(t,function(e){CG(e)||(Bt.tokenIdxToClass[Bt.tokenShortNameIdx]=e,e.tokenTypeIdx=Bt.tokenShortNameIdx++),zv(e)&&!(0,Kr.isArray)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),zv(e)||(e.CATEGORIES=[]),mG(e)||(e.categoryMatches=[]),EG(e)||(e.categoryMatchesMap={})})}Bt.assignTokenDefaultProps=hG;function pG(t){(0,Kr.forEach)(t,function(e){e.categoryMatches=[],(0,Kr.forEach)(e.categoryMatchesMap,function(r,i){e.categoryMatches.push(Bt.tokenIdxToClass[i].tokenTypeIdx)})})}Bt.assignCategoriesTokensProp=pG;function dG(t){(0,Kr.forEach)(t,function(e){Vv([],e)})}Bt.assignCategoriesMapProp=dG;function Vv(t,e){(0,Kr.forEach)(t,function(r){e.categoryMatchesMap[r.tokenTypeIdx]=!0}),(0,Kr.forEach)(e.CATEGORIES,function(r){var i=t.concat(e);(0,Kr.contains)(i,r)||Vv(i,r)})}Bt.singleAssignCategoriesToksMap=Vv;function CG(t){return(0,Kr.has)(t,"tokenTypeIdx")}Bt.hasShortKeyProperty=CG;function zv(t){return(0,Kr.has)(t,"CATEGORIES")}Bt.hasCategoriesProperty=zv;function mG(t){return(0,Kr.has)(t,"categoryMatches")}Bt.hasExtendingTokensTypesProperty=mG;function EG(t){return(0,Kr.has)(t,"categoryMatchesMap")}Bt.hasExtendingTokensTypesMapProperty=EG;function nIe(t){return(0,Kr.has)(t,"tokenTypeIdx")}Bt.isTokenType=nIe});var _v=E(dI=>{"use strict";Object.defineProperty(dI,"__esModule",{value:!0});dI.defaultLexerErrorProvider=void 0;dI.defaultLexerErrorProvider={buildUnableToPopLexerModeMessage:function(t){return"Unable to pop Lexer Mode after encountering Token ->"+t.image+"<- The Mode Stack is empty"},buildUnexpectedCharactersMessage:function(t,e,r,i,n){return"unexpected character: ->"+t.charAt(e)+"<- at offset: "+e+","+(" skipped "+r+" characters.")}}});var Gh=E(Rl=>{"use strict";Object.defineProperty(Rl,"__esModule",{value:!0});Rl.Lexer=Rl.LexerDefinitionErrorType=void 0;var Ps=Hv(),Vt=Dt(),sIe=yu(),oIe=_v(),aIe=gI(),AIe;(function(t){t[t.MISSING_PATTERN=0]="MISSING_PATTERN",t[t.INVALID_PATTERN=1]="INVALID_PATTERN",t[t.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",t[t.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",t[t.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",t[t.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",t[t.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",t[t.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",t[t.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",t[t.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",t[t.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",t[t.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",t[t.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",t[t.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",t[t.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",t[t.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",t[t.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK"})(AIe=Rl.LexerDefinitionErrorType||(Rl.LexerDefinitionErrorType={}));var jh={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` +`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:oIe.defaultLexerErrorProvider,traceInitPerf:!1,skipValidations:!1};Object.freeze(jh);var lIe=function(){function t(e,r){var i=this;if(r===void 0&&(r=jh),this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.config=void 0,this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},typeof r=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object. +a boolean 2nd argument is no longer supported`);this.config=(0,Vt.merge)(jh,r);var n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=Infinity,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",function(){var s,o=!0;i.TRACE_INIT("Lexer Config handling",function(){if(i.config.lineTerminatorsPattern===jh.lineTerminatorsPattern)i.config.lineTerminatorsPattern=Ps.LineTerminatorOptimizedTester;else if(i.config.lineTerminatorCharacters===jh.lineTerminatorCharacters)throw Error(`Error: Missing property on the Lexer config. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(r.safeMode&&r.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');i.trackStartLines=/full|onlyStart/i.test(i.config.positionTracking),i.trackEndLines=/full/i.test(i.config.positionTracking),(0,Vt.isArray)(e)?(s={modes:{}},s.modes[Ps.DEFAULT_MODE]=(0,Vt.cloneArr)(e),s[Ps.DEFAULT_MODE]=Ps.DEFAULT_MODE):(o=!1,s=(0,Vt.cloneObj)(e))}),i.config.skipValidations===!1&&(i.TRACE_INIT("performRuntimeChecks",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,Ps.performRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))}),i.TRACE_INIT("performWarningRuntimeChecks",function(){i.lexerDefinitionWarning=i.lexerDefinitionWarning.concat((0,Ps.performWarningRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))})),s.modes=s.modes?s.modes:{},(0,Vt.forEach)(s.modes,function(u,g){s.modes[g]=(0,Vt.reject)(u,function(f){return(0,Vt.isUndefined)(f)})});var a=(0,Vt.keys)(s.modes);if((0,Vt.forEach)(s.modes,function(u,g){i.TRACE_INIT("Mode: <"+g+"> processing",function(){if(i.modes.push(g),i.config.skipValidations===!1&&i.TRACE_INIT("validatePatterns",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,Ps.validatePatterns)(u,a))}),(0,Vt.isEmpty)(i.lexerDefinitionErrors)){(0,sIe.augmentTokenTypes)(u);var f;i.TRACE_INIT("analyzeTokenTypes",function(){f=(0,Ps.analyzeTokenTypes)(u,{lineTerminatorCharacters:i.config.lineTerminatorCharacters,positionTracking:r.positionTracking,ensureOptimizations:r.ensureOptimizations,safeMode:r.safeMode,tracer:i.TRACE_INIT.bind(i)})}),i.patternIdxToConfig[g]=f.patternIdxToConfig,i.charCodeToPatternIdxToConfig[g]=f.charCodeToPatternIdxToConfig,i.emptyGroups=(0,Vt.merge)(i.emptyGroups,f.emptyGroups),i.hasCustom=f.hasCustom||i.hasCustom,i.canModeBeOptimized[g]=f.canBeOptimized}})}),i.defaultMode=s.defaultMode,!(0,Vt.isEmpty)(i.lexerDefinitionErrors)&&!i.config.deferDefinitionErrorsHandling){var l=(0,Vt.map)(i.lexerDefinitionErrors,function(u){return u.message}),c=l.join(`----------------------- +`);throw new Error(`Errors detected in definition of Lexer: +`+c)}(0,Vt.forEach)(i.lexerDefinitionWarning,function(u){(0,Vt.PRINT_WARNING)(u.message)}),i.TRACE_INIT("Choosing sub-methods implementations",function(){if(Ps.SUPPORT_STICKY?(i.chopInput=Vt.IDENTITY,i.match=i.matchWithTest):(i.updateLastIndex=Vt.NOOP,i.match=i.matchWithExec),o&&(i.handleModes=Vt.NOOP),i.trackStartLines===!1&&(i.computeNewColumn=Vt.IDENTITY),i.trackEndLines===!1&&(i.updateTokenEndLineColumnLocation=Vt.NOOP),/full/i.test(i.config.positionTracking))i.createTokenInstance=i.createFullToken;else if(/onlyStart/i.test(i.config.positionTracking))i.createTokenInstance=i.createStartOnlyToken;else if(/onlyOffset/i.test(i.config.positionTracking))i.createTokenInstance=i.createOffsetOnlyToken;else throw Error('Invalid config option: "'+i.config.positionTracking+'"');i.hasCustom?(i.addToken=i.addTokenUsingPush,i.handlePayload=i.handlePayloadWithCustom):(i.addToken=i.addTokenUsingMemberAccess,i.handlePayload=i.handlePayloadNoCustom)}),i.TRACE_INIT("Failed Optimization Warnings",function(){var u=(0,Vt.reduce)(i.canModeBeOptimized,function(g,f,h){return f===!1&&g.push(h),g},[]);if(r.ensureOptimizations&&!(0,Vt.isEmpty)(u))throw Error("Lexer Modes: < "+u.join(", ")+` > cannot be optimized. + Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode. + Or inspect the console log for details on how to resolve these issues.`)}),i.TRACE_INIT("clearRegExpParserCache",function(){(0,aIe.clearRegExpParserCache)()}),i.TRACE_INIT("toFastProperties",function(){(0,Vt.toFastProperties)(i)})})}return t.prototype.tokenize=function(e,r){if(r===void 0&&(r=this.defaultMode),!(0,Vt.isEmpty)(this.lexerDefinitionErrors)){var i=(0,Vt.map)(this.lexerDefinitionErrors,function(o){return o.message}),n=i.join(`----------------------- +`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer: +`+n)}var s=this.tokenizeInternal(e,r);return s},t.prototype.tokenizeInternal=function(e,r){var i=this,n,s,o,a,l,c,u,g,f,h,p,d,m,I,B,b,R=e,H=R.length,L=0,K=0,J=this.hasCustom?0:Math.floor(e.length/10),ne=new Array(J),q=[],A=this.trackStartLines?1:void 0,V=this.trackStartLines?1:void 0,W=(0,Ps.cloneEmptyGroups)(this.emptyGroups),X=this.trackStartLines,F=this.config.lineTerminatorsPattern,D=0,he=[],pe=[],Ne=[],Pe=[];Object.freeze(Pe);var qe=void 0;function re(){return he}function se(wr){var Ui=(0,Ps.charCodeToOptimizedIndex)(wr),ws=pe[Ui];return ws===void 0?Pe:ws}var be=function(wr){if(Ne.length===1&&wr.tokenType.PUSH_MODE===void 0){var Ui=i.config.errorMessageProvider.buildUnableToPopLexerModeMessage(wr);q.push({offset:wr.startOffset,line:wr.startLine!==void 0?wr.startLine:void 0,column:wr.startColumn!==void 0?wr.startColumn:void 0,length:wr.image.length,message:Ui})}else{Ne.pop();var ws=(0,Vt.last)(Ne);he=i.patternIdxToConfig[ws],pe=i.charCodeToPatternIdxToConfig[ws],D=he.length;var Tf=i.canModeBeOptimized[ws]&&i.config.safeMode===!1;pe&&Tf?qe=se:qe=re}};function ae(wr){Ne.push(wr),pe=this.charCodeToPatternIdxToConfig[wr],he=this.patternIdxToConfig[wr],D=he.length,D=he.length;var Ui=this.canModeBeOptimized[wr]&&this.config.safeMode===!1;pe&&Ui?qe=se:qe=re}ae.call(this,r);for(var Ae;Lc.length){c=a,u=g,Ae=Oe;break}}}break}}if(c!==null){if(f=c.length,h=Ae.group,h!==void 0&&(p=Ae.tokenTypeIdx,d=this.createTokenInstance(c,L,p,Ae.tokenType,A,V,f),this.handlePayload(d,u),h===!1?K=this.addToken(ne,K,d):W[h].push(d)),e=this.chopInput(e,f),L=L+f,V=this.computeNewColumn(V,f),X===!0&&Ae.canLineTerminator===!0){var dt=0,ri=void 0,ii=void 0;F.lastIndex=0;do ri=F.test(c),ri===!0&&(ii=F.lastIndex-1,dt++);while(ri===!0);dt!==0&&(A=A+dt,V=f-ii,this.updateTokenEndLineColumnLocation(d,h,ii,dt,A,V,f))}this.handleModes(Ae,be,ae,d)}else{for(var an=L,yr=A,Ki=V,Qi=!1;!Qi&&L <"+e+">");var n=(0,Vt.timer)(r),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return r()},t.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.",t.NA=/NOT_APPLICABLE/,t}();Rl.Lexer=lIe});var nA=E(Ci=>{"use strict";Object.defineProperty(Ci,"__esModule",{value:!0});Ci.tokenMatcher=Ci.createTokenInstance=Ci.EOF=Ci.createToken=Ci.hasTokenLabel=Ci.tokenName=Ci.tokenLabel=void 0;var Ds=Dt(),cIe=Gh(),Xv=yu();function uIe(t){return IG(t)?t.LABEL:t.name}Ci.tokenLabel=uIe;function gIe(t){return t.name}Ci.tokenName=gIe;function IG(t){return(0,Ds.isString)(t.LABEL)&&t.LABEL!==""}Ci.hasTokenLabel=IG;var fIe="parent",yG="categories",wG="label",BG="group",QG="push_mode",bG="pop_mode",vG="longer_alt",SG="line_breaks",xG="start_chars_hint";function kG(t){return hIe(t)}Ci.createToken=kG;function hIe(t){var e=t.pattern,r={};if(r.name=t.name,(0,Ds.isUndefined)(e)||(r.PATTERN=e),(0,Ds.has)(t,fIe))throw`The parent property is no longer supported. +See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.`;return(0,Ds.has)(t,yG)&&(r.CATEGORIES=t[yG]),(0,Xv.augmentTokenTypes)([r]),(0,Ds.has)(t,wG)&&(r.LABEL=t[wG]),(0,Ds.has)(t,BG)&&(r.GROUP=t[BG]),(0,Ds.has)(t,bG)&&(r.POP_MODE=t[bG]),(0,Ds.has)(t,QG)&&(r.PUSH_MODE=t[QG]),(0,Ds.has)(t,vG)&&(r.LONGER_ALT=t[vG]),(0,Ds.has)(t,SG)&&(r.LINE_BREAKS=t[SG]),(0,Ds.has)(t,xG)&&(r.START_CHARS_HINT=t[xG]),r}Ci.EOF=kG({name:"EOF",pattern:cIe.Lexer.NA});(0,Xv.augmentTokenTypes)([Ci.EOF]);function pIe(t,e,r,i,n,s,o,a){return{image:e,startOffset:r,endOffset:i,startLine:n,endLine:s,startColumn:o,endColumn:a,tokenTypeIdx:t.tokenTypeIdx,tokenType:t}}Ci.createTokenInstance=pIe;function dIe(t,e){return(0,Xv.tokenStructuredMatcher)(t,e)}Ci.tokenMatcher=dIe});var hn=E(Tt=>{"use strict";var oa=Tt&&Tt.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(Tt,"__esModule",{value:!0});Tt.serializeProduction=Tt.serializeGrammar=Tt.Terminal=Tt.Alternation=Tt.RepetitionWithSeparator=Tt.Repetition=Tt.RepetitionMandatoryWithSeparator=Tt.RepetitionMandatory=Tt.Option=Tt.Alternative=Tt.Rule=Tt.NonTerminal=Tt.AbstractProduction=void 0;var $t=Dt(),CIe=nA(),Ao=function(){function t(e){this._definition=e}return Object.defineProperty(t.prototype,"definition",{get:function(){return this._definition},set:function(e){this._definition=e},enumerable:!1,configurable:!0}),t.prototype.accept=function(e){e.visit(this),(0,$t.forEach)(this.definition,function(r){r.accept(e)})},t}();Tt.AbstractProduction=Ao;var PG=function(t){oa(e,t);function e(r){var i=t.call(this,[])||this;return i.idx=1,(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this.referencedRule!==void 0?this.referencedRule.definition:[]},set:function(r){},enumerable:!1,configurable:!0}),e.prototype.accept=function(r){r.visit(this)},e}(Ao);Tt.NonTerminal=PG;var DG=function(t){oa(e,t);function e(r){var i=t.call(this,r.definition)||this;return i.orgText="",(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return e}(Ao);Tt.Rule=DG;var RG=function(t){oa(e,t);function e(r){var i=t.call(this,r.definition)||this;return i.ignoreAmbiguities=!1,(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return e}(Ao);Tt.Alternative=RG;var FG=function(t){oa(e,t);function e(r){var i=t.call(this,r.definition)||this;return i.idx=1,(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return e}(Ao);Tt.Option=FG;var NG=function(t){oa(e,t);function e(r){var i=t.call(this,r.definition)||this;return i.idx=1,(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return e}(Ao);Tt.RepetitionMandatory=NG;var LG=function(t){oa(e,t);function e(r){var i=t.call(this,r.definition)||this;return i.idx=1,(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return e}(Ao);Tt.RepetitionMandatoryWithSeparator=LG;var TG=function(t){oa(e,t);function e(r){var i=t.call(this,r.definition)||this;return i.idx=1,(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return e}(Ao);Tt.Repetition=TG;var MG=function(t){oa(e,t);function e(r){var i=t.call(this,r.definition)||this;return i.idx=1,(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return e}(Ao);Tt.RepetitionWithSeparator=MG;var OG=function(t){oa(e,t);function e(r){var i=t.call(this,r.definition)||this;return i.idx=1,i.ignoreAmbiguities=!1,i.hasPredicates=!1,(0,$t.assign)(i,(0,$t.pick)(r,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this._definition},set:function(r){this._definition=r},enumerable:!1,configurable:!0}),e}(Ao);Tt.Alternation=OG;var CI=function(){function t(e){this.idx=1,(0,$t.assign)(this,(0,$t.pick)(e,function(r){return r!==void 0}))}return t.prototype.accept=function(e){e.visit(this)},t}();Tt.Terminal=CI;function mIe(t){return(0,$t.map)(t,Yh)}Tt.serializeGrammar=mIe;function Yh(t){function e(s){return(0,$t.map)(s,Yh)}if(t instanceof PG){var r={type:"NonTerminal",name:t.nonTerminalName,idx:t.idx};return(0,$t.isString)(t.label)&&(r.label=t.label),r}else{if(t instanceof RG)return{type:"Alternative",definition:e(t.definition)};if(t instanceof FG)return{type:"Option",idx:t.idx,definition:e(t.definition)};if(t instanceof NG)return{type:"RepetitionMandatory",idx:t.idx,definition:e(t.definition)};if(t instanceof LG)return{type:"RepetitionMandatoryWithSeparator",idx:t.idx,separator:Yh(new CI({terminalType:t.separator})),definition:e(t.definition)};if(t instanceof MG)return{type:"RepetitionWithSeparator",idx:t.idx,separator:Yh(new CI({terminalType:t.separator})),definition:e(t.definition)};if(t instanceof TG)return{type:"Repetition",idx:t.idx,definition:e(t.definition)};if(t instanceof OG)return{type:"Alternation",idx:t.idx,definition:e(t.definition)};if(t instanceof CI){var i={type:"Terminal",name:t.terminalType.name,label:(0,CIe.tokenLabel)(t.terminalType),idx:t.idx};(0,$t.isString)(t.label)&&(i.terminalLabel=t.label);var n=t.terminalType.PATTERN;return t.terminalType.PATTERN&&(i.pattern=(0,$t.isRegExp)(n)?n.source:n),i}else{if(t instanceof DG)return{type:"Rule",name:t.name,orgText:t.orgText,definition:e(t.definition)};throw Error("non exhaustive match")}}}Tt.serializeProduction=Yh});var EI=E(mI=>{"use strict";Object.defineProperty(mI,"__esModule",{value:!0});mI.RestWalker=void 0;var Zv=Dt(),pn=hn(),EIe=function(){function t(){}return t.prototype.walk=function(e,r){var i=this;r===void 0&&(r=[]),(0,Zv.forEach)(e.definition,function(n,s){var o=(0,Zv.drop)(e.definition,s+1);if(n instanceof pn.NonTerminal)i.walkProdRef(n,o,r);else if(n instanceof pn.Terminal)i.walkTerminal(n,o,r);else if(n instanceof pn.Alternative)i.walkFlat(n,o,r);else if(n instanceof pn.Option)i.walkOption(n,o,r);else if(n instanceof pn.RepetitionMandatory)i.walkAtLeastOne(n,o,r);else if(n instanceof pn.RepetitionMandatoryWithSeparator)i.walkAtLeastOneSep(n,o,r);else if(n instanceof pn.RepetitionWithSeparator)i.walkManySep(n,o,r);else if(n instanceof pn.Repetition)i.walkMany(n,o,r);else if(n instanceof pn.Alternation)i.walkOr(n,o,r);else throw Error("non exhaustive match")})},t.prototype.walkTerminal=function(e,r,i){},t.prototype.walkProdRef=function(e,r,i){},t.prototype.walkFlat=function(e,r,i){var n=r.concat(i);this.walk(e,n)},t.prototype.walkOption=function(e,r,i){var n=r.concat(i);this.walk(e,n)},t.prototype.walkAtLeastOne=function(e,r,i){var n=[new pn.Option({definition:e.definition})].concat(r,i);this.walk(e,n)},t.prototype.walkAtLeastOneSep=function(e,r,i){var n=KG(e,r,i);this.walk(e,n)},t.prototype.walkMany=function(e,r,i){var n=[new pn.Option({definition:e.definition})].concat(r,i);this.walk(e,n)},t.prototype.walkManySep=function(e,r,i){var n=KG(e,r,i);this.walk(e,n)},t.prototype.walkOr=function(e,r,i){var n=this,s=r.concat(i);(0,Zv.forEach)(e.definition,function(o){var a=new pn.Alternative({definition:[o]});n.walk(a,s)})},t}();mI.RestWalker=EIe;function KG(t,e,r){var i=[new pn.Option({definition:[new pn.Terminal({terminalType:t.separator})].concat(t.definition)})],n=i.concat(e,r);return n}});var wu=E(II=>{"use strict";Object.defineProperty(II,"__esModule",{value:!0});II.GAstVisitor=void 0;var lo=hn(),IIe=function(){function t(){}return t.prototype.visit=function(e){var r=e;switch(r.constructor){case lo.NonTerminal:return this.visitNonTerminal(r);case lo.Alternative:return this.visitAlternative(r);case lo.Option:return this.visitOption(r);case lo.RepetitionMandatory:return this.visitRepetitionMandatory(r);case lo.RepetitionMandatoryWithSeparator:return this.visitRepetitionMandatoryWithSeparator(r);case lo.RepetitionWithSeparator:return this.visitRepetitionWithSeparator(r);case lo.Repetition:return this.visitRepetition(r);case lo.Alternation:return this.visitAlternation(r);case lo.Terminal:return this.visitTerminal(r);case lo.Rule:return this.visitRule(r);default:throw Error("non exhaustive match")}},t.prototype.visitNonTerminal=function(e){},t.prototype.visitAlternative=function(e){},t.prototype.visitOption=function(e){},t.prototype.visitRepetition=function(e){},t.prototype.visitRepetitionMandatory=function(e){},t.prototype.visitRepetitionMandatoryWithSeparator=function(e){},t.prototype.visitRepetitionWithSeparator=function(e){},t.prototype.visitAlternation=function(e){},t.prototype.visitTerminal=function(e){},t.prototype.visitRule=function(e){},t}();II.GAstVisitor=IIe});var Jh=E(Si=>{"use strict";var yIe=Si&&Si.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(Si,"__esModule",{value:!0});Si.collectMethods=Si.DslMethodsCollectorVisitor=Si.getProductionDslName=Si.isBranchingProd=Si.isOptionalProd=Si.isSequenceProd=void 0;var qh=Dt(),dr=hn(),wIe=wu();function BIe(t){return t instanceof dr.Alternative||t instanceof dr.Option||t instanceof dr.Repetition||t instanceof dr.RepetitionMandatory||t instanceof dr.RepetitionMandatoryWithSeparator||t instanceof dr.RepetitionWithSeparator||t instanceof dr.Terminal||t instanceof dr.Rule}Si.isSequenceProd=BIe;function $v(t,e){e===void 0&&(e=[]);var r=t instanceof dr.Option||t instanceof dr.Repetition||t instanceof dr.RepetitionWithSeparator;return r?!0:t instanceof dr.Alternation?(0,qh.some)(t.definition,function(i){return $v(i,e)}):t instanceof dr.NonTerminal&&(0,qh.contains)(e,t)?!1:t instanceof dr.AbstractProduction?(t instanceof dr.NonTerminal&&e.push(t),(0,qh.every)(t.definition,function(i){return $v(i,e)})):!1}Si.isOptionalProd=$v;function QIe(t){return t instanceof dr.Alternation}Si.isBranchingProd=QIe;function bIe(t){if(t instanceof dr.NonTerminal)return"SUBRULE";if(t instanceof dr.Option)return"OPTION";if(t instanceof dr.Alternation)return"OR";if(t instanceof dr.RepetitionMandatory)return"AT_LEAST_ONE";if(t instanceof dr.RepetitionMandatoryWithSeparator)return"AT_LEAST_ONE_SEP";if(t instanceof dr.RepetitionWithSeparator)return"MANY_SEP";if(t instanceof dr.Repetition)return"MANY";if(t instanceof dr.Terminal)return"CONSUME";throw Error("non exhaustive match")}Si.getProductionDslName=bIe;var UG=function(t){yIe(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.separator="-",r.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]},r}return e.prototype.reset=function(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}},e.prototype.visitTerminal=function(r){var i=r.terminalType.name+this.separator+"Terminal";(0,qh.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(r)},e.prototype.visitNonTerminal=function(r){var i=r.nonTerminalName+this.separator+"Terminal";(0,qh.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(r)},e.prototype.visitOption=function(r){this.dslMethods.option.push(r)},e.prototype.visitRepetitionWithSeparator=function(r){this.dslMethods.repetitionWithSeparator.push(r)},e.prototype.visitRepetitionMandatory=function(r){this.dslMethods.repetitionMandatory.push(r)},e.prototype.visitRepetitionMandatoryWithSeparator=function(r){this.dslMethods.repetitionMandatoryWithSeparator.push(r)},e.prototype.visitRepetition=function(r){this.dslMethods.repetition.push(r)},e.prototype.visitAlternation=function(r){this.dslMethods.alternation.push(r)},e}(wIe.GAstVisitor);Si.DslMethodsCollectorVisitor=UG;var yI=new UG;function vIe(t){yI.reset(),t.accept(yI);var e=yI.dslMethods;return yI.reset(),e}Si.collectMethods=vIe});var tS=E(co=>{"use strict";Object.defineProperty(co,"__esModule",{value:!0});co.firstForTerminal=co.firstForBranching=co.firstForSequence=co.first=void 0;var wI=Dt(),HG=hn(),eS=Jh();function BI(t){if(t instanceof HG.NonTerminal)return BI(t.referencedRule);if(t instanceof HG.Terminal)return YG(t);if((0,eS.isSequenceProd)(t))return GG(t);if((0,eS.isBranchingProd)(t))return jG(t);throw Error("non exhaustive match")}co.first=BI;function GG(t){for(var e=[],r=t.definition,i=0,n=r.length>i,s,o=!0;n&&o;)s=r[i],o=(0,eS.isOptionalProd)(s),e=e.concat(BI(s)),i=i+1,n=r.length>i;return(0,wI.uniq)(e)}co.firstForSequence=GG;function jG(t){var e=(0,wI.map)(t.definition,function(r){return BI(r)});return(0,wI.uniq)((0,wI.flatten)(e))}co.firstForBranching=jG;function YG(t){return[t.terminalType]}co.firstForTerminal=YG});var rS=E(QI=>{"use strict";Object.defineProperty(QI,"__esModule",{value:!0});QI.IN=void 0;QI.IN="_~IN~_"});var VG=E(es=>{"use strict";var SIe=es&&es.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(es,"__esModule",{value:!0});es.buildInProdFollowPrefix=es.buildBetweenProdsFollowPrefix=es.computeAllProdsFollows=es.ResyncFollowsWalker=void 0;var xIe=EI(),kIe=tS(),qG=Dt(),JG=rS(),PIe=hn(),zG=function(t){SIe(e,t);function e(r){var i=t.call(this)||this;return i.topProd=r,i.follows={},i}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.follows},e.prototype.walkTerminal=function(r,i,n){},e.prototype.walkProdRef=function(r,i,n){var s=WG(r.referencedRule,r.idx)+this.topProd.name,o=i.concat(n),a=new PIe.Alternative({definition:o}),l=(0,kIe.first)(a);this.follows[s]=l},e}(xIe.RestWalker);es.ResyncFollowsWalker=zG;function DIe(t){var e={};return(0,qG.forEach)(t,function(r){var i=new zG(r).startWalking();(0,qG.assign)(e,i)}),e}es.computeAllProdsFollows=DIe;function WG(t,e){return t.name+e+JG.IN}es.buildBetweenProdsFollowPrefix=WG;function RIe(t){var e=t.terminalType.name;return e+t.idx+JG.IN}es.buildInProdFollowPrefix=RIe});var Wh=E(aa=>{"use strict";Object.defineProperty(aa,"__esModule",{value:!0});aa.defaultGrammarValidatorErrorProvider=aa.defaultGrammarResolverErrorProvider=aa.defaultParserErrorProvider=void 0;var Bu=nA(),FIe=Dt(),Rs=Dt(),iS=hn(),_G=Jh();aa.defaultParserErrorProvider={buildMismatchTokenMessage:function(t){var e=t.expected,r=t.actual,i=t.previous,n=t.ruleName,s=(0,Bu.hasTokenLabel)(e),o=s?"--> "+(0,Bu.tokenLabel)(e)+" <--":"token of type --> "+e.name+" <--",a="Expecting "+o+" but found --> '"+r.image+"' <--";return a},buildNotAllInputParsedMessage:function(t){var e=t.firstRedundant,r=t.ruleName;return"Redundant input, expecting EOF but found: "+e.image},buildNoViableAltMessage:function(t){var e=t.expectedPathsPerAlt,r=t.actual,i=t.previous,n=t.customUserDescription,s=t.ruleName,o="Expecting: ",a=(0,Rs.first)(r).image,l=` +but found: '`+a+"'";if(n)return o+n+l;var c=(0,Rs.reduce)(e,function(h,p){return h.concat(p)},[]),u=(0,Rs.map)(c,function(h){return"["+(0,Rs.map)(h,function(p){return(0,Bu.tokenLabel)(p)}).join(", ")+"]"}),g=(0,Rs.map)(u,function(h,p){return" "+(p+1)+". "+h}),f=`one of these possible Token sequences: +`+g.join(` +`);return o+f+l},buildEarlyExitMessage:function(t){var e=t.expectedIterationPaths,r=t.actual,i=t.customUserDescription,n=t.ruleName,s="Expecting: ",o=(0,Rs.first)(r).image,a=` +but found: '`+o+"'";if(i)return s+i+a;var l=(0,Rs.map)(e,function(u){return"["+(0,Rs.map)(u,function(g){return(0,Bu.tokenLabel)(g)}).join(",")+"]"}),c=`expecting at least one iteration which starts with one of these possible Token sequences:: + `+("<"+l.join(" ,")+">");return s+c+a}};Object.freeze(aa.defaultParserErrorProvider);aa.defaultGrammarResolverErrorProvider={buildRuleNotFoundError:function(t,e){var r="Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- +inside top level rule: ->`+t.name+"<-";return r}};aa.defaultGrammarValidatorErrorProvider={buildDuplicateFoundError:function(t,e){function r(u){return u instanceof iS.Terminal?u.terminalType.name:u instanceof iS.NonTerminal?u.nonTerminalName:""}var i=t.name,n=(0,Rs.first)(e),s=n.idx,o=(0,_G.getProductionDslName)(n),a=r(n),l=s>0,c="->"+o+(l?s:"")+"<- "+(a?"with argument: ->"+a+"<-":"")+` + appears more than once (`+e.length+" times) in the top level rule: ->"+i+`<-. + For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES + `;return c=c.replace(/[ \t]+/g," "),c=c.replace(/\s\s+/g,` +`),c},buildNamespaceConflictError:function(t){var e=`Namespace conflict found in grammar. +`+("The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <"+t.name+`>. +`)+`To resolve this make sure each Terminal and Non-Terminal names are unique +This is easy to accomplish by using the convention that Terminal names start with an uppercase letter +and Non-Terminal names start with a lower case letter.`;return e},buildAlternationPrefixAmbiguityError:function(t){var e=(0,Rs.map)(t.prefixPath,function(n){return(0,Bu.tokenLabel)(n)}).join(", "),r=t.alternation.idx===0?"":t.alternation.idx,i="Ambiguous alternatives: <"+t.ambiguityIndices.join(" ,")+`> due to common lookahead prefix +`+("in inside <"+t.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`)+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX +For Further details.`;return i},buildAlternationAmbiguityError:function(t){var e=(0,Rs.map)(t.prefixPath,function(n){return(0,Bu.tokenLabel)(n)}).join(", "),r=t.alternation.idx===0?"":t.alternation.idx,i="Ambiguous Alternatives Detected: <"+t.ambiguityIndices.join(" ,")+"> in "+(" inside <"+t.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`);return i=i+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES +For Further details.`,i},buildEmptyRepetitionError:function(t){var e=(0,_G.getProductionDslName)(t.repetition);t.repetition.idx!==0&&(e+=t.repetition.idx);var r="The repetition <"+e+"> within Rule <"+t.topLevelRule.name+`> can never consume any tokens. +This could lead to an infinite loop.`;return r},buildTokenNameError:function(t){return"deprecated"},buildEmptyAlternationError:function(t){var e="Ambiguous empty alternative: <"+(t.emptyChoiceIdx+1)+">"+(" in inside <"+t.topLevelRule.name+`> Rule. +`)+"Only the last alternative may be an empty alternative.";return e},buildTooManyAlternativesError:function(t){var e=`An Alternation cannot have more than 256 alternatives: +`+(" inside <"+t.topLevelRule.name+`> Rule. + has `+(t.alternation.definition.length+1)+" alternatives.");return e},buildLeftRecursionError:function(t){var e=t.topLevelRule.name,r=FIe.map(t.leftRecursionPath,function(s){return s.name}),i=e+" --> "+r.concat([e]).join(" --> "),n=`Left Recursion found in grammar. +`+("rule: <"+e+`> can be invoked from itself (directly or indirectly) +`)+(`without consuming any Tokens. The grammar path that causes this is: + `+i+` +`)+` To fix this refactor your grammar to remove the left recursion. +see: https://en.wikipedia.org/wiki/LL_parser#Left_Factoring.`;return n},buildInvalidRuleNameError:function(t){return"deprecated"},buildDuplicateRuleNameError:function(t){var e;t.topLevelRule instanceof iS.Rule?e=t.topLevelRule.name:e=t.topLevelRule;var r="Duplicate definition, rule: ->"+e+"<- is already defined in the grammar: ->"+t.grammarName+"<-";return r}}});var $G=E(sA=>{"use strict";var NIe=sA&&sA.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(sA,"__esModule",{value:!0});sA.GastRefResolverVisitor=sA.resolveGrammar=void 0;var LIe=Tn(),XG=Dt(),TIe=wu();function MIe(t,e){var r=new ZG(t,e);return r.resolveRefs(),r.errors}sA.resolveGrammar=MIe;var ZG=function(t){NIe(e,t);function e(r,i){var n=t.call(this)||this;return n.nameToTopRule=r,n.errMsgProvider=i,n.errors=[],n}return e.prototype.resolveRefs=function(){var r=this;(0,XG.forEach)((0,XG.values)(this.nameToTopRule),function(i){r.currTopLevel=i,i.accept(r)})},e.prototype.visitNonTerminal=function(r){var i=this.nameToTopRule[r.nonTerminalName];if(i)r.referencedRule=i;else{var n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,r);this.errors.push({message:n,type:LIe.ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:r.nonTerminalName})}},e}(TIe.GAstVisitor);sA.GastRefResolverVisitor=ZG});var Vh=E(Br=>{"use strict";var Fl=Br&&Br.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(Br,"__esModule",{value:!0});Br.nextPossibleTokensAfter=Br.possiblePathsFrom=Br.NextTerminalAfterAtLeastOneSepWalker=Br.NextTerminalAfterAtLeastOneWalker=Br.NextTerminalAfterManySepWalker=Br.NextTerminalAfterManyWalker=Br.AbstractNextTerminalAfterProductionWalker=Br.NextAfterTokenWalker=Br.AbstractNextPossibleTokensWalker=void 0;var ej=EI(),xt=Dt(),OIe=tS(),It=hn(),tj=function(t){Fl(e,t);function e(r,i){var n=t.call(this)||this;return n.topProd=r,n.path=i,n.possibleTokTypes=[],n.nextProductionName="",n.nextProductionOccurrence=0,n.found=!1,n.isAtEndOfPath=!1,n}return e.prototype.startWalking=function(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=(0,xt.cloneArr)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,xt.cloneArr)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes},e.prototype.walk=function(r,i){i===void 0&&(i=[]),this.found||t.prototype.walk.call(this,r,i)},e.prototype.walkProdRef=function(r,i,n){if(r.referencedRule.name===this.nextProductionName&&r.idx===this.nextProductionOccurrence){var s=i.concat(n);this.updateExpectedNext(),this.walk(r.referencedRule,s)}},e.prototype.updateExpectedNext=function(){(0,xt.isEmpty)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())},e}(ej.RestWalker);Br.AbstractNextPossibleTokensWalker=tj;var KIe=function(t){Fl(e,t);function e(r,i){var n=t.call(this,r,i)||this;return n.path=i,n.nextTerminalName="",n.nextTerminalOccurrence=0,n.nextTerminalName=n.path.lastTok.name,n.nextTerminalOccurrence=n.path.lastTokOccurrence,n}return e.prototype.walkTerminal=function(r,i,n){if(this.isAtEndOfPath&&r.terminalType.name===this.nextTerminalName&&r.idx===this.nextTerminalOccurrence&&!this.found){var s=i.concat(n),o=new It.Alternative({definition:s});this.possibleTokTypes=(0,OIe.first)(o),this.found=!0}},e}(tj);Br.NextAfterTokenWalker=KIe;var zh=function(t){Fl(e,t);function e(r,i){var n=t.call(this)||this;return n.topRule=r,n.occurrence=i,n.result={token:void 0,occurrence:void 0,isEndOfRule:void 0},n}return e.prototype.startWalking=function(){return this.walk(this.topRule),this.result},e}(ej.RestWalker);Br.AbstractNextTerminalAfterProductionWalker=zh;var UIe=function(t){Fl(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.walkMany=function(r,i,n){if(r.idx===this.occurrence){var s=(0,xt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof It.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else t.prototype.walkMany.call(this,r,i,n)},e}(zh);Br.NextTerminalAfterManyWalker=UIe;var HIe=function(t){Fl(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.walkManySep=function(r,i,n){if(r.idx===this.occurrence){var s=(0,xt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof It.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else t.prototype.walkManySep.call(this,r,i,n)},e}(zh);Br.NextTerminalAfterManySepWalker=HIe;var GIe=function(t){Fl(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.walkAtLeastOne=function(r,i,n){if(r.idx===this.occurrence){var s=(0,xt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof It.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else t.prototype.walkAtLeastOne.call(this,r,i,n)},e}(zh);Br.NextTerminalAfterAtLeastOneWalker=GIe;var jIe=function(t){Fl(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.walkAtLeastOneSep=function(r,i,n){if(r.idx===this.occurrence){var s=(0,xt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof It.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else t.prototype.walkAtLeastOneSep.call(this,r,i,n)},e}(zh);Br.NextTerminalAfterAtLeastOneSepWalker=jIe;function rj(t,e,r){r===void 0&&(r=[]),r=(0,xt.cloneArr)(r);var i=[],n=0;function s(c){return c.concat((0,xt.drop)(t,n+1))}function o(c){var u=rj(s(c),e,r);return i.concat(u)}for(;r.length=0;W--){var X=I.definition[W],F={idx:p,def:X.definition.concat((0,xt.drop)(h)),ruleStack:d,occurrenceStack:m};g.push(F),g.push(o)}else if(I instanceof It.Alternative)g.push({idx:p,def:I.definition.concat((0,xt.drop)(h)),ruleStack:d,occurrenceStack:m});else if(I instanceof It.Rule)g.push(YIe(I,p,d,m));else throw Error("non exhaustive match")}}return u}Br.nextPossibleTokensAfter=qIe;function YIe(t,e,r,i){var n=(0,xt.cloneArr)(r);n.push(t.name);var s=(0,xt.cloneArr)(i);return s.push(1),{idx:e,def:t.definition,ruleStack:n,occurrenceStack:s}}});var _h=E(Gt=>{"use strict";var ij=Gt&&Gt.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(Gt,"__esModule",{value:!0});Gt.areTokenCategoriesNotUsed=Gt.isStrictPrefixOfPath=Gt.containsPath=Gt.getLookaheadPathsForOptionalProd=Gt.getLookaheadPathsForOr=Gt.lookAheadSequenceFromAlternatives=Gt.buildSingleAlternativeLookaheadFunction=Gt.buildAlternativesLookAheadFunc=Gt.buildLookaheadFuncForOptionalProd=Gt.buildLookaheadFuncForOr=Gt.getProdType=Gt.PROD_TYPE=void 0;var _t=Dt(),nj=Vh(),JIe=EI(),bI=yu(),oA=hn(),WIe=wu(),zr;(function(t){t[t.OPTION=0]="OPTION",t[t.REPETITION=1]="REPETITION",t[t.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",t[t.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",t[t.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",t[t.ALTERNATION=5]="ALTERNATION"})(zr=Gt.PROD_TYPE||(Gt.PROD_TYPE={}));function zIe(t){if(t instanceof oA.Option)return zr.OPTION;if(t instanceof oA.Repetition)return zr.REPETITION;if(t instanceof oA.RepetitionMandatory)return zr.REPETITION_MANDATORY;if(t instanceof oA.RepetitionMandatoryWithSeparator)return zr.REPETITION_MANDATORY_WITH_SEPARATOR;if(t instanceof oA.RepetitionWithSeparator)return zr.REPETITION_WITH_SEPARATOR;if(t instanceof oA.Alternation)return zr.ALTERNATION;throw Error("non exhaustive match")}Gt.getProdType=zIe;function VIe(t,e,r,i,n,s){var o=sj(t,e,r),a=nS(o)?bI.tokenStructuredMatcherNoCategories:bI.tokenStructuredMatcher;return s(o,i,a,n)}Gt.buildLookaheadFuncForOr=VIe;function _Ie(t,e,r,i,n,s){var o=oj(t,e,n,r),a=nS(o)?bI.tokenStructuredMatcherNoCategories:bI.tokenStructuredMatcher;return s(o[0],a,i)}Gt.buildLookaheadFuncForOptionalProd=_Ie;function XIe(t,e,r,i){var n=t.length,s=(0,_t.every)(t,function(l){return(0,_t.every)(l,function(c){return c.length===1})});if(e)return function(l){for(var c=(0,_t.map)(l,function(b){return b.GATE}),u=0;u{"use strict";var aS=Mt&&Mt.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(Mt,"__esModule",{value:!0});Mt.checkPrefixAlternativesAmbiguities=Mt.validateSomeNonEmptyLookaheadPath=Mt.validateTooManyAlts=Mt.RepetionCollector=Mt.validateAmbiguousAlternationAlternatives=Mt.validateEmptyOrAlternative=Mt.getFirstNoneTerminal=Mt.validateNoLeftRecursion=Mt.validateRuleIsOverridden=Mt.validateRuleDoesNotAlreadyExist=Mt.OccurrenceValidationCollector=Mt.identifyProductionForDuplicates=Mt.validateGrammar=void 0;var jt=Dt(),Cr=Dt(),uo=Tn(),AS=Jh(),Qu=_h(),rye=Vh(),Fs=hn(),lS=wu();function sye(t,e,r,i,n){var s=jt.map(t,function(h){return iye(h,i)}),o=jt.map(t,function(h){return cS(h,h,i)}),a=[],l=[],c=[];(0,Cr.every)(o,Cr.isEmpty)&&(a=(0,Cr.map)(t,function(h){return uj(h,i)}),l=(0,Cr.map)(t,function(h){return gj(h,e,i)}),c=hj(t,e,i));var u=nye(t,r,i),g=(0,Cr.map)(t,function(h){return fj(h,i)}),f=(0,Cr.map)(t,function(h){return cj(h,t,n,i)});return jt.flatten(s.concat(c,o,a,l,u,g,f))}Mt.validateGrammar=sye;function iye(t,e){var r=new Cj;t.accept(r);var i=r.allProductions,n=jt.groupBy(i,pj),s=jt.pick(n,function(a){return a.length>1}),o=jt.map(jt.values(s),function(a){var l=jt.first(a),c=e.buildDuplicateFoundError(t,a),u=(0,AS.getProductionDslName)(l),g={message:c,type:uo.ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,ruleName:t.name,dslName:u,occurrence:l.idx},f=dj(l);return f&&(g.parameter=f),g});return o}function pj(t){return(0,AS.getProductionDslName)(t)+"_#_"+t.idx+"_#_"+dj(t)}Mt.identifyProductionForDuplicates=pj;function dj(t){return t instanceof Fs.Terminal?t.terminalType.name:t instanceof Fs.NonTerminal?t.nonTerminalName:""}var Cj=function(t){aS(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.allProductions=[],r}return e.prototype.visitNonTerminal=function(r){this.allProductions.push(r)},e.prototype.visitOption=function(r){this.allProductions.push(r)},e.prototype.visitRepetitionWithSeparator=function(r){this.allProductions.push(r)},e.prototype.visitRepetitionMandatory=function(r){this.allProductions.push(r)},e.prototype.visitRepetitionMandatoryWithSeparator=function(r){this.allProductions.push(r)},e.prototype.visitRepetition=function(r){this.allProductions.push(r)},e.prototype.visitAlternation=function(r){this.allProductions.push(r)},e.prototype.visitTerminal=function(r){this.allProductions.push(r)},e}(lS.GAstVisitor);Mt.OccurrenceValidationCollector=Cj;function cj(t,e,r,i){var n=[],s=(0,Cr.reduce)(e,function(a,l){return l.name===t.name?a+1:a},0);if(s>1){var o=i.buildDuplicateRuleNameError({topLevelRule:t,grammarName:r});n.push({message:o,type:uo.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:t.name})}return n}Mt.validateRuleDoesNotAlreadyExist=cj;function oye(t,e,r){var i=[],n;return jt.contains(e,t)||(n="Invalid rule override, rule: ->"+t+"<- cannot be overridden in the grammar: ->"+r+"<-as it is not defined in any of the super grammars ",i.push({message:n,type:uo.ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,ruleName:t})),i}Mt.validateRuleIsOverridden=oye;function cS(t,e,r,i){i===void 0&&(i=[]);var n=[],s=Xh(e.definition);if(jt.isEmpty(s))return[];var o=t.name,a=jt.contains(s,t);a&&n.push({message:r.buildLeftRecursionError({topLevelRule:t,leftRecursionPath:i}),type:uo.ParserDefinitionErrorType.LEFT_RECURSION,ruleName:o});var l=jt.difference(s,i.concat([t])),c=jt.map(l,function(u){var g=jt.cloneArr(i);return g.push(u),cS(t,u,r,g)});return n.concat(jt.flatten(c))}Mt.validateNoLeftRecursion=cS;function Xh(t){var e=[];if(jt.isEmpty(t))return e;var r=jt.first(t);if(r instanceof Fs.NonTerminal)e.push(r.referencedRule);else if(r instanceof Fs.Alternative||r instanceof Fs.Option||r instanceof Fs.RepetitionMandatory||r instanceof Fs.RepetitionMandatoryWithSeparator||r instanceof Fs.RepetitionWithSeparator||r instanceof Fs.Repetition)e=e.concat(Xh(r.definition));else if(r instanceof Fs.Alternation)e=jt.flatten(jt.map(r.definition,function(o){return Xh(o.definition)}));else if(!(r instanceof Fs.Terminal))throw Error("non exhaustive match");var i=(0,AS.isOptionalProd)(r),n=t.length>1;if(i&&n){var s=jt.drop(t);return e.concat(Xh(s))}else return e}Mt.getFirstNoneTerminal=Xh;var uS=function(t){aS(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.alternations=[],r}return e.prototype.visitAlternation=function(r){this.alternations.push(r)},e}(lS.GAstVisitor);function uj(t,e){var r=new uS;t.accept(r);var i=r.alternations,n=jt.reduce(i,function(s,o){var a=jt.dropRight(o.definition),l=jt.map(a,function(c,u){var g=(0,rye.nextPossibleTokensAfter)([c],[],null,1);return jt.isEmpty(g)?{message:e.buildEmptyAlternationError({topLevelRule:t,alternation:o,emptyChoiceIdx:u}),type:uo.ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,ruleName:t.name,occurrence:o.idx,alternative:u+1}:null});return s.concat(jt.compact(l))},[]);return n}Mt.validateEmptyOrAlternative=uj;function gj(t,e,r){var i=new uS;t.accept(i);var n=i.alternations;n=(0,Cr.reject)(n,function(o){return o.ignoreAmbiguities===!0});var s=jt.reduce(n,function(o,a){var l=a.idx,c=a.maxLookahead||e,u=(0,Qu.getLookaheadPathsForOr)(l,t,c,a),g=aye(u,a,t,r),f=mj(u,a,t,r);return o.concat(g,f)},[]);return s}Mt.validateAmbiguousAlternationAlternatives=gj;var Ej=function(t){aS(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.allProductions=[],r}return e.prototype.visitRepetitionWithSeparator=function(r){this.allProductions.push(r)},e.prototype.visitRepetitionMandatory=function(r){this.allProductions.push(r)},e.prototype.visitRepetitionMandatoryWithSeparator=function(r){this.allProductions.push(r)},e.prototype.visitRepetition=function(r){this.allProductions.push(r)},e}(lS.GAstVisitor);Mt.RepetionCollector=Ej;function fj(t,e){var r=new uS;t.accept(r);var i=r.alternations,n=jt.reduce(i,function(s,o){return o.definition.length>255&&s.push({message:e.buildTooManyAlternativesError({topLevelRule:t,alternation:o}),type:uo.ParserDefinitionErrorType.TOO_MANY_ALTS,ruleName:t.name,occurrence:o.idx}),s},[]);return n}Mt.validateTooManyAlts=fj;function hj(t,e,r){var i=[];return(0,Cr.forEach)(t,function(n){var s=new Ej;n.accept(s);var o=s.allProductions;(0,Cr.forEach)(o,function(a){var l=(0,Qu.getProdType)(a),c=a.maxLookahead||e,u=a.idx,g=(0,Qu.getLookaheadPathsForOptionalProd)(u,n,l,c),f=g[0];if((0,Cr.isEmpty)((0,Cr.flatten)(f))){var h=r.buildEmptyRepetitionError({topLevelRule:n,repetition:a});i.push({message:h,type:uo.ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,ruleName:n.name})}})}),i}Mt.validateSomeNonEmptyLookaheadPath=hj;function aye(t,e,r,i){var n=[],s=(0,Cr.reduce)(t,function(a,l,c){return e.definition[c].ignoreAmbiguities===!0||(0,Cr.forEach)(l,function(u){var g=[c];(0,Cr.forEach)(t,function(f,h){c!==h&&(0,Qu.containsPath)(f,u)&&e.definition[h].ignoreAmbiguities!==!0&&g.push(h)}),g.length>1&&!(0,Qu.containsPath)(n,u)&&(n.push(u),a.push({alts:g,path:u}))}),a},[]),o=jt.map(s,function(a){var l=(0,Cr.map)(a.alts,function(u){return u+1}),c=i.buildAlternationAmbiguityError({topLevelRule:r,alternation:e,ambiguityIndices:l,prefixPath:a.path});return{message:c,type:uo.ParserDefinitionErrorType.AMBIGUOUS_ALTS,ruleName:r.name,occurrence:e.idx,alternatives:[a.alts]}});return o}function mj(t,e,r,i){var n=[],s=(0,Cr.reduce)(t,function(o,a,l){var c=(0,Cr.map)(a,function(u){return{idx:l,path:u}});return o.concat(c)},[]);return(0,Cr.forEach)(s,function(o){var a=e.definition[o.idx];if(a.ignoreAmbiguities!==!0){var l=o.idx,c=o.path,u=(0,Cr.findAll)(s,function(f){return e.definition[f.idx].ignoreAmbiguities!==!0&&f.idx{"use strict";Object.defineProperty(bu,"__esModule",{value:!0});bu.validateGrammar=bu.resolveGrammar=void 0;var fS=Dt(),Aye=$G(),lye=gS(),Ij=Wh();function cye(t){t=(0,fS.defaults)(t,{errMsgProvider:Ij.defaultGrammarResolverErrorProvider});var e={};return(0,fS.forEach)(t.rules,function(r){e[r.name]=r}),(0,Aye.resolveGrammar)(e,t.errMsgProvider)}bu.resolveGrammar=cye;function uye(t){return t=(0,fS.defaults)(t,{errMsgProvider:Ij.defaultGrammarValidatorErrorProvider}),(0,lye.validateGrammar)(t.rules,t.maxLookahead,t.tokenTypes,t.errMsgProvider,t.grammarName)}bu.validateGrammar=uye});var vu=E(dn=>{"use strict";var Zh=dn&&dn.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(dn,"__esModule",{value:!0});dn.EarlyExitException=dn.NotAllInputParsedException=dn.NoViableAltException=dn.MismatchedTokenException=dn.isRecognitionException=void 0;var gye=Dt(),wj="MismatchedTokenException",Bj="NoViableAltException",Qj="EarlyExitException",bj="NotAllInputParsedException",vj=[wj,Bj,Qj,bj];Object.freeze(vj);function fye(t){return(0,gye.contains)(vj,t.name)}dn.isRecognitionException=fye;var vI=function(t){Zh(e,t);function e(r,i){var n=this.constructor,s=t.call(this,r)||this;return s.token=i,s.resyncedTokens=[],Object.setPrototypeOf(s,n.prototype),Error.captureStackTrace&&Error.captureStackTrace(s,s.constructor),s}return e}(Error),hye=function(t){Zh(e,t);function e(r,i,n){var s=t.call(this,r,i)||this;return s.previousToken=n,s.name=wj,s}return e}(vI);dn.MismatchedTokenException=hye;var pye=function(t){Zh(e,t);function e(r,i,n){var s=t.call(this,r,i)||this;return s.previousToken=n,s.name=Bj,s}return e}(vI);dn.NoViableAltException=pye;var dye=function(t){Zh(e,t);function e(r,i){var n=t.call(this,r,i)||this;return n.name=bj,n}return e}(vI);dn.NotAllInputParsedException=dye;var Cye=function(t){Zh(e,t);function e(r,i,n){var s=t.call(this,r,i)||this;return s.previousToken=n,s.name=Qj,s}return e}(vI);dn.EarlyExitException=Cye});var pS=E(xi=>{"use strict";Object.defineProperty(xi,"__esModule",{value:!0});xi.attemptInRepetitionRecovery=xi.Recoverable=xi.InRuleRecoveryException=xi.IN_RULE_RECOVERY_EXCEPTION=xi.EOF_FOLLOW_KEY=void 0;var SI=nA(),ts=Dt(),mye=vu(),Eye=rS(),Iye=Tn();xi.EOF_FOLLOW_KEY={};xi.IN_RULE_RECOVERY_EXCEPTION="InRuleRecoveryException";function hS(t){this.name=xi.IN_RULE_RECOVERY_EXCEPTION,this.message=t}xi.InRuleRecoveryException=hS;hS.prototype=Error.prototype;var yye=function(){function t(){}return t.prototype.initRecoverable=function(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,ts.has)(e,"recoveryEnabled")?e.recoveryEnabled:Iye.DEFAULT_PARSER_CONFIG.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=Sj)},t.prototype.getTokenToInsert=function(e){var r=(0,SI.createTokenInstance)(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return r.isInsertedInRecovery=!0,r},t.prototype.canTokenTypeBeInsertedInRecovery=function(e){return!0},t.prototype.tryInRepetitionRecovery=function(e,r,i,n){for(var s=this,o=this.findReSyncTokenType(),a=this.exportLexerState(),l=[],c=!1,u=this.LA(1),g=this.LA(1),f=function(){var h=s.LA(0),p=s.errorMessageProvider.buildMismatchTokenMessage({expected:n,actual:u,previous:h,ruleName:s.getCurrRuleFullName()}),d=new mye.MismatchedTokenException(p,u,s.LA(0));d.resyncedTokens=(0,ts.dropRight)(l),s.SAVE_ERROR(d)};!c;)if(this.tokenMatcher(g,n)){f();return}else if(i.call(this)){f(),e.apply(this,r);return}else this.tokenMatcher(g,o)?c=!0:(g=this.SKIP_TOKEN(),this.addToResyncTokens(g,l));this.importLexerState(a)},t.prototype.shouldInRepetitionRecoveryBeTried=function(e,r,i){return!(i===!1||e===void 0||r===void 0||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,r)))},t.prototype.getFollowsForInRuleRecovery=function(e,r){var i=this.getCurrentGrammarPath(e,r),n=this.getNextPossibleTokenTypes(i);return n},t.prototype.tryInRuleRecovery=function(e,r){if(this.canRecoverWithSingleTokenInsertion(e,r)){var i=this.getTokenToInsert(e);return i}if(this.canRecoverWithSingleTokenDeletion(e)){var n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new hS("sad sad panda")},t.prototype.canPerformInRuleRecovery=function(e,r){return this.canRecoverWithSingleTokenInsertion(e,r)||this.canRecoverWithSingleTokenDeletion(e)},t.prototype.canRecoverWithSingleTokenInsertion=function(e,r){var i=this;if(!this.canTokenTypeBeInsertedInRecovery(e)||(0,ts.isEmpty)(r))return!1;var n=this.LA(1),s=(0,ts.find)(r,function(o){return i.tokenMatcher(n,o)})!==void 0;return s},t.prototype.canRecoverWithSingleTokenDeletion=function(e){var r=this.tokenMatcher(this.LA(2),e);return r},t.prototype.isInCurrentRuleReSyncSet=function(e){var r=this.getCurrFollowKey(),i=this.getFollowSetFromFollowKey(r);return(0,ts.contains)(i,e)},t.prototype.findReSyncTokenType=function(){for(var e=this.flattenFollowSet(),r=this.LA(1),i=2;;){var n=r.tokenType;if((0,ts.contains)(e,n))return n;r=this.LA(i),i++}},t.prototype.getCurrFollowKey=function(){if(this.RULE_STACK.length===1)return xi.EOF_FOLLOW_KEY;var e=this.getLastExplicitRuleShortName(),r=this.getLastExplicitRuleOccurrenceIndex(),i=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:r,inRule:this.shortRuleNameToFullName(i)}},t.prototype.buildFullFollowKeyStack=function(){var e=this,r=this.RULE_STACK,i=this.RULE_OCCURRENCE_STACK;return(0,ts.map)(r,function(n,s){return s===0?xi.EOF_FOLLOW_KEY:{ruleName:e.shortRuleNameToFullName(n),idxInCallingRule:i[s],inRule:e.shortRuleNameToFullName(r[s-1])}})},t.prototype.flattenFollowSet=function(){var e=this,r=(0,ts.map)(this.buildFullFollowKeyStack(),function(i){return e.getFollowSetFromFollowKey(i)});return(0,ts.flatten)(r)},t.prototype.getFollowSetFromFollowKey=function(e){if(e===xi.EOF_FOLLOW_KEY)return[SI.EOF];var r=e.ruleName+e.idxInCallingRule+Eye.IN+e.inRule;return this.resyncFollows[r]},t.prototype.addToResyncTokens=function(e,r){return this.tokenMatcher(e,SI.EOF)||r.push(e),r},t.prototype.reSyncTo=function(e){for(var r=[],i=this.LA(1);this.tokenMatcher(i,e)===!1;)i=this.SKIP_TOKEN(),this.addToResyncTokens(i,r);return(0,ts.dropRight)(r)},t.prototype.attemptInRepetitionRecovery=function(e,r,i,n,s,o,a){},t.prototype.getCurrentGrammarPath=function(e,r){var i=this.getHumanReadableRuleStack(),n=(0,ts.cloneArr)(this.RULE_OCCURRENCE_STACK),s={ruleStack:i,occurrenceStack:n,lastTok:e,lastTokOccurrence:r};return s},t.prototype.getHumanReadableRuleStack=function(){var e=this;return(0,ts.map)(this.RULE_STACK,function(r){return e.shortRuleNameToFullName(r)})},t}();xi.Recoverable=yye;function Sj(t,e,r,i,n,s,o){var a=this.getKeyForAutomaticLookahead(i,n),l=this.firstAfterRepMap[a];if(l===void 0){var c=this.getCurrRuleFullName(),u=this.getGAstProductions()[c],g=new s(u,n);l=g.startWalking(),this.firstAfterRepMap[a]=l}var f=l.token,h=l.occurrence,p=l.isEndOfRule;this.RULE_STACK.length===1&&p&&f===void 0&&(f=SI.EOF,h=1),this.shouldInRepetitionRecoveryBeTried(f,h,o)&&this.tryInRepetitionRecovery(t,e,r,f)}xi.attemptInRepetitionRecovery=Sj});var xI=E(Nt=>{"use strict";Object.defineProperty(Nt,"__esModule",{value:!0});Nt.getKeyForAutomaticLookahead=Nt.AT_LEAST_ONE_SEP_IDX=Nt.MANY_SEP_IDX=Nt.AT_LEAST_ONE_IDX=Nt.MANY_IDX=Nt.OPTION_IDX=Nt.OR_IDX=Nt.BITS_FOR_ALT_IDX=Nt.BITS_FOR_RULE_IDX=Nt.BITS_FOR_OCCURRENCE_IDX=Nt.BITS_FOR_METHOD_TYPE=void 0;Nt.BITS_FOR_METHOD_TYPE=4;Nt.BITS_FOR_OCCURRENCE_IDX=8;Nt.BITS_FOR_RULE_IDX=12;Nt.BITS_FOR_ALT_IDX=8;Nt.OR_IDX=1<{"use strict";Object.defineProperty(kI,"__esModule",{value:!0});kI.LooksAhead=void 0;var Aa=_h(),Ns=Dt(),xj=Tn(),la=xI(),Nl=Jh(),Bye=function(){function t(){}return t.prototype.initLooksAhead=function(e){this.dynamicTokensEnabled=(0,Ns.has)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:xj.DEFAULT_PARSER_CONFIG.dynamicTokensEnabled,this.maxLookahead=(0,Ns.has)(e,"maxLookahead")?e.maxLookahead:xj.DEFAULT_PARSER_CONFIG.maxLookahead,this.lookAheadFuncsCache=(0,Ns.isES2015MapSupported)()?new Map:[],(0,Ns.isES2015MapSupported)()?(this.getLaFuncFromCache=this.getLaFuncFromMap,this.setLaFuncCache=this.setLaFuncCacheUsingMap):(this.getLaFuncFromCache=this.getLaFuncFromObj,this.setLaFuncCache=this.setLaFuncUsingObj)},t.prototype.preComputeLookaheadFunctions=function(e){var r=this;(0,Ns.forEach)(e,function(i){r.TRACE_INIT(i.name+" Rule Lookahead",function(){var n=(0,Nl.collectMethods)(i),s=n.alternation,o=n.repetition,a=n.option,l=n.repetitionMandatory,c=n.repetitionMandatoryWithSeparator,u=n.repetitionWithSeparator;(0,Ns.forEach)(s,function(g){var f=g.idx===0?"":g.idx;r.TRACE_INIT(""+(0,Nl.getProductionDslName)(g)+f,function(){var h=(0,Aa.buildLookaheadFuncForOr)(g.idx,i,g.maxLookahead||r.maxLookahead,g.hasPredicates,r.dynamicTokensEnabled,r.lookAheadBuilderForAlternatives),p=(0,la.getKeyForAutomaticLookahead)(r.fullRuleNameToShort[i.name],la.OR_IDX,g.idx);r.setLaFuncCache(p,h)})}),(0,Ns.forEach)(o,function(g){r.computeLookaheadFunc(i,g.idx,la.MANY_IDX,Aa.PROD_TYPE.REPETITION,g.maxLookahead,(0,Nl.getProductionDslName)(g))}),(0,Ns.forEach)(a,function(g){r.computeLookaheadFunc(i,g.idx,la.OPTION_IDX,Aa.PROD_TYPE.OPTION,g.maxLookahead,(0,Nl.getProductionDslName)(g))}),(0,Ns.forEach)(l,function(g){r.computeLookaheadFunc(i,g.idx,la.AT_LEAST_ONE_IDX,Aa.PROD_TYPE.REPETITION_MANDATORY,g.maxLookahead,(0,Nl.getProductionDslName)(g))}),(0,Ns.forEach)(c,function(g){r.computeLookaheadFunc(i,g.idx,la.AT_LEAST_ONE_SEP_IDX,Aa.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,g.maxLookahead,(0,Nl.getProductionDslName)(g))}),(0,Ns.forEach)(u,function(g){r.computeLookaheadFunc(i,g.idx,la.MANY_SEP_IDX,Aa.PROD_TYPE.REPETITION_WITH_SEPARATOR,g.maxLookahead,(0,Nl.getProductionDslName)(g))})})})},t.prototype.computeLookaheadFunc=function(e,r,i,n,s,o){var a=this;this.TRACE_INIT(""+o+(r===0?"":r),function(){var l=(0,Aa.buildLookaheadFuncForOptionalProd)(r,e,s||a.maxLookahead,a.dynamicTokensEnabled,n,a.lookAheadBuilderForOptional),c=(0,la.getKeyForAutomaticLookahead)(a.fullRuleNameToShort[e.name],i,r);a.setLaFuncCache(c,l)})},t.prototype.lookAheadBuilderForOptional=function(e,r,i){return(0,Aa.buildSingleAlternativeLookaheadFunction)(e,r,i)},t.prototype.lookAheadBuilderForAlternatives=function(e,r,i,n){return(0,Aa.buildAlternativesLookAheadFunc)(e,r,i,n)},t.prototype.getKeyForAutomaticLookahead=function(e,r){var i=this.getLastExplicitRuleShortName();return(0,la.getKeyForAutomaticLookahead)(i,e,r)},t.prototype.getLaFuncFromCache=function(e){},t.prototype.getLaFuncFromMap=function(e){return this.lookAheadFuncsCache.get(e)},t.prototype.getLaFuncFromObj=function(e){return this.lookAheadFuncsCache[e]},t.prototype.setLaFuncCache=function(e,r){},t.prototype.setLaFuncCacheUsingMap=function(e,r){this.lookAheadFuncsCache.set(e,r)},t.prototype.setLaFuncUsingObj=function(e,r){this.lookAheadFuncsCache[e]=r},t}();kI.LooksAhead=Bye});var Pj=E(go=>{"use strict";Object.defineProperty(go,"__esModule",{value:!0});go.addNoneTerminalToCst=go.addTerminalToCst=go.setNodeLocationFull=go.setNodeLocationOnlyOffset=void 0;function Qye(t,e){isNaN(t.startOffset)===!0?(t.startOffset=e.startOffset,t.endOffset=e.endOffset):t.endOffset{"use strict";Object.defineProperty(aA,"__esModule",{value:!0});aA.defineNameProp=aA.functionName=aA.classNameFromInstance=void 0;var xye=Dt();function kye(t){return Dj(t.constructor)}aA.classNameFromInstance=kye;var Rj="name";function Dj(t){var e=t.name;return e||"anonymous"}aA.functionName=Dj;function Pye(t,e){var r=Object.getOwnPropertyDescriptor(t,Rj);return(0,xye.isUndefined)(r)||r.configurable?(Object.defineProperty(t,Rj,{enumerable:!1,configurable:!0,writable:!1,value:e}),!0):!1}aA.defineNameProp=Pye});var Mj=E(mi=>{"use strict";Object.defineProperty(mi,"__esModule",{value:!0});mi.validateRedundantMethods=mi.validateMissingCstMethods=mi.validateVisitor=mi.CstVisitorDefinitionError=mi.createBaseVisitorConstructorWithDefaults=mi.createBaseSemanticVisitorConstructor=mi.defaultVisit=void 0;var rs=Dt(),$h=dS();function Fj(t,e){for(var r=(0,rs.keys)(t),i=r.length,n=0;n: + `+(""+s.join(` + +`).replace(/\n/g,` + `)))}}};return r.prototype=i,r.prototype.constructor=r,r._RULE_NAMES=e,r}mi.createBaseSemanticVisitorConstructor=Dye;function Rye(t,e,r){var i=function(){};(0,$h.defineNameProp)(i,t+"BaseSemanticsWithDefaults");var n=Object.create(r.prototype);return(0,rs.forEach)(e,function(s){n[s]=Fj}),i.prototype=n,i.prototype.constructor=i,i}mi.createBaseVisitorConstructorWithDefaults=Rye;var CS;(function(t){t[t.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",t[t.MISSING_METHOD=1]="MISSING_METHOD"})(CS=mi.CstVisitorDefinitionError||(mi.CstVisitorDefinitionError={}));function Nj(t,e){var r=Lj(t,e),i=Tj(t,e);return r.concat(i)}mi.validateVisitor=Nj;function Lj(t,e){var r=(0,rs.map)(e,function(i){if(!(0,rs.isFunction)(t[i]))return{msg:"Missing visitor method: <"+i+"> on "+(0,$h.functionName)(t.constructor)+" CST Visitor.",type:CS.MISSING_METHOD,methodName:i}});return(0,rs.compact)(r)}mi.validateMissingCstMethods=Lj;var Fye=["constructor","visit","validateVisitor"];function Tj(t,e){var r=[];for(var i in t)(0,rs.isFunction)(t[i])&&!(0,rs.contains)(Fye,i)&&!(0,rs.contains)(e,i)&&r.push({msg:"Redundant visitor method: <"+i+"> on "+(0,$h.functionName)(t.constructor)+` CST Visitor +There is no Grammar Rule corresponding to this method's name. +`,type:CS.REDUNDANT_METHOD,methodName:i});return r}mi.validateRedundantMethods=Tj});var Kj=E(PI=>{"use strict";Object.defineProperty(PI,"__esModule",{value:!0});PI.TreeBuilder=void 0;var Su=Pj(),Ur=Dt(),Oj=Mj(),Nye=Tn(),Lye=function(){function t(){}return t.prototype.initTreeBuilder=function(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,Ur.has)(e,"nodeLocationTracking")?e.nodeLocationTracking:Nye.DEFAULT_PARSER_CONFIG.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=Ur.NOOP,this.cstFinallyStateUpdate=Ur.NOOP,this.cstPostTerminal=Ur.NOOP,this.cstPostNonTerminal=Ur.NOOP,this.cstPostRule=Ur.NOOP;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=Su.setNodeLocationFull,this.setNodeLocationFromNode=Su.setNodeLocationFull,this.cstPostRule=Ur.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=Ur.NOOP,this.setNodeLocationFromNode=Ur.NOOP,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=Su.setNodeLocationOnlyOffset,this.setNodeLocationFromNode=Su.setNodeLocationOnlyOffset,this.cstPostRule=Ur.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=Ur.NOOP,this.setNodeLocationFromNode=Ur.NOOP,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=Ur.NOOP,this.setNodeLocationFromNode=Ur.NOOP,this.cstPostRule=Ur.NOOP,this.setInitialNodeLocation=Ur.NOOP;else throw Error('Invalid config option: "'+e.nodeLocationTracking+'"')},t.prototype.setInitialNodeLocationOnlyOffsetRecovery=function(e){e.location={startOffset:NaN,endOffset:NaN}},t.prototype.setInitialNodeLocationOnlyOffsetRegular=function(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}},t.prototype.setInitialNodeLocationFullRecovery=function(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}},t.prototype.setInitialNodeLocationFullRegular=function(e){var r=this.LA(1);e.location={startOffset:r.startOffset,startLine:r.startLine,startColumn:r.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}},t.prototype.cstInvocationStateUpdate=function(e,r){var i={name:e,children:{}};this.setInitialNodeLocation(i),this.CST_STACK.push(i)},t.prototype.cstFinallyStateUpdate=function(){this.CST_STACK.pop()},t.prototype.cstPostRuleFull=function(e){var r=this.LA(0),i=e.location;i.startOffset<=r.startOffset?(i.endOffset=r.endOffset,i.endLine=r.endLine,i.endColumn=r.endColumn):(i.startOffset=NaN,i.startLine=NaN,i.startColumn=NaN)},t.prototype.cstPostRuleOnlyOffset=function(e){var r=this.LA(0),i=e.location;i.startOffset<=r.startOffset?i.endOffset=r.endOffset:i.startOffset=NaN},t.prototype.cstPostTerminal=function(e,r){var i=this.CST_STACK[this.CST_STACK.length-1];(0,Su.addTerminalToCst)(i,r,e),this.setNodeLocationFromToken(i.location,r)},t.prototype.cstPostNonTerminal=function(e,r){var i=this.CST_STACK[this.CST_STACK.length-1];(0,Su.addNoneTerminalToCst)(i,r,e),this.setNodeLocationFromNode(i.location,e.location)},t.prototype.getBaseCstVisitorConstructor=function(){if((0,Ur.isUndefined)(this.baseCstVisitorConstructor)){var e=(0,Oj.createBaseSemanticVisitorConstructor)(this.className,(0,Ur.keys)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor},t.prototype.getBaseCstVisitorConstructorWithDefaults=function(){if((0,Ur.isUndefined)(this.baseCstVisitorWithDefaultsConstructor)){var e=(0,Oj.createBaseVisitorConstructorWithDefaults)(this.className,(0,Ur.keys)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor},t.prototype.getLastExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-1]},t.prototype.getPreviousExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-2]},t.prototype.getLastExplicitRuleOccurrenceIndex=function(){var e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]},t}();PI.TreeBuilder=Lye});var Hj=E(DI=>{"use strict";Object.defineProperty(DI,"__esModule",{value:!0});DI.LexerAdapter=void 0;var Uj=Tn(),Tye=function(){function t(){}return t.prototype.initLexerAdapter=function(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1},Object.defineProperty(t.prototype,"input",{get:function(){return this.tokVector},set:function(e){if(this.selfAnalysisDone!==!0)throw Error("Missing invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length},enumerable:!1,configurable:!0}),t.prototype.SKIP_TOKEN=function(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):Uj.END_OF_FILE},t.prototype.LA=function(e){var r=this.currIdx+e;return r<0||this.tokVectorLength<=r?Uj.END_OF_FILE:this.tokVector[r]},t.prototype.consumeToken=function(){this.currIdx++},t.prototype.exportLexerState=function(){return this.currIdx},t.prototype.importLexerState=function(e){this.currIdx=e},t.prototype.resetLexerState=function(){this.currIdx=-1},t.prototype.moveToTerminatedState=function(){this.currIdx=this.tokVector.length-1},t.prototype.getLexerPosition=function(){return this.exportLexerState()},t}();DI.LexerAdapter=Tye});var jj=E(RI=>{"use strict";Object.defineProperty(RI,"__esModule",{value:!0});RI.RecognizerApi=void 0;var Gj=Dt(),Mye=vu(),mS=Tn(),Oye=Wh(),Kye=gS(),Uye=hn(),Hye=function(){function t(){}return t.prototype.ACTION=function(e){return e.call(this)},t.prototype.consume=function(e,r,i){return this.consumeInternal(r,e,i)},t.prototype.subrule=function(e,r,i){return this.subruleInternal(r,e,i)},t.prototype.option=function(e,r){return this.optionInternal(r,e)},t.prototype.or=function(e,r){return this.orInternal(r,e)},t.prototype.many=function(e,r){return this.manyInternal(e,r)},t.prototype.atLeastOne=function(e,r){return this.atLeastOneInternal(e,r)},t.prototype.CONSUME=function(e,r){return this.consumeInternal(e,0,r)},t.prototype.CONSUME1=function(e,r){return this.consumeInternal(e,1,r)},t.prototype.CONSUME2=function(e,r){return this.consumeInternal(e,2,r)},t.prototype.CONSUME3=function(e,r){return this.consumeInternal(e,3,r)},t.prototype.CONSUME4=function(e,r){return this.consumeInternal(e,4,r)},t.prototype.CONSUME5=function(e,r){return this.consumeInternal(e,5,r)},t.prototype.CONSUME6=function(e,r){return this.consumeInternal(e,6,r)},t.prototype.CONSUME7=function(e,r){return this.consumeInternal(e,7,r)},t.prototype.CONSUME8=function(e,r){return this.consumeInternal(e,8,r)},t.prototype.CONSUME9=function(e,r){return this.consumeInternal(e,9,r)},t.prototype.SUBRULE=function(e,r){return this.subruleInternal(e,0,r)},t.prototype.SUBRULE1=function(e,r){return this.subruleInternal(e,1,r)},t.prototype.SUBRULE2=function(e,r){return this.subruleInternal(e,2,r)},t.prototype.SUBRULE3=function(e,r){return this.subruleInternal(e,3,r)},t.prototype.SUBRULE4=function(e,r){return this.subruleInternal(e,4,r)},t.prototype.SUBRULE5=function(e,r){return this.subruleInternal(e,5,r)},t.prototype.SUBRULE6=function(e,r){return this.subruleInternal(e,6,r)},t.prototype.SUBRULE7=function(e,r){return this.subruleInternal(e,7,r)},t.prototype.SUBRULE8=function(e,r){return this.subruleInternal(e,8,r)},t.prototype.SUBRULE9=function(e,r){return this.subruleInternal(e,9,r)},t.prototype.OPTION=function(e){return this.optionInternal(e,0)},t.prototype.OPTION1=function(e){return this.optionInternal(e,1)},t.prototype.OPTION2=function(e){return this.optionInternal(e,2)},t.prototype.OPTION3=function(e){return this.optionInternal(e,3)},t.prototype.OPTION4=function(e){return this.optionInternal(e,4)},t.prototype.OPTION5=function(e){return this.optionInternal(e,5)},t.prototype.OPTION6=function(e){return this.optionInternal(e,6)},t.prototype.OPTION7=function(e){return this.optionInternal(e,7)},t.prototype.OPTION8=function(e){return this.optionInternal(e,8)},t.prototype.OPTION9=function(e){return this.optionInternal(e,9)},t.prototype.OR=function(e){return this.orInternal(e,0)},t.prototype.OR1=function(e){return this.orInternal(e,1)},t.prototype.OR2=function(e){return this.orInternal(e,2)},t.prototype.OR3=function(e){return this.orInternal(e,3)},t.prototype.OR4=function(e){return this.orInternal(e,4)},t.prototype.OR5=function(e){return this.orInternal(e,5)},t.prototype.OR6=function(e){return this.orInternal(e,6)},t.prototype.OR7=function(e){return this.orInternal(e,7)},t.prototype.OR8=function(e){return this.orInternal(e,8)},t.prototype.OR9=function(e){return this.orInternal(e,9)},t.prototype.MANY=function(e){this.manyInternal(0,e)},t.prototype.MANY1=function(e){this.manyInternal(1,e)},t.prototype.MANY2=function(e){this.manyInternal(2,e)},t.prototype.MANY3=function(e){this.manyInternal(3,e)},t.prototype.MANY4=function(e){this.manyInternal(4,e)},t.prototype.MANY5=function(e){this.manyInternal(5,e)},t.prototype.MANY6=function(e){this.manyInternal(6,e)},t.prototype.MANY7=function(e){this.manyInternal(7,e)},t.prototype.MANY8=function(e){this.manyInternal(8,e)},t.prototype.MANY9=function(e){this.manyInternal(9,e)},t.prototype.MANY_SEP=function(e){this.manySepFirstInternal(0,e)},t.prototype.MANY_SEP1=function(e){this.manySepFirstInternal(1,e)},t.prototype.MANY_SEP2=function(e){this.manySepFirstInternal(2,e)},t.prototype.MANY_SEP3=function(e){this.manySepFirstInternal(3,e)},t.prototype.MANY_SEP4=function(e){this.manySepFirstInternal(4,e)},t.prototype.MANY_SEP5=function(e){this.manySepFirstInternal(5,e)},t.prototype.MANY_SEP6=function(e){this.manySepFirstInternal(6,e)},t.prototype.MANY_SEP7=function(e){this.manySepFirstInternal(7,e)},t.prototype.MANY_SEP8=function(e){this.manySepFirstInternal(8,e)},t.prototype.MANY_SEP9=function(e){this.manySepFirstInternal(9,e)},t.prototype.AT_LEAST_ONE=function(e){this.atLeastOneInternal(0,e)},t.prototype.AT_LEAST_ONE1=function(e){return this.atLeastOneInternal(1,e)},t.prototype.AT_LEAST_ONE2=function(e){this.atLeastOneInternal(2,e)},t.prototype.AT_LEAST_ONE3=function(e){this.atLeastOneInternal(3,e)},t.prototype.AT_LEAST_ONE4=function(e){this.atLeastOneInternal(4,e)},t.prototype.AT_LEAST_ONE5=function(e){this.atLeastOneInternal(5,e)},t.prototype.AT_LEAST_ONE6=function(e){this.atLeastOneInternal(6,e)},t.prototype.AT_LEAST_ONE7=function(e){this.atLeastOneInternal(7,e)},t.prototype.AT_LEAST_ONE8=function(e){this.atLeastOneInternal(8,e)},t.prototype.AT_LEAST_ONE9=function(e){this.atLeastOneInternal(9,e)},t.prototype.AT_LEAST_ONE_SEP=function(e){this.atLeastOneSepFirstInternal(0,e)},t.prototype.AT_LEAST_ONE_SEP1=function(e){this.atLeastOneSepFirstInternal(1,e)},t.prototype.AT_LEAST_ONE_SEP2=function(e){this.atLeastOneSepFirstInternal(2,e)},t.prototype.AT_LEAST_ONE_SEP3=function(e){this.atLeastOneSepFirstInternal(3,e)},t.prototype.AT_LEAST_ONE_SEP4=function(e){this.atLeastOneSepFirstInternal(4,e)},t.prototype.AT_LEAST_ONE_SEP5=function(e){this.atLeastOneSepFirstInternal(5,e)},t.prototype.AT_LEAST_ONE_SEP6=function(e){this.atLeastOneSepFirstInternal(6,e)},t.prototype.AT_LEAST_ONE_SEP7=function(e){this.atLeastOneSepFirstInternal(7,e)},t.prototype.AT_LEAST_ONE_SEP8=function(e){this.atLeastOneSepFirstInternal(8,e)},t.prototype.AT_LEAST_ONE_SEP9=function(e){this.atLeastOneSepFirstInternal(9,e)},t.prototype.RULE=function(e,r,i){if(i===void 0&&(i=mS.DEFAULT_RULE_CONFIG),(0,Gj.contains)(this.definedRulesNames,e)){var n=Oye.defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),s={message:n,type:mS.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);var o=this.defineRule(e,r,i);return this[e]=o,o},t.prototype.OVERRIDE_RULE=function(e,r,i){i===void 0&&(i=mS.DEFAULT_RULE_CONFIG);var n=[];n=n.concat((0,Kye.validateRuleIsOverridden)(e,this.definedRulesNames,this.className)),this.definitionErrors=this.definitionErrors.concat(n);var s=this.defineRule(e,r,i);return this[e]=s,s},t.prototype.BACKTRACK=function(e,r){return function(){this.isBackTrackingStack.push(1);var i=this.saveRecogState();try{return e.apply(this,r),!0}catch(n){if((0,Mye.isRecognitionException)(n))return!1;throw n}finally{this.reloadRecogState(i),this.isBackTrackingStack.pop()}}},t.prototype.getGAstProductions=function(){return this.gastProductionsCache},t.prototype.getSerializedGastProductions=function(){return(0,Uye.serializeGrammar)((0,Gj.values)(this.gastProductionsCache))},t}();RI.RecognizerApi=Hye});var Wj=E(FI=>{"use strict";Object.defineProperty(FI,"__esModule",{value:!0});FI.RecognizerEngine=void 0;var Er=Dt(),Mn=xI(),NI=vu(),Yj=_h(),xu=Vh(),qj=Tn(),Gye=pS(),Jj=nA(),ep=yu(),jye=dS(),Yye=function(){function t(){}return t.prototype.initRecognizerEngine=function(e,r){if(this.className=(0,jye.classNameFromInstance)(this),this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=ep.tokenStructuredMatcherNoCategories,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,Er.has)(r,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a property. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0 + For Further details.`);if((0,Er.isArray)(e)){if((0,Er.isEmpty)(e))throw Error(`A Token Vocabulary cannot be empty. + Note that the first argument for the parser constructor + is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0 + For Further details.`)}if((0,Er.isArray)(e))this.tokensMap=(0,Er.reduce)(e,function(o,a){return o[a.name]=a,o},{});else if((0,Er.has)(e,"modes")&&(0,Er.every)((0,Er.flatten)((0,Er.values)(e.modes)),ep.isTokenType)){var i=(0,Er.flatten)((0,Er.values)(e.modes)),n=(0,Er.uniq)(i);this.tokensMap=(0,Er.reduce)(n,function(o,a){return o[a.name]=a,o},{})}else if((0,Er.isObject)(e))this.tokensMap=(0,Er.cloneObj)(e);else throw new Error(" argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=Jj.EOF;var s=(0,Er.every)((0,Er.values)(e),function(o){return(0,Er.isEmpty)(o.categoryMatches)});this.tokenMatcher=s?ep.tokenStructuredMatcherNoCategories:ep.tokenStructuredMatcher,(0,ep.augmentTokenTypes)((0,Er.values)(this.tokensMap))},t.prototype.defineRule=function(e,r,i){if(this.selfAnalysisDone)throw Error("Grammar rule <"+e+`> may not be defined after the 'performSelfAnalysis' method has been called' +Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);var n=(0,Er.has)(i,"resyncEnabled")?i.resyncEnabled:qj.DEFAULT_RULE_CONFIG.resyncEnabled,s=(0,Er.has)(i,"recoveryValueFunc")?i.recoveryValueFunc:qj.DEFAULT_RULE_CONFIG.recoveryValueFunc,o=this.ruleShortNameIdx<r},t.prototype.orInternal=function(e,r){var i=this.getKeyForAutomaticLookahead(Mn.OR_IDX,r),n=(0,Er.isArray)(e)?e:e.DEF,s=this.getLaFuncFromCache(i),o=s.call(this,n);if(o!==void 0){var a=n[o];return a.ALT.call(this)}this.raiseNoAltException(r,e.ERR_MSG)},t.prototype.ruleFinallyStateUpdate=function(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){var e=this.LA(1),r=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new NI.NotAllInputParsedException(r,e))}},t.prototype.subruleInternal=function(e,r,i){var n;try{var s=i!==void 0?i.ARGS:void 0;return n=e.call(this,r,s),this.cstPostNonTerminal(n,i!==void 0&&i.LABEL!==void 0?i.LABEL:e.ruleName),n}catch(o){this.subruleInternalError(o,i,e.ruleName)}},t.prototype.subruleInternalError=function(e,r,i){throw(0,NI.isRecognitionException)(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,r!==void 0&&r.LABEL!==void 0?r.LABEL:i),delete e.partialCstResult),e},t.prototype.consumeInternal=function(e,r,i){var n;try{var s=this.LA(1);this.tokenMatcher(s,e)===!0?(this.consumeToken(),n=s):this.consumeInternalError(e,s,i)}catch(o){n=this.consumeInternalRecovery(e,r,o)}return this.cstPostTerminal(i!==void 0&&i.LABEL!==void 0?i.LABEL:e.name,n),n},t.prototype.consumeInternalError=function(e,r,i){var n,s=this.LA(0);throw i!==void 0&&i.ERR_MSG?n=i.ERR_MSG:n=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:r,previous:s,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new NI.MismatchedTokenException(n,r,s))},t.prototype.consumeInternalRecovery=function(e,r,i){if(this.recoveryEnabled&&i.name==="MismatchedTokenException"&&!this.isBackTracking()){var n=this.getFollowsForInRuleRecovery(e,r);try{return this.tryInRuleRecovery(e,n)}catch(s){throw s.name===Gye.IN_RULE_RECOVERY_EXCEPTION?i:s}}else throw i},t.prototype.saveRecogState=function(){var e=this.errors,r=(0,Er.cloneArr)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:r,CST_STACK:this.CST_STACK}},t.prototype.reloadRecogState=function(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK},t.prototype.ruleInvocationStateUpdate=function(e,r,i){this.RULE_OCCURRENCE_STACK.push(i),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(r,e)},t.prototype.isBackTracking=function(){return this.isBackTrackingStack.length!==0},t.prototype.getCurrRuleFullName=function(){var e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]},t.prototype.shortRuleNameToFullName=function(e){return this.shortRuleNameToFull[e]},t.prototype.isAtEndOfInput=function(){return this.tokenMatcher(this.LA(1),Jj.EOF)},t.prototype.reset=function(){this.resetLexerState(),this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]},t}();FI.RecognizerEngine=Yye});var Vj=E(LI=>{"use strict";Object.defineProperty(LI,"__esModule",{value:!0});LI.ErrorHandler=void 0;var ES=vu(),IS=Dt(),zj=_h(),qye=Tn(),Jye=function(){function t(){}return t.prototype.initErrorHandler=function(e){this._errors=[],this.errorMessageProvider=(0,IS.has)(e,"errorMessageProvider")?e.errorMessageProvider:qye.DEFAULT_PARSER_CONFIG.errorMessageProvider},t.prototype.SAVE_ERROR=function(e){if((0,ES.isRecognitionException)(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,IS.cloneArr)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")},Object.defineProperty(t.prototype,"errors",{get:function(){return(0,IS.cloneArr)(this._errors)},set:function(e){this._errors=e},enumerable:!1,configurable:!0}),t.prototype.raiseEarlyExitException=function(e,r,i){for(var n=this.getCurrRuleFullName(),s=this.getGAstProductions()[n],o=(0,zj.getLookaheadPathsForOptionalProd)(e,s,r,this.maxLookahead),a=o[0],l=[],c=1;c<=this.maxLookahead;c++)l.push(this.LA(c));var u=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:a,actual:l,previous:this.LA(0),customUserDescription:i,ruleName:n});throw this.SAVE_ERROR(new ES.EarlyExitException(u,this.LA(1),this.LA(0)))},t.prototype.raiseNoAltException=function(e,r){for(var i=this.getCurrRuleFullName(),n=this.getGAstProductions()[i],s=(0,zj.getLookaheadPathsForOr)(e,n,this.maxLookahead),o=[],a=1;a<=this.maxLookahead;a++)o.push(this.LA(a));var l=this.LA(0),c=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:s,actual:o,previous:l,customUserDescription:r,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new ES.NoViableAltException(c,this.LA(1),l))},t}();LI.ErrorHandler=Jye});var Zj=E(TI=>{"use strict";Object.defineProperty(TI,"__esModule",{value:!0});TI.ContentAssist=void 0;var _j=Vh(),Xj=Dt(),Wye=function(){function t(){}return t.prototype.initContentAssist=function(){},t.prototype.computeContentAssist=function(e,r){var i=this.gastProductionsCache[e];if((0,Xj.isUndefined)(i))throw Error("Rule ->"+e+"<- does not exist in this grammar.");return(0,_j.nextPossibleTokensAfter)([i],r,this.tokenMatcher,this.maxLookahead)},t.prototype.getNextPossibleTokenTypes=function(e){var r=(0,Xj.first)(e.ruleStack),i=this.getGAstProductions(),n=i[r],s=new _j.NextAfterTokenWalker(n,e).startWalking();return s},t}();TI.ContentAssist=Wye});var oY=E(MI=>{"use strict";Object.defineProperty(MI,"__esModule",{value:!0});MI.GastRecorder=void 0;var Cn=Dt(),fo=hn(),zye=Gh(),$j=yu(),eY=nA(),Vye=Tn(),_ye=xI(),OI={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(OI);var tY=!0,rY=Math.pow(2,_ye.BITS_FOR_OCCURRENCE_IDX)-1,iY=(0,eY.createToken)({name:"RECORDING_PHASE_TOKEN",pattern:zye.Lexer.NA});(0,$j.augmentTokenTypes)([iY]);var nY=(0,eY.createTokenInstance)(iY,`This IToken indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze(nY);var Xye={name:`This CSTNode indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},$ye=function(){function t(){}return t.prototype.initGastRecorder=function(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1},t.prototype.enableRecording=function(){var e=this;this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",function(){for(var r=function(n){var s=n>0?n:"";e["CONSUME"+s]=function(o,a){return this.consumeInternalRecord(o,n,a)},e["SUBRULE"+s]=function(o,a){return this.subruleInternalRecord(o,n,a)},e["OPTION"+s]=function(o){return this.optionInternalRecord(o,n)},e["OR"+s]=function(o){return this.orInternalRecord(o,n)},e["MANY"+s]=function(o){this.manyInternalRecord(n,o)},e["MANY_SEP"+s]=function(o){this.manySepFirstInternalRecord(n,o)},e["AT_LEAST_ONE"+s]=function(o){this.atLeastOneInternalRecord(n,o)},e["AT_LEAST_ONE_SEP"+s]=function(o){this.atLeastOneSepFirstInternalRecord(n,o)}},i=0;i<10;i++)r(i);e.consume=function(n,s,o){return this.consumeInternalRecord(s,n,o)},e.subrule=function(n,s,o){return this.subruleInternalRecord(s,n,o)},e.option=function(n,s){return this.optionInternalRecord(s,n)},e.or=function(n,s){return this.orInternalRecord(s,n)},e.many=function(n,s){this.manyInternalRecord(n,s)},e.atLeastOne=function(n,s){this.atLeastOneInternalRecord(n,s)},e.ACTION=e.ACTION_RECORD,e.BACKTRACK=e.BACKTRACK_RECORD,e.LA=e.LA_RECORD})},t.prototype.disableRecording=function(){var e=this;this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",function(){for(var r=0;r<10;r++){var i=r>0?r:"";delete e["CONSUME"+i],delete e["SUBRULE"+i],delete e["OPTION"+i],delete e["OR"+i],delete e["MANY"+i],delete e["MANY_SEP"+i],delete e["AT_LEAST_ONE"+i],delete e["AT_LEAST_ONE_SEP"+i]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})},t.prototype.ACTION_RECORD=function(e){},t.prototype.BACKTRACK_RECORD=function(e,r){return function(){return!0}},t.prototype.LA_RECORD=function(e){return Vye.END_OF_FILE},t.prototype.topLevelRuleRecord=function(e,r){try{var i=new fo.Rule({definition:[],name:e});return i.name=e,this.recordingProdStack.push(i),r.call(this),this.recordingProdStack.pop(),i}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+` + This error was thrown during the "grammar recording phase" For more info see: + https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch(s){throw n}throw n}},t.prototype.optionInternalRecord=function(e,r){return tp.call(this,fo.Option,e,r)},t.prototype.atLeastOneInternalRecord=function(e,r){tp.call(this,fo.RepetitionMandatory,r,e)},t.prototype.atLeastOneSepFirstInternalRecord=function(e,r){tp.call(this,fo.RepetitionMandatoryWithSeparator,r,e,tY)},t.prototype.manyInternalRecord=function(e,r){tp.call(this,fo.Repetition,r,e)},t.prototype.manySepFirstInternalRecord=function(e,r){tp.call(this,fo.RepetitionWithSeparator,r,e,tY)},t.prototype.orInternalRecord=function(e,r){return Zye.call(this,e,r)},t.prototype.subruleInternalRecord=function(e,r,i){if(KI(r),!e||(0,Cn.has)(e,"ruleName")===!1){var n=new Error(" argument is invalid"+(" expecting a Parser method reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,Cn.peek)(this.recordingProdStack),o=e.ruleName,a=new fo.NonTerminal({idx:r,nonTerminalName:o,label:i==null?void 0:i.LABEL,referencedRule:void 0});return s.definition.push(a),this.outputCst?Xye:OI},t.prototype.consumeInternalRecord=function(e,r,i){if(KI(r),!(0,$j.hasShortKeyProperty)(e)){var n=new Error(" argument is invalid"+(" expecting a TokenType reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,Cn.peek)(this.recordingProdStack),o=new fo.Terminal({idx:r,terminalType:e,label:i==null?void 0:i.LABEL});return s.definition.push(o),nY},t}();MI.GastRecorder=$ye;function tp(t,e,r,i){i===void 0&&(i=!1),KI(r);var n=(0,Cn.peek)(this.recordingProdStack),s=(0,Cn.isFunction)(e)?e:e.DEF,o=new t({definition:[],idx:r});return i&&(o.separator=e.SEP),(0,Cn.has)(e,"MAX_LOOKAHEAD")&&(o.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(o),s.call(this),n.definition.push(o),this.recordingProdStack.pop(),OI}function Zye(t,e){var r=this;KI(e);var i=(0,Cn.peek)(this.recordingProdStack),n=(0,Cn.isArray)(t)===!1,s=n===!1?t:t.DEF,o=new fo.Alternation({definition:[],idx:e,ignoreAmbiguities:n&&t.IGNORE_AMBIGUITIES===!0});(0,Cn.has)(t,"MAX_LOOKAHEAD")&&(o.maxLookahead=t.MAX_LOOKAHEAD);var a=(0,Cn.some)(s,function(l){return(0,Cn.isFunction)(l.GATE)});return o.hasPredicates=a,i.definition.push(o),(0,Cn.forEach)(s,function(l){var c=new fo.Alternative({definition:[]});o.definition.push(c),(0,Cn.has)(l,"IGNORE_AMBIGUITIES")?c.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:(0,Cn.has)(l,"GATE")&&(c.ignoreAmbiguities=!0),r.recordingProdStack.push(c),l.ALT.call(r),r.recordingProdStack.pop()}),OI}function sY(t){return t===0?"":""+t}function KI(t){if(t<0||t>rY){var e=new Error("Invalid DSL Method idx value: <"+t+`> + `+("Idx value must be a none negative value smaller than "+(rY+1)));throw e.KNOWN_RECORDER_ERROR=!0,e}}});var AY=E(UI=>{"use strict";Object.defineProperty(UI,"__esModule",{value:!0});UI.PerformanceTracer=void 0;var aY=Dt(),ewe=Tn(),twe=function(){function t(){}return t.prototype.initPerformanceTracer=function(e){if((0,aY.has)(e,"traceInitPerf")){var r=e.traceInitPerf,i=typeof r=="number";this.traceInitMaxIdent=i?r:Infinity,this.traceInitPerf=i?r>0:r}else this.traceInitMaxIdent=0,this.traceInitPerf=ewe.DEFAULT_PARSER_CONFIG.traceInitPerf;this.traceInitIndent=-1},t.prototype.TRACE_INIT=function(e,r){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <"+e+">");var n=(0,aY.timer)(r),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return r()},t}();UI.PerformanceTracer=twe});var lY=E(HI=>{"use strict";Object.defineProperty(HI,"__esModule",{value:!0});HI.applyMixins=void 0;function rwe(t,e){e.forEach(function(r){var i=r.prototype;Object.getOwnPropertyNames(i).forEach(function(n){if(n!=="constructor"){var s=Object.getOwnPropertyDescriptor(i,n);s&&(s.get||s.set)?Object.defineProperty(t.prototype,n,s):t.prototype[n]=r.prototype[n]}})})}HI.applyMixins=rwe});var Tn=E(or=>{"use strict";var cY=or&&or.__extends||function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function i(){this.constructor=e}e.prototype=r===null?Object.create(r):(i.prototype=r.prototype,new i)}}();Object.defineProperty(or,"__esModule",{value:!0});or.EmbeddedActionsParser=or.CstParser=or.Parser=or.EMPTY_ALT=or.ParserDefinitionErrorType=or.DEFAULT_RULE_CONFIG=or.DEFAULT_PARSER_CONFIG=or.END_OF_FILE=void 0;var Wi=Dt(),iwe=VG(),uY=nA(),gY=Wh(),fY=yj(),nwe=pS(),swe=kj(),owe=Kj(),awe=Hj(),Awe=jj(),lwe=Wj(),cwe=Vj(),uwe=Zj(),gwe=oY(),fwe=AY(),hwe=lY();or.END_OF_FILE=(0,uY.createTokenInstance)(uY.EOF,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(or.END_OF_FILE);or.DEFAULT_PARSER_CONFIG=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:gY.defaultParserErrorProvider,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1});or.DEFAULT_RULE_CONFIG=Object.freeze({recoveryValueFunc:function(){},resyncEnabled:!0});var pwe;(function(t){t[t.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",t[t.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",t[t.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",t[t.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",t[t.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",t[t.LEFT_RECURSION=5]="LEFT_RECURSION",t[t.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",t[t.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",t[t.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",t[t.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",t[t.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",t[t.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",t[t.TOO_MANY_ALTS=12]="TOO_MANY_ALTS"})(pwe=or.ParserDefinitionErrorType||(or.ParserDefinitionErrorType={}));function dwe(t){return t===void 0&&(t=void 0),function(){return t}}or.EMPTY_ALT=dwe;var GI=function(){function t(e,r){this.definitionErrors=[],this.selfAnalysisDone=!1;var i=this;if(i.initErrorHandler(r),i.initLexerAdapter(),i.initLooksAhead(r),i.initRecognizerEngine(e,r),i.initRecoverable(r),i.initTreeBuilder(r),i.initContentAssist(),i.initGastRecorder(r),i.initPerformanceTracer(r),(0,Wi.has)(r,"ignoredIssues"))throw new Error(`The IParserConfig property has been deprecated. + Please use the flag on the relevant DSL method instead. + See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES + For further details.`);this.skipValidations=(0,Wi.has)(r,"skipValidations")?r.skipValidations:or.DEFAULT_PARSER_CONFIG.skipValidations}return t.performSelfAnalysis=function(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")},t.prototype.performSelfAnalysis=function(){var e=this;this.TRACE_INIT("performSelfAnalysis",function(){var r;e.selfAnalysisDone=!0;var i=e.className;e.TRACE_INIT("toFastProps",function(){(0,Wi.toFastProperties)(e)}),e.TRACE_INIT("Grammar Recording",function(){try{e.enableRecording(),(0,Wi.forEach)(e.definedRulesNames,function(s){var o=e[s],a=o.originalGrammarAction,l=void 0;e.TRACE_INIT(s+" Rule",function(){l=e.topLevelRuleRecord(s,a)}),e.gastProductionsCache[s]=l})}finally{e.disableRecording()}});var n=[];if(e.TRACE_INIT("Grammar Resolving",function(){n=(0,fY.resolveGrammar)({rules:(0,Wi.values)(e.gastProductionsCache)}),e.definitionErrors=e.definitionErrors.concat(n)}),e.TRACE_INIT("Grammar Validations",function(){if((0,Wi.isEmpty)(n)&&e.skipValidations===!1){var s=(0,fY.validateGrammar)({rules:(0,Wi.values)(e.gastProductionsCache),maxLookahead:e.maxLookahead,tokenTypes:(0,Wi.values)(e.tokensMap),errMsgProvider:gY.defaultGrammarValidatorErrorProvider,grammarName:i});e.definitionErrors=e.definitionErrors.concat(s)}}),(0,Wi.isEmpty)(e.definitionErrors)&&(e.recoveryEnabled&&e.TRACE_INIT("computeAllProdsFollows",function(){var s=(0,iwe.computeAllProdsFollows)((0,Wi.values)(e.gastProductionsCache));e.resyncFollows=s}),e.TRACE_INIT("ComputeLookaheadFunctions",function(){e.preComputeLookaheadFunctions((0,Wi.values)(e.gastProductionsCache))})),!t.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,Wi.isEmpty)(e.definitionErrors))throw r=(0,Wi.map)(e.definitionErrors,function(s){return s.message}),new Error(`Parser Definition Errors detected: + `+r.join(` +------------------------------- +`))})},t.DEFER_DEFINITION_ERRORS_HANDLING=!1,t}();or.Parser=GI;(0,hwe.applyMixins)(GI,[nwe.Recoverable,swe.LooksAhead,owe.TreeBuilder,awe.LexerAdapter,lwe.RecognizerEngine,Awe.RecognizerApi,cwe.ErrorHandler,uwe.ContentAssist,gwe.GastRecorder,fwe.PerformanceTracer]);var Cwe=function(t){cY(e,t);function e(r,i){i===void 0&&(i=or.DEFAULT_PARSER_CONFIG);var n=this,s=(0,Wi.cloneObj)(i);return s.outputCst=!0,n=t.call(this,r,s)||this,n}return e}(GI);or.CstParser=Cwe;var mwe=function(t){cY(e,t);function e(r,i){i===void 0&&(i=or.DEFAULT_PARSER_CONFIG);var n=this,s=(0,Wi.cloneObj)(i);return s.outputCst=!1,n=t.call(this,r,s)||this,n}return e}(GI);or.EmbeddedActionsParser=mwe});var pY=E(jI=>{"use strict";Object.defineProperty(jI,"__esModule",{value:!0});jI.createSyntaxDiagramsCode=void 0;var hY=Uv();function Ewe(t,e){var r=e===void 0?{}:e,i=r.resourceBase,n=i===void 0?"https://unpkg.com/chevrotain@"+hY.VERSION+"/diagrams/":i,s=r.css,o=s===void 0?"https://unpkg.com/chevrotain@"+hY.VERSION+"/diagrams/diagrams.css":s,a=` + + + + + +`,l=` + +`,c=` + + + + +`,u=` +
+`,g=` + +`,f=` + +`;return a+l+c+u+g+f}jI.createSyntaxDiagramsCode=Ewe});var mY=E(He=>{"use strict";Object.defineProperty(He,"__esModule",{value:!0});He.Parser=He.createSyntaxDiagramsCode=He.clearCache=He.GAstVisitor=He.serializeProduction=He.serializeGrammar=He.Terminal=He.Rule=He.RepetitionWithSeparator=He.RepetitionMandatoryWithSeparator=He.RepetitionMandatory=He.Repetition=He.Option=He.NonTerminal=He.Alternative=He.Alternation=He.defaultLexerErrorProvider=He.NoViableAltException=He.NotAllInputParsedException=He.MismatchedTokenException=He.isRecognitionException=He.EarlyExitException=He.defaultParserErrorProvider=He.tokenName=He.tokenMatcher=He.tokenLabel=He.EOF=He.createTokenInstance=He.createToken=He.LexerDefinitionErrorType=He.Lexer=He.EMPTY_ALT=He.ParserDefinitionErrorType=He.EmbeddedActionsParser=He.CstParser=He.VERSION=void 0;var Iwe=Uv();Object.defineProperty(He,"VERSION",{enumerable:!0,get:function(){return Iwe.VERSION}});var YI=Tn();Object.defineProperty(He,"CstParser",{enumerable:!0,get:function(){return YI.CstParser}});Object.defineProperty(He,"EmbeddedActionsParser",{enumerable:!0,get:function(){return YI.EmbeddedActionsParser}});Object.defineProperty(He,"ParserDefinitionErrorType",{enumerable:!0,get:function(){return YI.ParserDefinitionErrorType}});Object.defineProperty(He,"EMPTY_ALT",{enumerable:!0,get:function(){return YI.EMPTY_ALT}});var dY=Gh();Object.defineProperty(He,"Lexer",{enumerable:!0,get:function(){return dY.Lexer}});Object.defineProperty(He,"LexerDefinitionErrorType",{enumerable:!0,get:function(){return dY.LexerDefinitionErrorType}});var ku=nA();Object.defineProperty(He,"createToken",{enumerable:!0,get:function(){return ku.createToken}});Object.defineProperty(He,"createTokenInstance",{enumerable:!0,get:function(){return ku.createTokenInstance}});Object.defineProperty(He,"EOF",{enumerable:!0,get:function(){return ku.EOF}});Object.defineProperty(He,"tokenLabel",{enumerable:!0,get:function(){return ku.tokenLabel}});Object.defineProperty(He,"tokenMatcher",{enumerable:!0,get:function(){return ku.tokenMatcher}});Object.defineProperty(He,"tokenName",{enumerable:!0,get:function(){return ku.tokenName}});var ywe=Wh();Object.defineProperty(He,"defaultParserErrorProvider",{enumerable:!0,get:function(){return ywe.defaultParserErrorProvider}});var rp=vu();Object.defineProperty(He,"EarlyExitException",{enumerable:!0,get:function(){return rp.EarlyExitException}});Object.defineProperty(He,"isRecognitionException",{enumerable:!0,get:function(){return rp.isRecognitionException}});Object.defineProperty(He,"MismatchedTokenException",{enumerable:!0,get:function(){return rp.MismatchedTokenException}});Object.defineProperty(He,"NotAllInputParsedException",{enumerable:!0,get:function(){return rp.NotAllInputParsedException}});Object.defineProperty(He,"NoViableAltException",{enumerable:!0,get:function(){return rp.NoViableAltException}});var wwe=_v();Object.defineProperty(He,"defaultLexerErrorProvider",{enumerable:!0,get:function(){return wwe.defaultLexerErrorProvider}});var ho=hn();Object.defineProperty(He,"Alternation",{enumerable:!0,get:function(){return ho.Alternation}});Object.defineProperty(He,"Alternative",{enumerable:!0,get:function(){return ho.Alternative}});Object.defineProperty(He,"NonTerminal",{enumerable:!0,get:function(){return ho.NonTerminal}});Object.defineProperty(He,"Option",{enumerable:!0,get:function(){return ho.Option}});Object.defineProperty(He,"Repetition",{enumerable:!0,get:function(){return ho.Repetition}});Object.defineProperty(He,"RepetitionMandatory",{enumerable:!0,get:function(){return ho.RepetitionMandatory}});Object.defineProperty(He,"RepetitionMandatoryWithSeparator",{enumerable:!0,get:function(){return ho.RepetitionMandatoryWithSeparator}});Object.defineProperty(He,"RepetitionWithSeparator",{enumerable:!0,get:function(){return ho.RepetitionWithSeparator}});Object.defineProperty(He,"Rule",{enumerable:!0,get:function(){return ho.Rule}});Object.defineProperty(He,"Terminal",{enumerable:!0,get:function(){return ho.Terminal}});var CY=hn();Object.defineProperty(He,"serializeGrammar",{enumerable:!0,get:function(){return CY.serializeGrammar}});Object.defineProperty(He,"serializeProduction",{enumerable:!0,get:function(){return CY.serializeProduction}});var Bwe=wu();Object.defineProperty(He,"GAstVisitor",{enumerable:!0,get:function(){return Bwe.GAstVisitor}});function Qwe(){console.warn(`The clearCache function was 'soft' removed from the Chevrotain API. + It performs no action other than printing this message. + Please avoid using it as it will be completely removed in the future`)}He.clearCache=Qwe;var bwe=pY();Object.defineProperty(He,"createSyntaxDiagramsCode",{enumerable:!0,get:function(){return bwe.createSyntaxDiagramsCode}});var vwe=function(){function t(){throw new Error(`The Parser class has been deprecated, use CstParser or EmbeddedActionsParser instead. +See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_7-0-0`)}return t}();He.Parser=vwe});var yY=E((Trt,EY)=>{var qI=mY(),ca=qI.createToken,IY=qI.tokenMatcher,yS=qI.Lexer,Swe=qI.EmbeddedActionsParser;EY.exports=t=>{let e=ca({name:"LogicalOperator",pattern:yS.NA}),r=ca({name:"Or",pattern:/\|/,categories:e}),i=ca({name:"Xor",pattern:/\^/,categories:e}),n=ca({name:"And",pattern:/&/,categories:e}),s=ca({name:"Not",pattern:/!/}),o=ca({name:"LParen",pattern:/\(/}),a=ca({name:"RParen",pattern:/\)/}),l=ca({name:"Query",pattern:t}),u=[ca({name:"WhiteSpace",pattern:/\s+/,group:yS.SKIPPED}),r,i,n,o,a,s,e,l],g=new yS(u);class f extends Swe{constructor(p){super(u);this.RULE("expression",()=>this.SUBRULE(this.logicalExpression)),this.RULE("logicalExpression",()=>{let m=this.SUBRULE(this.atomicExpression);return this.MANY(()=>{let I=m,B=this.CONSUME(e),b=this.SUBRULE2(this.atomicExpression);IY(B,r)?m=R=>I(R)||b(R):IY(B,i)?m=R=>!!(I(R)^b(R)):m=R=>I(R)&&b(R)}),m}),this.RULE("atomicExpression",()=>this.OR([{ALT:()=>this.SUBRULE(this.parenthesisExpression)},{ALT:()=>{let{image:d}=this.CONSUME(l);return m=>m(d)}},{ALT:()=>{this.CONSUME(s);let d=this.SUBRULE(this.atomicExpression);return m=>!d(m)}}])),this.RULE("parenthesisExpression",()=>{let d;return this.CONSUME(o),d=this.SUBRULE(this.expression),this.CONSUME(a),d}),this.performSelfAnalysis()}}return{TinylogicLexer:g,TinylogicParser:f}}});var wY=E(JI=>{var xwe=yY();JI.makeParser=(t=/[a-z]+/)=>{let{TinylogicLexer:e,TinylogicParser:r}=xwe(t),i=new r;return(n,s)=>{let o=e.tokenize(n);return i.input=o.tokens,i.expression()(s)}};JI.parse=JI.makeParser()});var QY=E((Ort,BY)=>{"use strict";BY.exports=(...t)=>[...new Set([].concat(...t))]});var wS=E((Krt,bY)=>{"use strict";var kwe=require("stream"),vY=kwe.PassThrough,Pwe=Array.prototype.slice;bY.exports=Dwe;function Dwe(){let t=[],e=!1,r=Pwe.call(arguments),i=r[r.length-1];i&&!Array.isArray(i)&&i.pipe==null?r.pop():i={};let n=i.end!==!1;i.objectMode==null&&(i.objectMode=!0),i.highWaterMark==null&&(i.highWaterMark=64*1024);let s=vY(i);function o(){for(let c=0,u=arguments.length;c0||(e=!1,a())}function f(h){function p(){h.removeListener("merge2UnpipeEnd",p),h.removeListener("end",p),g()}if(h._readableState.endEmitted)return g();h.on("merge2UnpipeEnd",p),h.on("end",p),h.pipe(s,{end:!1}),h.resume()}for(let h=0;h{"use strict";Object.defineProperty(WI,"__esModule",{value:!0});function Rwe(t){return t.reduce((e,r)=>[].concat(e,r),[])}WI.flatten=Rwe;function Fwe(t,e){let r=[[]],i=0;for(let n of t)e(n)?(i++,r[i]=[]):r[i].push(n);return r}WI.splitWhen=Fwe});var kY=E(BS=>{"use strict";Object.defineProperty(BS,"__esModule",{value:!0});function Nwe(t){return t.code==="ENOENT"}BS.isEnoentCodeError=Nwe});var DY=E(QS=>{"use strict";Object.defineProperty(QS,"__esModule",{value:!0});var PY=class{constructor(e,r){this.name=e,this.isBlockDevice=r.isBlockDevice.bind(r),this.isCharacterDevice=r.isCharacterDevice.bind(r),this.isDirectory=r.isDirectory.bind(r),this.isFIFO=r.isFIFO.bind(r),this.isFile=r.isFile.bind(r),this.isSocket=r.isSocket.bind(r),this.isSymbolicLink=r.isSymbolicLink.bind(r)}};function Lwe(t,e){return new PY(t,e)}QS.createDirentFromStats=Lwe});var RY=E(Pu=>{"use strict";Object.defineProperty(Pu,"__esModule",{value:!0});var Twe=require("path"),Mwe=2,Owe=/(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g;function Kwe(t){return t.replace(/\\/g,"/")}Pu.unixify=Kwe;function Uwe(t,e){return Twe.resolve(t,e)}Pu.makeAbsolute=Uwe;function Hwe(t){return t.replace(Owe,"\\$2")}Pu.escape=Hwe;function Gwe(t){if(t.charAt(0)==="."){let e=t.charAt(1);if(e==="/"||e==="\\")return t.slice(Mwe)}return t}Pu.removeLeadingDotSegment=Gwe});var NY=E((Yrt,FY)=>{FY.exports=function(e){if(typeof e!="string"||e==="")return!1;for(var r;r=/(\\).|([@?!+*]\(.*\))/g.exec(e);){if(r[2])return!0;e=e.slice(r.index+r[0].length)}return!1}});var TY=E((qrt,LY)=>{var jwe=NY(),Ywe={"{":"}","(":")","[":"]"},qwe=/\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/,Jwe=/\\(.)|(^!|[*?{}()[\]]|\(\?)/;LY.exports=function(e,r){if(typeof e!="string"||e==="")return!1;if(jwe(e))return!0;var i=qwe,n;for(r&&r.strict===!1&&(i=Jwe);n=i.exec(e);){if(n[2])return!0;var s=n.index+n[0].length,o=n[1],a=o?Ywe[o]:null;if(o&&a){var l=e.indexOf(a,s);l!==-1&&(s=l+1)}e=e.slice(s)}return!1}});var OY=E((Jrt,MY)=>{"use strict";var Wwe=TY(),zwe=require("path").posix.dirname,Vwe=require("os").platform()==="win32",bS="/",_we=/\\/g,Xwe=/[\{\[].*[\}\]]$/,Zwe=/(^|[^\\])([\{\[]|\([^\)]+$)/,$we=/\\([\!\*\?\|\[\]\(\)\{\}])/g;MY.exports=function(e,r){var i=Object.assign({flipBackslashes:!0},r);i.flipBackslashes&&Vwe&&e.indexOf(bS)<0&&(e=e.replace(_we,bS)),Xwe.test(e)&&(e+=bS),e+="a";do e=zwe(e);while(Wwe(e)||Zwe.test(e));return e.replace($we,"$1")}});var WY=E(Hr=>{"use strict";Object.defineProperty(Hr,"__esModule",{value:!0});var eBe=require("path"),tBe=OY(),KY=Nn(),rBe=iv(),UY="**",iBe="\\",nBe=/[*?]|^!/,sBe=/\[.*]/,oBe=/(?:^|[^!*+?@])\(.*\|.*\)/,aBe=/[!*+?@]\(.*\)/,ABe=/{.*(?:,|\.\.).*}/;function GY(t,e={}){return!HY(t,e)}Hr.isStaticPattern=GY;function HY(t,e={}){return!!(e.caseSensitiveMatch===!1||t.includes(iBe)||nBe.test(t)||sBe.test(t)||oBe.test(t)||e.extglob!==!1&&aBe.test(t)||e.braceExpansion!==!1&&ABe.test(t))}Hr.isDynamicPattern=HY;function lBe(t){return zI(t)?t.slice(1):t}Hr.convertToPositivePattern=lBe;function cBe(t){return"!"+t}Hr.convertToNegativePattern=cBe;function zI(t){return t.startsWith("!")&&t[1]!=="("}Hr.isNegativePattern=zI;function jY(t){return!zI(t)}Hr.isPositivePattern=jY;function uBe(t){return t.filter(zI)}Hr.getNegativePatterns=uBe;function gBe(t){return t.filter(jY)}Hr.getPositivePatterns=gBe;function fBe(t){return tBe(t,{flipBackslashes:!1})}Hr.getBaseDirectory=fBe;function hBe(t){return t.includes(UY)}Hr.hasGlobStar=hBe;function YY(t){return t.endsWith("/"+UY)}Hr.endsWithSlashGlobStar=YY;function pBe(t){let e=eBe.basename(t);return YY(t)||GY(e)}Hr.isAffectDepthOfReadingPattern=pBe;function dBe(t){return t.reduce((e,r)=>e.concat(qY(r)),[])}Hr.expandPatternsWithBraceExpansion=dBe;function qY(t){return KY.braces(t,{expand:!0,nodupes:!0})}Hr.expandBraceExpansion=qY;function CBe(t,e){let r=rBe.scan(t,Object.assign(Object.assign({},e),{parts:!0}));return r.parts.length===0?[t]:r.parts}Hr.getPatternParts=CBe;function JY(t,e){return KY.makeRe(t,e)}Hr.makeRe=JY;function mBe(t,e){return t.map(r=>JY(r,e))}Hr.convertPatternsToRe=mBe;function EBe(t,e){return e.some(r=>r.test(t))}Hr.matchAny=EBe});var VY=E(vS=>{"use strict";Object.defineProperty(vS,"__esModule",{value:!0});var IBe=wS();function yBe(t){let e=IBe(t);return t.forEach(r=>{r.once("error",i=>e.emit("error",i))}),e.once("close",()=>zY(t)),e.once("end",()=>zY(t)),e}vS.merge=yBe;function zY(t){t.forEach(e=>e.emit("close"))}});var _Y=E(VI=>{"use strict";Object.defineProperty(VI,"__esModule",{value:!0});function wBe(t){return typeof t=="string"}VI.isString=wBe;function BBe(t){return t===""}VI.isEmpty=BBe});var ga=E(ua=>{"use strict";Object.defineProperty(ua,"__esModule",{value:!0});var QBe=xY();ua.array=QBe;var bBe=kY();ua.errno=bBe;var vBe=DY();ua.fs=vBe;var SBe=RY();ua.path=SBe;var xBe=WY();ua.pattern=xBe;var kBe=VY();ua.stream=kBe;var PBe=_Y();ua.string=PBe});var tq=E(fa=>{"use strict";Object.defineProperty(fa,"__esModule",{value:!0});var Ll=ga();function DBe(t,e){let r=XY(t),i=ZY(t,e.ignore),n=r.filter(l=>Ll.pattern.isStaticPattern(l,e)),s=r.filter(l=>Ll.pattern.isDynamicPattern(l,e)),o=SS(n,i,!1),a=SS(s,i,!0);return o.concat(a)}fa.generate=DBe;function SS(t,e,r){let i=$Y(t);return"."in i?[xS(".",t,e,r)]:eq(i,e,r)}fa.convertPatternsToTasks=SS;function XY(t){return Ll.pattern.getPositivePatterns(t)}fa.getPositivePatterns=XY;function ZY(t,e){return Ll.pattern.getNegativePatterns(t).concat(e).map(Ll.pattern.convertToPositivePattern)}fa.getNegativePatternsAsPositive=ZY;function $Y(t){let e={};return t.reduce((r,i)=>{let n=Ll.pattern.getBaseDirectory(i);return n in r?r[n].push(i):r[n]=[i],r},e)}fa.groupPatternsByBaseDirectory=$Y;function eq(t,e,r){return Object.keys(t).map(i=>xS(i,t[i],e,r))}fa.convertPatternGroupsToTasks=eq;function xS(t,e,r,i){return{dynamic:i,positive:e,negative:r,base:t,patterns:[].concat(e,r.map(Ll.pattern.convertToNegativePattern))}}fa.convertPatternGroupToTask=xS});var iq=E(_I=>{"use strict";Object.defineProperty(_I,"__esModule",{value:!0});_I.read=void 0;function RBe(t,e,r){e.fs.lstat(t,(i,n)=>{if(i!==null){rq(r,i);return}if(!n.isSymbolicLink()||!e.followSymbolicLink){kS(r,n);return}e.fs.stat(t,(s,o)=>{if(s!==null){if(e.throwErrorOnBrokenSymbolicLink){rq(r,s);return}kS(r,n);return}e.markSymbolicLink&&(o.isSymbolicLink=()=>!0),kS(r,o)})})}_I.read=RBe;function rq(t,e){t(e)}function kS(t,e){t(null,e)}});var nq=E(XI=>{"use strict";Object.defineProperty(XI,"__esModule",{value:!0});XI.read=void 0;function FBe(t,e){let r=e.fs.lstatSync(t);if(!r.isSymbolicLink()||!e.followSymbolicLink)return r;try{let i=e.fs.statSync(t);return e.markSymbolicLink&&(i.isSymbolicLink=()=>!0),i}catch(i){if(!e.throwErrorOnBrokenSymbolicLink)return r;throw i}}XI.read=FBe});var sq=E(AA=>{"use strict";Object.defineProperty(AA,"__esModule",{value:!0});AA.createFileSystemAdapter=AA.FILE_SYSTEM_ADAPTER=void 0;var ZI=require("fs");AA.FILE_SYSTEM_ADAPTER={lstat:ZI.lstat,stat:ZI.stat,lstatSync:ZI.lstatSync,statSync:ZI.statSync};function NBe(t){return t===void 0?AA.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},AA.FILE_SYSTEM_ADAPTER),t)}AA.createFileSystemAdapter=NBe});var aq=E(PS=>{"use strict";Object.defineProperty(PS,"__esModule",{value:!0});var LBe=sq(),oq=class{constructor(e={}){this._options=e,this.followSymbolicLink=this._getValue(this._options.followSymbolicLink,!0),this.fs=LBe.createFileSystemAdapter(this._options.fs),this.markSymbolicLink=this._getValue(this._options.markSymbolicLink,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0)}_getValue(e,r){return e!=null?e:r}};PS.default=oq});var Tl=E(lA=>{"use strict";Object.defineProperty(lA,"__esModule",{value:!0});lA.statSync=lA.stat=lA.Settings=void 0;var Aq=iq(),TBe=nq(),DS=aq();lA.Settings=DS.default;function MBe(t,e,r){if(typeof e=="function"){Aq.read(t,RS(),e);return}Aq.read(t,RS(e),r)}lA.stat=MBe;function OBe(t,e){let r=RS(e);return TBe.read(t,r)}lA.statSync=OBe;function RS(t={}){return t instanceof DS.default?t:new DS.default(t)}});var cq=E((iit,lq)=>{lq.exports=KBe;function KBe(t,e){var r,i,n,s=!0;Array.isArray(t)?(r=[],i=t.length):(n=Object.keys(t),r={},i=n.length);function o(l){function c(){e&&e(l,r),e=null}s?process.nextTick(c):c()}function a(l,c,u){r[l]=u,(--i==0||c)&&o(c)}i?n?n.forEach(function(l){t[l](function(c,u){a(l,c,u)})}):t.forEach(function(l,c){l(function(u,g){a(c,u,g)})}):o(null),s=!1}});var FS=E($I=>{"use strict";Object.defineProperty($I,"__esModule",{value:!0});$I.IS_SUPPORT_READDIR_WITH_FILE_TYPES=void 0;var ey=process.versions.node.split(".");if(ey[0]===void 0||ey[1]===void 0)throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);var uq=Number.parseInt(ey[0],10),UBe=Number.parseInt(ey[1],10),gq=10,HBe=10,GBe=uq>gq,jBe=uq===gq&&UBe>=HBe;$I.IS_SUPPORT_READDIR_WITH_FILE_TYPES=GBe||jBe});var hq=E(ty=>{"use strict";Object.defineProperty(ty,"__esModule",{value:!0});ty.createDirentFromStats=void 0;var fq=class{constructor(e,r){this.name=e,this.isBlockDevice=r.isBlockDevice.bind(r),this.isCharacterDevice=r.isCharacterDevice.bind(r),this.isDirectory=r.isDirectory.bind(r),this.isFIFO=r.isFIFO.bind(r),this.isFile=r.isFile.bind(r),this.isSocket=r.isSocket.bind(r),this.isSymbolicLink=r.isSymbolicLink.bind(r)}};function YBe(t,e){return new fq(t,e)}ty.createDirentFromStats=YBe});var NS=E(ry=>{"use strict";Object.defineProperty(ry,"__esModule",{value:!0});ry.fs=void 0;var qBe=hq();ry.fs=qBe});var LS=E(iy=>{"use strict";Object.defineProperty(iy,"__esModule",{value:!0});iy.joinPathSegments=void 0;function JBe(t,e,r){return t.endsWith(r)?t+e:t+r+e}iy.joinPathSegments=JBe});var Iq=E(cA=>{"use strict";Object.defineProperty(cA,"__esModule",{value:!0});cA.readdir=cA.readdirWithFileTypes=cA.read=void 0;var WBe=Tl(),pq=cq(),zBe=FS(),dq=NS(),Cq=LS();function VBe(t,e,r){if(!e.stats&&zBe.IS_SUPPORT_READDIR_WITH_FILE_TYPES){mq(t,e,r);return}Eq(t,e,r)}cA.read=VBe;function mq(t,e,r){e.fs.readdir(t,{withFileTypes:!0},(i,n)=>{if(i!==null){ny(r,i);return}let s=n.map(a=>({dirent:a,name:a.name,path:Cq.joinPathSegments(t,a.name,e.pathSegmentSeparator)}));if(!e.followSymbolicLinks){TS(r,s);return}let o=s.map(a=>_Be(a,e));pq(o,(a,l)=>{if(a!==null){ny(r,a);return}TS(r,l)})})}cA.readdirWithFileTypes=mq;function _Be(t,e){return r=>{if(!t.dirent.isSymbolicLink()){r(null,t);return}e.fs.stat(t.path,(i,n)=>{if(i!==null){if(e.throwErrorOnBrokenSymbolicLink){r(i);return}r(null,t);return}t.dirent=dq.fs.createDirentFromStats(t.name,n),r(null,t)})}}function Eq(t,e,r){e.fs.readdir(t,(i,n)=>{if(i!==null){ny(r,i);return}let s=n.map(o=>{let a=Cq.joinPathSegments(t,o,e.pathSegmentSeparator);return l=>{WBe.stat(a,e.fsStatSettings,(c,u)=>{if(c!==null){l(c);return}let g={name:o,path:a,dirent:dq.fs.createDirentFromStats(o,u)};e.stats&&(g.stats=u),l(null,g)})}});pq(s,(o,a)=>{if(o!==null){ny(r,o);return}TS(r,a)})})}cA.readdir=Eq;function ny(t,e){t(e)}function TS(t,e){t(null,e)}});var bq=E(uA=>{"use strict";Object.defineProperty(uA,"__esModule",{value:!0});uA.readdir=uA.readdirWithFileTypes=uA.read=void 0;var XBe=Tl(),ZBe=FS(),yq=NS(),wq=LS();function $Be(t,e){return!e.stats&&ZBe.IS_SUPPORT_READDIR_WITH_FILE_TYPES?Bq(t,e):Qq(t,e)}uA.read=$Be;function Bq(t,e){return e.fs.readdirSync(t,{withFileTypes:!0}).map(i=>{let n={dirent:i,name:i.name,path:wq.joinPathSegments(t,i.name,e.pathSegmentSeparator)};if(n.dirent.isSymbolicLink()&&e.followSymbolicLinks)try{let s=e.fs.statSync(n.path);n.dirent=yq.fs.createDirentFromStats(n.name,s)}catch(s){if(e.throwErrorOnBrokenSymbolicLink)throw s}return n})}uA.readdirWithFileTypes=Bq;function Qq(t,e){return e.fs.readdirSync(t).map(i=>{let n=wq.joinPathSegments(t,i,e.pathSegmentSeparator),s=XBe.statSync(n,e.fsStatSettings),o={name:i,path:n,dirent:yq.fs.createDirentFromStats(i,s)};return e.stats&&(o.stats=s),o})}uA.readdir=Qq});var vq=E(gA=>{"use strict";Object.defineProperty(gA,"__esModule",{value:!0});gA.createFileSystemAdapter=gA.FILE_SYSTEM_ADAPTER=void 0;var Du=require("fs");gA.FILE_SYSTEM_ADAPTER={lstat:Du.lstat,stat:Du.stat,lstatSync:Du.lstatSync,statSync:Du.statSync,readdir:Du.readdir,readdirSync:Du.readdirSync};function e0e(t){return t===void 0?gA.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},gA.FILE_SYSTEM_ADAPTER),t)}gA.createFileSystemAdapter=e0e});var xq=E(MS=>{"use strict";Object.defineProperty(MS,"__esModule",{value:!0});var t0e=require("path"),r0e=Tl(),i0e=vq(),Sq=class{constructor(e={}){this._options=e,this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!1),this.fs=i0e.createFileSystemAdapter(this._options.fs),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,t0e.sep),this.stats=this._getValue(this._options.stats,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0),this.fsStatSettings=new r0e.Settings({followSymbolicLink:this.followSymbolicLinks,fs:this.fs,throwErrorOnBrokenSymbolicLink:this.throwErrorOnBrokenSymbolicLink})}_getValue(e,r){return e!=null?e:r}};MS.default=Sq});var sy=E(fA=>{"use strict";Object.defineProperty(fA,"__esModule",{value:!0});fA.Settings=fA.scandirSync=fA.scandir=void 0;var kq=Iq(),n0e=bq(),OS=xq();fA.Settings=OS.default;function s0e(t,e,r){if(typeof e=="function"){kq.read(t,KS(),e);return}kq.read(t,KS(e),r)}fA.scandir=s0e;function o0e(t,e){let r=KS(e);return n0e.read(t,r)}fA.scandirSync=o0e;function KS(t={}){return t instanceof OS.default?t:new OS.default(t)}});var Dq=E((fit,Pq)=>{"use strict";function a0e(t){var e=new t,r=e;function i(){var s=e;return s.next?e=s.next:(e=new t,r=e),s.next=null,s}function n(s){r.next=s,r=s}return{get:i,release:n}}Pq.exports=a0e});var Fq=E((hit,US)=>{"use strict";var A0e=Dq();function Rq(t,e,r){if(typeof t=="function"&&(r=e,e=t,t=null),r<1)throw new Error("fastqueue concurrency must be greater than 1");var i=A0e(l0e),n=null,s=null,o=0,a=null,l={push:d,drain:po,saturated:po,pause:u,paused:!1,concurrency:r,running:c,resume:h,idle:p,length:g,getQueue:f,unshift:m,empty:po,kill:B,killAndDrain:b,error:R};return l;function c(){return o}function u(){l.paused=!0}function g(){for(var H=n,L=0;H;)H=H.next,L++;return L}function f(){for(var H=n,L=[];H;)L.push(H.value),H=H.next;return L}function h(){if(!!l.paused){l.paused=!1;for(var H=0;H{"use strict";Object.defineProperty(Co,"__esModule",{value:!0});Co.joinPathSegments=Co.replacePathSegmentSeparator=Co.isAppliedFilter=Co.isFatalError=void 0;function u0e(t,e){return t.errorFilter===null?!0:!t.errorFilter(e)}Co.isFatalError=u0e;function g0e(t,e){return t===null||t(e)}Co.isAppliedFilter=g0e;function f0e(t,e){return t.split(/[/\\]/).join(e)}Co.replacePathSegmentSeparator=f0e;function h0e(t,e,r){return t===""?e:t.endsWith(r)?t+e:t+r+e}Co.joinPathSegments=h0e});var GS=E(HS=>{"use strict";Object.defineProperty(HS,"__esModule",{value:!0});var p0e=oy(),Nq=class{constructor(e,r){this._root=e,this._settings=r,this._root=p0e.replacePathSegmentSeparator(e,r.pathSegmentSeparator)}};HS.default=Nq});var YS=E(jS=>{"use strict";Object.defineProperty(jS,"__esModule",{value:!0});var d0e=require("events"),C0e=sy(),m0e=Fq(),ay=oy(),E0e=GS(),Lq=class extends E0e.default{constructor(e,r){super(e,r);this._settings=r,this._scandir=C0e.scandir,this._emitter=new d0e.EventEmitter,this._queue=m0e(this._worker.bind(this),this._settings.concurrency),this._isFatalError=!1,this._isDestroyed=!1,this._queue.drain=()=>{this._isFatalError||this._emitter.emit("end")}}read(){return this._isFatalError=!1,this._isDestroyed=!1,setImmediate(()=>{this._pushToQueue(this._root,this._settings.basePath)}),this._emitter}get isDestroyed(){return this._isDestroyed}destroy(){if(this._isDestroyed)throw new Error("The reader is already destroyed");this._isDestroyed=!0,this._queue.killAndDrain()}onEntry(e){this._emitter.on("entry",e)}onError(e){this._emitter.once("error",e)}onEnd(e){this._emitter.once("end",e)}_pushToQueue(e,r){let i={directory:e,base:r};this._queue.push(i,n=>{n!==null&&this._handleError(n)})}_worker(e,r){this._scandir(e.directory,this._settings.fsScandirSettings,(i,n)=>{if(i!==null){r(i,void 0);return}for(let s of n)this._handleEntry(s,e.base);r(null,void 0)})}_handleError(e){this._isDestroyed||!ay.isFatalError(this._settings,e)||(this._isFatalError=!0,this._isDestroyed=!0,this._emitter.emit("error",e))}_handleEntry(e,r){if(this._isDestroyed||this._isFatalError)return;let i=e.path;r!==void 0&&(e.path=ay.joinPathSegments(r,e.name,this._settings.pathSegmentSeparator)),ay.isAppliedFilter(this._settings.entryFilter,e)&&this._emitEntry(e),e.dirent.isDirectory()&&ay.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(i,e.path)}_emitEntry(e){this._emitter.emit("entry",e)}};jS.default=Lq});var Mq=E(qS=>{"use strict";Object.defineProperty(qS,"__esModule",{value:!0});var I0e=YS(),Tq=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new I0e.default(this._root,this._settings),this._storage=new Set}read(e){this._reader.onError(r=>{y0e(e,r)}),this._reader.onEntry(r=>{this._storage.add(r)}),this._reader.onEnd(()=>{w0e(e,[...this._storage])}),this._reader.read()}};qS.default=Tq;function y0e(t,e){t(e)}function w0e(t,e){t(null,e)}});var Kq=E(JS=>{"use strict";Object.defineProperty(JS,"__esModule",{value:!0});var B0e=require("stream"),Q0e=YS(),Oq=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new Q0e.default(this._root,this._settings),this._stream=new B0e.Readable({objectMode:!0,read:()=>{},destroy:()=>{this._reader.isDestroyed||this._reader.destroy()}})}read(){return this._reader.onError(e=>{this._stream.emit("error",e)}),this._reader.onEntry(e=>{this._stream.push(e)}),this._reader.onEnd(()=>{this._stream.push(null)}),this._reader.read(),this._stream}};JS.default=Oq});var Hq=E(WS=>{"use strict";Object.defineProperty(WS,"__esModule",{value:!0});var b0e=sy(),Ay=oy(),v0e=GS(),Uq=class extends v0e.default{constructor(){super(...arguments);this._scandir=b0e.scandirSync,this._storage=new Set,this._queue=new Set}read(){return this._pushToQueue(this._root,this._settings.basePath),this._handleQueue(),[...this._storage]}_pushToQueue(e,r){this._queue.add({directory:e,base:r})}_handleQueue(){for(let e of this._queue.values())this._handleDirectory(e.directory,e.base)}_handleDirectory(e,r){try{let i=this._scandir(e,this._settings.fsScandirSettings);for(let n of i)this._handleEntry(n,r)}catch(i){this._handleError(i)}}_handleError(e){if(!!Ay.isFatalError(this._settings,e))throw e}_handleEntry(e,r){let i=e.path;r!==void 0&&(e.path=Ay.joinPathSegments(r,e.name,this._settings.pathSegmentSeparator)),Ay.isAppliedFilter(this._settings.entryFilter,e)&&this._pushToStorage(e),e.dirent.isDirectory()&&Ay.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(i,e.path)}_pushToStorage(e){this._storage.add(e)}};WS.default=Uq});var jq=E(zS=>{"use strict";Object.defineProperty(zS,"__esModule",{value:!0});var S0e=Hq(),Gq=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new S0e.default(this._root,this._settings)}read(){return this._reader.read()}};zS.default=Gq});var qq=E(VS=>{"use strict";Object.defineProperty(VS,"__esModule",{value:!0});var x0e=require("path"),k0e=sy(),Yq=class{constructor(e={}){this._options=e,this.basePath=this._getValue(this._options.basePath,void 0),this.concurrency=this._getValue(this._options.concurrency,Number.POSITIVE_INFINITY),this.deepFilter=this._getValue(this._options.deepFilter,null),this.entryFilter=this._getValue(this._options.entryFilter,null),this.errorFilter=this._getValue(this._options.errorFilter,null),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,x0e.sep),this.fsScandirSettings=new k0e.Settings({followSymbolicLinks:this._options.followSymbolicLinks,fs:this._options.fs,pathSegmentSeparator:this._options.pathSegmentSeparator,stats:this._options.stats,throwErrorOnBrokenSymbolicLink:this._options.throwErrorOnBrokenSymbolicLink})}_getValue(e,r){return e!=null?e:r}};VS.default=Yq});var XS=E(mo=>{"use strict";Object.defineProperty(mo,"__esModule",{value:!0});mo.Settings=mo.walkStream=mo.walkSync=mo.walk=void 0;var Jq=Mq(),P0e=Kq(),D0e=jq(),_S=qq();mo.Settings=_S.default;function R0e(t,e,r){if(typeof e=="function"){new Jq.default(t,ly()).read(e);return}new Jq.default(t,ly(e)).read(r)}mo.walk=R0e;function F0e(t,e){let r=ly(e);return new D0e.default(t,r).read()}mo.walkSync=F0e;function N0e(t,e){let r=ly(e);return new P0e.default(t,r).read()}mo.walkStream=N0e;function ly(t={}){return t instanceof _S.default?t:new _S.default(t)}});var $S=E(ZS=>{"use strict";Object.defineProperty(ZS,"__esModule",{value:!0});var L0e=require("path"),T0e=Tl(),Wq=ga(),zq=class{constructor(e){this._settings=e,this._fsStatSettings=new T0e.Settings({followSymbolicLink:this._settings.followSymbolicLinks,fs:this._settings.fs,throwErrorOnBrokenSymbolicLink:this._settings.followSymbolicLinks})}_getFullEntryPath(e){return L0e.resolve(this._settings.cwd,e)}_makeEntry(e,r){let i={name:r,path:r,dirent:Wq.fs.createDirentFromStats(r,e)};return this._settings.stats&&(i.stats=e),i}_isFatalError(e){return!Wq.errno.isEnoentCodeError(e)&&!this._settings.suppressErrors}};ZS.default=zq});var tx=E(ex=>{"use strict";Object.defineProperty(ex,"__esModule",{value:!0});var M0e=require("stream"),O0e=Tl(),K0e=XS(),U0e=$S(),Vq=class extends U0e.default{constructor(){super(...arguments);this._walkStream=K0e.walkStream,this._stat=O0e.stat}dynamic(e,r){return this._walkStream(e,r)}static(e,r){let i=e.map(this._getFullEntryPath,this),n=new M0e.PassThrough({objectMode:!0});n._write=(s,o,a)=>this._getEntry(i[s],e[s],r).then(l=>{l!==null&&r.entryFilter(l)&&n.push(l),s===i.length-1&&n.end(),a()}).catch(a);for(let s=0;sthis._makeEntry(n,r)).catch(n=>{if(i.errorFilter(n))return null;throw n})}_getStat(e){return new Promise((r,i)=>{this._stat(e,this._fsStatSettings,(n,s)=>n===null?r(s):i(n))})}};ex.default=Vq});var Xq=E(rx=>{"use strict";Object.defineProperty(rx,"__esModule",{value:!0});var Ru=ga(),_q=class{constructor(e,r,i){this._patterns=e,this._settings=r,this._micromatchOptions=i,this._storage=[],this._fillStorage()}_fillStorage(){let e=Ru.pattern.expandPatternsWithBraceExpansion(this._patterns);for(let r of e){let i=this._getPatternSegments(r),n=this._splitSegmentsIntoSections(i);this._storage.push({complete:n.length<=1,pattern:r,segments:i,sections:n})}}_getPatternSegments(e){return Ru.pattern.getPatternParts(e,this._micromatchOptions).map(i=>Ru.pattern.isDynamicPattern(i,this._settings)?{dynamic:!0,pattern:i,patternRe:Ru.pattern.makeRe(i,this._micromatchOptions)}:{dynamic:!1,pattern:i})}_splitSegmentsIntoSections(e){return Ru.array.splitWhen(e,r=>r.dynamic&&Ru.pattern.hasGlobStar(r.pattern))}};rx.default=_q});var $q=E(ix=>{"use strict";Object.defineProperty(ix,"__esModule",{value:!0});var H0e=Xq(),Zq=class extends H0e.default{match(e){let r=e.split("/"),i=r.length,n=this._storage.filter(s=>!s.complete||s.segments.length>i);for(let s of n){let o=s.sections[0];if(!s.complete&&i>o.length||r.every((l,c)=>{let u=s.segments[c];return!!(u.dynamic&&u.patternRe.test(l)||!u.dynamic&&u.pattern===l)}))return!0}return!1}};ix.default=Zq});var tJ=E(nx=>{"use strict";Object.defineProperty(nx,"__esModule",{value:!0});var cy=ga(),G0e=$q(),eJ=class{constructor(e,r){this._settings=e,this._micromatchOptions=r}getFilter(e,r,i){let n=this._getMatcher(r),s=this._getNegativePatternsRe(i);return o=>this._filter(e,o,n,s)}_getMatcher(e){return new G0e.default(e,this._settings,this._micromatchOptions)}_getNegativePatternsRe(e){let r=e.filter(cy.pattern.isAffectDepthOfReadingPattern);return cy.pattern.convertPatternsToRe(r,this._micromatchOptions)}_filter(e,r,i,n){let s=this._getEntryLevel(e,r.path);if(this._isSkippedByDeep(s)||this._isSkippedSymbolicLink(r))return!1;let o=cy.path.removeLeadingDotSegment(r.path);return this._isSkippedByPositivePatterns(o,i)?!1:this._isSkippedByNegativePatterns(o,n)}_isSkippedByDeep(e){return e>=this._settings.deep}_isSkippedSymbolicLink(e){return!this._settings.followSymbolicLinks&&e.dirent.isSymbolicLink()}_getEntryLevel(e,r){let i=e.split("/").length;return r.split("/").length-(e===""?0:i)}_isSkippedByPositivePatterns(e,r){return!this._settings.baseNameMatch&&!r.match(e)}_isSkippedByNegativePatterns(e,r){return!cy.pattern.matchAny(e,r)}};nx.default=eJ});var iJ=E(sx=>{"use strict";Object.defineProperty(sx,"__esModule",{value:!0});var ip=ga(),rJ=class{constructor(e,r){this._settings=e,this._micromatchOptions=r,this.index=new Map}getFilter(e,r){let i=ip.pattern.convertPatternsToRe(e,this._micromatchOptions),n=ip.pattern.convertPatternsToRe(r,this._micromatchOptions);return s=>this._filter(s,i,n)}_filter(e,r,i){if(this._settings.unique){if(this._isDuplicateEntry(e))return!1;this._createIndexRecord(e)}if(this._onlyFileFilter(e)||this._onlyDirectoryFilter(e)||this._isSkippedByAbsoluteNegativePatterns(e,i))return!1;let n=this._settings.baseNameMatch?e.name:e.path;return this._isMatchToPatterns(n,r)&&!this._isMatchToPatterns(e.path,i)}_isDuplicateEntry(e){return this.index.has(e.path)}_createIndexRecord(e){this.index.set(e.path,void 0)}_onlyFileFilter(e){return this._settings.onlyFiles&&!e.dirent.isFile()}_onlyDirectoryFilter(e){return this._settings.onlyDirectories&&!e.dirent.isDirectory()}_isSkippedByAbsoluteNegativePatterns(e,r){if(!this._settings.absolute)return!1;let i=ip.path.makeAbsolute(this._settings.cwd,e.path);return this._isMatchToPatterns(i,r)}_isMatchToPatterns(e,r){let i=ip.path.removeLeadingDotSegment(e);return ip.pattern.matchAny(i,r)}};sx.default=rJ});var sJ=E(ox=>{"use strict";Object.defineProperty(ox,"__esModule",{value:!0});var j0e=ga(),nJ=class{constructor(e){this._settings=e}getFilter(){return e=>this._isNonFatalError(e)}_isNonFatalError(e){return j0e.errno.isEnoentCodeError(e)||this._settings.suppressErrors}};ox.default=nJ});var AJ=E(ax=>{"use strict";Object.defineProperty(ax,"__esModule",{value:!0});var oJ=ga(),aJ=class{constructor(e){this._settings=e}getTransformer(){return e=>this._transform(e)}_transform(e){let r=e.path;return this._settings.absolute&&(r=oJ.path.makeAbsolute(this._settings.cwd,r),r=oJ.path.unixify(r)),this._settings.markDirectories&&e.dirent.isDirectory()&&(r+="/"),this._settings.objectMode?Object.assign(Object.assign({},e),{path:r}):r}};ax.default=aJ});var uy=E(Ax=>{"use strict";Object.defineProperty(Ax,"__esModule",{value:!0});var Y0e=require("path"),q0e=tJ(),J0e=iJ(),W0e=sJ(),z0e=AJ(),lJ=class{constructor(e){this._settings=e,this.errorFilter=new W0e.default(this._settings),this.entryFilter=new J0e.default(this._settings,this._getMicromatchOptions()),this.deepFilter=new q0e.default(this._settings,this._getMicromatchOptions()),this.entryTransformer=new z0e.default(this._settings)}_getRootDirectory(e){return Y0e.resolve(this._settings.cwd,e.base)}_getReaderOptions(e){let r=e.base==="."?"":e.base;return{basePath:r,pathSegmentSeparator:"/",concurrency:this._settings.concurrency,deepFilter:this.deepFilter.getFilter(r,e.positive,e.negative),entryFilter:this.entryFilter.getFilter(e.positive,e.negative),errorFilter:this.errorFilter.getFilter(),followSymbolicLinks:this._settings.followSymbolicLinks,fs:this._settings.fs,stats:this._settings.stats,throwErrorOnBrokenSymbolicLink:this._settings.throwErrorOnBrokenSymbolicLink,transform:this.entryTransformer.getTransformer()}}_getMicromatchOptions(){return{dot:this._settings.dot,matchBase:this._settings.baseNameMatch,nobrace:!this._settings.braceExpansion,nocase:!this._settings.caseSensitiveMatch,noext:!this._settings.extglob,noglobstar:!this._settings.globstar,posix:!0,strictSlashes:!1}}};Ax.default=lJ});var uJ=E(lx=>{"use strict";Object.defineProperty(lx,"__esModule",{value:!0});var V0e=tx(),_0e=uy(),cJ=class extends _0e.default{constructor(){super(...arguments);this._reader=new V0e.default(this._settings)}read(e){let r=this._getRootDirectory(e),i=this._getReaderOptions(e),n=[];return new Promise((s,o)=>{let a=this.api(r,e,i);a.once("error",o),a.on("data",l=>n.push(i.transform(l))),a.once("end",()=>s(n))})}api(e,r,i){return r.dynamic?this._reader.dynamic(e,i):this._reader.static(r.patterns,i)}};lx.default=cJ});var fJ=E(cx=>{"use strict";Object.defineProperty(cx,"__esModule",{value:!0});var X0e=require("stream"),Z0e=tx(),$0e=uy(),gJ=class extends $0e.default{constructor(){super(...arguments);this._reader=new Z0e.default(this._settings)}read(e){let r=this._getRootDirectory(e),i=this._getReaderOptions(e),n=this.api(r,e,i),s=new X0e.Readable({objectMode:!0,read:()=>{}});return n.once("error",o=>s.emit("error",o)).on("data",o=>s.emit("data",i.transform(o))).once("end",()=>s.emit("end")),s.once("close",()=>n.destroy()),s}api(e,r,i){return r.dynamic?this._reader.dynamic(e,i):this._reader.static(r.patterns,i)}};cx.default=gJ});var pJ=E(ux=>{"use strict";Object.defineProperty(ux,"__esModule",{value:!0});var eQe=Tl(),tQe=XS(),rQe=$S(),hJ=class extends rQe.default{constructor(){super(...arguments);this._walkSync=tQe.walkSync,this._statSync=eQe.statSync}dynamic(e,r){return this._walkSync(e,r)}static(e,r){let i=[];for(let n of e){let s=this._getFullEntryPath(n),o=this._getEntry(s,n,r);o===null||!r.entryFilter(o)||i.push(o)}return i}_getEntry(e,r,i){try{let n=this._getStat(e);return this._makeEntry(n,r)}catch(n){if(i.errorFilter(n))return null;throw n}}_getStat(e){return this._statSync(e,this._fsStatSettings)}};ux.default=hJ});var CJ=E(gx=>{"use strict";Object.defineProperty(gx,"__esModule",{value:!0});var iQe=pJ(),nQe=uy(),dJ=class extends nQe.default{constructor(){super(...arguments);this._reader=new iQe.default(this._settings)}read(e){let r=this._getRootDirectory(e),i=this._getReaderOptions(e);return this.api(r,e,i).map(i.transform)}api(e,r,i){return r.dynamic?this._reader.dynamic(e,i):this._reader.static(r.patterns,i)}};gx.default=dJ});var EJ=E(np=>{"use strict";Object.defineProperty(np,"__esModule",{value:!0});var Fu=require("fs"),sQe=require("os"),oQe=sQe.cpus().length;np.DEFAULT_FILE_SYSTEM_ADAPTER={lstat:Fu.lstat,lstatSync:Fu.lstatSync,stat:Fu.stat,statSync:Fu.statSync,readdir:Fu.readdir,readdirSync:Fu.readdirSync};var mJ=class{constructor(e={}){this._options=e,this.absolute=this._getValue(this._options.absolute,!1),this.baseNameMatch=this._getValue(this._options.baseNameMatch,!1),this.braceExpansion=this._getValue(this._options.braceExpansion,!0),this.caseSensitiveMatch=this._getValue(this._options.caseSensitiveMatch,!0),this.concurrency=this._getValue(this._options.concurrency,oQe),this.cwd=this._getValue(this._options.cwd,process.cwd()),this.deep=this._getValue(this._options.deep,Infinity),this.dot=this._getValue(this._options.dot,!1),this.extglob=this._getValue(this._options.extglob,!0),this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!0),this.fs=this._getFileSystemMethods(this._options.fs),this.globstar=this._getValue(this._options.globstar,!0),this.ignore=this._getValue(this._options.ignore,[]),this.markDirectories=this._getValue(this._options.markDirectories,!1),this.objectMode=this._getValue(this._options.objectMode,!1),this.onlyDirectories=this._getValue(this._options.onlyDirectories,!1),this.onlyFiles=this._getValue(this._options.onlyFiles,!0),this.stats=this._getValue(this._options.stats,!1),this.suppressErrors=this._getValue(this._options.suppressErrors,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!1),this.unique=this._getValue(this._options.unique,!0),this.onlyDirectories&&(this.onlyFiles=!1),this.stats&&(this.objectMode=!0)}_getValue(e,r){return e===void 0?r:e}_getFileSystemMethods(e={}){return Object.assign(Object.assign({},np.DEFAULT_FILE_SYSTEM_ADAPTER),e)}};np.default=mJ});var gy=E((Oit,IJ)=>{"use strict";var yJ=tq(),aQe=uJ(),AQe=fJ(),lQe=CJ(),fx=EJ(),Ml=ga();async function px(t,e){Nu(t);let r=hx(t,aQe.default,e),i=await Promise.all(r);return Ml.array.flatten(i)}(function(t){function e(o,a){Nu(o);let l=hx(o,lQe.default,a);return Ml.array.flatten(l)}t.sync=e;function r(o,a){Nu(o);let l=hx(o,AQe.default,a);return Ml.stream.merge(l)}t.stream=r;function i(o,a){Nu(o);let l=[].concat(o),c=new fx.default(a);return yJ.generate(l,c)}t.generateTasks=i;function n(o,a){Nu(o);let l=new fx.default(a);return Ml.pattern.isDynamicPattern(o,l)}t.isDynamicPattern=n;function s(o){return Nu(o),Ml.path.escape(o)}t.escapePath=s})(px||(px={}));function hx(t,e,r){let i=[].concat(t),n=new fx.default(r),s=yJ.generate(i,n),o=new e(n);return s.map(o.read,o)}function Nu(t){if(![].concat(t).every(i=>Ml.string.isString(i)&&!Ml.string.isEmpty(i)))throw new TypeError("Patterns must be a string (non empty) or an array of strings")}IJ.exports=px});var BJ=E(Ol=>{"use strict";var{promisify:cQe}=require("util"),wJ=require("fs");async function dx(t,e,r){if(typeof r!="string")throw new TypeError(`Expected a string, got ${typeof r}`);try{return(await cQe(wJ[t])(r))[e]()}catch(i){if(i.code==="ENOENT")return!1;throw i}}function Cx(t,e,r){if(typeof r!="string")throw new TypeError(`Expected a string, got ${typeof r}`);try{return wJ[t](r)[e]()}catch(i){if(i.code==="ENOENT")return!1;throw i}}Ol.isFile=dx.bind(null,"stat","isFile");Ol.isDirectory=dx.bind(null,"stat","isDirectory");Ol.isSymlink=dx.bind(null,"lstat","isSymbolicLink");Ol.isFileSync=Cx.bind(null,"statSync","isFile");Ol.isDirectorySync=Cx.bind(null,"statSync","isDirectory");Ol.isSymlinkSync=Cx.bind(null,"lstatSync","isSymbolicLink")});var xJ=E((Uit,mx)=>{"use strict";var Kl=require("path"),QJ=BJ(),bJ=t=>t.length>1?`{${t.join(",")}}`:t[0],vJ=(t,e)=>{let r=t[0]==="!"?t.slice(1):t;return Kl.isAbsolute(r)?r:Kl.join(e,r)},uQe=(t,e)=>Kl.extname(t)?`**/${t}`:`**/${t}.${bJ(e)}`,SJ=(t,e)=>{if(e.files&&!Array.isArray(e.files))throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof e.files}\``);if(e.extensions&&!Array.isArray(e.extensions))throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof e.extensions}\``);return e.files&&e.extensions?e.files.map(r=>Kl.posix.join(t,uQe(r,e.extensions))):e.files?e.files.map(r=>Kl.posix.join(t,`**/${r}`)):e.extensions?[Kl.posix.join(t,`**/*.${bJ(e.extensions)}`)]:[Kl.posix.join(t,"**")]};mx.exports=async(t,e)=>{if(e=P({cwd:process.cwd()},e),typeof e.cwd!="string")throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof e.cwd}\``);let r=await Promise.all([].concat(t).map(async i=>await QJ.isDirectory(vJ(i,e.cwd))?SJ(i,e):i));return[].concat.apply([],r)};mx.exports.sync=(t,e)=>{if(e=P({cwd:process.cwd()},e),typeof e.cwd!="string")throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof e.cwd}\``);let r=[].concat(t).map(i=>QJ.isDirectorySync(vJ(i,e.cwd))?SJ(i,e):i);return[].concat.apply([],r)}});var TJ=E((Hit,kJ)=>{function PJ(t){return Array.isArray(t)?t:[t]}var gQe=/^\s+$/,fQe=/^\\!/,hQe=/^\\#/,pQe=/\r?\n/g,dQe=/^\.*\/|^\.+$/,Ex="/",DJ=typeof Symbol!="undefined"?Symbol.for("node-ignore"):"node-ignore",CQe=(t,e,r)=>Object.defineProperty(t,e,{value:r}),mQe=/([0-z])-([0-z])/g,EQe=t=>t.replace(mQe,(e,r,i)=>r.charCodeAt(0)<=i.charCodeAt(0)?e:""),IQe=[[/\\?\s+$/,t=>t.indexOf("\\")===0?" ":""],[/\\\s/g,()=>" "],[/[\\^$.|*+(){]/g,t=>`\\${t}`],[/\[([^\]/]*)($|\])/g,(t,e,r)=>r==="]"?`[${EQe(e)}]`:`\\${t}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/(?:[^*])$/,t=>/\/$/.test(t)?`${t}$`:`${t}(?=$|\\/$)`],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(t,e,r)=>e+6`${e}[^\\/]*`],[/(\^|\\\/)?\\\*$/,(t,e)=>`${e?`${e}[^/]+`:"[^/]*"}(?=$|\\/$)`],[/\\\\\\/g,()=>"\\"]],RJ=Object.create(null),yQe=(t,e,r)=>{let i=RJ[t];if(i)return i;let n=IQe.reduce((s,o)=>s.replace(o[0],o[1].bind(t)),t);return RJ[t]=r?new RegExp(n,"i"):new RegExp(n)},Ix=t=>typeof t=="string",wQe=t=>t&&Ix(t)&&!gQe.test(t)&&t.indexOf("#")!==0,BQe=t=>t.split(pQe),FJ=class{constructor(e,r,i,n){this.origin=e,this.pattern=r,this.negative=i,this.regex=n}},QQe=(t,e)=>{let r=t,i=!1;t.indexOf("!")===0&&(i=!0,t=t.substr(1)),t=t.replace(fQe,"!").replace(hQe,"#");let n=yQe(t,i,e);return new FJ(r,t,i,n)},bQe=(t,e)=>{throw new e(t)},ha=(t,e,r)=>Ix(t)?t?ha.isNotRelative(t)?r(`path should be a \`path.relative()\`d string, but got "${e}"`,RangeError):!0:r("path must not be empty",TypeError):r(`path must be a string, but got \`${e}\``,TypeError),NJ=t=>dQe.test(t);ha.isNotRelative=NJ;ha.convert=t=>t;var LJ=class{constructor({ignorecase:e=!0}={}){this._rules=[],this._ignorecase=e,CQe(this,DJ,!0),this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(e){if(e&&e[DJ]){this._rules=this._rules.concat(e._rules),this._added=!0;return}if(wQe(e)){let r=QQe(e,this._ignorecase);this._added=!0,this._rules.push(r)}}add(e){return this._added=!1,PJ(Ix(e)?BQe(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,r){let i=!1,n=!1;return this._rules.forEach(s=>{let{negative:o}=s;if(n===o&&i!==n||o&&!i&&!n&&!r)return;s.regex.test(e)&&(i=!o,n=o)}),{ignored:i,unignored:n}}_test(e,r,i,n){let s=e&&ha.convert(e);return ha(s,e,bQe),this._t(s,r,i,n)}_t(e,r,i,n){if(e in r)return r[e];if(n||(n=e.split(Ex)),n.pop(),!n.length)return r[e]=this._testOne(e,i);let s=this._t(n.join(Ex)+Ex,r,i,n);return r[e]=s.ignored?s:this._testOne(e,i)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return PJ(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}},fy=t=>new LJ(t),vQe=()=>!1,SQe=t=>ha(t&&ha.convert(t),t,vQe);fy.isPathValid=SQe;fy.default=fy;kJ.exports=fy;if(typeof process!="undefined"&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform==="win32")){let t=r=>/^\\\\\?\\/.test(r)||/["<>|\u0000-\u001F]+/u.test(r)?r:r.replace(/\\/g,"/");ha.convert=t;let e=/^[a-z]:\//i;ha.isNotRelative=r=>e.test(r)||NJ(r)}});var OJ=E((Git,MJ)=>{"use strict";MJ.exports=t=>{let e=/^\\\\\?\\/.test(t),r=/[^\u0000-\u0080]+/.test(t);return e||r?t:t.replace(/\\/g,"/")}});var qJ=E((jit,yx)=>{"use strict";var{promisify:xQe}=require("util"),KJ=require("fs"),pa=require("path"),UJ=gy(),kQe=TJ(),sp=OJ(),HJ=["**/node_modules/**","**/flow-typed/**","**/coverage/**","**/.git"],PQe=xQe(KJ.readFile),DQe=t=>e=>e.startsWith("!")?"!"+pa.posix.join(t,e.slice(1)):pa.posix.join(t,e),RQe=(t,e)=>{let r=sp(pa.relative(e.cwd,pa.dirname(e.fileName)));return t.split(/\r?\n/).filter(Boolean).filter(i=>!i.startsWith("#")).map(DQe(r))},GJ=t=>{let e=kQe();for(let r of t)e.add(RQe(r.content,{cwd:r.cwd,fileName:r.filePath}));return e},FQe=(t,e)=>{if(t=sp(t),pa.isAbsolute(e)){if(sp(e).startsWith(t))return e;throw new Error(`Path ${e} is not in cwd ${t}`)}return pa.join(t,e)},jJ=(t,e)=>r=>t.ignores(sp(pa.relative(e,FQe(e,r.path||r)))),NQe=async(t,e)=>{let r=pa.join(e,t),i=await PQe(r,"utf8");return{cwd:e,filePath:r,content:i}},LQe=(t,e)=>{let r=pa.join(e,t),i=KJ.readFileSync(r,"utf8");return{cwd:e,filePath:r,content:i}},YJ=({ignore:t=[],cwd:e=sp(process.cwd())}={})=>({ignore:t,cwd:e});yx.exports=async t=>{t=YJ(t);let e=await UJ("**/.gitignore",{ignore:HJ.concat(t.ignore),cwd:t.cwd}),r=await Promise.all(e.map(n=>NQe(n,t.cwd))),i=GJ(r);return jJ(i,t.cwd)};yx.exports.sync=t=>{t=YJ(t);let r=UJ.sync("**/.gitignore",{ignore:HJ.concat(t.ignore),cwd:t.cwd}).map(n=>LQe(n,t.cwd)),i=GJ(r);return jJ(i,t.cwd)}});var VJ=E((Yit,JJ)=>{"use strict";var{Transform:TQe}=require("stream"),wx=class extends TQe{constructor(){super({objectMode:!0})}},WJ=class extends wx{constructor(e){super();this._filter=e}_transform(e,r,i){this._filter(e)&&this.push(e),i()}},zJ=class extends wx{constructor(){super();this._pushed=new Set}_transform(e,r,i){this._pushed.has(e)||(this.push(e),this._pushed.add(e)),i()}};JJ.exports={FilterStream:WJ,UniqueStream:zJ}});var vx=E((qit,Ul)=>{"use strict";var _J=require("fs"),hy=QY(),MQe=wS(),py=gy(),dy=xJ(),Bx=qJ(),{FilterStream:OQe,UniqueStream:KQe}=VJ(),XJ=()=>!1,ZJ=t=>t[0]==="!",UQe=t=>{if(!t.every(e=>typeof e=="string"))throw new TypeError("Patterns must be a string or an array of strings")},HQe=(t={})=>{if(!t.cwd)return;let e;try{e=_J.statSync(t.cwd)}catch{return}if(!e.isDirectory())throw new Error("The `cwd` option must be a path to a directory")},GQe=t=>t.stats instanceof _J.Stats?t.path:t,Cy=(t,e)=>{t=hy([].concat(t)),UQe(t),HQe(e);let r=[];e=P({ignore:[],expandDirectories:!0},e);for(let[i,n]of t.entries()){if(ZJ(n))continue;let s=t.slice(i).filter(a=>ZJ(a)).map(a=>a.slice(1)),o=_(P({},e),{ignore:e.ignore.concat(s)});r.push({pattern:n,options:o})}return r},jQe=(t,e)=>{let r={};return t.options.cwd&&(r.cwd=t.options.cwd),Array.isArray(t.options.expandDirectories)?r=_(P({},r),{files:t.options.expandDirectories}):typeof t.options.expandDirectories=="object"&&(r=P(P({},r),t.options.expandDirectories)),e(t.pattern,r)},Qx=(t,e)=>t.options.expandDirectories?jQe(t,e):[t.pattern],$J=t=>t&&t.gitignore?Bx.sync({cwd:t.cwd,ignore:t.ignore}):XJ,bx=t=>e=>{let{options:r}=t;return r.ignore&&Array.isArray(r.ignore)&&r.expandDirectories&&(r.ignore=dy.sync(r.ignore)),{pattern:e,options:r}};Ul.exports=async(t,e)=>{let r=Cy(t,e),i=async()=>e&&e.gitignore?Bx({cwd:e.cwd,ignore:e.ignore}):XJ,n=async()=>{let l=await Promise.all(r.map(async c=>{let u=await Qx(c,dy);return Promise.all(u.map(bx(c)))}));return hy(...l)},[s,o]=await Promise.all([i(),n()]),a=await Promise.all(o.map(l=>py(l.pattern,l.options)));return hy(...a).filter(l=>!s(GQe(l)))};Ul.exports.sync=(t,e)=>{let r=Cy(t,e),i=[];for(let o of r){let a=Qx(o,dy.sync).map(bx(o));i.push(...a)}let n=$J(e),s=[];for(let o of i)s=hy(s,py.sync(o.pattern,o.options));return s.filter(o=>!n(o))};Ul.exports.stream=(t,e)=>{let r=Cy(t,e),i=[];for(let a of r){let l=Qx(a,dy.sync).map(bx(a));i.push(...l)}let n=$J(e),s=new OQe(a=>!n(a)),o=new KQe;return MQe(i.map(a=>py.stream(a.pattern,a.options))).pipe(s).pipe(o)};Ul.exports.generateGlobTasks=Cy;Ul.exports.hasMagic=(t,e)=>[].concat(t).some(r=>py.isDynamicPattern(r,e));Ul.exports.gitignore=Bx});var Ca=E((da,Dy)=>{"use strict";Object.defineProperty(da,"__esModule",{value:!0});var A3=["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];function ibe(t){return A3.includes(t)}var nbe=["Function","Generator","AsyncGenerator","GeneratorFunction","AsyncGeneratorFunction","AsyncFunction","Observable","Array","Buffer","Object","RegExp","Date","Error","Map","Set","WeakMap","WeakSet","ArrayBuffer","SharedArrayBuffer","DataView","Promise","URL","FormData","URLSearchParams","HTMLElement",...A3];function sbe(t){return nbe.includes(t)}var obe=["null","undefined","string","number","bigint","boolean","symbol"];function abe(t){return obe.includes(t)}function Hu(t){return e=>typeof e===t}var{toString:l3}=Object.prototype,mp=t=>{let e=l3.call(t).slice(8,-1);if(/HTML\w+Element/.test(e)&&j.domElement(t))return"HTMLElement";if(sbe(e))return e},er=t=>e=>mp(e)===t;function j(t){if(t===null)return"null";switch(typeof t){case"undefined":return"undefined";case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"function":return"Function";case"bigint":return"bigint";case"symbol":return"symbol";default:}if(j.observable(t))return"Observable";if(j.array(t))return"Array";if(j.buffer(t))return"Buffer";let e=mp(t);if(e)return e;if(t instanceof String||t instanceof Boolean||t instanceof Number)throw new TypeError("Please don't use object wrappers for primitive types");return"Object"}j.undefined=Hu("undefined");j.string=Hu("string");var Abe=Hu("number");j.number=t=>Abe(t)&&!j.nan(t);j.bigint=Hu("bigint");j.function_=Hu("function");j.null_=t=>t===null;j.class_=t=>j.function_(t)&&t.toString().startsWith("class ");j.boolean=t=>t===!0||t===!1;j.symbol=Hu("symbol");j.numericString=t=>j.string(t)&&!j.emptyStringOrWhitespace(t)&&!Number.isNaN(Number(t));j.array=(t,e)=>Array.isArray(t)?j.function_(e)?t.every(e):!0:!1;j.buffer=t=>{var e,r,i,n;return(n=(i=(r=(e=t)===null||e===void 0?void 0:e.constructor)===null||r===void 0?void 0:r.isBuffer)===null||i===void 0?void 0:i.call(r,t))!==null&&n!==void 0?n:!1};j.nullOrUndefined=t=>j.null_(t)||j.undefined(t);j.object=t=>!j.null_(t)&&(typeof t=="object"||j.function_(t));j.iterable=t=>{var e;return j.function_((e=t)===null||e===void 0?void 0:e[Symbol.iterator])};j.asyncIterable=t=>{var e;return j.function_((e=t)===null||e===void 0?void 0:e[Symbol.asyncIterator])};j.generator=t=>j.iterable(t)&&j.function_(t.next)&&j.function_(t.throw);j.asyncGenerator=t=>j.asyncIterable(t)&&j.function_(t.next)&&j.function_(t.throw);j.nativePromise=t=>er("Promise")(t);var lbe=t=>{var e,r;return j.function_((e=t)===null||e===void 0?void 0:e.then)&&j.function_((r=t)===null||r===void 0?void 0:r.catch)};j.promise=t=>j.nativePromise(t)||lbe(t);j.generatorFunction=er("GeneratorFunction");j.asyncGeneratorFunction=t=>mp(t)==="AsyncGeneratorFunction";j.asyncFunction=t=>mp(t)==="AsyncFunction";j.boundFunction=t=>j.function_(t)&&!t.hasOwnProperty("prototype");j.regExp=er("RegExp");j.date=er("Date");j.error=er("Error");j.map=t=>er("Map")(t);j.set=t=>er("Set")(t);j.weakMap=t=>er("WeakMap")(t);j.weakSet=t=>er("WeakSet")(t);j.int8Array=er("Int8Array");j.uint8Array=er("Uint8Array");j.uint8ClampedArray=er("Uint8ClampedArray");j.int16Array=er("Int16Array");j.uint16Array=er("Uint16Array");j.int32Array=er("Int32Array");j.uint32Array=er("Uint32Array");j.float32Array=er("Float32Array");j.float64Array=er("Float64Array");j.bigInt64Array=er("BigInt64Array");j.bigUint64Array=er("BigUint64Array");j.arrayBuffer=er("ArrayBuffer");j.sharedArrayBuffer=er("SharedArrayBuffer");j.dataView=er("DataView");j.directInstanceOf=(t,e)=>Object.getPrototypeOf(t)===e.prototype;j.urlInstance=t=>er("URL")(t);j.urlString=t=>{if(!j.string(t))return!1;try{return new URL(t),!0}catch(e){return!1}};j.truthy=t=>Boolean(t);j.falsy=t=>!t;j.nan=t=>Number.isNaN(t);j.primitive=t=>j.null_(t)||abe(typeof t);j.integer=t=>Number.isInteger(t);j.safeInteger=t=>Number.isSafeInteger(t);j.plainObject=t=>{if(l3.call(t)!=="[object Object]")return!1;let e=Object.getPrototypeOf(t);return e===null||e===Object.getPrototypeOf({})};j.typedArray=t=>ibe(mp(t));var cbe=t=>j.safeInteger(t)&&t>=0;j.arrayLike=t=>!j.nullOrUndefined(t)&&!j.function_(t)&&cbe(t.length);j.inRange=(t,e)=>{if(j.number(e))return t>=Math.min(0,e)&&t<=Math.max(e,0);if(j.array(e)&&e.length===2)return t>=Math.min(...e)&&t<=Math.max(...e);throw new TypeError(`Invalid range: ${JSON.stringify(e)}`)};var ube=1,gbe=["innerHTML","ownerDocument","style","attributes","nodeValue"];j.domElement=t=>j.object(t)&&t.nodeType===ube&&j.string(t.nodeName)&&!j.plainObject(t)&&gbe.every(e=>e in t);j.observable=t=>{var e,r,i,n;return t?t===((r=(e=t)[Symbol.observable])===null||r===void 0?void 0:r.call(e))||t===((n=(i=t)["@@observable"])===null||n===void 0?void 0:n.call(i)):!1};j.nodeStream=t=>j.object(t)&&j.function_(t.pipe)&&!j.observable(t);j.infinite=t=>t===Infinity||t===-Infinity;var c3=t=>e=>j.integer(e)&&Math.abs(e%2)===t;j.evenInteger=c3(0);j.oddInteger=c3(1);j.emptyArray=t=>j.array(t)&&t.length===0;j.nonEmptyArray=t=>j.array(t)&&t.length>0;j.emptyString=t=>j.string(t)&&t.length===0;j.nonEmptyString=t=>j.string(t)&&t.length>0;var fbe=t=>j.string(t)&&!/\S/.test(t);j.emptyStringOrWhitespace=t=>j.emptyString(t)||fbe(t);j.emptyObject=t=>j.object(t)&&!j.map(t)&&!j.set(t)&&Object.keys(t).length===0;j.nonEmptyObject=t=>j.object(t)&&!j.map(t)&&!j.set(t)&&Object.keys(t).length>0;j.emptySet=t=>j.set(t)&&t.size===0;j.nonEmptySet=t=>j.set(t)&&t.size>0;j.emptyMap=t=>j.map(t)&&t.size===0;j.nonEmptyMap=t=>j.map(t)&&t.size>0;j.propertyKey=t=>j.any([j.string,j.number,j.symbol],t);j.formData=t=>er("FormData")(t);j.urlSearchParams=t=>er("URLSearchParams")(t);var u3=(t,e,r)=>{if(!j.function_(e))throw new TypeError(`Invalid predicate: ${JSON.stringify(e)}`);if(r.length===0)throw new TypeError("Invalid number of values");return t.call(r,e)};j.any=(t,...e)=>(j.array(t)?t:[t]).some(i=>u3(Array.prototype.some,i,e));j.all=(t,...e)=>u3(Array.prototype.every,t,e);var Te=(t,e,r,i={})=>{if(!t){let{multipleValues:n}=i,s=n?`received values of types ${[...new Set(r.map(o=>`\`${j(o)}\``))].join(", ")}`:`received value of type \`${j(r)}\``;throw new TypeError(`Expected value which is \`${e}\`, ${s}.`)}};da.assert={undefined:t=>Te(j.undefined(t),"undefined",t),string:t=>Te(j.string(t),"string",t),number:t=>Te(j.number(t),"number",t),bigint:t=>Te(j.bigint(t),"bigint",t),function_:t=>Te(j.function_(t),"Function",t),null_:t=>Te(j.null_(t),"null",t),class_:t=>Te(j.class_(t),"Class",t),boolean:t=>Te(j.boolean(t),"boolean",t),symbol:t=>Te(j.symbol(t),"symbol",t),numericString:t=>Te(j.numericString(t),"string with a number",t),array:(t,e)=>{Te(j.array(t),"Array",t),e&&t.forEach(e)},buffer:t=>Te(j.buffer(t),"Buffer",t),nullOrUndefined:t=>Te(j.nullOrUndefined(t),"null or undefined",t),object:t=>Te(j.object(t),"Object",t),iterable:t=>Te(j.iterable(t),"Iterable",t),asyncIterable:t=>Te(j.asyncIterable(t),"AsyncIterable",t),generator:t=>Te(j.generator(t),"Generator",t),asyncGenerator:t=>Te(j.asyncGenerator(t),"AsyncGenerator",t),nativePromise:t=>Te(j.nativePromise(t),"native Promise",t),promise:t=>Te(j.promise(t),"Promise",t),generatorFunction:t=>Te(j.generatorFunction(t),"GeneratorFunction",t),asyncGeneratorFunction:t=>Te(j.asyncGeneratorFunction(t),"AsyncGeneratorFunction",t),asyncFunction:t=>Te(j.asyncFunction(t),"AsyncFunction",t),boundFunction:t=>Te(j.boundFunction(t),"Function",t),regExp:t=>Te(j.regExp(t),"RegExp",t),date:t=>Te(j.date(t),"Date",t),error:t=>Te(j.error(t),"Error",t),map:t=>Te(j.map(t),"Map",t),set:t=>Te(j.set(t),"Set",t),weakMap:t=>Te(j.weakMap(t),"WeakMap",t),weakSet:t=>Te(j.weakSet(t),"WeakSet",t),int8Array:t=>Te(j.int8Array(t),"Int8Array",t),uint8Array:t=>Te(j.uint8Array(t),"Uint8Array",t),uint8ClampedArray:t=>Te(j.uint8ClampedArray(t),"Uint8ClampedArray",t),int16Array:t=>Te(j.int16Array(t),"Int16Array",t),uint16Array:t=>Te(j.uint16Array(t),"Uint16Array",t),int32Array:t=>Te(j.int32Array(t),"Int32Array",t),uint32Array:t=>Te(j.uint32Array(t),"Uint32Array",t),float32Array:t=>Te(j.float32Array(t),"Float32Array",t),float64Array:t=>Te(j.float64Array(t),"Float64Array",t),bigInt64Array:t=>Te(j.bigInt64Array(t),"BigInt64Array",t),bigUint64Array:t=>Te(j.bigUint64Array(t),"BigUint64Array",t),arrayBuffer:t=>Te(j.arrayBuffer(t),"ArrayBuffer",t),sharedArrayBuffer:t=>Te(j.sharedArrayBuffer(t),"SharedArrayBuffer",t),dataView:t=>Te(j.dataView(t),"DataView",t),urlInstance:t=>Te(j.urlInstance(t),"URL",t),urlString:t=>Te(j.urlString(t),"string with a URL",t),truthy:t=>Te(j.truthy(t),"truthy",t),falsy:t=>Te(j.falsy(t),"falsy",t),nan:t=>Te(j.nan(t),"NaN",t),primitive:t=>Te(j.primitive(t),"primitive",t),integer:t=>Te(j.integer(t),"integer",t),safeInteger:t=>Te(j.safeInteger(t),"integer",t),plainObject:t=>Te(j.plainObject(t),"plain object",t),typedArray:t=>Te(j.typedArray(t),"TypedArray",t),arrayLike:t=>Te(j.arrayLike(t),"array-like",t),domElement:t=>Te(j.domElement(t),"HTMLElement",t),observable:t=>Te(j.observable(t),"Observable",t),nodeStream:t=>Te(j.nodeStream(t),"Node.js Stream",t),infinite:t=>Te(j.infinite(t),"infinite number",t),emptyArray:t=>Te(j.emptyArray(t),"empty array",t),nonEmptyArray:t=>Te(j.nonEmptyArray(t),"non-empty array",t),emptyString:t=>Te(j.emptyString(t),"empty string",t),nonEmptyString:t=>Te(j.nonEmptyString(t),"non-empty string",t),emptyStringOrWhitespace:t=>Te(j.emptyStringOrWhitespace(t),"empty string or whitespace",t),emptyObject:t=>Te(j.emptyObject(t),"empty object",t),nonEmptyObject:t=>Te(j.nonEmptyObject(t),"non-empty object",t),emptySet:t=>Te(j.emptySet(t),"empty set",t),nonEmptySet:t=>Te(j.nonEmptySet(t),"non-empty set",t),emptyMap:t=>Te(j.emptyMap(t),"empty map",t),nonEmptyMap:t=>Te(j.nonEmptyMap(t),"non-empty map",t),propertyKey:t=>Te(j.propertyKey(t),"PropertyKey",t),formData:t=>Te(j.formData(t),"FormData",t),urlSearchParams:t=>Te(j.urlSearchParams(t),"URLSearchParams",t),evenInteger:t=>Te(j.evenInteger(t),"even integer",t),oddInteger:t=>Te(j.oddInteger(t),"odd integer",t),directInstanceOf:(t,e)=>Te(j.directInstanceOf(t,e),"T",t),inRange:(t,e)=>Te(j.inRange(t,e),"in range",t),any:(t,...e)=>Te(j.any(t,...e),"predicate returns truthy for any value",e,{multipleValues:!0}),all:(t,...e)=>Te(j.all(t,...e),"predicate returns truthy for all values",e,{multipleValues:!0})};Object.defineProperties(j,{class:{value:j.class_},function:{value:j.function_},null:{value:j.null_}});Object.defineProperties(da.assert,{class:{value:da.assert.class_},function:{value:da.assert.function_},null:{value:da.assert.null_}});da.default=j;Dy.exports=j;Dy.exports.default=j;Dy.exports.assert=da.assert});var g3=E((gnt,Ux)=>{"use strict";var Hx=class extends Error{constructor(e){super(e||"Promise was canceled");this.name="CancelError"}get isCanceled(){return!0}},Ep=class{static fn(e){return(...r)=>new Ep((i,n,s)=>{r.push(s),e(...r).then(i,n)})}constructor(e){this._cancelHandlers=[],this._isPending=!0,this._isCanceled=!1,this._rejectOnCancel=!0,this._promise=new Promise((r,i)=>{this._reject=i;let n=a=>{this._isPending=!1,r(a)},s=a=>{this._isPending=!1,i(a)},o=a=>{if(!this._isPending)throw new Error("The `onCancel` handler was attached after the promise settled.");this._cancelHandlers.push(a)};return Object.defineProperties(o,{shouldReject:{get:()=>this._rejectOnCancel,set:a=>{this._rejectOnCancel=a}}}),e(n,s,o)})}then(e,r){return this._promise.then(e,r)}catch(e){return this._promise.catch(e)}finally(e){return this._promise.finally(e)}cancel(e){if(!(!this._isPending||this._isCanceled)){if(this._cancelHandlers.length>0)try{for(let r of this._cancelHandlers)r()}catch(r){this._reject(r)}this._isCanceled=!0,this._rejectOnCancel&&this._reject(new Hx(e))}}get isCanceled(){return this._isCanceled}};Object.setPrototypeOf(Ep.prototype,Promise.prototype);Ux.exports=Ep;Ux.exports.CancelError=Hx});var f3=E((Gx,jx)=>{"use strict";Object.defineProperty(Gx,"__esModule",{value:!0});var hbe=require("tls"),Yx=(t,e)=>{let r;typeof e=="function"?r={connect:e}:r=e;let i=typeof r.connect=="function",n=typeof r.secureConnect=="function",s=typeof r.close=="function",o=()=>{i&&r.connect(),t instanceof hbe.TLSSocket&&n&&(t.authorized?r.secureConnect():t.authorizationError||t.once("secureConnect",r.secureConnect)),s&&t.once("close",r.close)};t.writable&&!t.connecting?o():t.connecting?t.once("connect",o):t.destroyed&&s&&r.close(t._hadError)};Gx.default=Yx;jx.exports=Yx;jx.exports.default=Yx});var h3=E((qx,Jx)=>{"use strict";Object.defineProperty(qx,"__esModule",{value:!0});var pbe=f3(),dbe=Number(process.versions.node.split(".")[0]),Wx=t=>{let e={start:Date.now(),socket:void 0,lookup:void 0,connect:void 0,secureConnect:void 0,upload:void 0,response:void 0,end:void 0,error:void 0,abort:void 0,phases:{wait:void 0,dns:void 0,tcp:void 0,tls:void 0,request:void 0,firstByte:void 0,download:void 0,total:void 0}};t.timings=e;let r=o=>{let a=o.emit.bind(o);o.emit=(l,...c)=>(l==="error"&&(e.error=Date.now(),e.phases.total=e.error-e.start,o.emit=a),a(l,...c))};r(t),t.prependOnceListener("abort",()=>{e.abort=Date.now(),(!e.response||dbe>=13)&&(e.phases.total=Date.now()-e.start)});let i=o=>{e.socket=Date.now(),e.phases.wait=e.socket-e.start;let a=()=>{e.lookup=Date.now(),e.phases.dns=e.lookup-e.socket};o.prependOnceListener("lookup",a),pbe.default(o,{connect:()=>{e.connect=Date.now(),e.lookup===void 0&&(o.removeListener("lookup",a),e.lookup=e.connect,e.phases.dns=e.lookup-e.socket),e.phases.tcp=e.connect-e.lookup},secureConnect:()=>{e.secureConnect=Date.now(),e.phases.tls=e.secureConnect-e.connect}})};t.socket?i(t.socket):t.prependOnceListener("socket",i);let n=()=>{var o;e.upload=Date.now(),e.phases.request=e.upload-(o=e.secureConnect,o!=null?o:e.connect)};return(()=>typeof t.writableFinished=="boolean"?t.writableFinished:t.finished&&t.outputSize===0&&(!t.socket||t.socket.writableLength===0))()?n():t.prependOnceListener("finish",n),t.prependOnceListener("response",o=>{e.response=Date.now(),e.phases.firstByte=e.response-e.upload,o.timings=e,r(o),o.prependOnceListener("end",()=>{e.end=Date.now(),e.phases.download=e.end-e.response,e.phases.total=e.end-e.start})}),e};qx.default=Wx;Jx.exports=Wx;Jx.exports.default=Wx});var y3=E((fnt,zx)=>{"use strict";var{V4MAPPED:Cbe,ADDRCONFIG:mbe,ALL:p3,promises:{Resolver:d3},lookup:Ebe}=require("dns"),{promisify:Vx}=require("util"),Ibe=require("os"),Gu=Symbol("cacheableLookupCreateConnection"),_x=Symbol("cacheableLookupInstance"),C3=Symbol("expires"),ybe=typeof p3=="number",m3=t=>{if(!(t&&typeof t.createConnection=="function"))throw new Error("Expected an Agent instance as the first argument")},wbe=t=>{for(let e of t)e.family!==6&&(e.address=`::ffff:${e.address}`,e.family=6)},E3=()=>{let t=!1,e=!1;for(let r of Object.values(Ibe.networkInterfaces()))for(let i of r)if(!i.internal&&(i.family==="IPv6"?e=!0:t=!0,t&&e))return{has4:t,has6:e};return{has4:t,has6:e}},Bbe=t=>Symbol.iterator in t,I3={ttl:!0},Qbe={all:!0},Xx=class{constructor({cache:e=new Map,maxTtl:r=Infinity,fallbackDuration:i=3600,errorTtl:n=.15,resolver:s=new d3,lookup:o=Ebe}={}){if(this.maxTtl=r,this.errorTtl=n,this._cache=e,this._resolver=s,this._dnsLookup=Vx(o),this._resolver instanceof d3?(this._resolve4=this._resolver.resolve4.bind(this._resolver),this._resolve6=this._resolver.resolve6.bind(this._resolver)):(this._resolve4=Vx(this._resolver.resolve4.bind(this._resolver)),this._resolve6=Vx(this._resolver.resolve6.bind(this._resolver))),this._iface=E3(),this._pending={},this._nextRemovalTime=!1,this._hostnamesToFallback=new Set,i<1)this._fallback=!1;else{this._fallback=!0;let a=setInterval(()=>{this._hostnamesToFallback.clear()},i*1e3);a.unref&&a.unref()}this.lookup=this.lookup.bind(this),this.lookupAsync=this.lookupAsync.bind(this)}set servers(e){this.clear(),this._resolver.setServers(e)}get servers(){return this._resolver.getServers()}lookup(e,r,i){if(typeof r=="function"?(i=r,r={}):typeof r=="number"&&(r={family:r}),!i)throw new Error("Callback must be a function.");this.lookupAsync(e,r).then(n=>{r.all?i(null,n):i(null,n.address,n.family,n.expires,n.ttl)},i)}async lookupAsync(e,r={}){typeof r=="number"&&(r={family:r});let i=await this.query(e);if(r.family===6){let n=i.filter(s=>s.family===6);r.hints&Cbe&&(ybe&&r.hints&p3||n.length===0)?wbe(i):i=n}else r.family===4&&(i=i.filter(n=>n.family===4));if(r.hints&mbe){let{_iface:n}=this;i=i.filter(s=>s.family===6?n.has6:n.has4)}if(i.length===0){let n=new Error(`cacheableLookup ENOTFOUND ${e}`);throw n.code="ENOTFOUND",n.hostname=e,n}return r.all?i:i[0]}async query(e){let r=await this._cache.get(e);if(!r){let i=this._pending[e];if(i)r=await i;else{let n=this.queryAndCache(e);this._pending[e]=n,r=await n}}return r=r.map(i=>P({},i)),r}async _resolve(e){let r=async c=>{try{return await c}catch(u){if(u.code==="ENODATA"||u.code==="ENOTFOUND")return[];throw u}},[i,n]=await Promise.all([this._resolve4(e,I3),this._resolve6(e,I3)].map(c=>r(c))),s=0,o=0,a=0,l=Date.now();for(let c of i)c.family=4,c.expires=l+c.ttl*1e3,s=Math.max(s,c.ttl);for(let c of n)c.family=6,c.expires=l+c.ttl*1e3,o=Math.max(o,c.ttl);return i.length>0?n.length>0?a=Math.min(s,o):a=s:a=o,{entries:[...i,...n],cacheTtl:a}}async _lookup(e){try{return{entries:await this._dnsLookup(e,{all:!0}),cacheTtl:0}}catch(r){return{entries:[],cacheTtl:0}}}async _set(e,r,i){if(this.maxTtl>0&&i>0){i=Math.min(i,this.maxTtl)*1e3,r[C3]=Date.now()+i;try{await this._cache.set(e,r,i)}catch(n){this.lookupAsync=async()=>{let s=new Error("Cache Error. Please recreate the CacheableLookup instance.");throw s.cause=n,s}}Bbe(this._cache)&&this._tick(i)}}async queryAndCache(e){if(this._hostnamesToFallback.has(e))return this._dnsLookup(e,Qbe);try{let r=await this._resolve(e);r.entries.length===0&&this._fallback&&(r=await this._lookup(e),r.entries.length!==0&&this._hostnamesToFallback.add(e));let i=r.entries.length===0?this.errorTtl:r.cacheTtl;return await this._set(e,r.entries,i),delete this._pending[e],r.entries}catch(r){throw delete this._pending[e],r}}_tick(e){let r=this._nextRemovalTime;(!r||e{this._nextRemovalTime=!1;let i=Infinity,n=Date.now();for(let[s,o]of this._cache){let a=o[C3];n>=a?this._cache.delete(s):a("lookup"in r||(r.lookup=this.lookup),e[Gu](r,i))}uninstall(e){if(m3(e),e[Gu]){if(e[_x]!==this)throw new Error("The agent is not owned by this CacheableLookup instance");e.createConnection=e[Gu],delete e[Gu],delete e[_x]}}updateInterfaceInfo(){let{_iface:e}=this;this._iface=E3(),(e.has4&&!this._iface.has4||e.has6&&!this._iface.has6)&&this._cache.clear()}clear(e){if(e){this._cache.delete(e);return}this._cache.clear()}};zx.exports=Xx;zx.exports.default=Xx});var Q3=E((hnt,Zx)=>{"use strict";var bbe=typeof URL=="undefined"?require("url").URL:URL,vbe="text/plain",Sbe="us-ascii",w3=(t,e)=>e.some(r=>r instanceof RegExp?r.test(t):r===t),xbe=(t,{stripHash:e})=>{let r=t.match(/^data:([^,]*?),([^#]*?)(?:#(.*))?$/);if(!r)throw new Error(`Invalid URL: ${t}`);let i=r[1].split(";"),n=r[2],s=e?"":r[3],o=!1;i[i.length-1]==="base64"&&(i.pop(),o=!0);let a=(i.shift()||"").toLowerCase(),c=[...i.map(u=>{let[g,f=""]=u.split("=").map(h=>h.trim());return g==="charset"&&(f=f.toLowerCase(),f===Sbe)?"":`${g}${f?`=${f}`:""}`}).filter(Boolean)];return o&&c.push("base64"),(c.length!==0||a&&a!==vbe)&&c.unshift(a),`data:${c.join(";")},${o?n.trim():n}${s?`#${s}`:""}`},B3=(t,e)=>{if(e=P({defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0},e),Reflect.has(e,"normalizeHttps"))throw new Error("options.normalizeHttps is renamed to options.forceHttp");if(Reflect.has(e,"normalizeHttp"))throw new Error("options.normalizeHttp is renamed to options.forceHttps");if(Reflect.has(e,"stripFragment"))throw new Error("options.stripFragment is renamed to options.stripHash");if(t=t.trim(),/^data:/i.test(t))return xbe(t,e);let r=t.startsWith("//");!r&&/^\.*\//.test(t)||(t=t.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let n=new bbe(t);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&n.protocol==="https:"&&(n.protocol="http:"),e.forceHttps&&n.protocol==="http:"&&(n.protocol="https:"),e.stripAuthentication&&(n.username="",n.password=""),e.stripHash&&(n.hash=""),n.pathname&&(n.pathname=n.pathname.replace(/((?!:).|^)\/{2,}/g,(s,o)=>/^(?!\/)/g.test(o)?`${o}/`:"/")),n.pathname&&(n.pathname=decodeURI(n.pathname)),e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let s=n.pathname.split("/"),o=s[s.length-1];w3(o,e.removeDirectoryIndex)&&(s=s.slice(0,s.length-1),n.pathname=s.slice(1).join("/")+"/")}if(n.hostname&&(n.hostname=n.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(n.hostname)&&(n.hostname=n.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let s of[...n.searchParams.keys()])w3(s,e.removeQueryParameters)&&n.searchParams.delete(s);return e.sortQueryParameters&&n.searchParams.sort(),e.removeTrailingSlash&&(n.pathname=n.pathname.replace(/\/$/,"")),t=n.toString(),(e.removeTrailingSlash||n.pathname==="/")&&n.hash===""&&(t=t.replace(/\/$/,"")),r&&!e.normalizeProtocol&&(t=t.replace(/^http:\/\//,"//")),e.stripProtocol&&(t=t.replace(/^(?:https?:)?\/\//,"")),t};Zx.exports=B3;Zx.exports.default=B3});var S3=E((pnt,b3)=>{b3.exports=v3;function v3(t,e){if(t&&e)return v3(t)(e);if(typeof t!="function")throw new TypeError("need wrapper function");return Object.keys(t).forEach(function(i){r[i]=t[i]}),r;function r(){for(var i=new Array(arguments.length),n=0;n{var x3=S3();$x.exports=x3(Ry);$x.exports.strict=x3(k3);Ry.proto=Ry(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return Ry(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return k3(this)},configurable:!0})});function Ry(t){var e=function(){return e.called?e.value:(e.called=!0,e.value=t.apply(this,arguments))};return e.called=!1,e}function k3(t){var e=function(){if(e.called)throw new Error(e.onceError);return e.called=!0,e.value=t.apply(this,arguments)},r=t.name||"Function wrapped with `once`";return e.onceError=r+" shouldn't be called more than once",e.called=!1,e}});var tk=E((Cnt,P3)=>{var kbe=ek(),Pbe=function(){},Dbe=function(t){return t.setHeader&&typeof t.abort=="function"},Rbe=function(t){return t.stdio&&Array.isArray(t.stdio)&&t.stdio.length===3},D3=function(t,e,r){if(typeof e=="function")return D3(t,null,e);e||(e={}),r=kbe(r||Pbe);var i=t._writableState,n=t._readableState,s=e.readable||e.readable!==!1&&t.readable,o=e.writable||e.writable!==!1&&t.writable,a=function(){t.writable||l()},l=function(){o=!1,s||r.call(t)},c=function(){s=!1,o||r.call(t)},u=function(p){r.call(t,p?new Error("exited with error code: "+p):null)},g=function(p){r.call(t,p)},f=function(){if(s&&!(n&&n.ended))return r.call(t,new Error("premature close"));if(o&&!(i&&i.ended))return r.call(t,new Error("premature close"))},h=function(){t.req.on("finish",l)};return Dbe(t)?(t.on("complete",l),t.on("abort",f),t.req?h():t.on("request",h)):o&&!i&&(t.on("end",a),t.on("close",a)),Rbe(t)&&t.on("exit",u),t.on("end",c),t.on("finish",l),e.error!==!1&&t.on("error",g),t.on("close",f),function(){t.removeListener("complete",l),t.removeListener("abort",f),t.removeListener("request",h),t.req&&t.req.removeListener("finish",l),t.removeListener("end",a),t.removeListener("close",a),t.removeListener("finish",l),t.removeListener("exit",u),t.removeListener("end",c),t.removeListener("error",g),t.removeListener("close",f)}};P3.exports=D3});var N3=E((mnt,R3)=>{var Fbe=ek(),Nbe=tk(),rk=require("fs"),Ip=function(){},Lbe=/^v?\.0/.test(process.version),Fy=function(t){return typeof t=="function"},Tbe=function(t){return!Lbe||!rk?!1:(t instanceof(rk.ReadStream||Ip)||t instanceof(rk.WriteStream||Ip))&&Fy(t.close)},Mbe=function(t){return t.setHeader&&Fy(t.abort)},Obe=function(t,e,r,i){i=Fbe(i);var n=!1;t.on("close",function(){n=!0}),Nbe(t,{readable:e,writable:r},function(o){if(o)return i(o);n=!0,i()});var s=!1;return function(o){if(!n&&!s){if(s=!0,Tbe(t))return t.close(Ip);if(Mbe(t))return t.abort();if(Fy(t.destroy))return t.destroy();i(o||new Error("stream was destroyed"))}}},F3=function(t){t()},Kbe=function(t,e){return t.pipe(e)},Ube=function(){var t=Array.prototype.slice.call(arguments),e=Fy(t[t.length-1]||Ip)&&t.pop()||Ip;if(Array.isArray(t[0])&&(t=t[0]),t.length<2)throw new Error("pump requires two streams per minimum");var r,i=t.map(function(n,s){var o=s0;return Obe(n,o,a,function(l){r||(r=l),l&&i.forEach(F3),!o&&(i.forEach(F3),e(r))})});return t.reduce(Kbe)};R3.exports=Ube});var T3=E((Ent,L3)=>{"use strict";var{PassThrough:Hbe}=require("stream");L3.exports=t=>{t=P({},t);let{array:e}=t,{encoding:r}=t,i=r==="buffer",n=!1;e?n=!(r||i):r=r||"utf8",i&&(r=null);let s=new Hbe({objectMode:n});r&&s.setEncoding(r);let o=0,a=[];return s.on("data",l=>{a.push(l),n?o=a.length:o+=l.length}),s.getBufferedValue=()=>e?a:i?Buffer.concat(a,o):a.join(""),s.getBufferedLength=()=>o,s}});var M3=E((Int,ju)=>{"use strict";var Gbe=N3(),jbe=T3(),ik=class extends Error{constructor(){super("maxBuffer exceeded");this.name="MaxBufferError"}};async function Ny(t,e){if(!t)return Promise.reject(new Error("Expected a stream"));e=P({maxBuffer:Infinity},e);let{maxBuffer:r}=e,i;return await new Promise((n,s)=>{let o=a=>{a&&(a.bufferedData=i.getBufferedValue()),s(a)};i=Gbe(t,jbe(e),a=>{if(a){o(a);return}n()}),i.on("data",()=>{i.getBufferedLength()>r&&o(new ik)})}),i.getBufferedValue()}ju.exports=Ny;ju.exports.default=Ny;ju.exports.buffer=(t,e)=>Ny(t,_(P({},e),{encoding:"buffer"}));ju.exports.array=(t,e)=>Ny(t,_(P({},e),{array:!0}));ju.exports.MaxBufferError=ik});var K3=E((wnt,O3)=>{"use strict";var Ybe=[200,203,204,206,300,301,404,405,410,414,501],qbe=[200,203,204,300,301,302,303,307,308,404,405,410,414,501],Jbe={date:!0,connection:!0,"keep-alive":!0,"proxy-authenticate":!0,"proxy-authorization":!0,te:!0,trailer:!0,"transfer-encoding":!0,upgrade:!0},Wbe={"content-length":!0,"content-encoding":!0,"transfer-encoding":!0,"content-range":!0};function nk(t){let e={};if(!t)return e;let r=t.trim().split(/\s*,\s*/);for(let i of r){let[n,s]=i.split(/\s*=\s*/,2);e[n]=s===void 0?!0:s.replace(/^"|"$/g,"")}return e}function zbe(t){let e=[];for(let r in t){let i=t[r];e.push(i===!0?r:r+"="+i)}if(!!e.length)return e.join(", ")}O3.exports=class{constructor(e,r,{shared:i,cacheHeuristic:n,immutableMinTimeToLive:s,ignoreCargoCult:o,trustServerDate:a,_fromObject:l}={}){if(l){this._fromObject(l);return}if(!r||!r.headers)throw Error("Response headers missing");this._assertRequestHasHeaders(e),this._responseTime=this.now(),this._isShared=i!==!1,this._trustServerDate=a!==void 0?a:!0,this._cacheHeuristic=n!==void 0?n:.1,this._immutableMinTtl=s!==void 0?s:24*3600*1e3,this._status="status"in r?r.status:200,this._resHeaders=r.headers,this._rescc=nk(r.headers["cache-control"]),this._method="method"in e?e.method:"GET",this._url=e.url,this._host=e.headers.host,this._noAuthorization=!e.headers.authorization,this._reqHeaders=r.headers.vary?e.headers:null,this._reqcc=nk(e.headers["cache-control"]),o&&"pre-check"in this._rescc&&"post-check"in this._rescc&&(delete this._rescc["pre-check"],delete this._rescc["post-check"],delete this._rescc["no-cache"],delete this._rescc["no-store"],delete this._rescc["must-revalidate"],this._resHeaders=Object.assign({},this._resHeaders,{"cache-control":zbe(this._rescc)}),delete this._resHeaders.expires,delete this._resHeaders.pragma),!r.headers["cache-control"]&&/no-cache/.test(r.headers.pragma)&&(this._rescc["no-cache"]=!0)}now(){return Date.now()}storable(){return!!(!this._reqcc["no-store"]&&(this._method==="GET"||this._method==="HEAD"||this._method==="POST"&&this._hasExplicitExpiration())&&qbe.indexOf(this._status)!==-1&&!this._rescc["no-store"]&&(!this._isShared||!this._rescc.private)&&(!this._isShared||this._noAuthorization||this._allowsStoringAuthenticated())&&(this._resHeaders.expires||this._rescc.public||this._rescc["max-age"]||this._rescc["s-maxage"]||Ybe.indexOf(this._status)!==-1))}_hasExplicitExpiration(){return this._isShared&&this._rescc["s-maxage"]||this._rescc["max-age"]||this._resHeaders.expires}_assertRequestHasHeaders(e){if(!e||!e.headers)throw Error("Request headers missing")}satisfiesWithoutRevalidation(e){this._assertRequestHasHeaders(e);let r=nk(e.headers["cache-control"]);return r["no-cache"]||/no-cache/.test(e.headers.pragma)||r["max-age"]&&this.age()>r["max-age"]||r["min-fresh"]&&this.timeToLive()<1e3*r["min-fresh"]||this.stale()&&!(r["max-stale"]&&!this._rescc["must-revalidate"]&&(r["max-stale"]===!0||r["max-stale"]>this.age()-this.maxAge()))?!1:this._requestMatches(e,!1)}_requestMatches(e,r){return(!this._url||this._url===e.url)&&this._host===e.headers.host&&(!e.method||this._method===e.method||r&&e.method==="HEAD")&&this._varyMatches(e)}_allowsStoringAuthenticated(){return this._rescc["must-revalidate"]||this._rescc.public||this._rescc["s-maxage"]}_varyMatches(e){if(!this._resHeaders.vary)return!0;if(this._resHeaders.vary==="*")return!1;let r=this._resHeaders.vary.trim().toLowerCase().split(/\s*,\s*/);for(let i of r)if(e.headers[i]!==this._reqHeaders[i])return!1;return!0}_copyWithoutHopByHopHeaders(e){let r={};for(let i in e)Jbe[i]||(r[i]=e[i]);if(e.connection){let i=e.connection.trim().split(/\s*,\s*/);for(let n of i)delete r[n]}if(r.warning){let i=r.warning.split(/,/).filter(n=>!/^\s*1[0-9][0-9]/.test(n));i.length?r.warning=i.join(",").trim():delete r.warning}return r}responseHeaders(){let e=this._copyWithoutHopByHopHeaders(this._resHeaders),r=this.age();return r>3600*24&&!this._hasExplicitExpiration()&&this.maxAge()>3600*24&&(e.warning=(e.warning?`${e.warning}, `:"")+'113 - "rfc7234 5.5.4"'),e.age=`${Math.round(r)}`,e.date=new Date(this.now()).toUTCString(),e}date(){return this._trustServerDate?this._serverDate():this._responseTime}_serverDate(){let e=Date.parse(this._resHeaders.date);if(isFinite(e)){let r=8*3600*1e3;if(Math.abs(this._responseTime-e)e&&(e=i)}let r=(this.now()-this._responseTime)/1e3;return e+r}_ageValue(){let e=parseInt(this._resHeaders.age);return isFinite(e)?e:0}maxAge(){if(!this.storable()||this._rescc["no-cache"]||this._isShared&&this._resHeaders["set-cookie"]&&!this._rescc.public&&!this._rescc.immutable||this._resHeaders.vary==="*")return 0;if(this._isShared){if(this._rescc["proxy-revalidate"])return 0;if(this._rescc["s-maxage"])return parseInt(this._rescc["s-maxage"],10)}if(this._rescc["max-age"])return parseInt(this._rescc["max-age"],10);let e=this._rescc.immutable?this._immutableMinTtl:0,r=this._serverDate();if(this._resHeaders.expires){let i=Date.parse(this._resHeaders.expires);return Number.isNaN(i)||ii)return Math.max(e,(r-i)/1e3*this._cacheHeuristic)}return e}timeToLive(){return Math.max(0,this.maxAge()-this.age())*1e3}stale(){return this.maxAge()<=this.age()}static fromObject(e){return new this(void 0,void 0,{_fromObject:e})}_fromObject(e){if(this._responseTime)throw Error("Reinitialized");if(!e||e.v!==1)throw Error("Invalid serialization");this._responseTime=e.t,this._isShared=e.sh,this._cacheHeuristic=e.ch,this._immutableMinTtl=e.imm!==void 0?e.imm:24*3600*1e3,this._status=e.st,this._resHeaders=e.resh,this._rescc=e.rescc,this._method=e.m,this._url=e.u,this._host=e.h,this._noAuthorization=e.a,this._reqHeaders=e.reqh,this._reqcc=e.reqcc}toObject(){return{v:1,t:this._responseTime,sh:this._isShared,ch:this._cacheHeuristic,imm:this._immutableMinTtl,st:this._status,resh:this._resHeaders,rescc:this._rescc,m:this._method,u:this._url,h:this._host,a:this._noAuthorization,reqh:this._reqHeaders,reqcc:this._reqcc}}revalidationHeaders(e){this._assertRequestHasHeaders(e);let r=this._copyWithoutHopByHopHeaders(e.headers);if(delete r["if-range"],!this._requestMatches(e,!0)||!this.storable())return delete r["if-none-match"],delete r["if-modified-since"],r;if(this._resHeaders.etag&&(r["if-none-match"]=r["if-none-match"]?`${r["if-none-match"]}, ${this._resHeaders.etag}`:this._resHeaders.etag),r["accept-ranges"]||r["if-match"]||r["if-unmodified-since"]||this._method&&this._method!="GET"){if(delete r["if-modified-since"],r["if-none-match"]){let n=r["if-none-match"].split(/,/).filter(s=>!/^\s*W\//.test(s));n.length?r["if-none-match"]=n.join(",").trim():delete r["if-none-match"]}}else this._resHeaders["last-modified"]&&!r["if-modified-since"]&&(r["if-modified-since"]=this._resHeaders["last-modified"]);return r}revalidatedPolicy(e,r){if(this._assertRequestHasHeaders(e),!r||!r.headers)throw Error("Response headers missing");let i=!1;if(r.status!==void 0&&r.status!=304?i=!1:r.headers.etag&&!/^\s*W\//.test(r.headers.etag)?i=this._resHeaders.etag&&this._resHeaders.etag.replace(/^\s*W\//,"")===r.headers.etag:this._resHeaders.etag&&r.headers.etag?i=this._resHeaders.etag.replace(/^\s*W\//,"")===r.headers.etag.replace(/^\s*W\//,""):this._resHeaders["last-modified"]?i=this._resHeaders["last-modified"]===r.headers["last-modified"]:!this._resHeaders.etag&&!this._resHeaders["last-modified"]&&!r.headers.etag&&!r.headers["last-modified"]&&(i=!0),!i)return{policy:new this.constructor(e,r),modified:r.status!=304,matches:!1};let n={};for(let o in this._resHeaders)n[o]=o in r.headers&&!Wbe[o]?r.headers[o]:this._resHeaders[o];let s=Object.assign({},r,{status:this._status,method:this._method,headers:n});return{policy:new this.constructor(e,s,{shared:this._isShared,cacheHeuristic:this._cacheHeuristic,immutableMinTimeToLive:this._immutableMinTtl,trustServerDate:this._trustServerDate}),modified:!1,matches:!0}}}});var Ly=E((Bnt,U3)=>{"use strict";U3.exports=t=>{let e={};for(let[r,i]of Object.entries(t))e[r.toLowerCase()]=i;return e}});var j3=E((Qnt,H3)=>{"use strict";var Vbe=require("stream").Readable,_be=Ly(),G3=class extends Vbe{constructor(e,r,i,n){if(typeof e!="number")throw new TypeError("Argument `statusCode` should be a number");if(typeof r!="object")throw new TypeError("Argument `headers` should be an object");if(!(i instanceof Buffer))throw new TypeError("Argument `body` should be a buffer");if(typeof n!="string")throw new TypeError("Argument `url` should be a string");super();this.statusCode=e,this.headers=_be(r),this.body=i,this.url=n}_read(){this.push(this.body),this.push(null)}};H3.exports=G3});var q3=E((bnt,Y3)=>{"use strict";var Xbe=["destroy","setTimeout","socket","headers","trailers","rawHeaders","statusCode","httpVersion","httpVersionMinor","httpVersionMajor","rawTrailers","statusMessage"];Y3.exports=(t,e)=>{let r=new Set(Object.keys(t).concat(Xbe));for(let i of r)i in e||(e[i]=typeof t[i]=="function"?t[i].bind(t):t[i])}});var W3=E((vnt,J3)=>{"use strict";var Zbe=require("stream").PassThrough,$be=q3(),eve=t=>{if(!(t&&t.pipe))throw new TypeError("Parameter `response` must be a response stream.");let e=new Zbe;return $be(t,e),t.pipe(e)};J3.exports=eve});var z3=E(sk=>{sk.stringify=function t(e){if(typeof e=="undefined")return e;if(e&&Buffer.isBuffer(e))return JSON.stringify(":base64:"+e.toString("base64"));if(e&&e.toJSON&&(e=e.toJSON()),e&&typeof e=="object"){var r="",i=Array.isArray(e);r=i?"[":"{";var n=!0;for(var s in e){var o=typeof e[s]=="function"||!i&&typeof e[s]=="undefined";Object.hasOwnProperty.call(e,s)&&!o&&(n||(r+=","),n=!1,i?e[s]==null?r+="null":r+=t(e[s]):e[s]!==void 0&&(r+=t(s)+":"+t(e[s])))}return r+=i?"]":"}",r}else return typeof e=="string"?JSON.stringify(/^:/.test(e)?":"+e:e):typeof e=="undefined"?"null":JSON.stringify(e)};sk.parse=function(t){return JSON.parse(t,function(e,r){return typeof r=="string"?/^:base64:/.test(r)?Buffer.from(r.substring(8),"base64"):/^:/.test(r)?r.substring(1):r:r})}});var Z3=E((xnt,V3)=>{"use strict";var tve=require("events"),_3=z3(),rve=t=>{let e={redis:"@keyv/redis",mongodb:"@keyv/mongo",mongo:"@keyv/mongo",sqlite:"@keyv/sqlite",postgresql:"@keyv/postgres",postgres:"@keyv/postgres",mysql:"@keyv/mysql"};if(t.adapter||t.uri){let r=t.adapter||/^[^:]*/.exec(t.uri)[0];return new(require(e[r]))(t)}return new Map},X3=class extends tve{constructor(e,r){super();if(this.opts=Object.assign({namespace:"keyv",serialize:_3.stringify,deserialize:_3.parse},typeof e=="string"?{uri:e}:e,r),!this.opts.store){let i=Object.assign({},this.opts);this.opts.store=rve(i)}typeof this.opts.store.on=="function"&&this.opts.store.on("error",i=>this.emit("error",i)),this.opts.store.namespace=this.opts.namespace}_getKeyPrefix(e){return`${this.opts.namespace}:${e}`}get(e,r){e=this._getKeyPrefix(e);let{store:i}=this.opts;return Promise.resolve().then(()=>i.get(e)).then(n=>typeof n=="string"?this.opts.deserialize(n):n).then(n=>{if(n!==void 0){if(typeof n.expires=="number"&&Date.now()>n.expires){this.delete(e);return}return r&&r.raw?n:n.value}})}set(e,r,i){e=this._getKeyPrefix(e),typeof i=="undefined"&&(i=this.opts.ttl),i===0&&(i=void 0);let{store:n}=this.opts;return Promise.resolve().then(()=>{let s=typeof i=="number"?Date.now()+i:null;return r={value:r,expires:s},this.opts.serialize(r)}).then(s=>n.set(e,s,i)).then(()=>!0)}delete(e){e=this._getKeyPrefix(e);let{store:r}=this.opts;return Promise.resolve().then(()=>r.delete(e))}clear(){let{store:e}=this.opts;return Promise.resolve().then(()=>e.clear())}};V3.exports=X3});var tW=E((knt,$3)=>{"use strict";var ive=require("events"),Ty=require("url"),nve=Q3(),sve=M3(),ok=K3(),eW=j3(),ove=Ly(),ave=W3(),Ave=Z3(),yo=class{constructor(e,r){if(typeof e!="function")throw new TypeError("Parameter `request` must be a function");return this.cache=new Ave({uri:typeof r=="string"&&r,store:typeof r!="string"&&r,namespace:"cacheable-request"}),this.createCacheableRequest(e)}createCacheableRequest(e){return(r,i)=>{let n;if(typeof r=="string")n=ak(Ty.parse(r)),r={};else if(r instanceof Ty.URL)n=ak(Ty.parse(r.toString())),r={};else{let[g,...f]=(r.path||"").split("?"),h=f.length>0?`?${f.join("?")}`:"";n=ak(_(P({},r),{pathname:g,search:h}))}r=P(P({headers:{},method:"GET",cache:!0,strictTtl:!1,automaticFailover:!1},r),lve(n)),r.headers=ove(r.headers);let s=new ive,o=nve(Ty.format(n),{stripWWW:!1,removeTrailingSlash:!1,stripAuthentication:!1}),a=`${r.method}:${o}`,l=!1,c=!1,u=g=>{c=!0;let f=!1,h,p=new Promise(m=>{h=()=>{f||(f=!0,m())}}),d=m=>{if(l&&!g.forceRefresh){m.status=m.statusCode;let B=ok.fromObject(l.cachePolicy).revalidatedPolicy(g,m);if(!B.modified){let b=B.policy.responseHeaders();m=new eW(l.statusCode,b,l.body,l.url),m.cachePolicy=B.policy,m.fromCache=!0}}m.fromCache||(m.cachePolicy=new ok(g,m,g),m.fromCache=!1);let I;g.cache&&m.cachePolicy.storable()?(I=ave(m),(async()=>{try{let B=sve.buffer(m);if(await Promise.race([p,new Promise(L=>m.once("end",L))]),f)return;let b=await B,R={cachePolicy:m.cachePolicy.toObject(),url:m.url,statusCode:m.fromCache?l.statusCode:m.statusCode,body:b},H=g.strictTtl?m.cachePolicy.timeToLive():void 0;g.maxTtl&&(H=H?Math.min(H,g.maxTtl):g.maxTtl),await this.cache.set(a,R,H)}catch(B){s.emit("error",new yo.CacheError(B))}})()):g.cache&&l&&(async()=>{try{await this.cache.delete(a)}catch(B){s.emit("error",new yo.CacheError(B))}})(),s.emit("response",I||m),typeof i=="function"&&i(I||m)};try{let m=e(g,d);m.once("error",h),m.once("abort",h),s.emit("request",m)}catch(m){s.emit("error",new yo.RequestError(m))}};return(async()=>{let g=async h=>{await Promise.resolve();let p=h.cache?await this.cache.get(a):void 0;if(typeof p=="undefined")return u(h);let d=ok.fromObject(p.cachePolicy);if(d.satisfiesWithoutRevalidation(h)&&!h.forceRefresh){let m=d.responseHeaders(),I=new eW(p.statusCode,m,p.body,p.url);I.cachePolicy=d,I.fromCache=!0,s.emit("response",I),typeof i=="function"&&i(I)}else l=p,h.headers=d.revalidationHeaders(h),u(h)},f=h=>s.emit("error",new yo.CacheError(h));this.cache.once("error",f),s.on("response",()=>this.cache.removeListener("error",f));try{await g(r)}catch(h){r.automaticFailover&&!c&&u(r),s.emit("error",new yo.CacheError(h))}})(),s}}};function lve(t){let e=P({},t);return e.path=`${t.pathname||"/"}${t.search||""}`,delete e.pathname,delete e.search,e}function ak(t){return{protocol:t.protocol,auth:t.auth,hostname:t.hostname||t.host||"localhost",port:t.port,pathname:t.pathname,search:t.search}}yo.RequestError=class extends Error{constructor(t){super(t.message);this.name="RequestError",Object.assign(this,t)}};yo.CacheError=class extends Error{constructor(t){super(t.message);this.name="CacheError",Object.assign(this,t)}};$3.exports=yo});var iW=E((Pnt,rW)=>{"use strict";var cve=["aborted","complete","headers","httpVersion","httpVersionMinor","httpVersionMajor","method","rawHeaders","rawTrailers","setTimeout","socket","statusCode","statusMessage","trailers","url"];rW.exports=(t,e)=>{if(e._readableState.autoDestroy)throw new Error("The second stream must have the `autoDestroy` option set to `false`");let r=new Set(Object.keys(t).concat(cve)),i={};for(let n of r)n in e||(i[n]={get(){let s=t[n];return typeof s=="function"?s.bind(t):s},set(s){t[n]=s},enumerable:!0,configurable:!1});return Object.defineProperties(e,i),t.once("aborted",()=>{e.destroy(),e.emit("aborted")}),t.once("close",()=>{t.complete&&e.readable?e.once("end",()=>{e.emit("close")}):e.emit("close")}),e}});var sW=E((Dnt,nW)=>{"use strict";var{Transform:uve,PassThrough:gve}=require("stream"),Ak=require("zlib"),fve=iW();nW.exports=t=>{let e=(t.headers["content-encoding"]||"").toLowerCase();if(!["gzip","deflate","br"].includes(e))return t;let r=e==="br";if(r&&typeof Ak.createBrotliDecompress!="function")return t.destroy(new Error("Brotli is not supported on Node.js < 12")),t;let i=!0,n=new uve({transform(a,l,c){i=!1,c(null,a)},flush(a){a()}}),s=new gve({autoDestroy:!1,destroy(a,l){t.destroy(),l(a)}}),o=r?Ak.createBrotliDecompress():Ak.createUnzip();return o.once("error",a=>{if(i&&!t.readable){s.end();return}s.destroy(a)}),fve(t,s),t.pipe(n).pipe(o).pipe(s),s}});var lk=E((Rnt,oW)=>{"use strict";var aW=class{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_set(e,r){if(this.cache.set(e,r),this._size++,this._size>=this.maxSize){if(this._size=0,typeof this.onEviction=="function")for(let[i,n]of this.oldCache.entries())this.onEviction(i,n);this.oldCache=this.cache,this.cache=new Map}}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){let r=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,r),r}}set(e,r){return this.cache.has(e)?this.cache.set(e,r):this._set(e,r),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e))return this.oldCache.get(e)}delete(e){let r=this.cache.delete(e);return r&&this._size--,this.oldCache.delete(e)||r}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}*keys(){for(let[e]of this)yield e}*values(){for(let[,e]of this)yield e}*[Symbol.iterator](){for(let e of this.cache)yield e;for(let e of this.oldCache){let[r]=e;this.cache.has(r)||(yield e)}}get size(){let e=0;for(let r of this.oldCache.keys())this.cache.has(r)||e++;return Math.min(this._size+e,this.maxSize)}};oW.exports=aW});var uk=E((Fnt,AW)=>{"use strict";var hve=require("events"),pve=require("tls"),dve=require("http2"),Cve=lk(),_i=Symbol("currentStreamsCount"),lW=Symbol("request"),ns=Symbol("cachedOriginSet"),Yu=Symbol("gracefullyClosing"),mve=["maxDeflateDynamicTableSize","maxSessionMemory","maxHeaderListPairs","maxOutstandingPings","maxReservedRemoteStreams","maxSendHeaderBlockLength","paddingStrategy","localAddress","path","rejectUnauthorized","minDHSize","ca","cert","clientCertEngine","ciphers","key","pfx","servername","minVersion","maxVersion","secureProtocol","crl","honorCipherOrder","ecdhCurve","dhparam","secureOptions","sessionIdContext"],Eve=(t,e,r)=>{let i=0,n=t.length;for(;i>>1;r(t[s],e)?i=s+1:n=s}return i},Ive=(t,e)=>t.remoteSettings.maxConcurrentStreams>e.remoteSettings.maxConcurrentStreams,ck=(t,e)=>{for(let r of t)r[ns].lengthe[ns].includes(i))&&r[_i]+e[_i]<=e.remoteSettings.maxConcurrentStreams&&cW(r)},yve=(t,e)=>{for(let r of t)e[ns].lengthr[ns].includes(i))&&e[_i]+r[_i]<=r.remoteSettings.maxConcurrentStreams&&cW(e)},uW=({agent:t,isFree:e})=>{let r={};for(let i in t.sessions){let s=t.sessions[i].filter(o=>{let a=o[ma.kCurrentStreamsCount]{t[Yu]=!0,t[_i]===0&&t.close()},ma=class extends hve{constructor({timeout:e=6e4,maxSessions:r=Infinity,maxFreeSessions:i=10,maxCachedTlsSessions:n=100}={}){super();this.sessions={},this.queue={},this.timeout=e,this.maxSessions=r,this.maxFreeSessions=i,this._freeSessionsCount=0,this._sessionsCount=0,this.settings={enablePush:!1},this.tlsSessionCache=new Cve({maxSize:n})}static normalizeOrigin(e,r){return typeof e=="string"&&(e=new URL(e)),r&&e.hostname!==r&&(e.hostname=r),e.origin}normalizeOptions(e){let r="";if(e)for(let i of mve)e[i]&&(r+=`:${e[i]}`);return r}_tryToCreateNewSession(e,r){if(!(e in this.queue)||!(r in this.queue[e]))return;let i=this.queue[e][r];this._sessionsCount{Array.isArray(i)?(i=[...i],n()):i=[{resolve:n,reject:s}];let o=this.normalizeOptions(r),a=ma.normalizeOrigin(e,r&&r.servername);if(a===void 0){for(let{reject:u}of i)u(new TypeError("The `origin` argument needs to be a string or an URL object"));return}if(o in this.sessions){let u=this.sessions[o],g=-1,f=-1,h;for(let p of u){let d=p.remoteSettings.maxConcurrentStreams;if(d=d||p[Yu]||p.destroyed)continue;h||(g=d),m>f&&(h=p,f=m)}}if(h){if(i.length!==1){for(let{reject:p}of i){let d=new Error(`Expected the length of listeners to be 1, got ${i.length}. +Please report this to https://github.com/szmarczak/http2-wrapper/`);p(d)}return}i[0].resolve(h);return}}if(o in this.queue){if(a in this.queue[o]){this.queue[o][a].listeners.push(...i),this._tryToCreateNewSession(o,a);return}}else this.queue[o]={};let l=()=>{o in this.queue&&this.queue[o][a]===c&&(delete this.queue[o][a],Object.keys(this.queue[o]).length===0&&delete this.queue[o])},c=()=>{let u=`${a}:${o}`,g=!1;try{let f=dve.connect(e,P({createConnection:this.createConnection,settings:this.settings,session:this.tlsSessionCache.get(u)},r));f[_i]=0,f[Yu]=!1;let h=()=>f[_i]{this.tlsSessionCache.set(u,m)}),f.once("error",m=>{for(let{reject:I}of i)I(m);this.tlsSessionCache.delete(u)}),f.setTimeout(this.timeout,()=>{f.destroy()}),f.once("close",()=>{if(g){p&&this._freeSessionsCount--,this._sessionsCount--;let m=this.sessions[o];m.splice(m.indexOf(f),1),m.length===0&&delete this.sessions[o]}else{let m=new Error("Session closed without receiving a SETTINGS frame");m.code="HTTP2WRAPPER_NOSETTINGS";for(let{reject:I}of i)I(m);l()}this._tryToCreateNewSession(o,a)});let d=()=>{if(!(!(o in this.queue)||!h())){for(let m of f[ns])if(m in this.queue[o]){let{listeners:I}=this.queue[o][m];for(;I.length!==0&&h();)I.shift().resolve(f);let B=this.queue[o];if(B[m].listeners.length===0&&(delete B[m],Object.keys(B).length===0)){delete this.queue[o];break}if(!h())break}}};f.on("origin",()=>{f[ns]=f.originSet,!!h()&&(d(),ck(this.sessions[o],f))}),f.once("remoteSettings",()=>{if(f.ref(),f.unref(),this._sessionsCount++,c.destroyed){let m=new Error("Agent has been destroyed");for(let I of i)I.reject(m);f.destroy();return}f[ns]=f.originSet;{let m=this.sessions;if(o in m){let I=m[o];I.splice(Eve(I,f,Ive),0,f)}else m[o]=[f]}this._freeSessionsCount+=1,g=!0,this.emit("session",f),d(),l(),f[_i]===0&&this._freeSessionsCount>this.maxFreeSessions&&f.close(),i.length!==0&&(this.getSession(a,r,i),i.length=0),f.on("remoteSettings",()=>{d(),ck(this.sessions[o],f)})}),f[lW]=f.request,f.request=(m,I)=>{if(f[Yu])throw new Error("The session is gracefully closing. No new streams are allowed.");let B=f[lW](m,I);return f.ref(),++f[_i],f[_i]===f.remoteSettings.maxConcurrentStreams&&this._freeSessionsCount--,B.once("close",()=>{if(p=h(),--f[_i],!f.destroyed&&!f.closed&&(yve(this.sessions[o],f),h()&&!f.closed)){p||(this._freeSessionsCount++,p=!0);let b=f[_i]===0;b&&f.unref(),b&&(this._freeSessionsCount>this.maxFreeSessions||f[Yu])?f.close():(ck(this.sessions[o],f),d())}}),B}}catch(f){for(let h of i)h.reject(f);l()}};c.listeners=i,c.completed=!1,c.destroyed=!1,this.queue[o][a]=c,this._tryToCreateNewSession(o,a)})}request(e,r,i,n){return new Promise((s,o)=>{this.getSession(e,r,[{reject:o,resolve:a=>{try{s(a.request(i,n))}catch(l){o(l)}}}])})}createConnection(e,r){return ma.connect(e,r)}static connect(e,r){r.ALPNProtocols=["h2"];let i=e.port||443,n=e.hostname||e.host;return typeof r.servername=="undefined"&&(r.servername=n),pve.connect(i,n,r)}closeFreeSessions(){for(let e of Object.values(this.sessions))for(let r of e)r[_i]===0&&r.close()}destroy(e){for(let r of Object.values(this.sessions))for(let i of r)i.destroy(e);for(let r of Object.values(this.queue))for(let i of Object.values(r))i.destroyed=!0;this.queue={}}get freeSessions(){return uW({agent:this,isFree:!0})}get busySessions(){return uW({agent:this,isFree:!1})}};ma.kCurrentStreamsCount=_i;ma.kGracefullyClosing=Yu;AW.exports={Agent:ma,globalAgent:new ma}});var gk=E((Nnt,gW)=>{"use strict";var{Readable:wve}=require("stream"),fW=class extends wve{constructor(e,r){super({highWaterMark:r,autoDestroy:!1});this.statusCode=null,this.statusMessage="",this.httpVersion="2.0",this.httpVersionMajor=2,this.httpVersionMinor=0,this.headers={},this.trailers={},this.req=null,this.aborted=!1,this.complete=!1,this.upgrade=null,this.rawHeaders=[],this.rawTrailers=[],this.socket=e,this.connection=e,this._dumped=!1}_destroy(e){this.req._request.destroy(e)}setTimeout(e,r){return this.req.setTimeout(e,r),this}_dump(){this._dumped||(this._dumped=!0,this.removeAllListeners("data"),this.resume())}_read(){this.req&&this.req._request.resume()}};gW.exports=fW});var fk=E((Lnt,hW)=>{"use strict";hW.exports=t=>{let e={protocol:t.protocol,hostname:typeof t.hostname=="string"&&t.hostname.startsWith("[")?t.hostname.slice(1,-1):t.hostname,host:t.host,hash:t.hash,search:t.search,pathname:t.pathname,href:t.href,path:`${t.pathname||""}${t.search||""}`};return typeof t.port=="string"&&t.port.length!==0&&(e.port=Number(t.port)),(t.username||t.password)&&(e.auth=`${t.username||""}:${t.password||""}`),e}});var dW=E((Tnt,pW)=>{"use strict";pW.exports=(t,e,r)=>{for(let i of r)t.on(i,(...n)=>e.emit(i,...n))}});var mW=E((Mnt,CW)=>{"use strict";CW.exports=t=>{switch(t){case":method":case":scheme":case":authority":case":path":return!0;default:return!1}}});var IW=E((Knt,EW)=>{"use strict";var qu=(t,e,r)=>{EW.exports[e]=class extends t{constructor(...n){super(typeof r=="string"?r:r(n));this.name=`${super.name} [${e}]`,this.code=e}}};qu(TypeError,"ERR_INVALID_ARG_TYPE",t=>{let e=t[0].includes(".")?"property":"argument",r=t[1],i=Array.isArray(r);return i&&(r=`${r.slice(0,-1).join(", ")} or ${r.slice(-1)}`),`The "${t[0]}" ${e} must be ${i?"one of":"of"} type ${r}. Received ${typeof t[2]}`});qu(TypeError,"ERR_INVALID_PROTOCOL",t=>`Protocol "${t[0]}" not supported. Expected "${t[1]}"`);qu(Error,"ERR_HTTP_HEADERS_SENT",t=>`Cannot ${t[0]} headers after they are sent to the client`);qu(TypeError,"ERR_INVALID_HTTP_TOKEN",t=>`${t[0]} must be a valid HTTP token [${t[1]}]`);qu(TypeError,"ERR_HTTP_INVALID_HEADER_VALUE",t=>`Invalid value "${t[0]} for header "${t[1]}"`);qu(TypeError,"ERR_INVALID_CHAR",t=>`Invalid character in ${t[0]} [${t[1]}]`)});var Ck=E((Unt,yW)=>{"use strict";var Bve=require("http2"),{Writable:Qve}=require("stream"),{Agent:wW,globalAgent:bve}=uk(),vve=gk(),Sve=fk(),xve=dW(),kve=mW(),{ERR_INVALID_ARG_TYPE:hk,ERR_INVALID_PROTOCOL:Pve,ERR_HTTP_HEADERS_SENT:BW,ERR_INVALID_HTTP_TOKEN:Dve,ERR_HTTP_INVALID_HEADER_VALUE:Rve,ERR_INVALID_CHAR:Fve}=IW(),{HTTP2_HEADER_STATUS:QW,HTTP2_HEADER_METHOD:bW,HTTP2_HEADER_PATH:vW,HTTP2_METHOD_CONNECT:Nve}=Bve.constants,Pi=Symbol("headers"),pk=Symbol("origin"),dk=Symbol("session"),SW=Symbol("options"),My=Symbol("flushedHeaders"),yp=Symbol("jobs"),Lve=/^[\^`\-\w!#$%&*+.|~]+$/,Tve=/[^\t\u0020-\u007E\u0080-\u00FF]/,xW=class extends Qve{constructor(e,r,i){super({autoDestroy:!1});let n=typeof e=="string"||e instanceof URL;if(n&&(e=Sve(e instanceof URL?e:new URL(e))),typeof r=="function"||r===void 0?(i=r,r=n?e:P({},e)):r=P(P({},e),r),r.h2session)this[dk]=r.h2session;else if(r.agent===!1)this.agent=new wW({maxFreeSessions:0});else if(typeof r.agent=="undefined"||r.agent===null)typeof r.createConnection=="function"?(this.agent=new wW({maxFreeSessions:0}),this.agent.createConnection=r.createConnection):this.agent=bve;else if(typeof r.agent.request=="function")this.agent=r.agent;else throw new hk("options.agent",["Agent-like Object","undefined","false"],r.agent);if(r.protocol&&r.protocol!=="https:")throw new Pve(r.protocol,"https:");let s=r.port||r.defaultPort||this.agent&&this.agent.defaultPort||443,o=r.hostname||r.host||"localhost";delete r.hostname,delete r.host,delete r.port;let{timeout:a}=r;if(r.timeout=void 0,this[Pi]=Object.create(null),this[yp]=[],this.socket=null,this.connection=null,this.method=r.method||"GET",this.path=r.path,this.res=null,this.aborted=!1,this.reusedSocket=!1,r.headers)for(let[l,c]of Object.entries(r.headers))this.setHeader(l,c);r.auth&&!("authorization"in this[Pi])&&(this[Pi].authorization="Basic "+Buffer.from(r.auth).toString("base64")),r.session=r.tlsSession,r.path=r.socketPath,this[SW]=r,s===443?(this[pk]=`https://${o}`,":authority"in this[Pi]||(this[Pi][":authority"]=o)):(this[pk]=`https://${o}:${s}`,":authority"in this[Pi]||(this[Pi][":authority"]=`${o}:${s}`)),a&&this.setTimeout(a),i&&this.once("response",i),this[My]=!1}get method(){return this[Pi][bW]}set method(e){e&&(this[Pi][bW]=e.toUpperCase())}get path(){return this[Pi][vW]}set path(e){e&&(this[Pi][vW]=e)}get _mustNotHaveABody(){return this.method==="GET"||this.method==="HEAD"||this.method==="DELETE"}_write(e,r,i){if(this._mustNotHaveABody){i(new Error("The GET, HEAD and DELETE methods must NOT have a body"));return}this.flushHeaders();let n=()=>this._request.write(e,r,i);this._request?n():this[yp].push(n)}_final(e){if(this.destroyed)return;this.flushHeaders();let r=()=>{if(this._mustNotHaveABody){e();return}this._request.end(e)};this._request?r():this[yp].push(r)}abort(){this.res&&this.res.complete||(this.aborted||process.nextTick(()=>this.emit("abort")),this.aborted=!0,this.destroy())}_destroy(e,r){this.res&&this.res._dump(),this._request&&this._request.destroy(),r(e)}async flushHeaders(){if(this[My]||this.destroyed)return;this[My]=!0;let e=this.method===Nve,r=i=>{if(this._request=i,this.destroyed){i.destroy();return}e||xve(i,this,["timeout","continue","close","error"]);let n=o=>(...a)=>{!this.writable&&!this.destroyed?o(...a):this.once("finish",()=>{o(...a)})};i.once("response",n((o,a,l)=>{let c=new vve(this.socket,i.readableHighWaterMark);this.res=c,c.req=this,c.statusCode=o[QW],c.headers=o,c.rawHeaders=l,c.once("end",()=>{this.aborted?(c.aborted=!0,c.emit("aborted")):(c.complete=!0,c.socket=null,c.connection=null)}),e?(c.upgrade=!0,this.emit("connect",c,i,Buffer.alloc(0))?this.emit("close"):i.destroy()):(i.on("data",u=>{!c._dumped&&!c.push(u)&&i.pause()}),i.once("end",()=>{c.push(null)}),this.emit("response",c)||c._dump())})),i.once("headers",n(o=>this.emit("information",{statusCode:o[QW]}))),i.once("trailers",n((o,a,l)=>{let{res:c}=this;c.trailers=o,c.rawTrailers=l}));let{socket:s}=i.session;this.socket=s,this.connection=s;for(let o of this[yp])o();this.emit("socket",this.socket)};if(this[dk])try{r(this[dk].request(this[Pi]))}catch(i){this.emit("error",i)}else{this.reusedSocket=!0;try{r(await this.agent.request(this[pk],this[SW],this[Pi]))}catch(i){this.emit("error",i)}}}getHeader(e){if(typeof e!="string")throw new hk("name","string",e);return this[Pi][e.toLowerCase()]}get headersSent(){return this[My]}removeHeader(e){if(typeof e!="string")throw new hk("name","string",e);if(this.headersSent)throw new BW("remove");delete this[Pi][e.toLowerCase()]}setHeader(e,r){if(this.headersSent)throw new BW("set");if(typeof e!="string"||!Lve.test(e)&&!kve(e))throw new Dve("Header name",e);if(typeof r=="undefined")throw new Rve(r,e);if(Tve.test(r))throw new Fve("header content",e);this[Pi][e.toLowerCase()]=r}setNoDelay(){}setSocketKeepAlive(){}setTimeout(e,r){let i=()=>this._request.setTimeout(e,r);return this._request?i():this[yp].push(i),this}get maxHeadersCount(){if(!this.destroyed&&this._request)return this._request.session.localSettings.maxHeaderListSize}set maxHeadersCount(e){}};yW.exports=xW});var PW=E((Hnt,kW)=>{"use strict";var Mve=require("tls");kW.exports=(t={})=>new Promise((e,r)=>{let i=Mve.connect(t,()=>{t.resolveSocket?(i.off("error",r),e({alpnProtocol:i.alpnProtocol,socket:i})):(i.destroy(),e({alpnProtocol:i.alpnProtocol}))});i.on("error",r)})});var RW=E((Gnt,DW)=>{"use strict";var Ove=require("net");DW.exports=t=>{let e=t.host,r=t.headers&&t.headers.host;return r&&(r.startsWith("[")?r.indexOf("]")===-1?e=r:e=r.slice(1,-1):e=r.split(":",1)[0]),Ove.isIP(e)?"":e}});var LW=E((jnt,mk)=>{"use strict";var FW=require("http"),Ek=require("https"),Kve=PW(),Uve=lk(),Hve=Ck(),Gve=RW(),jve=fk(),Oy=new Uve({maxSize:100}),wp=new Map,NW=(t,e,r)=>{e._httpMessage={shouldKeepAlive:!0};let i=()=>{t.emit("free",e,r)};e.on("free",i);let n=()=>{t.removeSocket(e,r)};e.on("close",n);let s=()=>{t.removeSocket(e,r),e.off("close",n),e.off("free",i),e.off("agentRemove",s)};e.on("agentRemove",s),t.emit("free",e,r)},Yve=async t=>{let e=`${t.host}:${t.port}:${t.ALPNProtocols.sort()}`;if(!Oy.has(e)){if(wp.has(e))return(await wp.get(e)).alpnProtocol;let{path:r,agent:i}=t;t.path=t.socketPath;let n=Kve(t);wp.set(e,n);try{let{socket:s,alpnProtocol:o}=await n;if(Oy.set(e,o),t.path=r,o==="h2")s.destroy();else{let{globalAgent:a}=Ek,l=Ek.Agent.prototype.createConnection;i?i.createConnection===l?NW(i,s,t):s.destroy():a.createConnection===l?NW(a,s,t):s.destroy()}return wp.delete(e),o}catch(s){throw wp.delete(e),s}}return Oy.get(e)};mk.exports=async(t,e,r)=>{if((typeof t=="string"||t instanceof URL)&&(t=jve(new URL(t))),typeof e=="function"&&(r=e,e=void 0),e=_(P(P({ALPNProtocols:["h2","http/1.1"]},t),e),{resolveSocket:!0}),!Array.isArray(e.ALPNProtocols)||e.ALPNProtocols.length===0)throw new Error("The `ALPNProtocols` option must be an Array with at least one entry");e.protocol=e.protocol||"https:";let i=e.protocol==="https:";e.host=e.hostname||e.host||"localhost",e.session=e.tlsSession,e.servername=e.servername||Gve(e),e.port=e.port||(i?443:80),e._defaultAgent=i?Ek.globalAgent:FW.globalAgent;let n=e.agent;if(n){if(n.addRequest)throw new Error("The `options.agent` object can contain only `http`, `https` or `http2` properties");e.agent=n[i?"https":"http"]}return i&&await Yve(e)==="h2"?(n&&(e.agent=n.http2),new Hve(e,r)):FW.request(e,r)};mk.exports.protocolCache=Oy});var MW=E((Ynt,TW)=>{"use strict";var qve=require("http2"),Jve=uk(),Ik=Ck(),Wve=gk(),zve=LW(),Vve=(t,e,r)=>new Ik(t,e,r),_ve=(t,e,r)=>{let i=new Ik(t,e,r);return i.end(),i};TW.exports=_(P(_(P({},qve),{ClientRequest:Ik,IncomingMessage:Wve}),Jve),{request:Vve,get:_ve,auto:zve})});var wk=E(yk=>{"use strict";Object.defineProperty(yk,"__esModule",{value:!0});var OW=Ca();yk.default=t=>OW.default.nodeStream(t)&&OW.default.function_(t.getBoundary)});var GW=E(Bk=>{"use strict";Object.defineProperty(Bk,"__esModule",{value:!0});var KW=require("fs"),UW=require("util"),HW=Ca(),Xve=wk(),Zve=UW.promisify(KW.stat);Bk.default=async(t,e)=>{if(e&&"content-length"in e)return Number(e["content-length"]);if(!t)return 0;if(HW.default.string(t))return Buffer.byteLength(t);if(HW.default.buffer(t))return t.length;if(Xve.default(t))return UW.promisify(t.getLength.bind(t))();if(t instanceof KW.ReadStream){let{size:r}=await Zve(t.path);return r===0?void 0:r}}});var bk=E(Qk=>{"use strict";Object.defineProperty(Qk,"__esModule",{value:!0});function $ve(t,e,r){let i={};for(let n of r)i[n]=(...s)=>{e.emit(n,...s)},t.on(n,i[n]);return()=>{for(let n of r)t.off(n,i[n])}}Qk.default=$ve});var jW=E(vk=>{"use strict";Object.defineProperty(vk,"__esModule",{value:!0});vk.default=()=>{let t=[];return{once(e,r,i){e.once(r,i),t.push({origin:e,event:r,fn:i})},unhandleAll(){for(let e of t){let{origin:r,event:i,fn:n}=e;r.removeListener(i,n)}t.length=0}}}});var qW=E(Bp=>{"use strict";Object.defineProperty(Bp,"__esModule",{value:!0});Bp.TimeoutError=void 0;var eSe=require("net"),tSe=jW(),YW=Symbol("reentry"),rSe=()=>{},Sk=class extends Error{constructor(e,r){super(`Timeout awaiting '${r}' for ${e}ms`);this.event=r,this.name="TimeoutError",this.code="ETIMEDOUT"}};Bp.TimeoutError=Sk;Bp.default=(t,e,r)=>{if(YW in t)return rSe;t[YW]=!0;let i=[],{once:n,unhandleAll:s}=tSe.default(),o=(g,f,h)=>{var p;let d=setTimeout(f,g,g,h);(p=d.unref)===null||p===void 0||p.call(d);let m=()=>{clearTimeout(d)};return i.push(m),m},{host:a,hostname:l}=r,c=(g,f)=>{t.destroy(new Sk(g,f))},u=()=>{for(let g of i)g();s()};if(t.once("error",g=>{if(u(),t.listenerCount("error")===0)throw g}),t.once("close",u),n(t,"response",g=>{n(g,"end",u)}),typeof e.request!="undefined"&&o(e.request,c,"request"),typeof e.socket!="undefined"){let g=()=>{c(e.socket,"socket")};t.setTimeout(e.socket,g),i.push(()=>{t.removeListener("timeout",g)})}return n(t,"socket",g=>{var f;let{socketPath:h}=t;if(g.connecting){let p=Boolean(h!=null?h:eSe.isIP((f=l!=null?l:a)!==null&&f!==void 0?f:"")!==0);if(typeof e.lookup!="undefined"&&!p&&typeof g.address().address=="undefined"){let d=o(e.lookup,c,"lookup");n(g,"lookup",d)}if(typeof e.connect!="undefined"){let d=()=>o(e.connect,c,"connect");p?n(g,"connect",d()):n(g,"lookup",m=>{m===null&&n(g,"connect",d())})}typeof e.secureConnect!="undefined"&&r.protocol==="https:"&&n(g,"connect",()=>{let d=o(e.secureConnect,c,"secureConnect");n(g,"secureConnect",d)})}if(typeof e.send!="undefined"){let p=()=>o(e.send,c,"send");g.connecting?n(g,"connect",()=>{n(t,"upload-complete",p())}):n(t,"upload-complete",p())}}),typeof e.response!="undefined"&&n(t,"upload-complete",()=>{let g=o(e.response,c,"response");n(t,"response",g)}),u}});var WW=E(xk=>{"use strict";Object.defineProperty(xk,"__esModule",{value:!0});var JW=Ca();xk.default=t=>{t=t;let e={protocol:t.protocol,hostname:JW.default.string(t.hostname)&&t.hostname.startsWith("[")?t.hostname.slice(1,-1):t.hostname,host:t.host,hash:t.hash,search:t.search,pathname:t.pathname,href:t.href,path:`${t.pathname||""}${t.search||""}`};return JW.default.string(t.port)&&t.port.length>0&&(e.port=Number(t.port)),(t.username||t.password)&&(e.auth=`${t.username||""}:${t.password||""}`),e}});var zW=E(kk=>{"use strict";Object.defineProperty(kk,"__esModule",{value:!0});var iSe=require("url"),nSe=["protocol","host","hostname","port","pathname","search"];kk.default=(t,e)=>{var r,i;if(e.path){if(e.pathname)throw new TypeError("Parameters `path` and `pathname` are mutually exclusive.");if(e.search)throw new TypeError("Parameters `path` and `search` are mutually exclusive.");if(e.searchParams)throw new TypeError("Parameters `path` and `searchParams` are mutually exclusive.")}if(e.search&&e.searchParams)throw new TypeError("Parameters `search` and `searchParams` are mutually exclusive.");if(!t){if(!e.protocol)throw new TypeError("No URL protocol specified");t=`${e.protocol}//${(i=(r=e.hostname)!==null&&r!==void 0?r:e.host)!==null&&i!==void 0?i:""}`}let n=new iSe.URL(t);if(e.path){let s=e.path.indexOf("?");s===-1?e.pathname=e.path:(e.pathname=e.path.slice(0,s),e.search=e.path.slice(s+1)),delete e.path}for(let s of nSe)e[s]&&(n[s]=e[s].toString());return n}});var _W=E(Pk=>{"use strict";Object.defineProperty(Pk,"__esModule",{value:!0});var VW=class{constructor(){this.weakMap=new WeakMap,this.map=new Map}set(e,r){typeof e=="object"?this.weakMap.set(e,r):this.map.set(e,r)}get(e){return typeof e=="object"?this.weakMap.get(e):this.map.get(e)}has(e){return typeof e=="object"?this.weakMap.has(e):this.map.has(e)}};Pk.default=VW});var Rk=E(Dk=>{"use strict";Object.defineProperty(Dk,"__esModule",{value:!0});var sSe=async t=>{let e=[],r=0;for await(let i of t)e.push(i),r+=Buffer.byteLength(i);return Buffer.isBuffer(e[0])?Buffer.concat(e,r):Buffer.from(e.join(""))};Dk.default=sSe});var ZW=E(ql=>{"use strict";Object.defineProperty(ql,"__esModule",{value:!0});ql.dnsLookupIpVersionToFamily=ql.isDnsLookupIpVersion=void 0;var XW={auto:0,ipv4:4,ipv6:6};ql.isDnsLookupIpVersion=t=>t in XW;ql.dnsLookupIpVersionToFamily=t=>{if(ql.isDnsLookupIpVersion(t))return XW[t];throw new Error("Invalid DNS lookup IP version")}});var Fk=E(Ky=>{"use strict";Object.defineProperty(Ky,"__esModule",{value:!0});Ky.isResponseOk=void 0;Ky.isResponseOk=t=>{let{statusCode:e}=t,r=t.request.options.followRedirect?299:399;return e>=200&&e<=r||e===304}});var e8=E(Nk=>{"use strict";Object.defineProperty(Nk,"__esModule",{value:!0});var $W=new Set;Nk.default=t=>{$W.has(t)||($W.add(t),process.emitWarning(`Got: ${t}`,{type:"DeprecationWarning"}))}});var t8=E(Lk=>{"use strict";Object.defineProperty(Lk,"__esModule",{value:!0});var ar=Ca(),oSe=(t,e)=>{if(ar.default.null_(t.encoding))throw new TypeError("To get a Buffer, set `options.responseType` to `buffer` instead");ar.assert.any([ar.default.string,ar.default.undefined],t.encoding),ar.assert.any([ar.default.boolean,ar.default.undefined],t.resolveBodyOnly),ar.assert.any([ar.default.boolean,ar.default.undefined],t.methodRewriting),ar.assert.any([ar.default.boolean,ar.default.undefined],t.isStream),ar.assert.any([ar.default.string,ar.default.undefined],t.responseType),t.responseType===void 0&&(t.responseType="text");let{retry:r}=t;if(e?t.retry=P({},e.retry):t.retry={calculateDelay:i=>i.computedValue,limit:0,methods:[],statusCodes:[],errorCodes:[],maxRetryAfter:void 0},ar.default.object(r)?(t.retry=P(P({},t.retry),r),t.retry.methods=[...new Set(t.retry.methods.map(i=>i.toUpperCase()))],t.retry.statusCodes=[...new Set(t.retry.statusCodes)],t.retry.errorCodes=[...new Set(t.retry.errorCodes)]):ar.default.number(r)&&(t.retry.limit=r),ar.default.undefined(t.retry.maxRetryAfter)&&(t.retry.maxRetryAfter=Math.min(...[t.timeout.request,t.timeout.connect].filter(ar.default.number))),ar.default.object(t.pagination)){e&&(t.pagination=P(P({},e.pagination),t.pagination));let{pagination:i}=t;if(!ar.default.function_(i.transform))throw new Error("`options.pagination.transform` must be implemented");if(!ar.default.function_(i.shouldContinue))throw new Error("`options.pagination.shouldContinue` must be implemented");if(!ar.default.function_(i.filter))throw new TypeError("`options.pagination.filter` must be implemented");if(!ar.default.function_(i.paginate))throw new Error("`options.pagination.paginate` must be implemented")}return t.responseType==="json"&&t.headers.accept===void 0&&(t.headers.accept="application/json"),t};Lk.default=oSe});var r8=E(Qp=>{"use strict";Object.defineProperty(Qp,"__esModule",{value:!0});Qp.retryAfterStatusCodes=void 0;Qp.retryAfterStatusCodes=new Set([413,429,503]);var aSe=({attemptCount:t,retryOptions:e,error:r,retryAfter:i})=>{if(t>e.limit)return 0;let n=e.methods.includes(r.options.method),s=e.errorCodes.includes(r.code),o=r.response&&e.statusCodes.includes(r.response.statusCode);if(!n||!s&&!o)return 0;if(r.response){if(i)return e.maxRetryAfter===void 0||i>e.maxRetryAfter?0:i;if(r.response.statusCode===413)return 0}let a=Math.random()*100;return 2**(t-1)*1e3+a};Qp.default=aSe});var vp=E(Rt=>{"use strict";Object.defineProperty(Rt,"__esModule",{value:!0});Rt.UnsupportedProtocolError=Rt.ReadError=Rt.TimeoutError=Rt.UploadError=Rt.CacheError=Rt.HTTPError=Rt.MaxRedirectsError=Rt.RequestError=Rt.setNonEnumerableProperties=Rt.knownHookEvents=Rt.withoutBody=Rt.kIsNormalizedAlready=void 0;var i8=require("util"),n8=require("stream"),ASe=require("fs"),dA=require("url"),s8=require("http"),Tk=require("http"),lSe=require("https"),cSe=h3(),uSe=y3(),o8=tW(),gSe=sW(),fSe=MW(),hSe=Ly(),ce=Ca(),pSe=GW(),a8=wk(),dSe=bk(),A8=qW(),CSe=WW(),l8=zW(),mSe=_W(),ESe=Rk(),c8=ZW(),ISe=Fk(),CA=e8(),ySe=t8(),wSe=r8(),Mk,Ei=Symbol("request"),Uy=Symbol("response"),Ju=Symbol("responseSize"),Wu=Symbol("downloadedSize"),zu=Symbol("bodySize"),Vu=Symbol("uploadedSize"),Hy=Symbol("serverResponsesPiped"),u8=Symbol("unproxyEvents"),g8=Symbol("isFromCache"),Ok=Symbol("cancelTimeouts"),f8=Symbol("startedReading"),_u=Symbol("stopReading"),Gy=Symbol("triggerRead"),mA=Symbol("body"),bp=Symbol("jobs"),h8=Symbol("originalResponse"),p8=Symbol("retryTimeout");Rt.kIsNormalizedAlready=Symbol("isNormalizedAlready");var BSe=ce.default.string(process.versions.brotli);Rt.withoutBody=new Set(["GET","HEAD"]);Rt.knownHookEvents=["init","beforeRequest","beforeRedirect","beforeError","beforeRetry","afterResponse"];function QSe(t){for(let e in t){let r=t[e];if(!ce.default.string(r)&&!ce.default.number(r)&&!ce.default.boolean(r)&&!ce.default.null_(r)&&!ce.default.undefined(r))throw new TypeError(`The \`searchParams\` value '${String(r)}' must be a string, number, boolean or null`)}}function bSe(t){return ce.default.object(t)&&!("statusCode"in t)}var Kk=new mSe.default,vSe=async t=>new Promise((e,r)=>{let i=n=>{r(n)};t.pending||e(),t.once("error",i),t.once("ready",()=>{t.off("error",i),e()})}),SSe=new Set([300,301,302,303,304,307,308]),xSe=["context","body","json","form"];Rt.setNonEnumerableProperties=(t,e)=>{let r={};for(let i of t)if(!!i)for(let n of xSe)n in i&&(r[n]={writable:!0,configurable:!0,enumerable:!1,value:i[n]});Object.defineProperties(e,r)};var _r=class extends Error{constructor(e,r,i){var n;super(e);if(Error.captureStackTrace(this,this.constructor),this.name="RequestError",this.code=r.code,i instanceof Uk?(Object.defineProperty(this,"request",{enumerable:!1,value:i}),Object.defineProperty(this,"response",{enumerable:!1,value:i[Uy]}),Object.defineProperty(this,"options",{enumerable:!1,value:i.options})):Object.defineProperty(this,"options",{enumerable:!1,value:i}),this.timings=(n=this.request)===null||n===void 0?void 0:n.timings,ce.default.string(r.stack)&&ce.default.string(this.stack)){let s=this.stack.indexOf(this.message)+this.message.length,o=this.stack.slice(s).split(` +`).reverse(),a=r.stack.slice(r.stack.indexOf(r.message)+r.message.length).split(` +`).reverse();for(;a.length!==0&&a[0]===o[0];)o.shift();this.stack=`${this.stack.slice(0,s)}${o.reverse().join(` +`)}${a.reverse().join(` +`)}`}}};Rt.RequestError=_r;var Hk=class extends _r{constructor(e){super(`Redirected ${e.options.maxRedirects} times. Aborting.`,{},e);this.name="MaxRedirectsError"}};Rt.MaxRedirectsError=Hk;var Gk=class extends _r{constructor(e){super(`Response code ${e.statusCode} (${e.statusMessage})`,{},e.request);this.name="HTTPError"}};Rt.HTTPError=Gk;var jk=class extends _r{constructor(e,r){super(e.message,e,r);this.name="CacheError"}};Rt.CacheError=jk;var Yk=class extends _r{constructor(e,r){super(e.message,e,r);this.name="UploadError"}};Rt.UploadError=Yk;var qk=class extends _r{constructor(e,r,i){super(e.message,e,i);this.name="TimeoutError",this.event=e.event,this.timings=r}};Rt.TimeoutError=qk;var jy=class extends _r{constructor(e,r){super(e.message,e,r);this.name="ReadError"}};Rt.ReadError=jy;var Jk=class extends _r{constructor(e){super(`Unsupported protocol "${e.url.protocol}"`,{},e);this.name="UnsupportedProtocolError"}};Rt.UnsupportedProtocolError=Jk;var kSe=["socket","connect","continue","information","upgrade","timeout"],Uk=class extends n8.Duplex{constructor(e,r={},i){super({autoDestroy:!1,highWaterMark:0});this[Wu]=0,this[Vu]=0,this.requestInitialized=!1,this[Hy]=new Set,this.redirects=[],this[_u]=!1,this[Gy]=!1,this[bp]=[],this.retryCount=0,this._progressCallbacks=[];let n=()=>this._unlockWrite(),s=()=>this._lockWrite();this.on("pipe",c=>{c.prependListener("data",n),c.on("data",s),c.prependListener("end",n),c.on("end",s)}),this.on("unpipe",c=>{c.off("data",n),c.off("data",s),c.off("end",n),c.off("end",s)}),this.on("pipe",c=>{c instanceof Tk.IncomingMessage&&(this.options.headers=P(P({},c.headers),this.options.headers))});let{json:o,body:a,form:l}=r;if((o||a||l)&&this._lockWrite(),Rt.kIsNormalizedAlready in r)this.options=r;else try{this.options=this.constructor.normalizeArguments(e,r,i)}catch(c){ce.default.nodeStream(r.body)&&r.body.destroy(),this.destroy(c);return}(async()=>{var c;try{this.options.body instanceof ASe.ReadStream&&await vSe(this.options.body);let{url:u}=this.options;if(!u)throw new TypeError("Missing `url` property");if(this.requestUrl=u.toString(),decodeURI(this.requestUrl),await this._finalizeBody(),await this._makeRequest(),this.destroyed){(c=this[Ei])===null||c===void 0||c.destroy();return}for(let g of this[bp])g();this[bp].length=0,this.requestInitialized=!0}catch(u){if(u instanceof _r){this._beforeError(u);return}this.destroyed||this.destroy(u)}})()}static normalizeArguments(e,r,i){var n,s,o,a,l;let c=r;if(ce.default.object(e)&&!ce.default.urlInstance(e))r=P(P(P({},i),e),r);else{if(e&&r&&r.url!==void 0)throw new TypeError("The `url` option is mutually exclusive with the `input` argument");r=P(P({},i),r),e!==void 0&&(r.url=e),ce.default.urlInstance(r.url)&&(r.url=new dA.URL(r.url.toString()))}if(r.cache===!1&&(r.cache=void 0),r.dnsCache===!1&&(r.dnsCache=void 0),ce.assert.any([ce.default.string,ce.default.undefined],r.method),ce.assert.any([ce.default.object,ce.default.undefined],r.headers),ce.assert.any([ce.default.string,ce.default.urlInstance,ce.default.undefined],r.prefixUrl),ce.assert.any([ce.default.object,ce.default.undefined],r.cookieJar),ce.assert.any([ce.default.object,ce.default.string,ce.default.undefined],r.searchParams),ce.assert.any([ce.default.object,ce.default.string,ce.default.undefined],r.cache),ce.assert.any([ce.default.object,ce.default.number,ce.default.undefined],r.timeout),ce.assert.any([ce.default.object,ce.default.undefined],r.context),ce.assert.any([ce.default.object,ce.default.undefined],r.hooks),ce.assert.any([ce.default.boolean,ce.default.undefined],r.decompress),ce.assert.any([ce.default.boolean,ce.default.undefined],r.ignoreInvalidCookies),ce.assert.any([ce.default.boolean,ce.default.undefined],r.followRedirect),ce.assert.any([ce.default.number,ce.default.undefined],r.maxRedirects),ce.assert.any([ce.default.boolean,ce.default.undefined],r.throwHttpErrors),ce.assert.any([ce.default.boolean,ce.default.undefined],r.http2),ce.assert.any([ce.default.boolean,ce.default.undefined],r.allowGetBody),ce.assert.any([ce.default.string,ce.default.undefined],r.localAddress),ce.assert.any([c8.isDnsLookupIpVersion,ce.default.undefined],r.dnsLookupIpVersion),ce.assert.any([ce.default.object,ce.default.undefined],r.https),ce.assert.any([ce.default.boolean,ce.default.undefined],r.rejectUnauthorized),r.https&&(ce.assert.any([ce.default.boolean,ce.default.undefined],r.https.rejectUnauthorized),ce.assert.any([ce.default.function_,ce.default.undefined],r.https.checkServerIdentity),ce.assert.any([ce.default.string,ce.default.object,ce.default.array,ce.default.undefined],r.https.certificateAuthority),ce.assert.any([ce.default.string,ce.default.object,ce.default.array,ce.default.undefined],r.https.key),ce.assert.any([ce.default.string,ce.default.object,ce.default.array,ce.default.undefined],r.https.certificate),ce.assert.any([ce.default.string,ce.default.undefined],r.https.passphrase),ce.assert.any([ce.default.string,ce.default.buffer,ce.default.array,ce.default.undefined],r.https.pfx)),ce.assert.any([ce.default.object,ce.default.undefined],r.cacheOptions),ce.default.string(r.method)?r.method=r.method.toUpperCase():r.method="GET",r.headers===(i==null?void 0:i.headers)?r.headers=P({},r.headers):r.headers=hSe(P(P({},i==null?void 0:i.headers),r.headers)),"slashes"in r)throw new TypeError("The legacy `url.Url` has been deprecated. Use `URL` instead.");if("auth"in r)throw new TypeError("Parameter `auth` is deprecated. Use `username` / `password` instead.");if("searchParams"in r&&r.searchParams&&r.searchParams!==(i==null?void 0:i.searchParams)){let h;if(ce.default.string(r.searchParams)||r.searchParams instanceof dA.URLSearchParams)h=new dA.URLSearchParams(r.searchParams);else{QSe(r.searchParams),h=new dA.URLSearchParams;for(let p in r.searchParams){let d=r.searchParams[p];d===null?h.append(p,""):d!==void 0&&h.append(p,d)}}(n=i==null?void 0:i.searchParams)===null||n===void 0||n.forEach((p,d)=>{h.has(d)||h.append(d,p)}),r.searchParams=h}if(r.username=(s=r.username)!==null&&s!==void 0?s:"",r.password=(o=r.password)!==null&&o!==void 0?o:"",ce.default.undefined(r.prefixUrl)?r.prefixUrl=(a=i==null?void 0:i.prefixUrl)!==null&&a!==void 0?a:"":(r.prefixUrl=r.prefixUrl.toString(),r.prefixUrl!==""&&!r.prefixUrl.endsWith("/")&&(r.prefixUrl+="/")),ce.default.string(r.url)){if(r.url.startsWith("/"))throw new Error("`input` must not start with a slash when using `prefixUrl`");r.url=l8.default(r.prefixUrl+r.url,r)}else(ce.default.undefined(r.url)&&r.prefixUrl!==""||r.protocol)&&(r.url=l8.default(r.prefixUrl,r));if(r.url){"port"in r&&delete r.port;let{prefixUrl:h}=r;Object.defineProperty(r,"prefixUrl",{set:d=>{let m=r.url;if(!m.href.startsWith(d))throw new Error(`Cannot change \`prefixUrl\` from ${h} to ${d}: ${m.href}`);r.url=new dA.URL(d+m.href.slice(h.length)),h=d},get:()=>h});let{protocol:p}=r.url;if(p==="unix:"&&(p="http:",r.url=new dA.URL(`http://unix${r.url.pathname}${r.url.search}`)),r.searchParams&&(r.url.search=r.searchParams.toString()),p!=="http:"&&p!=="https:")throw new Jk(r);r.username===""?r.username=r.url.username:r.url.username=r.username,r.password===""?r.password=r.url.password:r.url.password=r.password}let{cookieJar:u}=r;if(u){let{setCookie:h,getCookieString:p}=u;ce.assert.function_(h),ce.assert.function_(p),h.length===4&&p.length===0&&(h=i8.promisify(h.bind(r.cookieJar)),p=i8.promisify(p.bind(r.cookieJar)),r.cookieJar={setCookie:h,getCookieString:p})}let{cache:g}=r;if(g&&(Kk.has(g)||Kk.set(g,new o8((h,p)=>{let d=h[Ei](h,p);return ce.default.promise(d)&&(d.once=(m,I)=>{if(m==="error")d.catch(I);else if(m==="abort")(async()=>{try{(await d).once("abort",I)}catch(B){}})();else throw new Error(`Unknown HTTP2 promise event: ${m}`);return d}),d},g))),r.cacheOptions=P({},r.cacheOptions),r.dnsCache===!0)Mk||(Mk=new uSe.default),r.dnsCache=Mk;else if(!ce.default.undefined(r.dnsCache)&&!r.dnsCache.lookup)throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${ce.default(r.dnsCache)}`);ce.default.number(r.timeout)?r.timeout={request:r.timeout}:i&&r.timeout!==i.timeout?r.timeout=P(P({},i.timeout),r.timeout):r.timeout=P({},r.timeout),r.context||(r.context={});let f=r.hooks===(i==null?void 0:i.hooks);r.hooks=P({},r.hooks);for(let h of Rt.knownHookEvents)if(h in r.hooks)if(ce.default.array(r.hooks[h]))r.hooks[h]=[...r.hooks[h]];else throw new TypeError(`Parameter \`${h}\` must be an Array, got ${ce.default(r.hooks[h])}`);else r.hooks[h]=[];if(i&&!f)for(let h of Rt.knownHookEvents)i.hooks[h].length>0&&(r.hooks[h]=[...i.hooks[h],...r.hooks[h]]);if("family"in r&&CA.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"'),(i==null?void 0:i.https)&&(r.https=P(P({},i.https),r.https)),"rejectUnauthorized"in r&&CA.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"'),"checkServerIdentity"in r&&CA.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"'),"ca"in r&&CA.default('"options.ca" was never documented, please use "options.https.certificateAuthority"'),"key"in r&&CA.default('"options.key" was never documented, please use "options.https.key"'),"cert"in r&&CA.default('"options.cert" was never documented, please use "options.https.certificate"'),"passphrase"in r&&CA.default('"options.passphrase" was never documented, please use "options.https.passphrase"'),"pfx"in r&&CA.default('"options.pfx" was never documented, please use "options.https.pfx"'),"followRedirects"in r)throw new TypeError("The `followRedirects` option does not exist. Use `followRedirect` instead.");if(r.agent){for(let h in r.agent)if(h!=="http"&&h!=="https"&&h!=="http2")throw new TypeError(`Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${h}\``)}return r.maxRedirects=(l=r.maxRedirects)!==null&&l!==void 0?l:0,Rt.setNonEnumerableProperties([i,c],r),ySe.default(r,i)}_lockWrite(){let e=()=>{throw new TypeError("The payload has been already provided")};this.write=e,this.end=e}_unlockWrite(){this.write=super.write,this.end=super.end}async _finalizeBody(){let{options:e}=this,{headers:r}=e,i=!ce.default.undefined(e.form),n=!ce.default.undefined(e.json),s=!ce.default.undefined(e.body),o=i||n||s,a=Rt.withoutBody.has(e.method)&&!(e.method==="GET"&&e.allowGetBody);if(this._cannotHaveBody=a,o){if(a)throw new TypeError(`The \`${e.method}\` method cannot be used with a body`);if([s,i,n].filter(l=>l).length>1)throw new TypeError("The `body`, `json` and `form` options are mutually exclusive");if(s&&!(e.body instanceof n8.Readable)&&!ce.default.string(e.body)&&!ce.default.buffer(e.body)&&!a8.default(e.body))throw new TypeError("The `body` option must be a stream.Readable, string or Buffer");if(i&&!ce.default.object(e.form))throw new TypeError("The `form` option must be an Object");{let l=!ce.default.string(r["content-type"]);s?(a8.default(e.body)&&l&&(r["content-type"]=`multipart/form-data; boundary=${e.body.getBoundary()}`),this[mA]=e.body):i?(l&&(r["content-type"]="application/x-www-form-urlencoded"),this[mA]=new dA.URLSearchParams(e.form).toString()):(l&&(r["content-type"]="application/json"),this[mA]=e.stringifyJson(e.json));let c=await pSe.default(this[mA],e.headers);ce.default.undefined(r["content-length"])&&ce.default.undefined(r["transfer-encoding"])&&!a&&!ce.default.undefined(c)&&(r["content-length"]=String(c))}}else a?this._lockWrite():this._unlockWrite();this[zu]=Number(r["content-length"])||void 0}async _onResponseBase(e){let{options:r}=this,{url:i}=r;this[h8]=e,r.decompress&&(e=gSe(e));let n=e.statusCode,s=e;s.statusMessage=s.statusMessage?s.statusMessage:s8.STATUS_CODES[n],s.url=r.url.toString(),s.requestUrl=this.requestUrl,s.redirectUrls=this.redirects,s.request=this,s.isFromCache=e.fromCache||!1,s.ip=this.ip,s.retryCount=this.retryCount,this[g8]=s.isFromCache,this[Ju]=Number(e.headers["content-length"])||void 0,this[Uy]=e,e.once("end",()=>{this[Ju]=this[Wu],this.emit("downloadProgress",this.downloadProgress)}),e.once("error",a=>{e.destroy(),this._beforeError(new jy(a,this))}),e.once("aborted",()=>{this._beforeError(new jy({name:"Error",message:"The server aborted pending request",code:"ECONNRESET"},this))}),this.emit("downloadProgress",this.downloadProgress);let o=e.headers["set-cookie"];if(ce.default.object(r.cookieJar)&&o){let a=o.map(async l=>r.cookieJar.setCookie(l,i.toString()));r.ignoreInvalidCookies&&(a=a.map(async l=>l.catch(()=>{})));try{await Promise.all(a)}catch(l){this._beforeError(l);return}}if(r.followRedirect&&e.headers.location&&SSe.has(n)){if(e.resume(),this[Ei]&&(this[Ok](),delete this[Ei],this[u8]()),(n===303&&r.method!=="GET"&&r.method!=="HEAD"||!r.methodRewriting)&&(r.method="GET","body"in r&&delete r.body,"json"in r&&delete r.json,"form"in r&&delete r.form,this[mA]=void 0,delete r.headers["content-length"]),this.redirects.length>=r.maxRedirects){this._beforeError(new Hk(this));return}try{let l=Buffer.from(e.headers.location,"binary").toString(),c=new dA.URL(l,i),u=c.toString();decodeURI(u),c.hostname!==i.hostname||c.port!==i.port?("host"in r.headers&&delete r.headers.host,"cookie"in r.headers&&delete r.headers.cookie,"authorization"in r.headers&&delete r.headers.authorization,(r.username||r.password)&&(r.username="",r.password="")):(c.username=r.username,c.password=r.password),this.redirects.push(u),r.url=c;for(let g of r.hooks.beforeRedirect)await g(r,s);this.emit("redirect",s,r),await this._makeRequest()}catch(l){this._beforeError(l);return}return}if(r.isStream&&r.throwHttpErrors&&!ISe.isResponseOk(s)){this._beforeError(new Gk(s));return}e.on("readable",()=>{this[Gy]&&this._read()}),this.on("resume",()=>{e.resume()}),this.on("pause",()=>{e.pause()}),e.once("end",()=>{this.push(null)}),this.emit("response",e);for(let a of this[Hy])if(!a.headersSent){for(let l in e.headers){let c=r.decompress?l!=="content-encoding":!0,u=e.headers[l];c&&a.setHeader(l,u)}a.statusCode=n}}async _onResponse(e){try{await this._onResponseBase(e)}catch(r){this._beforeError(r)}}_onRequest(e){let{options:r}=this,{timeout:i,url:n}=r;cSe.default(e),this[Ok]=A8.default(e,i,n);let s=r.cache?"cacheableResponse":"response";e.once(s,l=>{this._onResponse(l)}),e.once("error",l=>{var c;e.destroy(),(c=e.res)===null||c===void 0||c.removeAllListeners("end"),l=l instanceof A8.TimeoutError?new qk(l,this.timings,this):new _r(l.message,l,this),this._beforeError(l)}),this[u8]=dSe.default(e,this,kSe),this[Ei]=e,this.emit("uploadProgress",this.uploadProgress);let o=this[mA],a=this.redirects.length===0?this:e;ce.default.nodeStream(o)?(o.pipe(a),o.once("error",l=>{this._beforeError(new Yk(l,this))})):(this._unlockWrite(),ce.default.undefined(o)?(this._cannotHaveBody||this._noPipe)&&(a.end(),this._lockWrite()):(this._writeRequest(o,void 0,()=>{}),a.end(),this._lockWrite())),this.emit("request",e)}async _createCacheableRequest(e,r){return new Promise((i,n)=>{Object.assign(r,CSe.default(e)),delete r.url;let s,o=Kk.get(r.cache)(r,async a=>{a._readableState.autoDestroy=!1,s&&(await s).emit("cacheableResponse",a),i(a)});r.url=e,o.once("error",n),o.once("request",async a=>{s=a,i(s)})})}async _makeRequest(){var e,r,i,n,s;let{options:o}=this,{headers:a}=o;for(let I in a)if(ce.default.undefined(a[I]))delete a[I];else if(ce.default.null_(a[I]))throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${I}\` header`);if(o.decompress&&ce.default.undefined(a["accept-encoding"])&&(a["accept-encoding"]=BSe?"gzip, deflate, br":"gzip, deflate"),o.cookieJar){let I=await o.cookieJar.getCookieString(o.url.toString());ce.default.nonEmptyString(I)&&(o.headers.cookie=I)}for(let I of o.hooks.beforeRequest){let B=await I(o);if(!ce.default.undefined(B)){o.request=()=>B;break}}o.body&&this[mA]!==o.body&&(this[mA]=o.body);let{agent:l,request:c,timeout:u,url:g}=o;if(o.dnsCache&&!("lookup"in o)&&(o.lookup=o.dnsCache.lookup),g.hostname==="unix"){let I=/(?.+?):(?.+)/.exec(`${g.pathname}${g.search}`);if(I==null?void 0:I.groups){let{socketPath:B,path:b}=I.groups;Object.assign(o,{socketPath:B,path:b,host:""})}}let f=g.protocol==="https:",h;o.http2?h=fSe.auto:h=f?lSe.request:s8.request;let p=(e=o.request)!==null&&e!==void 0?e:h,d=o.cache?this._createCacheableRequest:p;l&&!o.http2&&(o.agent=l[f?"https":"http"]),o[Ei]=p,delete o.request,delete o.timeout;let m=o;if(m.shared=(r=o.cacheOptions)===null||r===void 0?void 0:r.shared,m.cacheHeuristic=(i=o.cacheOptions)===null||i===void 0?void 0:i.cacheHeuristic,m.immutableMinTimeToLive=(n=o.cacheOptions)===null||n===void 0?void 0:n.immutableMinTimeToLive,m.ignoreCargoCult=(s=o.cacheOptions)===null||s===void 0?void 0:s.ignoreCargoCult,o.dnsLookupIpVersion!==void 0)try{m.family=c8.dnsLookupIpVersionToFamily(o.dnsLookupIpVersion)}catch(I){throw new Error("Invalid `dnsLookupIpVersion` option value")}o.https&&("rejectUnauthorized"in o.https&&(m.rejectUnauthorized=o.https.rejectUnauthorized),o.https.checkServerIdentity&&(m.checkServerIdentity=o.https.checkServerIdentity),o.https.certificateAuthority&&(m.ca=o.https.certificateAuthority),o.https.certificate&&(m.cert=o.https.certificate),o.https.key&&(m.key=o.https.key),o.https.passphrase&&(m.passphrase=o.https.passphrase),o.https.pfx&&(m.pfx=o.https.pfx));try{let I=await d(g,m);ce.default.undefined(I)&&(I=h(g,m)),o.request=c,o.timeout=u,o.agent=l,o.https&&("rejectUnauthorized"in o.https&&delete m.rejectUnauthorized,o.https.checkServerIdentity&&delete m.checkServerIdentity,o.https.certificateAuthority&&delete m.ca,o.https.certificate&&delete m.cert,o.https.key&&delete m.key,o.https.passphrase&&delete m.passphrase,o.https.pfx&&delete m.pfx),bSe(I)?this._onRequest(I):this.writable?(this.once("finish",()=>{this._onResponse(I)}),this._unlockWrite(),this.end(),this._lockWrite()):this._onResponse(I)}catch(I){throw I instanceof o8.CacheError?new jk(I,this):new _r(I.message,I,this)}}async _error(e){try{for(let r of this.options.hooks.beforeError)e=await r(e)}catch(r){e=new _r(r.message,r,this)}this.destroy(e)}_beforeError(e){if(this[_u])return;let{options:r}=this,i=this.retryCount+1;this[_u]=!0,e instanceof _r||(e=new _r(e.message,e,this));let n=e,{response:s}=n;(async()=>{if(s&&!s.body){s.setEncoding(this._readableState.encoding);try{s.rawBody=await ESe.default(s),s.body=s.rawBody.toString()}catch(o){}}if(this.listenerCount("retry")!==0){let o;try{let a;s&&"retry-after"in s.headers&&(a=Number(s.headers["retry-after"]),Number.isNaN(a)?(a=Date.parse(s.headers["retry-after"])-Date.now(),a<=0&&(a=1)):a*=1e3),o=await r.retry.calculateDelay({attemptCount:i,retryOptions:r.retry,error:n,retryAfter:a,computedValue:wSe.default({attemptCount:i,retryOptions:r.retry,error:n,retryAfter:a,computedValue:0})})}catch(a){this._error(new _r(a.message,a,this));return}if(o){let a=async()=>{try{for(let l of this.options.hooks.beforeRetry)await l(this.options,n,i)}catch(l){this._error(new _r(l.message,e,this));return}this.destroyed||(this.destroy(),this.emit("retry",i,e))};this[p8]=setTimeout(a,o);return}}this._error(n)})()}_read(){this[Gy]=!0;let e=this[Uy];if(e&&!this[_u]){e.readableLength&&(this[Gy]=!1);let r;for(;(r=e.read())!==null;){this[Wu]+=r.length,this[f8]=!0;let i=this.downloadProgress;i.percent<1&&this.emit("downloadProgress",i),this.push(r)}}}_write(e,r,i){let n=()=>{this._writeRequest(e,r,i)};this.requestInitialized?n():this[bp].push(n)}_writeRequest(e,r,i){this[Ei].destroyed||(this._progressCallbacks.push(()=>{this[Vu]+=Buffer.byteLength(e,r);let n=this.uploadProgress;n.percent<1&&this.emit("uploadProgress",n)}),this[Ei].write(e,r,n=>{!n&&this._progressCallbacks.length>0&&this._progressCallbacks.shift()(),i(n)}))}_final(e){let r=()=>{for(;this._progressCallbacks.length!==0;)this._progressCallbacks.shift()();if(!(Ei in this)){e();return}if(this[Ei].destroyed){e();return}this[Ei].end(i=>{i||(this[zu]=this[Vu],this.emit("uploadProgress",this.uploadProgress),this[Ei].emit("upload-complete")),e(i)})};this.requestInitialized?r():this[bp].push(r)}_destroy(e,r){var i;this[_u]=!0,clearTimeout(this[p8]),Ei in this&&(this[Ok](),((i=this[Uy])===null||i===void 0?void 0:i.complete)||this[Ei].destroy()),e!==null&&!ce.default.undefined(e)&&!(e instanceof _r)&&(e=new _r(e.message,e,this)),r(e)}get _isAboutToError(){return this[_u]}get ip(){var e;return(e=this.socket)===null||e===void 0?void 0:e.remoteAddress}get aborted(){var e,r,i;return((r=(e=this[Ei])===null||e===void 0?void 0:e.destroyed)!==null&&r!==void 0?r:this.destroyed)&&!((i=this[h8])===null||i===void 0?void 0:i.complete)}get socket(){var e,r;return(r=(e=this[Ei])===null||e===void 0?void 0:e.socket)!==null&&r!==void 0?r:void 0}get downloadProgress(){let e;return this[Ju]?e=this[Wu]/this[Ju]:this[Ju]===this[Wu]?e=1:e=0,{percent:e,transferred:this[Wu],total:this[Ju]}}get uploadProgress(){let e;return this[zu]?e=this[Vu]/this[zu]:this[zu]===this[Vu]?e=1:e=0,{percent:e,transferred:this[Vu],total:this[zu]}}get timings(){var e;return(e=this[Ei])===null||e===void 0?void 0:e.timings}get isFromCache(){return this[g8]}pipe(e,r){if(this[f8])throw new Error("Failed to pipe. The response has been emitted already.");return e instanceof Tk.ServerResponse&&this[Hy].add(e),super.pipe(e,r)}unpipe(e){return e instanceof Tk.ServerResponse&&this[Hy].delete(e),super.unpipe(e),this}};Rt.default=Uk});var Sp=E(Ms=>{"use strict";var PSe=Ms&&Ms.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r),Object.defineProperty(t,i,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),DSe=Ms&&Ms.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&PSe(e,t,r)};Object.defineProperty(Ms,"__esModule",{value:!0});Ms.CancelError=Ms.ParseError=void 0;var d8=vp(),C8=class extends d8.RequestError{constructor(e,r){let{options:i}=r.request;super(`${e.message} in "${i.url.toString()}"`,e,r.request);this.name="ParseError"}};Ms.ParseError=C8;var m8=class extends d8.RequestError{constructor(e){super("Promise was canceled",{},e);this.name="CancelError"}get isCanceled(){return!0}};Ms.CancelError=m8;DSe(vp(),Ms)});var I8=E(Wk=>{"use strict";Object.defineProperty(Wk,"__esModule",{value:!0});var E8=Sp(),RSe=(t,e,r,i)=>{let{rawBody:n}=t;try{if(e==="text")return n.toString(i);if(e==="json")return n.length===0?"":r(n.toString());if(e==="buffer")return n;throw new E8.ParseError({message:`Unknown body type '${e}'`,name:"Error"},t)}catch(s){throw new E8.ParseError(s,t)}};Wk.default=RSe});var zk=E(EA=>{"use strict";var FSe=EA&&EA.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r),Object.defineProperty(t,i,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),NSe=EA&&EA.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&FSe(e,t,r)};Object.defineProperty(EA,"__esModule",{value:!0});var LSe=require("events"),TSe=Ca(),MSe=g3(),Yy=Sp(),y8=I8(),w8=vp(),OSe=bk(),KSe=Rk(),B8=Fk(),USe=["request","response","redirect","uploadProgress","downloadProgress"];function Q8(t){let e,r,i=new LSe.EventEmitter,n=new MSe((o,a,l)=>{let c=u=>{let g=new w8.default(void 0,t);g.retryCount=u,g._noPipe=!0,l(()=>g.destroy()),l.shouldReject=!1,l(()=>a(new Yy.CancelError(g))),e=g,g.once("response",async p=>{var d;if(p.retryCount=u,p.request.aborted)return;let m;try{m=await KSe.default(g),p.rawBody=m}catch(R){return}if(g._isAboutToError)return;let I=((d=p.headers["content-encoding"])!==null&&d!==void 0?d:"").toLowerCase(),B=["gzip","deflate","br"].includes(I),{options:b}=g;if(B&&!b.decompress)p.body=m;else try{p.body=y8.default(p,b.responseType,b.parseJson,b.encoding)}catch(R){if(p.body=m.toString(),B8.isResponseOk(p)){g._beforeError(R);return}}try{for(let[R,H]of b.hooks.afterResponse.entries())p=await H(p,async L=>{let K=w8.default.normalizeArguments(void 0,_(P({},L),{retry:{calculateDelay:()=>0},throwHttpErrors:!1,resolveBodyOnly:!1}),b);K.hooks.afterResponse=K.hooks.afterResponse.slice(0,R);for(let ne of K.hooks.beforeRetry)await ne(K);let J=Q8(K);return l(()=>{J.catch(()=>{}),J.cancel()}),J})}catch(R){g._beforeError(new Yy.RequestError(R.message,R,g));return}if(!B8.isResponseOk(p)){g._beforeError(new Yy.HTTPError(p));return}r=p,o(g.options.resolveBodyOnly?p.body:p)});let f=p=>{if(n.isCanceled)return;let{options:d}=g;if(p instanceof Yy.HTTPError&&!d.throwHttpErrors){let{response:m}=p;o(g.options.resolveBodyOnly?m.body:m);return}a(p)};g.once("error",f);let h=g.options.body;g.once("retry",(p,d)=>{var m,I;if(h===((m=d.request)===null||m===void 0?void 0:m.options.body)&&TSe.default.nodeStream((I=d.request)===null||I===void 0?void 0:I.options.body)){f(d);return}c(p)}),OSe.default(g,i,USe)};c(0)});n.on=(o,a)=>(i.on(o,a),n);let s=o=>{let a=(async()=>{await n;let{options:l}=r.request;return y8.default(r,o,l.parseJson,l.encoding)})();return Object.defineProperties(a,Object.getOwnPropertyDescriptors(n)),a};return n.json=()=>{let{headers:o}=e.options;return!e.writableFinished&&o.accept===void 0&&(o.accept="application/json"),s("json")},n.buffer=()=>s("buffer"),n.text=()=>s("text"),n}EA.default=Q8;NSe(Sp(),EA)});var b8=E(Vk=>{"use strict";Object.defineProperty(Vk,"__esModule",{value:!0});var HSe=Sp();function GSe(t,...e){let r=(async()=>{if(t instanceof HSe.RequestError)try{for(let n of e)if(n)for(let s of n)t=await s(t)}catch(n){t=n}throw t})(),i=()=>r;return r.json=i,r.text=i,r.buffer=i,r.on=i,r}Vk.default=GSe});var x8=E(_k=>{"use strict";Object.defineProperty(_k,"__esModule",{value:!0});var v8=Ca();function S8(t){for(let e of Object.values(t))(v8.default.plainObject(e)||v8.default.array(e))&&S8(e);return Object.freeze(t)}_k.default=S8});var P8=E(k8=>{"use strict";Object.defineProperty(k8,"__esModule",{value:!0})});var Xk=E(ss=>{"use strict";var jSe=ss&&ss.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r),Object.defineProperty(t,i,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),YSe=ss&&ss.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&jSe(e,t,r)};Object.defineProperty(ss,"__esModule",{value:!0});ss.defaultHandler=void 0;var D8=Ca(),os=zk(),qSe=b8(),qy=vp(),JSe=x8(),WSe={RequestError:os.RequestError,CacheError:os.CacheError,ReadError:os.ReadError,HTTPError:os.HTTPError,MaxRedirectsError:os.MaxRedirectsError,TimeoutError:os.TimeoutError,ParseError:os.ParseError,CancelError:os.CancelError,UnsupportedProtocolError:os.UnsupportedProtocolError,UploadError:os.UploadError},zSe=async t=>new Promise(e=>{setTimeout(e,t)}),{normalizeArguments:Jy}=qy.default,R8=(...t)=>{let e;for(let r of t)e=Jy(void 0,r,e);return e},VSe=t=>t.isStream?new qy.default(void 0,t):os.default(t),_Se=t=>"defaults"in t&&"options"in t.defaults,XSe=["get","post","put","patch","head","delete"];ss.defaultHandler=(t,e)=>e(t);var F8=(t,e)=>{if(t)for(let r of t)r(e)},N8=t=>{t._rawHandlers=t.handlers,t.handlers=t.handlers.map(i=>(n,s)=>{let o,a=i(n,l=>(o=s(l),o));if(a!==o&&!n.isStream&&o){let l=a,{then:c,catch:u,finally:g}=l;Object.setPrototypeOf(l,Object.getPrototypeOf(o)),Object.defineProperties(l,Object.getOwnPropertyDescriptors(o)),l.then=c,l.catch=u,l.finally=g}return a});let e=(i,n={},s)=>{var o,a;let l=0,c=u=>t.handlers[l++](u,l===t.handlers.length?VSe:c);if(D8.default.plainObject(i)){let u=P(P({},i),n);qy.setNonEnumerableProperties([i,n],u),n=u,i=void 0}try{let u;try{F8(t.options.hooks.init,n),F8((o=n.hooks)===null||o===void 0?void 0:o.init,n)}catch(f){u=f}let g=Jy(i,n,s!=null?s:t.options);if(g[qy.kIsNormalizedAlready]=!0,u)throw new os.RequestError(u.message,u,g);return c(g)}catch(u){if(n.isStream)throw u;return qSe.default(u,t.options.hooks.beforeError,(a=n.hooks)===null||a===void 0?void 0:a.beforeError)}};e.extend=(...i)=>{let n=[t.options],s=[...t._rawHandlers],o;for(let a of i)_Se(a)?(n.push(a.defaults.options),s.push(...a.defaults._rawHandlers),o=a.defaults.mutableDefaults):(n.push(a),"handlers"in a&&s.push(...a.handlers),o=a.mutableDefaults);return s=s.filter(a=>a!==ss.defaultHandler),s.length===0&&s.push(ss.defaultHandler),N8({options:R8(...n),handlers:s,mutableDefaults:Boolean(o)})};let r=async function*(i,n){let s=Jy(i,n,t.options);s.resolveBodyOnly=!1;let o=s.pagination;if(!D8.default.object(o))throw new TypeError("`options.pagination` must be implemented");let a=[],{countLimit:l}=o,c=0;for(;c{let s=[];for await(let o of r(i,n))s.push(o);return s},e.paginate.each=r,e.stream=(i,n)=>e(i,_(P({},n),{isStream:!0}));for(let i of XSe)e[i]=(n,s)=>e(n,_(P({},s),{method:i})),e.stream[i]=(n,s)=>e(n,_(P({},s),{method:i,isStream:!0}));return Object.assign(e,WSe),Object.defineProperty(e,"defaults",{value:t.mutableDefaults?t:JSe.default(t),writable:t.mutableDefaults,configurable:t.mutableDefaults,enumerable:!0}),e.mergeOptions=R8,e};ss.default=N8;YSe(P8(),ss)});var zy=E((Ea,Wy)=>{"use strict";var ZSe=Ea&&Ea.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r),Object.defineProperty(t,i,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),L8=Ea&&Ea.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&ZSe(e,t,r)};Object.defineProperty(Ea,"__esModule",{value:!0});var $Se=require("url"),T8=Xk(),exe={options:{method:"GET",retry:{limit:2,methods:["GET","PUT","HEAD","DELETE","OPTIONS","TRACE"],statusCodes:[408,413,429,500,502,503,504,521,522,524],errorCodes:["ETIMEDOUT","ECONNRESET","EADDRINUSE","ECONNREFUSED","EPIPE","ENOTFOUND","ENETUNREACH","EAI_AGAIN"],maxRetryAfter:void 0,calculateDelay:({computedValue:t})=>t},timeout:{},headers:{"user-agent":"got (https://github.com/sindresorhus/got)"},hooks:{init:[],beforeRequest:[],beforeRedirect:[],beforeRetry:[],beforeError:[],afterResponse:[]},cache:void 0,dnsCache:void 0,decompress:!0,throwHttpErrors:!0,followRedirect:!0,isStream:!1,responseType:"text",resolveBodyOnly:!1,maxRedirects:10,prefixUrl:"",methodRewriting:!0,ignoreInvalidCookies:!1,context:{},http2:!1,allowGetBody:!1,https:void 0,pagination:{transform:t=>t.request.options.responseType==="json"?t.body:JSON.parse(t.body),paginate:t=>{if(!Reflect.has(t.headers,"link"))return!1;let e=t.headers.link.split(","),r;for(let i of e){let n=i.split(";");if(n[1].includes("next")){r=n[0].trimStart().trim(),r=r.slice(1,-1);break}}return r?{url:new $Se.URL(r)}:!1},filter:()=>!0,shouldContinue:()=>!0,countLimit:Infinity,backoff:0,requestLimit:1e4,stackAllItems:!0},parseJson:t=>JSON.parse(t),stringifyJson:t=>JSON.stringify(t),cacheOptions:{}},handlers:[T8.defaultHandler],mutableDefaults:!1},Zk=T8.default(exe);Ea.default=Zk;Wy.exports=Zk;Wy.exports.default=Zk;Wy.exports.__esModule=!0;L8(Xk(),Ea);L8(zk(),Ea)});var U8=E(Xu=>{"use strict";var fst=require("net"),txe=require("tls"),$k=require("http"),M8=require("https"),rxe=require("events"),hst=require("assert"),ixe=require("util");Xu.httpOverHttp=nxe;Xu.httpsOverHttp=sxe;Xu.httpOverHttps=oxe;Xu.httpsOverHttps=axe;function nxe(t){var e=new Ia(t);return e.request=$k.request,e}function sxe(t){var e=new Ia(t);return e.request=$k.request,e.createSocket=O8,e.defaultPort=443,e}function oxe(t){var e=new Ia(t);return e.request=M8.request,e}function axe(t){var e=new Ia(t);return e.request=M8.request,e.createSocket=O8,e.defaultPort=443,e}function Ia(t){var e=this;e.options=t||{},e.proxyOptions=e.options.proxy||{},e.maxSockets=e.options.maxSockets||$k.Agent.defaultMaxSockets,e.requests=[],e.sockets=[],e.on("free",function(i,n,s,o){for(var a=K8(n,s,o),l=0,c=e.requests.length;l=this.maxSockets){s.requests.push(o);return}s.createSocket(o,function(a){a.on("free",l),a.on("close",c),a.on("agentRemove",c),e.onSocket(a);function l(){s.emit("free",a,o)}function c(u){s.removeSocket(a),a.removeListener("free",l),a.removeListener("close",c),a.removeListener("agentRemove",c)}})};Ia.prototype.createSocket=function(e,r){var i=this,n={};i.sockets.push(n);var s=eP({},i.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:!1,headers:{host:e.host+":"+e.port}});e.localAddress&&(s.localAddress=e.localAddress),s.proxyAuth&&(s.headers=s.headers||{},s.headers["Proxy-Authorization"]="Basic "+new Buffer(s.proxyAuth).toString("base64")),IA("making CONNECT request");var o=i.request(s);o.useChunkedEncodingByDefault=!1,o.once("response",a),o.once("upgrade",l),o.once("connect",c),o.once("error",u),o.end();function a(g){g.upgrade=!0}function l(g,f,h){process.nextTick(function(){c(g,f,h)})}function c(g,f,h){if(o.removeAllListeners(),f.removeAllListeners(),g.statusCode!==200){IA("tunneling socket could not be established, statusCode=%d",g.statusCode),f.destroy();var p=new Error("tunneling socket could not be established, statusCode="+g.statusCode);p.code="ECONNRESET",e.request.emit("error",p),i.removeSocket(n);return}if(h.length>0){IA("got illegal response body from proxy"),f.destroy();var p=new Error("got illegal response body from proxy");p.code="ECONNRESET",e.request.emit("error",p),i.removeSocket(n);return}return IA("tunneling connection has established"),i.sockets[i.sockets.indexOf(n)]=f,r(f)}function u(g){o.removeAllListeners(),IA(`tunneling socket could not be established, cause=%s +`,g.message,g.stack);var f=new Error("tunneling socket could not be established, cause="+g.message);f.code="ECONNRESET",e.request.emit("error",f),i.removeSocket(n)}};Ia.prototype.removeSocket=function(e){var r=this.sockets.indexOf(e);if(r!==-1){this.sockets.splice(r,1);var i=this.requests.shift();i&&this.createSocket(i,function(n){i.request.onSocket(n)})}};function O8(t,e){var r=this;Ia.prototype.createSocket.call(r,t,function(i){var n=t.request.getHeader("host"),s=eP({},r.options,{socket:i,servername:n?n.replace(/:.*$/,""):t.host}),o=txe.connect(0,s);r.sockets[r.sockets.indexOf(i)]=o,e(o)})}function K8(t,e,r){return typeof t=="string"?{host:t,port:e,localAddress:r}:t}function eP(t){for(var e=1,r=arguments.length;e{H8.exports=U8()});var b4=E((xot,sP)=>{var e4=Object.assign({},require("fs")),oe=typeof oe!="undefined"?oe:{},kp={},wA;for(wA in oe)oe.hasOwnProperty(wA)&&(kp[wA]=oe[wA]);var oP=[],t4="./this.program",r4=function(t,e){throw e},i4=!1,Wl=!0,Pp="";function dxe(t){return oe.locateFile?oe.locateFile(t,Pp):Pp+t}var Xy,aP,Zy,AP;Wl&&(i4?Pp=require("path").dirname(Pp)+"/":Pp=__dirname+"/",Xy=function(e,r){var i=s4(e);return i?r?i:i.toString():(Zy||(Zy=e4),AP||(AP=require("path")),e=AP.normalize(e),Zy.readFileSync(e,r?null:"utf8"))},aP=function(e){var r=Xy(e,!0);return r.buffer||(r=new Uint8Array(r)),n4(r.buffer),r},process.argv.length>1&&(t4=process.argv[1].replace(/\\/g,"/")),oP=process.argv.slice(2),typeof sP!="undefined"&&(sP.exports=oe),r4=function(t){process.exit(t)},oe.inspect=function(){return"[Emscripten Module object]"});var $y=oe.print||console.log.bind(console),Di=oe.printErr||console.warn.bind(console);for(wA in kp)kp.hasOwnProperty(wA)&&(oe[wA]=kp[wA]);kp=null;oe.arguments&&(oP=oe.arguments);oe.thisProgram&&(t4=oe.thisProgram);oe.quit&&(r4=oe.quit);var Cxe=16;function mxe(t,e){return e||(e=Cxe),Math.ceil(t/e)*e}var Exe=0,Ixe=function(t){Exe=t},lP;oe.wasmBinary&&(lP=oe.wasmBinary);var Pst=oe.noExitRuntime||!0;typeof WebAssembly!="object"&&Gr("no native wasm support detected");function yxe(t,e,r){switch(e=e||"i8",e.charAt(e.length-1)==="*"&&(e="i32"),e){case"i1":return Zi[t>>0];case"i8":return Zi[t>>0];case"i16":return cP[t>>1];case"i32":return _e[t>>2];case"i64":return _e[t>>2];case"float":return o4[t>>2];case"double":return a4[t>>3];default:Gr("invalid type for getValue: "+e)}return null}var ew,A4=!1,wxe;function n4(t,e){t||Gr("Assertion failed: "+e)}function l4(t){var e=oe["_"+t];return n4(e,"Cannot call unknown function "+t+", make sure it is exported"),e}function vxe(t,e,r,i,n){var s={string:function(h){var p=0;if(h!=null&&h!==0){var d=(h.length<<2)+1;p=g4(d),u4(h,p,d)}return p},array:function(h){var p=g4(h.length);return Bxe(h,p),p}};function o(h){return e==="string"?c4(h):e==="boolean"?Boolean(h):h}var a=l4(t),l=[],c=0;if(i)for(var u=0;u=i);)++n;if(n-e>16&&t.subarray&&f4)return f4.decode(t.subarray(e,n));for(var s="";e>10,56320|c&1023)}}return s}function c4(t,e){return t?Zu($u,t,e):""}function tw(t,e,r,i){if(!(i>0))return 0;for(var n=r,s=r+i-1,o=0;o=55296&&a<=57343){var l=t.charCodeAt(++o);a=65536+((a&1023)<<10)|l&1023}if(a<=127){if(r>=s)break;e[r++]=a}else if(a<=2047){if(r+1>=s)break;e[r++]=192|a>>6,e[r++]=128|a&63}else if(a<=65535){if(r+2>=s)break;e[r++]=224|a>>12,e[r++]=128|a>>6&63,e[r++]=128|a&63}else{if(r+3>=s)break;e[r++]=240|a>>18,e[r++]=128|a>>12&63,e[r++]=128|a>>6&63,e[r++]=128|a&63}}return e[r]=0,r-n}function u4(t,e,r){return tw(t,$u,e,r)}function rw(t){for(var e=0,r=0;r=55296&&i<=57343&&(i=65536+((i&1023)<<10)|t.charCodeAt(++r)&1023),i<=127?++e:i<=2047?e+=2:i<=65535?e+=3:e+=4}return e}function uP(t){var e=rw(t)+1,r=h4(e);return r&&tw(t,Zi,r,e),r}function Bxe(t,e){Zi.set(t,e)}function xxe(t,e){return t%e>0&&(t+=e-t%e),t}var gP,Zi,$u,cP,kxe,_e,Pxe,o4,a4;function p4(t){gP=t,oe.HEAP8=Zi=new Int8Array(t),oe.HEAP16=cP=new Int16Array(t),oe.HEAP32=_e=new Int32Array(t),oe.HEAPU8=$u=new Uint8Array(t),oe.HEAPU16=kxe=new Uint16Array(t),oe.HEAPU32=Pxe=new Uint32Array(t),oe.HEAPF32=o4=new Float32Array(t),oe.HEAPF64=a4=new Float64Array(t)}var Dst=oe.INITIAL_MEMORY||16777216,fP,d4=[],C4=[],m4=[],Dxe=!1;function Fxe(){if(oe.preRun)for(typeof oe.preRun=="function"&&(oe.preRun=[oe.preRun]);oe.preRun.length;)Rxe(oe.preRun.shift());hP(d4)}function Nxe(){Dxe=!0,!oe.noFSInit&&!y.init.initialized&&y.init(),BA.init(),hP(C4)}function Txe(){if(oe.postRun)for(typeof oe.postRun=="function"&&(oe.postRun=[oe.postRun]);oe.postRun.length;)Lxe(oe.postRun.shift());hP(m4)}function Rxe(t){d4.unshift(t)}function Mxe(t){C4.unshift(t)}function Lxe(t){m4.unshift(t)}var zl=0,pP=null,Dp=null;function Oxe(t){return t}function E4(t){zl++,oe.monitorRunDependencies&&oe.monitorRunDependencies(zl)}function dP(t){if(zl--,oe.monitorRunDependencies&&oe.monitorRunDependencies(zl),zl==0&&(pP!==null&&(clearInterval(pP),pP=null),Dp)){var e=Dp;Dp=null,e()}}oe.preloadedImages={};oe.preloadedAudios={};function Gr(t){oe.onAbort&&oe.onAbort(t),t+="",Di(t),A4=!0,wxe=1,t="abort("+t+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(t);throw e}var I4="data:application/octet-stream;base64,";function y4(t){return t.startsWith(I4)}var Rp="data:application/octet-stream;base64,AGFzbQEAAAABlAInYAF/AX9gA39/fwF/YAF/AGACf38Bf2ACf38AYAV/f39/fwF/YAR/f39/AX9gA39/fwBgBH9+f38Bf2AAAX9gBX9/f35/AX5gA39+fwF/YAF/AX5gAn9+AX9gBH9/fn8BfmADf35/AX5gA39/fgF/YAR/f35/AX9gBn9/f39/fwF/YAR/f39/AGADf39+AX5gAn5/AX9gA398fwBgBH9/f38BfmADf39/AX5gBn98f39/fwF/YAV/f35/fwF/YAV/fn9/fwF/YAV/f39/fwBgAn9+AGACf38BfmACf3wAYAh/fn5/f39+fwF/YAV/f39+fwBgAABgBX5+f35/AX5gAnx/AXxgAn9+AX5gBX9/f39/AX4CeRQBYQFhAAIBYQFiAAABYQFjAAMBYQFkAAYBYQFlAAEBYQFmAAABYQFnAAYBYQFoAAABYQFpAAMBYQFqAAMBYQFrAAMBYQFsAAMBYQFtAAABYQFuAAUBYQFvAAEBYQFwAAMBYQFxAAEBYQFyAAABYQFzAAEBYQF0AAADggKAAgcCAgQAAQECAgANBAQOBwICAhwLEw0AAA0dFAwMAAcCDBAeAgMCAwIAAgEABwgUBBUIBgADAAwABAgIAgEGBgABAB8XAQEDAhMCAwUFEQICIA8GAgMYAQgCAQAABwUBGAAaAxIBAAcEAyERCCIHAQsVAQMABQMDAwAFBAACIwYAAQEAGw0bFw0BBAALCwMDDAwAAwAHJAMBBAgaAQECBQMBAwMABwcHAgICAiURCwgICwEmCQkAAAAKAAIABQAGBgUFBQEDBgYGBRISBgQBAQEAAAIJBgABAA4AAQEPCQABBBkJCQkAAAADCgoBAQIQAAAAAgEDAwkEAQoABQ4AAAkEBQFwAR8fBQcBAYACgIACBgkBfwFB0KDBAgsHvgI8AXUCAAF2AIABAXcAkwIBeADxAQF5AM8BAXoAzQEBQQDLAQFCAMoBAUMAyQEBRADIAQFFAMcBAUYAkgIBRwCRAgFIAI4CAUkA6QEBSgDiAQFLAOEBAUwAPQFNAOABAU4A+gEBTwD5AQFQAPIBAVEA+wEBUgDfAQFTAN4BAVQA3QEBVQDcAQFWAOMBAVcA2wEBWADaAQFZANkBAVoA2AEBXwDXAQEkAOoBAmFhAJwBAmJhANYBAmNhANUBAmRhANQBAmVhADECZmEA6wECZ2EAGwJoYQDOAQJpYQBJAmphANMBAmthANIBAmxhAGgCbWEA0QECbmEA6AECb2EA0AECcGEA5AECcWEAigICcmEA+AECc2EA9wECdGEA9gECdWEA5wECdmEA5gECd2EA5QECeGEAGAJ5YQAVAnphAQAJQQEAQQELHswBkAKNAo8CjAKLArYBiQKIAocChgKFAoQCgwKCAoECgAL/Af4B/QH8AVr1AfQB8wHwAe8B7gHtAewBCq2RCYACQAEBfyMAQRBrIgMgADYCDCADIAE2AgggAyACNgIEIAMoAgwEQCADKAIMIAMoAgg2AgAgAygCDCADKAIENgIECwvMDAEHfwJAIABFDQAgAEEIayIDIABBBGsoAgAiAUF4cSIAaiEFAkAgAUEBcQ0AIAFBA3FFDQEgAyADKAIAIgFrIgNByJsBKAIASQ0BIAAgAWohACADQcybASgCAEcEQCABQf8BTQRAIAMoAggiAiABQQN2IgRBA3RB4JsBakYaIAIgAygCDCIBRgRAQbibAUG4mwEoAgBBfiAEd3E2AgAMAwsgAiABNgIMIAEgAjYCCAwCCyADKAIYIQYCQCADIAMoAgwiAUcEQCADKAIIIgIgATYCDCABIAI2AggMAQsCQCADQRRqIgIoAgAiBA0AIANBEGoiAigCACIEDQBBACEBDAELA0AgAiEHIAQiAUEUaiICKAIAIgQNACABQRBqIQIgASgCECIEDQALIAdBADYCAAsgBkUNAQJAIAMgAygCHCICQQJ0QeidAWoiBCgCAEYEQCAEIAE2AgAgAQ0BQbybAUG8mwEoAgBBfiACd3E2AgAMAwsgBkEQQRQgBigCECADRhtqIAE2AgAgAUUNAgsgASAGNgIYIAMoAhAiAgRAIAEgAjYCECACIAE2AhgLIAMoAhQiAkUNASABIAI2AhQgAiABNgIYDAELIAUoAgQiAUEDcUEDRw0AQcCbASAANgIAIAUgAUF+cTYCBCADIABBAXI2AgQgACADaiAANgIADwsgAyAFTw0AIAUoAgQiAUEBcUUNAAJAIAFBAnFFBEAgBUHQmwEoAgBGBEBB0JsBIAM2AgBBxJsBQcSbASgCACAAaiIANgIAIAMgAEEBcjYCBCADQcybASgCAEcNA0HAmwFBADYCAEHMmwFBADYCAA8LIAVBzJsBKAIARgRAQcybASADNgIAQcCbAUHAmwEoAgAgAGoiADYCACADIABBAXI2AgQgACADaiAANgIADwsgAUF4cSAAaiEAAkAgAUH/AU0EQCAFKAIIIgIgAUEDdiIEQQN0QeCbAWpGGiACIAUoAgwiAUYEQEG4mwFBuJsBKAIAQX4gBHdxNgIADAILIAIgATYCDCABIAI2AggMAQsgBSgCGCEGAkAgBSAFKAIMIgFHBEAgBSgCCCICQcibASgCAEkaIAIgATYCDCABIAI2AggMAQsCQCAFQRRqIgIoAgAiBA0AIAVBEGoiAigCACIEDQBBACEBDAELA0AgAiEHIAQiAUEUaiICKAIAIgQNACABQRBqIQIgASgCECIEDQALIAdBADYCAAsgBkUNAAJAIAUgBSgCHCICQQJ0QeidAWoiBCgCAEYEQCAEIAE2AgAgAQ0BQbybAUG8mwEoAgBBfiACd3E2AgAMAgsgBkEQQRQgBigCECAFRhtqIAE2AgAgAUUNAQsgASAGNgIYIAUoAhAiAgRAIAEgAjYCECACIAE2AhgLIAUoAhQiAkUNACABIAI2AhQgAiABNgIYCyADIABBAXI2AgQgACADaiAANgIAIANBzJsBKAIARw0BQcCbASAANgIADwsgBSABQX5xNgIEIAMgAEEBcjYCBCAAIANqIAA2AgALIABB/wFNBEAgAEEDdiIBQQN0QeCbAWohAAJ/QbibASgCACICQQEgAXQiAXFFBEBBuJsBIAEgAnI2AgAgAAwBCyAAKAIICyECIAAgAzYCCCACIAM2AgwgAyAANgIMIAMgAjYCCA8LQR8hAiADQgA3AhAgAEH///8HTQRAIABBCHYiASABQYD+P2pBEHZBCHEiAXQiAiACQYDgH2pBEHZBBHEiAnQiBCAEQYCAD2pBEHZBAnEiBHRBD3YgASACciAEcmsiAUEBdCAAIAFBFWp2QQFxckEcaiECCyADIAI2AhwgAkECdEHonQFqIQECQAJAAkBBvJsBKAIAIgRBASACdCIHcUUEQEG8mwEgBCAHcjYCACABIAM2AgAgAyABNgIYDAELIABBAEEZIAJBAXZrIAJBH0YbdCECIAEoAgAhAQNAIAEiBCgCBEF4cSAARg0CIAJBHXYhASACQQF0IQIgBCABQQRxaiIHQRBqKAIAIgENAAsgByADNgIQIAMgBDYCGAsgAyADNgIMIAMgAzYCCAwBCyAEKAIIIgAgAzYCDCAEIAM2AgggA0EANgIYIAMgBDYCDCADIAA2AggLQdibAUHYmwEoAgBBAWsiAEF/IAAbNgIACwtCAQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgASgCDC0AAUEBcQRAIAEoAgwoAgQQFQsgASgCDBAVCyABQRBqJAALQwEBfyMAQRBrIgIkACACIAA2AgwgAiABNgIIIAIoAgwCfyMAQRBrIgAgAigCCDYCDCAAKAIMQQxqCxBDIAJBEGokAAuiLgEMfyMAQRBrIgwkAAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAQfQBTQRAQbibASgCACIFQRAgAEELakF4cSAAQQtJGyIIQQN2IgJ2IgFBA3EEQCABQX9zQQFxIAJqIgNBA3QiAUHomwFqKAIAIgRBCGohAAJAIAQoAggiAiABQeCbAWoiAUYEQEG4mwEgBUF+IAN3cTYCAAwBCyACIAE2AgwgASACNgIICyAEIANBA3QiAUEDcjYCBCABIARqIgEgASgCBEEBcjYCBAwNCyAIQcCbASgCACIKTQ0BIAEEQAJAQQIgAnQiAEEAIABrciABIAJ0cSIAQQAgAGtxQQFrIgAgAEEMdkEQcSICdiIBQQV2QQhxIgAgAnIgASAAdiIBQQJ2QQRxIgByIAEgAHYiAUEBdkECcSIAciABIAB2IgFBAXZBAXEiAHIgASAAdmoiA0EDdCIAQeibAWooAgAiBCgCCCIBIABB4JsBaiIARgRAQbibASAFQX4gA3dxIgU2AgAMAQsgASAANgIMIAAgATYCCAsgBEEIaiEAIAQgCEEDcjYCBCAEIAhqIgIgA0EDdCIBIAhrIgNBAXI2AgQgASAEaiADNgIAIAoEQCAKQQN2IgFBA3RB4JsBaiEHQcybASgCACEEAn8gBUEBIAF0IgFxRQRAQbibASABIAVyNgIAIAcMAQsgBygCCAshASAHIAQ2AgggASAENgIMIAQgBzYCDCAEIAE2AggLQcybASACNgIAQcCbASADNgIADA0LQbybASgCACIGRQ0BIAZBACAGa3FBAWsiACAAQQx2QRBxIgJ2IgFBBXZBCHEiACACciABIAB2IgFBAnZBBHEiAHIgASAAdiIBQQF2QQJxIgByIAEgAHYiAUEBdkEBcSIAciABIAB2akECdEHonQFqKAIAIgEoAgRBeHEgCGshAyABIQIDQAJAIAIoAhAiAEUEQCACKAIUIgBFDQELIAAoAgRBeHEgCGsiAiADIAIgA0kiAhshAyAAIAEgAhshASAAIQIMAQsLIAEgCGoiCSABTQ0CIAEoAhghCyABIAEoAgwiBEcEQCABKAIIIgBByJsBKAIASRogACAENgIMIAQgADYCCAwMCyABQRRqIgIoAgAiAEUEQCABKAIQIgBFDQQgAUEQaiECCwNAIAIhByAAIgRBFGoiAigCACIADQAgBEEQaiECIAQoAhAiAA0ACyAHQQA2AgAMCwtBfyEIIABBv39LDQAgAEELaiIAQXhxIQhBvJsBKAIAIglFDQBBACAIayEDAkACQAJAAn9BACAIQYACSQ0AGkEfIAhB////B0sNABogAEEIdiIAIABBgP4/akEQdkEIcSICdCIAIABBgOAfakEQdkEEcSIBdCIAIABBgIAPakEQdkECcSIAdEEPdiABIAJyIAByayIAQQF0IAggAEEVanZBAXFyQRxqCyIFQQJ0QeidAWooAgAiAkUEQEEAIQAMAQtBACEAIAhBAEEZIAVBAXZrIAVBH0YbdCEBA0ACQCACKAIEQXhxIAhrIgcgA08NACACIQQgByIDDQBBACEDIAIhAAwDCyAAIAIoAhQiByAHIAIgAUEddkEEcWooAhAiAkYbIAAgBxshACABQQF0IQEgAg0ACwsgACAEckUEQEECIAV0IgBBACAAa3IgCXEiAEUNAyAAQQAgAGtxQQFrIgAgAEEMdkEQcSICdiIBQQV2QQhxIgAgAnIgASAAdiIBQQJ2QQRxIgByIAEgAHYiAUEBdkECcSIAciABIAB2IgFBAXZBAXEiAHIgASAAdmpBAnRB6J0BaigCACEACyAARQ0BCwNAIAAoAgRBeHEgCGsiASADSSECIAEgAyACGyEDIAAgBCACGyEEIAAoAhAiAQR/IAEFIAAoAhQLIgANAAsLIARFDQAgA0HAmwEoAgAgCGtPDQAgBCAIaiIGIARNDQEgBCgCGCEFIAQgBCgCDCIBRwRAIAQoAggiAEHImwEoAgBJGiAAIAE2AgwgASAANgIIDAoLIARBFGoiAigCACIARQRAIAQoAhAiAEUNBCAEQRBqIQILA0AgAiEHIAAiAUEUaiICKAIAIgANACABQRBqIQIgASgCECIADQALIAdBADYCAAwJCyAIQcCbASgCACICTQRAQcybASgCACEDAkAgAiAIayIBQRBPBEBBwJsBIAE2AgBBzJsBIAMgCGoiADYCACAAIAFBAXI2AgQgAiADaiABNgIAIAMgCEEDcjYCBAwBC0HMmwFBADYCAEHAmwFBADYCACADIAJBA3I2AgQgAiADaiIAIAAoAgRBAXI2AgQLIANBCGohAAwLCyAIQcSbASgCACIGSQRAQcSbASAGIAhrIgE2AgBB0JsBQdCbASgCACICIAhqIgA2AgAgACABQQFyNgIEIAIgCEEDcjYCBCACQQhqIQAMCwtBACEAIAhBL2oiCQJ/QZCfASgCAARAQZifASgCAAwBC0GcnwFCfzcCAEGUnwFCgKCAgICABDcCAEGQnwEgDEEMakFwcUHYqtWqBXM2AgBBpJ8BQQA2AgBB9J4BQQA2AgBBgCALIgFqIgVBACABayIHcSICIAhNDQpB8J4BKAIAIgQEQEHongEoAgAiAyACaiIBIANNDQsgASAESw0LC0H0ngEtAABBBHENBQJAAkBB0JsBKAIAIgMEQEH4ngEhAANAIAMgACgCACIBTwRAIAEgACgCBGogA0sNAwsgACgCCCIADQALC0EAEDwiAUF/Rg0GIAIhBUGUnwEoAgAiA0EBayIAIAFxBEAgAiABayAAIAFqQQAgA2txaiEFCyAFIAhNDQYgBUH+////B0sNBkHwngEoAgAiBARAQeieASgCACIDIAVqIgAgA00NByAAIARLDQcLIAUQPCIAIAFHDQEMCAsgBSAGayAHcSIFQf7///8HSw0FIAUQPCIBIAAoAgAgACgCBGpGDQQgASEACwJAIABBf0YNACAIQTBqIAVNDQBBmJ8BKAIAIgEgCSAFa2pBACABa3EiAUH+////B0sEQCAAIQEMCAsgARA8QX9HBEAgASAFaiEFIAAhAQwIC0EAIAVrEDwaDAULIAAiAUF/Rw0GDAQLAAtBACEEDAcLQQAhAQwFCyABQX9HDQILQfSeAUH0ngEoAgBBBHI2AgALIAJB/v///wdLDQEgAhA8IQFBABA8IQAgAUF/Rg0BIABBf0YNASAAIAFNDQEgACABayIFIAhBKGpNDQELQeieAUHongEoAgAgBWoiADYCAEHsngEoAgAgAEkEQEHsngEgADYCAAsCQAJAAkBB0JsBKAIAIgcEQEH4ngEhAANAIAEgACgCACIDIAAoAgQiAmpGDQIgACgCCCIADQALDAILQcibASgCACIAQQAgACABTRtFBEBByJsBIAE2AgALQQAhAEH8ngEgBTYCAEH4ngEgATYCAEHYmwFBfzYCAEHcmwFBkJ8BKAIANgIAQYSfAUEANgIAA0AgAEEDdCIDQeibAWogA0HgmwFqIgI2AgAgA0HsmwFqIAI2AgAgAEEBaiIAQSBHDQALQcSbASAFQShrIgNBeCABa0EHcUEAIAFBCGpBB3EbIgBrIgI2AgBB0JsBIAAgAWoiADYCACAAIAJBAXI2AgQgASADakEoNgIEQdSbAUGgnwEoAgA2AgAMAgsgAC0ADEEIcQ0AIAMgB0sNACABIAdNDQAgACACIAVqNgIEQdCbASAHQXggB2tBB3FBACAHQQhqQQdxGyIAaiICNgIAQcSbAUHEmwEoAgAgBWoiASAAayIANgIAIAIgAEEBcjYCBCABIAdqQSg2AgRB1JsBQaCfASgCADYCAAwBC0HImwEoAgAgAUsEQEHImwEgATYCAAsgASAFaiECQfieASEAAkACQAJAAkACQAJAA0AgAiAAKAIARwRAIAAoAggiAA0BDAILCyAALQAMQQhxRQ0BC0H4ngEhAANAIAcgACgCACICTwRAIAIgACgCBGoiBCAHSw0DCyAAKAIIIQAMAAsACyAAIAE2AgAgACAAKAIEIAVqNgIEIAFBeCABa0EHcUEAIAFBCGpBB3EbaiIJIAhBA3I2AgQgAkF4IAJrQQdxQQAgAkEIakEHcRtqIgUgCCAJaiIGayECIAUgB0YEQEHQmwEgBjYCAEHEmwFBxJsBKAIAIAJqIgA2AgAgBiAAQQFyNgIEDAMLIAVBzJsBKAIARgRAQcybASAGNgIAQcCbAUHAmwEoAgAgAmoiADYCACAGIABBAXI2AgQgACAGaiAANgIADAMLIAUoAgQiAEEDcUEBRgRAIABBeHEhBwJAIABB/wFNBEAgBSgCCCIDIABBA3YiAEEDdEHgmwFqRhogAyAFKAIMIgFGBEBBuJsBQbibASgCAEF+IAB3cTYCAAwCCyADIAE2AgwgASADNgIIDAELIAUoAhghCAJAIAUgBSgCDCIBRwRAIAUoAggiACABNgIMIAEgADYCCAwBCwJAIAVBFGoiACgCACIDDQAgBUEQaiIAKAIAIgMNAEEAIQEMAQsDQCAAIQQgAyIBQRRqIgAoAgAiAw0AIAFBEGohACABKAIQIgMNAAsgBEEANgIACyAIRQ0AAkAgBSAFKAIcIgNBAnRB6J0BaiIAKAIARgRAIAAgATYCACABDQFBvJsBQbybASgCAEF+IAN3cTYCAAwCCyAIQRBBFCAIKAIQIAVGG2ogATYCACABRQ0BCyABIAg2AhggBSgCECIABEAgASAANgIQIAAgATYCGAsgBSgCFCIARQ0AIAEgADYCFCAAIAE2AhgLIAUgB2ohBSACIAdqIQILIAUgBSgCBEF+cTYCBCAGIAJBAXI2AgQgAiAGaiACNgIAIAJB/wFNBEAgAkEDdiIAQQN0QeCbAWohAgJ/QbibASgCACIBQQEgAHQiAHFFBEBBuJsBIAAgAXI2AgAgAgwBCyACKAIICyEAIAIgBjYCCCAAIAY2AgwgBiACNgIMIAYgADYCCAwDC0EfIQAgAkH///8HTQRAIAJBCHYiACAAQYD+P2pBEHZBCHEiA3QiACAAQYDgH2pBEHZBBHEiAXQiACAAQYCAD2pBEHZBAnEiAHRBD3YgASADciAAcmsiAEEBdCACIABBFWp2QQFxckEcaiEACyAGIAA2AhwgBkIANwIQIABBAnRB6J0BaiEEAkBBvJsBKAIAIgNBASAAdCIBcUUEQEG8mwEgASADcjYCACAEIAY2AgAgBiAENgIYDAELIAJBAEEZIABBAXZrIABBH0YbdCEAIAQoAgAhAQNAIAEiAygCBEF4cSACRg0DIABBHXYhASAAQQF0IQAgAyABQQRxaiIEKAIQIgENAAsgBCAGNgIQIAYgAzYCGAsgBiAGNgIMIAYgBjYCCAwCC0HEmwEgBUEoayIDQXggAWtBB3FBACABQQhqQQdxGyIAayICNgIAQdCbASAAIAFqIgA2AgAgACACQQFyNgIEIAEgA2pBKDYCBEHUmwFBoJ8BKAIANgIAIAcgBEEnIARrQQdxQQAgBEEna0EHcRtqQS9rIgAgACAHQRBqSRsiAkEbNgIEIAJBgJ8BKQIANwIQIAJB+J4BKQIANwIIQYCfASACQQhqNgIAQfyeASAFNgIAQfieASABNgIAQYSfAUEANgIAIAJBGGohAANAIABBBzYCBCAAQQhqIQEgAEEEaiEAIAEgBEkNAAsgAiAHRg0DIAIgAigCBEF+cTYCBCAHIAIgB2siBEEBcjYCBCACIAQ2AgAgBEH/AU0EQCAEQQN2IgBBA3RB4JsBaiECAn9BuJsBKAIAIgFBASAAdCIAcUUEQEG4mwEgACABcjYCACACDAELIAIoAggLIQAgAiAHNgIIIAAgBzYCDCAHIAI2AgwgByAANgIIDAQLQR8hACAHQgA3AhAgBEH///8HTQRAIARBCHYiACAAQYD+P2pBEHZBCHEiAnQiACAAQYDgH2pBEHZBBHEiAXQiACAAQYCAD2pBEHZBAnEiAHRBD3YgASACciAAcmsiAEEBdCAEIABBFWp2QQFxckEcaiEACyAHIAA2AhwgAEECdEHonQFqIQMCQEG8mwEoAgAiAkEBIAB0IgFxRQRAQbybASABIAJyNgIAIAMgBzYCACAHIAM2AhgMAQsgBEEAQRkgAEEBdmsgAEEfRht0IQAgAygCACEBA0AgASICKAIEQXhxIARGDQQgAEEddiEBIABBAXQhACACIAFBBHFqIgMoAhAiAQ0ACyADIAc2AhAgByACNgIYCyAHIAc2AgwgByAHNgIIDAMLIAMoAggiACAGNgIMIAMgBjYCCCAGQQA2AhggBiADNgIMIAYgADYCCAsgCUEIaiEADAULIAIoAggiACAHNgIMIAIgBzYCCCAHQQA2AhggByACNgIMIAcgADYCCAtBxJsBKAIAIgAgCE0NAEHEmwEgACAIayIBNgIAQdCbAUHQmwEoAgAiAiAIaiIANgIAIAAgAUEBcjYCBCACIAhBA3I2AgQgAkEIaiEADAMLQbSbAUEwNgIAQQAhAAwCCwJAIAVFDQACQCAEKAIcIgJBAnRB6J0BaiIAKAIAIARGBEAgACABNgIAIAENAUG8mwEgCUF+IAJ3cSIJNgIADAILIAVBEEEUIAUoAhAgBEYbaiABNgIAIAFFDQELIAEgBTYCGCAEKAIQIgAEQCABIAA2AhAgACABNgIYCyAEKAIUIgBFDQAgASAANgIUIAAgATYCGAsCQCADQQ9NBEAgBCADIAhqIgBBA3I2AgQgACAEaiIAIAAoAgRBAXI2AgQMAQsgBCAIQQNyNgIEIAYgA0EBcjYCBCADIAZqIAM2AgAgA0H/AU0EQCADQQN2IgBBA3RB4JsBaiECAn9BuJsBKAIAIgFBASAAdCIAcUUEQEG4mwEgACABcjYCACACDAELIAIoAggLIQAgAiAGNgIIIAAgBjYCDCAGIAI2AgwgBiAANgIIDAELQR8hACADQf///wdNBEAgA0EIdiIAIABBgP4/akEQdkEIcSICdCIAIABBgOAfakEQdkEEcSIBdCIAIABBgIAPakEQdkECcSIAdEEPdiABIAJyIAByayIAQQF0IAMgAEEVanZBAXFyQRxqIQALIAYgADYCHCAGQgA3AhAgAEECdEHonQFqIQICQAJAIAlBASAAdCIBcUUEQEG8mwEgASAJcjYCACACIAY2AgAgBiACNgIYDAELIANBAEEZIABBAXZrIABBH0YbdCEAIAIoAgAhCANAIAgiASgCBEF4cSADRg0CIABBHXYhAiAAQQF0IQAgASACQQRxaiICKAIQIggNAAsgAiAGNgIQIAYgATYCGAsgBiAGNgIMIAYgBjYCCAwBCyABKAIIIgAgBjYCDCABIAY2AgggBkEANgIYIAYgATYCDCAGIAA2AggLIARBCGohAAwBCwJAIAtFDQACQCABKAIcIgJBAnRB6J0BaiIAKAIAIAFGBEAgACAENgIAIAQNAUG8mwEgBkF+IAJ3cTYCAAwCCyALQRBBFCALKAIQIAFGG2ogBDYCACAERQ0BCyAEIAs2AhggASgCECIABEAgBCAANgIQIAAgBDYCGAsgASgCFCIARQ0AIAQgADYCFCAAIAQ2AhgLAkAgA0EPTQRAIAEgAyAIaiIAQQNyNgIEIAAgAWoiACAAKAIEQQFyNgIEDAELIAEgCEEDcjYCBCAJIANBAXI2AgQgAyAJaiADNgIAIAoEQCAKQQN2IgBBA3RB4JsBaiEEQcybASgCACECAn9BASAAdCIAIAVxRQRAQbibASAAIAVyNgIAIAQMAQsgBCgCCAshACAEIAI2AgggACACNgIMIAIgBDYCDCACIAA2AggLQcybASAJNgIAQcCbASADNgIACyABQQhqIQALIAxBEGokACAAC4MEAQN/IAJBgARPBEAgACABIAIQEhogAA8LIAAgAmohAwJAIAAgAXNBA3FFBEACQCAAQQNxRQRAIAAhAgwBCyACQQFIBEAgACECDAELIAAhAgNAIAIgAS0AADoAACABQQFqIQEgAkEBaiICQQNxRQ0BIAIgA0kNAAsLAkAgA0F8cSIEQcAASQ0AIAIgBEFAaiIFSw0AA0AgAiABKAIANgIAIAIgASgCBDYCBCACIAEoAgg2AgggAiABKAIMNgIMIAIgASgCEDYCECACIAEoAhQ2AhQgAiABKAIYNgIYIAIgASgCHDYCHCACIAEoAiA2AiAgAiABKAIkNgIkIAIgASgCKDYCKCACIAEoAiw2AiwgAiABKAIwNgIwIAIgASgCNDYCNCACIAEoAjg2AjggAiABKAI8NgI8IAFBQGshASACQUBrIgIgBU0NAAsLIAIgBE8NAQNAIAIgASgCADYCACABQQRqIQEgAkEEaiICIARJDQALDAELIANBBEkEQCAAIQIMAQsgACADQQRrIgRLBEAgACECDAELIAAhAgNAIAIgAS0AADoAACACIAEtAAE6AAEgAiABLQACOgACIAIgAS0AAzoAAyABQQRqIQEgAkEEaiICIARNDQALCyACIANJBEADQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADRw0ACwsgAAu4GAECfyMAQRBrIgQkACAEIAA2AgwgBCABNgIIIAQgAjYCBCAEKAIMIQAgBCgCCCECIAQoAgQhAyMAQSBrIgEkACABIAA2AhggASACNgIUIAEgAzYCEAJAIAEoAhRFBEAgAUEANgIcDAELIAFBATYCDCABLQAMBEAgASgCFCECIAEoAhAhAyMAQSBrIgAgASgCGDYCHCAAIAI2AhggACADNgIUIAAgACgCHDYCECAAIAAoAhBBf3M2AhADQCAAKAIUBH8gACgCGEEDcUEARwVBAAtBAXEEQCAAKAIQIQIgACAAKAIYIgNBAWo2AhggACADLQAAIAJzQf8BcUECdEGQFWooAgAgACgCEEEIdnM2AhAgACAAKAIUQQFrNgIUDAELCyAAIAAoAhg2AgwDQCAAKAIUQSBPBEAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQFWooAgAgACgCEEEQdkH/AXFBAnRBkB1qKAIAIAAoAhBB/wFxQQJ0QZAtaigCACAAKAIQQQh2Qf8BcUECdEGQJWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQFWooAgAgACgCEEEQdkH/AXFBAnRBkB1qKAIAIAAoAhBB/wFxQQJ0QZAtaigCACAAKAIQQQh2Qf8BcUECdEGQJWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQFWooAgAgACgCEEEQdkH/AXFBAnRBkB1qKAIAIAAoAhBB/wFxQQJ0QZAtaigCACAAKAIQQQh2Qf8BcUECdEGQJWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQFWooAgAgACgCEEEQdkH/AXFBAnRBkB1qKAIAIAAoAhBB/wFxQQJ0QZAtaigCACAAKAIQQQh2Qf8BcUECdEGQJWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQFWooAgAgACgCEEEQdkH/AXFBAnRBkB1qKAIAIAAoAhBB/wFxQQJ0QZAtaigCACAAKAIQQQh2Qf8BcUECdEGQJWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQFWooAgAgACgCEEEQdkH/AXFBAnRBkB1qKAIAIAAoAhBB/wFxQQJ0QZAtaigCACAAKAIQQQh2Qf8BcUECdEGQJWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQFWooAgAgACgCEEEQdkH/AXFBAnRBkB1qKAIAIAAoAhBB/wFxQQJ0QZAtaigCACAAKAIQQQh2Qf8BcUECdEGQJWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQFWooAgAgACgCEEEQdkH/AXFBAnRBkB1qKAIAIAAoAhBB/wFxQQJ0QZAtaigCACAAKAIQQQh2Qf8BcUECdEGQJWooAgBzc3M2AhAgACAAKAIUQSBrNgIUDAELCwNAIAAoAhRBBE8EQCAAIAAoAgwiAkEEajYCDCAAIAIoAgAgACgCEHM2AhAgACAAKAIQQRh2QQJ0QZAVaigCACAAKAIQQRB2Qf8BcUECdEGQHWooAgAgACgCEEH/AXFBAnRBkC1qKAIAIAAoAhBBCHZB/wFxQQJ0QZAlaigCAHNzczYCECAAIAAoAhRBBGs2AhQMAQsLIAAgACgCDDYCGCAAKAIUBEADQCAAKAIQIQIgACAAKAIYIgNBAWo2AhggACADLQAAIAJzQf8BcUECdEGQFWooAgAgACgCEEEIdnM2AhAgACAAKAIUQQFrIgI2AhQgAg0ACwsgACAAKAIQQX9zNgIQIAEgACgCEDYCHAwBCyABKAIUIQIgASgCECEDIwBBIGsiACABKAIYNgIcIAAgAjYCGCAAIAM2AhQgACAAKAIcQQh2QYD+A3EgACgCHEEYdmogACgCHEGA/gNxQQh0aiAAKAIcQf8BcUEYdGo2AhAgACAAKAIQQX9zNgIQA0AgACgCFAR/IAAoAhhBA3FBAEcFQQALQQFxBEAgACgCEEEYdiECIAAgACgCGCIDQQFqNgIYIAAgAy0AACACc0ECdEGQNWooAgAgACgCEEEIdHM2AhAgACAAKAIUQQFrNgIUDAELCyAAIAAoAhg2AgwDQCAAKAIUQSBPBEAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQzQBqKAIAIAAoAhBBEHZB/wFxQQJ0QZDFAGooAgAgACgCEEH/AXFBAnRBkDVqKAIAIAAoAhBBCHZB/wFxQQJ0QZA9aigCAHNzczYCECAAIAAoAgwiAkEEajYCDCAAIAIoAgAgACgCEHM2AhAgACAAKAIQQRh2QQJ0QZDNAGooAgAgACgCEEEQdkH/AXFBAnRBkMUAaigCACAAKAIQQf8BcUECdEGQNWooAgAgACgCEEEIdkH/AXFBAnRBkD1qKAIAc3NzNgIQIAAgACgCDCICQQRqNgIMIAAgAigCACAAKAIQczYCECAAIAAoAhBBGHZBAnRBkM0AaigCACAAKAIQQRB2Qf8BcUECdEGQxQBqKAIAIAAoAhBB/wFxQQJ0QZA1aigCACAAKAIQQQh2Qf8BcUECdEGQPWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQzQBqKAIAIAAoAhBBEHZB/wFxQQJ0QZDFAGooAgAgACgCEEH/AXFBAnRBkDVqKAIAIAAoAhBBCHZB/wFxQQJ0QZA9aigCAHNzczYCECAAIAAoAgwiAkEEajYCDCAAIAIoAgAgACgCEHM2AhAgACAAKAIQQRh2QQJ0QZDNAGooAgAgACgCEEEQdkH/AXFBAnRBkMUAaigCACAAKAIQQf8BcUECdEGQNWooAgAgACgCEEEIdkH/AXFBAnRBkD1qKAIAc3NzNgIQIAAgACgCDCICQQRqNgIMIAAgAigCACAAKAIQczYCECAAIAAoAhBBGHZBAnRBkM0AaigCACAAKAIQQRB2Qf8BcUECdEGQxQBqKAIAIAAoAhBB/wFxQQJ0QZA1aigCACAAKAIQQQh2Qf8BcUECdEGQPWooAgBzc3M2AhAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQzQBqKAIAIAAoAhBBEHZB/wFxQQJ0QZDFAGooAgAgACgCEEH/AXFBAnRBkDVqKAIAIAAoAhBBCHZB/wFxQQJ0QZA9aigCAHNzczYCECAAIAAoAgwiAkEEajYCDCAAIAIoAgAgACgCEHM2AhAgACAAKAIQQRh2QQJ0QZDNAGooAgAgACgCEEEQdkH/AXFBAnRBkMUAaigCACAAKAIQQf8BcUECdEGQNWooAgAgACgCEEEIdkH/AXFBAnRBkD1qKAIAc3NzNgIQIAAgACgCFEEgazYCFAwBCwsDQCAAKAIUQQRPBEAgACAAKAIMIgJBBGo2AgwgACACKAIAIAAoAhBzNgIQIAAgACgCEEEYdkECdEGQzQBqKAIAIAAoAhBBEHZB/wFxQQJ0QZDFAGooAgAgACgCEEH/AXFBAnRBkDVqKAIAIAAoAhBBCHZB/wFxQQJ0QZA9aigCAHNzczYCECAAIAAoAhRBBGs2AhQMAQsLIAAgACgCDDYCGCAAKAIUBEADQCAAKAIQQRh2IQIgACAAKAIYIgNBAWo2AhggACADLQAAIAJzQQJ0QZA1aigCACAAKAIQQQh0czYCECAAIAAoAhRBAWsiAjYCFCACDQALCyAAIAAoAhBBf3M2AhAgASAAKAIQQQh2QYD+A3EgACgCEEEYdmogACgCEEGA/gNxQQh0aiAAKAIQQf8BcUEYdGo2AhwLIAEoAhwhACABQSBqJAAgBEEQaiQAIAAL7AIBAn8jAEEQayIBJAAgASAANgIMAkAgASgCDEUNACABKAIMKAIwBEAgASgCDCIAIAAoAjBBAWs2AjALIAEoAgwoAjANACABKAIMKAIgBEAgASgCDEEBNgIgIAEoAgwQMRoLIAEoAgwoAiRBAUYEQCABKAIMEGcLAkAgASgCDCgCLEUNACABKAIMLQAoQQFxDQAgASgCDCECIwBBEGsiACABKAIMKAIsNgIMIAAgAjYCCCAAQQA2AgQDQCAAKAIEIAAoAgwoAkRJBEAgACgCDCgCTCAAKAIEQQJ0aigCACAAKAIIRgRAIAAoAgwoAkwgACgCBEECdGogACgCDCgCTCAAKAIMKAJEQQFrQQJ0aigCADYCACAAKAIMIgAgACgCREEBazYCRAUgACAAKAIEQQFqNgIEDAILCwsLIAEoAgxBAEIAQQUQIRogASgCDCgCAARAIAEoAgwoAgAQGwsgASgCDBAVCyABQRBqJAALnwIBAn8jAEEQayIBJAAgASAANgIMIAEgASgCDCgCHDYCBCABKAIEIQIjAEEQayIAJAAgACACNgIMIAAoAgwQuwEgAEEQaiQAIAEgASgCBCgCFDYCCCABKAIIIAEoAgwoAhBLBEAgASABKAIMKAIQNgIICwJAIAEoAghFDQAgASgCDCgCDCABKAIEKAIQIAEoAggQGRogASgCDCIAIAEoAgggACgCDGo2AgwgASgCBCIAIAEoAgggACgCEGo2AhAgASgCDCIAIAEoAgggACgCFGo2AhQgASgCDCIAIAAoAhAgASgCCGs2AhAgASgCBCIAIAAoAhQgASgCCGs2AhQgASgCBCgCFA0AIAEoAgQgASgCBCgCCDYCEAsgAUEQaiQAC2ABAX8jAEEQayIBJAAgASAANgIIIAEgASgCCEICEB42AgQCQCABKAIERQRAIAFBADsBDgwBCyABIAEoAgQtAAAgASgCBC0AAUEIdGo7AQ4LIAEvAQ4hACABQRBqJAAgAAvpAQEBfyMAQSBrIgIkACACIAA2AhwgAiABNwMQIAIpAxAhASMAQSBrIgAgAigCHDYCGCAAIAE3AxACQAJAAkAgACgCGC0AAEEBcUUNACAAKQMQIAAoAhgpAxAgACkDEHxWDQAgACgCGCkDCCAAKAIYKQMQIAApAxB8Wg0BCyAAKAIYQQA6AAAgAEEANgIcDAELIAAgACgCGCgCBCAAKAIYKQMQp2o2AgwgACAAKAIMNgIcCyACIAAoAhw2AgwgAigCDARAIAIoAhwiACACKQMQIAApAxB8NwMQCyACKAIMIQAgAkEgaiQAIAALbwEBfyMAQRBrIgIkACACIAA2AgggAiABOwEGIAIgAigCCEICEB42AgACQCACKAIARQRAIAJBfzYCDAwBCyACKAIAIAIvAQY6AAAgAigCACACLwEGQQh2OgABIAJBADYCDAsgAigCDBogAkEQaiQAC48BAQF/IwBBEGsiAiQAIAIgADYCCCACIAE2AgQgAiACKAIIQgQQHjYCAAJAIAIoAgBFBEAgAkF/NgIMDAELIAIoAgAgAigCBDoAACACKAIAIAIoAgRBCHY6AAEgAigCACACKAIEQRB2OgACIAIoAgAgAigCBEEYdjoAAyACQQA2AgwLIAIoAgwaIAJBEGokAAu2AgEBfyMAQTBrIgQkACAEIAA2AiQgBCABNgIgIAQgAjcDGCAEIAM2AhQCQCAEKAIkKQMYQgEgBCgCFK2Gg1AEQCAEKAIkQQxqQRxBABAUIARCfzcDKAwBCwJAIAQoAiQoAgBFBEAgBCAEKAIkKAIIIAQoAiAgBCkDGCAEKAIUIAQoAiQoAgQRDgA3AwgMAQsgBCAEKAIkKAIAIAQoAiQoAgggBCgCICAEKQMYIAQoAhQgBCgCJCgCBBEKADcDCAsgBCkDCEIAUwRAAkAgBCgCFEEERg0AIAQoAhRBDkYNAAJAIAQoAiQgBEIIQQQQIUIAUwRAIAQoAiRBDGpBFEEAEBQMAQsgBCgCJEEMaiAEKAIAIAQoAgQQFAsLCyAEIAQpAwg3AygLIAQpAyghAiAEQTBqJAAgAgsXACAALQAAQSBxRQRAIAEgAiAAEHIaCwtQAQF/IwBBEGsiASQAIAEgADYCDANAIAEoAgwEQCABIAEoAgwoAgA2AgggASgCDCgCDBAVIAEoAgwQFSABIAEoAgg2AgwMAQsLIAFBEGokAAt9AQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgAUIANwMAA0AgASkDACABKAIMKQMIWkUEQCABKAIMKAIAIAEpAwCnQQR0ahBiIAEgASkDAEIBfDcDAAwBCwsgASgCDCgCABAVIAEoAgwoAigQJSABKAIMEBULIAFBEGokAAs+AQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgASgCDCgCABAVIAEoAgwoAgwQFSABKAIMEBULIAFBEGokAAtuAQF/IwBBgAJrIgUkAAJAIARBgMAEcQ0AIAIgA0wNACAFIAFB/wFxIAIgA2siAkGAAiACQYACSSIBGxAyIAFFBEADQCAAIAVBgAIQIiACQYACayICQf8BSw0ACwsgACAFIAIQIgsgBUGAAmokAAvRAQEBfyMAQTBrIgMkACADIAA2AiggAyABNwMgIAMgAjYCHAJAIAMoAigtAChBAXEEQCADQX82AiwMAQsCQCADKAIoKAIgBEAgAygCHEUNASADKAIcQQFGDQEgAygCHEECRg0BCyADKAIoQQxqQRJBABAUIANBfzYCLAwBCyADIAMpAyA3AwggAyADKAIcNgIQIAMoAiggA0EIakIQQQYQIUIAUwRAIANBfzYCLAwBCyADKAIoQQA6ADQgA0EANgIsCyADKAIsIQAgA0EwaiQAIAALmBcBAn8jAEEwayIEJAAgBCAANgIsIAQgATYCKCAEIAI2AiQgBCADNgIgIARBADYCFAJAIAQoAiwoAoQBQQBKBEAgBCgCLCgCACgCLEECRgRAIwBBEGsiACAEKAIsNgIIIABB/4D/n382AgQgAEEANgIAAkADQCAAKAIAQR9MBEACQCAAKAIEQQFxRQ0AIAAoAghBlAFqIAAoAgBBAnRqLwEARQ0AIABBADYCDAwDCyAAIAAoAgBBAWo2AgAgACAAKAIEQQF2NgIEDAELCwJAAkAgACgCCC8BuAENACAAKAIILwG8AQ0AIAAoAggvAcgBRQ0BCyAAQQE2AgwMAQsgAEEgNgIAA0AgACgCAEGAAkgEQCAAKAIIQZQBaiAAKAIAQQJ0ai8BAARAIABBATYCDAwDBSAAIAAoAgBBAWo2AgAMAgsACwsgAEEANgIMCyAAKAIMIQAgBCgCLCgCACAANgIsCyAEKAIsIAQoAixBmBZqEHsgBCgCLCAEKAIsQaQWahB7IAQoAiwhASMAQRBrIgAkACAAIAE2AgwgACgCDCAAKAIMQZQBaiAAKAIMKAKcFhC5ASAAKAIMIAAoAgxBiBNqIAAoAgwoAqgWELkBIAAoAgwgACgCDEGwFmoQeyAAQRI2AggDQAJAIAAoAghBA0gNACAAKAIMQfwUaiAAKAIILQDgbEECdGovAQINACAAIAAoAghBAWs2AggMAQsLIAAoAgwiASABKAKoLSAAKAIIQQNsQRFqajYCqC0gACgCCCEBIABBEGokACAEIAE2AhQgBCAEKAIsKAKoLUEKakEDdjYCHCAEIAQoAiwoAqwtQQpqQQN2NgIYIAQoAhggBCgCHE0EQCAEIAQoAhg2AhwLDAELIAQgBCgCJEEFaiIANgIYIAQgADYCHAsCQAJAIAQoAhwgBCgCJEEEakkNACAEKAIoRQ0AIAQoAiwgBCgCKCAEKAIkIAQoAiAQXAwBCwJAAkAgBCgCLCgCiAFBBEcEQCAEKAIYIAQoAhxHDQELIARBAzYCEAJAIAQoAiwoArwtQRAgBCgCEGtKBEAgBCAEKAIgQQJqNgIMIAQoAiwiACAALwG4LSAEKAIMQf//A3EgBCgCLCgCvC10cjsBuC0gBCgCLC8BuC1B/wFxIQEgBCgCLCgCCCECIAQoAiwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCLC8BuC1BCHYhASAEKAIsKAIIIQIgBCgCLCIDKAIUIQAgAyAAQQFqNgIUIAAgAmogAToAACAEKAIsIAQoAgxB//8DcUEQIAQoAiwoArwta3U7AbgtIAQoAiwiACAAKAK8LSAEKAIQQRBrajYCvC0MAQsgBCgCLCIAIAAvAbgtIAQoAiBBAmpB//8DcSAEKAIsKAK8LXRyOwG4LSAEKAIsIgAgBCgCECAAKAK8LWo2ArwtCyAEKAIsQZDgAEGQ6QAQugEMAQsgBEEDNgIIAkAgBCgCLCgCvC1BECAEKAIIa0oEQCAEIAQoAiBBBGo2AgQgBCgCLCIAIAAvAbgtIAQoAgRB//8DcSAEKAIsKAK8LXRyOwG4LSAEKAIsLwG4LUH/AXEhASAEKAIsKAIIIQIgBCgCLCIDKAIUIQAgAyAAQQFqNgIUIAAgAmogAToAACAEKAIsLwG4LUEIdiEBIAQoAiwoAgghAiAEKAIsIgMoAhQhACADIABBAWo2AhQgACACaiABOgAAIAQoAiwgBCgCBEH//wNxQRAgBCgCLCgCvC1rdTsBuC0gBCgCLCIAIAAoArwtIAQoAghBEGtqNgK8LQwBCyAEKAIsIgAgAC8BuC0gBCgCIEEEakH//wNxIAQoAiwoArwtdHI7AbgtIAQoAiwiACAEKAIIIAAoArwtajYCvC0LIAQoAiwhASAEKAIsKAKcFkEBaiECIAQoAiwoAqgWQQFqIQMgBCgCFEEBaiEFIwBBQGoiACQAIAAgATYCPCAAIAI2AjggACADNgI0IAAgBTYCMCAAQQU2AigCQCAAKAI8KAK8LUEQIAAoAihrSgRAIAAgACgCOEGBAms2AiQgACgCPCIBIAEvAbgtIAAoAiRB//8DcSAAKAI8KAK8LXRyOwG4LSAAKAI8LwG4LUH/AXEhAiAAKAI8KAIIIQMgACgCPCIFKAIUIQEgBSABQQFqNgIUIAEgA2ogAjoAACAAKAI8LwG4LUEIdiECIAAoAjwoAgghAyAAKAI8IgUoAhQhASAFIAFBAWo2AhQgASADaiACOgAAIAAoAjwgACgCJEH//wNxQRAgACgCPCgCvC1rdTsBuC0gACgCPCIBIAEoArwtIAAoAihBEGtqNgK8LQwBCyAAKAI8IgEgAS8BuC0gACgCOEGBAmtB//8DcSAAKAI8KAK8LXRyOwG4LSAAKAI8IgEgACgCKCABKAK8LWo2ArwtCyAAQQU2AiACQCAAKAI8KAK8LUEQIAAoAiBrSgRAIAAgACgCNEEBazYCHCAAKAI8IgEgAS8BuC0gACgCHEH//wNxIAAoAjwoArwtdHI7AbgtIAAoAjwvAbgtQf8BcSECIAAoAjwoAgghAyAAKAI8IgUoAhQhASAFIAFBAWo2AhQgASADaiACOgAAIAAoAjwvAbgtQQh2IQIgACgCPCgCCCEDIAAoAjwiBSgCFCEBIAUgAUEBajYCFCABIANqIAI6AAAgACgCPCAAKAIcQf//A3FBECAAKAI8KAK8LWt1OwG4LSAAKAI8IgEgASgCvC0gACgCIEEQa2o2ArwtDAELIAAoAjwiASABLwG4LSAAKAI0QQFrQf//A3EgACgCPCgCvC10cjsBuC0gACgCPCIBIAAoAiAgASgCvC1qNgK8LQsgAEEENgIYAkAgACgCPCgCvC1BECAAKAIYa0oEQCAAIAAoAjBBBGs2AhQgACgCPCIBIAEvAbgtIAAoAhRB//8DcSAAKAI8KAK8LXRyOwG4LSAAKAI8LwG4LUH/AXEhAiAAKAI8KAIIIQMgACgCPCIFKAIUIQEgBSABQQFqNgIUIAEgA2ogAjoAACAAKAI8LwG4LUEIdiECIAAoAjwoAgghAyAAKAI8IgUoAhQhASAFIAFBAWo2AhQgASADaiACOgAAIAAoAjwgACgCFEH//wNxQRAgACgCPCgCvC1rdTsBuC0gACgCPCIBIAEoArwtIAAoAhhBEGtqNgK8LQwBCyAAKAI8IgEgAS8BuC0gACgCMEEEa0H//wNxIAAoAjwoArwtdHI7AbgtIAAoAjwiASAAKAIYIAEoArwtajYCvC0LIABBADYCLANAIAAoAiwgACgCMEgEQCAAQQM2AhACQCAAKAI8KAK8LUEQIAAoAhBrSgRAIAAgACgCPEH8FGogACgCLC0A4GxBAnRqLwECNgIMIAAoAjwiASABLwG4LSAAKAIMQf//A3EgACgCPCgCvC10cjsBuC0gACgCPC8BuC1B/wFxIQIgACgCPCgCCCEDIAAoAjwiBSgCFCEBIAUgAUEBajYCFCABIANqIAI6AAAgACgCPC8BuC1BCHYhAiAAKAI8KAIIIQMgACgCPCIFKAIUIQEgBSABQQFqNgIUIAEgA2ogAjoAACAAKAI8IAAoAgxB//8DcUEQIAAoAjwoArwta3U7AbgtIAAoAjwiASABKAK8LSAAKAIQQRBrajYCvC0MAQsgACgCPCIBIAEvAbgtIAAoAjxB/BRqIAAoAiwtAOBsQQJ0ai8BAiAAKAI8KAK8LXRyOwG4LSAAKAI8IgEgACgCECABKAK8LWo2ArwtCyAAIAAoAixBAWo2AiwMAQsLIAAoAjwgACgCPEGUAWogACgCOEEBaxC4ASAAKAI8IAAoAjxBiBNqIAAoAjRBAWsQuAEgAEFAayQAIAQoAiwgBCgCLEGUAWogBCgCLEGIE2oQugELCyAEKAIsEL0BIAQoAiAEQCAEKAIsELwBCyAEQTBqJAAL1AEBAX8jAEEgayICJAAgAiAANgIYIAIgATcDECACIAIoAhhFOgAPAkAgAigCGEUEQCACIAIpAxCnEBgiADYCGCAARQRAIAJBADYCHAwCCwsgAkEYEBgiADYCCCAARQRAIAItAA9BAXEEQCACKAIYEBULIAJBADYCHAwBCyACKAIIQQE6AAAgAigCCCACKAIYNgIEIAIoAgggAikDEDcDCCACKAIIQgA3AxAgAigCCCACLQAPQQFxOgABIAIgAigCCDYCHAsgAigCHCEAIAJBIGokACAAC3gBAX8jAEEQayIBJAAgASAANgIIIAEgASgCCEIEEB42AgQCQCABKAIERQRAIAFBADYCDAwBCyABIAEoAgQtAAAgASgCBC0AASABKAIELQACIAEoAgQtAANBCHRqQQh0akEIdGo2AgwLIAEoAgwhACABQRBqJAAgAAt/AQN/IAAhAQJAIABBA3EEQANAIAEtAABFDQIgAUEBaiIBQQNxDQALCwNAIAEiAkEEaiEBIAIoAgAiA0F/cyADQYGChAhrcUGAgYKEeHFFDQALIANB/wFxRQRAIAIgAGsPCwNAIAItAAEhAyACQQFqIgEhAiADDQALCyABIABrC2EBAX8jAEEQayICIAA2AgggAiABNwMAAkAgAikDACACKAIIKQMIVgRAIAIoAghBADoAACACQX82AgwMAQsgAigCCEEBOgAAIAIoAgggAikDADcDECACQQA2AgwLIAIoAgwL7wEBAX8jAEEgayICJAAgAiAANgIYIAIgATcDECACIAIoAhhCCBAeNgIMAkAgAigCDEUEQCACQX82AhwMAQsgAigCDCACKQMQQv8BgzwAACACKAIMIAIpAxBCCIhC/wGDPAABIAIoAgwgAikDEEIQiEL/AYM8AAIgAigCDCACKQMQQhiIQv8BgzwAAyACKAIMIAIpAxBCIIhC/wGDPAAEIAIoAgwgAikDEEIoiEL/AYM8AAUgAigCDCACKQMQQjCIQv8BgzwABiACKAIMIAIpAxBCOIhC/wGDPAAHIAJBADYCHAsgAigCHBogAkEgaiQAC4cDAQF/IwBBMGsiAyQAIAMgADYCJCADIAE2AiAgAyACNwMYAkAgAygCJC0AKEEBcQRAIANCfzcDKAwBCwJAAkAgAygCJCgCIEUNACADKQMYQv///////////wBWDQAgAykDGFANASADKAIgDQELIAMoAiRBDGpBEkEAEBQgA0J/NwMoDAELIAMoAiQtADVBAXEEQCADQn83AygMAQsCfyMAQRBrIgAgAygCJDYCDCAAKAIMLQA0QQFxCwRAIANCADcDKAwBCyADKQMYUARAIANCADcDKAwBCyADQgA3AxADQCADKQMQIAMpAxhUBEAgAyADKAIkIAMoAiAgAykDEKdqIAMpAxggAykDEH1BARAhIgI3AwggAkIAUwRAIAMoAiRBAToANSADKQMQUARAIANCfzcDKAwECyADIAMpAxA3AygMAwsgAykDCFAEQCADKAIkQQE6ADQFIAMgAykDCCADKQMQfDcDEAwCCwsLIAMgAykDEDcDKAsgAykDKCECIANBMGokACACCzYBAX8jAEEQayIBIAA2AgwCfiABKAIMLQAAQQFxBEAgASgCDCkDCCABKAIMKQMQfQwBC0IACwuyAQIBfwF+IwBBEGsiASQAIAEgADYCBCABIAEoAgRC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AkEBNgIQIAJBADYCCANAAkAgAigCCCACKAIYLwEETw0AAkAgAigCDCACKAIIai0AAEEfSwRAIAIoAgwgAigCCGotAABBgAFJDQELIAIoAgwgAigCCGotAABBDUYNACACKAIMIAIoAghqLQAAQQpGDQAgAigCDCACKAIIai0AAEEJRgRADAELIAJBAzYCEAJAIAIoAgwgAigCCGotAABB4AFxQcABRgRAIAJBATYCAAwBCwJAIAIoAgwgAigCCGotAABB8AFxQeABRgRAIAJBAjYCAAwBCwJAIAIoAgwgAigCCGotAABB+AFxQfABRgRAIAJBAzYCAAwBCyACQQQ2AhAMBAsLCyACKAIYLwEEIAIoAgggAigCAGpNBEAgAkEENgIQDAILIAJBATYCBANAIAIoAgQgAigCAE0EQCACKAIMIAIoAgggAigCBGpqLQAAQcABcUGAAUcEQCACQQQ2AhAMBgUgAiACKAIEQQFqNgIEDAILAAsLIAIgAigCACACKAIIajYCCAsgAiACKAIIQQFqNgIIDAELCwsgAigCGCACKAIQNgIIIAIoAhQEQAJAIAIoAhRBAkcNACACKAIQQQNHDQAgAkECNgIQIAIoAhhBAjYCCAsCQCACKAIUIAIoAhBGDQAgAigCEEEBRg0AIAJBBTYCHAwCCwsgAiACKAIQNgIcCyACKAIcC2oBAX8jAEEQayIBIAA2AgwgASgCDEIANwMAIAEoAgxBADYCCCABKAIMQn83AxAgASgCDEEANgIsIAEoAgxBfzYCKCABKAIMQgA3AxggASgCDEIANwMgIAEoAgxBADsBMCABKAIMQQA7ATILUgECf0GQlwEoAgAiASAAQQNqQXxxIgJqIQACQCACQQAgACABTRsNACAAPwBBEHRLBEAgABATRQ0BC0GQlwEgADYCACABDwtBtJsBQTA2AgBBfwuNBQEDfyMAQRBrIgEkACABIAA2AgwgASgCDARAIAEoAgwoAgAEQCABKAIMKAIAEDEaIAEoAgwoAgAQGwsgASgCDCgCHBAVIAEoAgwoAiAQJSABKAIMKAIkECUgASgCDCgCUCECIwBBEGsiACQAIAAgAjYCDCAAKAIMBEAgACgCDCgCEARAIABBADYCCANAIAAoAgggACgCDCgCAEkEQCAAKAIMKAIQIAAoAghBAnRqKAIABEAgACgCDCgC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A3EQHwsgAygCpAEoAhQgA0GeAWogA0GcAWoQgQEgAygCTCADLwGeARAfIAMoAkwgAy8BnAEQHwJAAkAgAy0AhQFBAXFFDQAgAygCpAEpAyhCFFoNACADKAJMQQAQIAwBCyADKAJMIAMoAqQBKAIYECALAkACQCADKAKgAUGAAnFBgAJHDQAgAygCpAEpAyBC/////w9UBEAgAygCpAEpAyhC/////w9UDQELIAMoAkxBfxAgIAMoAkxBfxAgDAELAkAgAygCpAEpAyBC/////w9UBEAgAygCTCADKAKkASkDIKcQIAwBCyADKAJMQX8QIAsCQCADKAKkASkDKEL/////D1QEQCADKAJMIAMoAqQBKQMopxAgDAELIAMoAkxBfxAgCwsgAygCTCADKAKkASgCMBBTQf//A3EQHyADIAMoAqQBKAI0IAMoAqABEIYBQf//A3EgAygCkAFBgAYQhgFB//8DcWo2AogBIAMoAkwgAygCiAFB//8DcRAfIAMoAqABQYACcUUEQCADKAJMIAMoAqQBKAI4EFNB//8DcRAfIAMoAkwgAygCpAEoAjxB//8DcRAfIAMoAkwgAygCpAEvAUAQHyADKAJMIAMoAqQBKAJEECACQCADKAKkASkDSEL/////D1QEQCADKAJMIAMoAqQBKQNIpxAgDAELIAMoAkxBfxAgCwsCfyMAQRBrIgAgAygCTDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAJMEBYgAygCkAEQIyADQX82AqwBDAELIAMoAqgBIANB0ABqAn4jAEEQayIAIAMoAkw2AgwCfiAAKAIMLQAAQQFxBEAgACgCDCkDEAwBC0IACwsQNUEASARAIAMoAkwQFiADKAKQARAjIANBfzYCrAEMAQsgAygCTBAWIAMoAqQBKAIwBEAgAygCqAEgAygCpAEoAjAQigFBAEgEQCADKAKQARAjIANBfzYCrAEMAgsLIAMoApABBEAgAygCqAEgAygCkAFBgAYQhQFBAEgEQCADKAKQARAjIANBfzYCrAEMAgsLIAMoApABECMgAygCpAEoAjQEQCADKAKoASADKAKkASgCNCADKAKgARCFAUEASARAIANBfzYCrAEMAgsLIAMoAqABQYACcUUEQCADKAKkASgCOARAIAMoAqgBIAMoAqQBKAI4EIoB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HCAAIAAoAhRBAWo2AhQMAQsLIAAoAggQR0EBcUUEQCAAKAIgQRRBABAUIAAoAggQFiAAQX82AiwMAQsgACgCCBAWIAAgACgCHDYCLAsgACgCLCECIABBMGokACADIAIiADYCBCAAQQBIBEAgA0IANwMoDAELIAMpAwggAygCBK18Qv///////////wBWBEAgAygCFEEEQRYQFCADQgA3AygMAQsgAyADKQMIIAMoAgStfDcDKAsgAykDKCEBIANBMGokACABC20BAX8jAEEgayIEJAAgBCAANgIYIAQgATYCFCAEIAI2AhAgBCADNgIMAkAgBCgCGEUEQCAEQQA2AhwMAQsgBCAEKAIUIAQoAhAgBCgCDCAEKAIYQQhqEJIBNgIcCyAEKAIcIQAgBEEgaiQAIAALVQEBfyMAQRBrIgEkACABIAA2AgwCQAJAIAEoAgwoAiRBAUYNACABKAIMKAIkQQJGDQAMAQsgASgCDEEAQgBBChAhGiABKAIMQQA2AiQLIAFBEGokAAumAQEBfyMAQRBrIgIkACACIAA2AgggAiABNgIEAkAgAigCCC0AKEEBcQRAIAJBfzYCDAwBCyACKAIIKAIABEAgAigCCCgCACACKAIEEGhBAEgEQCACKAIIQQxqIAIoAggoAgAQFyACQX82AgwMAgsLIAIoAgggAkEEakIEQRMQIUIAUwRAIAJBfzYCDAwBCyACQQA2AgwLIAIoAgwhACACQRBqJAAgAAuNCAIBfwF+IwBBkAFrIgMkACADIAA2AoQBIAMgATYCgAEgAyACNgJ8IAMQTwJAIAMoAoABKQMIQgBSBEAgAyADKAKAASgCACgCACkDSDcDYCADIAMoAoABKAIAKAIAKQNINwNoDAELIANCADcDYCADQgA3A2gLIANCADcDcAJAA0AgAykDcCADKAKAASkDCFQEQCADKAKAASgCACADKQNwp0EEdGooAgApA0ggAykDaFQEQCADIAMoAoABKAIAIAMpA3CnQQR0aigCACkDSDcDaAsgAykDaCADKAKAASkDIFYEQCADKAJ8QRNBABAUIANCfzcDiAEMAwsgAyADKAKAASgCACADKQNwp0EEdGooAgApA0ggAygCgAEoAgAgAykDcKdBBHRqKAIAKQMgfCADKAKAASgCACADKQNwp0EEdGooAgAoAjAQU0H//wNxrXxC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DEECdGooAgBBAnRqLwEASA0AAkAgAygCGCADKAIQQQJ0ai8BACADKAIYIAMoAhxB3BZqIAMoAgxBAnRqKAIAQQJ0ai8BAEcNACADKAIQIAMoAhxB2Chqai0AACADKAIcQdwWaiADKAIMQQJ0aigCACADKAIcQdgoamotAABKDQAMAQsgAygCHEHcFmogAygCFEECdGogAygCHEHcFmogAygCDEECdGooAgA2AgAgAyADKAIMNgIUIAMgAygCDEEBdDYCDAwBCwsgAygCHEHcFmogAygCFEECdGogAygCEDYCAAvXEwEDfyMAQTBrIgIkACACIAA2AiwgAiABNgIoIAIgAigCKCgCADYCJCACIAIoAigoAggoAgA2AiAgAiACKAIoKAIIKAIMNgIcIAJBfzYCECACKAIsQQA2AtAoIAIoAixBvQQ2AtQoIAJBADYCGANAIAIoAhggAigCHEgEQAJAIAIoAiQgAigCGEECdGovAQAEQCACIAIoAhgiATYCECACKAIsQdwWaiEDIAIoAiwiBCgC0ChBAWohACAEIAA2AtAoIABBAnQgA2ogATYCACACKAIYIAIoAixB2ChqakEAOgAADAELIAIoAiQgAigCGEECdGpBADsBAgsgAiACKAIYQQFqNgIYDAELCwNAIAIoAiwoAtAoQQJIBEACQCACKAIQQQJIBEAgAiACKAIQQQFqIgA2AhAMAQtBACEACyACKAIsQdwWaiEDIAIoAiwiBCgC0ChBAWohASAEIAE2AtAoIAFBAnQgA2ogADYCACACIAA2AgwgAigCJCACKAIMQQJ0akEBOwEAIAIoAgwgAigCLEHYKGpqQQA6AAAgAigCLCIAIAAoAqgtQQFrNgKoLSACKAIgBEAgAigCLCIAIAAoAqwtIAIoAiAgAigCDEECdGovAQJrNgKsLQsMAQsLIAIoAiggAigCEDYCBCACIAIoAiwoAtAoQQJtNgIYA0AgAigCGEEBTgRAIAIoAiwgAigCJCACKAIYEHogAiACKAIYQQFrNgIYDAELCyACIAIoAhw2AgwDQCACIAIoAiwoAuAWNgIYIAIoAixB3BZqIQEgAigCLCIDKALQKCEAIAMgAEEBazYC0CggAigCLCAAQQJ0IAFqKAIANgLgFiACKAIsIAIoAiRBARB6IAIgAigCLCgC4BY2AhQgAigCGCEBIAIoAixB3BZqIQMgAigCLCIEKALUKEEBayEAIAQgADYC1CggAEECdCADaiABNgIAIAIoAhQhASACKAIsQdwWaiEDIAIoAiwiBCgC1ChBAWshACAEIAA2AtQoIABBAnQgA2ogATYCACACKAIkIAIoAgxBAnRqIAIoAiQgAigCGEECdGovAQAgAigCJCACKAIUQQJ0ai8BAGo7AQAgAigCDCACKAIsQdgoamoCfyACKAIYIAIoAixB2Chqai0AACACKAIUIAIoAixB2Chqai0AAE4EQCACKAIYIAIoAixB2Chqai0AAAwBCyACKAIUIAIoAixB2Chqai0AAAtBAWo6AAAgAigCJCACKAIUQQJ0aiACKAIMIgA7AQIgAigCJCACKAIYQQJ0aiAAOwECIAIgAigCDCIAQQFqNgIMIAIoAiwgADYC4BYgAigCLCACKAIkQQEQeiACKAIsKALQKEECTg0ACyACKAIsKALgFiEBIAIoAixB3BZqIQMgAigCLCIEKALUKEEBayEAIAQgADYC1CggAEECdCADaiABNgIAIAIoAighASMAQUBqIgAgAigCLDYCPCAAIAE2AjggACAAKAI4KAIANgI0IAAgACgCOCgCBDYCMCAAIAAoAjgoAggoAgA2AiwgACAAKAI4KAIIKAIENgIoIAAgACgCOCgCCCgCCDYCJCAAIAAoAjgoAggoAhA2AiAgAEEANgIEIABBADYCEANAIAAoAhBBD0wEQCAAKAI8QbwWaiAAKAIQQQF0akEAOwEAIAAgACgCEEEBajYCEAwBCwsgACgCNCAAKAI8QdwWaiAAKAI8KALUKEECdGooAgBBAnRqQQA7AQIgACAAKAI8KALUKEEBajYCHANAIAAoAhxBvQRIBEAgACAAKAI8QdwWaiAAKAIcQQJ0aigCADYCGCAAIAAoAjQgACgCNCAAKAIYQQJ0ai8BAkECdGovAQJBAWo2AhAgACgCECAAKAIgSgRAIAAgACgCIDYCECAAIAAoAgRBAWo2AgQLIAAoAjQgACgCGEECdGogACgCEDsBAiAAKAIYIAAoAjBMBEAgACgCPCAAKAIQQQF0akG8FmoiASABLwEAQQFqOwEAIABBADYCDCAAKAIYIAAoAiROBEAgACAAKAIoIAAoAhggACgCJGtBAnRqKAIANgIMCyAAIAAoAjQgACgCGEECdGovAQA7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EANAIAMpAxAgAykDCFpFBEAgAygCKCgCACADKQMQp0EEdGoQkAEgAyADKQMQQgF8NwMQDAELCyADKAIoIAMpAwgiATcDECADKAIoIAE3AwggA0EBOgAvCyADLQAvQQFxIQAgA0EwaiQAIAALzAEBAX8jAEEgayICJAAgAiAANwMQIAIgATYCDCACQTAQGCIBNgIIAkAgAUUEQCACKAIMQQ5BABAUIAJBADYCHAwBCyACKAIIQQA2AgAgAigCCEIANwMQIAIoAghCADcDCCACKAIIQgA3AyAgAigCCEIANwMYIAIoAghBADYCKCACKAIIQQA6ACwgAigCCCACKQMQIAIoAgwQgwFBAXFFBEAgAigCCBAkIAJBADYCHAwBCyACIAIoAgg2AhwLIAIoAhwhASACQSBqJAAgAQvWAgEBfyMAQSBrIgMkACADIAA2AhggAyABNgIUIAMgAjYCECADIANBDGpCBBApNgIIAkAgAygCCEUEQCADQX82AhwMAQsDQCADKAIUBEAgAygCFCgCBCADKAIQcUGABnEEQCADKAIIQgAQLBogAygCCCADKAIULwEIEB8gAygCCCADKAIULwEKEB8CfyMAQRBrIgAgAygCCDYCDCAAKAIMLQAAQQFxRQsEQCADKAIYQQhqQRRBABAUIAMoAggQFiADQX82AhwMBAsgAygCGCADQQxqQgQQNUEASARAIAMoAggQFiADQX82AhwMBAsgAygCFC8BCgRAIAMoAhggAygCFCgCDCADKAIULwEKrRA1QQBIBEAgAygCCBAWIANBfzYCHAwFCwsLIAMgAygCFCgCADYCFAwBCwsgAygCCBAWIANBADYCHAsgAygCHCEAIANBIGokACAAC2gBAX8jAEEQayICIAA2AgwgAiABNgIIIAJBADsBBgNAIAIoAgwEQCACKAIMKAIEIAIoAghxQYAGcQRAIAIgAigCDC8BCiACLwEGQQRqajsBBgsgAiACKAIMKAIANgIMDAELCyACLwEGC/ABAQF/IwBBEGsiASQAIAEgADYCDCABIAEoAgw2AgggAUEANgIEA0AgASgCDARAAkACQCABKAIMLwEIQfXGAUYNACABKAIMLwEIQfXgAUYNACABKAIMLwEIQYGyAkYNACABKAIMLwEIQQFHDQELIAEgASgCDCgCADYCACABKAIIIAEoAgxGBEAgASABKAIANgIICyABKAIMQQA2AgAgASgCDBAjIAEoAgQEQCABKAIEIAEoAgA2AgALIAEgASgCADYCDAwCCyABIAEoAgw2AgQgASABKAIMKAIANgIMDAELCyABKAIIIQAgAUEQaiQAIAALswQBAX8jAEFAaiIFJAAgBSAANgI4IAUgATsBNiAFIAI2AjAgBSADNgIsIAUgBDYCKCAFIAUoAjggBS8BNq0QKSIANgIkAkAgAEUEQCAFKAIoQQ5BABAUIAVBADoAPwwBCyAFQQA2AiAgBUEANgIYA0ACfyMAQRBrIgAgBSgCJDYCDCAAKAIMLQAAQQFxCwR/IAUoAiQQL0IEWgVBAAtBAXEEQCAFIAUoAiQQHTsBFiAFIAUoAiQQHTsBFCAFIAUoAiQgBS8BFK0QHjYCECAFKAIQRQRAIAUoAihBFUEAEBQgBSgCJBAWIAUoAhgQIyAFQQA6AD8MAwsgBSAFLwEWIAUvARQgBSgCECAFKAIwEFEiADYCHCAARQRAIAUoAihBDkEAEBQgBSgCJBAWIAUoAhgQIyAFQQA6AD8MAwsCQCAFKAIYBEAgBSgCICAFKAIcNgIAIAUgBSgCHDYCIAwBCyAFIAUoAhwiADYCICAFIAA2AhgLDAELCyAFKAIkEEdBAXFFBEAgBSAFKAIkEC8+AgwgBSAFKAIkIAUoAgytEB42AggCQAJAIAUoAgxBBE8NACAFKAIIRQ0AIAUoAghBktkAIAUoAgwQVEUNAQsgBSgCKEEVQQAQFCAFKAIkEBYgBSgCGBAjIAVBADoAPwwCCwsgBSgCJBAWAkAgBSgCLARAIAUoAiwgBSgCGDYCAAwBCyAFKAIYECMLIAVBAToAPwsgBS0AP0EBcSEAIAVBQGskACAAC+8CAQF/IwBBIGsiAiQAIAIgADYCGCACIAE2AhQCQCACKAIYRQRAIAIgAigCFDYCHAwBCyACIAIoAhg2AggDQCACKAIIKAIABEAgAiACKAIIKAIANgIIDAELCwNAIAIoAhQEQCACIAIoAhQoAgA2AhAgAkEANgIEIAIgAigCGDYCDANAAkAgAigCDEUNAAJAIAIoAgwvAQggAigCFC8BCEcNACACKAIMLwEKIAIoAhQvAQpHDQAgAigCDC8BCgRAIAIoAgwoAgwgAigCFCgCDCACKAIMLwEKEFQNAQsgAigCDCIAIAAoAgQgAigCFCgCBEGABnFyNgIEIAJBATYCBAwBCyACIAIoAgwoAgA2AgwMAQsLIAIoAhRBADYCAAJAIAIoAgQEQCACKAIUECMMAQsgAigCCCACKAIUIgA2AgAgAiAANgIICyACIAIoAhA2AhQMAQsLIAIgAigCGDYCHAsgAigCHCEAIAJBIGokACAAC10BAX8jAEEQayICJAAgAiAANgIIIAIgATYCBAJAIAIoAgRFBEAgAkEANgIMDAELIAIgAigCCCACKAIEKAIAIAIoAgQvAQStEDU2AgwLIAIoAgwhACACQRBqJAAgAAuPAQEBfyMAQRBrIgIkACACIAA2AgggAiABNgIEAkACQCACKAIIBEAgAigCBA0BCyACIAIoAgggAigCBEY2AgwMAQsgAigCCC8BBCACKAIELwEERwRAIAJBADYCDAwBCyACIAIoAggoAgAgAigCBCgCACACKAIILwEEEFRFNgIMCyACKAIMIQAgAkEQaiQAIAALVQEBfyMAQRBrIgEkACABIAA2AgwgAUEAQQBBABAaNgIIIAEoAgwEQCABIAEoAgggASgCDCgCACABKAIMLwEEEBo2AggLIAEoAgghACABQRBqJAAgAAugAQEBfyMAQSBrIgUkACAFIAA2AhggBSABNgIUIAUgAjsBEiAFIAM6ABEgBSAENgIMIAUgBSgCGCAFKAIUIAUvARIgBS0AEUEBcSAFKAIMEGAiADYCCAJAIABFBEAgBUEANgIcDAELIAUgBSgCCCAFLwESQQAgBSgCDBBSNgIEIAUoAggQFSAFIAUoAgQ2AhwLIAUoAhwhACAFQSBqJAAgAAtfAQF/IwBBEGsiAiQAIAIgADYCCCACIAE6AAcgAiACKAIIQgEQHjYCAAJAIAIoAgBFBEAgAkF/NgIMDAELIAIoAgAgAi0ABzoAACACQQA2AgwLIAIoAgwaIAJBEGokAAtUAQF/IwBBEGsiASQAIAEgADYCCCABIAEoAghCARAeNgIEAkAgASgCBEUEQCABQQA6AA8MAQsgASABKAIELQAAOgAPCyABLQAPIQAgAUEQaiQAIAALOAEBfyMAQRBrIgEgADYCDCABKAIMQQA2AgAgASgCDEEANgIEIAEoAgxBADYCCCABKAIMQQA6AAwLnwIBAX8jAEFAaiIFJAAgBSAANwMwIAUgATcDKCAFIAI2AiQgBSADNwMYIAUgBDYCFCAFAn8gBSkDGEIQVARAIAUoAhRBEkEAEBRBAAwBCyAFKAIkCzYCBAJAIAUoAgRFBEAgBUJ/NwM4DAELAkACQAJAAkACQCAFKAIEKAIIDgMCAAEDCyAFIAUpAzAgBSgCBCkDAHw3AwgMAwsgBSAFKQMoIAUoAgQpAwB8NwMIDAILIAUgBSgCBCkDADcDCAwBCyAFKAIUQRJBABAUIAVCfzcDOAwBCwJAIAUpAwhCAFkEQCAFKQMIIAUpAyhYDQELIAUoAhRBEkEAEBQgBUJ/NwM4DAELIAUgBSkDCDcDOAsgBSkDOCEAIAVBQGskACAAC+oBAgF/AX4jAEEgayIEJAAgBCAANgIYIAQgATYCFCAEIAI2AhAgBCADNgIMIAQgBCgCDBCTASIANgIIAkAgAEUEQCAEQQA2AhwMAQsjAEEQayIAIAQoAhg2AgwgACgCDCIAIAAoAjBBAWo2AjAgBCgCCCAEKAIYNgIAIAQoAgggBCgCFDYCBCAEKAIIIAQoAhA2AgggBCgCGCAEKAIQQQBCAEEOIAQoAhQRCgAhBSAEKAIIIAU3AxggBCgCCCkDGEIAUwRAIAQoAghCPzcDGAsgBCAEKAIINgIcCyAEKAIcIQAgBEEgaiQAIAAL6gEBAX8jAEEQayIBJAAgASAANgIIIAFBOBAYIgA2AgQCQCAARQRAIAEoAghBDkEAEBQgAUEANgIMDAELIAEoAgRBADYCACABKAIEQQA2AgQgASgCBEEANgIIIAEoAgRBADYCICABKAIEQQA2AiQgASgCBEEAOgAoIAEoAgRBADYCLCABKAIEQQE2AjAjAEEQayIAIAEoAgRBDGo2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AgggASgCBEEAOgA0IAEoAgRBADoANSABIAEoAgQ2AgwLIAEoAgwhACABQRBqJAAgAAuwAQIBfwF+IwBBIGsiAyQAIAMgADYCGCADIAE2AhQgAyACNgIQIAMgAygCEBCTASIANgIMAkAgAEUEQCADQQA2AhwMAQsgAygCDCADKAIYNgIEIAMoAgwgAygCFDYCCCADKAIUQQBCAEEOIAMoAhgRDgAhBCADKAIMIAQ3AxggAygCDCkDGEIAUwRAIAMoAgxCPzcDGAsgAyADKAIMNgIcCyADKAIcIQAgA0EgaiQAIAALwwIBAX8jAEEQayIDIAA2AgwgAyABNgIIIAMgAjYCBCADKAIIKQMAQgKDQgBSBEAgAygCDCADKAIIKQMQNwMQCyADKAIIKQMAQgSDQgBSBEAgAygCDCADKAIIKQMYNwMYCyADKAIIKQMAQgiDQgBSBEAgAygCDCADKAIIKQMgNwMgCyADKAIIKQMAQhCDQgBSBEAgAygCDCADKAIIKAIoNgIoCyADKAIIKQMAQiCDQgBSBEAgAygCDCADKAIIKAIsNgIsCyADKAIIKQMAQsAAg0IAUgRAIAMoAgwgAygCCC8BMDsBMAsgAygCCCkDAEKAAYNCAFIEQCADKAIMIAMoAggvATI7ATILIAMoAggpAwBCgAKDQgBSBEAgAygCDCADKAIIKAI0NgI0CyADKAIMIgAgAygCCCkDACAAKQMAhDcDAEEAC1oBAX8jAEEQayIBIAA2AggCQAJAIAEoAggoAgBBAE4EQCABKAIIKAIAQYAUKAIASA0BCyABQQA2AgwMAQsgASABKAIIKAIAQQJ0QZAUaigCADYCDAsgASgCDAumAQEBfyMAQSBrIgUkACAFIAA2AhggBSABNwMQIAUgAjYCDCAFIAM2AgggBSAENgIEIAUgBSgCGCAFKQMQIAUoAgxBABBFIgA2AgACQCAARQRAIAVBfzYCHAwBCyAFKAIIBEAgBSgCCCAFKAIALwEIQQh2OgAACyAFKAIEBEAgBSgCBCAFKAIAKAJENgIACyAFQQA2AhwLIAUoAhwhACAFQSBqJAAgAAucBgECfyMAQSBrIgIkACACIAA2AhggAiABNwMQAkAgAikDECACKAIYKQMwWgRAIAIoAhhBCGpBEkEAEBQgAkF/NgIcDAELIAIoAhgoAhhBAnEEQCACKAIYQQhqQRlBABAUIAJBfzYCHAwBCyACIAIoAhggAikDEEEAIAIoAhhBCGoQTiIANgIMIABFBEAgAkF/NgIcDAELIAIoAhgoAlAgAigCDCACKAIYQQhqEFhBAXFFBEAgAkF/NgIcDAELAn8gAigCGCEDIAIpAxAhASMAQTBrIgAkACAAIAM2AiggACABNwMgIABBATYCHAJAIAApAyAgACgCKCkDMFoEQCAAKAIoQQhqQRJBABAUIABBfzYCLAwBCwJAIAAoAhwNACAAKAIoKAJAIAApAyCnQQR0aigCBEUNACAAKAIoKAJAIAApAyCnQQR0aigCBCgCAEECcUUNAAJAIAAoAigoAkAgACkDIKdBBHRqKAIABEAgACAAKAIoIAApAyBBCCAAKAIoQQhqEE4iAzYCDCADRQRAIABBfzYCLAwECyAAIAAoAiggACgCDEEAQQAQVzcDEAJAIAApAxBCAFMNACAAKQMQIAApAyBRDQAgACgCKEEIakEKQQAQFCAAQX82AiwMBAsMAQsgAEEANgIMCyAAIAAoAiggACkDIEEAIAAoAihBCGoQTiIDNgIIIANFBEAgAEF/NgIsDAILIAAoAgwEQCAAKAIoKAJQIAAoAgwgACkDIEEAIAAoAihBCGoQdUEBcUUEQCAAQX82AiwMAwsLIAAoAigoAlAgACgCCCAAKAIoQQhqEFhBAXFFBEAgACgCKCgCUCAAKAIMQQAQWBogAEF/NgIsDAILCyAAKAIoKAJAIAApAyCnQQR0aigCBBA5IAAoAigoAkAgACkDIKdBBHRqQQA2AgQgACgCKCgCQCAAKQMgp0EEdGoQYyAAQQA2AiwLIAAoAiwhAyAAQTBqJAAgAwsEQCACQX82AhwMAQsgAigCGCgCQCACKQMQp0EEdGpBAToADCACQQA2AhwLIAIoAhwhACACQSBqJAAgAAulBAEBfyMAQTBrIgUkACAFIAA2AiggBSABNwMgIAUgAjYCHCAFIAM6ABsgBSAENgIUAkAgBSgCKCAFKQMgQQBBABBFRQRAIAVBfzYCLAwBCyAFKAIoKAIYQQJxBEAgBSgCKEEIakEZQQAQFCAFQX82AiwMAQsgBSAFKAIoKAJAIAUpAyCnQQR0ajYCECAFAn8gBSgCECgCAARAIAUoAhAoAgAvAQhBCHYMAQtBAws6AAsgBQJ/IAUoAhAoAgAEQCAFKAIQKAIAKAJEDAELQYCA2I14CzYCBEEBIQAgBSAFLQAbIAUtAAtGBH8gBSgCFCAFKAIERwVBAQtBAXE2AgwCQCAFKAIMBEAgBSgCECgCBEUEQCAFKAIQKAIAED8hACAFKAIQIAA2AgQgAEUEQCAFKAIoQQhqQQ5BABAUIAVBfzYCLAwECwsgBSgCECgCBCAFKAIQKAIELwEIQf8BcSAFLQAbQQh0cjsBCCAFKAIQKAIEIAUoAhQ2AkQgBSgCECgCBCIAIAAoAgBBEHI2AgAMAQsgBSgCECgCBARAIAUoAhAoAgQiACAAKAIAQW9xNgIAAkAgBSgCECgCBCgCAEUEQCAFKAIQKAIEEDkgBSgCEEEANgIEDAELIAUoAhAoAgQgBSgCECgCBC8BCEH/AXEgBS0AC0EIdHI7AQggBSgCECgCBCAFKAIENgJECwsLIAVBADYCLAsgBSgCLCEAIAVBMGokACAAC90PAgF/AX4jAEFAaiIEJAAgBCAANgI0IARCfzcDKCAEIAE2AiQgBCACNgIgIAQgAzYCHAJAIAQoAjQoAhhBAnEEQCAEKAI0QQhqQRlBABAUIARCfzcDOAwBCyAEIAQoAjQpAzA3AxAgBCkDKEJ/UQRAIARCfzcDCCAEKAIcQYDAAHEEQCAEIAQoAjQgBCgCJCAEKAIcQQAQVzcDCAsgBCkDCEJ/UQRAIAQoAjQhASMAQUBqIgAkACAAIAE2AjQCQCAAKAI0KQM4IAAoAjQpAzBCAXxYBEAgACAAKAI0KQM4NwMYIAAgACkDGEIBhjcDEAJAIAApAxBCEFQEQCAAQhA3AxAMAQsgACkDEEKACFYEQCAAQoAINwMQCwsgACAAKQMQIAApAxh8NwMYIAAgACkDGKdBBHStNwMIIAApAwggACgCNCkDOKdBBHStVARAIAAoAjRBCGpBDkEAEBQgAEJ/NwM4DAILIAAgACgCNCgCQCAAKQMYp0EEdBBINgIkIAAoAiRFBEAgACgCNEEIakEOQQAQFCAAQn83AzgMAgsgACgCNCAAKAIkNgJAIAAoAjQgACkDGDcDOAsgACgCNCIBKQMwIQUgASAFQgF8NwMwIAAgBTcDKCAAKAI0KAJAIAApAyinQQR0ahCQASAAIAApAyg3AzgLIAApAzghBSAAQUBrJAAgBCAFNwMIIAVCAFMEQCAEQn83AzgMAwsLIAQgBCkDCDcDKAsCQCAEKAIkRQ0AIAQoAjQhASAEKQMoIQUgBCgCJCECIAQoAhwhAyMAQUBqIgAkACAAIAE2AjggACAFNwMwIAAgAjYCLCAAIAM2AigCQCAAKQMwIAAoAjgpAzBaBEAgACgCOEEIakESQQAQFCAAQX82AjwMAQsgACgCOCgCGEECcQRAIAAoAjhBCGpBGUEAEBQgAEF/NgI8DAELAkACQCAAKAIsRQ0AIAAoAiwsAABFDQAgACAAKAIsIAAoAiwQK0H//wNxIAAoAiggACgCOEEIahBSIgE2AiAgAUUEQCAAQX82AjwMAwsCQCAAKAIoQYAwcQ0AIAAoAiBBABA6QQNHDQAgACgCIEECNgIICwwBCyAAQQA2AiALIAAgACgCOCAAKAIsQQBBABBXIgU3AxACQCAFQgBTDQAgACkDECAAKQMwUQ0AIAAoAiAQJSAAKAI4QQhqQQpBABAUIABBfzYCPAwBCwJAIAApAxBCAFMNACAAKQMQIAApAzBSDQAgACgCIBAlIABBADYCPAwBCyAAIAAoAjgoAkAgACkDMKdBBHRqNgIkAkAgACgCJCgCAARAIAAgACgCJCgCACgCMCAAKAIgEIsBQQBHOgAfDAELIABBADoAHwsCQCAALQAfQQFxDQAgACgCJCgCBA0AIAAoAiQoAgAQPyEBIAAoAiQgATYCBCABRQRAIAAoAjhBCGpBDkEAEBQgACgCIBAlIABBfzYCPAwCCwsgAAJ/IAAtAB9BAXEEQCAAKAIkKAIAKAIwDAELIAAoAiALQQBBACAAKAI4QQhqEEYiATYCCCABRQRAIAAoAiAQJSAAQX82AjwMAQsCQCAAKAIkKAIEBEAgACAAKAIkKAIEKAIwNgIEDAELAkAgACgCJCgCAARAIAAgACgCJCgCACgCMDYCBAwBCyAAQQA2AgQLCwJAIAAoAgQEQCAAIAAoAgRBAEEAIAAoAjhBCGoQRiIBNgIMIAFFBEAgACgCIBAlIABBfzYCPAwDCwwBCyAAQQA2AgwLIAAoAjgoAlAgACgCCCAAKQMwQQAgACgCOEEIahB1QQFxRQRAIAAoAiAQJSAAQX82AjwMAQsgACgCDARAIAAoAjgoAlAgACgCDEEAEFgaCwJAIAAtAB9BAXEEQCAAKAIkKAIEBEAgACgCJCgCBCgCAEECcQRAIAAoAiQoAgQoAjAQJSAAKAIkKAIEIgEgASgCAEF9cTYCAAJAIAAoAiQoAgQoAgBFBEAgACgCJCgCBBA5IAAoAiRBADYCBAwBCyAAKAIkKAIEIAAoAiQoAgAoAjA2AjALCwsgACgCIBAlDAELIAAoAiQoAgQoAgBBAnEEQCAAKAIkKAIEKAIwECULIAAoAiQoAgQiASABKAIAQQJyNgIAIAAoAiQoAgQgACgCIDYCMAsgAEEANgI8CyAAKAI8IQEgAEFAayQAIAFFDQAgBCgCNCkDMCAEKQMQUgRAIAQoAjQoAkAgBCkDKKdBBHRqEGIgBCgCNCAEKQMQNwMwCyAEQn83AzgMAQsgBCgCNCgCQCAEKQMop0EEdGoQYwJAIAQoAjQoAkAgBCkDKKdBBHRqKAIARQ0AIAQoAjQoAkAgBCkDKKdBBHRqKAIEBEAgBCgCNCgCQCAEKQMop0EEdGooAgQoAgBBAXENAQsgBCgCNCgCQCAEKQMop0EEdGooAgRFBEAgBCgCNCgCQCAEKQMop0EEdGooAgAQPyEAIAQoAjQoAkAgBCkDKKdBBHRqIAA2AgQgAEUEQCAEKAI0QQhqQQ5BABAUIARCfzcDOAwDCwsgBCgCNCgCQCAEKQMop0EEdGooAgRBfjYCECAEKAI0KAJAIAQpAyinQQR0aigCBCIAIAAoAgBBAXI2AgALIAQoAjQoAkAgBCkDKKdBBHRqIAQoAiA2AgggBCAEKQMoNwM4CyAEKQM4IQUgBEFAayQAIAULqgEBAX8jAEEwayICJAAgAiAANgIoIAIgATcDICACQQA2AhwCQAJAIAIoAigoAiRBAUYEQCACKAIcRQ0BIAIoAhxBAUYNASACKAIcQQJGDQELIAIoAihBDGpBEkEAEBQgAkF/NgIsDAELIAIgAikDIDcDCCACIAIoAhw2AhAgAkF/QQAgAigCKCACQQhqQhBBDBAhQgBTGzYCLAsgAigCLCEAIAJBMGokACAAC6UyAwZ/AX4BfCMAQeAAayIEJAAgBCAANgJYIAQgATYCVCAEIAI2AlACQAJAIAQoAlRBAE4EQCAEKAJYDQELIAQoAlBBEkEAEBQgBEEANgJcDAELIAQgBCgCVDYCTCMAQRBrIgAgBCgCWDYCDCAEIAAoAgwpAxg3A0BB4JoBKQMAQn9RBEAgBEF/NgIUIARBAzYCECAEQQc2AgwgBEEGNgIIIARBAjYCBCAEQQE2AgBB4JoBQQAgBBA2NwMAIARBfzYCNCAEQQ82AjAgBEENNgIsIARBDDYCKCAEQQo2AiQgBEEJNgIgQeiaAUEIIARBIGoQNjcDAAtB4JoBKQMAIAQpA0BB4JoBKQMAg1IEQCAEKAJQQRxBABAUIARBADYCXAwBC0HomgEpAwAgBCkDQEHomgEpAwCDUgRAIAQgBCgCTEEQcjYCTAsgBCgCTEEYcUEYRgRAIAQoAlBBGUEAEBQgBEEANgJcDAELIAQoAlghASAEKAJQIQIjAEHQAGsiACQAIAAgATYCSCAAIAI2AkQgAEEIahA7AkAgACgCSCAAQQhqEDgEQCMAQRBrIgEgACgCSDYCDCAAIAEoAgxBDGo2AgQjAEEQayIBIAAoAgQ2AgwCQCABKAIMKAIAQQVHDQAjAEEQayIBIAAoAgQ2AgwgASgCDCgCBEEsRw0AIABBADYCTAwCCyAAKAJEIAAoAgQQQyAAQX82AkwMAQsgAEEBNgJMCyAAKAJMIQEgAEHQAGokACAEIAE2AjwCQAJAAkAgBCgCPEEBag4CAAECCyAEQQA2AlwMAgsgBCgCTEEBcUUEQCAEKAJQQQlBABAUIARBADYCXAwCCyAEIAQoAlggBCgCTCAEKAJQEGo2AlwMAQsgBCgCTEECcQRAIAQoAlBBCkEAEBQgBEEANgJcDAELIAQoAlgQSUEASARAIAQoAlAgBCgCWBAXIARBADYCXAwBCwJAIAQoAkxBCHEEQCAEIAQoAlggBCgCTCAEKAJQEGo2AjgMAQsgBCgCWCEAIAQoAkwhASAEKAJQIQIjAEHwAGsiAyQAIAMgADYCaCADIAE2AmQgAyACNgJgIANBIGoQOwJAIAMoAmggA0EgahA4QQBIBEAgAygCYCADKAJoEBcgA0EANgJsDAELIAMpAyBCBINQBEAgAygCYEEEQYoBEBQgA0EANgJsDAELIAMgAykDODcDGCADIAMoAmggAygCZCADKAJgEGoiADYCXCAARQRAIANBADYCbAwBCwJAIAMpAxhQRQ0AIAMoAmgQngFBAXFFDQAgAyADKAJcNgJsDAELIAMoAlwhACADKQMYIQkjAEHgAGsiAiQAIAIgADYCWCACIAk3A1ACQCACKQNQQhZUBEAgAigCWEEIakETQQAQFCACQQA2AlwMAQsgAgJ+IAIpA1BCqoAEVARAIAIpA1AMAQtCqoAECzcDMCACKAJYKAIAQgAgAikDMH1BAhAnQQBIBEAjAEEQayIAIAIoAlgoAgA2AgwgAiAAKAIMQQxqNgIIAkACfyMAQRBrIgAgAigCCDYCDCAAKAIMKAIAQQRGCwRAIwBBEGsiACACKAIINgIMIAAoAgwoAgRBFkYNAQsgAigCWEEIaiACKAIIEEMgAkEANgJcDAILCyACIAIoAlgoAgAQSiIJNwM4IAlCAFMEQCACKAJYQQhqIAIoAlgoAgAQFyACQQA2AlwMAQsgAiACKAJYKAIAIAIpAzBBACACKAJYQQhqEEEiADYCDCAARQRAIAJBADYCXAwBCyACQn83AyAgAkEANgJMIAIpAzBCqoAEWgRAIAIoAgxCFBAsGgsgAkEQakETQQAQFCACIAIoAgxCABAeNgJEA0ACQCACKAJEIQEgAigCDBAvQhJ9pyEFIwBBIGsiACQAIAAgATYCGCAAIAU2AhQgAEHsEjYCECAAQQQ2AgwCQAJAIAAoAhQgACgCDE8EQCAAKAIMDQELIABBADYCHAwBCyAAIAAoAhhBAWs2AggDQAJAIAAgACgCCEEBaiAAKAIQLQAAIAAoAhggACgCCGsgACgCFCAAKAIMa2oQqwEiATYCCCABRQ0AIAAoAghBAWogACgCEEEBaiAAKAIMQQFrEFQNASAAIAAoAgg2AhwMAgsLIABBADYCHAsgACgCHCEBIABBIGokACACIAE2AkQgAUUNACACKAIMIAIoAkQCfyMAQRBrIgAgAigCDDYCDCAAKAIMKAIEC2usECwaIAIoAlghASACKAIMIQUgAikDOCEJIwBB8ABrIgAkACAAIAE2AmggACAFNgJkIAAgCTcDWCAAIAJBEGo2AlQjAEEQayIBIAAoAmQ2AgwgAAJ+IAEoAgwtAABBAXEEQCABKAIMKQMQDAELQgALNwMwAkAgACgCZBAvQhZUBEAgACgCVEETQQAQFCAAQQA2AmwMAQsgACgCZEIEEB4oAABB0JaVMEcEQCAAKAJUQRNBABAUIABBADYCbAwBCwJAAkAgACkDMEIUVA0AIwBBEGsiASAAKAJkNgIMIAEoAgwoAgQgACkDMKdqQRRrKAAAQdCWmThHDQAgACgCZCAAKQMwQhR9ECwaIAAoAmgoAgAhBSAAKAJkIQYgACkDWCEJIAAoAmgoAhQhByAAKAJUIQgjAEGwAWsiASQAIAEgBTYCqAEgASAGNgKkASABIAk3A5gBIAEgBzYClAEgASAINgKQASMAQRBrIgUgASgCpAE2AgwgAQJ+IAUoAgwtAABBAXEEQCAFKAIMKQMQDAELQgALNwMYIAEoAqQBQgQQHhogASABKAKkARAdQf//A3E2AhAgASABKAKkARAdQf//A3E2AgggASABKAKkARAwNwM4AkAgASkDOEL///////////8AVgRAIAEoApABQQRBFhAUIAFBADYCrAEMAQsgASkDOEI4fCABKQMYIAEpA5gBfFYEQCABKAKQAUEVQQAQFCABQQA2AqwBDAELAkACQCABKQM4IAEpA5gBVA0AIAEpAzhCOHwgASkDmAECfiMAQRBrIgUgASgCpAE2AgwgBSgCDCkDCAt8Vg0AIAEoAqQBIAEpAzggASkDmAF9ECwaIAFBADoAFwwBCyABKAKoASABKQM4QQAQJ0EASARAIAEoApABIAEoAqgBEBcgAUEANgKsAQwCCyABIAEoAqgBQjggAUFAayABKAKQARBBIgU2AqQBIAVFBEAgAUEANgKsAQwCCyABQQE6ABcLIAEoAqQBQgQQHigAAEHQlpkwRwRAIAEoApABQRVBABAUIAEtABdBAXEEQCABKAKkARAWCyABQQA2AqwBDAELIAEgASgCpAEQMDcDMAJAIAEoApQBQQRxRQ0AIAEpAzAgASkDOHxCDHwgASkDmAEgASkDGHxRDQAgASgCkAFBFUEAEBQgAS0AF0EBcQRAIAEoAqQBEBYLIAFBADYCrAEMAQsgASgCpAFCBBAeGiABIAEoAqQBECo2AgwgASABKAKkARAqNgIEIAEoAhBB//8DRgRAIAEgASgCDDYCEAsgASgCCEH//wNGBEAgASABKAIENgIICwJAIAEoApQBQQRxRQ0AIAEoAgggASgCBEYEQCABKAIQIAEoAgxGDQELIAEoApABQRVBABAUIAEtABdBAXEEQCABKAKkARAWCyABQQA2AqwBDAELAkAgASgCEEUEQCABKAIIRQ0BCyABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDA3AyggASABKAKkARAwNwMgIAEpAyggASkDIFIEQCABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDA3AzAgASABKAKkARAwNwOAAQJ/IwBBEGsiBSABKAKkATYCDCAFKAIMLQAAQQFxRQsEQCABKAKQAUEUQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABLQAXQQFxBEAgASgCpAEQFgsCQCABKQOAAUL///////////8AWARAIAEpA4ABIAEpA4ABIAEpAzB8WA0BCyABKAKQAUEEQRYQFCABQQA2AqwBDAELIAEpA4ABIAEpAzB8IAEpA5gBIAEpAzh8VgRAIAEoApABQRVBABAUIAFBADYCrAEMAQsCQCABKAKUAUEEcUUNACABKQOAASABKQMwfCABKQOYASABKQM4fFENACABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEpAyggASkDMEIugFYEQCABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEgASkDKCABKAKQARCEASIFNgKMASAFRQRAIAFBADYCrAEMAQsgASgCjAFBAToALCABKAKMASABKQMwNwMYIAEoAowBIAEpA4ABNwMgIAEgASgCjAE2AqwBCyABKAKsASEFIAFBsAFqJAAgACAFNgJQDAELIAAoAmQgACkDMBAsGiAAKAJkIQUgACkDWCEJIAAoAmgoAhQhBiAAKAJUIQcjAEHQAGsiASQAIAEgBTYCSCABIAk3A0AgASAGNgI8IAEgBzYCOAJAIAEoAkgQL0IWVARAIAEoAjhBFUEAEBQgAUEANgJMDAELIwBBEGsiBSABKAJINgIMIAECfiAFKAIMLQAAQQFxBEAgBSgCDCkDEAwBC0IACzcDCCABKAJIQgQQHhogASgCSBAqBEAgASgCOEEBQQAQFCABQQA2AkwMAQsgASABKAJIEB1B//8Dca03AyggASABKAJIEB1B//8Dca03AyAgASkDICABKQMoUgRAIAEoAjhBE0EAEBQgAUEANgJMDAELIAEgASgCSBAqrTcDGCABIAEoAkgQKq03AxAgASkDECABKQMQIAEpAxh8VgRAIAEoAjhBBEEWEBQgAUEANgJMDAELIAEpAxAgASkDGHwgASkDQCABKQMIfFYEQCABKAI4QRVBABAUIAFBADYCTAwBCwJAIAEoAjxBBHFFDQAgASkDECABKQMYfCABKQNAIAEpAwh8UQ0AIAEoAjhBFUEAEBQgAUEANgJMDAELIAEgASkDICABKAI4EIQBIgU2AjQgBUUEQCABQQA2AkwMAQsgASgCNEEAOgAsIAEoAjQgASkDGDcDGCABKAI0IAEpAxA3AyAgASABKAI0NgJMCyABKAJMIQUgAUHQAGokACAAIAU2AlALIAAoAlBFBEAgAEEANgJsDAELIAAoAmQgACkDMEIUfBAsGiAAIAAoAmQQHTsBTiAAKAJQKQMgIAAoAlApAxh8IAApA1ggACkDMHxWBEAg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IAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACKAIsIAIoAgxJC0EBcQ0ACyACQYICIAIoAgwgAigCLGtrNgIkIAIgAigCDEGCAms2AiwgAigCJCACKAIgSgRAIAIoAjggAigCNDYCcCACIAIoAiQ2AiAgAigCJCACKAIcTg0CIAIgAigCLCACKAIgQQFrai0AADoACyACIAIoAiwgAigCIGotAAA6AAoLCyACIAIoAhQgAigCNCACKAIQcUEBdGovAQAiATYCNEEAIQAgASACKAIYSwR/IAIgAigCMEEBayIANgIwIABBAEcFQQALQQFxDQELCwJAIAIoAiAgAigCOCgCdE0EQCACIAIoAiA2AjwMAQsgAiACKAI4KAJ0NgI8CyACKAI8C5IQAQF/IwBBMGsiAiQAIAIgADYCKCACIAE2AiQgAgJ/IAIoAigoAiwgAigCKCgCDEEFa0kEQCACKAIoKAIsDAELIAIoAigoAgxBBWsLNgIgIAJBADYCECACIAIoAigoAgAoAgQ2AgwDQAJAIAJB//8DNgIcIAIgAigCKCgCvC1BKmpBA3U2AhQgAigCKCgCACgCECACKAIUSQ0AIAIgAigCKCgCACgCECACKAIUazYCFCACIAIoAigoAmwgAigCKCgCXGs2AhggAigCHCACKAIYIAIoAigoAgAoAgRqSwRAIAIgAigCGCACKAIoKAIAKAIEajYCHAsgAigCHCACKAIUSwRAIAIgAigCFDYCHAsCQCACKAIcIAIoAiBPDQACQCACKAIcRQRAIAIoAiRBBEcNAQsgAigCJEUNACACKAIcIAIoAhggAigCKCgCACgCBGpGDQELDAELQQAhACACIAIoAiRBBEYEfyACKAIcIAIoAhggAigCKCgCACgCBGpGBUEAC0EBcTYCECACKAIoQQBBACACKAIQEFwgAigCKCgCCCACKAIoKAIUQQRraiACKAIcOgAAIAIoAigoAgggAigCKCgCFEEDa2ogAigCHEEIdjoAACACKAIoKAIIIAIoAigoAhRBAmtqIAIoAhxBf3M6AAAgAigCKCgCCCACKAIoKAIUQQFraiACKAIcQX9zQQh2OgAAIAIoAigoAgAQHCACKAIYBEAgAigCGCACKAIcSwRAIAIgAigCHDYCGAsgAigCKCgCACgCDCACKAIoKAI4IAIoAigoAlxqIAIoAhgQGRogAigCKCgCACIAIAIoAhggACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCGGs2AhAgAigCKCgCACIAIAIoAhggACgCFGo2AhQgAigCKCIAIAIoAhggACgCXGo2AlwgAiACKAIcIAIoAhhrNgIcCyACKAIcBEAgAigCKCgCACACKAIoKAIAKAIMIAIoAhwQeBogAigCKCgCACIAIAIoAhwgACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCHGs2AhAgAigCKCgCACIAIAIoAhwgACgCFGo2AhQLIAIoAhBFDQELCyACIAIoAgwgAigCKCgCACgCBGs2AgwgAigCDARAAkAgAigCDCACKAIoKAIsTwRAIAIoAihBAjYCsC0gAigCKCgCOCACKAIoKAIAKAIAIAIoAigoAixrIAIoAigoAiwQGRogAigCKCACKAIoKAIsNgJsDAELIAIoAgwgAigCKCgCPCACKAIoKAJsa08EQCACKAIoIgAgACgCbCACKAIoKAIsazYCbCACKAIoKAI4IAIoAigoAjggAigCKCgCLGogAigCKCgCbBAZGiACKAIoKAKwLUECSQRAIAIoAigiACAAKAKwLUEBajYCsC0LCyACKAIoKAI4IAIoAigoAmxqIAIoAigoAgAoAgAgAigCDGsgAigCDBAZGiACKAIoIgAgAigCDCAAKAJsajYCbAsgAigCKCACKAIoKAJsNgJcIAIoAigiAQJ/IAIoAgwgAigCKCgCLCACKAIoKAK0LWtLBEAgAigCKCgCLCACKAIoKAK0LWsMAQsgAigCDAsgASgCtC1qNgK0LQsgAigCKCgCwC0gAigCKCgCbEkEQCACKAIoIAIoAigoAmw2AsAtCwJAIAIoAhAEQCACQQM2AiwMAQsCQCACKAIkRQ0AIAIoAiRBBEYNACACKAIoKAIAKAIEDQAgAigCKCgCbCACKAIoKAJcRw0AIAJBATYCLAwBCyACIAIoAigoAjwgAigCKCgCbGtBAWs2AhQCQCACKAIoKAIAKAIEIAIoAhRNDQAgAigCKCgCXCACKAIoKAIsSA0AIAIoAigiACAAKAJcIAIoAigoAixrNgJcIAIoAigiACAAKAJsIAIoAigoAixrNgJsIAIoAigoAjggAigCKCgCOCACKAIoKAIsaiACKAIoKAJsEBkaIAIoAigoArAtQQJJBEAgAigCKCIAIAAoArAtQQFqNgKwLQsgAiACKAIoKAIsIAIoAhRqNgIUCyACKAIUIAIoAigoAgAoAgRLBEAgAiACKAIoKAIAKAIENgIUCyACKAIUBEAgAigCKCgCACACKAIoKAI4IAIoAigoAmxqIAIoAhQQeBogAigCKCIAIAIoAhQgACgCbGo2AmwLIAIoAigoAsAtIAIoAigoAmxJBEAgAigCKCACKAIoKAJsNgLALQsgAiACKAIoKAK8LUEqakEDdTYCFCACIAIoAigoAgwgAigCFGtB//8DSwR/Qf//AwUgAigCKCgCDCACKAIUaws2AhQgAgJ/IAIoAhQgAigCKCgCLEsEQCACKAIoKAIsDAELIAIoAhQLNgIgIAIgAigCKCgCbCACKAIoKAJcazYCGAJAIAIoAhggAigCIEkEQCACKAIYRQRAIAIoAiRBBEcNAgsgAigCJEUNASACKAIoKAIAKAIEDQEgAigCGCACKAIUSw0BCyACAn8gAigCGCACKAIUSwRAIAIoAhQMAQsgAigCGAs2AhwgAgJ/QQAgAigCJEEERw0AGkEAIAIoAigoAgAoAgQNABogAigCHCACKAIYRgtBAXE2AhAgAigCKCACKAIoKAI4IAIoAigoAlxqIAIoAhwgAigCEBBcIAIoAigiACACKAIcIAAoAlxqNgJcIAIoAigoAgAQHAsgAkECQQAgAigCEBs2AiwLIAIoAiwhACACQTBqJAAgAAuyAgEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIEHkEQCABQX42AgwMAQsgASABKAIIKAIcKAIENgIEIAEoAggoAhwoAggEQCABKAIIKAIoIAEoAggoAhwoAgggASgCCCgCJBEEAAsgASgCCCgCHCgCRARAIAEoAggoAiggASgCCCgCHCgCRCABKAIIKAIkEQQACyABKAIIKAIcKAJABEAgASgCCCgCKCABKAIIKAIcKAJAIAEoAggoAiQRBAALIAEoAggoAhwoAjgEQCABKAIIKAIoIAEoAggoAhwoAjggASgCCCgCJBEEAAsgASgCCCgCKCABKAIIKAIcIAEoAggoAiQRBAAgASgCCEEANgIcIAFBfUEAIAEoAgRB8QBGGzYCDAsgASgCDCEAIAFBEGokACAAC+sXAQJ/IwBB8ABrIgMgADYCbCADIAE2AmggAyACNgJkIANBfzYCXCADIAMoAmgvAQI2AlQgA0EANgJQIANBBzYCTCADQQQ2AkggAygCVEUEQCADQYoBNgJMIANBAzYCSAsgA0EANgJgA0AgAygCYCADKAJkSkUEQCADIAMoAlQ2AlggAyADKAJoIAMoAmBBAWpBAnRqLwECNgJUIAMgAygCUEEBaiIANgJQAkACQCADKAJMIABMDQAgAygCWCADKAJURw0ADAELAkAgAygCUCADKAJISARAA0AgAyADKAJsQfwUaiADKAJYQQJ0ai8BAjYCRAJAIAMoAmwoArwtQRAgAygCRGtKBEAgAyADKAJsQfwUaiADKAJYQQJ0ai8BADYCQCADKAJsIgAgAC8BuC0gAygCQEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAJAQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCREEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsQfwUaiADKAJYQQJ0ai8BACADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCRCAAKAK8LWo2ArwtCyADIAMoAlBBAWsiADYCUCAADQALDAELAkAgAygCWARAIAMoAlggAygCXEcEQCADIAMoAmxB/BRqIAMoAlhBAnRqLwECNgI8AkAgAygCbCgCvC1BECADKAI8a0oEQCADIAMoAmxB/BRqIAMoAlhBAnRqLwEANgI4IAMoAmwiACAALwG4LSADKAI4Qf//A3EgAygCbCgCvC10cjsBuC0gAygCbC8BuC1B/wFxIQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbC8BuC1BCHYhASADKAJsKAIIIQIgAygCbCIEKAIUIQAgBCAAQQFqNgIUIAAgAmogAToAACADKAJsIAMoAjhB//8DcUEQIAMoAmwoArwta3U7AbgtIAMoAmwiACAAKAK8LSADKAI8QRBrajYCvC0MAQsgAygCbCIAIAAvAbgtIAMoAmxB/BRqIAMoAlhBAnRqLwEAIAMoAmwoArwtdHI7AbgtIAMoAmwiACADKAI8IAAoArwtajYCvC0LIAMgAygCUEEBazYCUAsgAyADKAJsLwG+FTYCNAJAIAMoAmwoArwtQRAgAygCNGtKBEAgAyADKAJsLwG8FTYCMCADKAJsIgAgAC8BuC0gAygCMEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIwQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCNEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwG8FSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCNCAAKAK8LWo2ArwtCyADQQI2AiwCQCADKAJsKAK8LUEQIAMoAixrSgRAIAMgAygCUEEDazYCKCADKAJsIgAgAC8BuC0gAygCKEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIoQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCLEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQNrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAiwgACgCvC1qNgK8LQsMAQsCQCADKAJQQQpMBEAgAyADKAJsLwHCFTYCJAJAIAMoAmwoArwtQRAgAygCJGtKBEAgAyADKAJsLwHAFTYCICADKAJsIgAgAC8BuC0gAygCIEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIgQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCJEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwHAFSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCJCAAKAK8LWo2ArwtCyADQQM2AhwCQCADKAJsKAK8LUEQIAMoAhxrSgRAIAMgAygCUEEDazYCGCADKAJsIgAgAC8BuC0gAygCGEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIYQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCHEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQNrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAhwgACgCvC1qNgK8LQsMAQsgAyADKAJsLwHGFTYCFAJAIAMoAmwoArwtQRAgAygCFGtKBEAgAyADKAJsLwHEFTYCECADKAJsIgAgAC8BuC0gAygCEEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIQQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCFEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwHEFSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCFCAAKAK8LWo2ArwtCyADQQc2AgwCQCADKAJsKAK8LUEQIAMoAgxrSgRAIAMgAygCUEELazYCCCADKAJsIgAgAC8BuC0gAygCCEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIIQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCDEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQtrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAgwgACgCvC1qNgK8LQsLCwsgA0EANgJQIAMgAygCWDYCXAJAIAMoAlRFBEAgA0GKATYCTCADQQM2AkgMAQsCQCADKAJYIAMoAlRGBEAgA0EGNgJMIANBAzYCSAwBCyADQQc2AkwgA0EENgJICwsLIAMgAygCYEEBajYCYAwBCwsLkQQBAX8jAEEwayIDIAA2AiwgAyABNgIoIAMgAjYCJCADQX82AhwgAyADKAIoLwECNgIUIANBADYCECADQQc2AgwgA0EENgIIIAMoAhRFBEAgA0GKATYCDCADQQM2AggLIAMoAiggAygCJEEBakECdGpB//8DOwECIANBADYCIANAIAMoAiAgAygCJEpFBEAgAyADKAIUNgIYIAMgAygCKCADKAIgQQFqQQJ0ai8BAjYCFCADIAMoAhBBAWoiADYCEAJAAkAgAygCDCAATA0AIAMoAhggAygCFEcNAAwBCwJAIAMoAhAgAygCCEgEQCADKAIsQfwUaiADKAIYQQJ0aiIAIAMoAhAgAC8BAGo7AQAMAQsCQCADKAIYBEAgAygCGCADKAIcRwRAIAMoAiwgAygCGEECdGpB/BRqIgAgAC8BAEEBajsBAAsgAygCLCIAIABBvBVqLwEAQQFqOwG8FQwBCwJAIAMoAhBBCkwEQCADKAIsIgAgAEHAFWovAQBBAWo7AcAVDAELIAMoAiwiACAAQcQVai8BAEEBajsBxBULCwsgA0EANgIQIAMgAygCGDYCHAJAIAMoAhRFBEAgA0GKATYCDCADQQM2AggMAQsCQCADKAIYIAMoAhRGBEAgA0EGNgIMIANBAzYCCAwBCyADQQc2AgwgA0EENgIICwsLIAMgAygCIEEBajYCIAwBCwsLpxIBAn8jAEHQAGsiAyAANgJMIAMgATYCSCADIAI2AkQgA0EANgI4IAMoAkwoAqAtBEADQCADIAMoAkwoAqQtIAMoAjhBAXRqLwEANgJAIAMoAkwoApgtIQAgAyADKAI4IgFBAWo2AjggAyAAIAFqLQAANgI8AkAgAygCQEUEQCADIAMoAkggAygCPEECdGovAQI2AiwCQCADKAJMKAK8LUEQIAMoAixrSgRAIAMgAygCSCADKAI8QQJ0ai8BADYCKCADKAJMIgAgAC8BuC0gAygCKEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIoQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCLEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJIIAMoAjxBAnRqLwEAIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIsIAAoArwtajYCvC0LDAELIAMgAygCPC0A0F02AjQgAyADKAJIIAMoAjRBgQJqQQJ0ai8BAjYCJAJAIAMoAkwoArwtQRAgAygCJGtKBEAgAyADKAJIIAMoAjRBgQJqQQJ0ai8BADYCICADKAJMIgAgAC8BuC0gAygCIEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIgQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCJEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJIIAMoAjRBgQJqQQJ0ai8BACADKAJMKAK8LXRyOwG4LSADKAJMIgAgAygCJCAAKAK8LWo2ArwtCyADIAMoAjRBAnRBkOoAaigCADYCMCADKAIwBEAgAyADKAI8IAMoAjRBAnRBgO0AaigCAGs2AjwgAyADKAIwNgIcAkAgAygCTCgCvC1BECADKAIca0oEQCADIAMoAjw2AhggAygCTCIAIAAvAbgtIAMoAhhB//8DcSADKAJMKAK8LXRyOwG4LSADKAJMLwG4LUH/AXEhASADKAJMKAIIIQIgAygCTCIEKAIUIQAgBCAAQQFqNgIUIAAgAmogAToAACADKAJMLwG4LUEIdiEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwgAygCGEH//wNxQRAgAygCTCgCvC1rdTsBuC0gAygCTCIAIAAoArwtIAMoAhxBEGtqNgK8LQwBCyADKAJMIgAgAC8BuC0gAygCPEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIcIAAoArwtajYCvC0LCyADIAMoAkBBAWs2AkAgAwJ/IAMoAkBBgAJJBEAgAygCQC0A0FkMAQsgAygCQEEHdkGAAmotANBZCzYCNCADIAMoAkQgAygCNEECdGovAQI2AhQCQCADKAJMKAK8LUEQIAMoAhRrSgRAIAMgAygCRCADKAI0QQJ0ai8BADYCECADKAJMIgAgAC8BuC0gAygCEEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIQQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCFEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJEIAMoAjRBAnRqLwEAIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIUIAAoArwtajYCvC0LIAMgAygCNEECdEGQ6wBqKAIANgIwIAMoAjAEQCADIAMoAkAgAygCNEECdEGA7gBqKAIAazYCQCADIAMoAjA2AgwCQCADKAJMKAK8LUEQIAMoAgxrSgRAIAMgAygCQDYCCCADKAJMIgAgAC8BuC0gAygCCEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIIQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCDEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJAQf//A3EgAygCTCgCvC10cjsBuC0gAygCTCIAIAMoAgwgACgCvC1qNgK8LQsLCyADKAI4IAMoAkwoAqAtSQ0ACwsgAyADKAJILwGCCDYCBAJAIAMoAkwoArwtQRAgAygCBGtKBEAgAyADKAJILwGACDYCACADKAJMIgAgAC8BuC0gAygCAEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIAQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCBEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJILwGACCADKAJMKAK8LXRyOwG4LSADKAJMIgAgAygCBCAAKAK8LWo2ArwtCwuXAgEEfyMAQRBrIgEgADYCDAJAIAEoAgwoArwtQRBGBEAgASgCDC8BuC1B/wFxIQIgASgCDCgCCCEDIAEoAgwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAI6AAAgASgCDC8BuC1BCHYhAiABKAIMKAIIIQMgASgCDCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAACABKAIMQQA7AbgtIAEoAgxBADYCvC0MAQsgASgCDCgCvC1BCE4EQCABKAIMLwG4LSECIAEoAgwoAgghAyABKAIMIgQoAhQhACAEIABBAWo2AhQgACADaiACOgAAIAEoAgwiACAALwG4LUEIdjsBuC0gASgCDCIAIAAoArwtQQhrNgK8LQsLC+8BAQR/IwBBEGsiASAANgIMAkAgASgCDCgCvC1BCEoEQCABKAIMLwG4LUH/AXEhAiABKAIMKAIIIQMgASgCDCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAACABKAIMLwG4LUEIdiECIAEoAgwoAgghAyABKAIMIgQoAhQhACAEIABBAWo2AhQgACADaiACOgAADAELIAEoAgwoArwtQQBKBEAgASgCDC8BuC0hAiABKAIMKAIIIQMgASgCDCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAAAsLIAEoAgxBADsBuC0gASgCDEEANgK8LQv8AQEBfyMAQRBrIgEgADYCDCABQQA2AggDQCABKAIIQZ4CTkUEQCABKAIMQZQBaiABKAIIQQJ0akEAOwEAIAEgASgCCEEBajYCCAwBCwsgAUEANgIIA0AgASgCCEEeTkUEQCABKAIMQYgTaiABKAIIQQJ0akEAOwEAIAEgASgCCEEBajYCCAwBCwsgAUEANgIIA0AgASgCCEETTkUEQCABKAIMQfwUaiABKAIIQQJ0akEAOwEAIAEgASgCCEEBajYCCAwBCwsgASgCDEEBOwGUCSABKAIMQQA2AqwtIAEoAgxBADYCqC0gASgCDEEANgKwLSABKAIMQQA2AqAtCyIBAX8jAEEQayIBJAAgASAANgIMIAEoAgwQFSABQRBqJAAL6QEBAX8jAEEwayICIAA2AiQgAiABNwMYIAJCADcDECACIAIoAiQpAwhCAX03AwgCQANAIAIpAxAgAikDCFQEQCACIAIpAxAgAikDCCACKQMQfUIBiHw3AwACQCACKAIkKAIEIAIpAwCnQQN0aikDACACKQMYVgRAIAIgAikDAEIBfTcDCAwBCwJAIAIpAwAgAigCJCkDCFIEQCACKAIkKAIEIAIpAwBCAXynQQN0aikDACACKQMYWA0BCyACIAIpAwA3AygMBAsgAiACKQMAQgF8NwMQCwwBCwsgAiACKQMQNwMoCyACKQMoC6cBAQF/IwBBMGsiBCQAIAQgADYCKCAEIAE2AiQgBCACNwMYIAQgAzYCFCAEIAQoAigpAzggBCgCKCkDMCAEKAIkIAQpAxggBCgCFBCRATcDCAJAIAQpAwhCAFMEQCAEQX82AiwMAQsgBCgCKCAEKQMINwM4IAQoAiggBCgCKCkDOBC/ASECIAQoAiggAjcDQCAEQQA2AiwLIAQoAiwhACAEQTBqJAAgAAvrAQEBfyMAQSBrIgMkACADIAA2AhggAyABNwMQIAMgAjYCDAJAIAMpAxAgAygCGCkDEFQEQCADQQE6AB8MAQsgAyADKAIYKAIAIAMpAxBCBIanEEgiADYCCCAARQRAIAMoAgxBDkEAEBQgA0EAOgAfDAELIAMoAhggAygCCDYCACADIAMoAhgoAgQgAykDEEIBfEIDhqcQSCIANgIEIABFBEAgAygCDEEOQQAQFCADQQA6AB8MAQsgAygCGCADKAIENgIEIAMoAhggAykDEDcDECADQQE6AB8LIAMtAB9BAXEhACADQSBqJAAgAAvOAgEBfyMAQTBrIgQkACAEIAA2AiggBCABNwMgIAQgAjYCHCAEIAM2AhgCQAJAIAQoAigNACAEKQMgUA0AIAQoAhhBEkEAEBQgBEEANgIsDAELIAQgBCgCKCAEKQMgIAQoAhwgBCgCGBBNIgA2AgwgAEUEQCAEQQA2AiwMAQsgBEEYEBgiADYCFCAARQRAIAQoAhhBDkEAEBQgBCgCDBAzIARBADYCLAwBCyAEKAIUIAQoAgw2AhAgBCgCFEEANgIUQQAQASEAIAQoAhQgADYCDCMAQRBrIgAgBCgCFDYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCAEQQIgBCgCFCAEKAIYEJQBIgA2AhAgAEUEQCAEKAIUKAIQEDMgBCgCFBAVIARBADYCLAwBCyAEIAQoAhA2AiwLIAQoAiwhACAEQTBqJAAgAAupAQEBfyMAQTBrIgQkACAEIAA2AiggBCABNwMgIAQgAjYCHCAEIAM2AhgCQCAEKAIoRQRAIAQpAyBCAFIEQCAEKAIYQRJBABAUIARBADYCLAwCCyAEQQBCACAEKAIcIAQoAhgQwgE2AiwMAQsgBCAEKAIoNgIIIAQgBCkDIDcDECAEIARBCGpCASAEKAIcIAQoAhgQwgE2AiwLIAQoAiwhACAEQTBqJAAgAAtGAQF/IwBBIGsiAyQAIAMgADYCHCADIAE3AxAgAyACNgIMIAMoAhwgAykDECADKAIMIAMoAhxBCGoQTiEAIANBIGokACAAC40CAQF/IwBBMGsiAyQAIAMgADYCKCADIAE7ASYgAyACNgIgIAMgAygCKCgCNCADQR5qIAMvASZBgAZBABBfNgIQAkAgAygCEEUNACADLwEeQQVJDQACQCADKAIQLQAAQQFGDQAMAQsgAyADKAIQIAMvAR6tECkiADYCFCAARQRADAELIAMoAhQQjwEaIAMgAygCFBAqNgIYIAMoAiAQjAEgAygCGEYEQCADIAMoAhQQLz0BDiADIAMoAhQgAy8BDq0QHiADLwEOQYAQQQAQUjYCCCADKAIIBEAgAygCIBAlIAMgAygCCDYCIAsLIAMoAhQQFgsgAyADKAIgNgIsIAMoAiwhACADQTBqJAAgAAvaFwIBfwF+IwBBgAFrIgUkACAFIAA2AnQgBSABNgJwIAUgAjYCbCAFIAM6AGsgBSAENgJkIAUgBSgCbEEARzoAHSAFQR5BLiAFLQBrQQFxGzYCKAJAAkAgBSgCbARAIAUoAmwQLyAFKAIorVQEQCAFKAJkQRNBABAUIAVCfzcDeAwDCwwBCyAFIAUoAnAgBSgCKK0gBUEwaiAFKAJkEEEiADYCbCAARQRAIAVCfzcDeAwCCwsgBSgCbEIEEB4hAEHxEkH2EiAFLQBrQQFxGygAACAAKAAARwRAIAUoAmRBE0EAEBQgBS0AHUEBcUUEQCAFKAJsEBYLIAVCfzcDeAwBCyAFKAJ0EE8CQCAFLQBrQQFxRQRAIAUoAmwQHSEAIAUoAnQgADsBCAwBCyAFKAJ0QQA7AQgLIAUoAmwQHSEAIAUoAnQgADsBCiAFKAJsEB0hACAFKAJ0IAA7AQwgBSgCbBAdQf//A3EhACAFKAJ0IAA2AhAgBSAFKAJsEB07AS4gBSAFKAJsEB07ASwgBS8BLiEBIAUvASwhAiMAQTBrIgAkACAAIAE7AS4gACACOwEsIABCADcCACAAQQA2AiggAEIANwIgIABCADcCGCAAQgA3AhAgAEIANwIIIABBADYCICAAIAAvASxBCXZB0ABqNgIUIAAgAC8BLEEFdkEPcUEBazYCECAAIAAvASxBH3E2AgwgACAALwEuQQt2NgIIIAAgAC8BLkEFdkE/cTYCBCAAIAAvAS5BAXRBPnE2AgAgABAMIQEgAEEwaiQAIAEhACAFKAJ0IAA2AhQgBSgCbBAqIQAgBSgCdCAANgIYIAUoAmwQKq0hBiAFKAJ0IAY3AyAgBSgCbBAqrSEGIAUoAnQgBjcDKCAFIAUoAmwQHTsBIiAFIAUoAmwQHTsBHgJAIAUtAGtBAXEEQCAFQQA7ASAgBSgCdEEANgI8IAUoAnRBADsBQCAFKAJ0QQA2AkQgBSgCdEIANwNIDAELIAUgBSgCbBAdOwEgIAUoAmwQHUH//wNxIQAgBSgCdCAANgI8IAUoAmwQHSEAIAUoAnQgADsBQCAFKAJsECohACAFKAJ0IAA2AkQgBSgCbBAqrSEGIAUoAnQgBjcDSAsCfyMAQRBrIgAgBSgCbDYCDCAAKAIMLQAAQQFxRQsEQCAFKAJkQRRBABAUIAUtAB1BAXFFBEAgBSgCbBAWCyAFQn83A3gMAQsCQCAFKAJ0LwEMQQFxBEAgBSgCdC8BDEHAAHEEQCAFKAJ0Qf//AzsBUgwCCyAFKAJ0QQE7AVIMAQsgBSgCdEEAOwFSCyAFKAJ0QQA2AjAgBSgCdEEANgI0IAUoAnRBADYCOCAFIAUvASAgBS8BIiAFLwEeamo2AiQCQCAFLQAdQQFxBEAgBSgCbBAvIAUoAiStVARAIAUoAmRBFUEAEBQgBUJ/NwN4DAMLDAELIAUoAmwQFiAFIAUoAnAgBSgCJK1BACAFKAJkEEEiADYCbCAARQRAIAVCfzcDeAwCCwsgBS8BIgRAIAUoAmwgBSgCcCAFLwEiQQEgBSgCZBCNASEAIAUoAnQgADYCMCAFKAJ0KAIwRQRAAn8jAEEQayIAIAUoAmQ2AgwgACgCDCgCAEERRgsEQCAFKAJkQRVBABAUCyAFLQAdQQFxRQRAIAUoAmwQFgsgBUJ/NwN4DAILIAUoAnQvAQxBgBBxBEAgBSgCdCgCMEECEDpBBUYEQCAFKAJkQRVBABAUIAUtAB1BAXFFBEAgBSgCbBAWCyAFQn83A3gMAwsLCyAFLwEeBEAgBSAFKAJsIAUoAnAgBS8BHkEAIAUoAmQQYDYCGCAFKAIYRQRAIAUtAB1BAXFFBEAgBSgCbBAWCyAFQn83A3gMAgsgBSgCGCAFLwEeQYACQYAEIAUtAGtBAXEbIAUoAnRBNGogBSgCZBCIAUEBcUUEQCAFKAIYEBUgBS0AHUEBcUUEQCAFKAJsEBYLIAVCfzcDeAwCCyAFKAIYEBUgBS0Aa0EBcQRAIAUoAnRBAToABAsLIAUvASAEQCAFKAJsIAUoAnAgBS8BIEEAIAUoAmQQjQEhACAFKAJ0IAA2AjggBSgCdCgCOEUEQCAFLQAdQQFxRQRAIAUoAmwQFgsgBUJ/NwN4DAILIAUoAnQvAQxBgBBxBEAgBSgCdCgCOEECEDpBBUYEQCAFKAJkQRVBABAUIAUtAB1BAXFFBEAgBSgCbBAWCyAFQn83A3gMAwsLCyAFKAJ0QfXgASAFKAJ0KAIwEMUBIQAgBSgCdCAANgIwIAUoAnRB9cYBIAUoAnQoAjgQxQEhACAFKAJ0IAA2AjgCQAJAIAUoAnQpAyhC/////w9RDQAgBSgCdCkDIEL/////D1ENACAFKAJ0KQNIQv////8PUg0BCyAFIAUoAnQoAjQgBUEWakEBQYACQYAEIAUtAGtBAXEbIAUoAmQQXzYCDCAFKAIMRQRAIAUtAB1BAXFFBEAgBSgCbBAWCyAFQn83A3gMAgsgBSAFKAIMIAUvARatECkiADYCECAARQRAIAUoAmRBDkEAEBQgBS0AHUEBcUUEQCAFKAJsEBYLIAVCfzcDeAwCCwJAIAUoAnQpAyhC/////w9RBEAgBSgCEBAwIQYgBSgCdCAGNwMoDAELIAUtAGtBAXEEQCAFKAIQIQEjAEEgayIAJAAgACABNgIYIABCCDcDECAAIAAoAhgpAxAgACkDEHw3AwgCQCAAKQMIIAAoAhgpAxBUBEAgACgCGEEAOgAAIABBfzYCHAwBCyAAIAAoAhggACkDCBAsNgIcCyAAKAIcGiAAQSBqJAALCyAFKAJ0KQMgQv////8PUQRAIAUoAhAQMCEGIAUoAnQgBjcDIAsgBS0Aa0EBcUUEQCAFKAJ0KQNIQv////8PUQRAIAUoAhAQMCEGIAUoAnQgBjcDSAsgBSgCdCgCPEH//wNGBEAgBSgCEBAqIQAgBSgCdCAANgI8CwsgBSgCEBBHQQFxRQRAIAUoAmRBFUEAEBQgBSgCEBAWIAUtAB1BAXFFBEAgBSgCbBAWCyAFQn83A3gMAgsgBSgCEBAWCwJ/IwBBEGsiACAFKAJsNgIMIAAoAgwtAABBAXFFCwRAIAUoAmRBFEEAEBQgBS0AHUEBcUUEQCAFKAJsEBYLIAVCfzcDeAwBCyAFLQAdQQFxRQRAIAUoAmwQFgsgBSgCdCkDSEL///////////8AVgRAIAUoAmRBBEEWEBQgBUJ/NwN4DAELAn8gBSgCdCEBIAUoAmQhAiMAQSBrIgAkACAAIAE2AhggACACNgIUAkAgACgCGCgCEEHjAEcEQCAAQQE6AB8MAQsgACAAKAIYKAI0IABBEmpBgbICQYAGQQAQXzYCCAJAIAAoAggEQCAALwESQQdPDQELIAAoAhRBFUEAEBQgAEEAOgAfDAELIAAgACgCCCAALwESrRApIgE2AgwgAUUEQCAAKAIUQRRBABAUIABBADoAHwwBCyAAQQE6AAcCQAJAAkAgACgCDBAdQQFrDgICAAELIAAoAhgpAyhCFFQEQCAAQQA6AAcLDAELIAAoAhRBGEEAEBQgACgCDBAWIABBADoAHwwBCyAAKAIMQgIQHi8AAEHBigFHBEAgACgCFEEYQQAQFCAAKAIMEBYgAEEAOgAfDAELAkACQAJAAkACQCAAKAIMEI8BQQFrDgMAAQIDCyAAQYECOwEEDAMLIABBggI7AQQMAgsgAEGDAjsBBAwBCyAAKAIUQRhBABAUIAAoAgwQFiAAQQA6AB8MAQsgAC8BEkEHRwRAIAAoAhRBFUEAEBQgACgCDBAWIABBADoAHwwBCyAAKAIYIAAtAAdBAXE6AAYgACgCGCAALwEEOwFSIAAoAgwQHUH//wNxIQEgACgCGCABNgIQIAAoAgwQFiAAQQE6AB8LIAAtAB9BAXEhASAAQSBqJAAgAUEBcUULBEAgBUJ/NwN4DAELIAUoAnQoAjQQhwEhACAFKAJ0IAA2AjQgBSAFKAIoIAUoAiRqrTcDeAsgBSkDeCEGIAVBgAFqJAAgBgsYAEGomwFCADcCAEGwmwFBADYCAEGomwELCABBAUEMEHYLBwAgACgCLAsHACAAKAIoCwcAIAAoAhgLtQkBAX8jAEHgwABrIgUkACAFIAA2AtRAIAUgATYC0EAgBSACNgLMQCAFIAM3A8BAIAUgBDYCvEAgBSAFKALQQDYCuEACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBSgCvEAOEQMEAAYBAgUJCgoKCgoKCAoHCgsgBUIANwPYQAwKCyAFIAUoArhAQeQAaiAFKALMQCAFKQPAQBBCNwPYQAwJCyAFKAK4QBAVIAVCADcD2EAMCAsgBSgCuEAoAhAEQCAFIAUoArhAKAIQIAUoArhAKQMYIAUoArhAQeQAahBlIgM3A5hAIANQBEAgBUJ/NwPYQAwJCyAFKAK4QCkDCCAFKAK4QCkDCCAFKQOYQHxWBEAgBSgCuEBB5ABqQRVBABAUIAVCfzcD2EAMCQsgBSgCuEAiACAFKQOYQCAAKQMAfDcDACAFKAK4QCIAIAUpA5hAIAApAwh8NwMIIAUoArhAQQA2AhALIAUoArhALQB4QQFxRQRAIAVCADcDqEADQCAFKQOoQCAFKAK4QCkDAFQEQCAFIAUoArhAKQMAIAUpA6hAfUKAwABWBH5CgMAABSAFKAK4QCkDACAFKQOoQH0LNwOgQCAFIAUoAtRAIAVBEGogBSkDoEAQLiIDNwOwQCADQgBTBEAgBSgCuEBB5ABqIAUoAtRAEBcgBUJ/NwPYQAwLCyAFKQOwQFAEQCAFKAK4QEHkAGpBEUEAEBQgBUJ/NwPYQAwLBSAFIAUpA7BAIAUpA6hAfDcDqEAMAgsACwsLIAUoArhAIAUoArhAKQMANwMgIAVCADcD2EAMBwsgBSkDwEAgBSgCuEApAwggBSgCuEApAyB9VgRAIAUgBSgCuEApAwggBSgCuEApAyB9NwPAQAsgBSkDwEBQBEAgBUIANwPYQAwHCyAFKAK4QC0AeEEBcQRAIAUoAtRAIAUoArhAKQMgQQAQJ0EASARAIAUoArhAQeQAaiAFKALUQBAXIAVCfzcD2EAMCAsLIAUgBSgC1EAgBSgCzEAgBSkDwEAQLiIDNwOwQCADQgBTBEAgBSgCuEBB5ABqQRFBABAUIAVCfzcD2EAMBwsgBSgCuEAiACAFKQOwQCAAKQMgfDcDICAFKQOwQFAEQCAFKAK4QCkDICAFKAK4QCkDCFQEQCAFKAK4QEHkAGpBEUEAEBQgBUJ/NwPYQAwICwsgBSAFKQOwQDcD2EAMBgsgBSAFKAK4QCkDICAFKAK4QCkDAH0gBSgCuEApAwggBSgCuEApAwB9IAUoAsxAIAUpA8BAIAUoArhAQeQAahCRATcDCCAFKQMIQgBTBEAgBUJ/NwPYQAwGCyAFKAK4QCAFKQMIIAUoArhAKQMAfDcDICAFQgA3A9hADAULIAUgBSgCzEA2AgQgBSgCBCAFKAK4QEEoaiAFKAK4QEHkAGoQlQFBAEgEQCAFQn83A9hADAULIAVCADcD2EAMBAsgBSAFKAK4QCwAYKw3A9hADAMLIAUgBSgCuEApA3A3A9hADAILIAUgBSgCuEApAyAgBSgCuEApAwB9NwPYQAwBCyAFKAK4QEHkAGpBHEEAEBQgBUJ/NwPYQAsgBSkD2EAhAyAFQeDAAGokACADCwcAIAAoAhALIgEBfyMAQRBrIgEgADYCDCABKAIMIgAgACgCMEEBajYCMAsHACAAKAIICxQAIAAgAa0gAq1CIIaEIAMgBBB/CxMBAX4gABBKIgFCIIinEAAgAacLEgAgACABrSACrUIghoQgAxAnCx8BAX4gACABIAKtIAOtQiCGhBAuIgRCIIinEAAgBKcLFQAgACABrSACrUIghoQgAyAEEMMBCxQAIAAgASACrSADrUIghoQgBBB+C60EAQF/IwBBIGsiBSQAIAUgADYCGCAFIAGtIAKtQiCGhDcDECAFIAM2AgwgBSAENgIIAkACQCAFKQMQIAUoAhgpAzBUBEAgBSgCCEEJTQ0BCyAFKAIYQQhqQRJBABAUIAVBfzYCHAwBCyAFKAIYKAIYQQJxBEAgBSgCGEEIakEZQQAQFCAFQX82AhwMAQsCfyAFKAIMIQEjAEEQayIAJAAgACABNgIIIABBAToABwJAIAAoAghFBEAgAEEBOgAPDAELIAAgACgCCCAALQAHQQFxELMBQQBHOgAPCyAALQAPQQFxIQEgAEEQaiQAIAFFCwRAIAUoAhhBCGpBEEEAEBQgBUF/NgIcDAELIAUgBSgCGCgCQCAFKQMQp0EEdGo2AgQgBSAFKAIEKAIABH8gBSgCBCgCACgCEAVBfws2AgACQCAFKAIMIAUoAgBGBEAgBSgCBCgCBARAIAUoAgQoAgQiACAAKAIAQX5xNgIAIAUoAgQoAgRBADsBUCAFKAIEKAIEKAIARQRAIAUoAgQoAgQQOSAFKAIEQQA2AgQLCwwBCyAFKAIEKAIERQRAIAUoAgQoAgAQPyEAIAUoAgQgADYCBCAARQRAIAUoAhhBCGpBDkEAEBQgBUF/NgIcDAMLCyAFKAIEKAIEIAUoAgw2AhAgBSgCBCgCBCAFKAIIOwFQIAUoAgQoAgQiACAAKAIAQQFyNgIACyAFQQA2AhwLIAUoAhwhACAFQSBqJAAgAAsXAQF+IAAgASACEHMiA0IgiKcQACADpwuuAQIBfwF+An8jAEEgayICIAA2AhQgAiABNgIQAkAgAigCFEUEQCACQn83AxgMAQsgAigCEEEIcQRAIAIgAigCFCkDMDcDCANAIAIpAwhCAFIEfyACKAIUKAJAIAIpAwhCAX2nQQR0aigCAAVBAQtFBEAgAiACKQMIQgF9NwMIDAELCyACIAIpAwg3AxgMAQsgAiACKAIUKQMwNwMYCyACKQMYIgNCIIinCxAAIAOnCxMAIAAgAa0gAq1CIIaEIAMQxAELiAICAX8BfgJ/IwBBIGsiBCQAIAQgADYCFCAEIAE2AhAgBCACrSADrUIghoQ3AwgCQCAEKAIURQRAIARCfzcDGAwBCyAEKAIUKAIEBEAgBEJ/NwMYDAELIAQpAwhC////////////AFYEQCAEKAIUQQRqQRJBABAUIARCfzcDGAwBCwJAIAQoAhQtABBBAXFFBEAgBCkDCFBFDQELIARCADcDGAwBCyAEIAQoAhQoAhQgBCgCECAEKQMIEC4iBTcDACAFQgBTBEAgBCgCFEEEaiAEKAIUKAIUEBcgBEJ/NwMYDAELIAQgBCkDADcDGAsgBCkDGCEFIARBIGokACAFQiCIpwsQACAFpwtPAQF/IwBBIGsiBCQAIAQgADYCHCAEIAGtIAKtQiCGhDcDECAEIAM2AgwgBCgCHCAEKQMQIAQoAgwgBCgCHCgCHBCtASEAIARBIGokACAAC9kDAQF/IwBBIGsiBSQAIAUgADYCGCAFIAGtIAKtQiCGhDcDECAFIAM2AgwgBSAENgIIAkAgBSgCGCAFKQMQQQBBABBFRQRAIAVBfzYCHAwBCyAFKAIYKAIYQQJxBEAgBSgCGEEIakEZQQAQFCAFQX82AhwMAQsgBSgCGCgCQCAFKQMQp0EEdGooAggEQCAFKAIYKAJAIAUpAxCnQQR0aigCCCAFKAIMEGhBAEgEQCAFKAIYQQhqQQ9BABAUIAVBfzYCHAwCCyAFQQA2AhwMAQsgBSAFKAIYKAJAIAUpAxCnQQR0ajYCBCAFIAUoAgQoAgAEfyAFKAIMIAUoAgQoAgAoAhRHBUEBC0EBcTYCAAJAIAUoAgAEQCAFKAIEKAIERQRAIAUoAgQoAgAQPyEAIAUoAgQgADYCBCAARQRAIAUoAhhBCGpBDkEAEBQgBUF/NgIcDAQLCyAFKAIEKAIEIAUoAgw2AhQgBSgCBCgCBCIAIAAoAgBBIHI2AgAMAQsgBSgCBCgCBARAIAUoAgQoAgQiACAAKAIAQV9xNgIAIAUoAgQoAgQoAgBFBEAgBSgCBCgCBBA5IAUoAgRBADYCBAsLCyAFQQA2AhwLIAUoAhwhACAFQSBqJAAgAAsXACAAIAGtIAKtQiCGhCADIAQgBRCZAQsXACAAIAGtIAKtQiCGhCADIAQgBRCXAQuPAQIBfwF+An8jAEEgayIEJAAgBCAANgIUIAQgATYCECAEIAI2AgwgBCADNgIIAkACQCAEKAIQBEAgBCgCDA0BCyAEKAIUQQhqQRJBABAUIARCfzcDGAwBCyAEIAQoAhQgBCgCECAEKAIMIAQoAggQmgE3AxgLIAQpAxghBSAEQSBqJAAgBUIgiKcLEAAgBacLiAEBAX8jAEEQayICJAAgAiAANgIMIAIgATYCCCMAQRBrIgAgAigCDDYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCACKAIMIAIoAgg2AgACQCACKAIMEJYBQQFGBEAgAigCDEG0mwEoAgA2AgQMAQsgAigCDEEANgIECyACQRBqJAALhQUCAX8BfgJ/IwBBMGsiAyQAIAMgADYCJCADIAE2AiAgAyACNgIcAkAgAygCJCgCGEECcQRAIAMoAiRBCGpBGUEAEBQgA0J/NwMoDAELIAMoAiBFBEAgAygCJEEIakESQQAQFCADQn83AygMAQsgA0EANgIMIAMgAygCIBArNgIYIAMoAiAgAygCGEEBa2osAABBL0cEQCADIAMoAhhBAmoQGCIANgIMIABFBEAgAygCJEEIakEOQQAQFCADQn83AygMAgsCQAJAIAMoAgwiASADKAIgIgBzQQNxDQAgAEEDcQRAA0AgASAALQAAIgI6AAAgAkUNAyABQQFqIQEgAEEBaiIAQQNxDQALCyAAKAIAIgJBf3MgAkGBgoQIa3FBgIGChHhxDQADQCABIAI2AgAgACgCBCECIAFBBGohASAAQQRqIQAgAkGBgoQIayACQX9zcUGAgYKEeHFFDQALCyABIAAtAAAiAjoAACACRQ0AA0AgASAALQABIgI6AAEgAUEBaiEBIABBAWohACACDQALCyADKAIMIAMoAhhqQS86AAAgAygCDCADKAIYQQFqakEAOgAACyADIAMoAiRBAEIAQQAQfiIANgIIIABFBEAgAygCDBAVIANCfzcDKAwBCyADIAMoAiQCfyADKAIMBEAgAygCDAwBCyADKAIgCyADKAIIIAMoAhwQmgE3AxAgAygCDBAVAkAgAykDEEIAUwRAIAMoAggQGwwBCyADKAIkIAMpAxBBAEEDQYCA/I8EEJkBQQBIBEAgAygCJCADKQMQEJgBGiADQn83AygMAgsLIAMgAykDEDcDKAsgAykDKCEEIANBMGokACAEQiCIpwsQACAEpwsRACAAIAGtIAKtQiCGhBCYAQt/AgF/AX4jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADKAIYIAMoAhQgAygCEBBzIgQ3AwgCQCAEQgBTBEAgA0EANgIcDAELIAMgAygCGCADKQMIIAMoAhAgAygCGCgCHBCtATYCHAsgAygCHCEAIANBIGokACAAC8QBAQF/IwBBMGsiASQAIAEgADYCKCABQQA2AiQgAUIANwMYAkADQCABKQMYIAEoAigpAzBUBEAgASABKAIoIAEpAxhBACABQRdqIAFBEGoQlwE2AgwgASgCDEF/RgRAIAFBfzYCLAwDBQJAIAEtABdBA0cNACABKAIQQRB2QYDgA3FBgMACRw0AIAEgASgCJEEBajYCJAsgASABKQMYQgF8NwMYDAILAAsLIAEgASgCJDYCLAsgASgCLCEAIAFBMGokACAACxAAIwAgAGtBcHEiACQAIAALBgAgACQACwQAIwALggECAX8BfiMAQSBrIgQkACAEIAA2AhggBCABNgIUIAQgAjYCECAEIAM2AgwgBCAEKAIYIAQoAhQgBCgCEBBzIgU3AwACQCAFQgBTBEAgBEF/NgIcDAELIAQgBCgCGCAEKQMAIAQoAhAgBCgCDBB/NgIcCyAEKAIcIQAgBEEgaiQAIAAL0EUDBn8BfgJ8IwBB4ABrIgEkACABIAA2AlgCQCABKAJYRQRAIAFBfzYCXAwBCyMAQSBrIgAgASgCWDYCHCAAIAFBQGs2AhggAEEANgIUIABCADcDAAJAIAAoAhwtAChBAXFFBEAgACgCHCgCGCAAKAIcKAIURg0BCyAAQQE2AhQLIABCADcDCANAIAApAwggACgCHCkDMFQEQAJAAkAgACgCHCgCQCAAKQMIp0EEdGooAggNACAAKAIcKAJAIAApAwinQQR0ai0ADEEBcQ0AIAAoAhwoAkAgACkDCKdBBHRqKAIERQ0BIAAoAhwoAkAgACkDCKdBBHRqKAIEKAIARQ0BCyAAQQE2AhQLIAAoAhwoAkAgACkDCKdBBHRqLQAMQQFxRQRAIAAgACkDAEIBfDcDAAsgACAAKQMIQgF8NwMIDAELCyAAKAIYBEAgACgCGCAAKQMANwMACyABIAAoAhQ2AiQgASkDQFAEQAJAIAEoAlgoAgRBCHFFBEAgASgCJEUNAQsCfyABKAJYKAIAIQIjAEEQayIAJAAgACACNgIIAkAgACgCCCgCJEEDRgRAIABBADYCDAwBCyAAKAIIKAIgBEAgACgCCBAxQQBIBEAgAEF/NgIMDAILCyAAKAIIKAIkBEAgACgCCBBnCyAAKAIIQQBCAEEPECFCAFMEQCAAQX82AgwMAQsgACgCCEEDNgIkIABBADYCDAsgACgCDCECIABBEGokACACQQBICwRAAkACfyMAQRBrIgAgASgCWCgCADYCDCMAQRBrIgIgACgCDEEMajYCDCACKAIMKAIAQRZGCwRAIwBBEGsiACABKAJYKAIANgIMIwBBEGsiAiAAKAIMQQxqNgIMIAIoAgwoAgRBLEYNAQsgASgCWEEIaiABKAJYKAIAEBcgAUF/NgJcDAQLCwsgASgCWBA9IAFBADYCXAwBCyABKAIkRQRAIAEoAlgQPSABQQA2AlwMAQsgASkDQCABKAJYKQMwVgRAIAEoAlhBCGpBFEEAEBQgAUF/NgJcDAELIAEgASkDQKdBA3QQGCIANgIoIABFBEAgAUF/NgJcDAELIAFCfzcDOCABQgA3A0ggAUIANwNQA0AgASkDUCABKAJYKQMwVARAAkAgASgCWCgCQCABKQNQp0EEdGooAgBFDQACQCABKAJYKAJAIAEpA1CnQQR0aigCCA0AIAEoAlgoAkAgASkDUKdBBHRqLQAMQQFxDQAgASgCWCgCQCABKQNQp0EEdGooAgRFDQEgASgCWCgCQCABKQNQp0EEdGooAgQoAgBFDQELIAECfiABKQM4IAEoAlgoAkAgASkDUKdBBHRqKAIAKQNIVARAIAEpAzgMAQsgASgCWCgCQCABKQNQp0EEdGooAgApA0gLNwM4CyABKAJYKAJAIAEpA1CnQQR0ai0ADEEBcUUEQCABKQNIIAEpA0BaBEAgASgCKBAVIAEoAlhBCGpBFEEAEBQgAUF/NgJcDAQLIAEoAiggASkDSKdBA3RqIAEpA1A3AwAgASABKQNIQgF8NwNICyABIAEpA1BCAXw3A1AMAQsLIAEpA0ggASkDQFQEQCABKAIoEBUgASgCWEEIakEUQQAQFCABQX82AlwMAQsCQAJ/IwBBEGsiACABKAJYKAIANgIMIAAoAgwpAxhCgIAIg1ALBEAgAUIANwM4DAELIAEpAzhCf1EEQCABQn83AxggAUIANwM4IAFCADcDUANAIAEpA1AgASgCWCkDMFQEQCABKAJYKAJAIAEpA1CnQQR0aigCAARAIAEoAlgoAkAgASkDUKdBBHRqKAIAKQNIIAEpAzhaBEAgASABKAJYKAJAIAEpA1CnQQR0aigCACkDSDcDOCABIAEpA1A3AxgLCyABIAEpA1BCAXw3A1AMAQsLIAEpAxhCf1IEQCABKAJYIQIgASkDGCEHIAEoAlhBCGohAyMAQTBrIgAkACAAIAI2AiQgACAHNwMYIAAgAzYCFCAAIAAoAiQgACkDGCAAKAIUEGUiBzcDCAJAIAdQBEAgAEIANwMoDAELIAAgACgCJCgCQCAAKQMYp0EEdGooAgA2AgQCQCAAKQMIIAApAwggACgCBCkDIHxYBEAgACkDCCAAKAIEKQMgfEL///////////8AWA0BCyAAKAIUQQRBFhAUIABCADcDKAwBCyAAIAAoAgQpAyAgACkDCHw3AwggACgCBC8BDEEIcQRAIAAoAiQoAgAgACkDCEEAECdBAEgEQCAAKAIUIAAoAiQoAgAQFyAAQgA3AygMAgsgACgCJCgCACAAQgQQLkIEUgRAIAAoAhQgACgCJCgCABAXIABCADcDKAwCCyAAKAAAQdCWncAARgRAIAAgACkDCEIEfDcDCAsgACAAKQMIQgx8NwMIIAAoAgRBABBeQQFxBEAgACAAKQMIQgh8NwMICyAAKQMIQv///////////wBWBEAgACgCFEEEQRYQFCAAQgA3AygMAgsLIAAgACkDCDcDKAsgACkDKCEHIABBMGokACABIAc3AzggB1AEQCABKAIoEBUgAUF/NgJcDAQLCwsgASkDOEIAUgRAAn8gASgCWCgCACECIAEpAzghByMAQRBrIgAkACAAIAI2AgggACAHNwMAAkAgACgCCCgCJEEBRgRAIAAoAghBDGpBEkEAEBQgAEF/NgIMDAELIAAoAghBACAAKQMAQREQIUIAUwRAIABBfzYCDAwBCyAAKAIIQQE2AiQgAEEANgIMCyAAKAIMIQIgAEEQaiQAIAJBAEgLBEAgAUIANwM4CwsLIAEpAzhQBEACfyABKAJYKAIAIQIjAEEQayIAJAAgACACNgIIAkAgACgCCCgCJEEBRgRAIAAoAghBDGpBEkEAEBQgAEF/NgIMDAELIAAoAghBAEIAQQgQIUIAUwRAIABBfzYCDAwBCyAAKAIIQQE2AiQgAEEANgIMCyAAKAIMIQIgAEEQaiQAIAJBAEgLBEAgASgCWEEIaiABKAJYKAIAEBcgASgCKBAVIAFBfzYCXAwCCwsgASgCWCgCVCECIwBBEGsiACQAIAAgAjYCDCAAKAIMBEAgACgCDEQAAAAAAAAAADkDGCAAKAIMKAIARAAAAAAAAAAAIAAoAgwoAgwgACgCDCgCBBEWAAsgAEEQaiQAIAFBADYCLCABQgA3A0gDQAJAIAEpA0ggASkDQFoNACABKAJYKAJUIQIgASkDSCIHuiABKQNAuiIIoyEJIwBBIGsiACQAIAAgAjYCHCAAIAk5AxAgACAHQgF8uiAIozkDCCAAKAIcBEAgACgCHCAAKwMQOQMgIAAoAhwgACsDCDkDKCAAKAIcRAAAAAAAAAAAEFYLIABBIGokACABIAEoAiggASkDSKdBA3RqKQMANwNQIAEgASgCWCgCQCABKQNQp0EEdGo2AhACQAJAIAEoAhAoAgBFDQAgASgCECgCACkDSCABKQM4Wg0ADAELIAECf0EBIAEoAhAoAggNABogASgCECgCBARAQQEgASgCECgCBCgCAEEBcQ0BGgsgASgCECgCBAR/IAEoAhAoAgQoAgBBwABxQQBHBUEACwtBAXE2AhQgASgCECgCBEUEQCABKAIQKAIAED8hACABKAIQIAA2AgQgAEUEQCABKAJYQQhqQQ5BABAUIAFBATYCLAwDCwsgASABKAIQKAIENgIMAn8gASgCWCECIAEpA1AhByMAQTBrIgAkACAAIAI2AiggACAHNwMgAkAgACkDICAAKAIoKQMwWgRAIAAoAihBCGpBEkEAEBQgAEF/NgIsDAELIAAgACgCKCgCQCAAKQMgp0EEdGo2AhwCQCAAKAIcKAIABEAgACgCHCgCAC0ABEEBcUUNAQsgAEEANgIsDAELIAAoAhwoAgApA0hCGnxC////////////AFYEQCAAKAIoQQhqQQRBFhAUIABBfzYCLAwBCyAAKAIoKAIAIAAoAhwoAgApA0hCGnxBABAnQQBIBEAgACgCKEEIaiAAKAIoKAIAEBcgAEF/NgIsDAELIAAgACgCKCgCAEIEIABBGGogACgCKEEIahBBIgI2AhQgAkUEQCAAQX82AiwMAQsgACAAKAIUEB07ARIgACAAKAIUEB07ARAgACgCFBBHQQFxRQRAIAAoAhQQFiAAKAIoQQhqQRRBABAUIABBfzYCLAwBCyAAKAIUEBYgAC8BEARAIAAoAigoAgAgAC8BEq1BARAnQQBIBEAgACgCKEEIakEEQbSbASgCABAUIABBfzYCLAwCCyAAQQAgACgCKCgCACAALwEQQQAgACgCKEEIahBgNgIIIAAoAghFBEAgAEF/NgIsDAILIAAoAgggAC8BEEGAAiAAQQxqIAAoAihBCGoQiAFBAXFFBEAgACgCCBAVIABBfzYCLAwCCyAAKAIIEBUgACgCDARAIAAgACgCDBCHATYCDCAAKAIcKAIAKAI0IAAoAgwQiQEhAiAAKAIcKAIAIAI2AjQLCyAAKAIcKAIAQQE6AAQCQCAAKAIcKAIERQ0AIAAoAhwoAgQtAARBAXENACAAKAIcKAIEIAAoAhwoAgAoAjQ2AjQgACgCHCgCBEEBOgAECyAAQQA2AiwLIAAoAiwhAiAAQTBqJAAgAkEASAsEQCABQQE2AiwMAgsgASABKAJYKAIAEDQiBzcDMCAHQgBTBEAgAUEBNgIsDAILIAEoAgwgASkDMDcDSAJAIAEoAhQEQCABQQA2AgggASgCECgCCEUEQCABIAEoAlggASgCWCABKQNQQQhBABCuASIANgIIIABFBEAgAUEBNgIsDAULCwJ/IAEoAlghAgJ/IAEoAggEQCABKAIIDAELIAEoAhAoAggLIQMgASgCDCEEIwBBoAFrIgAkACAAIAI2ApgBIAAgAzYClAEgACAENgKQAQJAIAAoApQBIABBOGoQOEEASARAIAAoApgBQQhqIAAoApQBEBcgAEF/NgKcAQwBCyAAKQM4QsAAg1AEQCAAIAApAzhCwACENwM4IABBADsBaAsCQAJAIAAoApABKAIQQX9HBEAgACgCkAEoAhBBfkcNAQsgAC8BaEUNACAAKAKQASAALwFoNgIQDAELAkACQCAAKAKQASgCEA0AIAApAzhCBINQDQAgACAAKQM4QgiENwM4IAAgACkDUDcDWAwBCyAAIAApAzhC9////w+DNwM4CwsgACkDOEKAAYNQBEAgACAAKQM4QoABhDcDOCAAQQA7AWoLIABBgAI2AiQCQCAAKQM4QgSDUARAIAAgACgCJEGACHI2AiQgAEJ/NwNwDAELIAAoApABIAApA1A3AyggACAAKQNQNwNwAkAgACkDOEIIg1AEQAJAAkACQAJAAkACfwJAIAAoApABKAIQQX9HBEAgACgCkAEoAhBBfkcNAQtBCAwBCyAAKAKQASgCEAtB//8DcQ4NAgMDAwMDAwMBAwMDAAMLIABClMLk8w83AxAMAwsgAEKDg7D/DzcDEAwCCyAAQv////8PNwMQDAELIABCADcDEAsgACkDUCAAKQMQVgRAIAAgACgCJEGACHI2AiQLDAELIAAoApABIAApA1g3AyALCyAAIAAoApgBKAIAEDQiBzcDiAEgB0IAUwRAIAAoApgBQQhqIAAoApgBKAIAEBcgAEF/NgKcAQwBCyAAKAKQASICIAIvAQxB9/8DcTsBDCAAIAAoApgBIAAoApABIAAoAiQQUCICNgIoIAJBAEgEQCAAQX82ApwBDAELIAAgAC8BaAJ/AkAgACgCkAEoAhBBf0cEQCAAKAKQASgCEEF+Rw0BC0EIDAELIAAoApABKAIQC0H//wNxRzoAIiAAIAAtACJBAXEEfyAALwFoQQBHBUEAC0EBcToAISAAIAAvAWgEfyAALQAhBUEBC0EBcToAICAAIAAtACJBAXEEfyAAKAKQASgCEEEARwVBAAtBAXE6AB8gAAJ/QQEgAC0AIkEBcQ0AGkEBIAAoApABKAIAQYABcQ0AGiAAKAKQAS8BUiAALwFqRwtBAXE6AB4gACAALQAeQQFxBH8gAC8BakEARwVBAAtBAXE6AB0gACAALQAeQQFxBH8gACgCkAEvAVJBAEcFQQALQQFxOgAcIAAgACgClAE2AjQjAEEQayICIAAoAjQ2AgwgAigCDCICIAIoAjBBAWo2AjAgAC0AHUEBcQRAIAAgAC8BakEAEHwiAjYCDCACRQRAIAAoApgBQQhqQRhBABAUIAAoAjQQGyAAQX82ApwBDAILIAAgACgCmAEgACgCNCAALwFqQQAgACgCmAEoAhwgACgCDBEFACICNgIwIAJFBEAgACgCNBAbIABBfzYCnAEMAgsgACgCNBAbIAAgACgCMDYCNAsgAC0AIUEBcQRAIAAgACgCmAEgACgCNCAALwFoELABIgI2AjAgAkUEQCAAKAI0EBsgAEF/NgKcAQwCCyAAKAI0EBsgACAAKAIwNgI0CyAALQAgQQFxBEAgACAAKAKYASAAKAI0QQAQrwEiAjYCMCACRQRAIAAoAjQQGyAAQX82ApwBDAILIAAoAjQQGyAAIAAoAjA2AjQLIAAtAB9BAXEEQCAAKAKYASEDIAAoAjQhBCAAKAKQASgCECEFIAAoApABLwFQIQYjAEEQayICJAAgAiADNgIMIAIgBDYCCCACIAU2AgQgAiAGNgIAIAIoAgwgAigCCCACKAIEQQEgAigCABCyASEDIAJBEGokACAAIAMiAjYCMCACRQRAIAAoAjQQGyAAQX82ApwBDAILIAAoAjQQGyAAIAAoAjA2AjQLIAAtABxBAXEEQCAAQQA2AgQCQCAAKAKQASgCVARAIAAgACgCkAEoAlQ2AgQMAQsgACgCmAEoAhwEQCAAIAAoApgBKAIcNgIECwsgACAAKAKQAS8BUkEBEHwiAjYCCCACRQRAIAAoApgBQQhqQRhBABAUIAAoAjQQGyAAQX82ApwBDAILIAAgACgCmAEgACgCNCAAKAKQAS8BUkEBIAAoAgQgACgCCBEFACICNgIwIAJFBEAgACgCNBAbIABBfzYCnAEMAgsgACgCNBAbIAAgACgCMDYCNAsgACAAKAKYASgCABA0Igc3A4ABIAdCAFMEQCAAKAKYAUEIaiAAKAKYASgCABAXIABBfzYCnAEMAQsgACgCmAEhAyAAKAI0IQQgACkDcCEHIwBBwMAAayICJAAgAiADNgK4QCACIAQ2ArRAIAIgBzcDqEACQCACKAK0QBBJQQBIBEAgAigCuEBBCGogAigCtEAQFyACQX82ArxADAELIAJBADYCDCACQgA3AxADQAJAIAIgAigCtEAgAkEgakKAwAAQLiIHNwMYIAdCAFcNACACKAK4QCACQSBqIAIpAxgQNUEASARAIAJBfzYCDAUgAikDGEKAwABSDQIgAigCuEAoAlRFDQIgAikDqEBCAFcNAiACIAIpAxggAikDEHw3AxAgAigCuEAoAlQgAikDELkgAikDqEC5oxBWDAILCwsgAikDGEIAUwRAIAIoArhAQQhqIAIoArRAEBcgAkF/NgIMCyACKAK0QBAxGiACIAIoAgw2ArxACyACKAK8QCEDIAJBwMAAaiQAIAAgAzYCLCAAKAI0IABBOGoQOEEASARAIAAoApgBQQhqIAAoAjQQFyAAQX82AiwLIAAoAjQhAyMAQRBrIgIkACACIAM2AggCQANAIAIoAggEQCACKAIIKQMYQoCABINCAFIEQCACIAIoAghBAEIAQRAQITcDACACKQMAQgBTBEAgAkH/AToADwwECyACKQMAQgNVBEAgAigCCEEMakEUQQAQFCACQf8BOgAPDAQLIAIgAikDADwADwwDBSACIAIoAggoAgA2AggMAgsACwsgAkEAOgAPCyACLAAPIQMgAkEQaiQAIAAgAyICOgAjIAJBGHRBGHVBAEgEQCAAKAKYAUEIaiAAKAI0EBcgAEF/NgIsCyAAKAI0EBsgACgCLEEASARAIABBfzYCnAEMAQsgACAAKAKYASgCABA0Igc3A3ggB0IAUwRAIAAoApgBQQhqIAAoApgBKAIAEBcgAEF/NgKcAQwBCyAAKAKYASgCACAAKQOIARCbAUEASARAIAAoApgBQQhqIAAoApgBKAIAEBcgAEF/NgKcAQwBCyAAKQM4QuQAg0LkAFIEQCAAKAKYAUEIakEUQQAQFCAAQX82ApwBDAELIAAoApABKAIAQSBxRQRAAkAgACkDOEIQg0IAUgRAIAAoApABIAAoAmA2AhQMAQsgACgCkAFBFGoQARoLCyAAKAKQASAALwFoNgIQIAAoApABIAAoAmQ2AhggACgCkAEgACkDUDcDKCAAKAKQASAAKQN4IAApA4ABfTcDICAAKAKQASAAKAKQAS8BDEH5/wNxIAAtACNBAXRyOwEMIAAoApABIQMgACgCJEGACHFBAEchBCMAQRBrIgIkACACIAM2AgwgAiAEOgALAkAgAigCDCgCEEEORgRAIAIoAgxBPzsBCgwBCyACKAIMKAIQQQxGBEAgAigCDEEuOwEKDAELAkAgAi0AC0EBcUUEQCACKAIMQQAQXkEBcUUNAQsgAigCDEEtOwEKDAELAkAgAigCDCgCEEEIRwRAIAIoAgwvAVJBAUcNAQsgAigCDEEUOwEKDAELIAIgAigCDCgCMBBTIgM7AQggA0H//wNxBEAgAigCDCgCMCgCACACLwEIQQFrai0AAEEvRgRAIAIoAgxBFDsBCgwCCwsgAigCDEEKOwEKCyACQRBqJAAgACAAKAKYASAAKAKQASAAKAIkEFAiAjYCLCACQQBIBEAgAEF/NgKcAQwBCyAAKAIoIAAoAixHBEAgACgCmAFBCGpBFEEAEBQgAEF/NgKcAQwBCyAAKAKYASgCACAAKQN4EJsBQQBIBEAgACgCmAFBCGogACgCmAEoAgAQFyAAQX82ApwBDAELIABBADYCnAELIAAoApwBIQIgAEGgAWokACACQQBICwRAIAFBATYCLCABKAIIBEAgASgCCBAbCwwECyABKAIIBEAgASgCCBAbCwwBCyABKAIMIgAgAC8BDEH3/wNxOwEMIAEoAlggASgCDEGAAhBQQQBIBEAgAUEBNgIsDAMLIAEgASgCWCABKQNQIAEoAlhBCGoQZSIHNwMAIAdQBEAgAUEBNgIsDAMLIAEoAlgoAgAgASkDAEEAECdBAEgEQCABKAJYQQhqIAEoAlgoAgAQFyABQQE2AiwMAwsCfyABKAJYIQIgASgCDCkDICEHIwBBoMAAayIAJAAgACACNgKYQCAAIAc3A5BAIAAgACkDkEC6OQMAAkADQCAAKQOQQFBFBEAgACAAKQOQQEKAwABWBH5CgMAABSAAKQOQQAs+AgwgACgCmEAoAgAgAEEQaiAAKAIMrSAAKAKYQEEIahBhQQBIBEAgAEF/NgKcQAwDCyAAKAKYQCAAQRBqIAAoAgytEDVBAEgEQCAAQX82ApxADAMFIAAgACkDkEAgADUCDH03A5BAIAAoAphAKAJUIAArAwAgACkDkEC6oSAAKwMAoxBWDAILAAsLIABBADYCnEALIAAoApxAIQIgAEGgwABqJAAgAkEASAsEQCABQQE2AiwMAwsLCyABIAEpA0hCAXw3A0gMAQsLIAEoAixFBEACfyABKAJYIQAgASgCKCEDIAEpA0AhByMAQTBrIgIkACACIAA2AiggAiADNgIkIAIgBzcDGCACIAIoAigoAgAQNCIHNwMQAkAgB0IAUwRAIAJBfzYCLAwBCyACKAIoIQMgAigCJCEEIAIpAxghByMAQcABayIAJAAgACADNgK0ASAAIAQ2ArABIAAgBzcDqAEgACAAKAK0ASgCABA0Igc3AyACQCAHQgBTBEAgACgCtAFBCGogACgCtAEoAgAQFyAAQn83A7gBDAELIAAgACkDIDcDoAEgAEEAOgAXIABCADcDGANAIAApAxggACkDqAFUBEAgACAAKAK0ASgCQCAAKAKwASAAKQMYp0EDdGopAwCnQQR0ajYCDCAAIAAoArQBAn8gACgCDCgCBARAIAAoAgwoAgQMAQsgACgCDCgCAAtBgAQQUCIDNgIQIANBAEgEQCAAQn83A7gBDAMLIAAoAhAEQCAAQQE6ABcLIAAgACkDGEIBfDcDGAwBCwsgACAAKAK0ASgCABA0Igc3AyAgB0IAUwRAIAAoArQBQQhqIAAoArQBKAIAEBcgAEJ/NwO4AQwBCyAAIAApAyAgACkDoAF9NwOYAQJAIAApA6ABQv////8PWARAIAApA6gBQv//A1gNAQsgAEEBOgAXCyAAIABBMGpC4gAQKSIDNgIsIANFBEAgACgCtAFBCGpBDkEAEBQgAEJ/NwO4AQwBCyAALQAXQQFxBEAgACgCLEHnEkEEEEAgACgCLEIsEC0gACgCLEEtEB8gACgCLEEtEB8gACgCLEEAECAgACgCLEEAECAgACgCLCAAKQOoARAtIAAoAiwgACkDqAEQLSAAKAIsIAApA5gBEC0gACgCLCAAKQOgARAtIAAoAixB4hJBBBBAIAAoAixBABAgIAAoAiwgACkDoAEgACkDmAF8EC0gACgCLEEBECALIAAoAixB7BJBBBBAIAAoAixBABAgIAAoAiwgACkDqAFC//8DWgR+Qv//AwUgACkDqAELp0H//wNxEB8gACgCLCAAKQOoAUL//wNaBH5C//8DBSAAKQOoAQunQf//A3EQHyAAKAIsIAApA5gBQv////8PWgR/QX8FIAApA5gBpwsQICAAKAIsIAApA6ABQv////8PWgR/QX8FIAApA6ABpwsQICAAAn8gACgCtAEtAChBAXEEQCAAKAK0ASgCJAwBCyAAKAK0ASgCIAs2ApQBIAAoAiwCfyAAKAKUAQRAIAAoApQBLwEEDAELQQALQf//A3EQHwJ/IwBBEGsiAyAAKAIsNgIMIAMoAgwtAABBAXFFCwRAIAAoArQBQQhqQRRBABAUIAAoAiwQFiAAQn83A7gBDAELIAAoArQBAn8jAEEQayIDIAAoAiw2AgwgAygCDCgCBAsCfiMAQRBrIgMgACgCLDYCDAJ+IAMoAgwtAABBAXEEQCADKAIMKQMQDAELQgALCxA1QQBIBEAgACgCLBAWIABCfzcDuAEMAQsgACgCLBAWIAAoApQBBEAgACgCtAEgACgClAEoAgAgACgClAEvAQStEDVBAEgEQCAAQn83A7gBDAILCyAAIAApA5gBNwO4AQsgACkDuAEhByAAQcABaiQAIAIgBzcDACAHQgBTBEAgAkF/NgIsDAELIAIgAigCKCgCABA0Igc3AwggB0IAUwRAIAJBfzYCLAwBCyACQQA2AiwLIAIoAiwhACACQTBqJAAgAEEASAsEQCABQQE2AiwLCyABKAIoEBUgASgCLEUEQAJ/IAEoAlgoAgAhAiMAQRBrIgAkACAAIAI2AggCQCAAKAIIKAIkQQFHBEAgACgCCEEMakESQQAQFCAAQX82AgwMAQsgACgCCCgCIEEBSwRAIAAoAghBDGpBHUEAEBQgAEF/NgIMDAELIAAoAggoAiAEQCAAKAIIEDFBAEgEQCAAQX82AgwMAgsLIAAoAghBAEIAQQkQIUIAUwRAIAAoAghBAjYCJCAAQX82AgwMAQsgACgCCEEANgIkIABBADYCDAsgACgCDCECIABBEGokACACCwRAIAEoAlhBCGogASgCWCgCABAXIAFBATYCLAsLIAEoAlgoAlQhAiMAQRBrIgAkACAAIAI2AgwgACgCDEQAAAAAAADwPxBWIABBEGokACABKAIsBEAgASgCWCgCABBnIAFBfzYCXAwBCyABKAJYED0gAUEANgJcCyABKAJcIQAgAUHgAGokACAAC9IOAgd/An4jAEEwayIDJAAgAyAANgIoIAMgATYCJCADIAI2AiAjAEEQayIAIANBCGo2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AgggAygCKCEAIwBBIGsiBCQAIAQgADYCGCAEQgA3AxAgBEJ/NwMIIAQgA0EIajYCBAJAAkAgBCgCGARAIAQpAwhCf1kNAQsgBCgCBEESQQAQFCAEQQA2AhwMAQsgBCgCGCEAIAQpAxAhCiAEKQMIIQsgBCgCBCEBIwBBoAFrIgIkACACIAA2ApgBIAJBADYClAEgAiAKNwOIASACIAs3A4ABIAJBADYCfCACIAE2AngCQAJAIAIoApQBDQAgAigCmAENACACKAJ4QRJBABAUIAJBADYCnAEMAQsgAikDgAFCAFMEQCACQgA3A4ABCwJAIAIpA4gBQv///////////wBYBEAgAikDiAEgAikDiAEgAikDgAF8WA0BCyACKAJ4QRJBABAUIAJBADYCnAEMAQsgAkGIARAYIgA2AnQgAEUEQCACKAJ4QQ5BABAUIAJBADYCnAEMAQsgAigCdEEANgIYIAIoApgBBEAgAigCmAEiABArQQFqIgEQGCIFBH8gBSAAIAEQGQVBAAshACACKAJ0IAA2AhggAEUEQCACKAJ4QQ5BABAUIAIoAnQQFSACQQA2ApwBDAILCyACKAJ0IAIoApQBNgIcIAIoAnQgAikDiAE3A2ggAigCdCACKQOAATcDcAJAIAIoAnwEQCACKAJ0IgAgAigCfCIBKQMANwMgIAAgASkDMDcDUCAAIAEpAyg3A0ggACABKQMgNwNAIAAgASkDGDcDOCAAIAEpAxA3AzAgACABKQMINwMoIAIoAnRBADYCKCACKAJ0IgAgACkDIEL+////D4M3AyAMAQsgAigCdEEgahA7CyACKAJ0KQNwQgBSBEAgAigCdCACKAJ0KQNwNwM4IAIoAnQiACAAKQMgQgSENwMgCyMAQRBrIgAgAigCdEHYAGo2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AgggAigCdEEANgKAASACKAJ0QQA2AoQBIwBBEGsiACACKAJ0NgIMIAAoAgxBADYCACAAKAIMQQA2AgQgACgCDEEANgIIIAJBfzYCBCACQQc2AgBBDiACEDZCP4QhCiACKAJ0IAo3AxACQCACKAJ0KAIYBEAgAiACKAJ0KAIYIAJBGGoQpgFBAE46ABcgAi0AF0EBcUUEQAJAIAIoAnQpA2hQRQ0AIAIoAnQpA3BQRQ0AIAIoAnRC//8DNwMQCwsMAQsCQCACKAJ0KAIcIgAoAkxBAEgNAAsgACgCPCEAQQAhBSMAQSBrIgYkAAJ/AkAgACACQRhqIgkQCiIBQXhGBEAjAEEgayIHJAAgACAHQQhqEAkiCAR/QbSbASAINgIAQQAFQQELIQggB0EgaiQAIAgNAQsgAUGBYE8Ef0G0mwFBACABazYCAEF/BSABCwwBCwNAIAUgBmoiASAFQccSai0AADoAACAFQQ5HIQcgBUEBaiEFIAcNAAsCQCAABEBBDyEFIAAhAQNAIAFBCk8EQCAFQQFqIQUgAUEKbiEBDAELCyAFIAZqQQA6AAADQCAGIAVBAWsiBWogACAAQQpuIgFBCmxrQTByOgAAIABBCUshByABIQAgBw0ACwwBCyABQTA6AAAgBkEAOgAPCyAGIAkQAiIAQYFgTwR/QbSbAUEAIABrNgIAQX8FIAALCyEAIAZBIGokACACIABBAE46ABcLAkAgAi0AF0EBcUUEQCACKAJ0QdgAakEFQbSbASgCABAUDAELIAIoAnQpAyBCEINQBEAgAigCdCACKAJYNgJIIAIoAnQiACAAKQMgQhCENwMgCyACKAIkQYDgA3FBgIACRgRAIAIoAnRC/4EBNwMQIAIpA0AgAigCdCkDaCACKAJ0KQNwfFQEQCACKAJ4QRJBABAUIAIoAnQoAhgQFSACKAJ0EBUgAkEANgKcAQwDCyACKAJ0KQNwUARAIAIoAnQgAikDQCACKAJ0KQNofTcDOCACKAJ0IgAgACkDIEIEhDcDIAJAIAIoAnQoAhhFDQAgAikDiAFQRQ0AIAIoAnRC//8DNwMQCwsLCyACKAJ0IgAgACkDEEKAgBCENwMQIAJBHiACKAJ0IAIoAngQlAEiADYCcCAARQRAIAIoAnQoAhgQFSACKAJ0EBUgAkEANgKcAQwBCyACIAIoAnA2ApwBCyACKAKcASEAIAJBoAFqJAAgBCAANgIcCyAEKAIcIQAgBEEgaiQAIAMgADYCGAJAIABFBEAgAygCICADQQhqEJ0BIANBCGoQNyADQQA2AiwMAQsgAyADKAIYIAMoAiQgA0EIahCcASIANgIcIABFBEAgAygCGBAbIAMoAiAgA0EIahCdASADQQhqEDcgA0EANgIsDAELIANBCGoQNyADIAMoAhw2AiwLIAMoAiwhACADQTBqJAAgAAsYAQF/IwBBEGsiASAANgIMIAEoAgxBDGoLkh8BBn8jAEHgAGsiBCQAIAQgADYCVCAEIAE2AlAgBCACNwNIIAQgAzYCRCAEIAQoAlQ2AkAgBCAEKAJQNgI8AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBCgCRA4TBgcCDAQFCg4BAwkQCw8NCBERABELIARCADcDWAwRCyAEKAJAKAIYRQRAIAQoAkBBHEEAEBQgBEJ/NwNYDBELIAQoAkAhACMAQYABayIBJAAgASAANgJ4IAEgASgCeCgCGBArQQhqEBgiADYCdAJAIABFBEAgASgCeEEOQQAQFCABQX82AnwMAQsCQCABKAJ4KAIYIAFBEGoQpgFFBEAgASABKAIcNgJsDAELIAFBfzYCbAsgASgCdCEAIAEgASgCeCgCGDYCACAAQasSIAEQcCABKAJ0IQMgASgCbCEHIwBBMGsiACQAIAAgAzYCKCAAIAc2AiQgAEEANgIQIAAgACgCKCAAKAIoECtqNgIYIAAgACgCGEEBazYCHANAIAAoAhwgACgCKE8EfyAAKAIcLAAAQdgARgVBAAtBAXEEQCAAIAAoAhBBAWo2AhAgACAAKAIcQQFrNgIcDAELCwJAIAAoAhBFBEBBtJsBQRw2AgAgAEF/NgIsDAELIAAgACgCHEEBajYCHANAIwBBEGsiByQAAkACfyMAQRBrIgMkACADIAdBCGo2AgggA0EEOwEGIANB6AtBAEEAEG0iBTYCAAJAIAVBAEgEQCADQQA6AA8MAQsCfyADKAIAIQYgAygCCCEIIAMvAQYhCSMAQRBrIgUkACAFIAk2AgwgBSAINgIIIAYgBUEIakEBIAVBBGoQBiIGBH9BtJsBIAY2AgBBfwVBAAshBiAFKAIEIQggBUEQaiQAIAMvAQZBfyAIIAYbRwsEQCADKAIAEGwgA0EAOgAPDAELIAMoAgAQbCADQQE6AA8LIAMtAA9BAXEhBSADQRBqJAAgBQsEQCAHIAcoAgg2AgwMAQtBwKABLQAAQQFxRQRAQQAQASEGAkBByJkBKAIAIgNFBEBBzJkBKAIAIAY2AgAMAQtB0JkBQQNBA0EBIANBB0YbIANBH0YbNgIAQbygAUEANgIAQcyZASgCACEFIANBAU4EQCAGrSECQQAhBgNAIAUgBkECdGogAkKt/tXk1IX9qNgAfkIBfCICQiCIPgIAIAZBAWoiBiADRw0ACwsgBSAFKAIAQQFyNgIACwtBzJkBKAIAIQMCQEHImQEoAgAiBUUEQCADIAMoAgBB7ZyZjgRsQbngAGpB/////wdxIgM2AgAMAQsgA0HQmQEoAgAiBkECdGoiCCAIKAIAIANBvKABKAIAIghBAnRqKAIAaiIDNgIAQbygAUEAIAhBAWoiCCAFIAhGGzYCAEHQmQFBACAGQQFqIgYgBSAGRhs2AgAgA0EBdiEDCyAHIAM2AgwLIAcoAgwhAyAHQRBqJAAgACADNgIMIAAgACgCHDYCFANAIAAoAhQgACgCGEkEQCAAIAAoAgxBJHA6AAsCfyAALAALQQpIBEAgACwAC0EwagwBCyAALAALQdcAagshAyAAIAAoAhQiB0EBajYCFCAHIAM6AAAgACAAKAIMQSRuNgIMDAELCyAAKAIoIQMgACAAKAIkQX9GBH9BtgMFIAAoAiQLNgIAIAAgA0HCgSAgABBtIgM2AiAgA0EATgRAIAAoAiRBf0cEQCAAKAIoIAAoAiQQDyIDQYFgTwR/QbSbAUEAIANrNgIAQQAFIAMLGgsgACAAKAIgNgIsDAILQbSbASgCAEEURg0ACyAAQX82AiwLIAAoAiwhAyAAQTBqJAAgASADIgA2AnAgAEF/RgRAIAEoAnhBDEG0mwEoAgAQFCABKAJ0EBUgAUF/NgJ8DAELIAEgASgCcEGjEhChASIANgJoIABFBEAgASgCeEEMQbSbASgCABAUIAEoAnAQbCABKAJ0EG4aIAEoAnQQFSABQX82AnwMAQsgASgCeCABKAJoNgKEASABKAJ4IAEoAnQ2AoABIAFBADYCfAsgASgCfCEAIAFBgAFqJAAgBCAArDcDWAwQCyAEKAJAKAIYBEAgBCgCQCgCHBBVGiAEKAJAQQA2AhwLIARCADcDWAwPCyAEKAJAKAKEARBVQQBIBEAgBCgCQEEANgKEASAEKAJAQQZBtJsBKAIAEBQLIAQoAkBBADYChAEgBCgCQCgCgAEgBCgCQCgCGBAIIgBBgWBPBH9BtJsBQQAgAGs2AgBBfwUgAAtBAEgEQCAEKAJAQQJBtJsBKAIAEBQgBEJ/NwNYDA8LIAQoAkAoAoABEBUgBCgCQEEANgKAASAEQgA3A1gMDgsgBCAEKAJAIAQoAlAgBCkDSBBCNwNYDA0LIAQoAkAoAhgQFSAEKAJAKAKAARAVIAQoAkAoAhwEQCAEKAJAKAIcEFUaCyAEKAJAEBUgBEIANwNYDAwLIAQoAkAoAhgEQCAEKAJAKAIYIQEjAEEgayIAJAAgACABNgIYIABBADoAFyAAQYCAIDYCDAJAIAAtABdBAXEEQCAAIAAoAgxBAnI2AgwMAQsgACAAKAIMNgIMCyAAKAIYIQEgACgCDCEDIABBtgM2AgAgACABIAMgABBtIgE2AhACQCABQQBIBEAgAEEANgIcDAELIAAgACgCEEGjEkGgEiAALQAXQQFxGxChASIBNgIIIAFFBEAgAEEANgIcDAELIAAgACgCCDYCHAsgACgCHCEBIABBIGokACAEKAJAIAE2AhwgAUUEQCAEKAJAQQtBtJsBKAIAEBQgBEJ/NwNYDA0LCyAEKAJAKQNoQgBSBEAgBCgCQCgCHCAEKAJAKQNoIAQoAkAQnwFBAEgEQCAEQn83A1gMDQsLIAQoAkBCADcDeCAEQgA3A1gMCwsCQCAEKAJAKQNwQgBSBEAgBCAEKAJAKQNwIAQoAkApA3h9NwMwIAQpAzAgBCkDSFYEQCAEIAQpA0g3AzALDAELIAQgBCkDSDcDMAsgBCkDMEL/////D1YEQCAEQv////8PNwMwCyAEAn8gBCgCPCEHIAQpAzCnIQAgBCgCQCgCHCIDKAJMGiADIAMtAEoiAUEBayABcjoASiADKAIIIAMoAgQiBWsiAUEBSAR/IAAFIAcgBSABIAAgACABSxsiARAZGiADIAMoAgQgAWo2AgQgASAHaiEHIAAgAWsLIgEEQANAAkACfyADIAMtAEoiBUEBayAFcjoASiADKAIUIAMoAhxLBEAgA0EAQQAgAygCJBEBABoLIANBADYCHCADQgA3AxAgAygCACIFQQRxBEAgAyAFQSByNgIAQX8MAQsgAyADKAIsIAMoAjBqIgY2AgggAyAGNgIEIAVBG3RBH3ULRQRAIAMgByABIAMoAiARAQAiBUEBakEBSw0BCyAAIAFrDAMLIAUgB2ohByABIAVrIgENAAsLIAALIgA2AiwgAEUEQAJ/IAQoAkAoAhwiACgCTEF/TARAIAAoAgAMAQsgACgCAAtBBXZBAXEEQCAEKAJAQQVBtJsBKAIAEBQgBEJ/NwNYDAwLCyAEKAJAIgAgACkDeCAEKAIsrXw3A3ggBCAEKAIsrTcDWAwKCyAEKAJAKAIYEG5BAEgEQCAEKAJAQRZBtJsBKAIAEBQgBEJ/NwNYDAoLIARCADcDWAwJCyAEKAJAKAKEAQRAIAQoAkAoAoQBEFUaIAQoAkBBADYChAELIAQoAkAoAoABEG4aIAQoAkAoAoABEBUgBCgCQEEANgKAASAEQgA3A1gMCAsgBAJ/IAQpA0hCEFQEQCAEKAJAQRJBABAUQQAMAQsgBCgCUAs2AhggBCgCGEUEQCAEQn83A1gMCAsgBEEBNgIcAkACQAJAAkACQCAEKAIYKAIIDgMAAgEDCyAEIAQoAhgpAwA3AyAMAwsCQCAEKAJAKQNwUARAIAQoAkAoAhwgBCgCGCkDAEECIAQoAkAQa0EASARAIARCfzcDWAwNCyAEIAQoAkAoAhwQowEiAjcDICACQgBTBEAgBCgCQEEEQbSbASgCABAUIARCfzcDWAwNCyAEIAQpAyAgBCgCQCkDaH03AyAgBEEANgIcDAELIAQgBCgCQCkDcCAEKAIYKQMAfDcDIAsMAgsgBCAEKAJAKQN4IAQoAhgpAwB8NwMgDAELIAQoAkBBEkEAEBQgBEJ/NwNYDAgLAkACQCAEKQMgQgBTDQAgBCgCQCkDcEIAUgRAIAQpAyAgBCgCQCkDcFYNAQsgBCgCQCkDaCAEKQMgIAQoAkApA2h8WA0BCyAEKAJAQRJBABAUIARCfzcDWAwICyAEKAJAIAQpAyA3A3ggBCgCHARAIAQoAkAoAhwgBCgCQCkDeCAEKAJAKQNofCAEKAJAEJ8BQQBIBEAgBEJ/NwNYDAkLCyAEQgA3A1gMBwsgBAJ/IAQpA0hCEFQEQCAEKAJAQRJBABAUQQAMAQsgBCgCUAs2AhQgBCgCFEUEQCAEQn83A1gMBwsgBCgCQCgChAEgBCgCFCkDACAEKAIUKAIIIAQoAkAQa0EASARAIARCfzcDWAwHCyAEQgA3A1gMBgsgBCkDSEI4VARAIARCfzcDWAwGCwJ/IwBBEGsiACAEKAJAQdgAajYCDCAAKAIMKAIACwRAIAQoAkACfyMAQRBrIgAgBCgCQEHYAGo2AgwgACgCDCgCAAsCfyMAQRBrIgAgBCgCQEHYAGo2AgwgACgCDCgCBAsQFCAEQn83A1gMBgsgBCgCUCIAIAQoAkAiASkAIDcAACAAIAEpAFA3ADAgACABKQBINwAoIAAgASkAQDcAICAAIAEpADg3ABggACABKQAwNwAQIAAgASkAKDcACCAEQjg3A1gMBQsgBCAEKAJAKQMQNwNYDAQLIAQgBCgCQCkDeDcDWAwDCyAEIAQoAkAoAoQBEKMBNwMIIAQpAwhCAFMEQCAEKAJAQR5BtJsBKAIAEBQgBEJ/NwNYDAMLIAQgBCkDCDcDWAwCCyAEKAJAKAKEASIAKAJMQQBOGiAAIAAoAgBBT3E2AgAgBAJ/IAQoAlAhASAEKQNIpyIAIAACfyAEKAJAKAKEASIDKAJMQX9MBEAgASAAIAMQcgwBCyABIAAgAxByCyIBRg0AGiABCzYCBAJAIAQpA0ggBCgCBK1RBEACfyAEKAJAKAKEASIAKAJMQX9MBEAgACgCAAwBCyAAKAIAC0EFdkEBcUUNAQsgBCgCQEEGQbSbASgCABAUIARCfzcDWAwCCyAEIAQoAgStNwNYDAELIAQoAkBBHEEAEBQgBEJ/NwNYCyAEKQNYIQIgBEHgAGokACACCwkAIAAoAjwQBQvkAQEEfyMAQSBrIgMkACADIAE2AhAgAyACIAAoAjAiBEEAR2s2AhQgACgCLCEFIAMgBDYCHCADIAU2AhhBfyEEAkACQCAAKAI8IANBEGpBAiADQQxqEAYiBQR/QbSbASAFNgIAQX8FQQALRQRAIAMoAgwiBEEASg0BCyAAIAAoAgAgBEEwcUEQc3I2AgAMAQsgBCADKAIUIgZNDQAgACAAKAIsIgU2AgQgACAFIAQgBmtqNgIIIAAoAjAEQCAAIAVBAWo2AgQgASACakEBayAFLQAAOgAACyACIQQLIANBIGokACAEC/QCAQd/IwBBIGsiAyQAIAMgACgCHCIFNgIQIAAoAhQhBCADIAI2AhwgAyABNgIYIAMgBCAFayIBNgIUIAEgAmohBUECIQcgA0EQaiEBAn8CQAJAIAAoAjwgA0EQakECIANBDGoQAyIEBH9BtJsBIAQ2AgBBfwVBAAtFBEADQCAFIAMoAgwiBEYNAiAEQX9MDQMgASAEIAEoAgQiCEsiBkEDdGoiCSAEIAhBACAGG2siCCAJKAIAajYCACABQQxBBCAGG2oiCSAJKAIAIAhrNgIAIAUgBGshBSAAKAI8IAFBCGogASAGGyIBIAcgBmsiByADQQxqEAMiBAR/QbSbASAENgIAQX8FQQALRQ0ACwsgBUF/Rw0BCyAAIAAoAiwiATYCHCAAIAE2AhQgACABIAAoAjBqNgIQIAIMAQsgAEEANgIcIABCADcDECAAIAAoAgBBIHI2AgBBACAHQQJGDQAaIAIgASgCBGsLIQAgA0EgaiQAIAALUgEBfyMAQRBrIgMkACAAKAI8IAGnIAFCIIinIAJB/wFxIANBCGoQDSIABH9BtJsBIAA2AgBBfwVBAAshACADKQMIIQEgA0EQaiQAQn8gASAAGwtFAEGgmwFCADcDAEGYmwFCADcDAEGQmwFCADcDAEGImwFCADcDAEGAmwFCADcDAEH4mgFCADcDAEHwmgFCADcDAEHwmgEL1QQBBX8jAEGwAWsiASQAIAEgADYCqAEgASgCqAEQNwJAAkAgASgCqAEoAgBBAE4EQCABKAKoASgCAEGAFCgCAEgNAQsgASABKAKoASgCADYCECABQSBqQY8SIAFBEGoQcCABQQA2AqQBIAEgAUEgajYCoAEMAQsgASABKAKoASgCAEECdEGAE2ooAgA2AqQBAkACQAJAAkAgASgCqAEoAgBBAnRBkBRqKAIAQQFrDgIAAQILIAEoAqgBKAIEIQJBkJkBKAIAIQRBACEAAkACQANAIAIgAEGgiAFqLQAARwRAQdcAIQMgAEEBaiIAQdcARw0BDAILCyAAIgMNAEGAiQEhAgwBC0GAiQEhAANAIAAtAAAhBSAAQQFqIgIhACAFDQAgAiEAIANBAWsiAw0ACwsgBCgCFBogASACNgKgAQwCCyMAQRBrIgAgASgCqAEoAgQ2AgwgAUEAIAAoAgxrQQJ0QajZAGooAgA2AqABDAELIAFBADYCoAELCwJAIAEoAqABRQRAIAEgASgCpAE2AqwBDAELIAEgASgCoAEQKwJ/IAEoAqQBBEAgASgCpAEQK0ECagwBC0EAC2pBAWoQGCIANgIcIABFBEAgAUG4EygCADYCrAEMAQsgASgCHCEAAn8gASgCpAEEQCABKAKkAQwBC0H6EgshA0HfEkH6EiABKAKkARshAiABIAEoAqABNgIIIAEgAjYCBCABIAM2AgAgAEG+CiABEHAgASgCqAEgASgCHDYCCCABIAEoAhw2AqwBCyABKAKsASEAIAFBsAFqJAAgAAszAQF/IAAoAhQiAyABIAIgACgCECADayIBIAEgAksbIgEQGRogACAAKAIUIAFqNgIUIAILjwUCBn4BfyABIAEoAgBBD2pBcHEiAUEQajYCACAAAnwgASkDACEDIAEpAwghBiMAQSBrIggkAAJAIAZC////////////AIMiBEKAgICAgIDAgDx9IARCgICAgICAwP/DAH1UBEAgBkIEhiADQjyIhCEEIANC//////////8PgyIDQoGAgICAgICACFoEQCAEQoGAgICAgICAwAB8IQIMAgsgBEKAgICAgICAgEB9IQIgA0KAgICAgICAgAiFQgBSDQEgAiAEQgGDfCECDAELIANQIARCgICAgICAwP//AFQgBEKAgICAgIDA//8AURtFBEAgBkIEhiADQjyIhEL/////////A4NCgICAgICAgPz/AIQhAgwBC0KAgICAgICA+P8AIQIgBEL///////+//8MAVg0AQgAhAiAEQjCIpyIAQZH3AEkNACADIQIgBkL///////8/g0KAgICAgIDAAIQiBSEHAkAgAEGB9wBrIgFBwABxBEAgAiABQUBqrYYhB0IAIQIMAQsgAUUNACAHIAGtIgSGIAJBwAAgAWutiIQhByACIASGIQILIAggAjcDECAIIAc3AxgCQEGB+AAgAGsiAEHAAHEEQCAFIABBQGqtiCEDQgAhBQwBCyAARQ0AIAVBwAAgAGuthiADIACtIgKIhCEDIAUgAoghBQsgCCADNwMAIAggBTcDCCAIKQMIQgSGIAgpAwAiA0I8iIQhAiAIKQMQIAgpAxiEQgBSrSADQv//////////D4OEIgNCgYCAgICAgIAIWgRAIAJCAXwhAgwBCyADQoCAgICAgICACIVCAFINACACQgGDIAJ8IQILIAhBIGokACACIAZCgICAgICAgICAf4OEvws5AwALrRcDEn8CfgF8IwBBsARrIgkkACAJQQA2AiwCQCABvSIYQn9XBEBBASESQa4IIRMgAZoiAb0hGAwBCyAEQYAQcQRAQQEhEkGxCCETDAELQbQIQa8IIARBAXEiEhshEyASRSEXCwJAIBhCgICAgICAgPj/AINCgICAgICAgPj/AFEEQCAAQSAgAiASQQNqIg0gBEH//3txECYgACATIBIQIiAAQeQLQbUSIAVBIHEiAxtBjw1BuRIgAxsgASABYhtBAxAiDAELIAlBEGohEAJAAn8CQCABIAlBLGoQqQEiASABoCIBRAAAAAAAAAAAYgRAIAkgCSgCLCIGQQFrNgIsIAVBIHIiFEHhAEcNAQwDCyAFQSByIhRB4QBGDQIgCSgCLCELQQYgAyADQQBIGwwBCyAJIAZBHWsiCzYCLCABRAAAAAAAALBBoiEBQQYgAyADQQBIGwshCiAJQTBqIAlB0AJqIAtBAEgbIg4hBwNAIAcCfyABRAAAAAAAAPBBYyABRAAAAAAAAAAAZnEEQCABqwwBC0EACyIDNgIAIAdBBGohByABIAO4oUQA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HCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCGCABKAIUSQtBAXENAAsgASgCKEGCAiABKAIUIAEoAhhrazYCYCABKAIoKAJgIAEoAigoAnRLBEAgASgCKCABKAIoKAJ0NgJgCwsLAkAgASgCKCgCYEEDTwRAIAEgASgCKCgCYEEDazoAEyABQQE7ARAgASgCKCICKAKkLSACKAKgLUEBdGogAS8BEDsBACABLQATIQMgASgCKCICKAKYLSEEIAIgAigCoC0iAkEBajYCoC0gAiAEaiADOgAAIAEgAS8BEEEBazsBECABKAIoIAEtABNB0N0Aai0AAEECdGpBmAlqIgIgAi8BAEEBajsBACABKAIoQYgTagJ/IAEvARBBgAJJBEAgAS8BEC0A0FkMAQsgAS8BEEEHdkGAAmotANBZC0ECdGoiAiACLwEAQQFqOwEAIAEgASgCKCgCoC0gASgCKCgCnC1BAWtGNgIgIAEoAigiAiACKAJ0IAEoAigoAmBrNgJ0IAEoAigiAiABKAIoKAJgIAIoAmxqNgJsIAEoAihBADYCYAwBCyABIAEoAigiAigCOCACKAJsai0AADoADyABKAIoIgIoAqQtIAIoAqAtQQF0akEAOwEAIAEtAA8hAyABKAIoIgIoApgtIQQgAiACKAKgLSICQQFqNgKgLSACIARqIAM6AAAgASgCKCABLQAPQQJ0aiICIAIvAZQBQQFqOwGUASABIAEoAigoAqAtIAEoAigoApwtQQFrRjYCICABKAIoIgIgAigCdEEBazYCdCABKAIoIgIgAigCbEEBajYCbAsgASgCIARAIAEoAigCfyABKAIoKAJcQQBOBEAgASgCKCgCOCABKAIoKAJcagwBC0EACyABKAIoKAJsIAEoAigoAlxrQQAQKCABKAIoIAEoAigoAmw2AlwgASgCKCgCABAcIAEoAigo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QCABKAIoQQ9JBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABIAEoAlAiAkEBajYCUCABIAEoAiwgAi0AACABKAIodGo2AiwgASABKAIoQQhqNgIoCyABIAEoAiQgASgCLCABKAIccUECdGooAQA2ARACQAJAA0AgASABLQARNgIMIAEgASgCLCABKAIMdjYCLCABIAEoAiggASgCDGs2AiggASABLQAQNgIMIAEoAgxFBEAgAS8BEiECIAEgASgCSCIDQQFqNgJIIAMgAjoAAAwCCyABKAIMQRBxBEAgASABLwESNgIIIAEgASgCDEEPcTYCDCABKAIMBEAgASgCKCABKAIMSQRAIAEgASgCUCICQQFqNgJQIAEgASgCLCACLQAAIAEoAih0ajYCLCABIAEoAihBCGo2AigLIAEgASgCCCABKAIsQQEgASgCDHRBAWtxajYCCCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoCyABKAIoQQ9JBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABIAEoAlAiAkEBajYCUCABIAEoAiwgAi0AACABKAIodGo2AiwgASABKAIoQQhqNgIoCyABIAEoAiAgASgCLCABKAIYcUECdGooAQA2ARACQANAIAEgAS0AETYCDCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgAS0AEDYCDCABKAIMQRBxBEAgASABLwESNgIEIAEgASgCDEEPcTYCDCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKAsLIAEgASgCBCABKAIsQQEgASgCDHRBAWtxajYCBCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgASgCSCABKAJEazYCDAJAIAEoAgQgASgCDEsEQCABIAEoAgQgASgCDGs2AgwgASgCDCABKAI4SwRAIAEoAlQoAsQ3BEAgASgCXEHdDDYCGCABKAJUQdH+ADYCBAwKCwsgASABKAIwNgIAAkAgASgCNEUEQCABIAEoAgAgASgCPCABKAIMa2o2AgAgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAkggASgCBGs2AgALDAELAkAgASgCNCABKAIMSQRAIAEgASgCACABKAI8IAEoAjRqIAEoAgxrajYCACABIAEoAgwgASgCNGs2AgwgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAjA2AgAgASgCNCABKAIISQRAIAEgASgCNDYCDCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsMAQsgASABKAIAIAEoAjQgASgCDGtqNgIAIAEoAgwgASgCCEkEQCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsLA0AgASgCCEECSwRAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCCEEDazYCCAwBCwsMAQsgASABKAJIIAEoAgRrNgIAA0AgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgi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ZWFkIGVycm9yAFpsaWIgZXJyb3IAZGF0YSBlcnJvcgBDUkMgZXJyb3IAaW5jb21wYXRpYmxlIHZlcnNpb24AbmFuAC9kZXYvdXJhbmRvbQBpbnZhbGlkIGNvZGUgLS0gbWlzc2luZyBlbmQtb2YtYmxvY2sAaW5jb3JyZWN0IGhlYWRlciBjaGVjawBpbmNvcnJlY3QgbGVuZ3RoIGNoZWNrAGluY29ycmVjdCBkYXRhIGNoZWNrAGludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrAGhlYWRlciBjcmMgbWlzbWF0Y2gAaW5mAGludmFsaWQgd2luZG93IHNpemUAUmVhZC1vbmx5IGFyY2hpdmUATm90IGEgemlwIGFyY2hpdmUAUmVzb3VyY2Ugc3RpbGwgaW4gdXNlAE1hbGxvYyBmYWlsdXJlAGludmFsaWQgYmxvY2sgdHlwZQBGYWlsdXJlIHRvIGNyZWF0ZSB0ZW1wb3JhcnkgZmlsZQBDYW4ndCBvcGVuIGZpbGUATm8gc3VjaCBmaWxlAFByZW1hdHVyZSBlbmQgb2YgZmlsZQBDYW4ndCByZW1vdmUgZmlsZQBpbnZhbGlkIGxpdGVyYWwvbGVuZ3RoIGNvZGUAaW52YWxpZCBkaXN0YW5jZSBjb2RlAHVua25vd24gY29tcHJlc3Npb24gbWV0aG9kAHN0cmVhbSBlbmQAQ29tcHJlc3NlZCBkYXRhIGludmFsaWQATXVsdGktZGlzayB6aXAgYXJjaGl2ZXMgbm90IHN1cHBvcnRlZABPcGVyYXRpb24gbm90IHN1cHBvcnRlZABFbmNyeXB0aW9uIG1ldGhvZCBub3Qgc3VwcG9ydGVkAENvbXByZXNzaW9uIG1ldGhvZCBub3Qgc3VwcG9ydGVkAEVudHJ5IGhhcyBiZWVuIGRlbGV0ZWQAQ29udGFpbmluZyB6aXAgYXJjaGl2ZSB3YXMgY2xvc2VkAENsb3NpbmcgemlwIGFyY2hpdmUgZmFpbGVkAFJlbmFtaW5nIHRlbXBvcmFyeSBmaWxlIGZhaWxlZABFbnRyeSBoYXMgYmVlbiBjaGFuZ2VkAE5vIHBhc3N3b3JkIHByb3ZpZGVkAFdyb25nIHBhc3N3b3JkIHByb3ZpZGVkAFVua25vd24gZXJyb3IgJWQAcmIAcitiAHJ3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CADcAAgAPAAIALwACAB8AAgA/AAIAAIACACCAAgAQgAIAMIACAAiAAgAogAIAGIACADiAAgAEgAIAJIACABSAAgA0gAIADIACACyAAgAcgAIAPIACAAKAAgAigAIAEoACADKAAgAKgAIAKoACABqAAgA6gAIABoACACaAAgAWgAIANoACAA6AAgAugAIAHoACAD6AAgABgAIAIYACABGAAgAxgAIACYACACmAAgAZgAIAOYACAAWAAgAlgAIAFYACADWAAgANgAIALYACAB2AAgA9gAIAA4ACACOAAgATgAIAM4ACAAuAAgArgAIAG4ACADuAAgAHgAIAJ4ACABeAAgA3gAIAD4ACAC+AAgAfgAIAP4ACAABAAgAgQAIAEEACADBAAgAIQAIAKEACABhAAgA4QAIABEACACRAAgAUQAIANEACAAxAAgAsQAIAHEACADxAAgACQAIAIkACABJAAgAyQAIACkACACpAAgAaQAIAOkACAAZAAgAmQAIAFkACADZAAgAOQAIALkACAB5AAgA+QAIAAUACACFAAgARQAIAMUACAAlAAgApQAIAGUACADlAAgAFQAIAJUACABVAAgA1QAIADUACAC1AAgAdQAIAPUACAANAAgAjQAIAE0ACADNAAgALQAIAK0ACABtAAgA7QAIAB0ACACdAAgAXQAIAN0ACAA9AAgAvQAIAH0ACAD9AAgAEwAJABMBCQCTAAkAkwEJAFMACQBTAQkA0wAJANMBCQAzAAkAMwEJALMACQCzAQkAcwAJAHMBCQDzAAkA8wEJAAsACQALAQkAiwAJAIsBCQBLAAkASwEJAMsACQDLAQkAKwAJACsBCQCrAAkAqwEJAGsACQBrAQkA6wAJAOsBCQAbAAkAGwEJAJsACQCbAQkAWwAJAFsBCQDbAAkA2wEJADsACQA7AQkAuwAJALsBCQB7AAkAewEJAPsACQD7AQkABwAJAAcBCQCHAAkAhwEJAEcACQBHAQkAxwAJAMcBCQAnAAkAJwEJAKcACQCnAQkAZwAJAGcBCQDnAAkA5wEJABcACQAXAQkAlwAJAJcBCQBXAAkAVwEJANcACQDXAQkANwAJADcBCQC3AAkAtwEJAHcACQB3AQkA9wAJAPcBCQAPAAkADwEJAI8ACQCPAQkATwAJAE8BCQDPAAkAzwEJAC8ACQAvAQkArwAJAK8BCQBvAAkAbwEJAO8ACQDvAQkAHwAJAB8BCQCfAAkAnwEJAF8ACQBfAQkA3wAJAN8BCQA/AAkAPwEJAL8ACQC/AQkAfwAJAH8BCQD/AAkA/wEJAAAABwBAAAcAIAAHAGAABwAQAAcAUAAHADAABwBwAAcACAAHAEgABwAoAAcAaAAHABgABwBYAAcAOAAHAHgABwAEAAcARAAHACQABwBkAAcAFAAHAFQABwA0AAcAdAAHAAMACACDAAgAQwAIAMMACAAjAAgAowAIAGMACADjAAgAAAAFABAABQAIAAUAGAAFAAQABQAUAAUADAAFABwABQACAAUAEgAFAAoABQAaAAUABgAFABYABQAOAAUAHgAFAAEABQARAAUACQAFABkABQAFAAUAFQAFAA0ABQAdAAUAAwAFABMABQALAAUAGwAFAAcABQAXAAUAQbDqAAtNAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAABAAAAAQAAAAEAAAABAAAAAUAAAAFAAAABQAAAAUAQaDrAAtlAQAAAAEAAAACAAAAAgAAAAMAAAADAAAABAAAAAQAAAAFAAAABQAAAAYAAAAGAAAABwAAAAcAAAAIAAAACAAAAAkAAAAJAAAACgAAAAoAAAALAAAACwAAAAwAAAAMAAAADQAAAA0AQdDsAAsjAgAAAAMAAAAHAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AQYTtAAtpAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAKAAAADAAAAA4AAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAwAAAAOAAAAEAAAABQAAAAYAAAAHAAAACAAAAAoAAAAMAAAADgAEGE7gALegEAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAAABAACAAQAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAMS4yLjExAEGI7wALbQcAAAAEAAQACAAEAAgAAAAEAAUAEAAIAAgAAAAEAAYAIAAgAAgAAAAEAAQAEAAQAAkAAAAIABAAIAAgAAkAAAAIABAAgACAAAkAAAAIACAAgAAAAQkAAAAgAIAAAgEABAkAAAAgAAIBAgEAEAkAQYDwAAulAgMABAAFAAYABwAIAAkACgALAA0ADwARABMAFwAbAB8AIwArADMAOwBDAFMAYwBzAIMAowDDAOMAAgEAAAAAAAAQABAAEAAQABAAEAAQABAAEQARABEAEQASABIAEgASABMAEwATABMAFAAUABQAFAAVABUAFQAVABAATQDKAAAAAQACAAMABAAFAAcACQANABEAGQAhADEAQQBhAIEAwQABAYEBAQIBAwEEAQYBCAEMARABGAEgATABQAFgAAAAABAAEAAQABAAEQARABIAEgATABMAFAAUABUAFQAWABYAFwAXABgAGAAZABkAGgAaABsAGwAcABwAHQAdAEAAQAAQABEAEgAAAAgABwAJAAYACgAFAAsABAAMAAMADQACAA4AAQAPAEGw8gALwRFgBwAAAAhQAAAIEAAUCHMAEgcfAAAIcAAACDAAAAnAABAHCgAACGAAAAggAAAJoAAACAAAAAiAAAAIQAAACeAAEAcGAAAIWAAACBgAAAmQABMHOwAACHgAAAg4AAAJ0AARBxEAAAhoAAAIKAAACbAAAAgIAAAIiAAACEgAAAnwABAHBAAACFQAAAgUABUI4wATBysAAAh0AAAINAAACcgAEQcNAAAIZAAACCQAAAmoAAAIBAAACIQAAAhEAAAJ6AAQBwgAAAhcAAAIHAAACZgAFAdTAAAIfAAACDwAAAnYABIHFwAACGwAAAgsAAAJuAAACAwAAAiMAAAITAAACfgAEAcDAAAIUgAACBIAFQijABMHIwAACHIAAAgyAAAJxAARBwsAAAhiAAAIIgAACaQAAAgCAAAIggAACEIAAAnkABAHBwAACFoAAAgaAAAJlAAUB0MAAAh6AAAIOgAACdQAEgcTAAAIagAACCoAAAm0AAAICgAACIoAAAhKAAAJ9AAQBwUAAAhWAAAIFgBACAAAEwczAAAIdgAACDYAAAnMABEHDwAACGYAAAgmAAAJrAAACAYAAAiGAAAIRgAACewAEAcJAAAIXgAACB4AAAmcABQHYwAACH4AAAg+AAAJ3AASBxsAAAhuAAAILgAACbwAAAgOAAAIjgAACE4AAAn8AGAHAAAACFEAAAgRABUIgwASBx8AAAhxAAAIMQAACcIAEAcKAAAIYQAACCEAAAmiAAAIAQAACIEAAAhBAAAJ4gAQBwYAAAhZAAAIGQAACZIAEwc7AAAIeQAACDkAAAnSABEHEQAACGkAAAgpAAAJsgAACAkAAAiJAAAISQAACfIAEAcEAAAIVQAACBUAEAgCARMHKwAACHUAAAg1AAAJygARBw0AAAhlAAAIJQAACaoAAAgFAAAIhQAACEUAAAnqABAHCAAACF0AAAgdAAAJmgAUB1MAAAh9AAAIPQAACdoAEgcXAAAIbQAACC0AAAm6AAAIDQAACI0AAAhNAAAJ+gAQBwMAAAhTAAAIEwAVCMMAEwcjAAAIcwAACDMAAAnGABEHCwAACGMAAAgjAAAJpgAACAMAAAiDAAAIQwAACeYAEAcHAAAIWwAACBsAAAmWABQHQwAACHsAAAg7AAAJ1gASBxMAAAhrAAAIKwAACbYAAAgLAAAIiwAACEsAAAn2ABAHBQAACFcAAAgXAEAIAAATBzMAAAh3AAAINwAACc4AEQcPAAAIZwAACCcAAAmuAAAIBwAACIcAAAhHAAAJ7gAQBwkAAAhfAAAIHwAACZ4AFAdjAAAIfwAACD8AAAneABIHGwAACG8AAAgvAAAJvgAACA8AAAiPAAAITwAACf4AYAcAAAAIUAAACBAAFAhzABIHHwAACHAAAAgwAAAJwQAQBwoAAAhgAAAIIAAACaEAAAgAAAAIgAAACEAAAAnhABAHBgAACFgAAAgYAAAJkQATBzsAAAh4AAAIOAAACdEAEQcRAAAIaAAACCgAAAmxAAAICAAACIgAAAhIAAAJ8QAQBwQAAAhUAAAIFAAVCOMAEwcrAAAIdAAACDQAAAnJABEHDQAACGQAAAgkAAAJqQAACAQAAAiEAAAIRAAACekAEAcIAAAIXAAACBwAAAmZABQHUwAACHwAAAg8AAAJ2QASBxcAAAhsAAAILAAACbkAAAgMAAAIjAAACEwAAAn5ABAHAwAACFIAAAgSABUIowATByMAAAhyAAAIMgAACcUAEQcLAAAIYgAACCIAAAmlAAAIAgAACIIAAAhCAAAJ5QAQBwcAAAhaAAAIGgAACZUAFAdDAAAIegAACDoAAAnVABIHEwAACGoAAAgqAAAJtQAACAoAAAiKAAAISgAACfUAEAcFAAAIVgAACBYAQAgAABMHMwAACHYAAAg2AAAJzQARBw8AAAhmAAAIJgAACa0AAAgGAAAIhgAACEYAAAntABAHCQAACF4AAAgeAAAJnQAUB2MAAAh+AAAIPgAACd0AEgcbAAAIbgAACC4AAAm9AAAIDgAACI4AAAhOAAAJ/QBgBwAAAAhRAAAIEQAVCIMAEgcfAAAIcQAACDEAAAnDABAHCgAACGEAAAghAAAJowAACAEAAAiBAAAIQQAACeMAEAcGAAAIWQAACBkAAAmTABMHOwAACHkAAAg5AAAJ0wARBxEAAAhpAAAIKQAACbMAAAgJAAAIiQAACEkAAAnzABAHBAAACFUAAAgVABAIAgETBysAAAh1AAAINQAACcsAEQcNAAAIZQAACCUAAAmrAAAIBQAACIUAAAhFAAAJ6wAQBwgAAAhdAAAIHQAACZsAFAdTAAAIfQAACD0AAAnbABIHFwAACG0AAAgtAAAJuwAACA0AAAiNAAAITQAACfsAEAcDAAAIUwAACBMAFQjDABMHIwAACHMAAAgzAAAJxwARBwsAAAhjAAAIIwAACacAAAgDAAAIgwAACEMAAAnnABAHBwAACFsAAAgbAAAJlwAUB0MAAAh7AAAIOwAACdcAEgcTAAAIawAACCsAAAm3AAAICwAACIsAAAhLAAAJ9wAQBwUAAAhXAAAIFwBACAAAEwczAAAIdwAACDcAAAnPABEHDwAACGcAAAgnAAAJrwAACAcAAAiHAAAIRwAACe8AEAcJAAAIXwAACB8AAAmfABQHYwAACH8AAAg/AAAJ3wASBxsAAAhvAAAILwAACb8AAAgPAAAIjwAACE8AAAn/ABAFAQAXBQEBEwURABsFARARBQUAGQUBBBUFQQAdBQFAEAUDABgFAQIUBSEAHAUBIBIFCQAaBQEIFgWBAEAFAAAQBQIAFwWBARMFGQAbBQEYEQUHABkFAQYVBWEAHQUBYBAFBAAYBQEDFAUxABwFATASBQ0AGgUBDBYFwQBABQAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAEACQsLAAAJBgsAAAsABhEAAAAREREAQYGEAQshCwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAEG7hAELAQwAQceEAQsVDAAAAAAMAAAAAAkMAAAAAAAMAAAMAEH1hAELAQ4AQYGFAQsVDQAAAAQNAAAAAAkOAAAAAAAOAAAOAEGvhQELARAAQbuFAQseDwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAEHyhQELDhIAAAASEhIAAAAAAAAJAEGjhgELAQsAQa+GAQsVCgAAAAAKAAAAAAkLAAAAAAALAAALAEHdhgELAQwAQemGAQsnDAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGAEG0hwELARkAQduHAQsF//////8AQaCIAQtXGRJEOwI/LEcUPTMwChsGRktFNw9JDo4XA0AdPGkrNh9KLRwBICUpIQgMFRYiLhA4Pgs0MRhkdHV2L0EJfzkRI0MyQomKiwUEJignDSoeNYwHGkiTE5SVAEGAiQELig5JbGxlZ2FsIGJ5dGUgc2VxdWVuY2UARG9tYWluIGVycm9yAFJlc3VsdCBub3QgcmVwcmVzZW50YWJsZQBOb3QgYSB0dHkAUGVybWlzc2lvbiBkZW5pZWQAT3BlcmF0aW9uIG5vdCBwZXJtaXR0ZWQATm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeQBObyBzdWNoIHByb2Nlc3MARmlsZSBleGlzdHMAVmFsdWUgdG9vIGxhcmdlIGZvciBkYXRhIHR5cGUATm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UAT3V0IG9mIG1lbW9yeQBSZXNvdXJjZSBidXN5AEludGVycnVwdGVkIHN5c3RlbSBjYWxsAFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlAEludmFsaWQgc2VlawBDcm9zcy1kZXZpY2UgbGluawBSZWFkLW9ubHkgZmlsZSBzeXN0ZW0ARGlyZWN0b3J5IG5vdCBlbXB0eQBDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIAT3BlcmF0aW9uIHRpbWVkIG91dABDb25uZWN0aW9uIHJlZnVzZWQASG9zdCBpcyBkb3duAEhvc3QgaXMgdW5yZWFjaGFibGUAQWRkcmVzcyBpbiB1c2UAQnJva2VuIHBpcGUASS9PIGVycm9yAE5vIHN1Y2ggZGV2aWNlIG9yIGFkZHJlc3MAQmxvY2sgZGV2aWNlIHJlcXVpcmVkAE5vIHN1Y2ggZGV2aWNlAE5vdCBhIGRpcmVjdG9yeQBJcyBhIGRpcmVjdG9yeQBUZXh0IGZpbGUgYnVzeQBFeGVjIGZvcm1hdCBlcnJvcgBJbnZhbGlkIGFyZ3VtZW50AEFyZ3VtZW50IGxpc3QgdG9vIGxvbmcAU3ltYm9saWMgbGluayBsb29wAEZpbGVuYW1lIHRvbyBsb25nAFRvbyBtYW55IG9wZW4gZmlsZXMgaW4gc3lzdGVtAE5vIGZpbGUgZGVzY3JpcHRvcnMgYXZhaWxhYmxlAEJhZCBmaWxlIGRlc2NyaXB0b3IATm8gY2hpbGQgcHJvY2VzcwBCYWQgYWRkcmVzcwBGaWxlIHRvbyBsYXJnZQBUb28gbWFueSBsaW5rcwBObyBsb2NrcyBhdmFpbGFibGUAUmVzb3VyY2UgZGVhZGxvY2sgd291bGQgb2NjdXIAU3RhdGUgbm90IHJlY292ZXJhYmxlAFByZXZpb3VzIG93bmVyIGRpZWQAT3BlcmF0aW9uIGNhbmNlbGVkAEZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZABObyBtZXNzYWdlIG9mIGRlc2lyZWQgdHlwZQBJZGVudGlmaWVyIHJlbW92ZWQARGV2aWNlIG5vdCBhIHN0cmVhbQBObyBkYXRhIGF2YWlsYWJsZQBEZXZpY2UgdGltZW91dABPdXQgb2Ygc3RyZWFtcyByZXNvdXJjZXMATGluayBoYXMgYmVlbiBzZXZlcmVkAFByb3RvY29sIGVycm9yAEJhZCBtZXNzYWdlAEZpbGUgZGVzY3JpcHRvciBpbiBiYWQgc3RhdGUATm90IGEgc29ja2V0AERlc3RpbmF0aW9uIGFkZHJlc3MgcmVxdWlyZWQATWVzc2FnZSB0b28gbGFyZ2UAUHJvdG9jb2wgd3JvbmcgdHlwZSBmb3Igc29ja2V0AFByb3RvY29sIG5vdCBhdmFpbGFibGUAUHJvdG9jb2wgbm90IHN1cHBvcnRlZABTb2NrZXQgdHlwZSBub3Qgc3VwcG9ydGVkAE5vdCBzdXBwb3J0ZWQAUHJvdG9jb2wgZmFtaWx5IG5vdCBzdXBwb3J0ZWQAQWRkcmVzcyBmYW1pbHkgbm90IHN1cHBvcnRlZCBieSBwcm90b2NvbABBZGRyZXNzIG5vdCBhdmFpbGFibGUATmV0d29yayBpcyBkb3duAE5ldHdvcmsgdW5yZWFjaGFibGUAQ29ubmVjdGlvbiByZXNldCBieSBuZXR3b3JrAENvbm5lY3Rpb24gYWJvcnRlZABObyBidWZmZXIgc3BhY2UgYXZhaWxhYmxlAFNvY2tldCBpcyBjb25uZWN0ZWQAU29ja2V0IG5vdCBjb25uZWN0ZWQAQ2Fubm90IHNlbmQgYWZ0ZXIgc29ja2V0IHNodXRkb3duAE9wZXJhdGlvbiBhbHJlYWR5IGluIHByb2dyZXNzAE9wZXJhdGlvbiBpbiBwcm9ncmVzcwBTdGFsZSBmaWxlIGhhbmRsZQBSZW1vdGUgSS9PIGVycm9yAFF1b3RhIGV4Y2VlZGVkAE5vIG1lZGl1bSBmb3VuZABXcm9uZyBtZWRpdW0gdHlwZQBObyBlcnJvciBpbmZvcm1hdGlvbgBBkJcBC1JQUFAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAAAEAAAAIAAAAlEsAALRLAEGQmQELAgxQAEHImQELCR8AAADkTAAAAwBB5JkBC4wBLfRRWM+MscBG9rXLKTEDxwRbcDC0Xf0geH+LmthZKVBoSImrp1YDbP+3zYg/1He0K6WjcPG65Kj8QYP92W/hinovLXSWBx8NCV4Ddixw90ClLKdvV0GoqnTfoFhkA0rHxDxTrq9fGAQVseNtKIarDKS/Q/DpUIE5VxZSN/////////////////////8=";y4(Rp)||(Rp=dxe(Rp));function Kxe(t){try{if(t==Rp&&lP)return new Uint8Array(lP);var e=s4(t);if(e)return e;if(aP)return aP(t);throw"sync fetching of the wasm failed: you can preload it to Module['wasmBinary'] manually, or emcc.py will do that for you when generating HTML (but not JS)"}catch(r){Gr(r)}}function Uxe(t,e){var r,i,n;try{n=Kxe(t),i=new WebAssembly.Module(n),r=new WebAssembly.Instance(i,e)}catch(o){var s=o.toString();throw Di("failed to compile wasm module: "+s),(s.includes("imported Memory")||s.includes("memory import"))&&Di("Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time)."),o}return[r,i]}function Gxe(){var t={a:Hxe};function e(n,s){var o=n.exports;oe.asm=o,ew=oe.asm.u,p4(ew.buffer),fP=oe.asm.za,Mxe(oe.asm.v),dP("wasm-instantiate")}if(E4("wasm-instantiate"),oe.instantiateWasm)try{var r=oe.instantiateWasm(t,e);return r}catch(n){return Di("Module.instantiateWasm callback failed with error: "+n),!1}var i=Uxe(Rp,t);return e(i[0]),oe.asm}var ai,ya;function hP(t){for(;t.length>0;){var e=t.shift();if(typeof e=="function"){e(oe);continue}var r=e.func;typeof r=="number"?e.arg===void 0?fP.get(r)():fP.get(r)(e.arg):r(e.arg===void 0?null:e.arg)}}function iw(t,e){var r=new Date(_e[t>>2]*1e3);_e[e>>2]=r.getUTCSeconds(),_e[e+4>>2]=r.getUTCMinutes(),_e[e+8>>2]=r.getUTCHours(),_e[e+12>>2]=r.getUTCDate(),_e[e+16>>2]=r.getUTCMonth(),_e[e+20>>2]=r.getUTCFullYear()-1900,_e[e+24>>2]=r.getUTCDay(),_e[e+36>>2]=0,_e[e+32>>2]=0;var i=Date.UTC(r.getUTCFullYear(),0,1,0,0,0,0),n=(r.getTime()-i)/(1e3*60*60*24)|0;return _e[e+28>>2]=n,iw.GMTString||(iw.GMTString=uP("GMT")),_e[e+40>>2]=iw.GMTString,e}function jxe(t,e){return iw(t,e)}var yt={splitPath:function(t){var e=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return e.exec(t).slice(1)},normalizeArray:function(t,e){for(var r=0,i=t.length-1;i>=0;i--){var n=t[i];n==="."?t.splice(i,1):n===".."?(t.splice(i,1),r++):r&&(t.splice(i,1),r--)}if(e)for(;r;r--)t.unshift("..");return t},normalize:function(t){var e=t.charAt(0)==="/",r=t.substr(-1)==="/";return t=yt.normalizeArray(t.split("/").filter(function(i){return!!i}),!e).join("/"),!t&&!e&&(t="."),t&&r&&(t+="/"),(e?"/":"")+t},dirname:function(t){var e=yt.splitPath(t),r=e[0],i=e[1];return!r&&!i?".":(i&&(i=i.substr(0,i.length-1)),r+i)},basename:function(t){if(t==="/")return"/";t=yt.normalize(t),t=t.replace(/\/$/,"");var e=t.lastIndexOf("/");return e===-1?t:t.substr(e+1)},extname:function(t){return yt.splitPath(t)[3]},join:function(){var t=Array.prototype.slice.call(arguments,0);return yt.normalize(t.join("/"))},join2:function(t,e){return yt.normalize(t+"/"+e)}};function Yxe(){if(typeof crypto=="object"&&typeof crypto.getRandomValues=="function"){var t=new Uint8Array(1);return function(){return crypto.getRandomValues(t),t[0]}}else if(Wl)try{var e=require("crypto");return function(){return e.randomBytes(1)[0]}}catch(r){}return function(){Gr("randomDevice")}}var wa={resolve:function(){for(var t="",e=!1,r=arguments.length-1;r>=-1&&!e;r--){var i=r>=0?arguments[r]:y.cwd();if(typeof i!="string")throw new TypeError("Arguments to path.resolve must be strings");if(!i)return"";t=i+"/"+t,e=i.charAt(0)==="/"}return t=yt.normalizeArray(t.split("/").filter(function(n){return!!n}),!e).join("/"),(e?"/":"")+t||"."},relative:function(t,e){t=wa.resolve(t).substr(1),e=wa.resolve(e).substr(1);function r(c){for(var u=0;u=0&&c[g]==="";g--);return u>g?[]:c.slice(u,g-u+1)}for(var i=r(t.split("/")),n=r(e.split("/")),s=Math.min(i.length,n.length),o=s,a=0;a0?e=i.slice(0,n).toString("utf-8"):e=null}else typeof window!="undefined"&&typeof window.prompt=="function"?(e=window.prompt("Input: "),e!==null&&(e+=` +`)):typeof readline=="function"&&(e=readline(),e!==null&&(e+=` +`));if(!e)return null;t.input=CP(e,!0)}return t.input.shift()},put_char:function(t,e){e===null||e===10?($y(Zu(t.output,0)),t.output=[]):e!=0&&t.output.push(e)},flush:function(t){t.output&&t.output.length>0&&($y(Zu(t.output,0)),t.output=[])}},default_tty1_ops:{put_char:function(t,e){e===null||e===10?(Di(Zu(t.output,0)),t.output=[]):e!=0&&t.output.push(e)},flush:function(t){t.output&&t.output.length>0&&(Di(Zu(t.output,0)),t.output=[])}}};function mP(t){for(var e=mxe(t,65536),r=h4(e);t=e)){var i=1024*1024;e=Math.max(e,r*(r>>0),r!=0&&(e=Math.max(e,256));var n=t.contents;t.contents=new Uint8Array(e),t.usedBytes>0&&t.contents.set(n.subarray(0,t.usedBytes),0)}},resizeFileStorage:function(t,e){if(t.usedBytes!=e)if(e==0)t.contents=null,t.usedBytes=0;else{var r=t.contents;t.contents=new Uint8Array(e),r&&t.contents.set(r.subarray(0,Math.min(e,t.usedBytes))),t.usedBytes=e}},node_ops:{getattr:function(t){var e={};return e.dev=y.isChrdev(t.mode)?t.id:1,e.ino=t.id,e.mode=t.mode,e.nlink=1,e.uid=0,e.gid=0,e.rdev=t.rdev,y.isDir(t.mode)?e.size=4096:y.isFile(t.mode)?e.size=t.usedBytes:y.isLink(t.mode)?e.size=t.link.length:e.size=0,e.atime=new Date(t.timestamp),e.mtime=new Date(t.timestamp),e.ctime=new Date(t.timestamp),e.blksize=4096,e.blocks=Math.ceil(e.size/e.blksize),e},setattr:function(t,e){e.mode!==void 0&&(t.mode=e.mode),e.timestamp!==void 0&&(t.timestamp=e.timestamp),e.size!==void 0&&pt.resizeFileStorage(t,e.size)},lookup:function(t,e){throw y.genericErrors[44]},mknod:function(t,e,r,i){return pt.createNode(t,e,r,i)},rename:function(t,e,r){if(y.isDir(t.mode)){var i;try{i=y.lookupNode(e,r)}catch(s){}if(i)for(var n in i.contents)throw new y.ErrnoError(55)}delete t.parent.contents[t.name],t.parent.timestamp=Date.now(),t.name=r,e.contents[r]=t,e.timestamp=t.parent.timestamp,t.parent=e},unlink:function(t,e){delete t.contents[e],t.timestamp=Date.now()},rmdir:function(t,e){var r=y.lookupNode(t,e);for(var i in r.contents)throw new y.ErrnoError(55);delete t.contents[e],t.timestamp=Date.now()},readdir:function(t){var e=[".",".."];for(var r in t.contents)!t.contents.hasOwnProperty(r)||e.push(r);return e},symlink:function(t,e,r){var i=pt.createNode(t,e,511|40960,0);return i.link=r,i},readlink:function(t){if(!y.isLink(t.mode))throw new y.ErrnoError(28);return t.link}},stream_ops:{read:function(t,e,r,i,n){var s=t.node.contents;if(n>=t.node.usedBytes)return 0;var o=Math.min(t.node.usedBytes-n,i);if(o>8&&s.subarray)e.set(s.subarray(n,n+o),r);else for(var a=0;a0||i+r>2)}catch(r){throw r.code?new y.ErrnoError(tt.convertNodeCode(r)):r}return e.mode},realPath:function(t){for(var e=[];t.parent!==t;)e.push(t.name),t=t.parent;return e.push(t.mount.opts.root),e.reverse(),yt.join.apply(null,e)},flagsForNode:function(t){t&=~2097152,t&=~2048,t&=~32768,t&=~524288;var e=0;for(var r in tt.flagsForNodeMap)t&r&&(e|=tt.flagsForNodeMap[r],t^=r);if(t)throw new y.ErrnoError(28);return e},node_ops:{getattr:function(t){var e=tt.realPath(t),r;try{r=ft.lstatSync(e)}catch(i){throw i.code?new y.ErrnoError(tt.convertNodeCode(i)):i}return tt.isWindows&&!r.blksize&&(r.blksize=4096),tt.isWindows&&!r.blocks&&(r.blocks=(r.size+r.blksize-1)/r.blksize|0),{dev:r.dev,ino:r.ino,mode:r.mode,nlink:r.nlink,uid:r.uid,gid:r.gid,rdev:r.rdev,size:r.size,atime:r.atime,mtime:r.mtime,ctime:r.ctime,blksize:r.blksize,blocks:r.blocks}},setattr:function(t,e){var r=tt.realPath(t);try{if(e.mode!==void 0&&(ft.chmodSync(r,e.mode),t.mode=e.mode),e.timestamp!==void 0){var i=new Date(e.timestamp);ft.utimesSync(r,i,i)}e.size!==void 0&&ft.truncateSync(r,e.size)}catch(n){throw n.code?new y.ErrnoError(tt.convertNodeCode(n)):n}},lookup:function(t,e){var r=yt.join2(tt.realPath(t),e),i=tt.getMode(r);return tt.createNode(t,e,i)},mknod:function(t,e,r,i){var n=tt.createNode(t,e,r,i),s=tt.realPath(n);try{y.isDir(n.mode)?ft.mkdirSync(s,n.mode):ft.writeFileSync(s,"",{mode:n.mode})}catch(o){throw o.code?new y.ErrnoError(tt.convertNodeCode(o)):o}return n},rename:function(t,e,r){var i=tt.realPath(t),n=yt.join2(tt.realPath(e),r);try{ft.renameSync(i,n)}catch(s){throw s.code?new y.ErrnoError(tt.convertNodeCode(s)):s}t.name=r},unlink:function(t,e){var r=yt.join2(tt.realPath(t),e);try{ft.unlinkSync(r)}catch(i){throw i.code?new y.ErrnoError(tt.convertNodeCode(i)):i}},rmdir:function(t,e){var r=yt.join2(tt.realPath(t),e);try{ft.rmdirSync(r)}catch(i){throw i.code?new y.ErrnoError(tt.convertNodeCode(i)):i}},readdir:function(t){var e=tt.realPath(t);try{return ft.readdirSync(e)}catch(r){throw r.code?new y.ErrnoError(tt.convertNodeCode(r)):r}},symlink:function(t,e,r){var i=yt.join2(tt.realPath(t),e);try{ft.symlinkSync(r,i)}catch(n){throw n.code?new y.ErrnoError(tt.convertNodeCode(n)):n}},readlink:function(t){var e=tt.realPath(t);try{return e=ft.readlinkSync(e),e=EP.relative(EP.resolve(t.mount.opts.root),e),e}catch(r){throw r.code?new y.ErrnoError(tt.convertNodeCode(r)):r}}},stream_ops:{open:function(t){var e=tt.realPath(t.node);try{y.isFile(t.node.mode)&&(t.nfd=ft.openSync(e,tt.flagsForNode(t.flags)))}catch(r){throw r.code?new y.ErrnoError(tt.convertNodeCode(r)):r}},close:function(t){try{y.isFile(t.node.mode)&&t.nfd&&ft.closeSync(t.nfd)}catch(e){throw e.code?new y.ErrnoError(tt.convertNodeCode(e)):e}},read:function(t,e,r,i,n){if(i===0)return 0;try{return ft.readSync(t.nfd,tt.bufferFrom(e.buffer),r,i,n)}catch(s){throw new y.ErrnoError(tt.convertNodeCode(s))}},write:function(t,e,r,i,n){try{return ft.writeSync(t.nfd,tt.bufferFrom(e.buffer),r,i,n)}catch(s){throw new y.ErrnoError(tt.convertNodeCode(s))}},llseek:function(t,e,r){var i=e;if(r===1)i+=t.position;else if(r===2&&y.isFile(t.node.mode))try{var n=ft.fstatSync(t.nfd);i+=n.size}catch(s){throw new y.ErrnoError(tt.convertNodeCode(s))}if(i<0)throw new y.ErrnoError(28);return i},mmap:function(t,e,r,i,n,s){if(e!==0)throw new y.ErrnoError(28);if(!y.isFile(t.node.mode))throw new y.ErrnoError(43);var o=mP(r);return tt.stream_ops.read(t,Zi,o,r,i),{ptr:o,allocated:!0}},msync:function(t,e,r,i,n){if(!y.isFile(t.node.mode))throw new y.ErrnoError(43);if(n&2)return 0;var s=tt.stream_ops.write(t,e,0,i,r,!1);return 0}}},w4={lookupPath:function(t){return{path:t,node:{mode:tt.getMode(t)}}},createStandardStreams:function(){y.streams[0]={fd:0,nfd:0,position:0,path:"",flags:0,tty:!0,seekable:!1};for(var t=1;t<3;t++)y.streams[t]={fd:t,nfd:t,position:0,path:"",flags:577,tty:!0,seekable:!1}},cwd:function(){return process.cwd()},chdir:function(){process.chdir.apply(void 0,arguments)},mknod:function(t,e){y.isDir(t)?ft.mkdirSync(t,e):ft.writeFileSync(t,"",{mode:e})},mkdir:function(){ft.mkdirSync.apply(void 0,arguments)},symlink:function(){ft.symlinkSync.apply(void 0,arguments)},rename:function(){ft.renameSync.apply(void 0,arguments)},rmdir:function(){ft.rmdirSync.apply(void 0,arguments)},readdir:function(){ft.readdirSync.apply(void 0,arguments)},unlink:function(){ft.unlinkSync.apply(void 0,arguments)},readlink:function(){return ft.readlinkSync.apply(void 0,arguments)},stat:function(){return ft.statSync.apply(void 0,arguments)},lstat:function(){return ft.lstatSync.apply(void 0,arguments)},chmod:function(){ft.chmodSync.apply(void 0,arguments)},fchmod:function(){ft.fchmodSync.apply(void 0,arguments)},chown:function(){ft.chownSync.apply(void 0,arguments)},fchown:function(){ft.fchownSync.apply(void 0,arguments)},truncate:function(){ft.truncateSync.apply(void 0,arguments)},ftruncate:function(t,e){if(e<0)throw new y.ErrnoError(28);ft.ftruncateSync.apply(void 0,arguments)},utime:function(){ft.utimesSync.apply(void 0,arguments)},open:function(t,e,r,i){typeof e=="string"&&(e=Vl.modeStringToFlags(e));var n=ft.openSync(t,tt.flagsForNode(e),r),s=i!=null?i:y.nextfd(n),o={fd:s,nfd:n,position:0,path:t,flags:e,seekable:!0};return y.streams[s]=o,o},close:function(t){t.stream_ops||ft.closeSync(t.nfd),y.closeStream(t.fd)},llseek:function(t,e,r){if(t.stream_ops)return Vl.llseek(t,e,r);var i=e;if(r===1)i+=t.position;else if(r===2)i+=ft.fstatSync(t.nfd).size;else if(r!==0)throw new y.ErrnoError(eg.EINVAL);if(i<0)throw new y.ErrnoError(eg.EINVAL);return t.position=i,i},read:function(t,e,r,i,n){if(t.stream_ops)return Vl.read(t,e,r,i,n);var s=typeof n!="undefined";!s&&t.seekable&&(n=t.position);var o=ft.readSync(t.nfd,tt.bufferFrom(e.buffer),r,i,n);return s||(t.position+=o),o},write:function(t,e,r,i,n){if(t.stream_ops)return Vl.write(t,e,r,i,n);t.flags&+"1024"&&y.llseek(t,0,+"2");var s=typeof n!="undefined";!s&&t.seekable&&(n=t.position);var o=ft.writeSync(t.nfd,tt.bufferFrom(e.buffer),r,i,n);return s||(t.position+=o),o},allocate:function(){throw new y.ErrnoError(eg.EOPNOTSUPP)},mmap:function(t,e,r,i,n,s){if(t.stream_ops)return Vl.mmap(t,e,r,i,n,s);if(e!==0)throw new y.ErrnoError(28);var o=mP(r);return y.read(t,Zi,o,r,i),{ptr:o,allocated:!0}},msync:function(t,e,r,i,n){return t.stream_ops?Vl.msync(t,e,r,i,n):(n&2||y.write(t,e,0,i,r),0)},munmap:function(){return 0},ioctl:function(){throw new y.ErrnoError(eg.ENOTTY)}},y={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:!1,ignorePermissions:!0,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:function(t,e){if(t=wa.resolve(y.cwd(),t),e=e||{},!t)return{path:"",node:null};var r={follow_mount:!0,recurse_count:0};for(var i in r)e[i]===void 0&&(e[i]=r[i]);if(e.recurse_count>8)throw new y.ErrnoError(32);for(var n=yt.normalizeArray(t.split("/").filter(function(f){return!!f}),!1),s=y.root,o="/",a=0;a40)throw new y.ErrnoError(32)}}return{path:o,node:s}},getPath:function(t){for(var e;;){if(y.isRoot(t)){var r=t.mount.mountpoint;return e?r[r.length-1]!=="/"?r+"/"+e:r+e:r}e=e?t.name+"/"+e:t.name,t=t.parent}},hashName:function(t,e){for(var r=0,i=0;i>>0)%y.nameTable.length},hashAddNode:function(t){var e=y.hashName(t.parent.id,t.name);t.name_next=y.nameTable[e],y.nameTable[e]=t},hashRemoveNode:function(t){var e=y.hashName(t.parent.id,t.name);if(y.nameTable[e]===t)y.nameTable[e]=t.name_next;else for(var r=y.nameTable[e];r;){if(r.name_next===t){r.name_next=t.name_next;break}r=r.name_next}},lookupNode:function(t,e){var r=y.mayLookup(t);if(r)throw new y.ErrnoError(r,t);for(var i=y.hashName(t.id,e),n=y.nameTable[i];n;n=n.name_next){var s=n.name;if(n.parent.id===t.id&&s===e)return n}return y.lookup(t,e)},createNode:function(t,e,r,i){var n=new y.FSNode(t,e,r,i);return y.hashAddNode(n),n},destroyNode:function(t){y.hashRemoveNode(t)},isRoot:function(t){return t===t.parent},isMountpoint:function(t){return!!t.mounted},isFile:function(t){return(t&61440)==32768},isDir:function(t){return(t&61440)==16384},isLink:function(t){return(t&61440)==40960},isChrdev:function(t){return(t&61440)==8192},isBlkdev:function(t){return(t&61440)==24576},isFIFO:function(t){return(t&61440)==4096},isSocket:function(t){return(t&49152)==49152},flagModes:{r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090},modeStringToFlags:function(t){var e=y.flagModes[t];if(typeof e=="undefined")throw new Error("Unknown file open mode: "+t);return e},flagsToPermissionString:function(t){var e=["r","w","rw"][t&3];return t&512&&(e+="w"),e},nodePermissions:function(t,e){return y.ignorePermissions?0:e.includes("r")&&!(t.mode&292)||e.includes("w")&&!(t.mode&146)||e.includes("x")&&!(t.mode&73)?2:0},mayLookup:function(t){var e=y.nodePermissions(t,"x");return e||(t.node_ops.lookup?0:2)},mayCreate:function(t,e){try{var r=y.lookupNode(t,e);return 20}catch(i){}return y.nodePermissions(t,"wx")},mayDelete:function(t,e,r){var i;try{i=y.lookupNode(t,e)}catch(s){return s.errno}var n=y.nodePermissions(t,"wx");if(n)return n;if(r){if(!y.isDir(i.mode))return 54;if(y.isRoot(i)||y.getPath(i)===y.cwd())return 10}else if(y.isDir(i.mode))return 31;return 0},mayOpen:function(t,e){return t?y.isLink(t.mode)?32:y.isDir(t.mode)&&(y.flagsToPermissionString(e)!=="r"||e&512)?31:y.nodePermissions(t,y.flagsToPermissionString(e)):44},MAX_OPEN_FDS:4096,nextfd:function(t,e){t=t||0,e=e||y.MAX_OPEN_FDS;for(var r=t;r<=e;r++)if(!y.streams[r])return r;throw new y.ErrnoError(33)},getStream:function(t){return y.streams[t]},createStream:function(t,e,r){y.FSStream||(y.FSStream=function(){},y.FSStream.prototype={object:{get:function(){return this.node},set:function(o){this.node=o}},isRead:{get:function(){return(this.flags&2097155)!=1}},isWrite:{get:function(){return(this.flags&2097155)!=0}},isAppend:{get:function(){return this.flags&1024}}});var i=new y.FSStream;for(var n in t)i[n]=t[n];t=i;var s=y.nextfd(e,r);return t.fd=s,y.streams[s]=t,t},closeStream:function(t){y.streams[t]=null},chrdev_stream_ops:{open:function(t){var e=y.getDevice(t.node.rdev);t.stream_ops=e.stream_ops,t.stream_ops.open&&t.stream_ops.open(t)},llseek:function(){throw new y.ErrnoError(70)}},major:function(t){return t>>8},minor:function(t){return t&255},makedev:function(t,e){return t<<8|e},registerDevice:function(t,e){y.devices[t]={stream_ops:e}},getDevice:function(t){return y.devices[t]},getMounts:function(t){for(var e=[],r=[t];r.length;){var i=r.pop();e.push(i),r.push.apply(r,i.mounts)}return e},syncfs:function(t,e){typeof t=="function"&&(e=t,t=!1),y.syncFSRequests++,y.syncFSRequests>1&&Di("warning: "+y.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work");var r=y.getMounts(y.root.mount),i=0;function n(o){return y.syncFSRequests--,e(o)}function s(o){if(o)return s.errored?void 0:(s.errored=!0,n(o));++i>=r.length&&n(null)}r.forEach(function(o){if(!o.type.syncfs)return s(null);o.type.syncfs(o,t,s)})},mount:function(t,e,r){var i=r==="/",n=!r,s;if(i&&y.root)throw new y.ErrnoError(10);if(!i&&!n){var o=y.lookupPath(r,{follow_mount:!1});if(r=o.path,s=o.node,y.isMountpoint(s))throw new y.ErrnoError(10);if(!y.isDir(s.mode))throw new y.ErrnoError(54)}var a={type:t,opts:e,mountpoint:r,mounts:[]},l=t.mount(a);return l.mount=a,a.root=l,i?y.root=l:s&&(s.mounted=a,s.mount&&s.mount.mounts.push(a)),l},unmount:function(t){var e=y.lookupPath(t,{follow_mount:!1});if(!y.isMountpoint(e.node))throw new y.ErrnoError(28);var r=e.node,i=r.mounted,n=y.getMounts(i);Object.keys(y.nameTable).forEach(function(o){for(var a=y.nameTable[o];a;){var l=a.name_next;n.includes(a.mount)&&y.destroyNode(a),a=l}}),r.mounted=null;var s=r.mount.mounts.indexOf(i);r.mount.mounts.splice(s,1)},lookup:function(t,e){return t.node_ops.lookup(t,e)},mknod:function(t,e,r){var i=y.lookupPath(t,{parent:!0}),n=i.node,s=yt.basename(t);if(!s||s==="."||s==="..")throw new y.ErrnoError(28);var o=y.mayCreate(n,s);if(o)throw new y.ErrnoError(o);if(!n.node_ops.mknod)throw new y.ErrnoError(63);return n.node_ops.mknod(n,s,e,r)},create:function(t,e){return e=e!==void 0?e:438,e&=4095,e|=32768,y.mknod(t,e,0)},mkdir:function(t,e){return e=e!==void 0?e:511,e&=511|512,e|=16384,y.mknod(t,e,0)},mkdirTree:function(t,e){for(var r=t.split("/"),i="",n=0;nthis.length-1||f<0)){var h=f%this.chunkSize,p=f/this.chunkSize|0;return this.getter(p)[h]}},s.prototype.setDataGetter=function(f){this.getter=f},s.prototype.cacheLength=function(){var f=new XMLHttpRequest;if(f.open("HEAD",r,!1),f.send(null),!(f.status>=200&&f.status<300||f.status===304))throw new Error("Couldn't load "+r+". Status: "+f.status);var h=Number(f.getResponseHeader("Content-length")),p,d=(p=f.getResponseHeader("Accept-Ranges"))&&p==="bytes",m=(p=f.getResponseHeader("Content-Encoding"))&&p==="gzip",I=1024*1024;d||(I=h);var B=function(R,H){if(R>H)throw new Error("invalid range ("+R+", "+H+") or no bytes requested!");if(H>h-1)throw new Error("only "+h+" bytes available! programmer error!");var L=new XMLHttpRequest;if(L.open("GET",r,!1),h!==I&&L.setRequestHeader("Range","bytes="+R+"-"+H),typeof Uint8Array!="undefined"&&(L.responseType="arraybuffer"),L.overrideMimeType&&L.overrideMimeType("text/plain; charset=x-user-defined"),L.send(null),!(L.status>=200&&L.status<300||L.status===304))throw new Error("Couldn't load "+r+". Status: "+L.status);return L.response!==void 0?new Uint8Array(L.response||[]):CP(L.responseText||"",!0)},b=this;b.setDataGetter(function(R){var H=R*I,L=(R+1)*I-1;if(L=Math.min(L,h-1),typeof b.chunks[R]=="undefined"&&(b.chunks[R]=B(H,L)),typeof b.chunks[R]=="undefined")throw new Error("doXHR failed!");return b.chunks[R]}),(m||!h)&&(I=h=1,h=this.getter(0).length,I=h,$y("LazyFiles on gzip forces download of the whole file when length is accessed")),this._length=h,this._chunkSize=I,this.lengthKnown=!0},typeof XMLHttpRequest!="undefined"){if(!i4)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var o=new s;Object.defineProperties(o,{length:{get:function(){return this.lengthKnown||this.cacheLength(),this._length}},chunkSize:{get:function(){return this.lengthKnown||this.cacheLength(),this._chunkSize}}});var a={isDevice:!1,contents:o}}else var a={isDevice:!1,url:r};var l=y.createFile(t,e,a,i,n);a.contents?l.contents=a.contents:a.url&&(l.contents=null,l.url=a.url),Object.defineProperties(l,{usedBytes:{get:function(){return this.contents.length}}});var c={},u=Object.keys(l.stream_ops);return u.forEach(function(g){var f=l.stream_ops[g];c[g]=function(){return y.forceLoadFile(l),f.apply(null,arguments)}}),c.read=function(f,h,p,d,m){y.forceLoadFile(l);var I=f.node.contents;if(m>=I.length)return 0;var B=Math.min(I.length-m,d);if(I.slice)for(var b=0;b>2]=i.dev,_e[r+4>>2]=0,_e[r+8>>2]=i.ino,_e[r+12>>2]=i.mode,_e[r+16>>2]=i.nlink,_e[r+20>>2]=i.uid,_e[r+24>>2]=i.gid,_e[r+28>>2]=i.rdev,_e[r+32>>2]=0,ya=[i.size>>>0,(ai=i.size,+Math.abs(ai)>=1?ai>0?(Math.min(+Math.floor(ai/4294967296),4294967295)|0)>>>0:~~+Math.ceil((ai-+(~~ai>>>0))/4294967296)>>>0:0)],_e[r+40>>2]=ya[0],_e[r+44>>2]=ya[1],_e[r+48>>2]=4096,_e[r+52>>2]=i.blocks,_e[r+56>>2]=i.atime.getTime()/1e3|0,_e[r+60>>2]=0,_e[r+64>>2]=i.mtime.getTime()/1e3|0,_e[r+68>>2]=0,_e[r+72>>2]=i.ctime.getTime()/1e3|0,_e[r+76>>2]=0,ya=[i.ino>>>0,(ai=i.ino,+Math.abs(ai)>=1?ai>0?(Math.min(+Math.floor(ai/4294967296),4294967295)|0)>>>0:~~+Math.ceil((ai-+(~~ai>>>0))/4294967296)>>>0:0)],_e[r+80>>2]=ya[0],_e[r+84>>2]=ya[1],0},doMsync:function(t,e,r,i,n){var s=$u.slice(t,t+r);y.msync(e,s,n,r,i)},doMkdir:function(t,e){return t=yt.normalize(t),t[t.length-1]==="/"&&(t=t.substr(0,t.length-1)),y.mkdir(t,e,0),0},doMknod:function(t,e,r){switch(e&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}return y.mknod(t,e,r),0},doReadlink:function(t,e,r){if(r<=0)return-28;var i=y.readlink(t),n=Math.min(r,rw(i)),s=Zi[e+n];return u4(i,e,r+1),Zi[e+n]=s,n},doAccess:function(t,e){if(e&~7)return-28;var r,i=y.lookupPath(t,{follow:!0});if(r=i.node,!r)return-44;var n="";return e&4&&(n+="r"),e&2&&(n+="w"),e&1&&(n+="x"),n&&y.nodePermissions(r,n)?-2:0},doDup:function(t,e,r){var i=y.getStream(r);return i&&y.close(i),y.open(t,e,0,r,r).fd},doReadv:function(t,e,r,i){for(var n=0,s=0;s>2],a=_e[e+(s*8+4)>>2],l=y.read(t,Zi,o,a,i);if(l<0)return-1;if(n+=l,l>2],a=_e[e+(s*8+4)>>2],l=y.write(t,Zi,o,a,i);if(l<0)return-1;n+=l}return n},varargs:void 0,get:function(){Ot.varargs+=4;var t=_e[Ot.varargs-4>>2];return t},getStr:function(t){var e=c4(t);return e},getStreamFromFD:function(t){var e=y.getStream(t);if(!e)throw new y.ErrnoError(8);return e},get64:function(t,e){return t}};function qxe(t,e){try{return t=Ot.getStr(t),y.chmod(t,e),0}catch(r){return(typeof y=="undefined"||!(r instanceof y.ErrnoError))&&Gr(r),-r.errno}}function Wxe(t){return _e[Jxe()>>2]=t,t}function zxe(t,e,r){Ot.varargs=r;try{var i=Ot.getStreamFromFD(t);switch(e){case 0:{var n=Ot.get();if(n<0)return-28;var s;return s=y.open(i.path,i.flags,0,n),s.fd}case 1:case 2:return 0;case 3:return i.flags;case 4:{var n=Ot.get();return i.flags|=n,0}case 12:{var n=Ot.get(),o=0;return cP[n+o>>1]=2,0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:return Wxe(28),-1;default:return-28}}catch(a){return(typeof y=="undefined"||!(a instanceof y.ErrnoError))&&Gr(a),-a.errno}}function Vxe(t,e){try{var r=Ot.getStreamFromFD(t);return Ot.doStat(y.stat,r.path,e)}catch(i){return(typeof y=="undefined"||!(i instanceof y.ErrnoError))&&Gr(i),-i.errno}}function _xe(t,e,r){Ot.varargs=r;try{var i=Ot.getStreamFromFD(t);switch(e){case 21509:case 21505:return i.tty?0:-59;case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:return i.tty?0:-59;case 21519:{if(!i.tty)return-59;var n=Ot.get();return _e[n>>2]=0,0}case 21520:return i.tty?-28:-59;case 21531:{var n=Ot.get();return y.ioctl(i,e,n)}case 21523:return i.tty?0:-59;case 21524:return i.tty?0:-59;default:Gr("bad ioctl syscall "+e)}}catch(s){return(typeof y=="undefined"||!(s instanceof y.ErrnoError))&&Gr(s),-s.errno}}function Xxe(t,e,r){Ot.varargs=r;try{var i=Ot.getStr(t),n=r?Ot.get():0,s=y.open(i,e,n);return s.fd}catch(o){return(typeof y=="undefined"||!(o instanceof y.ErrnoError))&&Gr(o),-o.errno}}function Zxe(t,e){try{return t=Ot.getStr(t),e=Ot.getStr(e),y.rename(t,e),0}catch(r){return(typeof y=="undefined"||!(r instanceof y.ErrnoError))&&Gr(r),-r.errno}}function $xe(t){try{return t=Ot.getStr(t),y.rmdir(t),0}catch(e){return(typeof y=="undefined"||!(e instanceof y.ErrnoError))&&Gr(e),-e.errno}}function eke(t,e){try{return t=Ot.getStr(t),Ot.doStat(y.stat,t,e)}catch(r){return(typeof y=="undefined"||!(r instanceof y.ErrnoError))&&Gr(r),-r.errno}}function tke(t){try{return t=Ot.getStr(t),y.unlink(t),0}catch(e){return(typeof y=="undefined"||!(e instanceof y.ErrnoError))&&Gr(e),-e.errno}}function rke(t,e,r){$u.copyWithin(t,e,e+r)}function ike(t){try{return ew.grow(t-gP.byteLength+65535>>>16),p4(ew.buffer),1}catch(e){}}function nke(t){var e=$u.length;t=t>>>0;var r=2147483648;if(t>r)return!1;for(var i=1;i<=4;i*=2){var n=e*(1+.2/i);n=Math.min(n,t+100663296);var s=Math.min(r,xxe(Math.max(t,n),65536)),o=ike(s);if(o)return!0}return!1}function ske(t){try{var e=Ot.getStreamFromFD(t);return y.close(e),0}catch(r){return(typeof y=="undefined"||!(r instanceof y.ErrnoError))&&Gr(r),r.errno}}function oke(t,e){try{var r=Ot.getStreamFromFD(t),i=r.tty?2:y.isDir(r.mode)?3:y.isLink(r.mode)?7:4;return Zi[e>>0]=i,0}catch(n){return(typeof y=="undefined"||!(n instanceof y.ErrnoError))&&Gr(n),n.errno}}function ake(t,e,r,i){try{var n=Ot.getStreamFromFD(t),s=Ot.doReadv(n,e,r);return _e[i>>2]=s,0}catch(o){return(typeof y=="undefined"||!(o instanceof y.ErrnoError))&&Gr(o),o.errno}}function Ake(t,e,r,i,n){try{var s=Ot.getStreamFromFD(t),o=4294967296,a=r*o+(e>>>0),l=9007199254740992;return a<=-l||a>=l?-61:(y.llseek(s,a,i),ya=[s.position>>>0,(ai=s.position,+Math.abs(ai)>=1?ai>0?(Math.min(+Math.floor(ai/4294967296),4294967295)|0)>>>0:~~+Math.ceil((ai-+(~~ai>>>0))/4294967296)>>>0:0)],_e[n>>2]=ya[0],_e[n+4>>2]=ya[1],s.getdents&&a===0&&i===0&&(s.getdents=null),0)}catch(c){return(typeof y=="undefined"||!(c instanceof y.ErrnoError))&&Gr(c),c.errno}}function lke(t,e,r,i){try{var n=Ot.getStreamFromFD(t),s=Ot.doWritev(n,e,r);return _e[i>>2]=s,0}catch(o){return(typeof y=="undefined"||!(o instanceof y.ErrnoError))&&Gr(o),o.errno}}function cke(t){Ixe(t)}function uke(t){var e=Date.now()/1e3|0;return t&&(_e[t>>2]=e),e}function IP(){if(IP.called)return;IP.called=!0;var t=new Date().getFullYear(),e=new Date(t,0,1),r=new Date(t,6,1),i=e.getTimezoneOffset(),n=r.getTimezoneOffset(),s=Math.max(i,n);_e[fke()>>2]=s*60,_e[gke()>>2]=Number(i!=n);function o(g){var f=g.toTimeString().match(/\(([A-Za-z ]+)\)$/);return f?f[1]:"GMT"}var a=o(e),l=o(r),c=uP(a),u=uP(l);n>2]=c,_e[nw()+4>>2]=u):(_e[nw()>>2]=u,_e[nw()+4>>2]=c)}function hke(t){IP();var e=Date.UTC(_e[t+20>>2]+1900,_e[t+16>>2],_e[t+12>>2],_e[t+8>>2],_e[t+4>>2],_e[t>>2],0),r=new Date(e);_e[t+24>>2]=r.getUTCDay();var i=Date.UTC(r.getUTCFullYear(),0,1,0,0,0,0),n=(r.getTime()-i)/(1e3*60*60*24)|0;return _e[t+28>>2]=n,r.getTime()/1e3|0}var B4=function(t,e,r,i){t||(t=this),this.parent=t,this.mount=t.mount,this.mounted=null,this.id=y.nextInode++,this.name=e,this.mode=r,this.node_ops={},this.stream_ops={},this.rdev=i},sw=292|73,ow=146;Object.defineProperties(B4.prototype,{read:{get:function(){return(this.mode&sw)===sw},set:function(t){t?this.mode|=sw:this.mode&=~sw}},write:{get:function(){return(this.mode&ow)===ow},set:function(t){t?this.mode|=ow:this.mode&=~ow}},isFolder:{get:function(){return y.isDir(this.mode)}},isDevice:{get:function(){return y.isChrdev(this.mode)}}});y.FSNode=B4;y.staticInit();Wl&&(ft=e4,EP=require("path"),tt.staticInit());var ft,EP;if(Wl){Q4=function(t){return function(){try{return t.apply(this,arguments)}catch(e){throw e.code?new y.ErrnoError(eg[e.code]):e}}},Vl=Object.assign({},y);for(yP in w4)y[yP]=Q4(w4[yP])}else throw new Error("NODERAWFS is currently only supported on Node.js environment.");var Q4,Vl,yP;function CP(t,e,r){var i=r>0?r:rw(t)+1,n=new Array(i),s=tw(t,n,0,n.length);return e&&(n.length=s),n}var pke=typeof atob=="function"?atob:function(t){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r="",i,n,s,o,a,l,c,u=0;t=t.replace(/[^A-Za-z0-9\+\/\=]/g,"");do o=e.indexOf(t.charAt(u++)),a=e.indexOf(t.charAt(u++)),l=e.indexOf(t.charAt(u++)),c=e.indexOf(t.charAt(u++)),i=o<<2|a>>4,n=(a&15)<<4|l>>2,s=(l&3)<<6|c,r=r+String.fromCharCode(i),l!==64&&(r=r+String.fromCharCode(n)),c!==64&&(r=r+String.fromCharCode(s));while(u0||(Fxe(),zl>0))return;function e(){aw||(aw=!0,oe.calledRun=!0,!A4&&(Nxe(),oe.onRuntimeInitialized&&oe.onRuntimeInitialized(),Txe()))}oe.setStatus?(oe.setStatus("Running..."),setTimeout(function(){setTimeout(function(){oe.setStatus("")},1),e()},1)):e()}oe.run=wP;if(oe.preInit)for(typeof oe.preInit=="function"&&(oe.preInit=[oe.preInit]);oe.preInit.length>0;)oe.preInit.pop()();wP()});var x4=E((Dot,S4)=>{"use strict";function Cke(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function _l(t,e,r,i){this.message=t,this.expected=e,this.found=r,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,_l)}Cke(_l,Error);_l.buildMessage=function(t,e){var r={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g>",ee=At(">>",!1),Ue=">&",Oe=At(">&",!1),vt=">",dt=At(">",!1),ri="<<<",ii=At("<<<",!1),an="<&",yr=At("<&",!1),Ki="<",Qi=At("<",!1),Go=function(C){return{type:"argument",segments:[].concat(...C)}},wr=function(C){return C},Ui="'",ws=At("'",!1),Tf=function(C){return[{type:"text",text:C}]},Mf='"',Rm=At('"',!1),Fm=function(C){return C},Nm=function(C){return{type:"arithmetic",arithmetic:C,quoted:!0}},DQ=function(C){return{type:"shell",shell:C,quoted:!0}},RQ=function(C){return _(P({type:"variable"},C),{quoted:!0})},Of=function(C){return{type:"text",text:C}},FQ=function(C){return{type:"arithmetic",arithmetic:C,quoted:!1}},NQ=function(C){return{type:"shell",shell:C,quoted:!1}},Lm=function(C){return _(P({type:"variable"},C),{quoted:!1})},LQ=function(C){return{type:"glob",pattern:C}},Va="\\",jo=At("\\",!1),Tm=/^[\\']/,Mm=Qs(["\\","'"],!1,!1),te=function(C){return C},Om=/^[^']/,Km=Qs(["'"],!0,!1),il=function(C){return C.join("")},Um=/^[\\$"]/,Hm=Qs(["\\","$",'"'],!1,!1),Kf=/^[^$"]/,Gm=Qs(["$",'"'],!0,!1),jm="\\0",TQ=At("\\0",!1),MQ=function(){return"\0"},Ym="\\a",qm=At("\\a",!1),Jm=function(){return"a"},Wm="\\b",zm=At("\\b",!1),Vm=function(){return"\b"},Uf="\\e",OQ=At("\\e",!1),KQ=function(){return""},_m="\\f",UQ=At("\\f",!1),HQ=function(){return"\f"},O="\\n",ht=At("\\n",!1),Vc=function(){return` +`},xn="\\r",Hf=At("\\r",!1),Ye=function(){return"\r"},nl="\\t",Xm=At("\\t",!1),MM=function(){return" "},GQ="\\v",OM=At("\\v",!1),fr=function(){return"\v"},Bs="\\x",jQ=At("\\x",!1),Zm=function(C){return String.fromCharCode(parseInt(C,16))},Yo="\\u",$m=At("\\u",!1),_a="\\U",et=At("\\U",!1),YQ=function(C){return String.fromCodePoint(parseInt(C,16))},eE=/^[0-9a-fA-f]/,tE=Qs([["0","9"],["a","f"],["A","f"]],!1,!1),Xa=Cfe(),sl="-",ol=At("-",!1),al="+",qo=At("+",!1),Al=".",qQ=At(".",!1),rE=function(C,Q,k){return{type:"number",value:(C==="-"?-1:1)*parseFloat(Q.join("")+"."+k.join(""))}},iE=function(C,Q){return{type:"number",value:(C==="-"?-1:1)*parseInt(Q.join(""))}},JQ=function(C){return P({type:"variable"},C)},ll=function(C){return{type:"variable",name:C}},WQ=function(C){return C},nE="*",Gf=At("*",!1),_c="/",jf=At("/",!1),sE=function(C,Q,k){return{type:Q==="*"?"multiplication":"division",right:k}},cl=function(C,Q){return Q.reduce((k,N)=>P({left:k},N),C)},oE=function(C,Q,k){return{type:Q==="+"?"addition":"subtraction",right:k}},Yf="$((",Xc=At("$((",!1),xr="))",KM=At("))",!1),Jo=function(C){return C},Zs="$(",aE=At("$(",!1),Zc=function(C){return C},x="${",U=At("${",!1),le=":-",xe=At(":-",!1),Qe=function(C,Q){return{name:C,defaultValue:Q}},Ge=":-}",ct=At(":-}",!1),sr=function(C){return{name:C,defaultValue:[]}},Wo=function(C){return{name:C}},Afe="$",lfe=At("$",!1),cfe=function(C){return e.isGlobPattern(C)},ufe=function(C){return C},UM=/^[a-zA-Z0-9_]/,HM=Qs([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),GM=function(){return dfe()},jM=/^[$@*?#a-zA-Z0-9_\-]/,YM=Qs(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),gfe=/^[(){}<>$|&; \t"']/,ffe=Qs(["(",")","{","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),hfe=/^[<>&; \t"']/,pfe=Qs(["<",">","&",";"," "," ",'"',"'"],!1,!1),qM=/^[ \t]/,JM=Qs([" "," "],!1,!1),w=0,Re=0,AE=[{line:1,column:1}],$s=0,zQ=[],we=0,lE;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function dfe(){return t.substring(Re,w)}function P_e(){return qf(Re,w)}function D_e(C,Q){throw Q=Q!==void 0?Q:qf(Re,w),zM([Efe(C)],t.substring(Re,w),Q)}function R_e(C,Q){throw Q=Q!==void 0?Q:qf(Re,w),Ife(C,Q)}function At(C,Q){return{type:"literal",text:C,ignoreCase:Q}}function Qs(C,Q,k){return{type:"class",parts:C,inverted:Q,ignoreCase:k}}function Cfe(){return{type:"any"}}function mfe(){return{type:"end"}}function Efe(C){return{type:"other",description:C}}function WM(C){var Q=AE[C],k;if(Q)return Q;for(k=C-1;!AE[k];)k--;for(Q=AE[k],Q={line:Q.line,column:Q.column};k$s&&($s=w,zQ=[]),zQ.push(C))}function Ife(C,Q){return new _l(C,null,null,Q)}function zM(C,Q,k){return new _l(_l.buildMessage(C,Q),C,Q,k)}function VM(){var C,Q;return C=w,Q=Jf(),Q===r&&(Q=null),Q!==r&&(Re=C,Q=s(Q)),C=Q,C}function Jf(){var C,Q,k,N,Z;if(C=w,Q=VQ(),Q!==r){for(k=[],N=ke();N!==r;)k.push(N),N=ke();k!==r?(N=_M(),N!==r?(Z=yfe(),Z===r&&(Z=null),Z!==r?(Re=C,Q=o(Q,N,Z),C=Q):(w=C,C=r)):(w=C,C=r)):(w=C,C=r)}else w=C,C=r;if(C===r)if(C=w,Q=VQ(),Q!==r){for(k=[],N=ke();N!==r;)k.push(N),N=ke();k!==r?(N=_M(),N===r&&(N=null),N!==r?(Re=C,Q=a(Q,N),C=Q):(w=C,C=r)):(w=C,C=r)}else w=C,C=r;return C}function yfe(){var C,Q,k,N,Z;for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r)if(k=Jf(),k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();N!==r?(Re=C,Q=l(k),C=Q):(w=C,C=r)}else w=C,C=r;else w=C,C=r;return C}function _M(){var C;return t.charCodeAt(w)===59?(C=c,w++):(C=r,we===0&&ve(u)),C===r&&(t.charCodeAt(w)===38?(C=g,w++):(C=r,we===0&&ve(f))),C}function VQ(){var C,Q,k;return C=w,Q=XM(),Q!==r?(k=wfe(),k===r&&(k=null),k!==r?(Re=C,Q=h(Q,k),C=Q):(w=C,C=r)):(w=C,C=r),C}function wfe(){var C,Q,k,N,Z,Ee,ot;for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r)if(k=Bfe(),k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();if(N!==r)if(Z=VQ(),Z!==r){for(Ee=[],ot=ke();ot!==r;)Ee.push(ot),ot=ke();Ee!==r?(Re=C,Q=p(k,Z),C=Q):(w=C,C=r)}else w=C,C=r;else w=C,C=r}else w=C,C=r;else w=C,C=r;return C}function Bfe(){var C;return t.substr(w,2)===d?(C=d,w+=2):(C=r,we===0&&ve(m)),C===r&&(t.substr(w,2)===I?(C=I,w+=2):(C=r,we===0&&ve(B))),C}function XM(){var C,Q,k;return C=w,Q=vfe(),Q!==r?(k=Qfe(),k===r&&(k=null),k!==r?(Re=C,Q=b(Q,k),C=Q):(w=C,C=r)):(w=C,C=r),C}function Qfe(){var C,Q,k,N,Z,Ee,ot;for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r)if(k=bfe(),k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();if(N!==r)if(Z=XM(),Z!==r){for(Ee=[],ot=ke();ot!==r;)Ee.push(ot),ot=ke();Ee!==r?(Re=C,Q=R(k,Z),C=Q):(w=C,C=r)}else w=C,C=r;else w=C,C=r}else w=C,C=r;else w=C,C=r;return C}function bfe(){var C;return t.substr(w,2)===H?(C=H,w+=2):(C=r,we===0&&ve(L)),C===r&&(t.charCodeAt(w)===124?(C=K,w++):(C=r,we===0&&ve(J))),C}function cE(){var C,Q,k,N,Z,Ee;if(C=w,Q=oO(),Q!==r)if(t.charCodeAt(w)===61?(k=ne,w++):(k=r,we===0&&ve(q)),k!==r)if(N=$M(),N!==r){for(Z=[],Ee=ke();Ee!==r;)Z.push(Ee),Ee=ke();Z!==r?(Re=C,Q=A(Q,N),C=Q):(w=C,C=r)}else w=C,C=r;else w=C,C=r;else w=C,C=r;if(C===r)if(C=w,Q=oO(),Q!==r)if(t.charCodeAt(w)===61?(k=ne,w++):(k=r,we===0&&ve(q)),k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();N!==r?(Re=C,Q=V(Q),C=Q):(w=C,C=r)}else w=C,C=r;else w=C,C=r;return C}function vfe(){var C,Q,k,N,Z,Ee,ot,ut,Tr,ni,Yn;for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r)if(t.charCodeAt(w)===40?(k=W,w++):(k=r,we===0&&ve(X)),k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();if(N!==r)if(Z=Jf(),Z!==r){for(Ee=[],ot=ke();ot!==r;)Ee.push(ot),ot=ke();if(Ee!==r)if(t.charCodeAt(w)===41?(ot=F,w++):(ot=r,we===0&&ve(D)),ot!==r){for(ut=[],Tr=ke();Tr!==r;)ut.push(Tr),Tr=ke();if(ut!==r){for(Tr=[],ni=Wf();ni!==r;)Tr.push(ni),ni=Wf();if(Tr!==r){for(ni=[],Yn=ke();Yn!==r;)ni.push(Yn),Yn=ke();ni!==r?(Re=C,Q=he(Z,Tr),C=Q):(w=C,C=r)}else w=C,C=r}else w=C,C=r}else w=C,C=r;else w=C,C=r}else w=C,C=r;else w=C,C=r}else w=C,C=r;else w=C,C=r;if(C===r){for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r)if(t.charCodeAt(w)===123?(k=pe,w++):(k=r,we===0&&ve(Ne)),k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();if(N!==r)if(Z=Jf(),Z!==r){for(Ee=[],ot=ke();ot!==r;)Ee.push(ot),ot=ke();if(Ee!==r)if(t.charCodeAt(w)===125?(ot=Pe,w++):(ot=r,we===0&&ve(qe)),ot!==r){for(ut=[],Tr=ke();Tr!==r;)ut.push(Tr),Tr=ke();if(ut!==r){for(Tr=[],ni=Wf();ni!==r;)Tr.push(ni),ni=Wf();if(Tr!==r){for(ni=[],Yn=ke();Yn!==r;)ni.push(Yn),Yn=ke();ni!==r?(Re=C,Q=re(Z,Tr),C=Q):(w=C,C=r)}else w=C,C=r}else w=C,C=r}else w=C,C=r;else w=C,C=r}else w=C,C=r;else w=C,C=r}else w=C,C=r;else w=C,C=r;if(C===r){for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r){for(k=[],N=cE();N!==r;)k.push(N),N=cE();if(k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();if(N!==r){if(Z=[],Ee=ZM(),Ee!==r)for(;Ee!==r;)Z.push(Ee),Ee=ZM();else Z=r;if(Z!==r){for(Ee=[],ot=ke();ot!==r;)Ee.push(ot),ot=ke();Ee!==r?(Re=C,Q=se(k,Z),C=Q):(w=C,C=r)}else w=C,C=r}else w=C,C=r}else w=C,C=r}else w=C,C=r;if(C===r){for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r){if(k=[],N=cE(),N!==r)for(;N!==r;)k.push(N),N=cE();else k=r;if(k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();N!==r?(Re=C,Q=be(k),C=Q):(w=C,C=r)}else w=C,C=r}else w=C,C=r}}}return C}function Sfe(){var C,Q,k,N,Z;for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r){if(k=[],N=uE(),N!==r)for(;N!==r;)k.push(N),N=uE();else k=r;if(k!==r){for(N=[],Z=ke();Z!==r;)N.push(Z),Z=ke();N!==r?(Re=C,Q=ae(k),C=Q):(w=C,C=r)}else w=C,C=r}else w=C,C=r;return C}function ZM(){var C,Q,k;for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();if(Q!==r?(k=Wf(),k!==r?(Re=C,Q=Ae(k),C=Q):(w=C,C=r)):(w=C,C=r),C===r){for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();Q!==r?(k=uE(),k!==r?(Re=C,Q=Ae(k),C=Q):(w=C,C=r)):(w=C,C=r)}return C}function Wf(){var C,Q,k,N,Z;for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();return Q!==r?(De.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve($)),k===r&&(k=null),k!==r?(N=xfe(),N!==r?(Z=uE(),Z!==r?(Re=C,Q=G(k,N,Z),C=Q):(w=C,C=r)):(w=C,C=r)):(w=C,C=r)):(w=C,C=r),C}function xfe(){var C;return t.substr(w,2)===Ce?(C=Ce,w+=2):(C=r,we===0&&ve(ee)),C===r&&(t.substr(w,2)===Ue?(C=Ue,w+=2):(C=r,we===0&&ve(Oe)),C===r&&(t.charCodeAt(w)===62?(C=vt,w++):(C=r,we===0&&ve(dt)),C===r&&(t.substr(w,3)===ri?(C=ri,w+=3):(C=r,we===0&&ve(ii)),C===r&&(t.substr(w,2)===an?(C=an,w+=2):(C=r,we===0&&ve(yr)),C===r&&(t.charCodeAt(w)===60?(C=Ki,w++):(C=r,we===0&&ve(Qi))))))),C}function uE(){var C,Q,k;for(C=w,Q=[],k=ke();k!==r;)Q.push(k),k=ke();return Q!==r?(k=$M(),k!==r?(Re=C,Q=Ae(k),C=Q):(w=C,C=r)):(w=C,C=r),C}function $M(){var C,Q,k;if(C=w,Q=[],k=eO(),k!==r)for(;k!==r;)Q.push(k),k=eO();else Q=r;return Q!==r&&(Re=C,Q=Go(Q)),C=Q,C}function eO(){var C,Q;return C=w,Q=kfe(),Q!==r&&(Re=C,Q=wr(Q)),C=Q,C===r&&(C=w,Q=Pfe(),Q!==r&&(Re=C,Q=wr(Q)),C=Q,C===r&&(C=w,Q=Dfe(),Q!==r&&(Re=C,Q=wr(Q)),C=Q)),C}function kfe(){var C,Q,k,N;return C=w,t.charCodeAt(w)===39?(Q=Ui,w++):(Q=r,we===0&&ve(ws)),Q!==r?(k=Rfe(),k!==r?(t.charCodeAt(w)===39?(N=Ui,w++):(N=r,we===0&&ve(ws)),N!==r?(Re=C,Q=Tf(k),C=Q):(w=C,C=r)):(w=C,C=r)):(w=C,C=r),C}function Pfe(){var C,Q,k,N;if(C=w,t.charCodeAt(w)===34?(Q=Mf,w++):(Q=r,we===0&&ve(Rm)),Q!==r){for(k=[],N=tO();N!==r;)k.push(N),N=tO();k!==r?(t.charCodeAt(w)===34?(N=Mf,w++):(N=r,we===0&&ve(Rm)),N!==r?(Re=C,Q=Fm(k),C=Q):(w=C,C=r)):(w=C,C=r)}else w=C,C=r;return C}function Dfe(){var C,Q,k;if(C=w,Q=[],k=rO(),k!==r)for(;k!==r;)Q.push(k),k=rO();else Q=r;return Q!==r&&(Re=C,Q=Fm(Q)),C=Q,C}function tO(){var C,Q;return C=w,Q=nO(),Q!==r&&(Re=C,Q=Nm(Q)),C=Q,C===r&&(C=w,Q=sO(),Q!==r&&(Re=C,Q=DQ(Q)),C=Q,C===r&&(C=w,Q=ZQ(),Q!==r&&(Re=C,Q=RQ(Q)),C=Q,C===r&&(C=w,Q=Ffe(),Q!==r&&(Re=C,Q=Of(Q)),C=Q))),C}function rO(){var C,Q;return C=w,Q=nO(),Q!==r&&(Re=C,Q=FQ(Q)),C=Q,C===r&&(C=w,Q=sO(),Q!==r&&(Re=C,Q=NQ(Q)),C=Q,C===r&&(C=w,Q=ZQ(),Q!==r&&(Re=C,Q=Lm(Q)),C=Q,C===r&&(C=w,Q=Lfe(),Q!==r&&(Re=C,Q=LQ(Q)),C=Q,C===r&&(C=w,Q=Nfe(),Q!==r&&(Re=C,Q=Of(Q)),C=Q)))),C}function Rfe(){var C,Q,k,N,Z;for(C=w,Q=[],k=gE(),k===r&&(k=fE(),k===r&&(k=w,t.charCodeAt(w)===92?(N=Va,w++):(N=r,we===0&&ve(jo)),N!==r?(Tm.test(t.charAt(w))?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Mm)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r),k===r&&(Om.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve(Km)))));k!==r;)Q.push(k),k=gE(),k===r&&(k=fE(),k===r&&(k=w,t.charCodeAt(w)===92?(N=Va,w++):(N=r,we===0&&ve(jo)),N!==r?(Tm.test(t.charAt(w))?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Mm)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r),k===r&&(Om.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve(Km)))));return Q!==r&&(Re=C,Q=il(Q)),C=Q,C}function Ffe(){var C,Q,k,N,Z;if(C=w,Q=[],k=gE(),k===r&&(k=fE(),k===r&&(k=w,t.charCodeAt(w)===92?(N=Va,w++):(N=r,we===0&&ve(jo)),N!==r?(Um.test(t.charAt(w))?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Hm)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r),k===r&&(Kf.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve(Gm))))),k!==r)for(;k!==r;)Q.push(k),k=gE(),k===r&&(k=fE(),k===r&&(k=w,t.charCodeAt(w)===92?(N=Va,w++):(N=r,we===0&&ve(jo)),N!==r?(Um.test(t.charAt(w))?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Hm)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r),k===r&&(Kf.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve(Gm)))));else Q=r;return Q!==r&&(Re=C,Q=il(Q)),C=Q,C}function gE(){var C,Q;return C=w,t.substr(w,2)===jm?(Q=jm,w+=2):(Q=r,we===0&&ve(TQ)),Q!==r&&(Re=C,Q=MQ()),C=Q,C===r&&(C=w,t.substr(w,2)===Ym?(Q=Ym,w+=2):(Q=r,we===0&&ve(qm)),Q!==r&&(Re=C,Q=Jm()),C=Q,C===r&&(C=w,t.substr(w,2)===Wm?(Q=Wm,w+=2):(Q=r,we===0&&ve(zm)),Q!==r&&(Re=C,Q=Vm()),C=Q,C===r&&(C=w,t.substr(w,2)===Uf?(Q=Uf,w+=2):(Q=r,we===0&&ve(OQ)),Q!==r&&(Re=C,Q=KQ()),C=Q,C===r&&(C=w,t.substr(w,2)===_m?(Q=_m,w+=2):(Q=r,we===0&&ve(UQ)),Q!==r&&(Re=C,Q=HQ()),C=Q,C===r&&(C=w,t.substr(w,2)===O?(Q=O,w+=2):(Q=r,we===0&&ve(ht)),Q!==r&&(Re=C,Q=Vc()),C=Q,C===r&&(C=w,t.substr(w,2)===xn?(Q=xn,w+=2):(Q=r,we===0&&ve(Hf)),Q!==r&&(Re=C,Q=Ye()),C=Q,C===r&&(C=w,t.substr(w,2)===nl?(Q=nl,w+=2):(Q=r,we===0&&ve(Xm)),Q!==r&&(Re=C,Q=MM()),C=Q,C===r&&(C=w,t.substr(w,2)===GQ?(Q=GQ,w+=2):(Q=r,we===0&&ve(OM)),Q!==r&&(Re=C,Q=fr()),C=Q)))))))),C}function fE(){var C,Q,k,N,Z,Ee,ot,ut,Tr,ni,Yn,$Q;return C=w,t.substr(w,2)===Bs?(Q=Bs,w+=2):(Q=r,we===0&&ve(jQ)),Q!==r?(k=w,N=w,Z=An(),Z!==r?(Ee=An(),Ee!==r?(Z=[Z,Ee],N=Z):(w=N,N=r)):(w=N,N=r),N!==r?k=t.substring(k,w):k=N,k!==r?(Re=C,Q=Zm(k),C=Q):(w=C,C=r)):(w=C,C=r),C===r&&(C=w,t.substr(w,2)===Yo?(Q=Yo,w+=2):(Q=r,we===0&&ve($m)),Q!==r?(k=w,N=w,Z=An(),Z!==r?(Ee=An(),Ee!==r?(ot=An(),ot!==r?(ut=An(),ut!==r?(Z=[Z,Ee,ot,ut],N=Z):(w=N,N=r)):(w=N,N=r)):(w=N,N=r)):(w=N,N=r),N!==r?k=t.substring(k,w):k=N,k!==r?(Re=C,Q=Zm(k),C=Q):(w=C,C=r)):(w=C,C=r),C===r&&(C=w,t.substr(w,2)===_a?(Q=_a,w+=2):(Q=r,we===0&&ve(et)),Q!==r?(k=w,N=w,Z=An(),Z!==r?(Ee=An(),Ee!==r?(ot=An(),ot!==r?(ut=An(),ut!==r?(Tr=An(),Tr!==r?(ni=An(),ni!==r?(Yn=An(),Yn!==r?($Q=An(),$Q!==r?(Z=[Z,Ee,ot,ut,Tr,ni,Yn,$Q],N=Z):(w=N,N=r)):(w=N,N=r)):(w=N,N=r)):(w=N,N=r)):(w=N,N=r)):(w=N,N=r)):(w=N,N=r)):(w=N,N=r),N!==r?k=t.substring(k,w):k=N,k!==r?(Re=C,Q=YQ(k),C=Q):(w=C,C=r)):(w=C,C=r))),C}function An(){var C;return eE.test(t.charAt(w))?(C=t.charAt(w),w++):(C=r,we===0&&ve(tE)),C}function Nfe(){var C,Q,k,N,Z;if(C=w,Q=[],k=w,t.charCodeAt(w)===92?(N=Va,w++):(N=r,we===0&&ve(jo)),N!==r?(t.length>w?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Xa)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r),k===r&&(k=w,N=w,we++,Z=aO(),we--,Z===r?N=void 0:(w=N,N=r),N!==r?(t.length>w?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Xa)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r)),k!==r)for(;k!==r;)Q.push(k),k=w,t.charCodeAt(w)===92?(N=Va,w++):(N=r,we===0&&ve(jo)),N!==r?(t.length>w?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Xa)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r),k===r&&(k=w,N=w,we++,Z=aO(),we--,Z===r?N=void 0:(w=N,N=r),N!==r?(t.length>w?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Xa)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r));else Q=r;return Q!==r&&(Re=C,Q=il(Q)),C=Q,C}function _Q(){var C,Q,k,N,Z,Ee;if(C=w,t.charCodeAt(w)===45?(Q=sl,w++):(Q=r,we===0&&ve(ol)),Q===r&&(t.charCodeAt(w)===43?(Q=al,w++):(Q=r,we===0&&ve(qo))),Q===r&&(Q=null),Q!==r){if(k=[],De.test(t.charAt(w))?(N=t.charAt(w),w++):(N=r,we===0&&ve($)),N!==r)for(;N!==r;)k.push(N),De.test(t.charAt(w))?(N=t.charAt(w),w++):(N=r,we===0&&ve($));else k=r;if(k!==r)if(t.charCodeAt(w)===46?(N=Al,w++):(N=r,we===0&&ve(qQ)),N!==r){if(Z=[],De.test(t.charAt(w))?(Ee=t.charAt(w),w++):(Ee=r,we===0&&ve($)),Ee!==r)for(;Ee!==r;)Z.push(Ee),De.test(t.charAt(w))?(Ee=t.charAt(w),w++):(Ee=r,we===0&&ve($));else Z=r;Z!==r?(Re=C,Q=rE(Q,k,Z),C=Q):(w=C,C=r)}else w=C,C=r;else w=C,C=r}else w=C,C=r;if(C===r){if(C=w,t.charCodeAt(w)===45?(Q=sl,w++):(Q=r,we===0&&ve(ol)),Q===r&&(t.charCodeAt(w)===43?(Q=al,w++):(Q=r,we===0&&ve(qo))),Q===r&&(Q=null),Q!==r){if(k=[],De.test(t.charAt(w))?(N=t.charAt(w),w++):(N=r,we===0&&ve($)),N!==r)for(;N!==r;)k.push(N),De.test(t.charAt(w))?(N=t.charAt(w),w++):(N=r,we===0&&ve($));else k=r;k!==r?(Re=C,Q=iE(Q,k),C=Q):(w=C,C=r)}else w=C,C=r;if(C===r&&(C=w,Q=ZQ(),Q!==r&&(Re=C,Q=JQ(Q)),C=Q,C===r&&(C=w,Q=zf(),Q!==r&&(Re=C,Q=ll(Q)),C=Q,C===r)))if(C=w,t.charCodeAt(w)===40?(Q=W,w++):(Q=r,we===0&&ve(X)),Q!==r){for(k=[],N=ke();N!==r;)k.push(N),N=ke();if(k!==r)if(N=iO(),N!==r){for(Z=[],Ee=ke();Ee!==r;)Z.push(Ee),Ee=ke();Z!==r?(t.charCodeAt(w)===41?(Ee=F,w++):(Ee=r,we===0&&ve(D)),Ee!==r?(Re=C,Q=WQ(N),C=Q):(w=C,C=r)):(w=C,C=r)}else w=C,C=r;else w=C,C=r}else w=C,C=r}return C}function XQ(){var C,Q,k,N,Z,Ee,ot,ut;if(C=w,Q=_Q(),Q!==r){for(k=[],N=w,Z=[],Ee=ke();Ee!==r;)Z.push(Ee),Ee=ke();if(Z!==r)if(t.charCodeAt(w)===42?(Ee=nE,w++):(Ee=r,we===0&&ve(Gf)),Ee===r&&(t.charCodeAt(w)===47?(Ee=_c,w++):(Ee=r,we===0&&ve(jf))),Ee!==r){for(ot=[],ut=ke();ut!==r;)ot.push(ut),ut=ke();ot!==r?(ut=_Q(),ut!==r?(Re=N,Z=sE(Q,Ee,ut),N=Z):(w=N,N=r)):(w=N,N=r)}else w=N,N=r;else w=N,N=r;for(;N!==r;){for(k.push(N),N=w,Z=[],Ee=ke();Ee!==r;)Z.push(Ee),Ee=ke();if(Z!==r)if(t.charCodeAt(w)===42?(Ee=nE,w++):(Ee=r,we===0&&ve(Gf)),Ee===r&&(t.charCodeAt(w)===47?(Ee=_c,w++):(Ee=r,we===0&&ve(jf))),Ee!==r){for(ot=[],ut=ke();ut!==r;)ot.push(ut),ut=ke();ot!==r?(ut=_Q(),ut!==r?(Re=N,Z=sE(Q,Ee,ut),N=Z):(w=N,N=r)):(w=N,N=r)}else w=N,N=r;else w=N,N=r}k!==r?(Re=C,Q=cl(Q,k),C=Q):(w=C,C=r)}else w=C,C=r;return C}function iO(){var C,Q,k,N,Z,Ee,ot,ut;if(C=w,Q=XQ(),Q!==r){for(k=[],N=w,Z=[],Ee=ke();Ee!==r;)Z.push(Ee),Ee=ke();if(Z!==r)if(t.charCodeAt(w)===43?(Ee=al,w++):(Ee=r,we===0&&ve(qo)),Ee===r&&(t.charCodeAt(w)===45?(Ee=sl,w++):(Ee=r,we===0&&ve(ol))),Ee!==r){for(ot=[],ut=ke();ut!==r;)ot.push(ut),ut=ke();ot!==r?(ut=XQ(),ut!==r?(Re=N,Z=oE(Q,Ee,ut),N=Z):(w=N,N=r)):(w=N,N=r)}else w=N,N=r;else w=N,N=r;for(;N!==r;){for(k.push(N),N=w,Z=[],Ee=ke();Ee!==r;)Z.push(Ee),Ee=ke();if(Z!==r)if(t.charCodeAt(w)===43?(Ee=al,w++):(Ee=r,we===0&&ve(qo)),Ee===r&&(t.charCodeAt(w)===45?(Ee=sl,w++):(Ee=r,we===0&&ve(ol))),Ee!==r){for(ot=[],ut=ke();ut!==r;)ot.push(ut),ut=ke();ot!==r?(ut=XQ(),ut!==r?(Re=N,Z=oE(Q,Ee,ut),N=Z):(w=N,N=r)):(w=N,N=r)}else w=N,N=r;else w=N,N=r}k!==r?(Re=C,Q=cl(Q,k),C=Q):(w=C,C=r)}else w=C,C=r;return C}function nO(){var C,Q,k,N,Z,Ee;if(C=w,t.substr(w,3)===Yf?(Q=Yf,w+=3):(Q=r,we===0&&ve(Xc)),Q!==r){for(k=[],N=ke();N!==r;)k.push(N),N=ke();if(k!==r)if(N=iO(),N!==r){for(Z=[],Ee=ke();Ee!==r;)Z.push(Ee),Ee=ke();Z!==r?(t.substr(w,2)===xr?(Ee=xr,w+=2):(Ee=r,we===0&&ve(KM)),Ee!==r?(Re=C,Q=Jo(N),C=Q):(w=C,C=r)):(w=C,C=r)}else w=C,C=r;else w=C,C=r}else w=C,C=r;return C}function sO(){var C,Q,k,N;return C=w,t.substr(w,2)===Zs?(Q=Zs,w+=2):(Q=r,we===0&&ve(aE)),Q!==r?(k=Jf(),k!==r?(t.charCodeAt(w)===41?(N=F,w++):(N=r,we===0&&ve(D)),N!==r?(Re=C,Q=Zc(k),C=Q):(w=C,C=r)):(w=C,C=r)):(w=C,C=r),C}function ZQ(){var C,Q,k,N,Z,Ee;return C=w,t.substr(w,2)===x?(Q=x,w+=2):(Q=r,we===0&&ve(U)),Q!==r?(k=zf(),k!==r?(t.substr(w,2)===le?(N=le,w+=2):(N=r,we===0&&ve(xe)),N!==r?(Z=Sfe(),Z!==r?(t.charCodeAt(w)===125?(Ee=Pe,w++):(Ee=r,we===0&&ve(qe)),Ee!==r?(Re=C,Q=Qe(k,Z),C=Q):(w=C,C=r)):(w=C,C=r)):(w=C,C=r)):(w=C,C=r)):(w=C,C=r),C===r&&(C=w,t.substr(w,2)===x?(Q=x,w+=2):(Q=r,we===0&&ve(U)),Q!==r?(k=zf(),k!==r?(t.substr(w,3)===Ge?(N=Ge,w+=3):(N=r,we===0&&ve(ct)),N!==r?(Re=C,Q=sr(k),C=Q):(w=C,C=r)):(w=C,C=r)):(w=C,C=r),C===r&&(C=w,t.substr(w,2)===x?(Q=x,w+=2):(Q=r,we===0&&ve(U)),Q!==r?(k=zf(),k!==r?(t.charCodeAt(w)===125?(N=Pe,w++):(N=r,we===0&&ve(qe)),N!==r?(Re=C,Q=Wo(k),C=Q):(w=C,C=r)):(w=C,C=r)):(w=C,C=r),C===r&&(C=w,t.charCodeAt(w)===36?(Q=Afe,w++):(Q=r,we===0&&ve(lfe)),Q!==r?(k=zf(),k!==r?(Re=C,Q=Wo(k),C=Q):(w=C,C=r)):(w=C,C=r)))),C}function Lfe(){var C,Q,k;return C=w,Q=Tfe(),Q!==r?(Re=w,k=cfe(Q),k?k=void 0:k=r,k!==r?(Re=C,Q=ufe(Q),C=Q):(w=C,C=r)):(w=C,C=r),C}function Tfe(){var C,Q,k,N,Z;if(C=w,Q=[],k=w,N=w,we++,Z=AO(),we--,Z===r?N=void 0:(w=N,N=r),N!==r?(t.length>w?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Xa)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r),k!==r)for(;k!==r;)Q.push(k),k=w,N=w,we++,Z=AO(),we--,Z===r?N=void 0:(w=N,N=r),N!==r?(t.length>w?(Z=t.charAt(w),w++):(Z=r,we===0&&ve(Xa)),Z!==r?(Re=k,N=te(Z),k=N):(w=k,k=r)):(w=k,k=r);else Q=r;return Q!==r&&(Re=C,Q=il(Q)),C=Q,C}function oO(){var C,Q,k;if(C=w,Q=[],UM.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve(HM)),k!==r)for(;k!==r;)Q.push(k),UM.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve(HM));else Q=r;return Q!==r&&(Re=C,Q=GM()),C=Q,C}function zf(){var C,Q,k;if(C=w,Q=[],jM.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve(YM)),k!==r)for(;k!==r;)Q.push(k),jM.test(t.charAt(w))?(k=t.charAt(w),w++):(k=r,we===0&&ve(YM));else Q=r;return Q!==r&&(Re=C,Q=GM()),C=Q,C}function aO(){var C;return gfe.test(t.charAt(w))?(C=t.charAt(w),w++):(C=r,we===0&&ve(ffe)),C}function AO(){var C;return hfe.test(t.charAt(w))?(C=t.charAt(w),w++):(C=r,we===0&&ve(pfe)),C}function ke(){var C,Q;if(C=[],qM.test(t.charAt(w))?(Q=t.charAt(w),w++):(Q=r,we===0&&ve(JM)),Q!==r)for(;Q!==r;)C.push(Q),qM.test(t.charAt(w))?(Q=t.charAt(w),w++):(Q=r,we===0&&ve(JM));else C=r;return C}if(lE=n(),lE!==r&&w===t.length)return lE;throw lE!==r&&w{"use strict";function Eke(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function Xl(t,e,r,i){this.message=t,this.expected=e,this.found=r,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,Xl)}Eke(Xl,Error);Xl.buildMessage=function(t,e){var r={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;gH&&(H=B,L=[]),L.push($))}function qe($,G){return new Xl($,null,null,G)}function re($,G,Ce){return new Xl(Xl.buildMessage($,G),$,G,Ce)}function se(){var $,G,Ce,ee;return $=B,G=be(),G!==r?(t.charCodeAt(B)===47?(Ce=s,B++):(Ce=r,K===0&&Pe(o)),Ce!==r?(ee=be(),ee!==r?(b=$,G=a(G,ee),$=G):(B=$,$=r)):(B=$,$=r)):(B=$,$=r),$===r&&($=B,G=be(),G!==r&&(b=$,G=l(G)),$=G),$}function be(){var $,G,Ce,ee;return $=B,G=ae(),G!==r?(t.charCodeAt(B)===64?(Ce=c,B++):(Ce=r,K===0&&Pe(u)),Ce!==r?(ee=De(),ee!==r?(b=$,G=g(G,ee),$=G):(B=$,$=r)):(B=$,$=r)):(B=$,$=r),$===r&&($=B,G=ae(),G!==r&&(b=$,G=f(G)),$=G),$}function ae(){var $,G,Ce,ee,Ue;return $=B,t.charCodeAt(B)===64?(G=c,B++):(G=r,K===0&&Pe(u)),G!==r?(Ce=Ae(),Ce!==r?(t.charCodeAt(B)===47?(ee=s,B++):(ee=r,K===0&&Pe(o)),ee!==r?(Ue=Ae(),Ue!==r?(b=$,G=h(),$=G):(B=$,$=r)):(B=$,$=r)):(B=$,$=r)):(B=$,$=r),$===r&&($=B,G=Ae(),G!==r&&(b=$,G=h()),$=G),$}function Ae(){var $,G,Ce;if($=B,G=[],p.test(t.charAt(B))?(Ce=t.charAt(B),B++):(Ce=r,K===0&&Pe(d)),Ce!==r)for(;Ce!==r;)G.push(Ce),p.test(t.charAt(B))?(Ce=t.charAt(B),B++):(Ce=r,K===0&&Pe(d));else G=r;return G!==r&&(b=$,G=h()),$=G,$}function De(){var $,G,Ce;if($=B,G=[],m.test(t.charAt(B))?(Ce=t.charAt(B),B++):(Ce=r,K===0&&Pe(I)),Ce!==r)for(;Ce!==r;)G.push(Ce),m.test(t.charAt(B))?(Ce=t.charAt(B),B++):(Ce=r,K===0&&Pe(I));else G=r;return G!==r&&(b=$,G=h()),$=G,$}if(J=n(),J!==r&&B===t.length)return J;throw J!==r&&B{"use strict";function F4(t){return typeof t=="undefined"||t===null}function yke(t){return typeof t=="object"&&t!==null}function wke(t){return Array.isArray(t)?t:F4(t)?[]:[t]}function Bke(t,e){var r,i,n,s;if(e)for(s=Object.keys(e),r=0,i=s.length;r{"use strict";function Lp(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}Lp.prototype=Object.create(Error.prototype);Lp.prototype.constructor=Lp;Lp.prototype.toString=function(e){var r=this.name+": ";return r+=this.reason||"(unknown reason)",!e&&this.mark&&(r+=" "+this.mark.toString()),r};N4.exports=Lp});var M4=E((Vot,L4)=>{"use strict";var T4=$l();function kP(t,e,r,i,n){this.name=t,this.buffer=e,this.position=r,this.line=i,this.column=n}kP.prototype.getSnippet=function(e,r){var i,n,s,o,a;if(!this.buffer)return null;for(e=e||4,r=r||75,i="",n=this.position;n>0&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(n-1))===-1;)if(n-=1,this.position-n>r/2-1){i=" ... ",n+=5;break}for(s="",o=this.position;or/2-1){s=" ... ",o-=5;break}return a=this.buffer.slice(n,o),T4.repeat(" ",e)+i+a+s+` +`+T4.repeat(" ",e+this.position-n+i.length)+"^"};kP.prototype.toString=function(e){var r,i="";return this.name&&(i+='in "'+this.name+'" '),i+="at line "+(this.line+1)+", column "+(this.column+1),e||(r=this.getSnippet(),r&&(i+=`: +`+r)),i};L4.exports=kP});var Xr=E((_ot,O4)=>{"use strict";var K4=ng(),vke=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],Ske=["scalar","sequence","mapping"];function xke(t){var e={};return t!==null&&Object.keys(t).forEach(function(r){t[r].forEach(function(i){e[String(i)]=r})}),e}function kke(t,e){if(e=e||{},Object.keys(e).forEach(function(r){if(vke.indexOf(r)===-1)throw new K4('Unknown option "'+r+'" is met in definition of "'+t+'" YAML type.')}),this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(r){return r},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=xke(e.styleAliases||null),Ske.indexOf(this.kind)===-1)throw new K4('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}O4.exports=kke});var ec=E((Xot,U4)=>{"use strict";var H4=$l(),hw=ng(),Pke=Xr();function PP(t,e,r){var i=[];return t.include.forEach(function(n){r=PP(n,e,r)}),t[e].forEach(function(n){r.forEach(function(s,o){s.tag===n.tag&&s.kind===n.kind&&i.push(o)}),r.push(n)}),r.filter(function(n,s){return i.indexOf(s)===-1})}function Dke(){var t={scalar:{},sequence:{},mapping:{},fallback:{}},e,r;function i(n){t[n.kind][n.tag]=t.fallback[n.tag]=n}for(e=0,r=arguments.length;e{"use strict";var Rke=Xr();G4.exports=new Rke("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return t!==null?t:""}})});var q4=E(($ot,Y4)=>{"use strict";var Fke=Xr();Y4.exports=new Fke("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return t!==null?t:[]}})});var W4=E((eat,J4)=>{"use strict";var Nke=Xr();J4.exports=new Nke("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return t!==null?t:{}}})});var pw=E((tat,z4)=>{"use strict";var Lke=ec();z4.exports=new Lke({explicit:[j4(),q4(),W4()]})});var _4=E((rat,V4)=>{"use strict";var Tke=Xr();function Mke(t){if(t===null)return!0;var e=t.length;return e===1&&t==="~"||e===4&&(t==="null"||t==="Null"||t==="NULL")}function Oke(){return null}function Kke(t){return t===null}V4.exports=new Tke("tag:yaml.org,2002:null",{kind:"scalar",resolve:Mke,construct:Oke,predicate:Kke,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var Z4=E((iat,X4)=>{"use strict";var Uke=Xr();function Hke(t){if(t===null)return!1;var e=t.length;return e===4&&(t==="true"||t==="True"||t==="TRUE")||e===5&&(t==="false"||t==="False"||t==="FALSE")}function Gke(t){return t==="true"||t==="True"||t==="TRUE"}function jke(t){return Object.prototype.toString.call(t)==="[object Boolean]"}X4.exports=new Uke("tag:yaml.org,2002:bool",{kind:"scalar",resolve:Hke,construct:Gke,predicate:jke,represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"})});var ez=E((nat,$4)=>{"use strict";var Yke=$l(),qke=Xr();function Jke(t){return 48<=t&&t<=57||65<=t&&t<=70||97<=t&&t<=102}function Wke(t){return 48<=t&&t<=55}function zke(t){return 48<=t&&t<=57}function Vke(t){if(t===null)return!1;var e=t.length,r=0,i=!1,n;if(!e)return!1;if(n=t[r],(n==="-"||n==="+")&&(n=t[++r]),n==="0"){if(r+1===e)return!0;if(n=t[++r],n==="b"){for(r++;r=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0"+t.toString(8):"-0"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var iz=E((sat,tz)=>{"use strict";var rz=$l(),Zke=Xr(),$ke=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function ePe(t){return!(t===null||!$ke.test(t)||t[t.length-1]==="_")}function tPe(t){var e,r,i,n;return e=t.replace(/_/g,"").toLowerCase(),r=e[0]==="-"?-1:1,n=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?r===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:e.indexOf(":")>=0?(e.split(":").forEach(function(s){n.unshift(parseFloat(s,10))}),e=0,i=1,n.forEach(function(s){e+=s*i,i*=60}),r*e):r*parseFloat(e,10)}var rPe=/^[-+]?[0-9]+e/;function iPe(t,e){var r;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(rz.isNegativeZero(t))return"-0.0";return r=t.toString(10),rPe.test(r)?r.replace("e",".e"):r}function nPe(t){return Object.prototype.toString.call(t)==="[object Number]"&&(t%1!=0||rz.isNegativeZero(t))}tz.exports=new Zke("tag:yaml.org,2002:float",{kind:"scalar",resolve:ePe,construct:tPe,predicate:nPe,represent:iPe,defaultStyle:"lowercase"})});var DP=E((oat,nz)=>{"use strict";var sPe=ec();nz.exports=new sPe({include:[pw()],implicit:[_4(),Z4(),ez(),iz()]})});var RP=E((aat,sz)=>{"use strict";var oPe=ec();sz.exports=new oPe({include:[DP()]})});var lz=E((Aat,oz)=>{"use strict";var aPe=Xr(),az=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),Az=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function APe(t){return t===null?!1:az.exec(t)!==null||Az.exec(t)!==null}function lPe(t){var e,r,i,n,s,o,a,l=0,c=null,u,g,f;if(e=az.exec(t),e===null&&(e=Az.exec(t)),e===null)throw new Error("Date resolve error");if(r=+e[1],i=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(r,i,n));if(s=+e[4],o=+e[5],a=+e[6],e[7]){for(l=e[7].slice(0,3);l.length<3;)l+="0";l=+l}return e[9]&&(u=+e[10],g=+(e[11]||0),c=(u*60+g)*6e4,e[9]==="-"&&(c=-c)),f=new Date(Date.UTC(r,i,n,s,o,a,l)),c&&f.setTime(f.getTime()-c),f}function cPe(t){return t.toISOString()}oz.exports=new aPe("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:APe,construct:lPe,instanceOf:Date,represent:cPe})});var uz=E((lat,cz)=>{"use strict";var uPe=Xr();function gPe(t){return t==="<<"||t===null}cz.exports=new uPe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:gPe})});var hz=E((cat,gz)=>{"use strict";var tc;try{fz=require,tc=fz("buffer").Buffer}catch(t){}var fz,fPe=Xr(),FP=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function hPe(t){if(t===null)return!1;var e,r,i=0,n=t.length,s=FP;for(r=0;r64)){if(e<0)return!1;i+=6}return i%8==0}function pPe(t){var e,r,i=t.replace(/[\r\n=]/g,""),n=i.length,s=FP,o=0,a=[];for(e=0;e>16&255),a.push(o>>8&255),a.push(o&255)),o=o<<6|s.indexOf(i.charAt(e));return r=n%4*6,r===0?(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)):r===18?(a.push(o>>10&255),a.push(o>>2&255)):r===12&&a.push(o>>4&255),tc?tc.from?tc.from(a):new tc(a):a}function dPe(t){var e="",r=0,i,n,s=t.length,o=FP;for(i=0;i>18&63],e+=o[r>>12&63],e+=o[r>>6&63],e+=o[r&63]),r=(r<<8)+t[i];return n=s%3,n===0?(e+=o[r>>18&63],e+=o[r>>12&63],e+=o[r>>6&63],e+=o[r&63]):n===2?(e+=o[r>>10&63],e+=o[r>>4&63],e+=o[r<<2&63],e+=o[64]):n===1&&(e+=o[r>>2&63],e+=o[r<<4&63],e+=o[64],e+=o[64]),e}function CPe(t){return tc&&tc.isBuffer(t)}gz.exports=new fPe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:hPe,construct:pPe,predicate:CPe,represent:dPe})});var dz=E((uat,pz)=>{"use strict";var mPe=Xr(),EPe=Object.prototype.hasOwnProperty,IPe=Object.prototype.toString;function yPe(t){if(t===null)return!0;var e=[],r,i,n,s,o,a=t;for(r=0,i=a.length;r{"use strict";var BPe=Xr(),QPe=Object.prototype.toString;function bPe(t){if(t===null)return!0;var e,r,i,n,s,o=t;for(s=new Array(o.length),e=0,r=o.length;e{"use strict";var SPe=Xr(),xPe=Object.prototype.hasOwnProperty;function kPe(t){if(t===null)return!0;var e,r=t;for(e in r)if(xPe.call(r,e)&&r[e]!==null)return!1;return!0}function PPe(t){return t!==null?t:{}}Ez.exports=new SPe("tag:yaml.org,2002:set",{kind:"mapping",resolve:kPe,construct:PPe})});var og=E((hat,yz)=>{"use strict";var DPe=ec();yz.exports=new DPe({include:[RP()],implicit:[lz(),uz()],explicit:[hz(),dz(),mz(),Iz()]})});var Bz=E((pat,wz)=>{"use strict";var RPe=Xr();function FPe(){return!0}function NPe(){}function LPe(){return""}function TPe(t){return typeof t=="undefined"}wz.exports=new RPe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:FPe,construct:NPe,predicate:TPe,represent:LPe})});var bz=E((dat,Qz)=>{"use strict";var MPe=Xr();function OPe(t){if(t===null||t.length===0)return!1;var e=t,r=/\/([gim]*)$/.exec(t),i="";return!(e[0]==="/"&&(r&&(i=r[1]),i.length>3||e[e.length-i.length-1]!=="/"))}function KPe(t){var e=t,r=/\/([gim]*)$/.exec(t),i="";return e[0]==="/"&&(r&&(i=r[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function UPe(t){var e="/"+t.source+"/";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),e}function HPe(t){return Object.prototype.toString.call(t)==="[object RegExp]"}Qz.exports=new MPe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:OPe,construct:KPe,predicate:HPe,represent:UPe})});var xz=E((Cat,vz)=>{"use strict";var dw;try{Sz=require,dw=Sz("esprima")}catch(t){typeof window!="undefined"&&(dw=window.esprima)}var Sz,GPe=Xr();function jPe(t){if(t===null)return!1;try{var e="("+t+")",r=dw.parse(e,{range:!0});return!(r.type!=="Program"||r.body.length!==1||r.body[0].type!=="ExpressionStatement"||r.body[0].expression.type!=="ArrowFunctionExpression"&&r.body[0].expression.type!=="FunctionExpression")}catch(i){return!1}}function YPe(t){var e="("+t+")",r=dw.parse(e,{range:!0}),i=[],n;if(r.type!=="Program"||r.body.length!==1||r.body[0].type!=="ExpressionStatement"||r.body[0].expression.type!=="ArrowFunctionExpression"&&r.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return r.body[0].expression.params.forEach(function(s){i.push(s.name)}),n=r.body[0].expression.body.range,r.body[0].expression.body.type==="BlockStatement"?new Function(i,e.slice(n[0]+1,n[1]-1)):new Function(i,"return "+e.slice(n[0],n[1]))}function qPe(t){return t.toString()}function JPe(t){return Object.prototype.toString.call(t)==="[object Function]"}vz.exports=new GPe("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:jPe,construct:YPe,predicate:JPe,represent:qPe})});var Tp=E((mat,kz)=>{"use strict";var Pz=ec();kz.exports=Pz.DEFAULT=new Pz({include:[og()],explicit:[Bz(),bz(),xz()]})});var Vz=E((Eat,Mp)=>{"use strict";var Ba=$l(),Dz=ng(),WPe=M4(),Rz=og(),zPe=Tp(),QA=Object.prototype.hasOwnProperty,Cw=1,Fz=2,Nz=3,mw=4,NP=1,VPe=2,Lz=3,_Pe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,XPe=/[\x85\u2028\u2029]/,ZPe=/[,\[\]\{\}]/,Tz=/^(?:!|!!|![a-z\-]+!)$/i,Mz=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function Oz(t){return Object.prototype.toString.call(t)}function wo(t){return t===10||t===13}function rc(t){return t===9||t===32}function yn(t){return t===9||t===32||t===10||t===13}function ag(t){return t===44||t===91||t===93||t===123||t===125}function $Pe(t){var e;return 48<=t&&t<=57?t-48:(e=t|32,97<=e&&e<=102?e-97+10:-1)}function eDe(t){return t===120?2:t===117?4:t===85?8:0}function tDe(t){return 48<=t&&t<=57?t-48:-1}function Kz(t){return t===48?"\0":t===97?"\x07":t===98?"\b":t===116||t===9?" ":t===110?` +`:t===118?"\v":t===102?"\f":t===114?"\r":t===101?"":t===32?" ":t===34?'"':t===47?"/":t===92?"\\":t===78?"\x85":t===95?"\xA0":t===76?"\u2028":t===80?"\u2029":""}function rDe(t){return t<=65535?String.fromCharCode(t):String.fromCharCode((t-65536>>10)+55296,(t-65536&1023)+56320)}var Uz=new Array(256),Hz=new Array(256);for(var Ag=0;Ag<256;Ag++)Uz[Ag]=Kz(Ag)?1:0,Hz[Ag]=Kz(Ag);function iDe(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||zPe,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function Gz(t,e){return new Dz(e,new WPe(t.filename,t.input,t.position,t.line,t.position-t.lineStart))}function st(t,e){throw Gz(t,e)}function Ew(t,e){t.onWarning&&t.onWarning.call(null,Gz(t,e))}var jz={YAML:function(e,r,i){var n,s,o;e.version!==null&&st(e,"duplication of %YAML directive"),i.length!==1&&st(e,"YAML directive accepts exactly one argument"),n=/^([0-9]+)\.([0-9]+)$/.exec(i[0]),n===null&&st(e,"ill-formed argument of the YAML directive"),s=parseInt(n[1],10),o=parseInt(n[2],10),s!==1&&st(e,"unacceptable YAML version of the document"),e.version=i[0],e.checkLineBreaks=o<2,o!==1&&o!==2&&Ew(e,"unsupported YAML version of the document")},TAG:function(e,r,i){var n,s;i.length!==2&&st(e,"TAG directive accepts exactly two arguments"),n=i[0],s=i[1],Tz.test(n)||st(e,"ill-formed tag handle (first argument) of the TAG directive"),QA.call(e.tagMap,n)&&st(e,'there is a previously declared suffix for "'+n+'" tag handle'),Mz.test(s)||st(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[n]=s}};function bA(t,e,r,i){var n,s,o,a;if(e1&&(t.result+=Ba.repeat(` +`,e-1))}function nDe(t,e,r){var i,n,s,o,a,l,c,u,g=t.kind,f=t.result,h;if(h=t.input.charCodeAt(t.position),yn(h)||ag(h)||h===35||h===38||h===42||h===33||h===124||h===62||h===39||h===34||h===37||h===64||h===96||(h===63||h===45)&&(n=t.input.charCodeAt(t.position+1),yn(n)||r&&ag(n)))return!1;for(t.kind="scalar",t.result="",s=o=t.position,a=!1;h!==0;){if(h===58){if(n=t.input.charCodeAt(t.position+1),yn(n)||r&&ag(n))break}else if(h===35){if(i=t.input.charCodeAt(t.position-1),yn(i))break}else{if(t.position===t.lineStart&&Iw(t)||r&&ag(h))break;if(wo(h))if(l=t.line,c=t.lineStart,u=t.lineIndent,jr(t,!1,-1),t.lineIndent>=e){a=!0,h=t.input.charCodeAt(t.position);continue}else{t.position=o,t.line=l,t.lineStart=c,t.lineIndent=u;break}}a&&(bA(t,s,o,!1),TP(t,t.line-l),s=o=t.position,a=!1),rc(h)||(o=t.position+1),h=t.input.charCodeAt(++t.position)}return bA(t,s,o,!1),t.result?!0:(t.kind=g,t.result=f,!1)}function sDe(t,e){var r,i,n;if(r=t.input.charCodeAt(t.position),r!==39)return!1;for(t.kind="scalar",t.result="",t.position++,i=n=t.position;(r=t.input.charCodeAt(t.position))!==0;)if(r===39)if(bA(t,i,t.position,!0),r=t.input.charCodeAt(++t.position),r===39)i=t.position,t.position++,n=t.position;else return!0;else wo(r)?(bA(t,i,n,!0),TP(t,jr(t,!1,e)),i=n=t.position):t.position===t.lineStart&&Iw(t)?st(t,"unexpected end of the document within a single quoted scalar"):(t.position++,n=t.position);st(t,"unexpected end of the stream within a single quoted scalar")}function oDe(t,e){var r,i,n,s,o,a;if(a=t.input.charCodeAt(t.position),a!==34)return!1;for(t.kind="scalar",t.result="",t.position++,r=i=t.position;(a=t.input.charCodeAt(t.position))!==0;){if(a===34)return bA(t,r,t.position,!0),t.position++,!0;if(a===92){if(bA(t,r,t.position,!0),a=t.input.charCodeAt(++t.position),wo(a))jr(t,!1,e);else if(a<256&&Uz[a])t.result+=Hz[a],t.position++;else if((o=eDe(a))>0){for(n=o,s=0;n>0;n--)a=t.input.charCodeAt(++t.position),(o=$Pe(a))>=0?s=(s<<4)+o:st(t,"expected hexadecimal character");t.result+=rDe(s),t.position++}else st(t,"unknown escape sequence");r=i=t.position}else wo(a)?(bA(t,r,i,!0),TP(t,jr(t,!1,e)),r=i=t.position):t.position===t.lineStart&&Iw(t)?st(t,"unexpected end of the document within a double quoted scalar"):(t.position++,i=t.position)}st(t,"unexpected end of the stream within a double quoted scalar")}function aDe(t,e){var r=!0,i,n=t.tag,s,o=t.anchor,a,l,c,u,g,f={},h,p,d,m;if(m=t.input.charCodeAt(t.position),m===91)l=93,g=!1,s=[];else if(m===123)l=125,g=!0,s={};else return!1;for(t.anchor!==null&&(t.anchorMap[t.anchor]=s),m=t.input.charCodeAt(++t.position);m!==0;){if(jr(t,!0,e),m=t.input.charCodeAt(t.position),m===l)return t.position++,t.tag=n,t.anchor=o,t.kind=g?"mapping":"sequence",t.result=s,!0;r||st(t,"missed comma between flow collection entries"),p=h=d=null,c=u=!1,m===63&&(a=t.input.charCodeAt(t.position+1),yn(a)&&(c=u=!0,t.position++,jr(t,!0,e))),i=t.line,cg(t,e,Cw,!1,!0),p=t.tag,h=t.result,jr(t,!0,e),m=t.input.charCodeAt(t.position),(u||t.line===i)&&m===58&&(c=!0,m=t.input.charCodeAt(++t.position),jr(t,!0,e),cg(t,e,Cw,!1,!0),d=t.result),g?lg(t,s,f,p,h,d):c?s.push(lg(t,null,f,p,h,d)):s.push(h),jr(t,!0,e),m=t.input.charCodeAt(t.position),m===44?(r=!0,m=t.input.charCodeAt(++t.position)):r=!1}st(t,"unexpected end of the stream within a flow collection")}function ADe(t,e){var r,i,n=NP,s=!1,o=!1,a=e,l=0,c=!1,u,g;if(g=t.input.charCodeAt(t.position),g===124)i=!1;else if(g===62)i=!0;else return!1;for(t.kind="scalar",t.result="";g!==0;)if(g=t.input.charCodeAt(++t.position),g===43||g===45)NP===n?n=g===43?Lz:VPe:st(t,"repeat of a chomping mode identifier");else if((u=tDe(g))>=0)u===0?st(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?st(t,"repeat of an indentation width identifier"):(a=e+u-1,o=!0);else break;if(rc(g)){do g=t.input.charCodeAt(++t.position);while(rc(g));if(g===35)do g=t.input.charCodeAt(++t.position);while(!wo(g)&&g!==0)}for(;g!==0;){for(LP(t),t.lineIndent=0,g=t.input.charCodeAt(t.position);(!o||t.lineIndenta&&(a=t.lineIndent),wo(g)){l++;continue}if(t.lineIndente)&&l!==0)st(t,"bad indentation of a sequence entry");else if(t.lineIndente)&&(cg(t,e,mw,!0,n)&&(p?f=t.result:h=t.result),p||(lg(t,c,u,g,f,h,s,o),g=f=h=null),jr(t,!0,-1),m=t.input.charCodeAt(t.position)),t.lineIndent>e&&m!==0)st(t,"bad indentation of a mapping entry");else if(t.lineIndente?l=1:t.lineIndent===e?l=0:t.lineIndente?l=1:t.lineIndent===e?l=0:t.lineIndent tag; it should be "scalar", not "'+t.kind+'"'),g=0,f=t.implicitTypes.length;g tag; it should be "'+h.kind+'", not "'+t.kind+'"'),h.resolve(t.result)?(t.result=h.construct(t.result),t.anchor!==null&&(t.anchorMap[t.anchor]=t.result)):st(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")):st(t,"unknown tag !<"+t.tag+">");return t.listener!==null&&t.listener("close",t),t.tag!==null||t.anchor!==null||u}function fDe(t){var e=t.position,r,i,n,s=!1,o;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap={},t.anchorMap={};(o=t.input.charCodeAt(t.position))!==0&&(jr(t,!0,-1),o=t.input.charCodeAt(t.position),!(t.lineIndent>0||o!==37));){for(s=!0,o=t.input.charCodeAt(++t.position),r=t.position;o!==0&&!yn(o);)o=t.input.charCodeAt(++t.position);for(i=t.input.slice(r,t.position),n=[],i.length<1&&st(t,"directive name must not be less than one character in length");o!==0;){for(;rc(o);)o=t.input.charCodeAt(++t.position);if(o===35){do o=t.input.charCodeAt(++t.position);while(o!==0&&!wo(o));break}if(wo(o))break;for(r=t.position;o!==0&&!yn(o);)o=t.input.charCodeAt(++t.position);n.push(t.input.slice(r,t.position))}o!==0&&LP(t),QA.call(jz,i)?jz[i](t,i,n):Ew(t,'unknown document directive "'+i+'"')}if(jr(t,!0,-1),t.lineIndent===0&&t.input.charCodeAt(t.position)===45&&t.input.charCodeAt(t.position+1)===45&&t.input.charCodeAt(t.position+2)===45?(t.position+=3,jr(t,!0,-1)):s&&st(t,"directives end mark is expected"),cg(t,t.lineIndent-1,mw,!1,!0),jr(t,!0,-1),t.checkLineBreaks&&XPe.test(t.input.slice(e,t.position))&&Ew(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&Iw(t)){t.input.charCodeAt(t.position)===46&&(t.position+=3,jr(t,!0,-1));return}if(t.position{"use strict";var Op=$l(),Kp=ng(),dDe=Tp(),CDe=og(),_z=Object.prototype.toString,Xz=Object.prototype.hasOwnProperty,mDe=9,Up=10,EDe=13,IDe=32,yDe=33,wDe=34,Zz=35,BDe=37,QDe=38,bDe=39,vDe=42,$z=44,SDe=45,e5=58,xDe=61,kDe=62,PDe=63,DDe=64,t5=91,r5=93,RDe=96,i5=123,FDe=124,n5=125,Ri={};Ri[0]="\\0";Ri[7]="\\a";Ri[8]="\\b";Ri[9]="\\t";Ri[10]="\\n";Ri[11]="\\v";Ri[12]="\\f";Ri[13]="\\r";Ri[27]="\\e";Ri[34]='\\"';Ri[92]="\\\\";Ri[133]="\\N";Ri[160]="\\_";Ri[8232]="\\L";Ri[8233]="\\P";var NDe=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function LDe(t,e){var r,i,n,s,o,a,l;if(e===null)return{};for(r={},i=Object.keys(e),n=0,s=i.length;n0?t.charCodeAt(s-1):null,f=f&&a5(o,a)}else{for(s=0;si&&t[g+1]!==" ",g=s);else if(!ug(o))return yw;a=s>0?t.charCodeAt(s-1):null,f=f&&a5(o,a)}c=c||u&&s-g-1>i&&t[g+1]!==" "}return!l&&!c?f&&!n(t)?l5:c5:r>9&&A5(t)?yw:c?g5:u5}function jDe(t,e,r,i){t.dump=function(){if(e.length===0)return"''";if(!t.noCompatMode&&NDe.indexOf(e)!==-1)return"'"+e+"'";var n=t.indent*Math.max(1,r),s=t.lineWidth===-1?-1:Math.max(Math.min(t.lineWidth,40),t.lineWidth-n),o=i||t.flowLevel>-1&&r>=t.flowLevel;function a(l){return MDe(t,l)}switch(UDe(e,o,t.indent,s,a)){case l5:return e;case c5:return"'"+e.replace(/'/g,"''")+"'";case u5:return"|"+f5(e,t.indent)+h5(o5(e,n));case g5:return">"+f5(e,t.indent)+h5(o5(HDe(e,s),n));case yw:return'"'+GDe(e,s)+'"';default:throw new Kp("impossible error: invalid scalar style")}}()}function f5(t,e){var r=A5(t)?String(e):"",i=t[t.length-1]===` +`,n=i&&(t[t.length-2]===` +`||t===` +`),s=n?"+":i?"":"-";return r+s+` +`}function h5(t){return t[t.length-1]===` +`?t.slice(0,-1):t}function HDe(t,e){for(var r=/(\n+)([^\n]*)/g,i=function(){var c=t.indexOf(` +`);return c=c!==-1?c:t.length,r.lastIndex=c,p5(t.slice(0,c),e)}(),n=t[0]===` +`||t[0]===" ",s,o;o=r.exec(t);){var a=o[1],l=o[2];s=l[0]===" ",i+=a+(!n&&!s&&l!==""?` +`:"")+p5(l,e),n=s}return i}function p5(t,e){if(t===""||t[0]===" ")return t;for(var r=/ [^ ]/g,i,n=0,s,o=0,a=0,l="";i=r.exec(t);)a=i.index,a-n>e&&(s=o>n?o:a,l+=` +`+t.slice(n,s),n=s+1),o=a;return l+=` +`,t.length-n>e&&o>n?l+=t.slice(n,o)+` +`+t.slice(o+1):l+=t.slice(n),l.slice(1)}function GDe(t){for(var e="",r,i,n,s=0;s=55296&&r<=56319&&(i=t.charCodeAt(s+1),i>=56320&&i<=57343)){e+=s5((r-55296)*1024+i-56320+65536),s++;continue}n=Ri[r],e+=!n&&ug(r)?t[s]:n||s5(r)}return e}function YDe(t,e,r){var i="",n=t.tag,s,o;for(s=0,o=r.length;s1024&&(u+="? "),u+=t.dump+(t.condenseFlow?'"':"")+":"+(t.condenseFlow?"":" "),!!ic(t,e,c,!1,!1)&&(u+=t.dump,i+=u));t.tag=n,t.dump="{"+i+"}"}function WDe(t,e,r,i){var n="",s=t.tag,o=Object.keys(r),a,l,c,u,g,f;if(t.sortKeys===!0)o.sort();else if(typeof t.sortKeys=="function")o.sort(t.sortKeys);else if(t.sortKeys)throw new Kp("sortKeys must be a boolean or a function");for(a=0,l=o.length;a1024,g&&(t.dump&&Up===t.dump.charCodeAt(0)?f+="?":f+="? "),f+=t.dump,g&&(f+=OP(t,e)),!!ic(t,e+1,u,!0,g)&&(t.dump&&Up===t.dump.charCodeAt(0)?f+=":":f+=": ",f+=t.dump,n+=f));t.tag=s,t.dump=n||"{}"}function d5(t,e,r){var i,n,s,o,a,l;for(n=r?t.explicitTypes:t.implicitTypes,s=0,o=n.length;s tag resolver accepts not "'+l+'" style');t.dump=i}return!0}return!1}function ic(t,e,r,i,n,s){t.tag=null,t.dump=r,d5(t,r,!1)||d5(t,r,!0);var o=_z.call(t.dump);i&&(i=t.flowLevel<0||t.flowLevel>e);var a=o==="[object Object]"||o==="[object Array]",l,c;if(a&&(l=t.duplicates.indexOf(r),c=l!==-1),(t.tag!==null&&t.tag!=="?"||c||t.indent!==2&&e>0)&&(n=!1),c&&t.usedDuplicates[l])t.dump="*ref_"+l;else{if(a&&c&&!t.usedDuplicates[l]&&(t.usedDuplicates[l]=!0),o==="[object Object]")i&&Object.keys(t.dump).length!==0?(WDe(t,e,t.dump,n),c&&(t.dump="&ref_"+l+t.dump)):(JDe(t,e,t.dump),c&&(t.dump="&ref_"+l+" "+t.dump));else if(o==="[object Array]"){var u=t.noArrayIndent&&e>0?e-1:e;i&&t.dump.length!==0?(qDe(t,u,t.dump,n),c&&(t.dump="&ref_"+l+t.dump)):(YDe(t,u,t.dump),c&&(t.dump="&ref_"+l+" "+t.dump))}else if(o==="[object String]")t.tag!=="?"&&jDe(t,t.dump,e,s);else{if(t.skipInvalid)return!1;throw new Kp("unacceptable kind of an object to dump "+o)}t.tag!==null&&t.tag!=="?"&&(t.dump="!<"+t.tag+"> "+t.dump)}return!0}function zDe(t,e){var r=[],i=[],n,s;for(UP(t,r,i),n=0,s=i.length;n{"use strict";var ww=Vz(),E5=m5();function Bw(t){return function(){throw new Error("Function "+t+" is deprecated and cannot be used.")}}Qr.exports.Type=Xr();Qr.exports.Schema=ec();Qr.exports.FAILSAFE_SCHEMA=pw();Qr.exports.JSON_SCHEMA=DP();Qr.exports.CORE_SCHEMA=RP();Qr.exports.DEFAULT_SAFE_SCHEMA=og();Qr.exports.DEFAULT_FULL_SCHEMA=Tp();Qr.exports.load=ww.load;Qr.exports.loadAll=ww.loadAll;Qr.exports.safeLoad=ww.safeLoad;Qr.exports.safeLoadAll=ww.safeLoadAll;Qr.exports.dump=E5.dump;Qr.exports.safeDump=E5.safeDump;Qr.exports.YAMLException=ng();Qr.exports.MINIMAL_SCHEMA=pw();Qr.exports.SAFE_SCHEMA=og();Qr.exports.DEFAULT_SCHEMA=Tp();Qr.exports.scan=Bw("scan");Qr.exports.parse=Bw("parse");Qr.exports.compose=Bw("compose");Qr.exports.addConstructor=Bw("addConstructor")});var w5=E((wat,y5)=>{"use strict";var _De=I5();y5.exports=_De});var Q5=E((Bat,B5)=>{"use strict";function XDe(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function nc(t,e,r,i){this.message=t,this.expected=e,this.found=r,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,nc)}XDe(nc,Error);nc.buildMessage=function(t,e){var r={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g({[xe]:le})))},H=function(x){return x},L=function(x){return x},K=Yo("correct indentation"),J=" ",ne=fr(" ",!1),q=function(x){return x.length===Zc*aE},A=function(x){return x.length===(Zc+1)*aE},V=function(){return Zc++,!0},W=function(){return Zc--,!0},X=function(){return Xm()},F=Yo("pseudostring"),D=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,he=Bs(["\r",` +`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),pe=/^[^\r\n\t ,\][{}:#"']/,Ne=Bs(["\r",` +`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),Pe=function(){return Xm().replace(/^ *| *$/g,"")},qe="--",re=fr("--",!1),se=/^[a-zA-Z\/0-9]/,be=Bs([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),ae=/^[^\r\n\t :,]/,Ae=Bs(["\r",` +`," "," ",":",","],!0,!1),De="null",$=fr("null",!1),G=function(){return null},Ce="true",ee=fr("true",!1),Ue=function(){return!0},Oe="false",vt=fr("false",!1),dt=function(){return!1},ri=Yo("string"),ii='"',an=fr('"',!1),yr=function(){return""},Ki=function(x){return x},Qi=function(x){return x.join("")},Go=/^[^"\\\0-\x1F\x7F]/,wr=Bs(['"',"\\",["\0",""],"\x7F"],!0,!1),Ui='\\"',ws=fr('\\"',!1),Tf=function(){return'"'},Mf="\\\\",Rm=fr("\\\\",!1),Fm=function(){return"\\"},Nm="\\/",DQ=fr("\\/",!1),RQ=function(){return"/"},Of="\\b",FQ=fr("\\b",!1),NQ=function(){return"\b"},Lm="\\f",LQ=fr("\\f",!1),Va=function(){return"\f"},jo="\\n",Tm=fr("\\n",!1),Mm=function(){return` +`},te="\\r",Om=fr("\\r",!1),Km=function(){return"\r"},il="\\t",Um=fr("\\t",!1),Hm=function(){return" "},Kf="\\u",Gm=fr("\\u",!1),jm=function(x,U,le,xe){return String.fromCharCode(parseInt(`0x${x}${U}${le}${xe}`))},TQ=/^[0-9a-fA-F]/,MQ=Bs([["0","9"],["a","f"],["A","F"]],!1,!1),Ym=Yo("blank space"),qm=/^[ \t]/,Jm=Bs([" "," "],!1,!1),Wm=Yo("white space"),zm=/^[ \t\n\r]/,Vm=Bs([" "," ",` +`,"\r"],!1,!1),Uf=`\r +`,OQ=fr(`\r +`,!1),KQ=` +`,_m=fr(` +`,!1),UQ="\r",HQ=fr("\r",!1),O=0,ht=0,Vc=[{line:1,column:1}],xn=0,Hf=[],Ye=0,nl;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function Xm(){return t.substring(ht,O)}function MM(){return _a(ht,O)}function GQ(x,U){throw U=U!==void 0?U:_a(ht,O),eE([Yo(x)],t.substring(ht,O),U)}function OM(x,U){throw U=U!==void 0?U:_a(ht,O),YQ(x,U)}function fr(x,U){return{type:"literal",text:x,ignoreCase:U}}function Bs(x,U,le){return{type:"class",parts:x,inverted:U,ignoreCase:le}}function jQ(){return{type:"any"}}function Zm(){return{type:"end"}}function Yo(x){return{type:"other",description:x}}function $m(x){var U=Vc[x],le;if(U)return U;for(le=x-1;!Vc[le];)le--;for(U=Vc[le],U={line:U.line,column:U.column};lexn&&(xn=O,Hf=[]),Hf.push(x))}function YQ(x,U){return new nc(x,null,null,U)}function eE(x,U,le){return new nc(nc.buildMessage(x,U),x,U,le)}function tE(){var x;return x=ol(),x}function Xa(){var x,U,le;for(x=O,U=[],le=sl();le!==r;)U.push(le),le=sl();return U!==r&&(ht=x,U=s(U)),x=U,x}function sl(){var x,U,le,xe,Qe;return x=O,U=Al(),U!==r?(t.charCodeAt(O)===45?(le=o,O++):(le=r,Ye===0&&et(a)),le!==r?(xe=xr(),xe!==r?(Qe=qo(),Qe!==r?(ht=x,U=l(Qe),x=U):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r),x}function ol(){var x,U,le;for(x=O,U=[],le=al();le!==r;)U.push(le),le=al();return U!==r&&(ht=x,U=c(U)),x=U,x}function al(){var x,U,le,xe,Qe,Ge,ct,sr,Wo;if(x=O,U=xr(),U===r&&(U=null),U!==r){if(le=O,t.charCodeAt(O)===35?(xe=u,O++):(xe=r,Ye===0&&et(g)),xe!==r){if(Qe=[],Ge=O,ct=O,Ye++,sr=Zs(),Ye--,sr===r?ct=void 0:(O=ct,ct=r),ct!==r?(t.length>O?(sr=t.charAt(O),O++):(sr=r,Ye===0&&et(f)),sr!==r?(ct=[ct,sr],Ge=ct):(O=Ge,Ge=r)):(O=Ge,Ge=r),Ge!==r)for(;Ge!==r;)Qe.push(Ge),Ge=O,ct=O,Ye++,sr=Zs(),Ye--,sr===r?ct=void 0:(O=ct,ct=r),ct!==r?(t.length>O?(sr=t.charAt(O),O++):(sr=r,Ye===0&&et(f)),sr!==r?(ct=[ct,sr],Ge=ct):(O=Ge,Ge=r)):(O=Ge,Ge=r);else Qe=r;Qe!==r?(xe=[xe,Qe],le=xe):(O=le,le=r)}else O=le,le=r;if(le===r&&(le=null),le!==r){if(xe=[],Qe=Jo(),Qe!==r)for(;Qe!==r;)xe.push(Qe),Qe=Jo();else xe=r;xe!==r?(ht=x,U=h(),x=U):(O=x,x=r)}else O=x,x=r}else O=x,x=r;if(x===r&&(x=O,U=Al(),U!==r?(le=JQ(),le!==r?(xe=xr(),xe===r&&(xe=null),xe!==r?(t.charCodeAt(O)===58?(Qe=p,O++):(Qe=r,Ye===0&&et(d)),Qe!==r?(Ge=xr(),Ge===r&&(Ge=null),Ge!==r?(ct=qo(),ct!==r?(ht=x,U=m(le,ct),x=U):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r),x===r&&(x=O,U=Al(),U!==r?(le=ll(),le!==r?(xe=xr(),xe===r&&(xe=null),xe!==r?(t.charCodeAt(O)===58?(Qe=p,O++):(Qe=r,Ye===0&&et(d)),Qe!==r?(Ge=xr(),Ge===r&&(Ge=null),Ge!==r?(ct=qo(),ct!==r?(ht=x,U=m(le,ct),x=U):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r),x===r))){if(x=O,U=Al(),U!==r)if(le=ll(),le!==r)if(xe=xr(),xe!==r)if(Qe=nE(),Qe!==r){if(Ge=[],ct=Jo(),ct!==r)for(;ct!==r;)Ge.push(ct),ct=Jo();else Ge=r;Ge!==r?(ht=x,U=m(le,Qe),x=U):(O=x,x=r)}else O=x,x=r;else O=x,x=r;else O=x,x=r;else O=x,x=r;if(x===r)if(x=O,U=Al(),U!==r)if(le=ll(),le!==r){if(xe=[],Qe=O,Ge=xr(),Ge===r&&(Ge=null),Ge!==r?(t.charCodeAt(O)===44?(ct=I,O++):(ct=r,Ye===0&&et(B)),ct!==r?(sr=xr(),sr===r&&(sr=null),sr!==r?(Wo=ll(),Wo!==r?(ht=Qe,Ge=b(le,Wo),Qe=Ge):(O=Qe,Qe=r)):(O=Qe,Qe=r)):(O=Qe,Qe=r)):(O=Qe,Qe=r),Qe!==r)for(;Qe!==r;)xe.push(Qe),Qe=O,Ge=xr(),Ge===r&&(Ge=null),Ge!==r?(t.charCodeAt(O)===44?(ct=I,O++):(ct=r,Ye===0&&et(B)),ct!==r?(sr=xr(),sr===r&&(sr=null),sr!==r?(Wo=ll(),Wo!==r?(ht=Qe,Ge=b(le,Wo),Qe=Ge):(O=Qe,Qe=r)):(O=Qe,Qe=r)):(O=Qe,Qe=r)):(O=Qe,Qe=r);else xe=r;xe!==r?(Qe=xr(),Qe===r&&(Qe=null),Qe!==r?(t.charCodeAt(O)===58?(Ge=p,O++):(Ge=r,Ye===0&&et(d)),Ge!==r?(ct=xr(),ct===r&&(ct=null),ct!==r?(sr=qo(),sr!==r?(ht=x,U=R(le,xe,sr),x=U):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)}else O=x,x=r;else O=x,x=r}return x}function qo(){var x,U,le,xe,Qe,Ge,ct;if(x=O,U=O,Ye++,le=O,xe=Zs(),xe!==r?(Qe=qQ(),Qe!==r?(t.charCodeAt(O)===45?(Ge=o,O++):(Ge=r,Ye===0&&et(a)),Ge!==r?(ct=xr(),ct!==r?(xe=[xe,Qe,Ge,ct],le=xe):(O=le,le=r)):(O=le,le=r)):(O=le,le=r)):(O=le,le=r),Ye--,le!==r?(O=U,U=void 0):U=r,U!==r?(le=Jo(),le!==r?(xe=rE(),xe!==r?(Qe=Xa(),Qe!==r?(Ge=iE(),Ge!==r?(ht=x,U=H(Qe),x=U):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r),x===r&&(x=O,U=Zs(),U!==r?(le=rE(),le!==r?(xe=ol(),xe!==r?(Qe=iE(),Qe!==r?(ht=x,U=H(xe),x=U):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r),x===r))if(x=O,U=WQ(),U!==r){if(le=[],xe=Jo(),xe!==r)for(;xe!==r;)le.push(xe),xe=Jo();else le=r;le!==r?(ht=x,U=L(U),x=U):(O=x,x=r)}else O=x,x=r;return x}function Al(){var x,U,le;for(Ye++,x=O,U=[],t.charCodeAt(O)===32?(le=J,O++):(le=r,Ye===0&&et(ne));le!==r;)U.push(le),t.charCodeAt(O)===32?(le=J,O++):(le=r,Ye===0&&et(ne));return U!==r?(ht=O,le=q(U),le?le=void 0:le=r,le!==r?(U=[U,le],x=U):(O=x,x=r)):(O=x,x=r),Ye--,x===r&&(U=r,Ye===0&&et(K)),x}function qQ(){var x,U,le;for(x=O,U=[],t.charCodeAt(O)===32?(le=J,O++):(le=r,Ye===0&&et(ne));le!==r;)U.push(le),t.charCodeAt(O)===32?(le=J,O++):(le=r,Ye===0&&et(ne));return U!==r?(ht=O,le=A(U),le?le=void 0:le=r,le!==r?(U=[U,le],x=U):(O=x,x=r)):(O=x,x=r),x}function rE(){var x;return ht=O,x=V(),x?x=void 0:x=r,x}function iE(){var x;return ht=O,x=W(),x?x=void 0:x=r,x}function JQ(){var x;return x=cl(),x===r&&(x=Gf()),x}function ll(){var x,U,le;if(x=cl(),x===r){if(x=O,U=[],le=_c(),le!==r)for(;le!==r;)U.push(le),le=_c();else U=r;U!==r&&(ht=x,U=X()),x=U}return x}function WQ(){var x;return x=jf(),x===r&&(x=sE(),x===r&&(x=cl(),x===r&&(x=Gf()))),x}function nE(){var x;return x=jf(),x===r&&(x=cl(),x===r&&(x=_c())),x}function Gf(){var x,U,le,xe,Qe,Ge;if(Ye++,x=O,D.test(t.charAt(O))?(U=t.charAt(O),O++):(U=r,Ye===0&&et(he)),U!==r){for(le=[],xe=O,Qe=xr(),Qe===r&&(Qe=null),Qe!==r?(pe.test(t.charAt(O))?(Ge=t.charAt(O),O++):(Ge=r,Ye===0&&et(Ne)),Ge!==r?(Qe=[Qe,Ge],xe=Qe):(O=xe,xe=r)):(O=xe,xe=r);xe!==r;)le.push(xe),xe=O,Qe=xr(),Qe===r&&(Qe=null),Qe!==r?(pe.test(t.charAt(O))?(Ge=t.charAt(O),O++):(Ge=r,Ye===0&&et(Ne)),Ge!==r?(Qe=[Qe,Ge],xe=Qe):(O=xe,xe=r)):(O=xe,xe=r);le!==r?(ht=x,U=Pe(),x=U):(O=x,x=r)}else O=x,x=r;return Ye--,x===r&&(U=r,Ye===0&&et(F)),x}function _c(){var x,U,le,xe,Qe;if(x=O,t.substr(O,2)===qe?(U=qe,O+=2):(U=r,Ye===0&&et(re)),U===r&&(U=null),U!==r)if(se.test(t.charAt(O))?(le=t.charAt(O),O++):(le=r,Ye===0&&et(be)),le!==r){for(xe=[],ae.test(t.charAt(O))?(Qe=t.charAt(O),O++):(Qe=r,Ye===0&&et(Ae));Qe!==r;)xe.push(Qe),ae.test(t.charAt(O))?(Qe=t.charAt(O),O++):(Qe=r,Ye===0&&et(Ae));xe!==r?(ht=x,U=Pe(),x=U):(O=x,x=r)}else O=x,x=r;else O=x,x=r;return x}function jf(){var x,U;return x=O,t.substr(O,4)===De?(U=De,O+=4):(U=r,Ye===0&&et($)),U!==r&&(ht=x,U=G()),x=U,x}function sE(){var x,U;return x=O,t.substr(O,4)===Ce?(U=Ce,O+=4):(U=r,Ye===0&&et(ee)),U!==r&&(ht=x,U=Ue()),x=U,x===r&&(x=O,t.substr(O,5)===Oe?(U=Oe,O+=5):(U=r,Ye===0&&et(vt)),U!==r&&(ht=x,U=dt()),x=U),x}function cl(){var x,U,le,xe;return Ye++,x=O,t.charCodeAt(O)===34?(U=ii,O++):(U=r,Ye===0&&et(an)),U!==r?(t.charCodeAt(O)===34?(le=ii,O++):(le=r,Ye===0&&et(an)),le!==r?(ht=x,U=yr(),x=U):(O=x,x=r)):(O=x,x=r),x===r&&(x=O,t.charCodeAt(O)===34?(U=ii,O++):(U=r,Ye===0&&et(an)),U!==r?(le=oE(),le!==r?(t.charCodeAt(O)===34?(xe=ii,O++):(xe=r,Ye===0&&et(an)),xe!==r?(ht=x,U=Ki(le),x=U):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)),Ye--,x===r&&(U=r,Ye===0&&et(ri)),x}function oE(){var x,U,le;if(x=O,U=[],le=Yf(),le!==r)for(;le!==r;)U.push(le),le=Yf();else U=r;return U!==r&&(ht=x,U=Qi(U)),x=U,x}function Yf(){var x,U,le,xe,Qe,Ge;return Go.test(t.charAt(O))?(x=t.charAt(O),O++):(x=r,Ye===0&&et(wr)),x===r&&(x=O,t.substr(O,2)===Ui?(U=Ui,O+=2):(U=r,Ye===0&&et(ws)),U!==r&&(ht=x,U=Tf()),x=U,x===r&&(x=O,t.substr(O,2)===Mf?(U=Mf,O+=2):(U=r,Ye===0&&et(Rm)),U!==r&&(ht=x,U=Fm()),x=U,x===r&&(x=O,t.substr(O,2)===Nm?(U=Nm,O+=2):(U=r,Ye===0&&et(DQ)),U!==r&&(ht=x,U=RQ()),x=U,x===r&&(x=O,t.substr(O,2)===Of?(U=Of,O+=2):(U=r,Ye===0&&et(FQ)),U!==r&&(ht=x,U=NQ()),x=U,x===r&&(x=O,t.substr(O,2)===Lm?(U=Lm,O+=2):(U=r,Ye===0&&et(LQ)),U!==r&&(ht=x,U=Va()),x=U,x===r&&(x=O,t.substr(O,2)===jo?(U=jo,O+=2):(U=r,Ye===0&&et(Tm)),U!==r&&(ht=x,U=Mm()),x=U,x===r&&(x=O,t.substr(O,2)===te?(U=te,O+=2):(U=r,Ye===0&&et(Om)),U!==r&&(ht=x,U=Km()),x=U,x===r&&(x=O,t.substr(O,2)===il?(U=il,O+=2):(U=r,Ye===0&&et(Um)),U!==r&&(ht=x,U=Hm()),x=U,x===r&&(x=O,t.substr(O,2)===Kf?(U=Kf,O+=2):(U=r,Ye===0&&et(Gm)),U!==r?(le=Xc(),le!==r?(xe=Xc(),xe!==r?(Qe=Xc(),Qe!==r?(Ge=Xc(),Ge!==r?(ht=x,U=jm(le,xe,Qe,Ge),x=U):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)):(O=x,x=r)))))))))),x}function Xc(){var x;return TQ.test(t.charAt(O))?(x=t.charAt(O),O++):(x=r,Ye===0&&et(MQ)),x}function xr(){var x,U;if(Ye++,x=[],qm.test(t.charAt(O))?(U=t.charAt(O),O++):(U=r,Ye===0&&et(Jm)),U!==r)for(;U!==r;)x.push(U),qm.test(t.charAt(O))?(U=t.charAt(O),O++):(U=r,Ye===0&&et(Jm));else x=r;return Ye--,x===r&&(U=r,Ye===0&&et(Ym)),x}function KM(){var x,U;if(Ye++,x=[],zm.test(t.charAt(O))?(U=t.charAt(O),O++):(U=r,Ye===0&&et(Vm)),U!==r)for(;U!==r;)x.push(U),zm.test(t.charAt(O))?(U=t.charAt(O),O++):(U=r,Ye===0&&et(Vm));else x=r;return Ye--,x===r&&(U=r,Ye===0&&et(Wm)),x}function Jo(){var x,U,le,xe,Qe,Ge;if(x=O,U=Zs(),U!==r){for(le=[],xe=O,Qe=xr(),Qe===r&&(Qe=null),Qe!==r?(Ge=Zs(),Ge!==r?(Qe=[Qe,Ge],xe=Qe):(O=xe,xe=r)):(O=xe,xe=r);xe!==r;)le.push(xe),xe=O,Qe=xr(),Qe===r&&(Qe=null),Qe!==r?(Ge=Zs(),Ge!==r?(Qe=[Qe,Ge],xe=Qe):(O=xe,xe=r)):(O=xe,xe=r);le!==r?(U=[U,le],x=U):(O=x,x=r)}else O=x,x=r;return x}function Zs(){var x;return t.substr(O,2)===Uf?(x=Uf,O+=2):(x=r,Ye===0&&et(OQ)),x===r&&(t.charCodeAt(O)===10?(x=KQ,O++):(x=r,Ye===0&&et(_m)),x===r&&(t.charCodeAt(O)===13?(x=UQ,O++):(x=r,Ye===0&&et(HQ)))),x}let aE=2,Zc=0;if(nl=n(),nl!==r&&O===t.length)return nl;throw nl!==r&&O{var fRe=typeof global=="object"&&global&&global.Object===Object&&global;V5.exports=fRe});var Ks=E((Zat,_5)=>{var hRe=WP(),pRe=typeof self=="object"&&self&&self.Object===Object&&self,dRe=hRe||pRe||Function("return this")();_5.exports=dRe});var ac=E(($at,X5)=>{var CRe=Ks(),mRe=CRe.Symbol;X5.exports=mRe});var $5=E((eAt,Z5)=>{function ERe(t,e){for(var r=-1,i=t==null?0:t.length,n=Array(i);++r{var IRe=Array.isArray;e6.exports=IRe});var n6=E((rAt,t6)=>{var r6=ac(),i6=Object.prototype,yRe=i6.hasOwnProperty,wRe=i6.toString,Jp=r6?r6.toStringTag:void 0;function BRe(t){var e=yRe.call(t,Jp),r=t[Jp];try{t[Jp]=void 0;var i=!0}catch(s){}var n=wRe.call(t);return i&&(e?t[Jp]=r:delete t[Jp]),n}t6.exports=BRe});var o6=E((iAt,s6)=>{var QRe=Object.prototype,bRe=QRe.toString;function vRe(t){return bRe.call(t)}s6.exports=vRe});var Ac=E((nAt,a6)=>{var A6=ac(),SRe=n6(),xRe=o6(),kRe="[object Null]",PRe="[object Undefined]",l6=A6?A6.toStringTag:void 0;function DRe(t){return t==null?t===void 0?PRe:kRe:l6&&l6 in Object(t)?SRe(t):xRe(t)}a6.exports=DRe});var Qo=E((sAt,c6)=>{function RRe(t){return t!=null&&typeof t=="object"}c6.exports=RRe});var Nw=E((oAt,u6)=>{var FRe=Ac(),NRe=Qo(),LRe="[object Symbol]";function TRe(t){return typeof t=="symbol"||NRe(t)&&FRe(t)==LRe}u6.exports=TRe});var C6=E((aAt,g6)=>{var f6=ac(),MRe=$5(),ORe=As(),KRe=Nw(),URe=1/0,h6=f6?f6.prototype:void 0,p6=h6?h6.toString:void 0;function d6(t){if(typeof t=="string")return t;if(ORe(t))return MRe(t,d6)+"";if(KRe(t))return p6?p6.call(t):"";var e=t+"";return e=="0"&&1/t==-URe?"-0":e}g6.exports=d6});var gg=E((AAt,m6)=>{var HRe=C6();function GRe(t){return t==null?"":HRe(t)}m6.exports=GRe});var zP=E((lAt,E6)=>{function jRe(t,e,r){var i=-1,n=t.length;e<0&&(e=-e>n?0:n+e),r=r>n?n:r,r<0&&(r+=n),n=e>r?0:r-e>>>0,e>>>=0;for(var s=Array(n);++i{var YRe=zP();function qRe(t,e,r){var i=t.length;return r=r===void 0?i:r,!e&&r>=i?t:YRe(t,e,r)}I6.exports=qRe});var VP=E((uAt,w6)=>{var JRe="\\ud800-\\udfff",WRe="\\u0300-\\u036f",zRe="\\ufe20-\\ufe2f",VRe="\\u20d0-\\u20ff",_Re=WRe+zRe+VRe,XRe="\\ufe0e\\ufe0f",ZRe="\\u200d",$Re=RegExp("["+ZRe+JRe+_Re+XRe+"]");function eFe(t){return $Re.test(t)}w6.exports=eFe});var Q6=E((gAt,B6)=>{function tFe(t){return t.split("")}B6.exports=tFe});var R6=E((fAt,b6)=>{var v6="\\ud800-\\udfff",rFe="\\u0300-\\u036f",iFe="\\ufe20-\\ufe2f",nFe="\\u20d0-\\u20ff",sFe=rFe+iFe+nFe,oFe="\\ufe0e\\ufe0f",aFe="["+v6+"]",_P="["+sFe+"]",XP="\\ud83c[\\udffb-\\udfff]",AFe="(?:"+_P+"|"+XP+")",S6="[^"+v6+"]",x6="(?:\\ud83c[\\udde6-\\uddff]){2}",k6="[\\ud800-\\udbff][\\udc00-\\udfff]",lFe="\\u200d",P6=AFe+"?",D6="["+oFe+"]?",cFe="(?:"+lFe+"(?:"+[S6,x6,k6].join("|")+")"+D6+P6+")*",uFe=D6+P6+cFe,gFe="(?:"+[S6+_P+"?",_P,x6,k6,aFe].join("|")+")",fFe=RegExp(XP+"(?="+XP+")|"+gFe+uFe,"g");function hFe(t){return t.match(fFe)||[]}b6.exports=hFe});var N6=E((hAt,F6)=>{var pFe=Q6(),dFe=VP(),CFe=R6();function mFe(t){return dFe(t)?CFe(t):pFe(t)}F6.exports=mFe});var T6=E((pAt,L6)=>{var EFe=y6(),IFe=VP(),yFe=N6(),wFe=gg();function BFe(t){return function(e){e=wFe(e);var r=IFe(e)?yFe(e):void 0,i=r?r[0]:e.charAt(0),n=r?EFe(r,1).join(""):e.slice(1);return i[t]()+n}}L6.exports=BFe});var O6=E((dAt,M6)=>{var QFe=T6(),bFe=QFe("toUpperCase");M6.exports=bFe});var ZP=E((CAt,K6)=>{var vFe=gg(),SFe=O6();function xFe(t){return SFe(vFe(t).toLowerCase())}K6.exports=xFe});var H6=E((mAt,U6)=>{"use strict";U6.exports=(t,...e)=>new Promise(r=>{r(t(...e))})});var Wp=E((EAt,$P)=>{"use strict";var kFe=H6(),G6=t=>{if(t<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],r=0,i=()=>{r--,e.length>0&&e.shift()()},n=(a,l,...c)=>{r++;let u=kFe(a,...c);l(u),u.then(i,i)},s=(a,l,...c)=>{rnew Promise(c=>s(a,c,...l));return Object.defineProperties(o,{activeCount:{get:()=>r},pendingCount:{get:()=>e.length}}),o};$P.exports=G6;$P.exports.default=G6});var X6=E((FAt,Mw)=>{function PFe(){var t=0,e=1,r=2,i=3,n=4,s=5,o=6,a=7,l=8,c=9,u=10,g=11,f=12,h=13,p=14,d=15,m=16,I=17,B=0,b=1,R=2,H=3,L=4;function K(A,V){return 55296<=A.charCodeAt(V)&&A.charCodeAt(V)<=56319&&56320<=A.charCodeAt(V+1)&&A.charCodeAt(V+1)<=57343}function J(A,V){V===void 0&&(V=0);var W=A.charCodeAt(V);if(55296<=W&&W<=56319&&V=1){var X=A.charCodeAt(V-1),F=W;return 55296<=X&&X<=56319?(X-55296)*1024+(F-56320)+65536:F}return W}function ne(A,V,W){var X=[A].concat(V).concat([W]),F=X[X.length-2],D=W,he=X.lastIndexOf(p);if(he>1&&X.slice(1,he).every(function(Pe){return Pe==i})&&[i,h,I].indexOf(A)==-1)return R;var pe=X.lastIndexOf(n);if(pe>0&&X.slice(1,pe).every(function(Pe){return Pe==n})&&[f,n].indexOf(F)==-1)return X.filter(function(Pe){return Pe==n}).length%2==1?H:L;if(F==t&&D==e)return B;if(F==r||F==t||F==e)return D==p&&V.every(function(Pe){return Pe==i})?R:b;if(D==r||D==t||D==e)return b;if(F==o&&(D==o||D==a||D==c||D==u))return B;if((F==c||F==a)&&(D==a||D==l))return B;if((F==u||F==l)&&D==l)return B;if(D==i||D==d)return B;if(D==s)return B;if(F==f)return B;var Ne=X.indexOf(i)!=-1?X.lastIndexOf(i)-1:X.length-2;return[h,I].indexOf(X[Ne])!=-1&&X.slice(Ne+1,-1).every(function(Pe){return Pe==i})&&D==p||F==d&&[m,I].indexOf(D)!=-1?B:V.indexOf(n)!=-1?R:F==n&&D==n?B:b}this.nextBreak=function(A,V){if(V===void 0&&(V=0),V<0)return 0;if(V>=A.length-1)return A.length;for(var W=q(J(A,V)),X=[],F=V+1;F{var DFe=X6(),RFe=/^(.*?)(\x1b\[[^m]+m|\x1b\]8;;.*?(\x1b\\|\u0007))/,FFe=new DFe;Z6.exports=(t,e=0,r=t.length)=>{if(e<0||r<0)throw new RangeError("Negative indices aren't supported by this implementation");let i=r-e,n="",s=0,o=0;for(;t.length>0;){let a=t.match(RFe)||[t,t,void 0],l=FFe.splitGraphemes(a[1]),c=Math.min(e-s,l.length);l=l.slice(c);let u=Math.min(i-o,l.length);n+=l.slice(0,u).join(""),s+=c,o+=u,typeof a[2]!="undefined"&&(n+=a[2]),t=t.slice(a[0].length)}return n}});var fg=E((alt,f9)=>{"use strict";var h9=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"]]),olt=f9.exports=t=>t?Object.keys(t).map(e=>[h9.has(e)?h9.get(e):e,t[e]]).reduce((e,r)=>(e[r[0]]=r[1],e),Object.create(null)):{}});var hg=E((Alt,p9)=>{"use strict";var JFe=require("events"),d9=require("stream"),_p=Rh(),C9=require("string_decoder").StringDecoder,va=Symbol("EOF"),Xp=Symbol("maybeEmitEnd"),xA=Symbol("emittedEnd"),Gw=Symbol("emittingEnd"),jw=Symbol("closed"),m9=Symbol("read"),iD=Symbol("flush"),E9=Symbol("flushChunk"),Bn=Symbol("encoding"),Sa=Symbol("decoder"),Yw=Symbol("flowing"),Zp=Symbol("paused"),$p=Symbol("resume"),rn=Symbol("bufferLength"),I9=Symbol("bufferPush"),nD=Symbol("bufferShift"),Ni=Symbol("objectMode"),Li=Symbol("destroyed"),y9=global._MP_NO_ITERATOR_SYMBOLS_!=="1",WFe=y9&&Symbol.asyncIterator||Symbol("asyncIterator not implemented"),zFe=y9&&Symbol.iterator||Symbol("iterator not implemented"),w9=t=>t==="end"||t==="finish"||t==="prefinish",VFe=t=>t instanceof ArrayBuffer||typeof t=="object"&&t.constructor&&t.constructor.name==="ArrayBuffer"&&t.byteLength>=0,_Fe=t=>!Buffer.isBuffer(t)&&ArrayBuffer.isView(t);p9.exports=class B9 extends d9{constructor(e){super();this[Yw]=!1,this[Zp]=!1,this.pipes=new _p,this.buffer=new _p,this[Ni]=e&&e.objectMode||!1,this[Ni]?this[Bn]=null:this[Bn]=e&&e.encoding||null,this[Bn]==="buffer"&&(this[Bn]=null),this[Sa]=this[Bn]?new C9(this[Bn]):null,this[va]=!1,this[xA]=!1,this[Gw]=!1,this[jw]=!1,this.writable=!0,this.readable=!0,this[rn]=0,this[Li]=!1}get bufferLength(){return this[rn]}get encoding(){return this[Bn]}set encoding(e){if(this[Ni])throw new Error("cannot set encoding in objectMode");if(this[Bn]&&e!==this[Bn]&&(this[Sa]&&this[Sa].lastNeed||this[rn]))throw new Error("cannot change encoding");this[Bn]!==e&&(this[Sa]=e?new C9(e):null,this.buffer.length&&(this.buffer=this.buffer.map(r=>this[Sa].write(r)))),this[Bn]=e}setEncoding(e){this.encoding=e}get objectMode(){return this[Ni]}set objectMode(e){this[Ni]=this[Ni]||!!e}write(e,r,i){if(this[va])throw new Error("write after end");return this[Li]?(this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0):(typeof r=="function"&&(i=r,r="utf8"),r||(r="utf8"),!this[Ni]&&!Buffer.isBuffer(e)&&(_Fe(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):VFe(e)?e=Buffer.from(e):typeof e!="string"&&(this.objectMode=!0)),!this.objectMode&&!e.length?(this[rn]!==0&&this.emit("readable"),i&&i(),this.flowing):(typeof e=="string"&&!this[Ni]&&!(r===this[Bn]&&!this[Sa].lastNeed)&&(e=Buffer.from(e,r)),Buffer.isBuffer(e)&&this[Bn]&&(e=this[Sa].write(e)),this.flowing?(this[rn]!==0&&this[iD](!0),this.emit("data",e)):this[I9](e),this[rn]!==0&&this.emit("readable"),i&&i(),this.flowing))}read(e){if(this[Li])return null;try{return this[rn]===0||e===0||e>this[rn]?null:(this[Ni]&&(e=null),this.buffer.length>1&&!this[Ni]&&(this.encoding?this.buffer=new _p([Array.from(this.buffer).join("")]):this.buffer=new _p([Buffer.concat(Array.from(this.buffer),this[rn])])),this[m9](e||null,this.buffer.head.value))}finally{this[Xp]()}}[m9](e,r){return e===r.length||e===null?this[nD]():(this.buffer.head.value=r.slice(e),r=r.slice(0,e),this[rn]-=e),this.emit("data",r),!this.buffer.length&&!this[va]&&this.emit("drain"),r}end(e,r,i){return typeof e=="function"&&(i=e,e=null),typeof r=="function"&&(i=r,r="utf8"),e&&this.write(e,r),i&&this.once("end",i),this[va]=!0,this.writable=!1,(this.flowing||!this[Zp])&&this[Xp](),this}[$p](){this[Li]||(this[Zp]=!1,this[Yw]=!0,this.emit("resume"),this.buffer.length?this[iD]():this[va]?this[Xp]():this.emit("drain"))}resume(){return this[$p]()}pause(){this[Yw]=!1,this[Zp]=!0}get destroyed(){return this[Li]}get flowing(){return this[Yw]}get paused(){return this[Zp]}[I9](e){return this[Ni]?this[rn]+=1:this[rn]+=e.length,this.buffer.push(e)}[nD](){return this.buffer.length&&(this[Ni]?this[rn]-=1:this[rn]-=this.buffer.head.value.length),this.buffer.shift()}[iD](e){do;while(this[E9](this[nD]()));!e&&!this.buffer.length&&!this[va]&&this.emit("drain")}[E9](e){return e?(this.emit("data",e),this.flowing):!1}pipe(e,r){if(this[Li])return;let i=this[xA];r=r||{},e===process.stdout||e===process.stderr?r.end=!1:r.end=r.end!==!1;let n={dest:e,opts:r,ondrain:s=>this[$p]()};return this.pipes.push(n),e.on("drain",n.ondrain),this[$p](),i&&n.opts.end&&n.dest.end(),e}addListener(e,r){return this.on(e,r)}on(e,r){try{return super.on(e,r)}finally{e==="data"&&!this.pipes.length&&!this.flowing?this[$p]():w9(e)&&this[xA]&&(super.emit(e),this.removeAllListeners(e))}}get emittedEnd(){return this[xA]}[Xp](){!this[Gw]&&!this[xA]&&!this[Li]&&this.buffer.length===0&&this[va]&&(this[Gw]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[jw]&&this.emit("close"),this[Gw]=!1)}emit(e,r){if(e!=="error"&&e!=="close"&&e!==Li&&this[Li])return;if(e==="data"){if(!r)return;this.pipes.length&&this.pipes.forEach(n=>n.dest.write(r)===!1&&this.pause())}else if(e==="end"){if(this[xA]===!0)return;this[xA]=!0,this.readable=!1,this[Sa]&&(r=this[Sa].end(),r&&(this.pipes.forEach(n=>n.dest.write(r)),super.emit("data",r))),this.pipes.forEach(n=>{n.dest.removeListener("drain",n.ondrain),n.opts.end&&n.dest.end()})}else if(e==="close"&&(this[jw]=!0,!this[xA]&&!this[Li]))return;let i=new Array(arguments.length);if(i[0]=e,i[1]=r,arguments.length>2)for(let n=2;n{e.push(i),this[Ni]||(e.dataLength+=i.length)}),r.then(()=>e)}concat(){return this[Ni]?Promise.reject(new Error("cannot concat in objectMode")):this.collect().then(e=>this[Ni]?Promise.reject(new Error("cannot concat in objectMode")):this[Bn]?e.join(""):Buffer.concat(e,e.dataLength))}promise(){return new Promise((e,r)=>{this.on(Li,()=>r(new Error("stream destroyed"))),this.on("end",()=>e()),this.on("error",i=>r(i))})}[WFe](){return{next:()=>{let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[va])return Promise.resolve({done:!0});let i=null,n=null,s=c=>{this.removeListener("data",o),this.removeListener("end",a),n(c)},o=c=>{this.removeListener("error",s),this.removeListener("end",a),this.pause(),i({value:c,done:!!this[va]})},a=()=>{this.removeListener("error",s),this.removeListener("data",o),i({done:!0})},l=()=>s(new Error("stream destroyed"));return new Promise((c,u)=>{n=u,i=c,this.once(Li,l),this.once("error",s),this.once("end",a),this.once("data",o)})}}}[zFe](){return{next:()=>{let r=this.read();return{value:r,done:r===null}}}}destroy(e){return this[Li]?(e?this.emit("error",e):this.emit(Li),this):(this[Li]=!0,this.buffer=new _p,this[rn]=0,typeof this.close=="function"&&!this[jw]&&this.close(),e?this.emit("error",e):this.emit(Li),this)}static isStream(e){return!!e&&(e instanceof B9||e instanceof d9||e instanceof JFe&&(typeof e.pipe=="function"||typeof e.write=="function"&&typeof e.end=="function"))}}});var b9=E((llt,Q9)=>{var XFe=require("zlib").constants||{ZLIB_VERNUM:4736};Q9.exports=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:Infinity,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},XFe))});var fD=E(Un=>{"use strict";var sD=require("assert"),kA=require("buffer").Buffer,v9=require("zlib"),uc=Un.constants=b9(),ZFe=hg(),S9=kA.concat,gc=Symbol("_superWrite"),ed=class extends Error{constructor(e){super("zlib: "+e.message);this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,this.constructor)}get name(){return"ZlibError"}},$Fe=Symbol("opts"),td=Symbol("flushFlag"),x9=Symbol("finishFlushFlag"),oD=Symbol("fullFlushFlag"),tr=Symbol("handle"),qw=Symbol("onError"),pg=Symbol("sawError"),aD=Symbol("level"),AD=Symbol("strategy"),lD=Symbol("ended"),clt=Symbol("_defaultFullFlush"),cD=class extends ZFe{constructor(e,r){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");super(e);this[pg]=!1,this[lD]=!1,this[$Fe]=e,this[td]=e.flush,this[x9]=e.finishFlush;try{this[tr]=new v9[r](e)}catch(i){throw new ed(i)}this[qw]=i=>{this[pg]||(this[pg]=!0,this.close(),this.emit("error",i))},this[tr].on("error",i=>this[qw](new ed(i))),this.once("end",()=>this.close)}close(){this[tr]&&(this[tr].close(),this[tr]=null,this.emit("close"))}reset(){if(!this[pg])return sD(this[tr],"zlib binding closed"),this[tr].reset()}flush(e){this.ended||(typeof e!="number"&&(e=this[oD]),this.write(Object.assign(kA.alloc(0),{[td]:e})))}end(e,r,i){return e&&this.write(e,r),this.flush(this[x9]),this[lD]=!0,super.end(null,null,i)}get ended(){return this[lD]}write(e,r,i){if(typeof r=="function"&&(i=r,r="utf8"),typeof e=="string"&&(e=kA.from(e,r)),this[pg])return;sD(this[tr],"zlib binding closed");let n=this[tr]._handle,s=n.close;n.close=()=>{};let o=this[tr].close;this[tr].close=()=>{},kA.concat=c=>c;let a;try{let c=typeof e[td]=="number"?e[td]:this[td];a=this[tr]._processChunk(e,c),kA.concat=S9}catch(c){kA.concat=S9,this[qw](new ed(c))}finally{this[tr]&&(this[tr]._handle=n,n.close=s,this[tr].close=o,this[tr].removeAllListeners("error"))}this[tr]&&this[tr].on("error",c=>this[qw](new ed(c)));let l;if(a)if(Array.isArray(a)&&a.length>0){l=this[gc](kA.from(a[0]));for(let c=1;c{this.flush(n),s()};try{this[tr].params(e,r)}finally{this[tr].flush=i}this[tr]&&(this[aD]=e,this[AD]=r)}}}},k9=class extends PA{constructor(e){super(e,"Deflate")}},P9=class extends PA{constructor(e){super(e,"Inflate")}},uD=Symbol("_portable"),D9=class extends PA{constructor(e){super(e,"Gzip");this[uD]=e&&!!e.portable}[gc](e){return this[uD]?(this[uD]=!1,e[9]=255,super[gc](e)):super[gc](e)}},R9=class extends PA{constructor(e){super(e,"Gunzip")}},F9=class extends PA{constructor(e){super(e,"DeflateRaw")}},N9=class extends PA{constructor(e){super(e,"InflateRaw")}},L9=class extends PA{constructor(e){super(e,"Unzip")}},gD=class extends cD{constructor(e,r){e=e||{},e.flush=e.flush||uc.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||uc.BROTLI_OPERATION_FINISH,super(e,r),this[oD]=uc.BROTLI_OPERATION_FLUSH}},T9=class extends gD{constructor(e){super(e,"BrotliCompress")}},M9=class extends gD{constructor(e){super(e,"BrotliDecompress")}};Un.Deflate=k9;Un.Inflate=P9;Un.Gzip=D9;Un.Gunzip=R9;Un.DeflateRaw=F9;Un.InflateRaw=N9;Un.Unzip=L9;typeof v9.BrotliCompress=="function"?(Un.BrotliCompress=T9,Un.BrotliDecompress=M9):Un.BrotliCompress=Un.BrotliDecompress=class{constructor(){throw new Error("Brotli is not supported in this version of Node.js")}}});var rd=E(Jw=>{"use strict";Jw.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);Jw.code=new Map(Array.from(Jw.name).map(t=>[t[1],t[0]]))});var id=E((plt,O9)=>{"use strict";var flt=rd(),eNe=hg(),hD=Symbol("slurp");O9.exports=class extends eNe{constructor(e,r,i){super();switch(this.pause(),this.extended=r,this.globalExtended=i,this.header=e,this.startBlockSize=512*Math.ceil(e.size/512),this.blockRemain=this.startBlockSize,this.remain=e.size,this.type=e.type,this.meta=!1,this.ignore=!1,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}this.path=e.path,this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=e.size,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=e.linkpath,this.uname=e.uname,this.gname=e.gname,r&&this[hD](r),i&&this[hD](i,!0)}write(e){let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,n=this.blockRemain;return this.remain=Math.max(0,i-r),this.blockRemain=Math.max(0,n-r),this.ignore?!0:i>=r?super.write(e):super.write(e.slice(0,i))}[hD](e,r){for(let i in e)e[i]!==null&&e[i]!==void 0&&!(r&&i==="path")&&(this[i]=e[i])}}});var H9=E(pD=>{"use strict";var dlt=pD.encode=(t,e)=>{if(Number.isSafeInteger(t))t<0?rNe(t,e):tNe(t,e);else throw Error("cannot encode number outside of javascript safe integer range");return e},tNe=(t,e)=>{e[0]=128;for(var r=e.length;r>1;r--)e[r-1]=t&255,t=Math.floor(t/256)},rNe=(t,e)=>{e[0]=255;var r=!1;t=t*-1;for(var i=e.length;i>1;i--){var n=t&255;t=Math.floor(t/256),r?e[i-1]=K9(n):n===0?e[i-1]=0:(r=!0,e[i-1]=U9(n))}},Clt=pD.parse=t=>{var e=t[t.length-1],r=t[0],i;if(r===128)i=nNe(t.slice(1,t.length));else if(r===255)i=iNe(t);else throw Error("invalid base256 encoding");if(!Number.isSafeInteger(i))throw Error("parsed number outside of javascript safe integer range");return i},iNe=t=>{for(var e=t.length,r=0,i=!1,n=e-1;n>-1;n--){var s=t[n],o;i?o=K9(s):s===0?o=s:(i=!0,o=U9(s)),o!==0&&(r-=o*Math.pow(256,e-n-1))}return r},nNe=t=>{for(var e=t.length,r=0,i=e-1;i>-1;i--){var n=t[i];n!==0&&(r+=n*Math.pow(256,e-i-1))}return r},K9=t=>(255^t)&255,U9=t=>(255^t)+1&255});var Cg=E((Elt,G9)=>{"use strict";var dD=rd(),dg=require("path").posix,j9=H9(),CD=Symbol("slurp"),Hn=Symbol("type"),Y9=class{constructor(e,r,i,n){this.cksumValid=!1,this.needPax=!1,this.nullBlock=!1,this.block=null,this.path=null,this.mode=null,this.uid=null,this.gid=null,this.size=null,this.mtime=null,this.cksum=null,this[Hn]="0",this.linkpath=null,this.uname=null,this.gname=null,this.devmaj=0,this.devmin=0,this.atime=null,this.ctime=null,Buffer.isBuffer(e)?this.decode(e,r||0,i,n):e&&this.set(e)}decode(e,r,i,n){if(r||(r=0),!e||!(e.length>=r+512))throw new Error("need 512 bytes for header");if(this.path=fc(e,r,100),this.mode=DA(e,r+100,8),this.uid=DA(e,r+108,8),this.gid=DA(e,r+116,8),this.size=DA(e,r+124,12),this.mtime=mD(e,r+136,12),this.cksum=DA(e,r+148,12),this[CD](i),this[CD](n,!0),this[Hn]=fc(e,r+156,1),this[Hn]===""&&(this[Hn]="0"),this[Hn]==="0"&&this.path.substr(-1)==="/"&&(this[Hn]="5"),this[Hn]==="5"&&(this.size=0),this.linkpath=fc(e,r+157,100),e.slice(r+257,r+265).toString()==="ustar\x0000")if(this.uname=fc(e,r+265,32),this.gname=fc(e,r+297,32),this.devmaj=DA(e,r+329,8),this.devmin=DA(e,r+337,8),e[r+475]!==0){let o=fc(e,r+345,155);this.path=o+"/"+this.path}else{let o=fc(e,r+345,130);o&&(this.path=o+"/"+this.path),this.atime=mD(e,r+476,12),this.ctime=mD(e,r+488,12)}let s=8*32;for(let o=r;o=r+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,n=sNe(this.path||"",i),s=n[0],o=n[1];this.needPax=n[2],this.needPax=hc(e,r,100,s)||this.needPax,this.needPax=RA(e,r+100,8,this.mode)||this.needPax,this.needPax=RA(e,r+108,8,this.uid)||this.needPax,this.needPax=RA(e,r+116,8,this.gid)||this.needPax,this.needPax=RA(e,r+124,12,this.size)||this.needPax,this.needPax=ED(e,r+136,12,this.mtime)||this.needPax,e[r+156]=this[Hn].charCodeAt(0),this.needPax=hc(e,r+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",r+257,8),this.needPax=hc(e,r+265,32,this.uname)||this.needPax,this.needPax=hc(e,r+297,32,this.gname)||this.needPax,this.needPax=RA(e,r+329,8,this.devmaj)||this.needPax,this.needPax=RA(e,r+337,8,this.devmin)||this.needPax,this.needPax=hc(e,r+345,i,o)||this.needPax,e[r+475]!==0?this.needPax=hc(e,r+345,155,o)||this.needPax:(this.needPax=hc(e,r+345,130,o)||this.needPax,this.needPax=ED(e,r+476,12,this.atime)||this.needPax,this.needPax=ED(e,r+488,12,this.ctime)||this.needPax);let a=8*32;for(let l=r;l{let r=100,i=t,n="",s,o=dg.parse(t).root||".";if(Buffer.byteLength(i)r&&Buffer.byteLength(n)<=e?s=[i.substr(0,r-1),n,!0]:(i=dg.join(dg.basename(n),i),n=dg.dirname(n));while(n!==o&&!s);s||(s=[t.substr(0,r-1),"",!0])}return s},fc=(t,e,r)=>t.slice(e,e+r).toString("utf8").replace(/\0.*/,""),mD=(t,e,r)=>oNe(DA(t,e,r)),oNe=t=>t===null?null:new Date(t*1e3),DA=(t,e,r)=>t[e]&128?j9.parse(t.slice(e,e+r)):aNe(t,e,r),ANe=t=>isNaN(t)?null:t,aNe=(t,e,r)=>ANe(parseInt(t.slice(e,e+r).toString("utf8").replace(/\0.*$/,"").trim(),8)),lNe={12:8589934591,8:2097151},RA=(t,e,r,i)=>i===null?!1:i>lNe[r]||i<0?(j9.encode(i,t.slice(e,e+r)),!0):(cNe(t,e,r,i),!1),cNe=(t,e,r,i)=>t.write(uNe(i,r),e,r,"ascii"),uNe=(t,e)=>gNe(Math.floor(t).toString(8),e),gNe=(t,e)=>(t.length===e-1?t:new Array(e-t.length-1).join("0")+t+" ")+"\0",ED=(t,e,r,i)=>i===null?!1:RA(t,e,r,i.getTime()/1e3),fNe=new Array(156).join("\0"),hc=(t,e,r,i)=>i===null?!1:(t.write(i+fNe,e,r,"utf8"),i.length!==Buffer.byteLength(i)||i.length>r);G9.exports=Y9});var zw=E((Ilt,q9)=>{"use strict";var hNe=Cg(),pNe=require("path"),Ww=class{constructor(e,r){this.atime=e.atime||null,this.charset=e.charset||null,this.comment=e.comment||null,this.ctime=e.ctime||null,this.gid=e.gid||null,this.gname=e.gname||null,this.linkpath=e.linkpath||null,this.mtime=e.mtime||null,this.path=e.path||null,this.size=e.size||null,this.uid=e.uid||null,this.uname=e.uname||null,this.dev=e.dev||null,this.ino=e.ino||null,this.nlink=e.nlink||null,this.global=r||!1}encode(){let e=this.encodeBody();if(e==="")return null;let r=Buffer.byteLength(e),i=512*Math.ceil(1+r/512),n=Buffer.allocUnsafe(i);for(let s=0;s<512;s++)n[s]=0;new hNe({path:("PaxHeader/"+pNe.basename(this.path)).slice(0,99),mode:this.mode||420,uid:this.uid||null,gid:this.gid||null,size:r,mtime:this.mtime||null,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime||null,ctime:this.ctime||null}).encode(n),n.write(e,512,r,"utf8");for(let s=r+512;s=Math.pow(10,s)&&(s+=1),s+n+i}};Ww.parse=(t,e,r)=>new Ww(dNe(CNe(t),e),r);var dNe=(t,e)=>e?Object.keys(t).reduce((r,i)=>(r[i]=t[i],r),e):t,CNe=t=>t.replace(/\n$/,"").split(` +`).reduce(mNe,Object.create(null)),mNe=(t,e)=>{let r=parseInt(e,10);if(r!==Buffer.byteLength(e)+1)return t;e=e.substr((r+" ").length);let i=e.split("="),n=i.shift().replace(/^SCHILY\.(dev|ino|nlink)/,"$1");if(!n)return t;let s=i.join("=");return t[n]=/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(n)?new Date(s*1e3):/^[0-9]+$/.test(s)?+s:s,t};q9.exports=Ww});var Vw=E((ylt,J9)=>{"use strict";J9.exports=t=>class extends t{warn(e,r,i={}){this.file&&(i.file=this.file),this.cwd&&(i.cwd=this.cwd),i.code=r instanceof Error&&r.code||e,i.tarCode=e,!this.strict&&i.recoverable!==!1?(r instanceof Error&&(i=Object.assign(r,i),r=r.message),this.emit("warn",i.tarCode,r,i)):r instanceof Error?this.emit("error",Object.assign(r,i)):this.emit("error",Object.assign(new Error(`${e}: ${r}`),i))}}});var yD=E((wlt,W9)=>{"use strict";var _w=["|","<",">","?",":"],ID=_w.map(t=>String.fromCharCode(61440+t.charCodeAt(0))),ENe=new Map(_w.map((t,e)=>[t,ID[e]])),INe=new Map(ID.map((t,e)=>[t,_w[e]]));W9.exports={encode:t=>_w.reduce((e,r)=>e.split(r).join(ENe.get(r)),t),decode:t=>ID.reduce((e,r)=>e.split(r).join(INe.get(r)),t)}});var V9=E((Blt,z9)=>{"use strict";z9.exports=(t,e,r)=>(t&=4095,r&&(t=(t|384)&~18),e&&(t&256&&(t|=64),t&32&&(t|=8),t&4&&(t|=1)),t)});var xD=E((xlt,_9)=>{"use strict";var X9=hg(),Z9=zw(),$9=Cg(),Qlt=id(),bo=require("fs"),mg=require("path"),blt=rd(),yNe=16*1024*1024,eV=Symbol("process"),tV=Symbol("file"),rV=Symbol("directory"),wD=Symbol("symlink"),iV=Symbol("hardlink"),nd=Symbol("header"),Xw=Symbol("read"),BD=Symbol("lstat"),Zw=Symbol("onlstat"),QD=Symbol("onread"),bD=Symbol("onreadlink"),vD=Symbol("openfile"),SD=Symbol("onopenfile"),pc=Symbol("close"),$w=Symbol("mode"),nV=Vw(),wNe=yD(),sV=V9(),eB=nV(class extends X9{constructor(e,r){if(r=r||{},super(r),typeof e!="string")throw new TypeError("path is required");this.path=e,this.portable=!!r.portable,this.myuid=process.getuid&&process.getuid(),this.myuser=process.env.USER||"",this.maxReadSize=r.maxReadSize||yNe,this.linkCache=r.linkCache||new Map,this.statCache=r.statCache||new Map,this.preservePaths=!!r.preservePaths,this.cwd=r.cwd||process.cwd(),this.strict=!!r.strict,this.noPax=!!r.noPax,this.noMtime=!!r.noMtime,this.mtime=r.mtime||null,typeof r.onwarn=="function"&&this.on("warn",r.onwarn);let i=!1;if(!this.preservePaths&&mg.win32.isAbsolute(e)){let n=mg.win32.parse(e);this.path=e.substr(n.root.length),i=n.root}this.win32=!!r.win32||process.platform==="win32",this.win32&&(this.path=wNe.decode(this.path.replace(/\\/g,"/")),e=e.replace(/\\/g,"/")),this.absolute=r.absolute||mg.resolve(this.cwd,e),this.path===""&&(this.path="./"),i&&this.warn("TAR_ENTRY_INFO",`stripping ${i} from absolute path`,{entry:this,path:i+this.path}),this.statCache.has(this.absolute)?this[Zw](this.statCache.get(this.absolute)):this[BD]()}[BD](){bo.lstat(this.absolute,(e,r)=>{if(e)return this.emit("error",e);this[Zw](r)})}[Zw](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=BNe(e),this.emit("stat",e),this[eV]()}[eV](){switch(this.type){case"File":return this[tV]();case"Directory":return this[rV]();case"SymbolicLink":return this[wD]();default:return this.end()}}[$w](e){return sV(e,this.type==="Directory",this.portable)}[nd](){this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.header=new $9({path:this.path,linkpath:this.linkpath,mode:this[$w](this.stat.mode),uid:this.portable?null:this.stat.uid,gid:this.portable?null:this.stat.gid,size:this.stat.size,mtime:this.noMtime?null:this.mtime||this.stat.mtime,type:this.type,uname:this.portable?null:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?null:this.stat.atime,ctime:this.portable?null:this.stat.ctime}),this.header.encode()&&!this.noPax&&this.write(new Z9({atime:this.portable?null:this.header.atime,ctime:this.portable?null:this.header.ctime,gid:this.portable?null:this.header.gid,mtime:this.noMtime?null:this.mtime||this.header.mtime,path:this.path,linkpath:this.linkpath,size:this.header.size,uid:this.portable?null:this.header.uid,uname:this.portable?null:this.header.uname,dev:this.portable?null:this.stat.dev,ino:this.portable?null:this.stat.ino,nlink:this.portable?null:this.stat.nlink}).encode()),this.write(this.header.block)}[rV](){this.path.substr(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[nd](),this.end()}[wD](){bo.readlink(this.absolute,(e,r)=>{if(e)return this.emit("error",e);this[bD](r)})}[bD](e){this.linkpath=e.replace(/\\/g,"/"),this[nd](),this.end()}[iV](e){this.type="Link",this.linkpath=mg.relative(this.cwd,e).replace(/\\/g,"/"),this.stat.size=0,this[nd](),this.end()}[tV](){if(this.stat.nlink>1){let e=this.stat.dev+":"+this.stat.ino;if(this.linkCache.has(e)){let r=this.linkCache.get(e);if(r.indexOf(this.cwd)===0)return this[iV](r)}this.linkCache.set(e,this.absolute)}if(this[nd](),this.stat.size===0)return this.end();this[vD]()}[vD](){bo.open(this.absolute,"r",(e,r)=>{if(e)return this.emit("error",e);this[SD](r)})}[SD](e){let r=512*Math.ceil(this.stat.size/512),i=Math.min(r,this.maxReadSize),n=Buffer.allocUnsafe(i);this[Xw](e,n,0,n.length,0,this.stat.size,r)}[Xw](e,r,i,n,s,o,a){bo.read(e,r,i,n,s,(l,c)=>{if(l)return this[pc](e,()=>this.emit("error",l));this[QD](e,r,i,n,s,o,a,c)})}[pc](e,r){bo.close(e,r)}[QD](e,r,i,n,s,o,a,l){if(l<=0&&o>0){let u=new Error("encountered unexpected EOF");return u.path=this.absolute,u.syscall="read",u.code="EOF",this[pc](e,()=>this.emit("error",u))}if(l>o){let u=new Error("did not encounter expected EOF");return u.path=this.absolute,u.syscall="read",u.code="EOF",this[pc](e,()=>this.emit("error",u))}if(l===o)for(let u=l;uu?this.emit("error",u):this.end());i>=n&&(r=Buffer.allocUnsafe(n),i=0),n=r.length-i,this[Xw](e,r,i,n,s,o,a)}}),oV=class extends eB{constructor(e,r){super(e,r)}[BD](){this[Zw](bo.lstatSync(this.absolute))}[wD](){this[bD](bo.readlinkSync(this.absolute))}[vD](){this[SD](bo.openSync(this.absolute,"r"))}[Xw](e,r,i,n,s,o,a){let l=!0;try{let c=bo.readSync(e,r,i,n,s);this[QD](e,r,i,n,s,o,a,c),l=!1}finally{if(l)try{this[pc](e,()=>{})}catch(c){}}}[pc](e,r){bo.closeSync(e),r()}},QNe=nV(class extends X9{constructor(e,r){r=r||{},super(r),this.preservePaths=!!r.preservePaths,this.portable=!!r.portable,this.strict=!!r.strict,this.noPax=!!r.noPax,this.noMtime=!!r.noMtime,this.readEntry=e,this.type=e.type,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.path=e.path,this.mode=this[$w](e.mode),this.uid=this.portable?null:e.uid,this.gid=this.portable?null:e.gid,this.uname=this.portable?null:e.uname,this.gname=this.portable?null:e.gname,this.size=e.size,this.mtime=this.noMtime?null:r.mtime||e.mtime,this.atime=this.portable?null:e.atime,this.ctime=this.portable?null:e.ctime,this.linkpath=e.linkpath,typeof r.onwarn=="function"&&this.on("warn",r.onwarn);let i=!1;if(mg.isAbsolute(this.path)&&!this.preservePaths){let n=mg.parse(this.path);i=n.root,this.path=this.path.substr(n.root.length)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.header=new $9({path:this.path,linkpath:this.linkpath,mode:this.mode,uid:this.portable?null:this.uid,gid:this.portable?null:this.gid,size:this.size,mtime:this.noMtime?null:this.mtime,type:this.type,uname:this.portable?null:this.uname,atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime}),i&&this.warn("TAR_ENTRY_INFO",`stripping ${i} from absolute path`,{entry:this,path:i+this.path}),this.header.encode()&&!this.noPax&&super.write(new Z9({atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime,gid:this.portable?null:this.gid,mtime:this.noMtime?null:this.mtime,path:this.path,linkpath:this.linkpath,size:this.size,uid:this.portable?null:this.uid,uname:this.portable?null:this.uname,dev:this.portable?null:this.readEntry.dev,ino:this.portable?null:this.readEntry.ino,nlink:this.portable?null:this.readEntry.nlink}).encode()),super.write(this.header.block),e.pipe(this)}[$w](e){return sV(e,this.type==="Directory",this.portable)}write(e){let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(e)}end(){return this.blockRemain&&this.write(Buffer.alloc(this.blockRemain)),super.end()}});eB.Sync=oV;eB.Tar=QNe;var BNe=t=>t.isFile()?"File":t.isDirectory()?"Directory":t.isSymbolicLink()?"SymbolicLink":"Unsupported";_9.exports=eB});var AB=E((Plt,aV)=>{"use strict";var kD=class{constructor(e,r){this.path=e||"./",this.absolute=r,this.entry=null,this.stat=null,this.readdir=null,this.pending=!1,this.ignore=!1,this.piped=!1}},bNe=hg(),vNe=fD(),SNe=id(),PD=xD(),xNe=PD.Sync,kNe=PD.Tar,PNe=Rh(),AV=Buffer.alloc(1024),tB=Symbol("onStat"),rB=Symbol("ended"),vo=Symbol("queue"),Eg=Symbol("current"),dc=Symbol("process"),iB=Symbol("processing"),lV=Symbol("processJob"),So=Symbol("jobs"),DD=Symbol("jobDone"),nB=Symbol("addFSEntry"),cV=Symbol("addTarEntry"),RD=Symbol("stat"),FD=Symbol("readdir"),sB=Symbol("onreaddir"),oB=Symbol("pipe"),uV=Symbol("entry"),ND=Symbol("entryOpt"),LD=Symbol("writeEntryClass"),gV=Symbol("write"),TD=Symbol("ondrain"),aB=require("fs"),fV=require("path"),DNe=Vw(),MD=DNe(class extends bNe{constructor(e){super(e);e=e||Object.create(null),this.opt=e,this.file=e.file||"",this.cwd=e.cwd||process.cwd(),this.maxReadSize=e.maxReadSize,this.preservePaths=!!e.preservePaths,this.strict=!!e.strict,this.noPax=!!e.noPax,this.prefix=(e.prefix||"").replace(/(\\|\/)+$/,""),this.linkCache=e.linkCache||new Map,this.statCache=e.statCache||new Map,this.readdirCache=e.readdirCache||new Map,this[LD]=PD,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),this.portable=!!e.portable,this.zip=null,e.gzip?(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new vNe.Gzip(e.gzip),this.zip.on("data",r=>super.write(r)),this.zip.on("end",r=>super.end()),this.zip.on("drain",r=>this[TD]()),this.on("resume",r=>this.zip.resume())):this.on("drain",this[TD]),this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,this.mtime=e.mtime||null,this.filter=typeof e.filter=="function"?e.filter:r=>!0,this[vo]=new PNe,this[So]=0,this.jobs=+e.jobs||4,this[iB]=!1,this[rB]=!1}[gV](e){return super.write(e)}add(e){return this.write(e),this}end(e){return e&&this.write(e),this[rB]=!0,this[dc](),this}write(e){if(this[rB])throw new Error("write after end");return e instanceof SNe?this[cV](e):this[nB](e),this.flowing}[cV](e){let r=fV.resolve(this.cwd,e.path);if(this.prefix&&(e.path=this.prefix+"/"+e.path.replace(/^\.(\/+|$)/,"")),!this.filter(e.path,e))e.resume();else{let i=new kD(e.path,r,!1);i.entry=new kNe(e,this[ND](i)),i.entry.on("end",n=>this[DD](i)),this[So]+=1,this[vo].push(i)}this[dc]()}[nB](e){let r=fV.resolve(this.cwd,e);this.prefix&&(e=this.prefix+"/"+e.replace(/^\.(\/+|$)/,"")),this[vo].push(new kD(e,r)),this[dc]()}[RD](e){e.pending=!0,this[So]+=1;let r=this.follow?"stat":"lstat";aB[r](e.absolute,(i,n)=>{e.pending=!1,this[So]-=1,i?this.emit("error",i):this[tB](e,n)})}[tB](e,r){this.statCache.set(e.absolute,r),e.stat=r,this.filter(e.path,r)||(e.ignore=!0),this[dc]()}[FD](e){e.pending=!0,this[So]+=1,aB.readdir(e.absolute,(r,i)=>{if(e.pending=!1,this[So]-=1,r)return this.emit("error",r);this[sB](e,i)})}[sB](e,r){this.readdirCache.set(e.absolute,r),e.readdir=r,this[dc]()}[dc](){if(!this[iB]){this[iB]=!0;for(let e=this[vo].head;e!==null&&this[So]this.warn(r,i,n),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime}}[uV](e){this[So]+=1;try{return new this[LD](e.path,this[ND](e)).on("end",()=>this[DD](e)).on("error",r=>this.emit("error",r))}catch(r){this.emit("error",r)}}[TD](){this[Eg]&&this[Eg].entry&&this[Eg].entry.resume()}[oB](e){e.piped=!0,e.readdir&&e.readdir.forEach(n=>{let s=this.prefix?e.path.slice(this.prefix.length+1)||"./":e.path,o=s==="./"?"":s.replace(/\/*$/,"/");this[nB](o+n)});let r=e.entry,i=this.zip;i?r.on("data",n=>{i.write(n)||r.pause()}):r.on("data",n=>{super.write(n)||r.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}}),hV=class extends MD{constructor(e){super(e);this[LD]=xNe}pause(){}resume(){}[RD](e){let r=this.follow?"statSync":"lstatSync";this[tB](e,aB[r](e.absolute))}[FD](e,r){this[sB](e,aB.readdirSync(e.absolute))}[oB](e){let r=e.entry,i=this.zip;e.readdir&&e.readdir.forEach(n=>{let s=this.prefix?e.path.slice(this.prefix.length+1)||"./":e.path,o=s==="./"?"":s.replace(/\/*$/,"/");this[nB](o+n)}),i?r.on("data",n=>{i.write(n)}):r.on("data",n=>{super[gV](n)})}};MD.Sync=hV;aV.exports=MD});var bg=E(sd=>{"use strict";var RNe=hg(),FNe=require("events").EventEmitter,ls=require("fs"),lB=process.binding("fs"),Dlt=lB.writeBuffers,NNe=lB.FSReqWrap||lB.FSReqCallback,Ig=Symbol("_autoClose"),xo=Symbol("_close"),od=Symbol("_ended"),Jt=Symbol("_fd"),pV=Symbol("_finished"),Cc=Symbol("_flags"),OD=Symbol("_flush"),KD=Symbol("_handleChunk"),UD=Symbol("_makeBuf"),HD=Symbol("_mode"),cB=Symbol("_needDrain"),yg=Symbol("_onerror"),wg=Symbol("_onopen"),GD=Symbol("_onread"),mc=Symbol("_onwrite"),FA=Symbol("_open"),NA=Symbol("_path"),Ec=Symbol("_pos"),ko=Symbol("_queue"),Bg=Symbol("_read"),dV=Symbol("_readSize"),LA=Symbol("_reading"),uB=Symbol("_remain"),CV=Symbol("_size"),gB=Symbol("_write"),Qg=Symbol("_writing"),fB=Symbol("_defaultFlag"),jD=class extends RNe{constructor(e,r){if(r=r||{},super(r),this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[Jt]=typeof r.fd=="number"?r.fd:null,this[NA]=e,this[dV]=r.readSize||16*1024*1024,this[LA]=!1,this[CV]=typeof r.size=="number"?r.size:Infinity,this[uB]=this[CV],this[Ig]=typeof r.autoClose=="boolean"?r.autoClose:!0,typeof this[Jt]=="number"?this[Bg]():this[FA]()}get fd(){return this[Jt]}get path(){return this[NA]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[FA](){ls.open(this[NA],"r",(e,r)=>this[wg](e,r))}[wg](e,r){e?this[yg](e):(this[Jt]=r,this.emit("open",r),this[Bg]())}[UD](){return Buffer.allocUnsafe(Math.min(this[dV],this[uB]))}[Bg](){if(!this[LA]){this[LA]=!0;let e=this[UD]();if(e.length===0)return process.nextTick(()=>this[GD](null,0,e));ls.read(this[Jt],e,0,e.length,null,(r,i,n)=>this[GD](r,i,n))}}[GD](e,r,i){this[LA]=!1,e?this[yg](e):this[KD](r,i)&&this[Bg]()}[xo](){this[Ig]&&typeof this[Jt]=="number"&&(ls.close(this[Jt],e=>this.emit("close")),this[Jt]=null)}[yg](e){this[LA]=!0,this[xo](),this.emit("error",e)}[KD](e,r){let i=!1;return this[uB]-=e,e>0&&(i=super.write(ethis[wg](e,r))}[wg](e,r){this[fB]&&this[Cc]==="r+"&&e&&e.code==="ENOENT"?(this[Cc]="w",this[FA]()):e?this[yg](e):(this[Jt]=r,this.emit("open",r),this[OD]())}end(e,r){e&&this.write(e,r),this[od]=!0,!this[Qg]&&!this[ko].length&&typeof this[Jt]=="number"&&this[mc](null,0)}write(e,r){return typeof e=="string"&&(e=new Buffer(e,r)),this[od]?(this.emit("error",new Error("write() after end()")),!1):this[Jt]===null||this[Qg]||this[ko].length?(this[ko].push(e),this[cB]=!0,!1):(this[Qg]=!0,this[gB](e),!0)}[gB](e){ls.write(this[Jt],e,0,e.length,this[Ec],(r,i)=>this[mc](r,i))}[mc](e,r){e?this[yg](e):(this[Ec]!==null&&(this[Ec]+=r),this[ko].length?this[OD]():(this[Qg]=!1,this[od]&&!this[pV]?(this[pV]=!0,this[xo](),this.emit("finish")):this[cB]&&(this[cB]=!1,this.emit("drain"))))}[OD](){if(this[ko].length===0)this[od]&&this[mc](null,0);else if(this[ko].length===1)this[gB](this[ko].pop());else{let e=this[ko];this[ko]=[],LNe(this[Jt],e,this[Ec],(r,i)=>this[mc](r,i))}}[xo](){this[Ig]&&typeof this[Jt]=="number"&&(ls.close(this[Jt],e=>this.emit("close")),this[Jt]=null)}},EV=class extends YD{[FA](){let e;try{e=ls.openSync(this[NA],this[Cc],this[HD])}catch(r){if(this[fB]&&this[Cc]==="r+"&&r&&r.code==="ENOENT")return this[Cc]="w",this[FA]();throw r}this[wg](null,e)}[xo](){if(this[Ig]&&typeof this[Jt]=="number"){try{ls.closeSync(this[Jt])}catch(e){}this[Jt]=null,this.emit("close")}}[gB](e){try{this[mc](null,ls.writeSync(this[Jt],e,0,e.length,this[Ec]))}catch(r){this[mc](r,0)}}},LNe=(t,e,r,i)=>{let n=(o,a)=>i(o,a,e),s=new NNe;s.oncomplete=n,lB.writeBuffers(t,e,r,s)};sd.ReadStream=jD;sd.ReadStreamSync=mV;sd.WriteStream=YD;sd.WriteStreamSync=EV});var ld=E((Llt,IV)=>{"use strict";var TNe=Vw(),Flt=require("path"),MNe=Cg(),ONe=require("events"),KNe=Rh(),UNe=1024*1024,HNe=id(),yV=zw(),GNe=fD(),qD=Buffer.from([31,139]),cs=Symbol("state"),Ic=Symbol("writeEntry"),xa=Symbol("readEntry"),JD=Symbol("nextEntry"),wV=Symbol("processEntry"),us=Symbol("extendedHeader"),ad=Symbol("globalExtendedHeader"),TA=Symbol("meta"),BV=Symbol("emitMeta"),Ar=Symbol("buffer"),ka=Symbol("queue"),yc=Symbol("ended"),QV=Symbol("emittedEnd"),wc=Symbol("emit"),Qn=Symbol("unzip"),hB=Symbol("consumeChunk"),pB=Symbol("consumeChunkSub"),WD=Symbol("consumeBody"),bV=Symbol("consumeMeta"),vV=Symbol("consumeHeader"),dB=Symbol("consuming"),zD=Symbol("bufferConcat"),VD=Symbol("maybeEnd"),Ad=Symbol("writing"),MA=Symbol("aborted"),CB=Symbol("onDone"),Bc=Symbol("sawValidEntry"),mB=Symbol("sawNullBlock"),EB=Symbol("sawEOF"),jNe=t=>!0;IV.exports=TNe(class extends ONe{constructor(e){e=e||{},super(e),this.file=e.file||"",this[Bc]=null,this.on(CB,r=>{(this[cs]==="begin"||this[Bc]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(CB,e.ondone):this.on(CB,r=>{this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close")}),this.strict=!!e.strict,this.maxMetaEntrySize=e.maxMetaEntrySize||UNe,this.filter=typeof e.filter=="function"?e.filter:jNe,this.writable=!0,this.readable=!1,this[ka]=new KNe,this[Ar]=null,this[xa]=null,this[Ic]=null,this[cs]="begin",this[TA]="",this[us]=null,this[ad]=null,this[yc]=!1,this[Qn]=null,this[MA]=!1,this[mB]=!1,this[EB]=!1,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onentry=="function"&&this.on("entry",e.onentry)}[vV](e,r){this[Bc]===null&&(this[Bc]=!1);let i;try{i=new MNe(e,r,this[us],this[ad])}catch(n){return this.warn("TAR_ENTRY_INVALID",n)}if(i.nullBlock)this[mB]?(this[EB]=!0,this[cs]==="begin"&&(this[cs]="header"),this[wc]("eof")):(this[mB]=!0,this[wc]("nullBlock"));else if(this[mB]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let n=i.type;if(/^(Symbolic)?Link$/.test(n)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(n)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let s=this[Ic]=new HNe(i,this[us],this[ad]);if(!this[Bc])if(s.remain){let o=()=>{s.invalid||(this[Bc]=!0)};s.on("end",o)}else this[Bc]=!0;s.meta?s.size>this.maxMetaEntrySize?(s.ignore=!0,this[wc]("ignoredEntry",s),this[cs]="ignore",s.resume()):s.size>0&&(this[TA]="",s.on("data",o=>this[TA]+=o),this[cs]="meta"):(this[us]=null,s.ignore=s.ignore||!this.filter(s.path,s),s.ignore?(this[wc]("ignoredEntry",s),this[cs]=s.remain?"ignore":"header",s.resume()):(s.remain?this[cs]="body":(this[cs]="header",s.end()),this[xa]?this[ka].push(s):(this[ka].push(s),this[JD]())))}}}[wV](e){let r=!0;return e?Array.isArray(e)?this.emit.apply(this,e):(this[xa]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",i=>this[JD]()),r=!1)):(this[xa]=null,r=!1),r}[JD](){do;while(this[wV](this[ka].shift()));if(!this[ka].length){let e=this[xa];!e||e.flowing||e.size===e.remain?this[Ad]||this.emit("drain"):e.once("drain",i=>this.emit("drain"))}}[WD](e,r){let i=this[Ic],n=i.blockRemain,s=n>=e.length&&r===0?e:e.slice(r,r+n);return i.write(s),i.blockRemain||(this[cs]="header",this[Ic]=null,i.end()),s.length}[bV](e,r){let i=this[Ic],n=this[WD](e,r);return this[Ic]||this[BV](i),n}[wc](e,r,i){!this[ka].length&&!this[xa]?this.emit(e,r,i):this[ka].push([e,r,i])}[BV](e){switch(this[wc]("meta",this[TA]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[us]=yV.parse(this[TA],this[us],!1);break;case"GlobalExtendedHeader":this[ad]=yV.parse(this[TA],this[ad],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":this[us]=this[us]||Object.create(null),this[us].path=this[TA].replace(/\0.*/,"");break;case"NextFileHasLongLinkpath":this[us]=this[us]||Object.create(null),this[us].linkpath=this[TA].replace(/\0.*/,"");break;default:throw new Error("unknown meta: "+e.type)}}abort(e){this[MA]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1})}write(e){if(this[MA])return;if(this[Qn]===null&&e){if(this[Ar]&&(e=Buffer.concat([this[Ar],e]),this[Ar]=null),e.lengththis[hB](s)),this[Qn].on("error",s=>this.abort(s)),this[Qn].on("end",s=>{this[yc]=!0,this[hB]()}),this[Ad]=!0;let n=this[Qn][i?"end":"write"](e);return this[Ad]=!1,n}}this[Ad]=!0,this[Qn]?this[Qn].write(e):this[hB](e),this[Ad]=!1;let r=this[ka].length?!1:this[xa]?this[xa].flowing:!0;return!r&&!this[ka].length&&this[xa].once("drain",i=>this.emit("drain")),r}[zD](e){e&&!this[MA]&&(this[Ar]=this[Ar]?Buffer.concat([this[Ar],e]):e)}[VD](){if(this[yc]&&!this[QV]&&!this[MA]&&!this[dB]){this[QV]=!0;let e=this[Ic];if(e&&e.blockRemain){let r=this[Ar]?this[Ar].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${r} available)`,{entry:e}),this[Ar]&&e.write(this[Ar]),e.end()}this[wc](CB)}}[hB](e){if(this[dB])this[zD](e);else if(!e&&!this[Ar])this[VD]();else{if(this[dB]=!0,this[Ar]){this[zD](e);let r=this[Ar];this[Ar]=null,this[pB](r)}else this[pB](e);for(;this[Ar]&&this[Ar].length>=512&&!this[MA]&&!this[EB];){let r=this[Ar];this[Ar]=null,this[pB](r)}this[dB]=!1}(!this[Ar]||this[yc])&&this[VD]()}[pB](e){let r=0,i=e.length;for(;r+512<=i&&!this[MA]&&!this[EB];)switch(this[cs]){case"begin":case"header":this[vV](e,r),r+=512;break;case"ignore":case"body":r+=this[WD](e,r);break;case"meta":r+=this[bV](e,r);break;default:throw new Error("invalid state: "+this[cs])}r{"use strict";var YNe=fg(),xV=ld(),vg=require("fs"),qNe=bg(),kV=require("path"),Tlt=SV.exports=(t,e,r)=>{typeof t=="function"?(r=t,e=null,t={}):Array.isArray(t)&&(e=t,t={}),typeof e=="function"&&(r=e,e=null),e?e=Array.from(e):e=[];let i=YNe(t);if(i.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return e.length&&WNe(i,e),i.noResume||JNe(i),i.file&&i.sync?zNe(i):i.file?VNe(i,r):PV(i)},JNe=t=>{let e=t.onentry;t.onentry=e?r=>{e(r),r.resume()}:r=>r.resume()},WNe=(t,e)=>{let r=new Map(e.map(s=>[s.replace(/\/+$/,""),!0])),i=t.filter,n=(s,o)=>{let a=o||kV.parse(s).root||".",l=s===a?!1:r.has(s)?r.get(s):n(kV.dirname(s),a);return r.set(s,l),l};t.filter=i?(s,o)=>i(s,o)&&n(s.replace(/\/+$/,"")):s=>n(s.replace(/\/+$/,""))},zNe=t=>{let e=PV(t),r=t.file,i=!0,n;try{let s=vg.statSync(r),o=t.maxReadSize||16*1024*1024;if(s.size{let r=new xV(t),i=t.maxReadSize||16*1024*1024,n=t.file,s=new Promise((o,a)=>{r.on("error",a),r.on("end",o),vg.stat(n,(l,c)=>{if(l)a(l);else{let u=new qNe.ReadStream(n,{readSize:i,size:c.size});u.on("error",a),u.pipe(r)}})});return e?s.then(e,e):s},PV=t=>new xV(t)});var TV=E((Ult,DV)=>{"use strict";var _Ne=fg(),yB=AB(),Olt=require("fs"),RV=bg(),FV=IB(),NV=require("path"),Klt=DV.exports=(t,e,r)=>{if(typeof e=="function"&&(r=e),Array.isArray(t)&&(e=t,t={}),!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");e=Array.from(e);let i=_Ne(t);if(i.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return i.file&&i.sync?XNe(i,e):i.file?ZNe(i,e,r):i.sync?$Ne(i,e):eLe(i,e)},XNe=(t,e)=>{let r=new yB.Sync(t),i=new RV.WriteStreamSync(t.file,{mode:t.mode||438});r.pipe(i),LV(r,e)},ZNe=(t,e,r)=>{let i=new yB(t),n=new RV.WriteStream(t.file,{mode:t.mode||438});i.pipe(n);let s=new Promise((o,a)=>{n.on("error",a),n.on("close",o),i.on("error",a)});return _D(i,e),r?s.then(r,r):s},LV=(t,e)=>{e.forEach(r=>{r.charAt(0)==="@"?FV({file:NV.resolve(t.cwd,r.substr(1)),sync:!0,noResume:!0,onentry:i=>t.add(i)}):t.add(r)}),t.end()},_D=(t,e)=>{for(;e.length;){let r=e.shift();if(r.charAt(0)==="@")return FV({file:NV.resolve(t.cwd,r.substr(1)),noResume:!0,onentry:i=>t.add(i)}).then(i=>_D(t,e));t.add(r)}t.end()},$Ne=(t,e)=>{let r=new yB.Sync(t);return LV(r,e),r},eLe=(t,e)=>{let r=new yB(t);return _D(r,e),r}});var XD=E((jlt,MV)=>{"use strict";var tLe=fg(),OV=AB(),Hlt=ld(),gs=require("fs"),KV=bg(),UV=IB(),HV=require("path"),GV=Cg(),Glt=MV.exports=(t,e,r)=>{let i=tLe(t);if(!i.file)throw new TypeError("file is required");if(i.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),i.sync?rLe(i,e):iLe(i,e,r)},rLe=(t,e)=>{let r=new OV.Sync(t),i=!0,n,s;try{try{n=gs.openSync(t.file,"r+")}catch(l){if(l.code==="ENOENT")n=gs.openSync(t.file,"w+");else throw l}let o=gs.fstatSync(n),a=Buffer.alloc(512);e:for(s=0;so.size)break;s+=c,t.mtimeCache&&t.mtimeCache.set(l.path,l.mtime)}i=!1,nLe(t,r,s,n,e)}finally{if(i)try{gs.closeSync(n)}catch(o){}}},nLe=(t,e,r,i,n)=>{let s=new KV.WriteStreamSync(t.file,{fd:i,start:r});e.pipe(s),sLe(e,n)},iLe=(t,e,r)=>{e=Array.from(e);let i=new OV(t),n=(o,a,l)=>{let c=(p,d)=>{p?gs.close(o,m=>l(p)):l(null,d)},u=0;if(a===0)return c(null,0);let g=0,f=Buffer.alloc(512),h=(p,d)=>{if(p)return c(p);if(g+=d,g<512&&d)return gs.read(o,f,g,f.length-g,u+g,h);if(u===0&&f[0]===31&&f[1]===139)return c(new Error("cannot append to compressed archives"));if(g<512)return c(null,u);let m=new GV(f);if(!m.cksumValid)return c(null,u);let I=512*Math.ceil(m.size/512);if(u+I+512>a||(u+=I+512,u>=a))return c(null,u);t.mtimeCache&&t.mtimeCache.set(m.path,m.mtime),g=0,gs.read(o,f,0,512,u,h)};gs.read(o,f,0,512,u,h)},s=new Promise((o,a)=>{i.on("error",a);let l="r+",c=(u,g)=>{if(u&&u.code==="ENOENT"&&l==="r+")return l="w+",gs.open(t.file,l,c);if(u)return a(u);gs.fstat(g,(f,h)=>{if(f)return a(f);n(g,h.size,(p,d)=>{if(p)return a(p);let m=new KV.WriteStream(t.file,{fd:g,start:d});i.pipe(m),m.on("error",a),m.on("close",o),jV(i,e)})})};gs.open(t.file,l,c)});return r?s.then(r,r):s},sLe=(t,e)=>{e.forEach(r=>{r.charAt(0)==="@"?UV({file:HV.resolve(t.cwd,r.substr(1)),sync:!0,noResume:!0,onentry:i=>t.add(i)}):t.add(r)}),t.end()},jV=(t,e)=>{for(;e.length;){let r=e.shift();if(r.charAt(0)==="@")return UV({file:HV.resolve(t.cwd,r.substr(1)),noResume:!0,onentry:i=>t.add(i)}).then(i=>jV(t,e));t.add(r)}t.end()}});var qV=E((qlt,YV)=>{"use strict";var oLe=fg(),aLe=XD(),Ylt=YV.exports=(t,e,r)=>{let i=oLe(t);if(!i.file)throw new TypeError("file is required");if(i.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),ALe(i),aLe(i,e,r)},ALe=t=>{let e=t.filter;t.mtimeCache||(t.mtimeCache=new Map),t.filter=e?(r,i)=>e(r,i)&&!(t.mtimeCache.get(r)>i.mtime):(r,i)=>!(t.mtimeCache.get(r)>i.mtime)}});var zV=E((Jlt,JV)=>{var{promisify:WV}=require("util"),OA=require("fs"),lLe=t=>{if(!t)t={mode:511,fs:OA};else if(typeof t=="object")t=P({mode:511,fs:OA},t);else if(typeof t=="number")t={mode:t,fs:OA};else if(typeof t=="string")t={mode:parseInt(t,8),fs:OA};else throw new TypeError("invalid options argument");return t.mkdir=t.mkdir||t.fs.mkdir||OA.mkdir,t.mkdirAsync=WV(t.mkdir),t.stat=t.stat||t.fs.stat||OA.stat,t.statAsync=WV(t.stat),t.statSync=t.statSync||t.fs.statSync||OA.statSync,t.mkdirSync=t.mkdirSync||t.fs.mkdirSync||OA.mkdirSync,t};JV.exports=lLe});var _V=E((Wlt,VV)=>{var cLe=process.env.__TESTING_MKDIRP_PLATFORM__||process.platform,{resolve:uLe,parse:gLe}=require("path"),fLe=t=>{if(/\0/.test(t))throw Object.assign(new TypeError("path must be a string without null bytes"),{path:t,code:"ERR_INVALID_ARG_VALUE"});if(t=uLe(t),cLe==="win32"){let e=/[*|"<>?:]/,{root:r}=gLe(t);if(e.test(t.substr(r.length)))throw Object.assign(new Error("Illegal characters in path."),{path:t,code:"EINVAL"})}return t};VV.exports=fLe});var t7=E((zlt,XV)=>{var{dirname:ZV}=require("path"),$V=(t,e,r=void 0)=>r===e?Promise.resolve():t.statAsync(e).then(i=>i.isDirectory()?r:void 0,i=>i.code==="ENOENT"?$V(t,ZV(e),e):void 0),e7=(t,e,r=void 0)=>{if(r!==e)try{return t.statSync(e).isDirectory()?r:void 0}catch(i){return i.code==="ENOENT"?e7(t,ZV(e),e):void 0}};XV.exports={findMade:$V,findMadeSync:e7}});var eR=E((Vlt,r7)=>{var{dirname:i7}=require("path"),ZD=(t,e,r)=>{e.recursive=!1;let i=i7(t);return i===t?e.mkdirAsync(t,e).catch(n=>{if(n.code!=="EISDIR")throw n}):e.mkdirAsync(t,e).then(()=>r||t,n=>{if(n.code==="ENOENT")return ZD(i,e).then(s=>ZD(t,e,s));if(n.code!=="EEXIST"&&n.code!=="EROFS")throw n;return e.statAsync(t).then(s=>{if(s.isDirectory())return r;throw n},()=>{throw n})})},$D=(t,e,r)=>{let i=i7(t);if(e.recursive=!1,i===t)try{return e.mkdirSync(t,e)}catch(n){if(n.code!=="EISDIR")throw n;return}try{return e.mkdirSync(t,e),r||t}catch(n){if(n.code==="ENOENT")return $D(t,e,$D(i,e,r));if(n.code!=="EEXIST"&&n.code!=="EROFS")throw n;try{if(!e.statSync(t).isDirectory())throw n}catch(s){throw n}}};r7.exports={mkdirpManual:ZD,mkdirpManualSync:$D}});var o7=E((_lt,n7)=>{var{dirname:s7}=require("path"),{findMade:hLe,findMadeSync:pLe}=t7(),{mkdirpManual:dLe,mkdirpManualSync:CLe}=eR(),mLe=(t,e)=>(e.recursive=!0,s7(t)===t?e.mkdirAsync(t,e):hLe(e,t).then(i=>e.mkdirAsync(t,e).then(()=>i).catch(n=>{if(n.code==="ENOENT")return dLe(t,e);throw n}))),ELe=(t,e)=>{if(e.recursive=!0,s7(t)===t)return e.mkdirSync(t,e);let i=pLe(e,t);try{return e.mkdirSync(t,e),i}catch(n){if(n.code==="ENOENT")return CLe(t,e);throw n}};n7.exports={mkdirpNative:mLe,mkdirpNativeSync:ELe}});var c7=E((Xlt,a7)=>{var A7=require("fs"),ILe=process.env.__TESTING_MKDIRP_NODE_VERSION__||process.version,tR=ILe.replace(/^v/,"").split("."),l7=+tR[0]>10||+tR[0]==10&&+tR[1]>=12,yLe=l7?t=>t.mkdir===A7.mkdir:()=>!1,wLe=l7?t=>t.mkdirSync===A7.mkdirSync:()=>!1;a7.exports={useNative:yLe,useNativeSync:wLe}});var d7=E((Zlt,u7)=>{var Sg=zV(),xg=_V(),{mkdirpNative:g7,mkdirpNativeSync:f7}=o7(),{mkdirpManual:h7,mkdirpManualSync:p7}=eR(),{useNative:BLe,useNativeSync:QLe}=c7(),kg=(t,e)=>(t=xg(t),e=Sg(e),BLe(e)?g7(t,e):h7(t,e)),bLe=(t,e)=>(t=xg(t),e=Sg(e),QLe(e)?f7(t,e):p7(t,e));kg.sync=bLe;kg.native=(t,e)=>g7(xg(t),Sg(e));kg.manual=(t,e)=>h7(xg(t),Sg(e));kg.nativeSync=(t,e)=>f7(xg(t),Sg(e));kg.manualSync=(t,e)=>p7(xg(t),Sg(e));u7.exports=kg});var B7=E(($lt,C7)=>{"use strict";var fs=require("fs"),Qc=require("path"),vLe=fs.lchown?"lchown":"chown",SLe=fs.lchownSync?"lchownSync":"chownSync",m7=fs.lchown&&!process.version.match(/v1[1-9]+\./)&&!process.version.match(/v10\.[6-9]/),E7=(t,e,r)=>{try{return fs[SLe](t,e,r)}catch(i){if(i.code!=="ENOENT")throw i}},xLe=(t,e,r)=>{try{return fs.chownSync(t,e,r)}catch(i){if(i.code!=="ENOENT")throw i}},kLe=m7?(t,e,r,i)=>n=>{!n||n.code!=="EISDIR"?i(n):fs.chown(t,e,r,i)}:(t,e,r,i)=>i,rR=m7?(t,e,r)=>{try{return E7(t,e,r)}catch(i){if(i.code!=="EISDIR")throw i;xLe(t,e,r)}}:(t,e,r)=>E7(t,e,r),PLe=process.version,I7=(t,e,r)=>fs.readdir(t,e,r),DLe=(t,e)=>fs.readdirSync(t,e);/^v4\./.test(PLe)&&(I7=(t,e,r)=>fs.readdir(t,r));var wB=(t,e,r,i)=>{fs[vLe](t,e,r,kLe(t,e,r,n=>{i(n&&n.code!=="ENOENT"?n:null)}))},y7=(t,e,r,i,n)=>{if(typeof e=="string")return fs.lstat(Qc.resolve(t,e),(s,o)=>{if(s)return n(s.code!=="ENOENT"?s:null);o.name=e,y7(t,o,r,i,n)});if(e.isDirectory())iR(Qc.resolve(t,e.name),r,i,s=>{if(s)return n(s);let o=Qc.resolve(t,e.name);wB(o,r,i,n)});else{let s=Qc.resolve(t,e.name);wB(s,r,i,n)}},iR=(t,e,r,i)=>{I7(t,{withFileTypes:!0},(n,s)=>{if(n){if(n.code==="ENOENT")return i();if(n.code!=="ENOTDIR"&&n.code!=="ENOTSUP")return i(n)}if(n||!s.length)return wB(t,e,r,i);let o=s.length,a=null,l=c=>{if(!a){if(c)return i(a=c);if(--o==0)return wB(t,e,r,i)}};s.forEach(c=>y7(t,c,e,r,l))})},RLe=(t,e,r,i)=>{if(typeof e=="string")try{let n=fs.lstatSync(Qc.resolve(t,e));n.name=e,e=n}catch(n){if(n.code==="ENOENT")return;throw n}e.isDirectory()&&w7(Qc.resolve(t,e.name),r,i),rR(Qc.resolve(t,e.name),r,i)},w7=(t,e,r)=>{let i;try{i=DLe(t,{withFileTypes:!0})}catch(n){if(n.code==="ENOENT")return;if(n.code==="ENOTDIR"||n.code==="ENOTSUP")return rR(t,e,r);throw n}return i&&i.length&&i.forEach(n=>RLe(t,n,e,r)),rR(t,e,r)};C7.exports=iR;iR.sync=w7});var S7=E((rct,nR)=>{"use strict";var Q7=d7(),hs=require("fs"),BB=require("path"),b7=B7(),sR=class extends Error{constructor(e,r){super("Cannot extract through symbolic link");this.path=r,this.symlink=e}get name(){return"SylinkError"}},cd=class extends Error{constructor(e,r){super(r+": Cannot cd into '"+e+"'");this.path=e,this.code=r}get name(){return"CwdError"}},ect=nR.exports=(t,e,r)=>{let i=e.umask,n=e.mode|448,s=(n&i)!=0,o=e.uid,a=e.gid,l=typeof o=="number"&&typeof a=="number"&&(o!==e.processUid||a!==e.processGid),c=e.preserve,u=e.unlink,g=e.cache,f=e.cwd,h=(m,I)=>{m?r(m):(g.set(t,!0),I&&l?b7(I,o,a,B=>h(B)):s?hs.chmod(t,n,r):r())};if(g&&g.get(t)===!0)return h();if(t===f)return hs.stat(t,(m,I)=>{(m||!I.isDirectory())&&(m=new cd(t,m&&m.code||"ENOTDIR")),h(m)});if(c)return Q7(t,{mode:n}).then(m=>h(null,m),h);let d=BB.relative(f,t).split(/\/|\\/);QB(f,d,n,g,u,f,null,h)},QB=(t,e,r,i,n,s,o,a)=>{if(!e.length)return a(null,o);let l=e.shift(),c=t+"/"+l;if(i.get(c))return QB(c,e,r,i,n,s,o,a);hs.mkdir(c,r,v7(c,e,r,i,n,s,o,a))},v7=(t,e,r,i,n,s,o,a)=>l=>{if(l){if(l.path&&BB.dirname(l.path)===s&&(l.code==="ENOTDIR"||l.code==="ENOENT"))return a(new cd(s,l.code));hs.lstat(t,(c,u)=>{if(c)a(c);else if(u.isDirectory())QB(t,e,r,i,n,s,o,a);else if(n)hs.unlink(t,g=>{if(g)return a(g);hs.mkdir(t,r,v7(t,e,r,i,n,s,o,a))});else{if(u.isSymbolicLink())return a(new sR(t,t+"/"+e.join("/")));a(l)}})}else o=o||t,QB(t,e,r,i,n,s,o,a)},tct=nR.exports.sync=(t,e)=>{let r=e.umask,i=e.mode|448,n=(i&r)!=0,s=e.uid,o=e.gid,a=typeof s=="number"&&typeof o=="number"&&(s!==e.processUid||o!==e.processGid),l=e.preserve,c=e.unlink,u=e.cache,g=e.cwd,f=m=>{u.set(t,!0),m&&a&&b7.sync(m,s,o),n&&hs.chmodSync(t,i)};if(u&&u.get(t)===!0)return f();if(t===g){let m=!1,I="ENOTDIR";try{m=hs.statSync(t).isDirectory()}catch(B){I=B.code}finally{if(!m)throw new cd(t,I)}f();return}if(l)return f(Q7.sync(t,i));let p=BB.relative(g,t).split(/\/|\\/),d=null;for(let m=p.shift(),I=g;m&&(I+="/"+m);m=p.shift())if(!u.get(I))try{hs.mkdirSync(I,i),d=d||I,u.set(I,!0)}catch(B){if(B.path&&BB.dirname(B.path)===g&&(B.code==="ENOTDIR"||B.code==="ENOENT"))return new cd(g,B.code);let b=hs.lstatSync(I);if(b.isDirectory()){u.set(I,!0);continue}else if(c){hs.unlinkSync(I),hs.mkdirSync(I,i),d=d||I,u.set(I,!0);continue}else if(b.isSymbolicLink())return new sR(I,I+"/"+p.join("/"))}return f(d)}});var P7=E((ict,x7)=>{var k7=require("assert");x7.exports=()=>{let t=new Map,e=new Map,{join:r}=require("path"),i=u=>r(u).split(/[\\\/]/).slice(0,-1).reduce((g,f)=>g.length?g.concat(r(g[g.length-1],f)):[f],[]),n=new Set,s=u=>{let g=e.get(u);if(!g)throw new Error("function does not have any path reservations");return{paths:g.paths.map(f=>t.get(f)),dirs:[...g.dirs].map(f=>t.get(f))}},o=u=>{let{paths:g,dirs:f}=s(u);return g.every(h=>h[0]===u)&&f.every(h=>h[0]instanceof Set&&h[0].has(u))},a=u=>n.has(u)||!o(u)?!1:(n.add(u),u(()=>l(u)),!0),l=u=>{if(!n.has(u))return!1;let{paths:g,dirs:f}=e.get(u),h=new Set;return g.forEach(p=>{let d=t.get(p);k7.equal(d[0],u),d.length===1?t.delete(p):(d.shift(),typeof d[0]=="function"?h.add(d[0]):d[0].forEach(m=>h.add(m)))}),f.forEach(p=>{let d=t.get(p);k7(d[0]instanceof Set),d[0].size===1&&d.length===1?t.delete(p):d[0].size===1?(d.shift(),h.add(d[0])):d[0].delete(u)}),n.delete(u),h.forEach(p=>a(p)),!0};return{check:o,reserve:(u,g)=>{let f=new Set(u.map(h=>i(h)).reduce((h,p)=>h.concat(p)));return e.set(g,{dirs:f,paths:u}),u.forEach(h=>{let p=t.get(h);p?p.push(g):t.set(h,[g])}),f.forEach(h=>{let p=t.get(h);p?p[p.length-1]instanceof Set?p[p.length-1].add(g):p.push(new Set([g])):t.set(h,[new Set([g])])}),a(g)}}}});var F7=E((nct,D7)=>{var FLe=process.env.__FAKE_PLATFORM__||process.platform,NLe=FLe==="win32",LLe=global.__FAKE_TESTING_FS__||require("fs"),{O_CREAT:TLe,O_TRUNC:MLe,O_WRONLY:OLe,UV_FS_O_FILEMAP:R7=0}=LLe.constants,KLe=NLe&&!!R7,ULe=512*1024,HLe=R7|MLe|TLe|OLe;D7.exports=KLe?t=>t"w"});var hR=E((Act,N7)=>{"use strict";var GLe=require("assert"),sct=require("events").EventEmitter,jLe=ld(),Ut=require("fs"),YLe=bg(),Pa=require("path"),oR=S7(),oct=oR.sync,L7=yD(),qLe=P7(),T7=Symbol("onEntry"),aR=Symbol("checkFs"),M7=Symbol("checkFs2"),AR=Symbol("isReusable"),Da=Symbol("makeFs"),lR=Symbol("file"),cR=Symbol("directory"),bB=Symbol("link"),O7=Symbol("symlink"),K7=Symbol("hardlink"),U7=Symbol("unsupported"),act=Symbol("unknown"),H7=Symbol("checkPath"),Pg=Symbol("mkdir"),nn=Symbol("onError"),vB=Symbol("pending"),G7=Symbol("pend"),Dg=Symbol("unpend"),uR=Symbol("ended"),gR=Symbol("maybeClose"),fR=Symbol("skip"),ud=Symbol("doChown"),gd=Symbol("uid"),fd=Symbol("gid"),j7=require("crypto"),Y7=F7(),SB=()=>{throw new Error("sync function called cb somehow?!?")},JLe=(t,e)=>{if(process.platform!=="win32")return Ut.unlink(t,e);let r=t+".DELETE."+j7.randomBytes(16).toString("hex");Ut.rename(t,r,i=>{if(i)return e(i);Ut.unlink(r,e)})},WLe=t=>{if(process.platform!=="win32")return Ut.unlinkSync(t);let e=t+".DELETE."+j7.randomBytes(16).toString("hex");Ut.renameSync(t,e),Ut.unlinkSync(e)},q7=(t,e,r)=>t===t>>>0?t:e===e>>>0?e:r,xB=class extends jLe{constructor(e){if(e||(e={}),e.ondone=r=>{this[uR]=!0,this[gR]()},super(e),this.reservations=qLe(),this.transform=typeof e.transform=="function"?e.transform:null,this.writable=!0,this.readable=!1,this[vB]=0,this[uR]=!1,this.dirCache=e.dirCache||new Map,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=null,this.gid=null,this.setOwner=!1;e.preserveOwner===void 0&&typeof e.uid!="number"?this.preserveOwner=process.getuid&&process.getuid()===0:this.preserveOwner=!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():null,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():null,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||process.platform==="win32",this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=Pa.resolve(e.cwd||process.cwd()),this.strip=+e.strip||0,this.processUmask=process.umask(),this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",r=>this[T7](r))}warn(e,r,i={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(i.recoverable=!1),super.warn(e,r,i)}[gR](){this[uR]&&this[vB]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close"))}[H7](e){if(this.strip){let r=e.path.split(/\/|\\/);if(r.length=this.strip&&(e.linkpath=i.slice(this.strip).join("/"))}}if(!this.preservePaths){let r=e.path;if(r.match(/(^|\/|\\)\.\.(\\|\/|$)/))return this.warn("TAR_ENTRY_ERROR","path contains '..'",{entry:e,path:r}),!1;if(Pa.win32.isAbsolute(r)){let i=Pa.win32.parse(r);e.path=r.substr(i.root.length);let n=i.root;this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:e,path:r})}}if(this.win32){let r=Pa.win32.parse(e.path);e.path=r.root===""?L7.encode(e.path):r.root+L7.encode(e.path.substr(r.root.length))}return Pa.isAbsolute(e.path)?e.absolute=e.path:e.absolute=Pa.resolve(this.cwd,e.path),!0}[T7](e){if(!this[H7](e))return e.resume();switch(GLe.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[aR](e);case"CharacterDevice":case"BlockDevice":case"FIFO":return this[U7](e)}}[nn](e,r){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:r}),this[Dg](),r.resume())}[Pg](e,r,i){oR(e,{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:r},i)}[ud](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[gd](e){return q7(this.uid,e.uid,this.processUid)}[fd](e){return q7(this.gid,e.gid,this.processGid)}[lR](e,r){let i=e.mode&4095||this.fmode,n=new YLe.WriteStream(e.absolute,{flags:Y7(e.size),mode:i,autoClose:!1});n.on("error",l=>this[nn](l,e));let s=1,o=l=>{if(l)return this[nn](l,e);--s==0&&Ut.close(n.fd,c=>{r(),c?this[nn](c,e):this[Dg]()})};n.on("finish",l=>{let c=e.absolute,u=n.fd;if(e.mtime&&!this.noMtime){s++;let g=e.atime||new Date,f=e.mtime;Ut.futimes(u,g,f,h=>h?Ut.utimes(c,g,f,p=>o(p&&h)):o())}if(this[ud](e)){s++;let g=this[gd](e),f=this[fd](e);Ut.fchown(u,g,f,h=>h?Ut.chown(c,g,f,p=>o(p&&h)):o())}o()});let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",l=>this[nn](l,e)),e.pipe(a)),a.pipe(n)}[cR](e,r){let i=e.mode&4095||this.dmode;this[Pg](e.absolute,i,n=>{if(n)return r(),this[nn](n,e);let s=1,o=a=>{--s==0&&(r(),this[Dg](),e.resume())};e.mtime&&!this.noMtime&&(s++,Ut.utimes(e.absolute,e.atime||new Date,e.mtime,o)),this[ud](e)&&(s++,Ut.chown(e.absolute,this[gd](e),this[fd](e),o)),o()})}[U7](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[O7](e,r){this[bB](e,e.linkpath,"symlink",r)}[K7](e,r){this[bB](e,Pa.resolve(this.cwd,e.linkpath),"link",r)}[G7](){this[vB]++}[Dg](){this[vB]--,this[gR]()}[fR](e){this[Dg](),e.resume()}[AR](e,r){return e.type==="File"&&!this.unlink&&r.isFile()&&r.nlink<=1&&process.platform!=="win32"}[aR](e){this[G7]();let r=[e.path];e.linkpath&&r.push(e.linkpath),this.reservations.reserve(r,i=>this[M7](e,i))}[M7](e,r){this[Pg](Pa.dirname(e.absolute),this.dmode,i=>{if(i)return r(),this[nn](i,e);Ut.lstat(e.absolute,(n,s)=>{s&&(this.keep||this.newer&&s.mtime>e.mtime)?(this[fR](e),r()):n||this[AR](e,s)?this[Da](null,e,r):s.isDirectory()?e.type==="Directory"?!e.mode||(s.mode&4095)===e.mode?this[Da](null,e,r):Ut.chmod(e.absolute,e.mode,o=>this[Da](o,e,r)):Ut.rmdir(e.absolute,o=>this[Da](o,e,r)):JLe(e.absolute,o=>this[Da](o,e,r))})})}[Da](e,r,i){if(e)return this[nn](e,r);switch(r.type){case"File":case"OldFile":case"ContiguousFile":return this[lR](r,i);case"Link":return this[K7](r,i);case"SymbolicLink":return this[O7](r,i);case"Directory":case"GNUDumpDir":return this[cR](r,i)}}[bB](e,r,i,n){Ut[i](r,e.absolute,s=>{if(s)return this[nn](s,e);n(),this[Dg](),e.resume()})}},J7=class extends xB{constructor(e){super(e)}[aR](e){let r=this[Pg](Pa.dirname(e.absolute),this.dmode,SB);if(r)return this[nn](r,e);try{let i=Ut.lstatSync(e.absolute);if(this.keep||this.newer&&i.mtime>e.mtime)return this[fR](e);if(this[AR](e,i))return this[Da](null,e,SB);try{return i.isDirectory()?e.type==="Directory"?e.mode&&(i.mode&4095)!==e.mode&&Ut.chmodSync(e.absolute,e.mode):Ut.rmdirSync(e.absolute):WLe(e.absolute),this[Da](null,e,SB)}catch(n){return this[nn](n,e)}}catch(i){return this[Da](null,e,SB)}}[lR](e,r){let i=e.mode&4095||this.fmode,n=l=>{let c;try{Ut.closeSync(o)}catch(u){c=u}(l||c)&&this[nn](l||c,e)},s,o;try{o=Ut.openSync(e.absolute,Y7(e.size),i)}catch(l){return n(l)}let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",l=>this[nn](l,e)),e.pipe(a)),a.on("data",l=>{try{Ut.writeSync(o,l,0,l.length)}catch(c){n(c)}}),a.on("end",l=>{let c=null;if(e.mtime&&!this.noMtime){let u=e.atime||new Date,g=e.mtime;try{Ut.futimesSync(o,u,g)}catch(f){try{Ut.utimesSync(e.absolute,u,g)}catch(h){c=f}}}if(this[ud](e)){let u=this[gd](e),g=this[fd](e);try{Ut.fchownSync(o,u,g)}catch(f){try{Ut.chownSync(e.absolute,u,g)}catch(h){c=c||f}}}n(c)})}[cR](e,r){let i=e.mode&4095||this.dmode,n=this[Pg](e.absolute,i);if(n)return this[nn](n,e);if(e.mtime&&!this.noMtime)try{Ut.utimesSync(e.absolute,e.atime||new Date,e.mtime)}catch(s){}if(this[ud](e))try{Ut.chownSync(e.absolute,this[gd](e),this[fd](e))}catch(s){}e.resume()}[Pg](e,r){try{return oR.sync(e,{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:r})}catch(i){return i}}[bB](e,r,i,n){try{Ut[i+"Sync"](r,e.absolute),e.resume()}catch(s){return this[nn](s,e)}}};xB.Sync=J7;N7.exports=xB});var X7=E((cct,W7)=>{"use strict";var zLe=fg(),kB=hR(),z7=require("fs"),V7=bg(),_7=require("path"),lct=W7.exports=(t,e,r)=>{typeof t=="function"?(r=t,e=null,t={}):Array.isArray(t)&&(e=t,t={}),typeof e=="function"&&(r=e,e=null),e?e=Array.from(e):e=[];let i=zLe(t);if(i.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return e.length&&VLe(i,e),i.file&&i.sync?_Le(i):i.file?XLe(i,r):i.sync?ZLe(i):$Le(i)},VLe=(t,e)=>{let r=new Map(e.map(s=>[s.replace(/\/+$/,""),!0])),i=t.filter,n=(s,o)=>{let a=o||_7.parse(s).root||".",l=s===a?!1:r.has(s)?r.get(s):n(_7.dirname(s),a);return r.set(s,l),l};t.filter=i?(s,o)=>i(s,o)&&n(s.replace(/\/+$/,"")):s=>n(s.replace(/\/+$/,""))},_Le=t=>{let e=new kB.Sync(t),r=t.file,i=!0,n,s=z7.statSync(r),o=t.maxReadSize||16*1024*1024;new V7.ReadStreamSync(r,{readSize:o,size:s.size}).pipe(e)},XLe=(t,e)=>{let r=new kB(t),i=t.maxReadSize||16*1024*1024,n=t.file,s=new Promise((o,a)=>{r.on("error",a),r.on("close",o),z7.stat(n,(l,c)=>{if(l)a(l);else{let u=new V7.ReadStream(n,{readSize:i,size:c.size});u.on("error",a),u.pipe(r)}})});return e?s.then(e,e):s},ZLe=t=>new kB.Sync(t),$Le=t=>new kB(t)});var Z7=E($r=>{"use strict";$r.c=$r.create=TV();$r.r=$r.replace=XD();$r.t=$r.list=IB();$r.u=$r.update=qV();$r.x=$r.extract=X7();$r.Pack=AB();$r.Unpack=hR();$r.Parse=ld();$r.ReadEntry=id();$r.WriteEntry=xD();$r.Header=Cg();$r.Pax=zw();$r.types=rd()});var e_=E((gct,pR)=>{"use strict";var eTe=Object.prototype.hasOwnProperty,sn="~";function hd(){}Object.create&&(hd.prototype=Object.create(null),new hd().__proto__||(sn=!1));function tTe(t,e,r){this.fn=t,this.context=e,this.once=r||!1}function $7(t,e,r,i,n){if(typeof r!="function")throw new TypeError("The listener must be a function");var s=new tTe(r,i||t,n),o=sn?sn+e:e;return t._events[o]?t._events[o].fn?t._events[o]=[t._events[o],s]:t._events[o].push(s):(t._events[o]=s,t._eventsCount++),t}function PB(t,e){--t._eventsCount==0?t._events=new hd:delete t._events[e]}function Ti(){this._events=new hd,this._eventsCount=0}Ti.prototype.eventNames=function(){var e=[],r,i;if(this._eventsCount===0)return e;for(i in r=this._events)eTe.call(r,i)&&e.push(sn?i.slice(1):i);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(r)):e};Ti.prototype.listeners=function(e){var r=sn?sn+e:e,i=this._events[r];if(!i)return[];if(i.fn)return[i.fn];for(var n=0,s=i.length,o=new Array(s);n{"use strict";t_.exports=(t,e)=>(e=e||(()=>{}),t.then(r=>new Promise(i=>{i(e())}).then(()=>r),r=>new Promise(i=>{i(e())}).then(()=>{throw r})))});var n_=E((hct,DB)=>{"use strict";var rTe=r_(),dR=class extends Error{constructor(e){super(e);this.name="TimeoutError"}},i_=(t,e,r)=>new Promise((i,n)=>{if(typeof e!="number"||e<0)throw new TypeError("Expected `milliseconds` to be a positive number");if(e===Infinity){i(t);return}let s=setTimeout(()=>{if(typeof r=="function"){try{i(r())}catch(l){n(l)}return}let o=typeof r=="string"?r:`Promise timed out after ${e} milliseconds`,a=r instanceof Error?r:new dR(o);typeof t.cancel=="function"&&t.cancel(),n(a)},e);rTe(t.then(i,n),()=>{clearTimeout(s)})});DB.exports=i_;DB.exports.default=i_;DB.exports.TimeoutError=dR});var s_=E(CR=>{"use strict";Object.defineProperty(CR,"__esModule",{value:!0});function iTe(t,e,r){let i=0,n=t.length;for(;n>0;){let s=n/2|0,o=i+s;r(t[o],e)<=0?(i=++o,n-=s+1):n=s}return i}CR.default=iTe});var a_=E(mR=>{"use strict";Object.defineProperty(mR,"__esModule",{value:!0});var nTe=s_(),o_=class{constructor(){this._queue=[]}enqueue(e,r){r=Object.assign({priority:0},r);let i={priority:r.priority,run:e};if(this.size&&this._queue[this.size-1].priority>=r.priority){this._queue.push(i);return}let n=nTe.default(this._queue,i,(s,o)=>o.priority-s.priority);this._queue.splice(n,0,i)}dequeue(){let e=this._queue.shift();return e==null?void 0:e.run}filter(e){return this._queue.filter(r=>r.priority===e.priority).map(r=>r.run)}get size(){return this._queue.length}};mR.default=o_});var c_=E(ER=>{"use strict";Object.defineProperty(ER,"__esModule",{value:!0});var sTe=e_(),A_=n_(),oTe=a_(),RB=()=>{},aTe=new A_.TimeoutError,l_=class extends sTe{constructor(e){var r,i,n,s;super();if(this._intervalCount=0,this._intervalEnd=0,this._pendingCount=0,this._resolveEmpty=RB,this._resolveIdle=RB,e=Object.assign({carryoverConcurrencyCount:!1,intervalCap:Infinity,interval:0,concurrency:Infinity,autoStart:!0,queueClass:oTe.default},e),!(typeof e.intervalCap=="number"&&e.intervalCap>=1))throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${(i=(r=e.intervalCap)===null||r===void 0?void 0:r.toString())!==null&&i!==void 0?i:""}\` (${typeof e.intervalCap})`);if(e.interval===void 0||!(Number.isFinite(e.interval)&&e.interval>=0))throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${(s=(n=e.interval)===null||n===void 0?void 0:n.toString())!==null&&s!==void 0?s:""}\` (${typeof e.interval})`);this._carryoverConcurrencyCount=e.carryoverConcurrencyCount,this._isIntervalIgnored=e.intervalCap===Infinity||e.interval===0,this._intervalCap=e.intervalCap,this._interval=e.interval,this._queue=new e.queueClass,this._queueClass=e.queueClass,this.concurrency=e.concurrency,this._timeout=e.timeout,this._throwOnTimeout=e.throwOnTimeout===!0,this._isPaused=e.autoStart===!1}get _doesIntervalAllowAnother(){return this._isIntervalIgnored||this._intervalCount{this._onResumeInterval()},r)),!0}return!1}_tryToStartAnother(){if(this._queue.size===0)return this._intervalId&&clearInterval(this._intervalId),this._intervalId=void 0,this._resolvePromises(),!1;if(!this._isPaused){let e=!this._isIntervalPaused();if(this._doesIntervalAllowAnother&&this._doesConcurrentAllowAnother){let r=this._queue.dequeue();return r?(this.emit("active"),r(),e&&this._initializeIntervalIfNeeded(),!0):!1}}return!1}_initializeIntervalIfNeeded(){this._isIntervalIgnored||this._intervalId!==void 0||(this._intervalId=setInterval(()=>{this._onInterval()},this._interval),this._intervalEnd=Date.now()+this._interval)}_onInterval(){this._intervalCount===0&&this._pendingCount===0&&this._intervalId&&(clearInterval(this._intervalId),this._intervalId=void 0),this._intervalCount=this._carryoverConcurrencyCount?this._pendingCount:0,this._processQueue()}_processQueue(){for(;this._tryToStartAnother(););}get concurrency(){return this._concurrency}set concurrency(e){if(!(typeof e=="number"&&e>=1))throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${e}\` (${typeof e})`);this._concurrency=e,this._processQueue()}async add(e,r={}){return new Promise((i,n)=>{let s=async()=>{this._pendingCount++,this._intervalCount++;try{let o=this._timeout===void 0&&r.timeout===void 0?e():A_.default(Promise.resolve(e()),r.timeout===void 0?this._timeout:r.timeout,()=>{(r.throwOnTimeout===void 0?this._throwOnTimeout:r.throwOnTimeout)&&n(aTe)});i(await o)}catch(o){n(o)}this._next()};this._queue.enqueue(s,r),this._tryToStartAnother(),this.emit("add")})}async addAll(e,r){return Promise.all(e.map(async i=>this.add(i,r)))}start(){return this._isPaused?(this._isPaused=!1,this._processQueue(),this):this}pause(){this._isPaused=!0}clear(){this._queue=new this._queueClass}async onEmpty(){if(this._queue.size!==0)return new Promise(e=>{let r=this._resolveEmpty;this._resolveEmpty=()=>{r(),e()}})}async onIdle(){if(!(this._pendingCount===0&&this._queue.size===0))return new Promise(e=>{let r=this._resolveIdle;this._resolveIdle=()=>{r(),e()}})}get size(){return this._queue.size}sizeBy(e){return this._queue.filter(e).length}get pending(){return this._pendingCount}get isPaused(){return this._isPaused}get timeout(){return this._timeout}set timeout(e){this._timeout=e}};ER.default=l_});var p_=E((Ect,h_)=>{var yR;h_.exports.getContent=()=>(typeof yR=="undefined"&&(yR=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),yR)});var y_=E((wR,I_)=>{(function(t,e){typeof wR=="object"?I_.exports=e():typeof define=="function"&&define.amd?define(e):t.treeify=e()})(wR,function(){function t(n,s){var o=s?"\u2514":"\u251C";return n?o+="\u2500 ":o+="\u2500\u2500\u2510",o}function e(n,s){var o=[];for(var a in n)!n.hasOwnProperty(a)||s&&typeof n[a]=="function"||o.push(a);return o}function r(n,s,o,a,l,c,u){var g="",f=0,h,p,d=a.slice(0);if(d.push([s,o])&&a.length>0&&(a.forEach(function(I,B){B>0&&(g+=(I[1]?" ":"\u2502")+" "),!p&&I[0]===s&&(p=!0)}),g+=t(n,o)+n,l&&(typeof s!="object"||s instanceof Date)&&(g+=": "+s),p&&(g+=" (circular ref.)"),u(g)),!p&&typeof s=="object"){var m=e(s,c);m.forEach(function(I){h=++f===m.length,r(I,s[I],h,d,l,c,u)})}}var i={};return i.asLines=function(n,s,o,a){var l=typeof o!="function"?o:!1;r(".",n,!1,[],s,l,a||o)},i.asTree=function(n,s,o){var a="";return r(".",n,!1,[],s,o,function(l){a+=l+` +`}),a},i})});var x_=E((Uct,bR)=>{"use strict";var pTe=t=>{let e=!1,r=!1,i=!1;for(let n=0;n{if(!(typeof t=="string"||Array.isArray(t)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let r=n=>e.pascalCase?n.charAt(0).toUpperCase()+n.slice(1):n;return Array.isArray(t)?t=t.map(n=>n.trim()).filter(n=>n.length).join("-"):t=t.trim(),t.length===0?"":t.length===1?e.pascalCase?t.toUpperCase():t.toLowerCase():(t!==t.toLowerCase()&&(t=pTe(t)),t=t.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(n,s)=>s.toUpperCase()).replace(/\d+(\w|$)/g,n=>n.toUpperCase()),r(t))};bR.exports=S_;bR.exports.default=S_});var Na=E(TR=>{"use strict";Object.defineProperty(TR,"__esModule",{value:!0});TR.default=L_;function L_(){}L_.prototype={diff:function(e,r){var i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},n=i.callback;typeof i=="function"&&(n=i,i={}),this.options=i;var s=this;function o(d){return n?(setTimeout(function(){n(void 0,d)},0),!0):d}e=this.castInput(e),r=this.castInput(r),e=this.removeEmpty(this.tokenize(e)),r=this.removeEmpty(this.tokenize(r));var a=r.length,l=e.length,c=1,u=a+l,g=[{newPos:-1,components:[]}],f=this.extractCommon(g[0],r,e,0);if(g[0].newPos+1>=a&&f+1>=l)return o([{value:this.join(r),count:r.length}]);function h(){for(var d=-1*c;d<=c;d+=2){var m=void 0,I=g[d-1],B=g[d+1],b=(B?B.newPos:0)-d;I&&(g[d-1]=void 0);var R=I&&I.newPos+1=a&&b+1>=l)return o(yTe(s,m.components,r,e,s.useLongestToken));g[d]=m}c++}if(n)(function d(){setTimeout(function(){if(c>u)return n();h()||d()},0)})();else for(;c<=u;){var p=h();if(p)return p}},pushComponent:function(e,r,i){var n=e[e.length-1];n&&n.added===r&&n.removed===i?e[e.length-1]={count:n.count+1,added:r,removed:i}:e.push({count:1,added:r,removed:i})},extractCommon:function(e,r,i,n){for(var s=r.length,o=i.length,a=e.newPos,l=a-n,c=0;a+1h.length?d:h}),c.value=t.join(u)}else c.value=t.join(r.slice(a,a+c.count));a+=c.count,c.added||(l+=c.count)}}var f=e[o-1];return o>1&&typeof f.value=="string"&&(f.added||f.removed)&&t.equals("",f.value)&&(e[o-2].value+=f.value,e.pop()),e}function wTe(t){return{newPos:t.newPos,components:t.components.slice(0)}}});var M_=E(Cd=>{"use strict";Object.defineProperty(Cd,"__esModule",{value:!0});Cd.diffChars=BTe;Cd.characterDiff=void 0;var bTe=QTe(Na());function QTe(t){return t&&t.__esModule?t:{default:t}}var T_=new bTe.default;Cd.characterDiff=T_;function BTe(t,e,r){return T_.diff(t,e,r)}});var OR=E(MR=>{"use strict";Object.defineProperty(MR,"__esModule",{value:!0});MR.generateOptions=vTe;function vTe(t,e){if(typeof t=="function")e.callback=t;else if(t)for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}});var U_=E(Ng=>{"use strict";Object.defineProperty(Ng,"__esModule",{value:!0});Ng.diffWords=STe;Ng.diffWordsWithSpace=xTe;Ng.wordDiff=void 0;var PTe=kTe(Na()),DTe=OR();function kTe(t){return t&&t.__esModule?t:{default:t}}var O_=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,K_=/\S/,md=new PTe.default;Ng.wordDiff=md;md.equals=function(t,e){return this.options.ignoreCase&&(t=t.toLowerCase(),e=e.toLowerCase()),t===e||this.options.ignoreWhitespace&&!K_.test(t)&&!K_.test(e)};md.tokenize=function(t){for(var e=t.split(/(\s+|[()[\]{}'"]|\b)/),r=0;r{"use strict";Object.defineProperty(Lg,"__esModule",{value:!0});Lg.diffLines=RTe;Lg.diffTrimmedLines=FTe;Lg.lineDiff=void 0;var LTe=NTe(Na()),TTe=OR();function NTe(t){return t&&t.__esModule?t:{default:t}}var OB=new LTe.default;Lg.lineDiff=OB;OB.tokenize=function(t){var e=[],r=t.split(/(\n|\r\n)/);r[r.length-1]||r.pop();for(var i=0;i{"use strict";Object.defineProperty(Ed,"__esModule",{value:!0});Ed.diffSentences=MTe;Ed.sentenceDiff=void 0;var KTe=OTe(Na());function OTe(t){return t&&t.__esModule?t:{default:t}}var KR=new KTe.default;Ed.sentenceDiff=KR;KR.tokenize=function(t){return t.split(/(\S.+?[.!?])(?=\s+|$)/)};function MTe(t,e,r){return KR.diff(t,e,r)}});var G_=E(Id=>{"use strict";Object.defineProperty(Id,"__esModule",{value:!0});Id.diffCss=UTe;Id.cssDiff=void 0;var GTe=HTe(Na());function HTe(t){return t&&t.__esModule?t:{default:t}}var UR=new GTe.default;Id.cssDiff=UR;UR.tokenize=function(t){return t.split(/([{}:;,]|\s+)/)};function UTe(t,e,r){return UR.diff(t,e,r)}});var Y_=E(Tg=>{"use strict";Object.defineProperty(Tg,"__esModule",{value:!0});Tg.diffJson=jTe;Tg.canonicalize=UB;Tg.jsonDiff=void 0;var j_=YTe(Na()),qTe=KB();function YTe(t){return t&&t.__esModule?t:{default:t}}function HB(t){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?HB=function(r){return typeof r}:HB=function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},HB(t)}var JTe=Object.prototype.toString,bc=new j_.default;Tg.jsonDiff=bc;bc.useLongestToken=!0;bc.tokenize=qTe.lineDiff.tokenize;bc.castInput=function(t){var e=this.options,r=e.undefinedReplacement,i=e.stringifyReplacer,n=i===void 0?function(s,o){return typeof o=="undefined"?r:o}:i;return typeof t=="string"?t:JSON.stringify(UB(t,null,null,n),n," ")};bc.equals=function(t,e){return j_.default.prototype.equals.call(bc,t.replace(/,([\r\n])/g,"$1"),e.replace(/,([\r\n])/g,"$1"))};function jTe(t,e,r){return bc.diff(t,e,r)}function UB(t,e,r,i,n){e=e||[],r=r||[],i&&(t=i(n,t));var s;for(s=0;s{"use strict";Object.defineProperty(yd,"__esModule",{value:!0});yd.diffArrays=WTe;yd.arrayDiff=void 0;var VTe=zTe(Na());function zTe(t){return t&&t.__esModule?t:{default:t}}var wd=new VTe.default;yd.arrayDiff=wd;wd.tokenize=function(t){return t.slice()};wd.join=wd.removeEmpty=function(t){return t};function WTe(t,e,r){return wd.diff(t,e,r)}});var GB=E(HR=>{"use strict";Object.defineProperty(HR,"__esModule",{value:!0});HR.parsePatch=_Te;function _Te(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=t.split(/\r\n|[\n\v\f\r\x85]/),i=t.match(/\r\n|[\n\v\f\r\x85]/g)||[],n=[],s=0;function o(){var c={};for(n.push(c);s{"use strict";Object.defineProperty(GR,"__esModule",{value:!0});GR.default=XTe;function XTe(t,e,r){var i=!0,n=!1,s=!1,o=1;return function a(){if(i&&!s){if(n?o++:i=!1,t+o<=r)return o;s=!0}if(!n)return s||(i=!0),e<=t-o?-o++:(n=!0,a())}}});var V_=E(jB=>{"use strict";Object.defineProperty(jB,"__esModule",{value:!0});jB.applyPatch=W_;jB.applyPatches=ZTe;var z_=GB(),eMe=$Te(J_());function $Te(t){return t&&t.__esModule?t:{default:t}}function W_(t,e){var r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(typeof e=="string"&&(e=(0,z_.parsePatch)(e)),Array.isArray(e)){if(e.length>1)throw new Error("applyPatch only works with a single input.");e=e[0]}var i=t.split(/\r\n|[\n\v\f\r\x85]/),n=t.match(/\r\n|[\n\v\f\r\x85]/g)||[],s=e.hunks,o=r.compareLine||function(F,D,he,pe){return D===pe},a=0,l=r.fuzzFactor||0,c=0,u=0,g,f;function h(F,D){for(var he=0;he0?pe[0]:" ",Pe=pe.length>0?pe.substr(1):pe;if(Ne===" "||Ne==="-"){if(!o(D+1,i[D],Ne,Pe)&&(a++,a>l))return!1;D++}}return!0}for(var p=0;p0?ne[0]:" ",A=ne.length>0?ne.substr(1):ne,V=L.linedelimiters[J];if(q===" ")K++;else if(q==="-")i.splice(K,1),n.splice(K,1);else if(q==="+")i.splice(K,0,A),n.splice(K,0,V),K++;else if(q==="\\"){var W=L.lines[J-1]?L.lines[J-1][0]:null;W==="+"?g=!0:W==="-"&&(f=!0)}}}if(g)for(;!i[i.length-1];)i.pop(),n.pop();else f&&(i.push(""),n.push(` +`));for(var X=0;X{"use strict";Object.defineProperty(Bd,"__esModule",{value:!0});Bd.structuredPatch=__;Bd.createTwoFilesPatch=X_;Bd.createPatch=tMe;var rMe=KB();function jR(t){return sMe(t)||nMe(t)||iMe()}function iMe(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function nMe(t){if(Symbol.iterator in Object(t)||Object.prototype.toString.call(t)==="[object Arguments]")return Array.from(t)}function sMe(t){if(Array.isArray(t)){for(var e=0,r=new Array(t.length);e0?l(L.lines.slice(-o.context)):[],u-=f.length,g-=f.length)}(H=f).push.apply(H,jR(R.map(function(X){return(b.added?"+":"-")+X}))),b.added?p+=R.length:h+=R.length}else{if(u)if(R.length<=o.context*2&&B=a.length-2&&R.length<=o.context){var A=/\n$/.test(r),V=/\n$/.test(i),W=R.length==0&&f.length>q.oldLines;!A&&W&&f.splice(q.oldLines,0,"\\ No newline at end of file"),(!A&&!W||!V)&&f.push("\\ No newline at end of file")}c.push(q),u=0,g=0,f=[]}h+=R.length,p+=R.length}},m=0;m{"use strict";Object.defineProperty(YB,"__esModule",{value:!0});YB.arrayEqual=oMe;YB.arrayStartsWith=Z_;function oMe(t,e){return t.length!==e.length?!1:Z_(t,e)}function Z_(t,e){if(e.length>t.length)return!1;for(var r=0;r{"use strict";Object.defineProperty(qB,"__esModule",{value:!0});qB.calcLineCount=eX;qB.merge=aMe;var AMe=YR(),lMe=GB(),qR=$_();function Mg(t){return gMe(t)||uMe(t)||cMe()}function cMe(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function uMe(t){if(Symbol.iterator in Object(t)||Object.prototype.toString.call(t)==="[object Arguments]")return Array.from(t)}function gMe(t){if(Array.isArray(t)){for(var e=0,r=new Array(t.length);e{"use strict";Object.defineProperty(zR,"__esModule",{value:!0});zR.convertChangesToDMP=dMe;function dMe(t){for(var e=[],r,i,n=0;n{"use strict";Object.defineProperty(VR,"__esModule",{value:!0});VR.convertChangesToXML=CMe;function CMe(t){for(var e=[],r=0;r"):i.removed&&e.push(""),e.push(mMe(i.value)),i.added?e.push(""):i.removed&&e.push("")}return e.join("")}function mMe(t){var e=t;return e=e.replace(/&/g,"&"),e=e.replace(//g,">"),e=e.replace(/"/g,"""),e}});var CX=E(br=>{"use strict";Object.defineProperty(br,"__esModule",{value:!0});Object.defineProperty(br,"Diff",{enumerable:!0,get:function(){return EMe.default}});Object.defineProperty(br,"diffChars",{enumerable:!0,get:function(){return IMe.diffChars}});Object.defineProperty(br,"diffWords",{enumerable:!0,get:function(){return fX.diffWords}});Object.defineProperty(br,"diffWordsWithSpace",{enumerable:!0,get:function(){return fX.diffWordsWithSpace}});Object.defineProperty(br,"diffLines",{enumerable:!0,get:function(){return hX.diffLines}});Object.defineProperty(br,"diffTrimmedLines",{enumerable:!0,get:function(){return hX.diffTrimmedLines}});Object.defineProperty(br,"diffSentences",{enumerable:!0,get:function(){return yMe.diffSentences}});Object.defineProperty(br,"diffCss",{enumerable:!0,get:function(){return wMe.diffCss}});Object.defineProperty(br,"diffJson",{enumerable:!0,get:function(){return pX.diffJson}});Object.defineProperty(br,"canonicalize",{enumerable:!0,get:function(){return pX.canonicalize}});Object.defineProperty(br,"diffArrays",{enumerable:!0,get:function(){return BMe.diffArrays}});Object.defineProperty(br,"applyPatch",{enumerable:!0,get:function(){return dX.applyPatch}});Object.defineProperty(br,"applyPatches",{enumerable:!0,get:function(){return dX.applyPatches}});Object.defineProperty(br,"parsePatch",{enumerable:!0,get:function(){return QMe.parsePatch}});Object.defineProperty(br,"merge",{enumerable:!0,get:function(){return bMe.merge}});Object.defineProperty(br,"structuredPatch",{enumerable:!0,get:function(){return _R.structuredPatch}});Object.defineProperty(br,"createTwoFilesPatch",{enumerable:!0,get:function(){return _R.createTwoFilesPatch}});Object.defineProperty(br,"createPatch",{enumerable:!0,get:function(){return _R.createPatch}});Object.defineProperty(br,"convertChangesToDMP",{enumerable:!0,get:function(){return vMe.convertChangesToDMP}});Object.defineProperty(br,"convertChangesToXML",{enumerable:!0,get:function(){return SMe.convertChangesToXML}});var EMe=xMe(Na()),IMe=M_(),fX=U_(),hX=KB(),yMe=H_(),wMe=G_(),pX=Y_(),BMe=q_(),dX=V_(),QMe=GB(),bMe=cX(),_R=YR(),vMe=uX(),SMe=gX();function xMe(t){return t&&t.__esModule?t:{default:t}}});var WB=E((agt,mX)=>{var kMe=As(),PMe=Nw(),DMe=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,RMe=/^\w*$/;function FMe(t,e){if(kMe(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||PMe(t)?!0:RMe.test(t)||!DMe.test(t)||e!=null&&t in Object(e)}mX.exports=FMe});var Gs=E((Agt,EX)=>{function NMe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}EX.exports=NMe});var zB=E((lgt,IX)=>{var LMe=Ac(),TMe=Gs(),MMe="[object AsyncFunction]",OMe="[object Function]",KMe="[object GeneratorFunction]",UMe="[object Proxy]";function HMe(t){if(!TMe(t))return!1;var e=LMe(t);return e==OMe||e==KMe||e==MMe||e==UMe}IX.exports=HMe});var wX=E((cgt,yX)=>{var GMe=Ks(),jMe=GMe["__core-js_shared__"];yX.exports=jMe});var bX=E((ugt,BX)=>{var XR=wX(),QX=function(){var t=/[^.]+$/.exec(XR&&XR.keys&&XR.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();function YMe(t){return!!QX&&QX in t}BX.exports=YMe});var ZR=E((ggt,vX)=>{var qMe=Function.prototype,JMe=qMe.toString;function WMe(t){if(t!=null){try{return JMe.call(t)}catch(e){}try{return t+""}catch(e){}}return""}vX.exports=WMe});var xX=E((fgt,SX)=>{var zMe=zB(),VMe=bX(),_Me=Gs(),XMe=ZR(),ZMe=/[\\^$.*+?()[\]{}|]/g,$Me=/^\[object .+?Constructor\]$/,eOe=Function.prototype,tOe=Object.prototype,rOe=eOe.toString,iOe=tOe.hasOwnProperty,nOe=RegExp("^"+rOe.call(iOe).replace(ZMe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function sOe(t){if(!_Me(t)||VMe(t))return!1;var e=zMe(t)?nOe:$Me;return e.test(XMe(t))}SX.exports=sOe});var PX=E((hgt,kX)=>{function oOe(t,e){return t==null?void 0:t[e]}kX.exports=oOe});var UA=E((pgt,DX)=>{var aOe=xX(),AOe=PX();function lOe(t,e){var r=AOe(t,e);return aOe(r)?r:void 0}DX.exports=lOe});var Qd=E((dgt,RX)=>{var cOe=UA(),uOe=cOe(Object,"create");RX.exports=uOe});var LX=E((Cgt,FX)=>{var NX=Qd();function gOe(){this.__data__=NX?NX(null):{},this.size=0}FX.exports=gOe});var MX=E((mgt,TX)=>{function fOe(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}TX.exports=fOe});var KX=E((Egt,OX)=>{var hOe=Qd(),pOe="__lodash_hash_undefined__",dOe=Object.prototype,COe=dOe.hasOwnProperty;function mOe(t){var e=this.__data__;if(hOe){var r=e[t];return r===pOe?void 0:r}return COe.call(e,t)?e[t]:void 0}OX.exports=mOe});var HX=E((Igt,UX)=>{var EOe=Qd(),IOe=Object.prototype,yOe=IOe.hasOwnProperty;function wOe(t){var e=this.__data__;return EOe?e[t]!==void 0:yOe.call(e,t)}UX.exports=wOe});var jX=E((ygt,GX)=>{var BOe=Qd(),QOe="__lodash_hash_undefined__";function bOe(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=BOe&&e===void 0?QOe:e,this}GX.exports=bOe});var qX=E((wgt,YX)=>{var vOe=LX(),SOe=MX(),xOe=KX(),kOe=HX(),POe=jX();function Og(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{function DOe(){this.__data__=[],this.size=0}JX.exports=DOe});var Kg=E((Qgt,zX)=>{function ROe(t,e){return t===e||t!==t&&e!==e}zX.exports=ROe});var bd=E((bgt,VX)=>{var FOe=Kg();function NOe(t,e){for(var r=t.length;r--;)if(FOe(t[r][0],e))return r;return-1}VX.exports=NOe});var XX=E((vgt,_X)=>{var LOe=bd(),TOe=Array.prototype,MOe=TOe.splice;function OOe(t){var e=this.__data__,r=LOe(e,t);if(r<0)return!1;var i=e.length-1;return r==i?e.pop():MOe.call(e,r,1),--this.size,!0}_X.exports=OOe});var $X=E((Sgt,ZX)=>{var KOe=bd();function UOe(t){var e=this.__data__,r=KOe(e,t);return r<0?void 0:e[r][1]}ZX.exports=UOe});var tZ=E((xgt,eZ)=>{var HOe=bd();function GOe(t){return HOe(this.__data__,t)>-1}eZ.exports=GOe});var iZ=E((kgt,rZ)=>{var jOe=bd();function YOe(t,e){var r=this.__data__,i=jOe(r,t);return i<0?(++this.size,r.push([t,e])):r[i][1]=e,this}rZ.exports=YOe});var vd=E((Pgt,nZ)=>{var qOe=WX(),JOe=XX(),WOe=$X(),zOe=tZ(),VOe=iZ();function Ug(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{var _Oe=UA(),XOe=Ks(),ZOe=_Oe(XOe,"Map");sZ.exports=ZOe});var AZ=E((Rgt,oZ)=>{var aZ=qX(),$Oe=vd(),eKe=VB();function tKe(){this.size=0,this.__data__={hash:new aZ,map:new(eKe||$Oe),string:new aZ}}oZ.exports=tKe});var cZ=E((Fgt,lZ)=>{function rKe(t){var e=typeof t;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?t!=="__proto__":t===null}lZ.exports=rKe});var Sd=E((Ngt,uZ)=>{var iKe=cZ();function nKe(t,e){var r=t.__data__;return iKe(e)?r[typeof e=="string"?"string":"hash"]:r.map}uZ.exports=nKe});var fZ=E((Lgt,gZ)=>{var sKe=Sd();function oKe(t){var e=sKe(this,t).delete(t);return this.size-=e?1:0,e}gZ.exports=oKe});var pZ=E((Tgt,hZ)=>{var aKe=Sd();function AKe(t){return aKe(this,t).get(t)}hZ.exports=AKe});var CZ=E((Mgt,dZ)=>{var lKe=Sd();function cKe(t){return lKe(this,t).has(t)}dZ.exports=cKe});var EZ=E((Ogt,mZ)=>{var uKe=Sd();function gKe(t,e){var r=uKe(this,t),i=r.size;return r.set(t,e),this.size+=r.size==i?0:1,this}mZ.exports=gKe});var _B=E((Kgt,IZ)=>{var fKe=AZ(),hKe=fZ(),pKe=pZ(),dKe=CZ(),CKe=EZ();function Hg(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{var wZ=_B(),mKe="Expected a function";function $R(t,e){if(typeof t!="function"||e!=null&&typeof e!="function")throw new TypeError(mKe);var r=function(){var i=arguments,n=e?e.apply(this,i):i[0],s=r.cache;if(s.has(n))return s.get(n);var o=t.apply(this,i);return r.cache=s.set(n,o)||s,o};return r.cache=new($R.Cache||wZ),r}$R.Cache=wZ;yZ.exports=$R});var bZ=E((Hgt,QZ)=>{var EKe=BZ(),IKe=500;function yKe(t){var e=EKe(t,function(i){return r.size===IKe&&r.clear(),i}),r=e.cache;return e}QZ.exports=yKe});var SZ=E((Ggt,vZ)=>{var wKe=bZ(),BKe=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,QKe=/\\(\\)?/g,bKe=wKe(function(t){var e=[];return t.charCodeAt(0)===46&&e.push(""),t.replace(BKe,function(r,i,n,s){e.push(n?s.replace(QKe,"$1"):i||r)}),e});vZ.exports=bKe});var Gg=E((jgt,xZ)=>{var vKe=As(),SKe=WB(),xKe=SZ(),kKe=gg();function PKe(t,e){return vKe(t)?t:SKe(t,e)?[t]:xKe(kKe(t))}xZ.exports=PKe});var Sc=E((Ygt,kZ)=>{var DKe=Nw(),RKe=1/0;function FKe(t){if(typeof t=="string"||DKe(t))return t;var e=t+"";return e=="0"&&1/t==-RKe?"-0":e}kZ.exports=FKe});var xd=E((qgt,PZ)=>{var NKe=Gg(),LKe=Sc();function TKe(t,e){e=NKe(e,t);for(var r=0,i=e.length;t!=null&&r{var MKe=UA(),OKe=function(){try{var t=MKe(Object,"defineProperty");return t({},"",{}),t}catch(e){}}();DZ.exports=OKe});var jg=E((Wgt,RZ)=>{var FZ=eF();function KKe(t,e,r){e=="__proto__"&&FZ?FZ(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}RZ.exports=KKe});var XB=E((zgt,NZ)=>{var UKe=jg(),HKe=Kg(),GKe=Object.prototype,jKe=GKe.hasOwnProperty;function YKe(t,e,r){var i=t[e];(!(jKe.call(t,e)&&HKe(i,r))||r===void 0&&!(e in t))&&UKe(t,e,r)}NZ.exports=YKe});var kd=E((Vgt,LZ)=>{var qKe=9007199254740991,JKe=/^(?:0|[1-9]\d*)$/;function WKe(t,e){var r=typeof t;return e=e==null?qKe:e,!!e&&(r=="number"||r!="symbol"&&JKe.test(t))&&t>-1&&t%1==0&&t{var zKe=XB(),VKe=Gg(),_Ke=kd(),MZ=Gs(),XKe=Sc();function ZKe(t,e,r,i){if(!MZ(t))return t;e=VKe(e,t);for(var n=-1,s=e.length,o=s-1,a=t;a!=null&&++n{var $Ke=xd(),e1e=tF(),t1e=Gg();function r1e(t,e,r){for(var i=-1,n=e.length,s={};++i{function i1e(t,e){return t!=null&&e in Object(t)}UZ.exports=i1e});var jZ=E(($gt,GZ)=>{var n1e=Ac(),s1e=Qo(),o1e="[object Arguments]";function a1e(t){return s1e(t)&&n1e(t)==o1e}GZ.exports=a1e});var Pd=E((eft,YZ)=>{var qZ=jZ(),A1e=Qo(),JZ=Object.prototype,l1e=JZ.hasOwnProperty,c1e=JZ.propertyIsEnumerable,u1e=qZ(function(){return arguments}())?qZ:function(t){return A1e(t)&&l1e.call(t,"callee")&&!c1e.call(t,"callee")};YZ.exports=u1e});var ZB=E((tft,WZ)=>{var g1e=9007199254740991;function f1e(t){return typeof t=="number"&&t>-1&&t%1==0&&t<=g1e}WZ.exports=f1e});var rF=E((rft,zZ)=>{var h1e=Gg(),p1e=Pd(),d1e=As(),C1e=kd(),m1e=ZB(),E1e=Sc();function I1e(t,e,r){e=h1e(e,t);for(var i=-1,n=e.length,s=!1;++i{var y1e=HZ(),w1e=rF();function B1e(t,e){return t!=null&&w1e(t,e,y1e)}VZ.exports=B1e});var XZ=E((nft,_Z)=>{var Q1e=KZ(),b1e=iF();function v1e(t,e){return Q1e(t,e,function(r,i){return b1e(t,i)})}_Z.exports=v1e});var $B=E((sft,ZZ)=>{function S1e(t,e){for(var r=-1,i=e.length,n=t.length;++r{var e$=ac(),x1e=Pd(),k1e=As(),t$=e$?e$.isConcatSpreadable:void 0;function P1e(t){return k1e(t)||x1e(t)||!!(t$&&t&&t[t$])}$Z.exports=P1e});var s$=E((aft,i$)=>{var D1e=$B(),R1e=r$();function n$(t,e,r,i,n){var s=-1,o=t.length;for(r||(r=R1e),n||(n=[]);++s0&&r(a)?e>1?n$(a,e-1,r,i,n):D1e(n,a):i||(n[n.length]=a)}return n}i$.exports=n$});var a$=E((Aft,o$)=>{var F1e=s$();function N1e(t){var e=t==null?0:t.length;return e?F1e(t,1):[]}o$.exports=N1e});var l$=E((lft,A$)=>{function L1e(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)}A$.exports=L1e});var nF=E((cft,c$)=>{var T1e=l$(),u$=Math.max;function M1e(t,e,r){return e=u$(e===void 0?t.length-1:e,0),function(){for(var i=arguments,n=-1,s=u$(i.length-e,0),o=Array(s);++n{function O1e(t){return function(){return t}}g$.exports=O1e});var e0=E((gft,h$)=>{function K1e(t){return t}h$.exports=K1e});var C$=E((fft,p$)=>{var U1e=f$(),d$=eF(),H1e=e0(),G1e=d$?function(t,e){return d$(t,"toString",{configurable:!0,enumerable:!1,value:U1e(e),writable:!0})}:H1e;p$.exports=G1e});var E$=E((hft,m$)=>{var j1e=800,Y1e=16,q1e=Date.now;function J1e(t){var e=0,r=0;return function(){var i=q1e(),n=Y1e-(i-r);if(r=i,n>0){if(++e>=j1e)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}m$.exports=J1e});var sF=E((pft,I$)=>{var W1e=C$(),z1e=E$(),V1e=z1e(W1e);I$.exports=V1e});var w$=E((dft,y$)=>{var _1e=a$(),X1e=nF(),Z1e=sF();function $1e(t){return Z1e(X1e(t,void 0,_1e),t+"")}y$.exports=$1e});var Q$=E((Cft,B$)=>{var eUe=XZ(),tUe=w$(),rUe=tUe(function(t,e){return t==null?{}:eUe(t,e)});B$.exports=rUe});var M$=E((lpt,N$)=>{"use strict";var pF;try{pF=Map}catch(t){}var dF;try{dF=Set}catch(t){}function L$(t,e,r){if(!t||typeof t!="object"||typeof t=="function")return t;if(t.nodeType&&"cloneNode"in t)return t.cloneNode(!0);if(t instanceof Date)return new Date(t.getTime());if(t instanceof RegExp)return new RegExp(t);if(Array.isArray(t))return t.map(T$);if(pF&&t instanceof pF)return new Map(Array.from(t.entries()));if(dF&&t instanceof dF)return new Set(Array.from(t.values()));if(t instanceof Object){e.push(t);var i=Object.create(t);r.push(i);for(var n in t){var s=e.findIndex(function(o){return o===t[n]});i[n]=s>-1?r[s]:L$(t[n],e,r)}return i}return t}function T$(t){return L$(t,[],[])}N$.exports=T$});var Nd=E(CF=>{"use strict";Object.defineProperty(CF,"__esModule",{value:!0});CF.default=uUe;var gUe=Object.prototype.toString,fUe=Error.prototype.toString,hUe=RegExp.prototype.toString,pUe=typeof Symbol!="undefined"?Symbol.prototype.toString:()=>"",dUe=/^Symbol\((.*)\)(.*)$/;function CUe(t){return t!=+t?"NaN":t===0&&1/t<0?"-0":""+t}function O$(t,e=!1){if(t==null||t===!0||t===!1)return""+t;let r=typeof t;if(r==="number")return CUe(t);if(r==="string")return e?`"${t}"`:t;if(r==="function")return"[Function "+(t.name||"anonymous")+"]";if(r==="symbol")return pUe.call(t).replace(dUe,"Symbol($1)");let i=gUe.call(t).slice(8,-1);return i==="Date"?isNaN(t.getTime())?""+t:t.toISOString(t):i==="Error"||t instanceof Error?"["+fUe.call(t)+"]":i==="RegExp"?hUe.call(t):null}function uUe(t,e){let r=O$(t,e);return r!==null?r:JSON.stringify(t,function(i,n){let s=O$(this[i],e);return s!==null?s:n},2)}});var La=E(ci=>{"use strict";Object.defineProperty(ci,"__esModule",{value:!0});ci.default=ci.array=ci.object=ci.boolean=ci.date=ci.number=ci.string=ci.mixed=void 0;var K$=mUe(Nd());function mUe(t){return t&&t.__esModule?t:{default:t}}var U$={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType:({path:t,type:e,value:r,originalValue:i})=>{let n=i!=null&&i!==r,s=`${t} must be a \`${e}\` type, but the final value was: \`${(0,K$.default)(r,!0)}\``+(n?` (cast from the value \`${(0,K$.default)(i,!0)}\`).`:".");return r===null&&(s+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),s},defined:"${path} must be defined"};ci.mixed=U$;var H$={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"};ci.string=H$;var G$={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"};ci.number=G$;var j$={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"};ci.date=j$;var Y$={isValue:"${path} field must be ${value}"};ci.boolean=Y$;var q$={noUnknown:"${path} field has unspecified keys: ${unknown}"};ci.object=q$;var J$={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};ci.array=J$;var EUe=Object.assign(Object.create(null),{mixed:U$,string:H$,number:G$,date:j$,object:q$,array:J$,boolean:Y$});ci.default=EUe});var z$=E((gpt,W$)=>{var IUe=Object.prototype,yUe=IUe.hasOwnProperty;function wUe(t,e){return t!=null&&yUe.call(t,e)}W$.exports=wUe});var Ld=E((fpt,V$)=>{var BUe=z$(),QUe=rF();function bUe(t,e){return t!=null&&QUe(t,e,BUe)}V$.exports=bUe});var qg=E(n0=>{"use strict";Object.defineProperty(n0,"__esModule",{value:!0});n0.default=void 0;var vUe=t=>t&&t.__isYupSchema__;n0.default=vUe});var Z$=E(s0=>{"use strict";Object.defineProperty(s0,"__esModule",{value:!0});s0.default=void 0;var SUe=_$(Ld()),xUe=_$(qg());function _$(t){return t&&t.__esModule?t:{default:t}}var X$=class{constructor(e,r){if(this.refs=e,this.refs=e,typeof r=="function"){this.fn=r;return}if(!(0,SUe.default)(r,"is"))throw new TypeError("`is:` is required for `when()` conditions");if(!r.then&&!r.otherwise)throw new TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:i,then:n,otherwise:s}=r,o=typeof i=="function"?i:(...a)=>a.every(l=>l===i);this.fn=function(...a){let l=a.pop(),c=a.pop(),u=o(...a)?n:s;if(!!u)return typeof u=="function"?u(c):c.concat(u.resolve(l))}}resolve(e,r){let i=this.refs.map(s=>s.getValue(r==null?void 0:r.value,r==null?void 0:r.parent,r==null?void 0:r.context)),n=this.fn.apply(e,i.concat(e,r));if(n===void 0||n===e)return e;if(!(0,xUe.default)(n))throw new TypeError("conditions must return a schema object");return n.resolve(r)}},kUe=X$;s0.default=kUe});var EF=E(mF=>{"use strict";Object.defineProperty(mF,"__esModule",{value:!0});mF.default=PUe;function PUe(t){return t==null?[]:[].concat(t)}});var xc=E(o0=>{"use strict";Object.defineProperty(o0,"__esModule",{value:!0});o0.default=void 0;var DUe=$$(Nd()),RUe=$$(EF());function $$(t){return t&&t.__esModule?t:{default:t}}function IF(){return IF=Object.assign||function(t){for(var e=1;e(0,DUe.default)(r[s])):typeof e=="function"?e(r):e}static isError(e){return e&&e.name==="ValidationError"}constructor(e,r,i,n){super();this.name="ValidationError",this.value=r,this.path=i,this.type=n,this.errors=[],this.inner=[],(0,RUe.default)(e).forEach(s=>{Td.isError(s)?(this.errors.push(...s.errors),this.inner=this.inner.concat(s.inner.length?s.inner:s)):this.errors.push(s)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,Td)}};o0.default=Td});var a0=E(yF=>{"use strict";Object.defineProperty(yF,"__esModule",{value:!0});yF.default=NUe;var wF=LUe(xc());function LUe(t){return t&&t.__esModule?t:{default:t}}var TUe=t=>{let e=!1;return(...r)=>{e||(e=!0,t(...r))}};function NUe(t,e){let{endEarly:r,tests:i,args:n,value:s,errors:o,sort:a,path:l}=t,c=TUe(e),u=i.length,g=[];if(o=o||[],!u)return o.length?c(new wF.default(o,s,l)):c(null,s);for(let f=0;f{function MUe(t){return function(e,r,i){for(var n=-1,s=Object(e),o=i(e),a=o.length;a--;){var l=o[t?a:++n];if(r(s[l],l,s)===!1)break}return e}}eee.exports=MUe});var BF=E((Ipt,ree)=>{var OUe=tee(),KUe=OUe();ree.exports=KUe});var nee=E((ypt,iee)=>{function UUe(t,e){for(var r=-1,i=Array(t);++r{function HUe(){return!1}see.exports=HUe});var Od=E((Md,Jg)=>{var GUe=Ks(),jUe=oee(),aee=typeof Md=="object"&&Md&&!Md.nodeType&&Md,Aee=aee&&typeof Jg=="object"&&Jg&&!Jg.nodeType&&Jg,YUe=Aee&&Aee.exports===aee,lee=YUe?GUe.Buffer:void 0,qUe=lee?lee.isBuffer:void 0,JUe=qUe||jUe;Jg.exports=JUe});var uee=E((Bpt,cee)=>{var WUe=Ac(),zUe=ZB(),VUe=Qo(),_Ue="[object Arguments]",XUe="[object Array]",ZUe="[object Boolean]",$Ue="[object Date]",e2e="[object Error]",t2e="[object Function]",r2e="[object Map]",i2e="[object Number]",n2e="[object Object]",s2e="[object RegExp]",o2e="[object Set]",a2e="[object String]",A2e="[object WeakMap]",l2e="[object ArrayBuffer]",c2e="[object DataView]",u2e="[object Float32Array]",g2e="[object Float64Array]",f2e="[object Int8Array]",h2e="[object Int16Array]",p2e="[object Int32Array]",d2e="[object Uint8Array]",C2e="[object Uint8ClampedArray]",m2e="[object Uint16Array]",E2e="[object Uint32Array]",lr={};lr[u2e]=lr[g2e]=lr[f2e]=lr[h2e]=lr[p2e]=lr[d2e]=lr[C2e]=lr[m2e]=lr[E2e]=!0;lr[_Ue]=lr[XUe]=lr[l2e]=lr[ZUe]=lr[c2e]=lr[$Ue]=lr[e2e]=lr[t2e]=lr[r2e]=lr[i2e]=lr[n2e]=lr[s2e]=lr[o2e]=lr[a2e]=lr[A2e]=!1;function I2e(t){return VUe(t)&&zUe(t.length)&&!!lr[WUe(t)]}cee.exports=I2e});var A0=E((Qpt,gee)=>{function y2e(t){return function(e){return t(e)}}gee.exports=y2e});var l0=E((Kd,Wg)=>{var w2e=WP(),fee=typeof Kd=="object"&&Kd&&!Kd.nodeType&&Kd,Ud=fee&&typeof Wg=="object"&&Wg&&!Wg.nodeType&&Wg,B2e=Ud&&Ud.exports===fee,QF=B2e&&w2e.process,Q2e=function(){try{var t=Ud&&Ud.require&&Ud.require("util").types;return t||QF&&QF.binding&&QF.binding("util")}catch(e){}}();Wg.exports=Q2e});var c0=E((bpt,hee)=>{var b2e=uee(),v2e=A0(),pee=l0(),dee=pee&&pee.isTypedArray,S2e=dee?v2e(dee):b2e;hee.exports=S2e});var bF=E((vpt,Cee)=>{var x2e=nee(),k2e=Pd(),P2e=As(),D2e=Od(),R2e=kd(),F2e=c0(),N2e=Object.prototype,L2e=N2e.hasOwnProperty;function T2e(t,e){var r=P2e(t),i=!r&&k2e(t),n=!r&&!i&&D2e(t),s=!r&&!i&&!n&&F2e(t),o=r||i||n||s,a=o?x2e(t.length,String):[],l=a.length;for(var c in t)(e||L2e.call(t,c))&&!(o&&(c=="length"||n&&(c=="offset"||c=="parent")||s&&(c=="buffer"||c=="byteLength"||c=="byteOffset")||R2e(c,l)))&&a.push(c);return a}Cee.exports=T2e});var u0=E((Spt,mee)=>{var M2e=Object.prototype;function O2e(t){var e=t&&t.constructor,r=typeof e=="function"&&e.prototype||M2e;return t===r}mee.exports=O2e});var vF=E((xpt,Eee)=>{function K2e(t,e){return function(r){return t(e(r))}}Eee.exports=K2e});var yee=E((kpt,Iee)=>{var U2e=vF(),H2e=U2e(Object.keys,Object);Iee.exports=H2e});var Bee=E((Ppt,wee)=>{var G2e=u0(),j2e=yee(),Y2e=Object.prototype,q2e=Y2e.hasOwnProperty;function J2e(t){if(!G2e(t))return j2e(t);var e=[];for(var r in Object(t))q2e.call(t,r)&&r!="constructor"&&e.push(r);return e}wee.exports=J2e});var Hd=E((Dpt,Qee)=>{var W2e=zB(),z2e=ZB();function V2e(t){return t!=null&&z2e(t.length)&&!W2e(t)}Qee.exports=V2e});var zg=E((Rpt,bee)=>{var _2e=bF(),X2e=Bee(),Z2e=Hd();function $2e(t){return Z2e(t)?_2e(t):X2e(t)}bee.exports=$2e});var SF=E((Fpt,vee)=>{var eHe=BF(),tHe=zg();function rHe(t,e){return t&&eHe(t,e,tHe)}vee.exports=rHe});var xee=E((Npt,See)=>{var iHe=vd();function nHe(){this.__data__=new iHe,this.size=0}See.exports=nHe});var Pee=E((Lpt,kee)=>{function sHe(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}kee.exports=sHe});var Ree=E((Tpt,Dee)=>{function oHe(t){return this.__data__.get(t)}Dee.exports=oHe});var Nee=E((Mpt,Fee)=>{function aHe(t){return this.__data__.has(t)}Fee.exports=aHe});var Tee=E((Opt,Lee)=>{var AHe=vd(),lHe=VB(),cHe=_B(),uHe=200;function gHe(t,e){var r=this.__data__;if(r instanceof AHe){var i=r.__data__;if(!lHe||i.length{var fHe=vd(),hHe=xee(),pHe=Pee(),dHe=Ree(),CHe=Nee(),mHe=Tee();function Vg(t){var e=this.__data__=new fHe(t);this.size=e.size}Vg.prototype.clear=hHe;Vg.prototype.delete=pHe;Vg.prototype.get=dHe;Vg.prototype.has=CHe;Vg.prototype.set=mHe;Mee.exports=Vg});var Kee=E((Upt,Oee)=>{var EHe="__lodash_hash_undefined__";function IHe(t){return this.__data__.set(t,EHe),this}Oee.exports=IHe});var Hee=E((Hpt,Uee)=>{function yHe(t){return this.__data__.has(t)}Uee.exports=yHe});var jee=E((Gpt,Gee)=>{var wHe=_B(),BHe=Kee(),QHe=Hee();function g0(t){var e=-1,r=t==null?0:t.length;for(this.__data__=new wHe;++e{function bHe(t,e){for(var r=-1,i=t==null?0:t.length;++r{function vHe(t,e){return t.has(e)}Jee.exports=vHe});var xF=E((qpt,zee)=>{var SHe=jee(),xHe=qee(),kHe=Wee(),PHe=1,DHe=2;function RHe(t,e,r,i,n,s){var o=r&PHe,a=t.length,l=e.length;if(a!=l&&!(o&&l>a))return!1;var c=s.get(t),u=s.get(e);if(c&&u)return c==e&&u==t;var g=-1,f=!0,h=r&DHe?new SHe:void 0;for(s.set(t,e),s.set(e,t);++g{var FHe=Ks(),NHe=FHe.Uint8Array;Vee.exports=NHe});var Xee=E((Wpt,_ee)=>{function LHe(t){var e=-1,r=Array(t.size);return t.forEach(function(i,n){r[++e]=[n,i]}),r}_ee.exports=LHe});var $ee=E((zpt,Zee)=>{function THe(t){var e=-1,r=Array(t.size);return t.forEach(function(i){r[++e]=i}),r}Zee.exports=THe});var nte=E((Vpt,ete)=>{var tte=ac(),rte=kF(),MHe=Kg(),OHe=xF(),KHe=Xee(),UHe=$ee(),HHe=1,GHe=2,jHe="[object Boolean]",YHe="[object Date]",qHe="[object Error]",JHe="[object Map]",WHe="[object Number]",zHe="[object RegExp]",VHe="[object Set]",_He="[object String]",XHe="[object Symbol]",ZHe="[object ArrayBuffer]",$He="[object DataView]",ite=tte?tte.prototype:void 0,PF=ite?ite.valueOf:void 0;function eGe(t,e,r,i,n,s,o){switch(r){case $He:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case ZHe:return!(t.byteLength!=e.byteLength||!s(new rte(t),new rte(e)));case jHe:case YHe:case WHe:return MHe(+t,+e);case qHe:return t.name==e.name&&t.message==e.message;case zHe:case _He:return t==e+"";case JHe:var a=KHe;case VHe:var l=i&HHe;if(a||(a=UHe),t.size!=e.size&&!l)return!1;var c=o.get(t);if(c)return c==e;i|=GHe,o.set(t,e);var u=OHe(a(t),a(e),i,n,s,o);return o.delete(t),u;case XHe:if(PF)return PF.call(t)==PF.call(e)}return!1}ete.exports=eGe});var DF=E((_pt,ste)=>{var tGe=$B(),rGe=As();function iGe(t,e,r){var i=e(t);return rGe(t)?i:tGe(i,r(t))}ste.exports=iGe});var ate=E((Xpt,ote)=>{function nGe(t,e){for(var r=-1,i=t==null?0:t.length,n=0,s=[];++r{function sGe(){return[]}Ate.exports=sGe});var f0=E(($pt,lte)=>{var oGe=ate(),aGe=RF(),AGe=Object.prototype,lGe=AGe.propertyIsEnumerable,cte=Object.getOwnPropertySymbols,cGe=cte?function(t){return t==null?[]:(t=Object(t),oGe(cte(t),function(e){return lGe.call(t,e)}))}:aGe;lte.exports=cGe});var FF=E((edt,ute)=>{var uGe=DF(),gGe=f0(),fGe=zg();function hGe(t){return uGe(t,fGe,gGe)}ute.exports=hGe});var hte=E((tdt,gte)=>{var fte=FF(),pGe=1,dGe=Object.prototype,CGe=dGe.hasOwnProperty;function mGe(t,e,r,i,n,s){var o=r&pGe,a=fte(t),l=a.length,c=fte(e),u=c.length;if(l!=u&&!o)return!1;for(var g=l;g--;){var f=a[g];if(!(o?f in e:CGe.call(e,f)))return!1}var h=s.get(t),p=s.get(e);if(h&&p)return h==e&&p==t;var d=!0;s.set(t,e),s.set(e,t);for(var m=o;++g{var EGe=UA(),IGe=Ks(),yGe=EGe(IGe,"DataView");pte.exports=yGe});var mte=E((idt,Cte)=>{var wGe=UA(),BGe=Ks(),QGe=wGe(BGe,"Promise");Cte.exports=QGe});var Ite=E((ndt,Ete)=>{var bGe=UA(),vGe=Ks(),SGe=bGe(vGe,"Set");Ete.exports=SGe});var wte=E((sdt,yte)=>{var xGe=UA(),kGe=Ks(),PGe=xGe(kGe,"WeakMap");yte.exports=PGe});var jd=E((odt,Bte)=>{var NF=dte(),LF=VB(),TF=mte(),MF=Ite(),OF=wte(),Qte=Ac(),_g=ZR(),bte="[object Map]",DGe="[object Object]",vte="[object Promise]",Ste="[object Set]",xte="[object WeakMap]",kte="[object DataView]",RGe=_g(NF),FGe=_g(LF),NGe=_g(TF),LGe=_g(MF),TGe=_g(OF),kc=Qte;(NF&&kc(new NF(new ArrayBuffer(1)))!=kte||LF&&kc(new LF)!=bte||TF&&kc(TF.resolve())!=vte||MF&&kc(new MF)!=Ste||OF&&kc(new OF)!=xte)&&(kc=function(t){var e=Qte(t),r=e==DGe?t.constructor:void 0,i=r?_g(r):"";if(i)switch(i){case RGe:return kte;case FGe:return bte;case NGe:return vte;case LGe:return Ste;case TGe:return xte}return e});Bte.exports=kc});var Mte=E((adt,Pte)=>{var KF=Gd(),MGe=xF(),OGe=nte(),KGe=hte(),Dte=jd(),Rte=As(),Fte=Od(),UGe=c0(),HGe=1,Nte="[object Arguments]",Lte="[object Array]",h0="[object Object]",GGe=Object.prototype,Tte=GGe.hasOwnProperty;function jGe(t,e,r,i,n,s){var o=Rte(t),a=Rte(e),l=o?Lte:Dte(t),c=a?Lte:Dte(e);l=l==Nte?h0:l,c=c==Nte?h0:c;var u=l==h0,g=c==h0,f=l==c;if(f&&Fte(t)){if(!Fte(e))return!1;o=!0,u=!1}if(f&&!u)return s||(s=new KF),o||UGe(t)?MGe(t,e,r,i,n,s):OGe(t,e,l,r,i,n,s);if(!(r&HGe)){var h=u&&Tte.call(t,"__wrapped__"),p=g&&Tte.call(e,"__wrapped__");if(h||p){var d=h?t.value():t,m=p?e.value():e;return s||(s=new KF),n(d,m,r,i,s)}}return f?(s||(s=new KF),KGe(t,e,r,i,n,s)):!1}Pte.exports=jGe});var UF=E((Adt,Ote)=>{var YGe=Mte(),Kte=Qo();function Ute(t,e,r,i,n){return t===e?!0:t==null||e==null||!Kte(t)&&!Kte(e)?t!==t&&e!==e:YGe(t,e,r,i,Ute,n)}Ote.exports=Ute});var Gte=E((ldt,Hte)=>{var qGe=Gd(),JGe=UF(),WGe=1,zGe=2;function VGe(t,e,r,i){var n=r.length,s=n,o=!i;if(t==null)return!s;for(t=Object(t);n--;){var a=r[n];if(o&&a[2]?a[1]!==t[a[0]]:!(a[0]in t))return!1}for(;++n{var _Ge=Gs();function XGe(t){return t===t&&!_Ge(t)}jte.exports=XGe});var qte=E((udt,Yte)=>{var ZGe=HF(),$Ge=zg();function eje(t){for(var e=$Ge(t),r=e.length;r--;){var i=e[r],n=t[i];e[r]=[i,n,ZGe(n)]}return e}Yte.exports=eje});var GF=E((gdt,Jte)=>{function tje(t,e){return function(r){return r==null?!1:r[t]===e&&(e!==void 0||t in Object(r))}}Jte.exports=tje});var zte=E((fdt,Wte)=>{var rje=Gte(),ije=qte(),nje=GF();function sje(t){var e=ije(t);return e.length==1&&e[0][2]?nje(e[0][0],e[0][1]):function(r){return r===t||rje(r,t,e)}}Wte.exports=sje});var p0=E((hdt,Vte)=>{var oje=xd();function aje(t,e,r){var i=t==null?void 0:oje(t,e);return i===void 0?r:i}Vte.exports=aje});var Xte=E((pdt,_te)=>{var Aje=UF(),lje=p0(),cje=iF(),uje=WB(),gje=HF(),fje=GF(),hje=Sc(),pje=1,dje=2;function Cje(t,e){return uje(t)&&gje(e)?fje(hje(t),e):function(r){var i=lje(r,t);return i===void 0&&i===e?cje(r,t):Aje(e,i,pje|dje)}}_te.exports=Cje});var $te=E((ddt,Zte)=>{function mje(t){return function(e){return e==null?void 0:e[t]}}Zte.exports=mje});var tre=E((Cdt,ere)=>{var Eje=xd();function Ije(t){return function(e){return Eje(e,t)}}ere.exports=Ije});var ire=E((mdt,rre)=>{var yje=$te(),wje=tre(),Bje=WB(),Qje=Sc();function bje(t){return Bje(t)?yje(Qje(t)):wje(t)}rre.exports=bje});var jF=E((Edt,nre)=>{var vje=zte(),Sje=Xte(),xje=e0(),kje=As(),Pje=ire();function Dje(t){return typeof t=="function"?t:t==null?xje:typeof t=="object"?kje(t)?Sje(t[0],t[1]):vje(t):Pje(t)}nre.exports=Dje});var YF=E((Idt,sre)=>{var Rje=jg(),Fje=SF(),Nje=jF();function Lje(t,e){var r={};return e=Nje(e,3),Fje(t,function(i,n,s){Rje(r,n,e(i,n,s))}),r}sre.exports=Lje});var Yd=E((ydt,ore)=>{"use strict";function Pc(t){this._maxSize=t,this.clear()}Pc.prototype.clear=function(){this._size=0,this._values=Object.create(null)};Pc.prototype.get=function(t){return this._values[t]};Pc.prototype.set=function(t,e){return this._size>=this._maxSize&&this.clear(),t in this._values||this._size++,this._values[t]=e};var Tje=/[^.^\]^[]+|(?=\[\]|\.\.)/g,are=/^\d+$/,Mje=/^\d/,Oje=/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,Kje=/^\s*(['"]?)(.*?)(\1)\s*$/,qF=512,Are=new Pc(qF),lre=new Pc(qF),cre=new Pc(qF);ore.exports={Cache:Pc,split:WF,normalizePath:JF,setter:function(t){var e=JF(t);return lre.get(t)||lre.set(t,function(i,n){for(var s=0,o=e.length,a=i;s{"use strict";Object.defineProperty(qd,"__esModule",{value:!0});qd.create=Yje;qd.default=void 0;var qje=Yd(),d0={context:"$",value:"."};function Yje(t,e){return new C0(t,e)}var C0=class{constructor(e,r={}){if(typeof e!="string")throw new TypeError("ref must be a string, got: "+e);if(this.key=e.trim(),e==="")throw new TypeError("ref must be a non-empty string");this.isContext=this.key[0]===d0.context,this.isValue=this.key[0]===d0.value,this.isSibling=!this.isContext&&!this.isValue;let i=this.isContext?d0.context:this.isValue?d0.value:"";this.path=this.key.slice(i.length),this.getter=this.path&&(0,qje.getter)(this.path,!0),this.map=r.map}getValue(e,r,i){let n=this.isContext?i:this.isValue?e:r;return this.getter&&(n=this.getter(n||{})),this.map&&(n=this.map(n)),n}cast(e,r){return this.getValue(e,r==null?void 0:r.parent,r==null?void 0:r.context)}resolve(){return this}describe(){return{type:"ref",key:this.key}}toString(){return`Ref(${this.key})`}static isRef(e){return e&&e.__isYupRef}};qd.default=C0;C0.prototype.__isYupRef=!0});var ure=E(VF=>{"use strict";Object.defineProperty(VF,"__esModule",{value:!0});VF.default=Jje;var Wje=_F(YF()),m0=_F(xc()),zje=_F(Dc());function _F(t){return t&&t.__esModule?t:{default:t}}function E0(){return E0=Object.assign||function(t){for(var e=1;e=0)&&(r[n]=t[n]);return r}function Jje(t){function e(r,i){let{value:n,path:s="",label:o,options:a,originalValue:l,sync:c}=r,u=Vje(r,["value","path","label","options","originalValue","sync"]),{name:g,test:f,params:h,message:p}=t,{parent:d,context:m}=a;function I(L){return zje.default.isRef(L)?L.getValue(n,d,m):L}function B(L={}){let K=(0,Wje.default)(E0({value:n,originalValue:l,label:o,path:L.path||s},h,L.params),I),J=new m0.default(m0.default.formatError(L.message||p,K),n,K.path,L.type||g);return J.params=K,J}let b=E0({path:s,parent:d,type:g,createError:B,resolve:I,options:a,originalValue:l},u);if(!c){try{Promise.resolve(f.call(b,n,b)).then(L=>{m0.default.isError(L)?i(L):L?i(null,L):i(B())})}catch(L){i(L)}return}let R;try{var H;if(R=f.call(b,n,b),typeof((H=R)==null?void 0:H.then)=="function")throw new Error(`Validation test of type: "${b.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(L){i(L);return}m0.default.isError(R)?i(R):R?i(null,R):i(B())}return e.OPTIONS=t,e}});var XF=E(Jd=>{"use strict";Object.defineProperty(Jd,"__esModule",{value:!0});Jd.getIn=gre;Jd.default=void 0;var _je=Yd(),Xje=t=>t.substr(0,t.length-1).substr(1);function gre(t,e,r,i=r){let n,s,o;return e?((0,_je.forEach)(e,(a,l,c)=>{let u=l?Xje(a):a;if(t=t.resolve({context:i,parent:n,value:r}),t.innerType){let g=c?parseInt(u,10):0;if(r&&g>=r.length)throw new Error(`Yup.reach cannot resolve an array item at index: ${a}, in the path: ${e}. because there is no value at that index. `);n=r,r=r&&r[g],t=t.innerType}if(!c){if(!t.fields||!t.fields[u])throw new Error(`The schema does not contain the path: ${e}. (failed at: ${o} which is a type: "${t._type}")`);n=r,r=r&&r[u],t=t.fields[u]}s=u,o=l?"["+a+"]":"."+a}),{schema:t,parent:n,parentPath:s}):{parent:n,parentPath:e,schema:t}}var Zje=(t,e,r,i)=>gre(t,e,r,i).schema,$je=Zje;Jd.default=$je});var hre=E(I0=>{"use strict";Object.defineProperty(I0,"__esModule",{value:!0});I0.default=void 0;var fre=eYe(Dc());function eYe(t){return t&&t.__esModule?t:{default:t}}var y0=class{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let r of this.list)e.push(r);for(let[,r]of this.refs)e.push(r.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){fre.default.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){fre.default.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,r){if(this.list.has(e))return!0;let i,n=this.refs.values();for(;i=n.next(),!i.done;)if(r(i.value)===e)return!0;return!1}clone(){let e=new y0;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,r){let i=this.clone();return e.list.forEach(n=>i.add(n)),e.refs.forEach(n=>i.add(n)),r.list.forEach(n=>i.delete(n)),r.refs.forEach(n=>i.delete(n)),i}};I0.default=y0});var Ma=E(w0=>{"use strict";Object.defineProperty(w0,"__esModule",{value:!0});w0.default=void 0;var pre=Ta(M$()),Xg=La(),tYe=Ta(Z$()),dre=Ta(a0()),B0=Ta(ure()),Cre=Ta(Nd()),rYe=Ta(Dc()),iYe=XF(),nYe=Ta(EF()),mre=Ta(xc()),Ere=Ta(hre());function Ta(t){return t&&t.__esModule?t:{default:t}}function ds(){return ds=Object.assign||function(t){for(var e=1;e{this.typeError(Xg.mixed.notType)}),this.type=(e==null?void 0:e.type)||"mixed",this.spec=ds({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},e==null?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let r=Object.create(Object.getPrototypeOf(this));return r.type=this.type,r._typeError=this._typeError,r._whitelistError=this._whitelistError,r._blacklistError=this._blacklistError,r._whitelist=this._whitelist.clone(),r._blacklist=this._blacklist.clone(),r.exclusiveTests=ds({},this.exclusiveTests),r.deps=[...this.deps],r.conditions=[...this.conditions],r.tests=[...this.tests],r.transforms=[...this.transforms],r.spec=(0,pre.default)(ds({},this.spec,e)),r}label(e){var r=this.clone();return r.spec.label=e,r}meta(...e){if(e.length===0)return this.spec.meta;let r=this.clone();return r.spec.meta=Object.assign(r.spec.meta||{},e[0]),r}withMutation(e){let r=this._mutate;this._mutate=!0;let i=e(this);return this._mutate=r,i}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&this.type!=="mixed")throw new TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let r=this,i=e.clone(),n=ds({},r.spec,i.spec);return i.spec=n,i._typeError||(i._typeError=r._typeError),i._whitelistError||(i._whitelistError=r._whitelistError),i._blacklistError||(i._blacklistError=r._blacklistError),i._whitelist=r._whitelist.merge(e._whitelist,e._blacklist),i._blacklist=r._blacklist.merge(e._blacklist,e._whitelist),i.tests=r.tests,i.exclusiveTests=r.exclusiveTests,i.withMutation(s=>{e.tests.forEach(o=>{s.test(o.OPTIONS)})}),i}isType(e){return this.spec.nullable&&e===null?!0:this._typeCheck(e)}resolve(e){let r=this;if(r.conditions.length){let i=r.conditions;r=r.clone(),r.conditions=[],r=i.reduce((n,s)=>s.resolve(n,e),r),r=r.resolve(e)}return r}cast(e,r={}){let i=this.resolve(ds({value:e},r)),n=i._cast(e,r);if(e!==void 0&&r.assert!==!1&&i.isType(n)!==!0){let s=(0,Cre.default)(e),o=(0,Cre.default)(n);throw new TypeError(`The value of ${r.path||"field"} could not be cast to a value that satisfies the schema type: "${i._type}". + +attempted value: ${s} +`+(o!==s?`result of cast: ${o}`:""))}return n}_cast(e,r){let i=e===void 0?e:this.transforms.reduce((n,s)=>s.call(this,n,e,this),e);return i===void 0&&(i=this.getDefault()),i}_validate(e,r={},i){let{sync:n,path:s,from:o=[],originalValue:a=e,strict:l=this.spec.strict,abortEarly:c=this.spec.abortEarly}=r,u=e;l||(u=this._cast(u,ds({assert:!1},r)));let g={value:u,path:s,options:r,originalValue:a,schema:this,label:this.spec.label,sync:n,from:o},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),(0,dre.default)({args:g,value:u,path:s,sync:n,tests:f,endEarly:c},h=>{if(h)return void i(h,u);(0,dre.default)({tests:this.tests,args:g,path:s,sync:n,value:u,endEarly:c},i)})}validate(e,r,i){let n=this.resolve(ds({},r,{value:e}));return typeof i=="function"?n._validate(e,r,i):new Promise((s,o)=>n._validate(e,r,(a,l)=>{a?o(a):s(l)}))}validateSync(e,r){let i=this.resolve(ds({},r,{value:e})),n;return i._validate(e,ds({},r,{sync:!0}),(s,o)=>{if(s)throw s;n=o}),n}isValid(e,r){return this.validate(e,r).then(()=>!0,i=>{if(mre.default.isError(i))return!1;throw i})}isValidSync(e,r){try{return this.validateSync(e,r),!0}catch(i){if(mre.default.isError(i))return!1;throw i}}_getDefault(){let e=this.spec.default;return e==null?e:typeof e=="function"?e.call(this):(0,pre.default)(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return arguments.length===0?this._getDefault():this.clone({default:e})}strict(e=!0){var r=this.clone();return r.spec.strict=e,r}_isPresent(e){return e!=null}defined(e=Xg.mixed.defined){return this.test({message:e,name:"defined",exclusive:!0,test(r){return r!==void 0}})}required(e=Xg.mixed.required){return this.clone({presence:"required"}).withMutation(r=>r.test({message:e,name:"required",exclusive:!0,test(i){return this.schema._isPresent(i)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(r=>r.OPTIONS.name!=="required"),e}nullable(e=!0){var r=this.clone({nullable:e!==!1});return r}transform(e){var r=this.clone();return r.transforms.push(e),r}test(...e){let r;if(e.length===1?typeof e[0]=="function"?r={test:e[0]}:r=e[0]:e.length===2?r={name:e[0],test:e[1]}:r={name:e[0],message:e[1],test:e[2]},r.message===void 0&&(r.message=Xg.mixed.default),typeof r.test!="function")throw new TypeError("`test` is a required parameters");let i=this.clone(),n=(0,B0.default)(r),s=r.exclusive||r.name&&i.exclusiveTests[r.name]===!0;if(r.exclusive&&!r.name)throw new TypeError("Exclusive tests must provide a unique `name` identifying the test");return r.name&&(i.exclusiveTests[r.name]=!!r.exclusive),i.tests=i.tests.filter(o=>!(o.OPTIONS.name===r.name&&(s||o.OPTIONS.test===n.OPTIONS.test))),i.tests.push(n),i}when(e,r){!Array.isArray(e)&&typeof e!="string"&&(r=e,e=".");let i=this.clone(),n=(0,nYe.default)(e).map(s=>new rYe.default(s));return n.forEach(s=>{s.isSibling&&i.deps.push(s.key)}),i.conditions.push(new tYe.default(n,r)),i}typeError(e){var r=this.clone();return r._typeError=(0,B0.default)({message:e,name:"typeError",test(i){return i!==void 0&&!this.schema.isType(i)?this.createError({params:{type:this.schema._type}}):!0}}),r}oneOf(e,r=Xg.mixed.oneOf){var i=this.clone();return e.forEach(n=>{i._whitelist.add(n),i._blacklist.delete(n)}),i._whitelistError=(0,B0.default)({message:r,name:"oneOf",test(n){if(n===void 0)return!0;let s=this.schema._whitelist;return s.has(n,this.resolve)?!0:this.createError({params:{values:s.toArray().join(", ")}})}}),i}notOneOf(e,r=Xg.mixed.notOneOf){var i=this.clone();return e.forEach(n=>{i._blacklist.add(n),i._whitelist.delete(n)}),i._blacklistError=(0,B0.default)({message:r,name:"notOneOf",test(n){let s=this.schema._blacklist;return s.has(n,this.resolve)?this.createError({params:{values:s.toArray().join(", ")}}):!0}}),i}strip(e=!0){let r=this.clone();return r.spec.strip=e,r}describe(){let e=this.clone(),{label:r,meta:i}=e.spec;return{meta:i,label:r,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(s=>({name:s.OPTIONS.name,params:s.OPTIONS.params})).filter((s,o,a)=>a.findIndex(l=>l.name===s.name)===o)}}};w0.default=Do;Do.prototype.__isYupSchema__=!0;for(let t of["validate","validateSync"])Do.prototype[`${t}At`]=function(e,r,i={}){let{parent:n,parentPath:s,schema:o}=(0,iYe.getIn)(this,e,r,i.context);return o[t](n&&n[s],ds({},i,{parent:n,path:e}))};for(let t of["equals","is"])Do.prototype[t]=Do.prototype.oneOf;for(let t of["not","nope"])Do.prototype[t]=Do.prototype.notOneOf;Do.prototype.optional=Do.prototype.notRequired});var yre=E(Wd=>{"use strict";Object.defineProperty(Wd,"__esModule",{value:!0});Wd.create=Ire;Wd.default=void 0;var oYe=sYe(Ma());function sYe(t){return t&&t.__esModule?t:{default:t}}var ZF=oYe.default,aYe=ZF;Wd.default=aYe;function Ire(){return new ZF}Ire.prototype=ZF.prototype});var Zg=E(Q0=>{"use strict";Object.defineProperty(Q0,"__esModule",{value:!0});Q0.default=void 0;var AYe=t=>t==null;Q0.default=AYe});var vre=E(zd=>{"use strict";Object.defineProperty(zd,"__esModule",{value:!0});zd.create=wre;zd.default=void 0;var lYe=Bre(Ma()),Qre=La(),bre=Bre(Zg());function Bre(t){return t&&t.__esModule?t:{default:t}}function wre(){return new b0}var b0=class extends lYe.default{constructor(){super({type:"boolean"});this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),typeof e=="boolean"}isTrue(e=Qre.boolean.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test(r){return(0,bre.default)(r)||r===!0}})}isFalse(e=Qre.boolean.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test(r){return(0,bre.default)(r)||r===!1}})}};zd.default=b0;wre.prototype=b0.prototype});var kre=E(Vd=>{"use strict";Object.defineProperty(Vd,"__esModule",{value:!0});Vd.create=Sre;Vd.default=void 0;var Ro=La(),Oa=xre(Zg()),cYe=xre(Ma());function xre(t){return t&&t.__esModule?t:{default:t}}var uYe=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,gYe=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,fYe=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,hYe=t=>(0,Oa.default)(t)||t===t.trim(),pYe={}.toString();function Sre(){return new v0}var v0=class extends cYe.default{constructor(){super({type:"string"});this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let r=e!=null&&e.toString?e.toString():e;return r===pYe?e:r})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),typeof e=="string"}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,r=Ro.string.length){return this.test({message:r,name:"length",exclusive:!0,params:{length:e},test(i){return(0,Oa.default)(i)||i.length===this.resolve(e)}})}min(e,r=Ro.string.min){return this.test({message:r,name:"min",exclusive:!0,params:{min:e},test(i){return(0,Oa.default)(i)||i.length>=this.resolve(e)}})}max(e,r=Ro.string.max){return this.test({name:"max",exclusive:!0,message:r,params:{max:e},test(i){return(0,Oa.default)(i)||i.length<=this.resolve(e)}})}matches(e,r){let i=!1,n,s;return r&&(typeof r=="object"?{excludeEmptyString:i=!1,message:n,name:s}=r:n=r),this.test({name:s||"matches",message:n||Ro.string.matches,params:{regex:e},test:o=>(0,Oa.default)(o)||o===""&&i||o.search(e)!==-1})}email(e=Ro.string.email){return this.matches(uYe,{name:"email",message:e,excludeEmptyString:!0})}url(e=Ro.string.url){return this.matches(gYe,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=Ro.string.uuid){return this.matches(fYe,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>e===null?"":e)}trim(e=Ro.string.trim){return this.transform(r=>r!=null?r.trim():r).test({message:e,name:"trim",test:hYe})}lowercase(e=Ro.string.lowercase){return this.transform(r=>(0,Oa.default)(r)?r:r.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:r=>(0,Oa.default)(r)||r===r.toLowerCase()})}uppercase(e=Ro.string.uppercase){return this.transform(r=>(0,Oa.default)(r)?r:r.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:r=>(0,Oa.default)(r)||r===r.toUpperCase()})}};Vd.default=v0;Sre.prototype=v0.prototype});var Rre=E(_d=>{"use strict";Object.defineProperty(_d,"__esModule",{value:!0});_d.create=Pre;_d.default=void 0;var Rc=La(),Fc=Dre(Zg()),dYe=Dre(Ma());function Dre(t){return t&&t.__esModule?t:{default:t}}var CYe=t=>t!=+t;function Pre(){return new S0}var S0=class extends dYe.default{constructor(){super({type:"number"});this.withMutation(()=>{this.transform(function(e){let r=e;if(typeof r=="string"){if(r=r.replace(/\s/g,""),r==="")return NaN;r=+r}return this.isType(r)?r:parseFloat(r)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),typeof e=="number"&&!CYe(e)}min(e,r=Rc.number.min){return this.test({message:r,name:"min",exclusive:!0,params:{min:e},test(i){return(0,Fc.default)(i)||i>=this.resolve(e)}})}max(e,r=Rc.number.max){return this.test({message:r,name:"max",exclusive:!0,params:{max:e},test(i){return(0,Fc.default)(i)||i<=this.resolve(e)}})}lessThan(e,r=Rc.number.lessThan){return this.test({message:r,name:"max",exclusive:!0,params:{less:e},test(i){return(0,Fc.default)(i)||ithis.resolve(e)}})}positive(e=Rc.number.positive){return this.moreThan(0,e)}negative(e=Rc.number.negative){return this.lessThan(0,e)}integer(e=Rc.number.integer){return this.test({name:"integer",message:e,test:r=>(0,Fc.default)(r)||Number.isInteger(r)})}truncate(){return this.transform(e=>(0,Fc.default)(e)?e:e|0)}round(e){var r,i=["ceil","floor","round","trunc"];if(e=((r=e)==null?void 0:r.toLowerCase())||"round",e==="trunc")return this.truncate();if(i.indexOf(e.toLowerCase())===-1)throw new TypeError("Only valid options for round() are: "+i.join(", "));return this.transform(n=>(0,Fc.default)(n)?n:Math[e](n))}};_d.default=S0;Pre.prototype=S0.prototype});var Fre=E($F=>{"use strict";Object.defineProperty($F,"__esModule",{value:!0});$F.default=mYe;var EYe=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function mYe(t){var e=[1,4,5,6,7,10,11],r=0,i,n;if(n=EYe.exec(t)){for(var s=0,o;o=e[s];++s)n[o]=+n[o]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(n[8]===void 0||n[8]==="")&&(n[9]===void 0||n[9]==="")?i=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):(n[8]!=="Z"&&n[9]!==void 0&&(r=n[10]*60+n[11],n[9]==="+"&&(r=0-r)),i=Date.UTC(n[1],n[2],n[3],n[4],n[5]+r,n[6],n[7]))}else i=Date.parse?Date.parse(t):NaN;return i}});var Tre=E(Xd=>{"use strict";Object.defineProperty(Xd,"__esModule",{value:!0});Xd.create=eN;Xd.default=void 0;var IYe=x0(Fre()),Nre=La(),Lre=x0(Zg()),yYe=x0(Dc()),wYe=x0(Ma());function x0(t){return t&&t.__esModule?t:{default:t}}var tN=new Date(""),BYe=t=>Object.prototype.toString.call(t)==="[object Date]";function eN(){return new Zd}var Zd=class extends wYe.default{constructor(){super({type:"date"});this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=(0,IYe.default)(e),isNaN(e)?tN:new Date(e))})})}_typeCheck(e){return BYe(e)&&!isNaN(e.getTime())}prepareParam(e,r){let i;if(yYe.default.isRef(e))i=e;else{let n=this.cast(e);if(!this._typeCheck(n))throw new TypeError(`\`${r}\` must be a Date or a value that can be \`cast()\` to a Date`);i=n}return i}min(e,r=Nre.date.min){let i=this.prepareParam(e,"min");return this.test({message:r,name:"min",exclusive:!0,params:{min:e},test(n){return(0,Lre.default)(n)||n>=this.resolve(i)}})}max(e,r=Nre.date.max){var i=this.prepareParam(e,"max");return this.test({message:r,name:"max",exclusive:!0,params:{max:e},test(n){return(0,Lre.default)(n)||n<=this.resolve(i)}})}};Xd.default=Zd;Zd.INVALID_DATE=tN;eN.prototype=Zd.prototype;eN.INVALID_DATE=tN});var Ore=E((Ndt,Mre)=>{function QYe(t,e,r,i){var n=-1,s=t==null?0:t.length;for(i&&s&&(r=t[++n]);++n{function bYe(t){return function(e){return t==null?void 0:t[e]}}Kre.exports=bYe});var Gre=E((Tdt,Hre)=>{var vYe=Ure(),SYe={\u00C0:"A",\u00C1:"A",\u00C2:"A",\u00C3:"A",\u00C4:"A",\u00C5:"A",\u00E0:"a",\u00E1:"a",\u00E2:"a",\u00E3:"a",\u00E4:"a",\u00E5:"a",\u00C7:"C",\u00E7:"c",\u00D0:"D",\u00F0:"d",\u00C8:"E",\u00C9:"E",\u00CA:"E",\u00CB:"E",\u00E8:"e",\u00E9:"e",\u00EA:"e",\u00EB:"e",\u00CC:"I",\u00CD:"I",\u00CE:"I",\u00CF:"I",\u00EC:"i",\u00ED:"i",\u00EE:"i",\u00EF:"i",\u00D1:"N",\u00F1:"n",\u00D2:"O",\u00D3:"O",\u00D4:"O",\u00D5:"O",\u00D6:"O",\u00D8:"O",\u00F2:"o",\u00F3:"o",\u00F4:"o",\u00F5:"o",\u00F6:"o",\u00F8:"o",\u00D9:"U",\u00DA:"U",\u00DB:"U",\u00DC:"U",\u00F9:"u",\u00FA:"u",\u00FB:"u",\u00FC:"u",\u00DD:"Y",\u00FD:"y",\u00FF:"y",\u00C6:"Ae",\u00E6:"ae",\u00DE:"Th",\u00FE:"th",\u00DF:"ss",\u0100:"A",\u0102:"A",\u0104:"A",\u0101:"a",\u0103:"a",\u0105:"a",\u0106:"C",\u0108:"C",\u010A:"C",\u010C:"C",\u0107:"c",\u0109:"c",\u010B:"c",\u010D:"c",\u010E:"D",\u0110:"D",\u010F:"d",\u0111:"d",\u0112:"E",\u0114:"E",\u0116:"E",\u0118:"E",\u011A:"E",\u0113:"e",\u0115:"e",\u0117:"e",\u0119:"e",\u011B:"e",\u011C:"G",\u011E:"G",\u0120:"G",\u0122:"G",\u011D:"g",\u011F:"g",\u0121:"g",\u0123:"g",\u0124:"H",\u0126:"H",\u0125:"h",\u0127:"h",\u0128:"I",\u012A:"I",\u012C:"I",\u012E:"I",\u0130:"I",\u0129:"i",\u012B:"i",\u012D:"i",\u012F:"i",\u0131:"i",\u0134:"J",\u0135:"j",\u0136:"K",\u0137:"k",\u0138:"k",\u0139:"L",\u013B:"L",\u013D:"L",\u013F:"L",\u0141:"L",\u013A:"l",\u013C:"l",\u013E:"l",\u0140:"l",\u0142:"l",\u0143:"N",\u0145:"N",\u0147:"N",\u014A:"N",\u0144:"n",\u0146:"n",\u0148:"n",\u014B:"n",\u014C:"O",\u014E:"O",\u0150:"O",\u014D:"o",\u014F:"o",\u0151:"o",\u0154:"R",\u0156:"R",\u0158:"R",\u0155:"r",\u0157:"r",\u0159:"r",\u015A:"S",\u015C:"S",\u015E:"S",\u0160:"S",\u015B:"s",\u015D:"s",\u015F:"s",\u0161:"s",\u0162:"T",\u0164:"T",\u0166:"T",\u0163:"t",\u0165:"t",\u0167:"t",\u0168:"U",\u016A:"U",\u016C:"U",\u016E:"U",\u0170:"U",\u0172:"U",\u0169:"u",\u016B:"u",\u016D:"u",\u016F:"u",\u0171:"u",\u0173:"u",\u0174:"W",\u0175:"w",\u0176:"Y",\u0177:"y",\u0178:"Y",\u0179:"Z",\u017B:"Z",\u017D:"Z",\u017A:"z",\u017C:"z",\u017E:"z",\u0132:"IJ",\u0133:"ij",\u0152:"Oe",\u0153:"oe",\u0149:"'n",\u017F:"s"},xYe=vYe(SYe);Hre.exports=xYe});var Yre=E((Mdt,jre)=>{var kYe=Gre(),PYe=gg(),DYe=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,RYe="\\u0300-\\u036f",FYe="\\ufe20-\\ufe2f",NYe="\\u20d0-\\u20ff",LYe=RYe+FYe+NYe,TYe="["+LYe+"]",MYe=RegExp(TYe,"g");function OYe(t){return t=PYe(t),t&&t.replace(DYe,kYe).replace(MYe,"")}jre.exports=OYe});var Jre=E((Odt,qre)=>{var KYe=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;function UYe(t){return t.match(KYe)||[]}qre.exports=UYe});var zre=E((Kdt,Wre)=>{var HYe=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;function GYe(t){return HYe.test(t)}Wre.exports=GYe});var fie=E((Udt,Vre)=>{var _re="\\ud800-\\udfff",jYe="\\u0300-\\u036f",YYe="\\ufe20-\\ufe2f",qYe="\\u20d0-\\u20ff",JYe=jYe+YYe+qYe,Xre="\\u2700-\\u27bf",Zre="a-z\\xdf-\\xf6\\xf8-\\xff",WYe="\\xac\\xb1\\xd7\\xf7",zYe="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",VYe="\\u2000-\\u206f",_Ye=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",$re="A-Z\\xc0-\\xd6\\xd8-\\xde",XYe="\\ufe0e\\ufe0f",eie=WYe+zYe+VYe+_Ye,tie="['\u2019]",rie="["+eie+"]",ZYe="["+JYe+"]",iie="\\d+",$Ye="["+Xre+"]",nie="["+Zre+"]",sie="[^"+_re+eie+iie+Xre+Zre+$re+"]",eqe="\\ud83c[\\udffb-\\udfff]",tqe="(?:"+ZYe+"|"+eqe+")",rqe="[^"+_re+"]",oie="(?:\\ud83c[\\udde6-\\uddff]){2}",aie="[\\ud800-\\udbff][\\udc00-\\udfff]",$g="["+$re+"]",iqe="\\u200d",Aie="(?:"+nie+"|"+sie+")",nqe="(?:"+$g+"|"+sie+")",lie="(?:"+tie+"(?:d|ll|m|re|s|t|ve))?",cie="(?:"+tie+"(?:D|LL|M|RE|S|T|VE))?",uie=tqe+"?",gie="["+XYe+"]?",sqe="(?:"+iqe+"(?:"+[rqe,oie,aie].join("|")+")"+gie+uie+")*",oqe="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",aqe="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",Aqe=gie+uie+sqe,lqe="(?:"+[$Ye,oie,aie].join("|")+")"+Aqe,cqe=RegExp([$g+"?"+nie+"+"+lie+"(?="+[rie,$g,"$"].join("|")+")",nqe+"+"+cie+"(?="+[rie,$g+Aie,"$"].join("|")+")",$g+"?"+Aie+"+"+lie,$g+"+"+cie,aqe,oqe,iie,lqe].join("|"),"g");function uqe(t){return t.match(cqe)||[]}Vre.exports=uqe});var pie=E((Hdt,hie)=>{var gqe=Jre(),fqe=zre(),hqe=gg(),pqe=fie();function dqe(t,e,r){return t=hqe(t),e=r?void 0:e,e===void 0?fqe(t)?pqe(t):gqe(t):t.match(e)||[]}hie.exports=dqe});var rN=E((Gdt,die)=>{var Cqe=Ore(),mqe=Yre(),Eqe=pie(),Iqe="['\u2019]",yqe=RegExp(Iqe,"g");function wqe(t){return function(e){return Cqe(Eqe(mqe(e).replace(yqe,"")),t,"")}}die.exports=wqe});var mie=E((jdt,Cie)=>{var Bqe=rN(),Qqe=Bqe(function(t,e,r){return t+(r?"_":"")+e.toLowerCase()});Cie.exports=Qqe});var Iie=E((Ydt,Eie)=>{var bqe=ZP(),vqe=rN(),Sqe=vqe(function(t,e,r){return e=e.toLowerCase(),t+(r?bqe(e):e)});Eie.exports=Sqe});var wie=E((qdt,yie)=>{var xqe=jg(),kqe=SF(),Pqe=jF();function Dqe(t,e){var r={};return e=Pqe(e,3),kqe(t,function(i,n,s){xqe(r,e(i,n,s),i)}),r}yie.exports=Dqe});var Qie=E((Jdt,iN)=>{iN.exports=function(t){return Bie(Rqe(t),t)};iN.exports.array=Bie;function Bie(t,e){var r=t.length,i=new Array(r),n={},s=r,o=Fqe(e),a=Nqe(t);for(e.forEach(function(c){if(!a.has(c[0])||!a.has(c[1]))throw new Error("Unknown node. There is an unknown node in the supplied edges.")});s--;)n[s]||l(t[s],s,new Set);return i;function l(c,u,g){if(g.has(c)){var f;try{f=", node was:"+JSON.stringify(c)}catch(d){f=""}throw new Error("Cyclic dependency"+f)}if(!a.has(c))throw new Error("Found unknown node. Make sure to provided all involved nodes. Unknown node: "+JSON.stringify(c));if(!n[u]){n[u]=!0;var h=o.get(c)||new Set;if(h=Array.from(h),u=h.length){g.add(c);do{var p=h[--u];l(p,a.get(p),g)}while(u);g.delete(c)}i[--r]=c}}}function Rqe(t){for(var e=new Set,r=0,i=t.length;r{"use strict";Object.defineProperty(nN,"__esModule",{value:!0});nN.default=Lqe;var Tqe=k0(Ld()),Mqe=k0(Qie()),Oqe=Yd(),Kqe=k0(Dc()),Uqe=k0(qg());function k0(t){return t&&t.__esModule?t:{default:t}}function Lqe(t,e=[]){let r=[],i=[];function n(s,o){var a=(0,Oqe.split)(s)[0];~i.indexOf(a)||i.push(a),~e.indexOf(`${o}-${a}`)||r.push([o,a])}for(let s in t)if((0,Tqe.default)(t,s)){let o=t[s];~i.indexOf(s)||i.push(s),Kqe.default.isRef(o)&&o.isSibling?n(o.path,s):(0,Uqe.default)(o)&&"deps"in o&&o.deps.forEach(a=>n(a,s))}return Mqe.default.array(i,r).reverse()}});var Sie=E(sN=>{"use strict";Object.defineProperty(sN,"__esModule",{value:!0});sN.default=Hqe;function vie(t,e){let r=Infinity;return t.some((i,n)=>{var s;if(((s=e.path)==null?void 0:s.indexOf(i))!==-1)return r=n,!0}),r}function Hqe(t){return(e,r)=>vie(t,e)-vie(t,r)}});var Nie=E($d=>{"use strict";Object.defineProperty($d,"__esModule",{value:!0});$d.create=xie;$d.default=void 0;var kie=Fo(Ld()),Pie=Fo(mie()),Gqe=Fo(Iie()),jqe=Fo(wie()),Yqe=Fo(YF()),qqe=Yd(),Die=La(),Jqe=Fo(bie()),Rie=Fo(Sie()),Wqe=Fo(a0()),zqe=Fo(xc()),oN=Fo(Ma());function Fo(t){return t&&t.__esModule?t:{default:t}}function ef(){return ef=Object.assign||function(t){for(var e=1;eObject.prototype.toString.call(t)==="[object Object]";function Vqe(t,e){let r=Object.keys(t.fields);return Object.keys(e).filter(i=>r.indexOf(i)===-1)}var _qe=(0,Rie.default)([]),P0=class extends oN.default{constructor(e){super({type:"object"});this.fields=Object.create(null),this._sortErrors=_qe,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(i){if(typeof i=="string")try{i=JSON.parse(i)}catch(n){i=null}return this.isType(i)?i:null}),e&&this.shape(e)})}_typeCheck(e){return Fie(e)||typeof e=="function"}_cast(e,r={}){var i;let n=super._cast(e,r);if(n===void 0)return this.getDefault();if(!this._typeCheck(n))return n;let s=this.fields,o=(i=r.stripUnknown)!=null?i:this.spec.noUnknown,a=this._nodes.concat(Object.keys(n).filter(g=>this._nodes.indexOf(g)===-1)),l={},c=ef({},r,{parent:l,__validating:r.__validating||!1}),u=!1;for(let g of a){let f=s[g],h=(0,kie.default)(n,g);if(f){let p,d=n[g];c.path=(r.path?`${r.path}.`:"")+g,f=f.resolve({value:d,context:r.context,parent:l});let m="spec"in f?f.spec:void 0,I=m==null?void 0:m.strict;if(m==null?void 0:m.strip){u=u||g in n;continue}p=!r.__validating||!I?f.cast(n[g],c):n[g],p!==void 0&&(l[g]=p)}else h&&!o&&(l[g]=n[g]);l[g]!==n[g]&&(u=!0)}return u?l:n}_validate(e,r={},i){let n=[],{sync:s,from:o=[],originalValue:a=e,abortEarly:l=this.spec.abortEarly,recursive:c=this.spec.recursive}=r;o=[{schema:this,value:a},...o],r.__validating=!0,r.originalValue=a,r.from=o,super._validate(e,r,(u,g)=>{if(u){if(!zqe.default.isError(u)||l)return void i(u,g);n.push(u)}if(!c||!Fie(g)){i(n[0]||null,g);return}a=a||g;let f=this._nodes.map(h=>(p,d)=>{let m=h.indexOf(".")===-1?(r.path?`${r.path}.`:"")+h:`${r.path||""}["${h}"]`,I=this.fields[h];if(I&&"validate"in I){I.validate(g[h],ef({},r,{path:m,from:o,strict:!0,parent:g,originalValue:a[h]}),d);return}d(null)});(0,Wqe.default)({sync:s,tests:f,value:g,errors:n,endEarly:l,sort:this._sortErrors,path:r.path},i)})}clone(e){let r=super.clone(e);return r.fields=ef({},this.fields),r._nodes=this._nodes,r._excludedEdges=this._excludedEdges,r._sortErrors=this._sortErrors,r}concat(e){let r=super.concat(e),i=r.fields;for(let[n,s]of Object.entries(this.fields)){let o=i[n];o===void 0?i[n]=s:o instanceof oN.default&&s instanceof oN.default&&(i[n]=s.concat(o))}return r.withMutation(()=>r.shape(i))}getDefaultFromShape(){let e={};return this._nodes.forEach(r=>{let i=this.fields[r];e[r]="default"in i?i.getDefault():void 0}),e}_getDefault(){if("default"in this.spec)return super._getDefault();if(!!this._nodes.length)return this.getDefaultFromShape()}shape(e,r=[]){let i=this.clone(),n=Object.assign(i.fields,e);if(i.fields=n,i._sortErrors=(0,Rie.default)(Object.keys(n)),r.length){Array.isArray(r[0])||(r=[r]);let s=r.map(([o,a])=>`${o}-${a}`);i._excludedEdges=i._excludedEdges.concat(s)}return i._nodes=(0,Jqe.default)(n,i._excludedEdges),i}pick(e){let r={};for(let i of e)this.fields[i]&&(r[i]=this.fields[i]);return this.clone().withMutation(i=>(i.fields={},i.shape(r)))}omit(e){let r=this.clone(),i=r.fields;r.fields={};for(let n of e)delete i[n];return r.withMutation(()=>r.shape(i))}from(e,r,i){let n=(0,qqe.getter)(e,!0);return this.transform(s=>{if(s==null)return s;let o=s;return(0,kie.default)(s,e)&&(o=ef({},s),i||delete o[e],o[r]=n(s)),o})}noUnknown(e=!0,r=Die.object.noUnknown){typeof e=="string"&&(r=e,e=!0);let i=this.test({name:"noUnknown",exclusive:!0,message:r,test(n){if(n==null)return!0;let s=Vqe(this.schema,n);return!e||s.length===0||this.createError({params:{unknown:s.join(", ")}})}});return i.spec.noUnknown=e,i}unknown(e=!0,r=Die.object.noUnknown){return this.noUnknown(!e,r)}transformKeys(e){return this.transform(r=>r&&(0,jqe.default)(r,(i,n)=>e(n)))}camelCase(){return this.transformKeys(Gqe.default)}snakeCase(){return this.transformKeys(Pie.default)}constantCase(){return this.transformKeys(e=>(0,Pie.default)(e).toUpperCase())}describe(){let e=super.describe();return e.fields=(0,Yqe.default)(this.fields,r=>r.describe()),e}};$d.default=P0;function xie(t){return new P0(t)}xie.prototype=P0.prototype});var Tie=E(eC=>{"use strict";Object.defineProperty(eC,"__esModule",{value:!0});eC.create=Lie;eC.default=void 0;var aN=tf(Zg()),Xqe=tf(qg()),Zqe=tf(Nd()),AN=La(),$qe=tf(a0()),eJe=tf(xc()),tJe=tf(Ma());function tf(t){return t&&t.__esModule?t:{default:t}}function D0(){return D0=Object.assign||function(t){for(var e=1;e{this.transform(function(r){if(typeof r=="string")try{r=JSON.parse(r)}catch(i){r=null}return this.isType(r)?r:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,r){let i=super._cast(e,r);if(!this._typeCheck(i)||!this.innerType)return i;let n=!1,s=i.map((o,a)=>{let l=this.innerType.cast(o,D0({},r,{path:`${r.path||""}[${a}]`}));return l!==o&&(n=!0),l});return n?s:i}_validate(e,r={},i){var n,s;let o=[],a=r.sync,l=r.path,c=this.innerType,u=(n=r.abortEarly)!=null?n:this.spec.abortEarly,g=(s=r.recursive)!=null?s:this.spec.recursive,f=r.originalValue!=null?r.originalValue:e;super._validate(e,r,(h,p)=>{if(h){if(!eJe.default.isError(h)||u)return void i(h,p);o.push(h)}if(!g||!c||!this._typeCheck(p)){i(o[0]||null,p);return}f=f||p;let d=new Array(p.length);for(let m=0;mc.validate(I,b,H)}(0,$qe.default)({sync:a,path:l,value:p,errors:o,endEarly:u,tests:d},i)})}clone(e){let r=super.clone(e);return r.innerType=this.innerType,r}concat(e){let r=super.concat(e);return r.innerType=this.innerType,e.innerType&&(r.innerType=r.innerType?r.innerType.concat(e.innerType):e.innerType),r}of(e){let r=this.clone();if(!(0,Xqe.default)(e))throw new TypeError("`array.of()` sub-schema must be a valid yup schema not: "+(0,Zqe.default)(e));return r.innerType=e,r}length(e,r=AN.array.length){return this.test({message:r,name:"length",exclusive:!0,params:{length:e},test(i){return(0,aN.default)(i)||i.length===this.resolve(e)}})}min(e,r){return r=r||AN.array.min,this.test({message:r,name:"min",exclusive:!0,params:{min:e},test(i){return(0,aN.default)(i)||i.length>=this.resolve(e)}})}max(e,r){return r=r||AN.array.max,this.test({message:r,name:"max",exclusive:!0,params:{max:e},test(i){return(0,aN.default)(i)||i.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,r)=>this._typeCheck(e)?e:r==null?[]:[].concat(r))}compact(e){let r=e?(i,n,s)=>!e(i,n,s):i=>!!i;return this.transform(i=>i!=null?i.filter(r):i)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}};eC.default=R0;Lie.prototype=R0.prototype});var Mie=E(tC=>{"use strict";Object.defineProperty(tC,"__esModule",{value:!0});tC.create=rJe;tC.default=void 0;var nJe=iJe(qg());function iJe(t){return t&&t.__esModule?t:{default:t}}function rJe(t){return new lN(t)}var lN=class{constructor(e){this.type="lazy",this.__isYupSchema__=!0,this._resolve=(r,i={})=>{let n=this.builder(r,i);if(!(0,nJe.default)(n))throw new TypeError("lazy() functions must return a valid schema");return n.resolve(i)},this.builder=e}resolve(e){return this._resolve(e.value,e)}cast(e,r){return this._resolve(e,r).cast(e,r)}validate(e,r,i){return this._resolve(e,r).validate(e,r,i)}validateSync(e,r){return this._resolve(e,r).validateSync(e,r)}validateAt(e,r,i){return this._resolve(r,i).validateAt(e,r,i)}validateSyncAt(e,r,i){return this._resolve(r,i).validateSyncAt(e,r,i)}describe(){return null}isValid(e,r){return this._resolve(e,r).isValid(e,r)}isValidSync(e,r){return this._resolve(e,r).isValidSync(e,r)}},sJe=lN;tC.default=sJe});var Oie=E(cN=>{"use strict";Object.defineProperty(cN,"__esModule",{value:!0});cN.default=oJe;var AJe=aJe(La());function aJe(t){return t&&t.__esModule?t:{default:t}}function oJe(t){Object.keys(t).forEach(e=>{Object.keys(t[e]).forEach(r=>{AJe.default[e][r]=t[e][r]})})}});var gN=E(cr=>{"use strict";Object.defineProperty(cr,"__esModule",{value:!0});cr.addMethod=lJe;Object.defineProperty(cr,"MixedSchema",{enumerable:!0,get:function(){return Kie.default}});Object.defineProperty(cr,"mixed",{enumerable:!0,get:function(){return Kie.create}});Object.defineProperty(cr,"BooleanSchema",{enumerable:!0,get:function(){return uN.default}});Object.defineProperty(cr,"bool",{enumerable:!0,get:function(){return uN.create}});Object.defineProperty(cr,"boolean",{enumerable:!0,get:function(){return uN.create}});Object.defineProperty(cr,"StringSchema",{enumerable:!0,get:function(){return Uie.default}});Object.defineProperty(cr,"string",{enumerable:!0,get:function(){return Uie.create}});Object.defineProperty(cr,"NumberSchema",{enumerable:!0,get:function(){return Hie.default}});Object.defineProperty(cr,"number",{enumerable:!0,get:function(){return Hie.create}});Object.defineProperty(cr,"DateSchema",{enumerable:!0,get:function(){return Gie.default}});Object.defineProperty(cr,"date",{enumerable:!0,get:function(){return Gie.create}});Object.defineProperty(cr,"ObjectSchema",{enumerable:!0,get:function(){return jie.default}});Object.defineProperty(cr,"object",{enumerable:!0,get:function(){return jie.create}});Object.defineProperty(cr,"ArraySchema",{enumerable:!0,get:function(){return Yie.default}});Object.defineProperty(cr,"array",{enumerable:!0,get:function(){return Yie.create}});Object.defineProperty(cr,"ref",{enumerable:!0,get:function(){return cJe.create}});Object.defineProperty(cr,"lazy",{enumerable:!0,get:function(){return uJe.create}});Object.defineProperty(cr,"ValidationError",{enumerable:!0,get:function(){return gJe.default}});Object.defineProperty(cr,"reach",{enumerable:!0,get:function(){return fJe.default}});Object.defineProperty(cr,"isSchema",{enumerable:!0,get:function(){return qie.default}});Object.defineProperty(cr,"setLocale",{enumerable:!0,get:function(){return hJe.default}});Object.defineProperty(cr,"BaseSchema",{enumerable:!0,get:function(){return pJe.default}});var Kie=Nc(yre()),uN=Nc(vre()),Uie=Nc(kre()),Hie=Nc(Rre()),Gie=Nc(Tre()),jie=Nc(Nie()),Yie=Nc(Tie()),cJe=Dc(),uJe=Mie(),gJe=rC(xc()),fJe=rC(XF()),qie=rC(qg()),hJe=rC(Oie()),pJe=rC(Ma());function rC(t){return t&&t.__esModule?t:{default:t}}function Jie(){if(typeof WeakMap!="function")return null;var t=new WeakMap;return Jie=function(){return t},t}function Nc(t){if(t&&t.__esModule)return t;if(t===null||typeof t!="object"&&typeof t!="function")return{default:t};var e=Jie();if(e&&e.has(t))return e.get(t);var r={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){var s=i?Object.getOwnPropertyDescriptor(t,n):null;s&&(s.get||s.set)?Object.defineProperty(r,n,s):r[n]=t[n]}return r.default=t,e&&e.set(t,r),r}function lJe(t,e,r){if(!t||!(0,qie.default)(t.prototype))throw new TypeError("You must provide a yup schema constructor function");if(typeof e!="string")throw new TypeError("A Method name must be provided");if(typeof r!="function")throw new TypeError("Method function must be provided");t.prototype[e]=r}});var Xie=E((gCt,nC)=>{"use strict";var mJe=process.env.TERM_PROGRAM==="Hyper",EJe=process.platform==="win32",zie=process.platform==="linux",fN={ballotDisabled:"\u2612",ballotOff:"\u2610",ballotOn:"\u2611",bullet:"\u2022",bulletWhite:"\u25E6",fullBlock:"\u2588",heart:"\u2764",identicalTo:"\u2261",line:"\u2500",mark:"\u203B",middot:"\xB7",minus:"\uFF0D",multiplication:"\xD7",obelus:"\xF7",pencilDownRight:"\u270E",pencilRight:"\u270F",pencilUpRight:"\u2710",percent:"%",pilcrow2:"\u2761",pilcrow:"\xB6",plusMinus:"\xB1",section:"\xA7",starsOff:"\u2606",starsOn:"\u2605",upDownArrow:"\u2195"},Vie=Object.assign({},fN,{check:"\u221A",cross:"\xD7",ellipsisLarge:"...",ellipsis:"...",info:"i",question:"?",questionSmall:"?",pointer:">",pointerSmall:"\xBB",radioOff:"( )",radioOn:"(*)",warning:"\u203C"}),_ie=Object.assign({},fN,{ballotCross:"\u2718",check:"\u2714",cross:"\u2716",ellipsisLarge:"\u22EF",ellipsis:"\u2026",info:"\u2139",question:"?",questionFull:"\uFF1F",questionSmall:"\uFE56",pointer:zie?"\u25B8":"\u276F",pointerSmall:zie?"\u2023":"\u203A",radioOff:"\u25EF",radioOn:"\u25C9",warning:"\u26A0"});nC.exports=EJe&&!mJe?Vie:_ie;Reflect.defineProperty(nC.exports,"common",{enumerable:!1,value:fN});Reflect.defineProperty(nC.exports,"windows",{enumerable:!1,value:Vie});Reflect.defineProperty(nC.exports,"other",{enumerable:!1,value:_ie})});var js=E((fCt,hN)=>{"use strict";var IJe=t=>t!==null&&typeof t=="object"&&!Array.isArray(t),yJe=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,Zie=()=>{let t={enabled:!0,visible:!0,styles:{},keys:{}};"FORCE_COLOR"in process.env&&(t.enabled=process.env.FORCE_COLOR!=="0");let e=s=>{let o=s.open=`[${s.codes[0]}m`,a=s.close=`[${s.codes[1]}m`,l=s.regex=new RegExp(`\\u001b\\[${s.codes[1]}m`,"g");return s.wrap=(c,u)=>{c.includes(a)&&(c=c.replace(l,a+o));let g=o+c+a;return u?g.replace(/\r*\n/g,`${a}$&${o}`):g},s},r=(s,o,a)=>typeof s=="function"?s(o):s.wrap(o,a),i=(s,o)=>{if(s===""||s==null)return"";if(t.enabled===!1)return s;if(t.visible===!1)return"";let a=""+s,l=a.includes(` +`),c=o.length;for(c>0&&o.includes("unstyle")&&(o=[...new Set(["unstyle",...o])].reverse());c-- >0;)a=r(t.styles[o[c]],a,l);return a},n=(s,o,a)=>{t.styles[s]=e({name:s,codes:o}),(t.keys[a]||(t.keys[a]=[])).push(s),Reflect.defineProperty(t,s,{configurable:!0,enumerable:!0,set(c){t.alias(s,c)},get(){let c=u=>i(u,c.stack);return Reflect.setPrototypeOf(c,t),c.stack=this.stack?this.stack.concat(s):[s],c}})};return n("reset",[0,0],"modifier"),n("bold",[1,22],"modifier"),n("dim",[2,22],"modifier"),n("italic",[3,23],"modifier"),n("underline",[4,24],"modifier"),n("inverse",[7,27],"modifier"),n("hidden",[8,28],"modifier"),n("strikethrough",[9,29],"modifier"),n("black",[30,39],"color"),n("red",[31,39],"color"),n("green",[32,39],"color"),n("yellow",[33,39],"color"),n("blue",[34,39],"color"),n("magenta",[35,39],"color"),n("cyan",[36,39],"color"),n("white",[37,39],"color"),n("gray",[90,39],"color"),n("grey",[90,39],"color"),n("bgBlack",[40,49],"bg"),n("bgRed",[41,49],"bg"),n("bgGreen",[42,49],"bg"),n("bgYellow",[43,49],"bg"),n("bgBlue",[44,49],"bg"),n("bgMagenta",[45,49],"bg"),n("bgCyan",[46,49],"bg"),n("bgWhite",[47,49],"bg"),n("blackBright",[90,39],"bright"),n("redBright",[91,39],"bright"),n("greenBright",[92,39],"bright"),n("yellowBright",[93,39],"bright"),n("blueBright",[94,39],"bright"),n("magentaBright",[95,39],"bright"),n("cyanBright",[96,39],"bright"),n("whiteBright",[97,39],"bright"),n("bgBlackBright",[100,49],"bgBright"),n("bgRedBright",[101,49],"bgBright"),n("bgGreenBright",[102,49],"bgBright"),n("bgYellowBright",[103,49],"bgBright"),n("bgBlueBright",[104,49],"bgBright"),n("bgMagentaBright",[105,49],"bgBright"),n("bgCyanBright",[106,49],"bgBright"),n("bgWhiteBright",[107,49],"bgBright"),t.ansiRegex=yJe,t.hasColor=t.hasAnsi=s=>(t.ansiRegex.lastIndex=0,typeof s=="string"&&s!==""&&t.ansiRegex.test(s)),t.alias=(s,o)=>{let a=typeof o=="string"?t[o]:o;if(typeof a!="function")throw new TypeError("Expected alias to be the name of an existing color (string) or a function");a.stack||(Reflect.defineProperty(a,"name",{value:s}),t.styles[s]=a,a.stack=[s]),Reflect.defineProperty(t,s,{configurable:!0,enumerable:!0,set(l){t.alias(s,l)},get(){let l=c=>i(c,l.stack);return Reflect.setPrototypeOf(l,t),l.stack=this.stack?this.stack.concat(a.stack):a.stack,l}})},t.theme=s=>{if(!IJe(s))throw new TypeError("Expected theme to be an object");for(let o of Object.keys(s))t.alias(o,s[o]);return t},t.alias("unstyle",s=>typeof s=="string"&&s!==""?(t.ansiRegex.lastIndex=0,s.replace(t.ansiRegex,"")):""),t.alias("noop",s=>s),t.none=t.clear=t.noop,t.stripColor=t.unstyle,t.symbols=Xie(),t.define=n,t};hN.exports=Zie();hN.exports.create=Zie});var Mi=E(bt=>{"use strict";var wJe=Object.prototype.toString,Cs=js(),$ie=!1,pN=[],ene={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};bt.longest=(t,e)=>t.reduce((r,i)=>Math.max(r,e?i[e].length:i.length),0);bt.hasColor=t=>!!t&&Cs.hasColor(t);var N0=bt.isObject=t=>t!==null&&typeof t=="object"&&!Array.isArray(t);bt.nativeType=t=>wJe.call(t).slice(8,-1).toLowerCase().replace(/\s/g,"");bt.isAsyncFn=t=>bt.nativeType(t)==="asyncfunction";bt.isPrimitive=t=>t!=null&&typeof t!="object"&&typeof t!="function";bt.resolve=(t,e,...r)=>typeof e=="function"?e.call(t,...r):e;bt.scrollDown=(t=[])=>[...t.slice(1),t[0]];bt.scrollUp=(t=[])=>[t.pop(),...t];bt.reorder=(t=[])=>{let e=t.slice();return e.sort((r,i)=>r.index>i.index?1:r.index{let i=t.length,n=r===i?0:r<0?i-1:r,s=t[e];t[e]=t[n],t[n]=s};bt.width=(t,e=80)=>{let r=t&&t.columns?t.columns:e;return t&&typeof t.getWindowSize=="function"&&(r=t.getWindowSize()[0]),process.platform==="win32"?r-1:r};bt.height=(t,e=20)=>{let r=t&&t.rows?t.rows:e;return t&&typeof t.getWindowSize=="function"&&(r=t.getWindowSize()[1]),r};bt.wordWrap=(t,e={})=>{if(!t)return t;typeof e=="number"&&(e={width:e});let{indent:r="",newline:i=` +`+r,width:n=80}=e;n-=((i+r).match(/[^\S\n]/g)||[]).length;let o=`.{1,${n}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,a=t.trim(),l=new RegExp(o,"g"),c=a.match(l)||[];return c=c.map(u=>u.replace(/\n$/,"")),e.padEnd&&(c=c.map(u=>u.padEnd(n," "))),e.padStart&&(c=c.map(u=>u.padStart(n," "))),r+c.join(i)};bt.unmute=t=>{let e=t.stack.find(i=>Cs.keys.color.includes(i));return e?Cs[e]:t.stack.find(i=>i.slice(2)==="bg")?Cs[e.slice(2)]:i=>i};bt.pascal=t=>t?t[0].toUpperCase()+t.slice(1):"";bt.inverse=t=>{if(!t||!t.stack)return t;let e=t.stack.find(i=>Cs.keys.color.includes(i));if(e){let i=Cs["bg"+bt.pascal(e)];return i?i.black:t}let r=t.stack.find(i=>i.slice(0,2)==="bg");return r?Cs[r.slice(2).toLowerCase()]||t:Cs.none};bt.complement=t=>{if(!t||!t.stack)return t;let e=t.stack.find(i=>Cs.keys.color.includes(i)),r=t.stack.find(i=>i.slice(0,2)==="bg");if(e&&!r)return Cs[ene[e]||e];if(r){let i=r.slice(2).toLowerCase(),n=ene[i];return n&&Cs["bg"+bt.pascal(n)]||t}return Cs.none};bt.meridiem=t=>{let e=t.getHours(),r=t.getMinutes(),i=e>=12?"pm":"am";e=e%12;let n=e===0?12:e,s=r<10?"0"+r:r;return n+":"+s+" "+i};bt.set=(t={},e="",r)=>e.split(".").reduce((i,n,s,o)=>{let a=o.length-1>s?i[n]||{}:r;return!bt.isObject(a)&&s{let i=t[e]==null?e.split(".").reduce((n,s)=>n&&n[s],t):t[e];return i==null?r:i};bt.mixin=(t,e)=>{if(!N0(t))return e;if(!N0(e))return t;for(let r of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,r);if(i.hasOwnProperty("value"))if(t.hasOwnProperty(r)&&N0(i.value)){let n=Object.getOwnPropertyDescriptor(t,r);N0(n.value)?t[r]=bt.merge({},t[r],e[r]):Reflect.defineProperty(t,r,i)}else Reflect.defineProperty(t,r,i);else Reflect.defineProperty(t,r,i)}return t};bt.merge=(...t)=>{let e={};for(let r of t)bt.mixin(e,r);return e};bt.mixinEmitter=(t,e)=>{let r=e.constructor.prototype;for(let i of Object.keys(r)){let n=r[i];typeof n=="function"?bt.define(t,i,n.bind(e)):bt.define(t,i,n)}};bt.onExit=t=>{let e=(r,i)=>{$ie||($ie=!0,pN.forEach(n=>n()),r===!0&&process.exit(128+i))};pN.length===0&&(process.once("SIGTERM",e.bind(null,!0,15)),process.once("SIGINT",e.bind(null,!0,2)),process.once("exit",e)),pN.push(t)};bt.define=(t,e,r)=>{Reflect.defineProperty(t,e,{value:r})};bt.defineExport=(t,e,r)=>{let i;Reflect.defineProperty(t,e,{enumerable:!0,configurable:!0,set(n){i=n},get(){return i?i():r()}})}});var tne=E(nf=>{"use strict";nf.ctrl={a:"first",b:"backward",c:"cancel",d:"deleteForward",e:"last",f:"forward",g:"reset",i:"tab",k:"cutForward",l:"reset",n:"newItem",m:"cancel",j:"submit",p:"search",r:"remove",s:"save",u:"undo",w:"cutLeft",x:"toggleCursor",v:"paste"};nf.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"};nf.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"};nf.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"};nf.keys={pageup:"pageUp",pagedown:"pageDown",home:"home",end:"end",cancel:"cancel",delete:"deleteForward",backspace:"delete",down:"down",enter:"submit",escape:"cancel",left:"left",space:"space",number:"number",return:"submit",right:"right",tab:"next",up:"up"}});var nne=E((dCt,rne)=>{"use strict";var ine=require("readline"),BJe=tne(),QJe=/^(?:\x1b)([a-zA-Z0-9])$/,bJe=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,vJe={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"};function SJe(t){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(t)}function xJe(t){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(t)}var L0=(t="",e={})=>{let r,i=P({name:e.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:t,raw:t},e);if(Buffer.isBuffer(t)?t[0]>127&&t[1]===void 0?(t[0]-=128,t=""+String(t)):t=String(t):t!==void 0&&typeof t!="string"?t=String(t):t||(t=i.sequence||""),i.sequence=i.sequence||t||i.name,t==="\r")i.raw=void 0,i.name="return";else if(t===` +`)i.name="enter";else if(t===" ")i.name="tab";else if(t==="\b"||t==="\x7F"||t==="\x7F"||t==="\b")i.name="backspace",i.meta=t.charAt(0)==="";else if(t===""||t==="")i.name="escape",i.meta=t.length===2;else if(t===" "||t===" ")i.name="space",i.meta=t.length===2;else if(t<="")i.name=String.fromCharCode(t.charCodeAt(0)+"a".charCodeAt(0)-1),i.ctrl=!0;else if(t.length===1&&t>="0"&&t<="9")i.name="number";else if(t.length===1&&t>="a"&&t<="z")i.name=t;else if(t.length===1&&t>="A"&&t<="Z")i.name=t.toLowerCase(),i.shift=!0;else if(r=QJe.exec(t))i.meta=!0,i.shift=/^[A-Z]$/.test(r[1]);else if(r=bJe.exec(t)){let n=[...t];n[0]===""&&n[1]===""&&(i.option=!0);let s=[r[1],r[2],r[4],r[6]].filter(Boolean).join(""),o=(r[3]||r[5]||1)-1;i.ctrl=!!(o&4),i.meta=!!(o&10),i.shift=!!(o&1),i.code=s,i.name=vJe[s],i.shift=SJe(s)||i.shift,i.ctrl=xJe(s)||i.ctrl}return i};L0.listen=(t={},e)=>{let{stdin:r}=t;if(!r||r!==process.stdin&&!r.isTTY)throw new Error("Invalid stream passed");let i=ine.createInterface({terminal:!0,input:r});ine.emitKeypressEvents(r,i);let n=(a,l)=>e(a,L0(a,l),i),s=r.isRaw;return r.isTTY&&r.setRawMode(!0),r.on("keypress",n),i.resume(),()=>{r.isTTY&&r.setRawMode(s),r.removeListener("keypress",n),i.pause(),i.close()}};L0.action=(t,e,r)=>{let i=P(P({},BJe),r);return e.ctrl?(e.action=i.ctrl[e.name],e):e.option&&i.option?(e.action=i.option[e.name],e):e.shift?(e.action=i.shift[e.name],e):(e.action=i.keys[e.name],e)};rne.exports=L0});var one=E((CCt,sne)=>{"use strict";sne.exports=t=>{t.timers=t.timers||{};let e=t.options.timers;if(!!e)for(let r of Object.keys(e)){let i=e[r];typeof i=="number"&&(i={interval:i}),kJe(t,r,i)}};function kJe(t,e,r={}){let i=t.timers[e]={name:e,start:Date.now(),ms:0,tick:0},n=r.interval||120;i.frames=r.frames||[],i.loading=!0;let s=setInterval(()=>{i.ms=Date.now()-i.start,i.tick++,t.render()},n);return i.stop=()=>{i.loading=!1,clearInterval(s)},Reflect.defineProperty(i,"interval",{value:s}),t.once("close",()=>i.stop()),i.stop}});var lne=E((mCt,ane)=>{"use strict";var{define:PJe,width:DJe}=Mi(),Ane=class{constructor(e){let r=e.options;PJe(this,"_prompt",e),this.type=e.type,this.name=e.name,this.message="",this.header="",this.footer="",this.error="",this.hint="",this.input="",this.cursor=0,this.index=0,this.lines=0,this.tick=0,this.prompt="",this.buffer="",this.width=DJe(r.stdout||process.stdout),Object.assign(this,r),this.name=this.name||this.message,this.message=this.message||this.name,this.symbols=e.symbols,this.styles=e.styles,this.required=new Set,this.cancelled=!1,this.submitted=!1}clone(){let e=P({},this);return e.status=this.status,e.buffer=Buffer.from(e.buffer),delete e.clone,e}set color(e){this._color=e}get color(){let e=this.prompt.styles;if(this.cancelled)return e.cancelled;if(this.submitted)return e.submitted;let r=this._color||e[this.status];return typeof r=="function"?r:e.pending}set loading(e){this._loading=e}get loading(){return typeof this._loading=="boolean"?this._loading:this.loadingChoices?"choices":!1}get status(){return this.cancelled?"cancelled":this.submitted?"submitted":"pending"}};ane.exports=Ane});var une=E((ECt,cne)=>{"use strict";var dN=Mi(),yi=js(),CN={default:yi.noop,noop:yi.noop,set inverse(t){this._inverse=t},get inverse(){return this._inverse||dN.inverse(this.primary)},set complement(t){this._complement=t},get complement(){return this._complement||dN.complement(this.primary)},primary:yi.cyan,success:yi.green,danger:yi.magenta,strong:yi.bold,warning:yi.yellow,muted:yi.dim,disabled:yi.gray,dark:yi.dim.gray,underline:yi.underline,set info(t){this._info=t},get info(){return this._info||this.primary},set em(t){this._em=t},get em(){return this._em||this.primary.underline},set heading(t){this._heading=t},get heading(){return this._heading||this.muted.underline},set pending(t){this._pending=t},get pending(){return this._pending||this.primary},set submitted(t){this._submitted=t},get submitted(){return this._submitted||this.success},set cancelled(t){this._cancelled=t},get cancelled(){return this._cancelled||this.danger},set typing(t){this._typing=t},get typing(){return this._typing||this.dim},set placeholder(t){this._placeholder=t},get placeholder(){return this._placeholder||this.primary.dim},set highlight(t){this._highlight=t},get highlight(){return this._highlight||this.inverse}};CN.merge=(t={})=>{t.styles&&typeof t.styles.enabled=="boolean"&&(yi.enabled=t.styles.enabled),t.styles&&typeof t.styles.visible=="boolean"&&(yi.visible=t.styles.visible);let e=dN.merge({},CN,t.styles);delete e.merge;for(let r of Object.keys(yi))e.hasOwnProperty(r)||Reflect.defineProperty(e,r,{get:()=>yi[r]});for(let r of Object.keys(yi.styles))e.hasOwnProperty(r)||Reflect.defineProperty(e,r,{get:()=>yi[r]});return e};cne.exports=CN});var fne=E((ICt,gne)=>{"use strict";var mN=process.platform==="win32",Ka=js(),RJe=Mi(),EN=_(P({},Ka.symbols),{upDownDoubleArrow:"\u21D5",upDownDoubleArrow2:"\u2B0D",upDownArrow:"\u2195",asterisk:"*",asterism:"\u2042",bulletWhite:"\u25E6",electricArrow:"\u2301",ellipsisLarge:"\u22EF",ellipsisSmall:"\u2026",fullBlock:"\u2588",identicalTo:"\u2261",indicator:Ka.symbols.check,leftAngle:"\u2039",mark:"\u203B",minus:"\u2212",multiplication:"\xD7",obelus:"\xF7",percent:"%",pilcrow:"\xB6",pilcrow2:"\u2761",pencilUpRight:"\u2710",pencilDownRight:"\u270E",pencilRight:"\u270F",plus:"+",plusMinus:"\xB1",pointRight:"\u261E",rightAngle:"\u203A",section:"\xA7",hexagon:{off:"\u2B21",on:"\u2B22",disabled:"\u2B22"},ballot:{on:"\u2611",off:"\u2610",disabled:"\u2612"},stars:{on:"\u2605",off:"\u2606",disabled:"\u2606"},folder:{on:"\u25BC",off:"\u25B6",disabled:"\u25B6"},prefix:{pending:Ka.symbols.question,submitted:Ka.symbols.check,cancelled:Ka.symbols.cross},separator:{pending:Ka.symbols.pointerSmall,submitted:Ka.symbols.middot,cancelled:Ka.symbols.middot},radio:{off:mN?"( )":"\u25EF",on:mN?"(*)":"\u25C9",disabled:mN?"(|)":"\u24BE"},numbers:["\u24EA","\u2460","\u2461","\u2462","\u2463","\u2464","\u2465","\u2466","\u2467","\u2468","\u2469","\u246A","\u246B","\u246C","\u246D","\u246E","\u246F","\u2470","\u2471","\u2472","\u2473","\u3251","\u3252","\u3253","\u3254","\u3255","\u3256","\u3257","\u3258","\u3259","\u325A","\u325B","\u325C","\u325D","\u325E","\u325F","\u32B1","\u32B2","\u32B3","\u32B4","\u32B5","\u32B6","\u32B7","\u32B8","\u32B9","\u32BA","\u32BB","\u32BC","\u32BD","\u32BE","\u32BF"]});EN.merge=t=>{let e=RJe.merge({},Ka.symbols,EN,t.symbols);return delete e.merge,e};gne.exports=EN});var pne=E((yCt,hne)=>{"use strict";var FJe=une(),NJe=fne(),LJe=Mi();hne.exports=t=>{t.options=LJe.merge({},t.options.theme,t.options),t.symbols=NJe.merge(t.options),t.styles=FJe.merge(t.options)}});var Ine=E((dne,Cne)=>{"use strict";var mne=process.env.TERM_PROGRAM==="Apple_Terminal",TJe=js(),IN=Mi(),Ys=Cne.exports=dne,Ir="[",Ene="\x07",yN=!1,HA=Ys.code={bell:Ene,beep:Ene,beginning:`${Ir}G`,down:`${Ir}J`,esc:Ir,getPosition:`${Ir}6n`,hide:`${Ir}?25l`,line:`${Ir}2K`,lineEnd:`${Ir}K`,lineStart:`${Ir}1K`,restorePosition:Ir+(mne?"8":"u"),savePosition:Ir+(mne?"7":"s"),screen:`${Ir}2J`,show:`${Ir}?25h`,up:`${Ir}1J`},Lc=Ys.cursor={get hidden(){return yN},hide(){return yN=!0,HA.hide},show(){return yN=!1,HA.show},forward:(t=1)=>`${Ir}${t}C`,backward:(t=1)=>`${Ir}${t}D`,nextLine:(t=1)=>`${Ir}E`.repeat(t),prevLine:(t=1)=>`${Ir}F`.repeat(t),up:(t=1)=>t?`${Ir}${t}A`:"",down:(t=1)=>t?`${Ir}${t}B`:"",right:(t=1)=>t?`${Ir}${t}C`:"",left:(t=1)=>t?`${Ir}${t}D`:"",to(t,e){return e?`${Ir}${e+1};${t+1}H`:`${Ir}${t+1}G`},move(t=0,e=0){let r="";return r+=t<0?Lc.left(-t):t>0?Lc.right(t):"",r+=e<0?Lc.up(-e):e>0?Lc.down(e):"",r},restore(t={}){let{after:e,cursor:r,initial:i,input:n,prompt:s,size:o,value:a}=t;if(i=IN.isPrimitive(i)?String(i):"",n=IN.isPrimitive(n)?String(n):"",a=IN.isPrimitive(a)?String(a):"",o){let l=Ys.cursor.up(o)+Ys.cursor.to(s.length),c=n.length-r;return c>0&&(l+=Ys.cursor.left(c)),l}if(a||e){let l=!n&&!!i?-i.length:-n.length+r;return e&&(l-=e.length),n===""&&i&&!s.includes(i)&&(l+=i.length),Ys.cursor.move(l)}}},wN=Ys.erase={screen:HA.screen,up:HA.up,down:HA.down,line:HA.line,lineEnd:HA.lineEnd,lineStart:HA.lineStart,lines(t){let e="";for(let r=0;r{if(!e)return wN.line+Lc.to(0);let r=s=>[...TJe.unstyle(s)].length,i=t.split(/\r?\n/),n=0;for(let s of i)n+=1+Math.floor(Math.max(r(s)-1,0)/e);return(wN.line+Lc.prevLine()).repeat(n-1)+wN.line+Lc.to(0)}});var sf=E((wCt,yne)=>{"use strict";var MJe=require("events"),wne=js(),BN=nne(),OJe=one(),KJe=lne(),UJe=pne(),bn=Mi(),Tc=Ine(),T0=class extends MJe{constructor(e={}){super();this.name=e.name,this.type=e.type,this.options=e,UJe(this),OJe(this),this.state=new KJe(this),this.initial=[e.initial,e.default].find(r=>r!=null),this.stdout=e.stdout||process.stdout,this.stdin=e.stdin||process.stdin,this.scale=e.scale||1,this.term=this.options.term||process.env.TERM_PROGRAM,this.margin=GJe(this.options.margin),this.setMaxListeners(0),HJe(this)}async keypress(e,r={}){this.keypressed=!0;let i=BN.action(e,BN(e,r),this.options.actions);this.state.keypress=i,this.emit("keypress",e,i),this.emit("state",this.state.clone());let n=this.options[i.action]||this[i.action]||this.dispatch;if(typeof n=="function")return await n.call(this,e,i);this.alert()}alert(){delete this.state.alert,this.options.show===!1?this.emit("alert"):this.stdout.write(Tc.code.beep)}cursorHide(){this.stdout.write(Tc.cursor.hide()),bn.onExit(()=>this.cursorShow())}cursorShow(){this.stdout.write(Tc.cursor.show())}write(e){!e||(this.stdout&&this.state.show!==!1&&this.stdout.write(e),this.state.buffer+=e)}clear(e=0){let r=this.state.buffer;this.state.buffer="",!(!r&&!e||this.options.show===!1)&&this.stdout.write(Tc.cursor.down(e)+Tc.clear(r,this.width))}restore(){if(this.state.closed||this.options.show===!1)return;let{prompt:e,after:r,rest:i}=this.sections(),{cursor:n,initial:s="",input:o="",value:a=""}=this,l=this.state.size=i.length,c={after:r,cursor:n,initial:s,input:o,prompt:e,size:l,value:a},u=Tc.cursor.restore(c);u&&this.stdout.write(u)}sections(){let{buffer:e,input:r,prompt:i}=this.state;i=wne.unstyle(i);let n=wne.unstyle(e),s=n.indexOf(i),o=n.slice(0,s),l=n.slice(s).split(` +`),c=l[0],u=l[l.length-1],f=(i+(r?" "+r:"")).length,h=fe.call(this,this.value),this.result=()=>i.call(this,this.value),typeof r.initial=="function"&&(this.initial=await r.initial.call(this,this)),typeof r.onRun=="function"&&await r.onRun.call(this,this),typeof r.onSubmit=="function"){let n=r.onSubmit.bind(this),s=this.submit.bind(this);delete this.options.onSubmit,this.submit=async()=>(await n(this.name,this.value,this),s())}await this.start(),await this.render()}render(){throw new Error("expected prompt to have a custom render method")}run(){return new Promise(async(e,r)=>{if(this.once("submit",e),this.once("cancel",r),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,r,i){let{options:n,state:s,symbols:o,timers:a}=this,l=a&&a[e];s.timer=l;let c=n[e]||s[e]||o[e],u=r&&r[e]!=null?r[e]:await c;if(u==="")return u;let g=await this.resolve(u,s,r,i);return!g&&r&&r[e]?this.resolve(c,s,r,i):g}async prefix(){let e=await this.element("prefix")||this.symbols,r=this.timers&&this.timers.prefix,i=this.state;return i.timer=r,bn.isObject(e)&&(e=e[i.status]||e.pending),bn.hasColor(e)?e:(this.styles[i.status]||this.styles.pending)(e)}async message(){let e=await this.element("message");return bn.hasColor(e)?e:this.styles.strong(e)}async separator(){let e=await this.element("separator")||this.symbols,r=this.timers&&this.timers.separator,i=this.state;i.timer=r;let n=e[i.status]||e.pending||i.separator,s=await this.resolve(n,i);return bn.isObject(s)&&(s=s[i.status]||s.pending),bn.hasColor(s)?s:this.styles.muted(s)}async pointer(e,r){let i=await this.element("pointer",e,r);if(typeof i=="string"&&bn.hasColor(i))return i;if(i){let n=this.styles,s=this.index===r,o=s?n.primary:c=>c,a=await this.resolve(i[s?"on":"off"]||i,this.state),l=bn.hasColor(a)?a:o(a);return s?l:" ".repeat(a.length)}}async indicator(e,r){let i=await this.element("indicator",e,r);if(typeof i=="string"&&bn.hasColor(i))return i;if(i){let n=this.styles,s=e.enabled===!0,o=s?n.success:n.dark,a=i[s?"on":"off"]||i;return bn.hasColor(a)?a:o(a)}return""}body(){return null}footer(){if(this.state.status==="pending")return this.element("footer")}header(){if(this.state.status==="pending")return this.element("header")}async hint(){if(this.state.status==="pending"&&!this.isValue(this.state.input)){let e=await this.element("hint");return bn.hasColor(e)?e:this.styles.muted(e)}}error(e){return this.state.submitted?"":e||this.state.error}format(e){return e}result(e){return e}validate(e){return this.options.required===!0?this.isValue(e):!0}isValue(e){return e!=null&&e!==""}resolve(e,...r){return bn.resolve(this,e,...r)}get base(){return T0.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||bn.height(this.stdout,25)}get width(){return this.options.columns||bn.width(this.stdout,80)}get size(){return{width:this.width,height:this.height}}set cursor(e){this.state.cursor=e}get cursor(){return this.state.cursor}set input(e){this.state.input=e}get input(){return this.state.input}set value(e){this.state.value=e}get value(){let{input:e,value:r}=this.state,i=[r,e].find(this.isValue.bind(this));return this.isValue(i)?i:this.initial}static get prompt(){return e=>new this(e).run()}};function HJe(t){let e=n=>t[n]===void 0||typeof t[n]=="function",r=["actions","choices","initial","margin","roles","styles","symbols","theme","timers","value"],i=["body","footer","error","header","hint","indicator","message","prefix","separator","skip"];for(let n of Object.keys(t.options)){if(r.includes(n)||/^on[A-Z]/.test(n))continue;let s=t.options[n];typeof s=="function"&&e(n)?i.includes(n)||(t[n]=s.bind(t)):typeof t[n]!="function"&&(t[n]=s)}}function GJe(t){typeof t=="number"&&(t=[t,t,t,t]);let e=[].concat(t||[]),r=n=>n%2==0?` +`:" ",i=[];for(let n=0;n<4;n++){let s=r(n);e[n]?i.push(s.repeat(e[n])):i.push("")}return i}yne.exports=T0});var bne=E((BCt,Bne)=>{"use strict";var jJe=Mi(),Qne={default(t,e){return e},checkbox(t,e){throw new Error("checkbox role is not implemented yet")},editable(t,e){throw new Error("editable role is not implemented yet")},expandable(t,e){throw new Error("expandable role is not implemented yet")},heading(t,e){return e.disabled="",e.indicator=[e.indicator," "].find(r=>r!=null),e.message=e.message||"",e},input(t,e){throw new Error("input role is not implemented yet")},option(t,e){return Qne.default(t,e)},radio(t,e){throw new Error("radio role is not implemented yet")},separator(t,e){return e.disabled="",e.indicator=[e.indicator," "].find(r=>r!=null),e.message=e.message||t.symbols.line.repeat(5),e},spacer(t,e){return e}};Bne.exports=(t,e={})=>{let r=jJe.merge({},Qne,e.roles);return r[t]||r.default}});var sC=E((QCt,vne)=>{"use strict";var YJe=js(),qJe=sf(),JJe=bne(),M0=Mi(),{reorder:QN,scrollUp:WJe,scrollDown:zJe,isObject:Sne,swap:VJe}=M0,xne=class extends qJe{constructor(e){super(e);this.cursorHide(),this.maxSelected=e.maxSelected||Infinity,this.multiple=e.multiple||!1,this.initial=e.initial||0,this.delay=e.delay||0,this.longest=0,this.num=""}async initialize(){typeof this.options.initial=="function"&&(this.initial=await this.options.initial.call(this)),await this.reset(!0),await super.initialize()}async reset(){let{choices:e,initial:r,autofocus:i,suggest:n}=this.options;if(this.state._choices=[],this.state.choices=[],this.choices=await Promise.all(await this.toChoices(e)),this.choices.forEach(s=>s.enabled=!1),typeof n!="function"&&this.selectable.length===0)throw new Error("At least one choice must be selectable");Sne(r)&&(r=Object.keys(r)),Array.isArray(r)?(i!=null&&(this.index=this.findIndex(i)),r.forEach(s=>this.enable(this.find(s))),await this.render()):(i!=null&&(r=i),typeof r=="string"&&(r=this.findIndex(r)),typeof r=="number"&&r>-1&&(this.index=Math.max(0,Math.min(r,this.choices.length)),this.enable(this.find(this.index)))),this.isDisabled(this.focused)&&await this.down()}async toChoices(e,r){this.state.loadingChoices=!0;let i=[],n=0,s=async(o,a)=>{typeof o=="function"&&(o=await o.call(this)),o instanceof Promise&&(o=await o);for(let l=0;l(this.state.loadingChoices=!1,o))}async toChoice(e,r,i){if(typeof e=="function"&&(e=await e.call(this,this)),e instanceof Promise&&(e=await e),typeof e=="string"&&(e={name:e}),e.normalized)return e;e.normalized=!0;let n=e.value;if(e=JJe(e.role,this.options)(this,e),typeof e.disabled=="string"&&!e.hint&&(e.hint=e.disabled,e.disabled=!0),e.disabled===!0&&e.hint==null&&(e.hint="(disabled)"),e.index!=null)return e;e.name=e.name||e.key||e.title||e.value||e.message,e.message=e.message||e.name||"",e.value=[e.value,e.name].find(this.isValue.bind(this)),e.input="",e.index=r,e.cursor=0,M0.define(e,"parent",i),e.level=i?i.level+1:1,e.indent==null&&(e.indent=i?i.indent+" ":e.indent||""),e.path=i?i.path+"."+e.name:e.name,e.enabled=!!(this.multiple&&!this.isDisabled(e)&&(e.enabled||this.isSelected(e))),this.isDisabled(e)||(this.longest=Math.max(this.longest,YJe.unstyle(e.message).length));let o=P({},e);return e.reset=(a=o.input,l=o.value)=>{for(let c of Object.keys(o))e[c]=o[c];e.input=a,e.value=l},n==null&&typeof e.initial=="function"&&(e.input=await e.initial.call(this,this.state,e,r)),e}async onChoice(e,r){this.emit("choice",e,r,this),typeof e.onChoice=="function"&&await e.onChoice.call(this,this.state,e,r)}async addChoice(e,r,i){let n=await this.toChoice(e,r,i);return this.choices.push(n),this.index=this.choices.length-1,this.limit=this.choices.length,n}async newItem(e,r,i){let n=P({name:"New choice name?",editable:!0,newChoice:!0},e),s=await this.addChoice(n,r,i);return s.updateChoice=()=>{delete s.newChoice,s.name=s.message=s.input,s.input="",s.cursor=0},this.render()}indent(e){return e.indent==null?e.level>1?" ".repeat(e.level-1):"":e.indent}dispatch(e,r){if(this.multiple&&this[r.name])return this[r.name]();this.alert()}focus(e,r){return typeof r!="boolean"&&(r=e.enabled),r&&!e.enabled&&this.selected.length>=this.maxSelected?this.alert():(this.index=e.index,e.enabled=r&&!this.isDisabled(e),e)}space(){return this.multiple?(this.toggle(this.focused),this.render()):this.alert()}a(){if(this.maxSelectedr.enabled);return this.choices.forEach(r=>r.enabled=!e),this.render()}i(){return this.choices.length-this.selected.length>this.maxSelected?this.alert():(this.choices.forEach(e=>e.enabled=!e.enabled),this.render())}g(e=this.focused){return this.choices.some(r=>!!r.parent)?(this.toggle(e.parent&&!e.choices?e.parent:e),this.render()):this.a()}toggle(e,r){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();typeof r!="boolean"&&(r=!e.enabled),e.enabled=r,e.choices&&e.choices.forEach(n=>this.toggle(n,r));let i=e.parent;for(;i;){let n=i.choices.filter(s=>this.isDisabled(s));i.enabled=n.every(s=>s.enabled===!0),i=i.parent}return kne(this,this.choices),this.emit("toggle",e,this),e}enable(e){return this.selected.length>=this.maxSelected?this.alert():(e.enabled=!this.isDisabled(e),e.choices&&e.choices.forEach(this.enable.bind(this)),e)}disable(e){return e.enabled=!1,e.choices&&e.choices.forEach(this.disable.bind(this)),e}number(e){this.num+=e;let r=i=>{let n=Number(i);if(n>this.choices.length-1)return this.alert();let s=this.focused,o=this.choices.find(a=>n===a.index);if(!o.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(this.visible.indexOf(o)===-1){let a=QN(this.choices),l=a.indexOf(o);if(s.index>l){let c=a.slice(l,l+this.limit),u=a.filter(g=>!c.includes(g));this.choices=c.concat(u)}else{let c=l-this.limit+1;this.choices=a.slice(c).concat(a.slice(0,c))}}return this.index=this.choices.indexOf(o),this.toggle(this.focused),this.render()};return clearTimeout(this.numberTimeout),new Promise(i=>{let n=this.choices.length,s=this.num,o=(a=!1,l)=>{clearTimeout(this.numberTimeout),a&&(l=r(s)),this.num="",i(l)};if(s==="0"||s.length===1&&Number(s+"0")>n)return o(!0);if(Number(s)>n)return o(!1,this.alert());this.numberTimeout=setTimeout(()=>o(!0),this.delay)})}home(){return this.choices=QN(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,r=QN(this.choices);return this.choices=r.slice(e).concat(r.slice(0,e)),this.index=this.limit-1,this.render()}first(){return this.index=0,this.render()}last(){return this.index=this.visible.length-1,this.render()}prev(){return this.visible.length<=1?this.alert():this.up()}next(){return this.visible.length<=1?this.alert():this.down()}right(){return this.cursor>=this.input.length?this.alert():(this.cursor++,this.render())}left(){return this.cursor<=0?this.alert():(this.cursor--,this.render())}up(){let e=this.choices.length,r=this.visible.length,i=this.index;return this.options.scroll===!1&&i===0?this.alert():e>r&&i===0?this.scrollUp():(this.index=(i-1%e+e)%e,this.isDisabled()?this.up():this.render())}down(){let e=this.choices.length,r=this.visible.length,i=this.index;return this.options.scroll===!1&&i===r-1?this.alert():e>r&&i===r-1?this.scrollDown():(this.index=(i+1)%e,this.isDisabled()?this.down():this.render())}scrollUp(e=0){return this.choices=WJe(this.choices),this.index=e,this.isDisabled()?this.up():this.render()}scrollDown(e=this.visible.length-1){return this.choices=zJe(this.choices),this.index=e,this.isDisabled()?this.down():this.render()}async shiftUp(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index-1),await this.up(),this.sorting=!1;return}return this.scrollUp(this.index)}async shiftDown(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index+1),await this.down(),this.sorting=!1;return}return this.scrollDown(this.index)}pageUp(){return this.visible.length<=1?this.alert():(this.limit=Math.max(this.limit-1,0),this.index=Math.min(this.limit-1,this.index),this._limit=this.limit,this.isDisabled()?this.up():this.render())}pageDown(){return this.visible.length>=this.choices.length?this.alert():(this.index=Math.max(0,this.index),this.limit=Math.min(this.limit+1,this.choices.length),this._limit=this.limit,this.isDisabled()?this.down():this.render())}swap(e){VJe(this.choices,this.index,e)}isDisabled(e=this.focused){return e&&["disabled","collapsed","hidden","completing","readonly"].some(i=>e[i]===!0)?!0:e&&e.role==="heading"}isEnabled(e=this.focused){if(Array.isArray(e))return e.every(r=>this.isEnabled(r));if(e.choices){let r=e.choices.filter(i=>!this.isDisabled(i));return e.enabled&&r.every(i=>this.isEnabled(i))}return e.enabled&&!this.isDisabled(e)}isChoice(e,r){return e.name===r||e.index===Number(r)}isSelected(e){return Array.isArray(this.initial)?this.initial.some(r=>this.isChoice(e,r)):this.isChoice(e,this.initial)}map(e=[],r="value"){return[].concat(e||[]).reduce((i,n)=>(i[n]=this.find(n,r),i),{})}filter(e,r){let i=(a,l)=>[a.name,l].includes(e),n=typeof e=="function"?e:i,o=(this.options.multiple?this.state._choices:this.choices).filter(n);return r?o.map(a=>a[r]):o}find(e,r){if(Sne(e))return r?e[r]:e;let i=(o,a)=>[o.name,a].includes(e),n=typeof e=="function"?e:i,s=this.choices.find(n);if(s)return r?s[r]:s}findIndex(e){return this.choices.indexOf(this.find(e))}async submit(){let e=this.focused;if(!e)return this.alert();if(e.newChoice)return e.input?(e.updateChoice(),this.render()):this.alert();if(this.choices.some(o=>o.newChoice))return this.alert();let{reorder:r,sort:i}=this.options,n=this.multiple===!0,s=this.selected;return s===void 0?this.alert():(Array.isArray(s)&&r!==!1&&i!==!0&&(s=M0.reorder(s)),this.value=n?s.map(o=>o.name):s.name,super.submit())}set choices(e=[]){this.state._choices=this.state._choices||[],this.state.choices=e;for(let r of e)this.state._choices.some(i=>i.name===r.name)||this.state._choices.push(r);if(!this._initial&&this.options.initial){this._initial=!0;let r=this.initial;if(typeof r=="string"||typeof r=="number"){let i=this.find(r);i&&(this.initial=i.index,this.focus(i,!0))}}}get choices(){return kne(this,this.state.choices||[])}set visible(e){this.state.visible=e}get visible(){return(this.state.visible||this.choices).slice(0,this.limit)}set limit(e){this.state.limit=e}get limit(){let{state:e,options:r,choices:i}=this,n=e.limit||this._limit||r.limit||i.length;return Math.min(n,this.height)}set value(e){super.value=e}get value(){return typeof super.value!="string"&&super.value===this.initial?this.input:super.value}set index(e){this.state.index=e}get index(){return Math.max(0,this.state?this.state.index:0)}get enabled(){return this.filter(this.isEnabled.bind(this))}get focused(){let e=this.choices[this.index];return e&&this.state.submitted&&this.multiple!==!0&&(e.enabled=!0),e}get selectable(){return this.choices.filter(e=>!this.isDisabled(e))}get selected(){return this.multiple?this.enabled:this.focused}};function kne(t,e){if(e instanceof Promise)return e;if(typeof e=="function"){if(M0.isAsyncFn(e))return e;e=e.call(t,t)}for(let r of e){if(Array.isArray(r.choices)){let i=r.choices.filter(n=>!t.isDisabled(n));r.enabled=i.every(n=>n.enabled===!0)}t.isDisabled(r)===!0&&delete r.enabled}return e}vne.exports=xne});var GA=E((bCt,Pne)=>{"use strict";var _Je=sC(),bN=Mi(),Dne=class extends _Je{constructor(e){super(e);this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,r){if(this.multiple)return this[r.name]?await this[r.name](e,r):await super.dispatch(e,r);this.alert()}separator(){if(this.options.separator)return super.separator();let e=this.styles.muted(this.symbols.ellipsis);return this.state.submitted?super.separator():e}pointer(e,r){return!this.multiple||this.options.pointer?super.pointer(e,r):""}indicator(e,r){return this.multiple?super.indicator(e,r):""}choiceMessage(e,r){let i=this.resolve(e.message,this.state,e,r);return e.role==="heading"&&!bN.hasColor(i)&&(i=this.styles.strong(i)),this.resolve(i,this.state,e,r)}choiceSeparator(){return":"}async renderChoice(e,r){await this.onChoice(e,r);let i=this.index===r,n=await this.pointer(e,r),s=await this.indicator(e,r)+(e.pad||""),o=await this.resolve(e.hint,this.state,e,r);o&&!bN.hasColor(o)&&(o=this.styles.muted(o));let a=this.indent(e),l=await this.choiceMessage(e,r),c=()=>[this.margin[3],a+n+s,l,this.margin[1],o].filter(Boolean).join(" ");return e.role==="heading"?c():e.disabled?(bN.hasColor(l)||(l=this.styles.disabled(l)),c()):(i&&(l=this.styles.em(l)),c())}async renderChoices(){if(this.state.loading==="choices")return this.styles.warning("Loading choices");if(this.state.submitted)return"";let e=this.visible.map(async(s,o)=>await this.renderChoice(s,o)),r=await Promise.all(e);r.length||r.push(this.styles.danger("No matching choices"));let i=this.margin[0]+r.join(` +`),n;return this.options.choicesHeader&&(n=await this.resolve(this.options.choicesHeader,this.state)),[n,i].filter(Boolean).join(` +`)}format(){return!this.state.submitted||this.state.cancelled?"":Array.isArray(this.selected)?this.selected.map(e=>this.styles.primary(e.name)).join(", "):this.styles.primary(this.selected.name)}async render(){let{submitted:e,size:r}=this.state,i="",n=await this.header(),s=await this.prefix(),o=await this.separator(),a=await this.message();this.options.promptLine!==!1&&(i=[s,a,o,""].join(" "),this.state.prompt=i);let l=await this.format(),c=await this.error()||await this.hint(),u=await this.renderChoices(),g=await this.footer();l&&(i+=l),c&&!i.includes(c)&&(i+=" "+c),e&&!l&&!u.trim()&&this.multiple&&this.emptyError!=null&&(i+=this.styles.danger(this.emptyError)),this.clear(r),this.write([n,i,u,g].filter(Boolean).join(` +`)),this.write(this.margin[2]),this.restore()}};Pne.exports=Dne});var Nne=E((vCt,Rne)=>{"use strict";var XJe=GA(),ZJe=(t,e)=>{let r=t.toLowerCase();return i=>{let s=i.toLowerCase().indexOf(r),o=e(i.slice(s,s+r.length));return s>=0?i.slice(0,s)+o+i.slice(s+r.length):i}},Fne=class extends XJe{constructor(e){super(e);this.cursorShow()}moveCursor(e){this.state.cursor+=e}dispatch(e){return this.append(e)}space(e){return this.options.multiple?super.space(e):this.append(e)}append(e){let{cursor:r,input:i}=this.state;return this.input=i.slice(0,r)+e+i.slice(r),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:r}=this.state;return r?(this.input=r.slice(0,e-1)+r.slice(e),this.moveCursor(-1),this.complete()):this.alert()}deleteForward(){let{cursor:e,input:r}=this.state;return r[e]===void 0?this.alert():(this.input=`${r}`.slice(0,e)+`${r}`.slice(e+1),this.complete())}number(e){return this.append(e)}async complete(){this.completing=!0,this.choices=await this.suggest(this.input,this.state._choices),this.state.limit=void 0,this.index=Math.min(Math.max(this.visible.length-1,0),this.index),await this.render(),this.completing=!1}suggest(e=this.input,r=this.state._choices){if(typeof this.options.suggest=="function")return this.options.suggest.call(this,e,r);let i=e.toLowerCase();return r.filter(n=>n.message.toLowerCase().includes(i))}pointer(){return""}format(){if(!this.focused)return this.input;if(this.options.multiple&&this.state.submitted)return this.selected.map(e=>this.styles.primary(e.message)).join(", ");if(this.state.submitted){let e=this.value=this.input=this.focused.value;return this.styles.primary(e)}return this.input}async render(){if(this.state.status!=="pending")return super.render();let e=this.options.highlight?this.options.highlight.bind(this):this.styles.placeholder,r=ZJe(this.input,e),i=this.choices;this.choices=i.map(n=>_(P({},n),{message:r(n.message)})),await super.render(),this.choices=i}submit(){return this.options.multiple&&(this.value=this.selected.map(e=>e.name)),super.submit()}};Rne.exports=Fne});var SN=E((SCt,Lne)=>{"use strict";var vN=Mi();Lne.exports=(t,e={})=>{t.cursorHide();let{input:r="",initial:i="",pos:n,showCursor:s=!0,color:o}=e,a=o||t.styles.placeholder,l=vN.inverse(t.styles.primary),c=d=>l(t.styles.black(d)),u=r,g=" ",f=c(g);if(t.blink&&t.blink.off===!0&&(c=d=>d,f=""),s&&n===0&&i===""&&r==="")return c(g);if(s&&n===0&&(r===i||r===""))return c(i[0])+a(i.slice(1));i=vN.isPrimitive(i)?`${i}`:"",r=vN.isPrimitive(r)?`${r}`:"";let h=i&&i.startsWith(r)&&i!==r,p=h?c(i[r.length]):f;if(n!==r.length&&s===!0&&(u=r.slice(0,n)+c(r[n])+r.slice(n+1),p=""),s===!1&&(p=""),h){let d=t.styles.unstyle(u+p);return u+p+a(i.slice(d.length))}return u+p}});var O0=E((xCt,Tne)=>{"use strict";var $Je=js(),e3e=GA(),t3e=SN(),Mne=class extends e3e{constructor(e){super(_(P({},e),{multiple:!0}));this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find(r=>r!=null),this.emptyError="",this.values={}}async reset(e){return await super.reset(),e===!0&&(this._index=this.index),this.index=this._index,this.values={},this.choices.forEach(r=>r.reset&&r.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let r=this.focused;if(!r)return this.alert();let{cursor:i,input:n}=r;return r.value=r.input=n.slice(0,i)+e+n.slice(i),r.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:r,input:i}=e;return e.value=e.input=i.slice(0,r-1)+i.slice(r),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:r,input:i}=e;if(i[r]===void 0)return this.alert();let n=`${i}`.slice(0,r)+`${i}`.slice(r+1);return e.value=e.input=n,this.render()}right(){let e=this.focused;return e?e.cursor>=e.input.length?this.alert():(e.cursor++,this.render()):this.alert()}left(){let e=this.focused;return e?e.cursor<=0?this.alert():(e.cursor--,this.render()):this.alert()}space(e,r){return this.dispatch(e,r)}number(e,r){return this.dispatch(e,r)}next(){let e=this.focused;if(!e)return this.alert();let{initial:r,input:i}=e;return r&&r.startsWith(i)&&i!==r?(e.value=e.input=r,e.cursor=e.value.length,this.render()):super.next()}prev(){let e=this.focused;return e?e.cursor===0?super.prev():(e.value=e.input="",e.cursor=0,this.render()):this.alert()}separator(){return""}format(e){return this.state.submitted?"":super.format(e)}pointer(){return""}indicator(e){return e.input?"\u29BF":"\u2299"}async choiceSeparator(e,r){let i=await this.resolve(e.separator,this.state,e,r)||":";return i?" "+this.styles.disabled(i):""}async renderChoice(e,r){await this.onChoice(e,r);let{state:i,styles:n}=this,{cursor:s,initial:o="",name:a,hint:l,input:c=""}=e,{muted:u,submitted:g,primary:f,danger:h}=n,p=l,d=this.index===r,m=e.validate||(()=>!0),I=await this.choiceSeparator(e,r),B=e.message;this.align==="right"&&(B=B.padStart(this.longest+1," ")),this.align==="left"&&(B=B.padEnd(this.longest+1," "));let b=this.values[a]=c||o,R=c?"success":"dark";await m.call(e,b,this.state)!==!0&&(R="danger");let L=n[R](await this.indicator(e,r))+(e.pad||""),K=this.indent(e),J=()=>[K,L,B+I,c,p].filter(Boolean).join(" ");if(i.submitted)return B=$Je.unstyle(B),c=g(c),p="",J();if(e.format)c=await e.format.call(this,c,e,r);else{let ne=this.styles.muted;c=t3e(this,{input:c,initial:o,pos:s,showCursor:d,color:ne})}return this.isValue(c)||(c=this.styles.muted(this.symbols.ellipsis)),e.result&&(this.values[a]=await e.result.call(this,b,e,r)),d&&(B=f(B)),e.error?c+=(c?" ":"")+h(e.error.trim()):e.hint&&(c+=(c?" ":"")+u(e.hint.trim())),J()}async submit(){return this.value=this.values,super.base.submit.call(this)}};Tne.exports=Mne});var xN=E((kCt,One)=>{"use strict";var r3e=O0(),i3e=()=>{throw new Error("expected prompt to have a custom authenticate method")},Kne=(t=i3e)=>{class e extends r3e{constructor(i){super(i)}async submit(){this.value=await t.call(this,this.values,this.state),super.base.submit.call(this)}static create(i){return Kne(i)}}return e};One.exports=Kne()});var Gne=E((PCt,Une)=>{"use strict";var n3e=xN();function s3e(t,e){return t.username===this.options.username&&t.password===this.options.password}var Hne=(t=s3e)=>{let e=[{name:"username",message:"username"},{name:"password",message:"password",format(i){return this.options.showPassword?i:(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(i.length))}}];class r extends n3e.create(t){constructor(n){super(_(P({},n),{choices:e}))}static create(n){return Hne(n)}}return r};Une.exports=Hne()});var K0=E((DCt,jne)=>{"use strict";var o3e=sf(),{isPrimitive:a3e,hasColor:A3e}=Mi(),Yne=class extends o3e{constructor(e){super(e);this.cursorHide()}async initialize(){let e=await this.resolve(this.initial,this.state);this.input=await this.cast(e),await super.initialize()}dispatch(e){return this.isValue(e)?(this.input=e,this.submit()):this.alert()}format(e){let{styles:r,state:i}=this;return i.submitted?r.success(e):r.primary(e)}cast(e){return this.isTrue(e)}isTrue(e){return/^[ty1]/i.test(e)}isFalse(e){return/^[fn0]/i.test(e)}isValue(e){return a3e(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if(this.state.status==="pending"){let e=await this.element("hint");return A3e(e)?e:this.styles.muted(e)}}async render(){let{input:e,size:r}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o=this.styles.muted(this.default),a=[i,s,o,n].filter(Boolean).join(" ");this.state.prompt=a;let l=await this.header(),c=this.value=this.cast(e),u=await this.format(c),g=await this.error()||await this.hint(),f=await this.footer();g&&!a.includes(g)&&(u+=" "+g),a+=" "+u,this.clear(r),this.write([l,a,f].filter(Boolean).join(` +`)),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}};jne.exports=Yne});var Wne=E((RCt,qne)=>{"use strict";var l3e=K0(),Jne=class extends l3e{constructor(e){super(e);this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}};qne.exports=Jne});var _ne=E((FCt,zne)=>{"use strict";var c3e=GA(),u3e=O0(),of=u3e.prototype,Vne=class extends c3e{constructor(e){super(_(P({},e),{multiple:!0}));this.align=[this.options.align,"left"].find(r=>r!=null),this.emptyError="",this.values={}}dispatch(e,r){let i=this.focused,n=i.parent||{};return!i.editable&&!n.editable&&(e==="a"||e==="i")?super[e]():of.dispatch.call(this,e,r)}append(e,r){return of.append.call(this,e,r)}delete(e,r){return of.delete.call(this,e,r)}space(e){return this.focused.editable?this.append(e):super.space()}number(e){return this.focused.editable?this.append(e):super.number(e)}next(){return this.focused.editable?of.next.call(this):super.next()}prev(){return this.focused.editable?of.prev.call(this):super.prev()}async indicator(e,r){let i=e.indicator||"",n=e.editable?i:super.indicator(e,r);return await this.resolve(n,this.state,e,r)||""}indent(e){return e.role==="heading"?"":e.editable?" ":" "}async renderChoice(e,r){return e.indent="",e.editable?of.renderChoice.call(this,e,r):super.renderChoice(e,r)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let r of this.choices){if(typeof r.validate!="function"||r.role==="heading")continue;let i=r.parent?this.value[r.parent.name]:this.value;if(r.editable?i=r.value===r.name?r.initial||"":r.value:this.isDisabled(r)||(i=r.enabled===!0),e=await r.validate(i,this.state),e!==!0)break}return e!==!0&&(this.state.error=typeof e=="string"?e:"Invalid Input"),e}submit(){if(this.focused.newChoice===!0)return super.submit();if(this.choices.some(e=>e.newChoice))return this.alert();this.value={};for(let e of this.choices){let r=e.parent?this.value[e.parent.name]:this.value;if(e.role==="heading"){this.value[e.name]={};continue}e.editable?r[e.name]=e.value===e.name?e.initial||"":e.value:this.isDisabled(e)||(r[e.name]=e.enabled===!0)}return this.base.submit.call(this)}};zne.exports=Vne});var Mc=E((NCt,Xne)=>{"use strict";var g3e=sf(),f3e=SN(),{isPrimitive:h3e}=Mi(),Zne=class extends g3e{constructor(e){super(e);this.initial=h3e(this.initial)?String(this.initial):"",this.initial&&this.cursorHide(),this.state.prevCursor=0,this.state.clipboard=[]}async keypress(e,r={}){let i=this.state.prevKeypress;return this.state.prevKeypress=r,this.options.multiline===!0&&r.name==="return"&&(!i||i.name!=="return")?this.append(` +`,r):super.keypress(e,r)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,r){if(!e||r.ctrl||r.code)return this.alert();this.append(e)}append(e){let{cursor:r,input:i}=this.state;this.input=`${i}`.slice(0,r)+e+`${i}`.slice(r),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:r}=this.state;if(e<=0)return this.alert();this.input=`${r}`.slice(0,e-1)+`${r}`.slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:r}=this.state;if(r[e]===void 0)return this.alert();this.input=`${r}`.slice(0,e)+`${r}`.slice(e+1),this.render()}cutForward(){let e=this.cursor;if(this.input.length<=e)return this.alert();this.state.clipboard.push(this.input.slice(e)),this.input=this.input.slice(0,e),this.render()}cutLeft(){let e=this.cursor;if(e===0)return this.alert();let r=this.input.slice(0,e),i=this.input.slice(e),n=r.split(" ");this.state.clipboard.push(n.pop()),this.input=n.join(" "),this.cursor=this.input.length,this.input+=i,this.render()}paste(){if(!this.state.clipboard.length)return this.alert();this.insert(this.state.clipboard.pop()),this.render()}toggleCursor(){this.state.prevCursor?(this.cursor=this.state.prevCursor,this.state.prevCursor=0):(this.state.prevCursor=this.cursor,this.cursor=0),this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.input.length-1,this.render()}next(){let e=this.initial!=null?String(this.initial):"";if(!e||!e.startsWith(this.input))return this.alert();this.input=this.initial,this.cursor=this.initial.length,this.render()}prev(){if(!this.input)return this.alert();this.reset()}backward(){return this.left()}forward(){return this.right()}right(){return this.cursor>=this.input.length?this.alert():(this.moveCursor(1),this.render())}left(){return this.cursor<=0?this.alert():(this.moveCursor(-1),this.render())}isValue(e){return!!e}async format(e=this.value){let r=await this.resolve(this.initial,this.state);return this.state.submitted?this.styles.submitted(e||r):f3e(this,{input:e,initial:r,pos:this.cursor})}async render(){let e=this.state.size,r=await this.prefix(),i=await this.separator(),n=await this.message(),s=[r,n,i].filter(Boolean).join(" ");this.state.prompt=s;let o=await this.header(),a=await this.format(),l=await this.error()||await this.hint(),c=await this.footer();l&&!a.includes(l)&&(a+=" "+l),s+=" "+a,this.clear(e),this.write([o,s,c].filter(Boolean).join(` +`)),this.restore()}};Xne.exports=Zne});var ese=E((LCt,$ne)=>{"use strict";var p3e=t=>t.filter((e,r)=>t.lastIndexOf(e)===r),U0=t=>p3e(t).filter(Boolean);$ne.exports=(t,e={},r="")=>{let{past:i=[],present:n=""}=e,s,o;switch(t){case"prev":case"undo":return s=i.slice(0,i.length-1),o=i[i.length-1]||"",{past:U0([r,...s]),present:o};case"next":case"redo":return s=i.slice(1),o=i[0]||"",{past:U0([...s,r]),present:o};case"save":return{past:U0([...i,r]),present:""};case"remove":return o=U0(i.filter(a=>a!==r)),n="",o.length&&(n=o.pop()),{past:o,present:n};default:throw new Error(`Invalid action: "${t}"`)}}});var kN=E((TCt,tse)=>{"use strict";var d3e=Mc(),rse=ese(),ise=class extends d3e{constructor(e){super(e);let r=this.options.history;if(r&&r.store){let i=r.values||this.initial;this.autosave=!!r.autosave,this.store=r.store,this.data=this.store.get("values")||{past:[],present:i},this.initial=this.data.present||this.data.past[this.data.past.length-1]}}completion(e){return this.store?(this.data=rse(e,this.data,this.input),this.data.present?(this.input=this.data.present,this.cursor=this.input.length,this.render()):this.alert()):this.alert()}altUp(){return this.completion("prev")}altDown(){return this.completion("next")}prev(){return this.save(),super.prev()}save(){!this.store||(this.data=rse("save",this.data,this.input),this.store.set("values",this.data))}submit(){return this.store&&this.autosave===!0&&this.save(),super.submit()}};tse.exports=ise});var ose=E((MCt,nse)=>{"use strict";var C3e=Mc(),sse=class extends C3e{format(){return""}};nse.exports=sse});var lse=E((OCt,ase)=>{"use strict";var m3e=Mc(),Ase=class extends m3e{constructor(e={}){super(e);this.sep=this.options.separator||/, */,this.initial=e.initial||""}split(e=this.value){return e?String(e).split(this.sep):[]}format(){let e=this.state.submitted?this.styles.primary:r=>r;return this.list.map(e).join(", ")}async submit(e){let r=this.state.error||await this.validate(this.list,this.state);return r!==!0?(this.state.error=r,super.submit()):(this.value=this.list,super.submit())}get list(){return this.split()}};ase.exports=Ase});var gse=E((KCt,cse)=>{"use strict";var E3e=GA(),use=class extends E3e{constructor(e){super(_(P({},e),{multiple:!0}))}};cse.exports=use});var PN=E((UCt,fse)=>{"use strict";var I3e=Mc(),hse=class extends I3e{constructor(e={}){super(P({style:"number"},e));this.min=this.isValue(e.min)?this.toNumber(e.min):-Infinity,this.max=this.isValue(e.max)?this.toNumber(e.max):Infinity,this.delay=e.delay!=null?e.delay:1e3,this.float=e.float!==!1,this.round=e.round===!0||e.float===!1,this.major=e.major||10,this.minor=e.minor||1,this.initial=e.initial!=null?e.initial:"",this.input=String(this.initial),this.cursor=this.input.length,this.cursorShow()}append(e){return!/[-+.]/.test(e)||e==="."&&this.input.includes(".")?this.alert("invalid number"):super.append(e)}number(e){return super.append(e)}next(){return this.input&&this.input!==this.initial?this.alert():this.isValue(this.initial)?(this.input=this.initial,this.cursor=String(this.initial).length,this.render()):this.alert()}up(e){let r=e||this.minor,i=this.toNumber(this.input);return i>this.max+r?this.alert():(this.input=`${i+r}`,this.render())}down(e){let r=e||this.minor,i=this.toNumber(this.input);return ithis.isValue(r));return this.value=this.toNumber(e||0),super.submit()}};fse.exports=hse});var dse=E((HCt,pse)=>{pse.exports=PN()});var Ese=E((GCt,Cse)=>{"use strict";var y3e=Mc(),mse=class extends y3e{constructor(e){super(e);this.cursorShow()}format(e=this.input){return this.keypressed?(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length)):""}};Cse.exports=mse});var Bse=E((jCt,Ise)=>{"use strict";var w3e=js(),B3e=sC(),yse=Mi(),wse=class extends B3e{constructor(e={}){super(e);this.widths=[].concat(e.messageWidth||50),this.align=[].concat(e.align||"left"),this.linebreak=e.linebreak||!1,this.edgeLength=e.edgeLength||3,this.newline=e.newline||` + `;let r=e.startNumber||1;typeof this.scale=="number"&&(this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((i,n)=>({name:n+r})))}async reset(){return this.tableized=!1,await super.reset(),this.render()}tableize(){if(this.tableized===!0)return;this.tableized=!0;let e=0;for(let r of this.choices){e=Math.max(e,r.message.length),r.scaleIndex=r.initial||2,r.scale=[];for(let i=0;i=this.scale.length-1?this.alert():(e.scaleIndex++,this.render())}left(){let e=this.focused;return e.scaleIndex<=0?this.alert():(e.scaleIndex--,this.render())}indent(){return""}format(){return this.state.submitted?this.choices.map(r=>this.styles.info(r.index)).join(", "):""}pointer(){return""}renderScaleKey(){if(this.scaleKey===!1||this.state.submitted)return"";let e=this.scale.map(i=>` ${i.name} - ${i.message}`);return["",...e].map(i=>this.styles.muted(i)).join(` +`)}renderScaleHeading(e){let r=this.scale.map(l=>l.name);typeof this.options.renderScaleHeading=="function"&&(r=this.options.renderScaleHeading.call(this,e));let i=this.scaleLength-r.join("").length,n=Math.round(i/(r.length-1)),o=r.map(l=>this.styles.strong(l)).join(" ".repeat(n)),a=" ".repeat(this.widths[0]);return this.margin[3]+a+this.margin[1]+o}scaleIndicator(e,r,i){if(typeof this.options.scaleIndicator=="function")return this.options.scaleIndicator.call(this,e,r,i);let n=e.scaleIndex===r.index;return r.disabled?this.styles.hint(this.symbols.radio.disabled):n?this.styles.success(this.symbols.radio.on):this.symbols.radio.off}renderScale(e,r){let i=e.scale.map(s=>this.scaleIndicator(e,s,r)),n=this.term==="Hyper"?"":" ";return i.join(n+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,r){await this.onChoice(e,r);let i=this.index===r,n=await this.pointer(e,r),s=await e.hint;s&&!yse.hasColor(s)&&(s=this.styles.muted(s));let o=p=>this.margin[3]+p.replace(/\s+$/,"").padEnd(this.widths[0]," "),a=this.newline,l=this.indent(e),c=await this.resolve(e.message,this.state,e,r),u=await this.renderScale(e,r),g=this.margin[1]+this.margin[3];this.scaleLength=w3e.unstyle(u).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-g.length);let h=yse.wordWrap(c,{width:this.widths[0],newline:a}).split(` +`).map(p=>o(p)+this.margin[1]);return i&&(u=this.styles.info(u),h=h.map(p=>this.styles.info(p))),h[0]+=u,this.linebreak&&h.push(""),[l+n,h.join(` +`)].filter(Boolean)}async renderChoices(){if(this.state.submitted)return"";this.tableize();let e=this.visible.map(async(n,s)=>await this.renderChoice(n,s)),r=await Promise.all(e),i=await this.renderScaleHeading();return this.margin[0]+[i,...r.map(n=>n.join(" "))].join(` +`)}async render(){let{submitted:e,size:r}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o="";this.options.promptLine!==!1&&(o=[i,s,n,""].join(" "),this.state.prompt=o);let a=await this.header(),l=await this.format(),c=await this.renderScaleKey(),u=await this.error()||await this.hint(),g=await this.renderChoices(),f=await this.footer(),h=this.emptyError;l&&(o+=l),u&&!o.includes(u)&&(o+=" "+u),e&&!l&&!g.trim()&&this.multiple&&h!=null&&(o+=this.styles.danger(h)),this.clear(r),this.write([a,o,c,g,f].filter(Boolean).join(` +`)),this.state.submitted||this.write(this.margin[2]),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIndex;return this.base.submit.call(this)}};Ise.exports=wse});var Sse=E((YCt,Qse)=>{"use strict";var bse=js(),Q3e=(t="")=>typeof t=="string"?t.replace(/^['"]|['"]$/g,""):"",vse=class{constructor(e){this.name=e.key,this.field=e.field||{},this.value=Q3e(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}},b3e=async(t={},e={},r=i=>i)=>{let i=new Set,n=t.fields||[],s=t.template,o=[],a=[],l=[],c=1;typeof s=="function"&&(s=await s());let u=-1,g=()=>s[++u],f=()=>s[u+1],h=p=>{p.line=c,o.push(p)};for(h({type:"bos",value:""});uR.name===I.key);I.field=n.find(R=>R.name===I.key),b||(b=new vse(I),a.push(b)),b.lines.push(I.line-1);continue}let d=o[o.length-1];d.type==="text"&&d.line===c?d.value+=p:h({type:"text",value:p})}return h({type:"eos",value:""}),{input:s,tabstops:o,unique:i,keys:l,items:a}};Qse.exports=async t=>{let e=t.options,r=new Set(e.required===!0?[]:e.required||[]),i=P(P({},e.values),e.initial),{tabstops:n,items:s,keys:o}=await b3e(e,i),a=DN("result",t,e),l=DN("format",t,e),c=DN("validate",t,e,!0),u=t.isValue.bind(t);return async(g={},f=!1)=>{let h=0;g.required=r,g.items=s,g.keys=o,g.output="";let p=async(B,b,R,H)=>{let L=await c(B,b,R,H);return L===!1?"Invalid field "+R.name:L};for(let B of n){let b=B.value,R=B.key;if(B.type!=="template"){b&&(g.output+=b);continue}if(B.type==="template"){let H=s.find(q=>q.name===R);e.required===!0&&g.required.add(H.name);let L=[H.input,g.values[H.value],H.value,b].find(u),J=(H.field||{}).message||B.inner;if(f){let q=await p(g.values[R],g,H,h);if(q&&typeof q=="string"||q===!1){g.invalid.set(R,q);continue}g.invalid.delete(R);let A=await a(g.values[R],g,H,h);g.output+=bse.unstyle(A);continue}H.placeholder=!1;let ne=b;b=await l(b,g,H,h),L!==b?(g.values[R]=L,b=t.styles.typing(L),g.missing.delete(J)):(g.values[R]=void 0,L=`<${J}>`,b=t.styles.primary(L),H.placeholder=!0,g.required.has(R)&&g.missing.add(J)),g.missing.has(J)&&g.validating&&(b=t.styles.warning(L)),g.invalid.has(R)&&g.validating&&(b=t.styles.danger(L)),h===g.index&&(ne!==b?b=t.styles.underline(b):b=t.styles.heading(bse.unstyle(b))),h++}b&&(g.output+=b)}let d=g.output.split(` +`).map(B=>" "+B),m=s.length,I=0;for(let B of s)g.invalid.has(B.name)&&B.lines.forEach(b=>{d[b][0]===" "&&(d[b]=g.styles.danger(g.symbols.bullet)+d[b].slice(1))}),t.isValue(g.values[B.name])&&I++;return g.completed=(I/m*100).toFixed(0),g.output=d.join(` +`),g.output}};function DN(t,e,r,i){return(n,s,o,a)=>typeof o.field[t]=="function"?o.field[t].call(e,n,s,o,a):[i,n].find(l=>e.isValue(l))}});var Pse=E((qCt,xse)=>{"use strict";var v3e=js(),S3e=Sse(),x3e=sf(),kse=class extends x3e{constructor(e){super(e);this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await S3e(this),await super.initialize()}async reset(e){this.state.keys=[],this.state.invalid=new Map,this.state.missing=new Set,this.state.completed=0,this.state.values={},e!==!0&&(await this.initialize(),await this.render())}moveCursor(e){let r=this.getItem();this.cursor+=e,r.cursor+=e}dispatch(e,r){if(!r.code&&!r.ctrl&&e!=null&&this.getItem()){this.append(e,r);return}this.alert()}append(e,r){let i=this.getItem(),n=i.input.slice(0,this.cursor),s=i.input.slice(this.cursor);this.input=i.input=`${n}${e}${s}`,this.moveCursor(1),this.render()}delete(){let e=this.getItem();if(this.cursor<=0||!e.input)return this.alert();let r=e.input.slice(this.cursor),i=e.input.slice(0,this.cursor-1);this.input=e.input=`${i}${r}`,this.moveCursor(-1),this.render()}increment(e){return e>=this.state.keys.length-1?0:e+1}decrement(e){return e<=0?this.state.keys.length-1:e-1}first(){this.state.index=0,this.render()}last(){this.state.index=this.state.keys.length-1,this.render()}right(){if(this.cursor>=this.input.length)return this.alert();this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();this.moveCursor(-1),this.render()}prev(){this.state.index=this.decrement(this.state.index),this.getItem(),this.render()}next(){this.state.index=this.increment(this.state.index),this.getItem(),this.render()}up(){this.prev()}down(){this.next()}format(e){let r=this.state.completed<100?this.styles.warning:this.styles.success;return this.state.submitted===!0&&this.state.completed!==100&&(r=this.styles.danger),r(`${this.state.completed}% completed`)}async render(){let{index:e,keys:r=[],submitted:i,size:n}=this.state,s=[this.options.newline,` +`].find(B=>B!=null),o=await this.prefix(),a=await this.separator(),l=await this.message(),c=[o,l,a].filter(Boolean).join(" ");this.state.prompt=c;let u=await this.header(),g=await this.error()||"",f=await this.hint()||"",h=i?"":await this.interpolate(this.state),p=this.state.key=r[e]||"",d=await this.format(p),m=await this.footer();d&&(c+=" "+d),f&&!d&&this.state.completed===0&&(c+=" "+f),this.clear(n);let I=[u,c,h,m,g.trim()];this.write(I.filter(Boolean).join(s)),this.restore()}getItem(e){let{items:r,keys:i,index:n}=this.state,s=r.find(o=>o.name===i[n]);return s&&s.input!=null&&(this.input=s.input,this.cursor=s.cursor),s}async submit(){typeof this.interpolate!="function"&&await this.initialize(),await this.interpolate(this.state,!0);let{invalid:e,missing:r,output:i,values:n}=this.state;if(e.size){let a="";for(let[l,c]of e)a+=`Invalid ${l}: ${c} +`;return this.state.error=a,super.submit()}if(r.size)return this.state.error="Required: "+[...r.keys()].join(", "),super.submit();let o=v3e.unstyle(i).split(` +`).map(a=>a.slice(1)).join(` +`);return this.value={values:n,result:o},super.submit()}};xse.exports=kse});var Fse=E((JCt,Dse)=>{"use strict";var k3e="(Use + to sort)",P3e=GA(),Rse=class extends P3e{constructor(e){super(_(P({},e),{reorder:!1,sort:!0,multiple:!0}));this.state.hint=[this.options.hint,k3e].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,r){let i=await super.renderChoice(e,r),n=this.symbols.identicalTo+" ",s=this.index===r&&this.sorting?this.styles.muted(n):" ";return this.options.drag===!1&&(s=""),this.options.numbered===!0?s+`${r+1} - `+i:s+i}get selected(){return this.choices}submit(){return this.value=this.choices.map(e=>e.value),super.submit()}};Dse.exports=Rse});var Tse=E((WCt,Nse)=>{"use strict";var D3e=sC(),Lse=class extends D3e{constructor(e={}){super(e);if(this.emptyError=e.emptyError||"No items were selected",this.term=process.env.TERM_PROGRAM,!this.options.header){let r=["","4 - Strongly Agree","3 - Agree","2 - Neutral","1 - Disagree","0 - Strongly Disagree",""];r=r.map(i=>this.styles.muted(i)),this.state.header=r.join(` + `)}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let r=await super.toChoices(...e);for(let i of r)i.scale=R3e(5,this.options),i.scaleIdx=2;return r}dispatch(){this.alert()}space(){let e=this.focused,r=e.scale[e.scaleIdx],i=r.selected;return e.scale.forEach(n=>n.selected=!1),r.selected=!i,this.render()}indicator(){return""}pointer(){return""}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIdx>=e.scale.length-1?this.alert():(e.scaleIdx++,this.render())}left(){let e=this.focused;return e.scaleIdx<=0?this.alert():(e.scaleIdx--,this.render())}indent(){return" "}async renderChoice(e,r){await this.onChoice(e,r);let i=this.index===r,n=this.term==="Hyper",s=n?9:8,o=n?"":" ",a=this.symbols.line.repeat(s),l=" ".repeat(s+(n?0:1)),c=b=>(b?this.styles.success("\u25C9"):"\u25EF")+o,u=r+1+".",g=i?this.styles.heading:this.styles.noop,f=await this.resolve(e.message,this.state,e,r),h=this.indent(e),p=h+e.scale.map((b,R)=>c(R===e.scaleIdx)).join(a),d=b=>b===e.scaleIdx?g(b):b,m=h+e.scale.map((b,R)=>d(R)).join(l),I=()=>[u,f].filter(Boolean).join(" "),B=()=>[I(),p,m," "].filter(Boolean).join(` +`);return i&&(p=this.styles.cyan(p),m=this.styles.cyan(m)),B()}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(i,n)=>await this.renderChoice(i,n)),r=await Promise.all(e);return r.length||r.push(this.styles.danger("No matching choices")),r.join(` +`)}format(){return this.state.submitted?this.choices.map(r=>this.styles.info(r.scaleIdx)).join(", "):""}async render(){let{submitted:e,size:r}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o=[i,s,n].filter(Boolean).join(" ");this.state.prompt=o;let a=await this.header(),l=await this.format(),c=await this.error()||await this.hint(),u=await this.renderChoices(),g=await this.footer();(l||!c)&&(o+=" "+l),c&&!o.includes(c)&&(o+=" "+c),e&&!l&&!u&&this.multiple&&this.type!=="form"&&(o+=this.styles.danger(this.emptyError)),this.clear(r),this.write([o,a,u,g].filter(Boolean).join(` +`)),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIdx;return this.base.submit.call(this)}};function R3e(t,e={}){if(Array.isArray(e.scale))return e.scale.map(i=>P({},i));let r=[];for(let i=1;i{Mse.exports=kN()});var Hse=E((VCt,Kse)=>{"use strict";var F3e=K0(),Use=class extends F3e{async initialize(){await super.initialize(),this.value=this.initial=!!this.options.initial,this.disabled=this.options.disabled||"no",this.enabled=this.options.enabled||"yes",await this.render()}reset(){this.value=this.initial,this.render()}delete(){this.alert()}toggle(){this.value=!this.value,this.render()}enable(){if(this.value===!0)return this.alert();this.value=!0,this.render()}disable(){if(this.value===!1)return this.alert();this.value=!1,this.render()}up(){this.toggle()}down(){this.toggle()}right(){this.toggle()}left(){this.toggle()}next(){this.toggle()}prev(){this.toggle()}dispatch(e="",r){switch(e.toLowerCase()){case" ":return this.toggle();case"1":case"y":case"t":return this.enable();case"0":case"n":case"f":return this.disable();default:return this.alert()}}format(){let e=i=>this.styles.primary.underline(i);return[this.value?this.disabled:e(this.disabled),this.value?e(this.enabled):this.enabled].join(this.styles.muted(" / "))}async render(){let{size:e}=this.state,r=await this.header(),i=await this.prefix(),n=await this.separator(),s=await this.message(),o=await this.format(),a=await this.error()||await this.hint(),l=await this.footer(),c=[i,s,n,o].join(" ");this.state.prompt=c,a&&!c.includes(a)&&(c+=" "+a),this.clear(e),this.write([r,c,l].filter(Boolean).join(` +`)),this.write(this.margin[2]),this.restore()}};Kse.exports=Use});var Yse=E((_Ct,Gse)=>{"use strict";var N3e=GA(),jse=class extends N3e{constructor(e){super(e);if(typeof this.options.correctChoice!="number"||this.options.correctChoice<0)throw new Error("Please specify the index of the correct answer from the list of choices")}async toChoices(e,r){let i=await super.toChoices(e,r);if(i.length<2)throw new Error("Please give at least two choices to the user");if(this.options.correctChoice>i.length)throw new Error("Please specify the index of the correct answer from the list of choices");return i}check(e){return e.index===this.options.correctChoice}async result(e){return{selectedAnswer:e,correctAnswer:this.options.choices[this.options.correctChoice].value,correct:await this.check(this.state)}}};Gse.exports=jse});var Jse=E(RN=>{"use strict";var qse=Mi(),ti=(t,e)=>{qse.defineExport(RN,t,e),qse.defineExport(RN,t.toLowerCase(),e)};ti("AutoComplete",()=>Nne());ti("BasicAuth",()=>Gne());ti("Confirm",()=>Wne());ti("Editable",()=>_ne());ti("Form",()=>O0());ti("Input",()=>kN());ti("Invisible",()=>ose());ti("List",()=>lse());ti("MultiSelect",()=>gse());ti("Numeral",()=>dse());ti("Password",()=>Ese());ti("Scale",()=>Bse());ti("Select",()=>GA());ti("Snippet",()=>Pse());ti("Sort",()=>Fse());ti("Survey",()=>Tse());ti("Text",()=>Ose());ti("Toggle",()=>Hse());ti("Quiz",()=>Yse())});var zse=E((ZCt,Wse)=>{Wse.exports={ArrayPrompt:sC(),AuthPrompt:xN(),BooleanPrompt:K0(),NumberPrompt:PN(),StringPrompt:Mc()}});var aC=E(($Ct,Vse)=>{"use strict";var _se=require("assert"),FN=require("events"),jA=Mi(),No=class extends FN{constructor(e,r){super();this.options=jA.merge({},e),this.answers=P({},r)}register(e,r){if(jA.isObject(e)){for(let n of Object.keys(e))this.register(n,e[n]);return this}_se.equal(typeof r,"function","expected a function");let i=e.toLowerCase();return r.prototype instanceof this.Prompt?this.prompts[i]=r:this.prompts[i]=r(this.Prompt,this),this}async prompt(e=[]){for(let r of[].concat(e))try{typeof r=="function"&&(r=await r.call(this)),await this.ask(jA.merge({},this.options,r))}catch(i){return Promise.reject(i)}return this.answers}async ask(e){typeof e=="function"&&(e=await e.call(this));let r=jA.merge({},this.options,e),{type:i,name:n}=e,{set:s,get:o}=jA;if(typeof i=="function"&&(i=await i.call(this,e,this.answers)),!i)return this.answers[n];_se(this.prompts[i],`Prompt "${i}" is not registered`);let a=new this.prompts[i](r),l=o(this.answers,n);a.state.answers=this.answers,a.enquirer=this,n&&a.on("submit",u=>{this.emit("answer",n,u,a),s(this.answers,n,u)});let c=a.emit.bind(a);return a.emit=(...u)=>(this.emit.call(this,...u),c(...u)),this.emit("prompt",a,this),r.autofill&&l!=null?(a.value=a.input=l,r.autofill==="show"&&await a.submit()):l=a.value=await a.run(),l}use(e){return e.call(this,this),this}set Prompt(e){this._Prompt=e}get Prompt(){return this._Prompt||this.constructor.Prompt}get prompts(){return this.constructor.prompts}static set Prompt(e){this._Prompt=e}static get Prompt(){return this._Prompt||sf()}static get prompts(){return Jse()}static get types(){return zse()}static get prompt(){let e=(r,...i)=>{let n=new this(...i),s=n.emit.bind(n);return n.emit=(...o)=>(e.emit(...o),s(...o)),n.prompt(r)};return jA.mixinEmitter(e,new FN),e}};jA.mixinEmitter(No,new FN);var NN=No.prompts;for(let t of Object.keys(NN)){let e=t.toLowerCase(),r=i=>new NN[t](i).run();No.prompt[e]=r,No[e]=r,No[t]||Reflect.defineProperty(No,t,{get:()=>NN[t]})}var oC=t=>{jA.defineExport(No,t,()=>No.types[t])};oC("ArrayPrompt");oC("AuthPrompt");oC("BooleanPrompt");oC("NumberPrompt");oC("StringPrompt");Vse.exports=No});var loe=E((Gmt,Aoe)=>{function K3e(t,e){for(var r=-1,i=t==null?0:t.length;++r{var U3e=XB(),H3e=jg();function G3e(t,e,r,i){var n=!r;r||(r={});for(var s=-1,o=e.length;++s{var j3e=Af(),Y3e=zg();function q3e(t,e){return t&&j3e(e,Y3e(e),t)}uoe.exports=q3e});var hoe=E((qmt,foe)=>{function J3e(t){var e=[];if(t!=null)for(var r in Object(t))e.push(r);return e}foe.exports=J3e});var doe=E((Jmt,poe)=>{var W3e=Gs(),z3e=u0(),V3e=hoe(),_3e=Object.prototype,X3e=_3e.hasOwnProperty;function Z3e(t){if(!W3e(t))return V3e(t);var e=z3e(t),r=[];for(var i in t)i=="constructor"&&(e||!X3e.call(t,i))||r.push(i);return r}poe.exports=Z3e});var lf=E((Wmt,Coe)=>{var $3e=bF(),eWe=doe(),tWe=Hd();function rWe(t){return tWe(t)?$3e(t,!0):eWe(t)}Coe.exports=rWe});var Eoe=E((zmt,moe)=>{var iWe=Af(),nWe=lf();function sWe(t,e){return t&&iWe(e,nWe(e),t)}moe.exports=sWe});var UN=E((hC,cf)=>{var oWe=Ks(),Ioe=typeof hC=="object"&&hC&&!hC.nodeType&&hC,yoe=Ioe&&typeof cf=="object"&&cf&&!cf.nodeType&&cf,aWe=yoe&&yoe.exports===Ioe,woe=aWe?oWe.Buffer:void 0,Boe=woe?woe.allocUnsafe:void 0;function AWe(t,e){if(e)return t.slice();var r=t.length,i=Boe?Boe(r):new t.constructor(r);return t.copy(i),i}cf.exports=AWe});var HN=E((Vmt,Qoe)=>{function lWe(t,e){var r=-1,i=t.length;for(e||(e=Array(i));++r{var cWe=Af(),uWe=f0();function gWe(t,e){return cWe(t,uWe(t),e)}boe.exports=gWe});var H0=E((Xmt,Soe)=>{var fWe=vF(),hWe=fWe(Object.getPrototypeOf,Object);Soe.exports=hWe});var GN=E((Zmt,xoe)=>{var pWe=$B(),dWe=H0(),CWe=f0(),mWe=RF(),EWe=Object.getOwnPropertySymbols,IWe=EWe?function(t){for(var e=[];t;)pWe(e,CWe(t)),t=dWe(t);return e}:mWe;xoe.exports=IWe});var Poe=E(($mt,koe)=>{var yWe=Af(),wWe=GN();function BWe(t,e){return yWe(t,wWe(t),e)}koe.exports=BWe});var Roe=E((eEt,Doe)=>{var QWe=DF(),bWe=GN(),vWe=lf();function SWe(t){return QWe(t,vWe,bWe)}Doe.exports=SWe});var Noe=E((tEt,Foe)=>{var xWe=Object.prototype,kWe=xWe.hasOwnProperty;function PWe(t){var e=t.length,r=new t.constructor(e);return e&&typeof t[0]=="string"&&kWe.call(t,"index")&&(r.index=t.index,r.input=t.input),r}Foe.exports=PWe});var G0=E((rEt,Loe)=>{var Toe=kF();function DWe(t){var e=new t.constructor(t.byteLength);return new Toe(e).set(new Toe(t)),e}Loe.exports=DWe});var Ooe=E((iEt,Moe)=>{var RWe=G0();function FWe(t,e){var r=e?RWe(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)}Moe.exports=FWe});var Uoe=E((nEt,Koe)=>{var NWe=/\w*$/;function LWe(t){var e=new t.constructor(t.source,NWe.exec(t));return e.lastIndex=t.lastIndex,e}Koe.exports=LWe});var qoe=E((sEt,Hoe)=>{var Goe=ac(),joe=Goe?Goe.prototype:void 0,Yoe=joe?joe.valueOf:void 0;function TWe(t){return Yoe?Object(Yoe.call(t)):{}}Hoe.exports=TWe});var jN=E((oEt,Joe)=>{var MWe=G0();function OWe(t,e){var r=e?MWe(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}Joe.exports=OWe});var zoe=E((aEt,Woe)=>{var KWe=G0(),UWe=Ooe(),HWe=Uoe(),GWe=qoe(),jWe=jN(),YWe="[object Boolean]",qWe="[object Date]",JWe="[object Map]",WWe="[object Number]",zWe="[object RegExp]",VWe="[object Set]",_We="[object String]",XWe="[object Symbol]",ZWe="[object ArrayBuffer]",$We="[object DataView]",e8e="[object Float32Array]",t8e="[object Float64Array]",r8e="[object Int8Array]",i8e="[object Int16Array]",n8e="[object Int32Array]",s8e="[object Uint8Array]",o8e="[object Uint8ClampedArray]",a8e="[object Uint16Array]",A8e="[object Uint32Array]";function l8e(t,e,r){var i=t.constructor;switch(e){case ZWe:return KWe(t);case YWe:case qWe:return new i(+t);case $We:return UWe(t,r);case e8e:case t8e:case r8e:case i8e:case n8e:case s8e:case o8e:case a8e:case A8e:return jWe(t,r);case JWe:return new i;case WWe:case _We:return new i(t);case zWe:return HWe(t);case VWe:return new i;case XWe:return GWe(t)}}Woe.exports=l8e});var Xoe=E((AEt,Voe)=>{var c8e=Gs(),_oe=Object.create,u8e=function(){function t(){}return function(e){if(!c8e(e))return{};if(_oe)return _oe(e);t.prototype=e;var r=new t;return t.prototype=void 0,r}}();Voe.exports=u8e});var YN=E((lEt,Zoe)=>{var g8e=Xoe(),f8e=H0(),h8e=u0();function p8e(t){return typeof t.constructor=="function"&&!h8e(t)?g8e(f8e(t)):{}}Zoe.exports=p8e});var eae=E((cEt,$oe)=>{var d8e=jd(),C8e=Qo(),m8e="[object Map]";function E8e(t){return C8e(t)&&d8e(t)==m8e}$oe.exports=E8e});var nae=E((uEt,tae)=>{var I8e=eae(),y8e=A0(),rae=l0(),iae=rae&&rae.isMap,w8e=iae?y8e(iae):I8e;tae.exports=w8e});var oae=E((gEt,sae)=>{var B8e=jd(),Q8e=Qo(),b8e="[object Set]";function v8e(t){return Q8e(t)&&B8e(t)==b8e}sae.exports=v8e});var cae=E((fEt,aae)=>{var S8e=oae(),x8e=A0(),Aae=l0(),lae=Aae&&Aae.isSet,k8e=lae?x8e(lae):S8e;aae.exports=k8e});var pae=E((hEt,uae)=>{var P8e=Gd(),D8e=loe(),R8e=XB(),F8e=goe(),N8e=Eoe(),L8e=UN(),T8e=HN(),M8e=voe(),O8e=Poe(),K8e=FF(),U8e=Roe(),H8e=jd(),G8e=Noe(),j8e=zoe(),Y8e=YN(),q8e=As(),J8e=Od(),W8e=nae(),z8e=Gs(),V8e=cae(),_8e=zg(),X8e=lf(),Z8e=1,$8e=2,e4e=4,gae="[object Arguments]",t4e="[object Array]",r4e="[object Boolean]",i4e="[object Date]",n4e="[object Error]",fae="[object Function]",s4e="[object GeneratorFunction]",o4e="[object Map]",a4e="[object Number]",hae="[object Object]",A4e="[object RegExp]",l4e="[object Set]",c4e="[object String]",u4e="[object Symbol]",g4e="[object WeakMap]",f4e="[object ArrayBuffer]",h4e="[object DataView]",p4e="[object Float32Array]",d4e="[object Float64Array]",C4e="[object Int8Array]",m4e="[object Int16Array]",E4e="[object Int32Array]",I4e="[object Uint8Array]",y4e="[object Uint8ClampedArray]",w4e="[object Uint16Array]",B4e="[object Uint32Array]",rr={};rr[gae]=rr[t4e]=rr[f4e]=rr[h4e]=rr[r4e]=rr[i4e]=rr[p4e]=rr[d4e]=rr[C4e]=rr[m4e]=rr[E4e]=rr[o4e]=rr[a4e]=rr[hae]=rr[A4e]=rr[l4e]=rr[c4e]=rr[u4e]=rr[I4e]=rr[y4e]=rr[w4e]=rr[B4e]=!0;rr[n4e]=rr[fae]=rr[g4e]=!1;function j0(t,e,r,i,n,s){var o,a=e&Z8e,l=e&$8e,c=e&e4e;if(r&&(o=n?r(t,i,n,s):r(t)),o!==void 0)return o;if(!z8e(t))return t;var u=q8e(t);if(u){if(o=G8e(t),!a)return T8e(t,o)}else{var g=H8e(t),f=g==fae||g==s4e;if(J8e(t))return L8e(t,a);if(g==hae||g==gae||f&&!n){if(o=l||f?{}:Y8e(t),!a)return l?O8e(t,N8e(o,t)):M8e(t,F8e(o,t))}else{if(!rr[g])return n?t:{};o=j8e(t,g,a)}}s||(s=new P8e);var h=s.get(t);if(h)return h;s.set(t,o),V8e(t)?t.forEach(function(m){o.add(j0(m,e,r,m,t,s))}):W8e(t)&&t.forEach(function(m,I){o.set(I,j0(m,e,r,I,t,s))});var p=c?l?U8e:K8e:l?X8e:_8e,d=u?void 0:p(t);return D8e(d||t,function(m,I){d&&(I=m,m=t[I]),R8e(o,I,j0(m,e,r,I,t,s))}),o}uae.exports=j0});var qN=E((pEt,dae)=>{var Q4e=pae(),b4e=1,v4e=4;function S4e(t){return Q4e(t,b4e|v4e)}dae.exports=S4e});var mae=E((dEt,Cae)=>{var x4e=tF();function k4e(t,e,r){return t==null?t:x4e(t,e,r)}Cae.exports=k4e});var Qae=E((wEt,Bae)=>{function P4e(t){var e=t==null?0:t.length;return e?t[e-1]:void 0}Bae.exports=P4e});var vae=E((BEt,bae)=>{var D4e=xd(),R4e=zP();function F4e(t,e){return e.length<2?t:D4e(t,R4e(e,0,-1))}bae.exports=F4e});var xae=E((QEt,Sae)=>{var N4e=Gg(),L4e=Qae(),T4e=vae(),M4e=Sc();function O4e(t,e){return e=N4e(e,t),t=T4e(t,e),t==null||delete t[M4e(L4e(e))]}Sae.exports=O4e});var Pae=E((bEt,kae)=>{var K4e=xae();function U4e(t,e){return t==null?!0:K4e(t,e)}kae.exports=U4e});var Kae=E((tIt,Oae)=>{Oae.exports={name:"@yarnpkg/cli",version:"3.1.1",license:"BSD-2-Clause",main:"./sources/index.ts",dependencies:{"@yarnpkg/core":"workspace:^","@yarnpkg/fslib":"workspace:^","@yarnpkg/libzip":"workspace:^","@yarnpkg/parsers":"workspace:^","@yarnpkg/plugin-compat":"workspace:^","@yarnpkg/plugin-dlx":"workspace:^","@yarnpkg/plugin-essentials":"workspace:^","@yarnpkg/plugin-file":"workspace:^","@yarnpkg/plugin-git":"workspace:^","@yarnpkg/plugin-github":"workspace:^","@yarnpkg/plugin-http":"workspace:^","@yarnpkg/plugin-init":"workspace:^","@yarnpkg/plugin-link":"workspace:^","@yarnpkg/plugin-nm":"workspace:^","@yarnpkg/plugin-npm":"workspace:^","@yarnpkg/plugin-npm-cli":"workspace:^","@yarnpkg/plugin-pack":"workspace:^","@yarnpkg/plugin-patch":"workspace:^","@yarnpkg/plugin-pnp":"workspace:^","@yarnpkg/plugin-pnpm":"workspace:^","@yarnpkg/shell":"workspace:^",chalk:"^3.0.0","ci-info":"^3.2.0",clipanion:"^3.0.1",semver:"^7.1.2",tslib:"^1.13.0",typanion:"^3.3.0",yup:"^0.32.9"},devDependencies:{"@types/semver":"^7.1.0","@types/yup":"^0","@yarnpkg/builder":"workspace:^","@yarnpkg/monorepo":"workspace:^","@yarnpkg/pnpify":"workspace:^",micromatch:"^4.0.2",typescript:"^4.5.2"},peerDependencies:{"@yarnpkg/core":"workspace:^"},scripts:{postpack:"rm -rf lib",prepack:'run build:compile "$(pwd)"',"build:cli+hook":"run build:pnp:hook && builder build bundle","build:cli":"builder build bundle","run:cli":"builder run","update-local":"run build:cli --no-git-hash && rsync -a --delete bundles/ bin/"},publishConfig:{main:"./lib/index.js",types:"./lib/index.d.ts",bin:null},files:["/lib/**/*","!/lib/pluginConfiguration.*","!/lib/cli.*"],"@yarnpkg/builder":{bundles:{standard:["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-dlx","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm"]}},repository:{type:"git",url:"ssh://git@github.com/yarnpkg/berry.git",directory:"packages/yarnpkg-cli"},engines:{node:">=12 <14 || 14.2 - 14.9 || >14.10.0"}}});var iL=E((SBt,QAe)=>{"use strict";QAe.exports=function(e,r){r===!0&&(r=0);var i=e.indexOf("://"),n=e.substring(0,i).split("+").filter(Boolean);return typeof r=="number"?n[r]:n}});var nL=E((xBt,bAe)=>{"use strict";var sze=iL();function vAe(t){if(Array.isArray(t))return t.indexOf("ssh")!==-1||t.indexOf("rsync")!==-1;if(typeof t!="string")return!1;var e=sze(t);return t=t.substring(t.indexOf("://")+3),vAe(e)?!0:t.indexOf("@"){"use strict";var oze=iL(),aze=nL(),Aze=require("querystring");function lze(t){t=(t||"").trim();var e={protocols:oze(t),protocol:null,port:null,resource:"",user:"",pathname:"",hash:"",search:"",href:t,query:Object.create(null)},r=t.indexOf("://"),i=-1,n=null,s=null;t.startsWith(".")&&(t.startsWith("./")&&(t=t.substring(2)),e.pathname=t,e.protocol="file");var o=t.charAt(1);return e.protocol||(e.protocol=e.protocols[0],e.protocol||(aze(t)?e.protocol="ssh":((o==="/"||o==="~")&&(t=t.substring(2)),e.protocol="file"))),r!==-1&&(t=t.substring(r+3)),s=t.split("/"),e.protocol!=="file"?e.resource=s.shift():e.resource="",n=e.resource.split("@"),n.length===2&&(e.user=n[0],e.resource=n[1]),n=e.resource.split(":"),n.length===2&&(e.resource=n[0],n[1]?(e.port=Number(n[1]),isNaN(e.port)&&(e.port=null,s.unshift(n[1]))):e.port=null),s=s.filter(Boolean),e.protocol==="file"?e.pathname=e.href:e.pathname=e.pathname||(e.protocol!=="file"||e.href[0]==="/"?"/":"")+s.join("/"),n=e.pathname.split("#"),n.length===2&&(e.pathname=n[0],e.hash=n[1]),n=e.pathname.split("?"),n.length===2&&(e.pathname=n[0],e.search=n[1]),e.query=Aze.parse(e.search),e.href=e.href.replace(/\/$/,""),e.pathname=e.pathname.replace(/\/$/,""),e}SAe.exports=lze});var DAe=E((PBt,kAe)=>{"use strict";var cze=typeof URL=="undefined"?require("url").URL:URL,PAe=(t,e)=>e.some(r=>r instanceof RegExp?r.test(t):r===t);kAe.exports=(t,e)=>{e=Object.assign({defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripHash:!0,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0},e),Reflect.has(e,"normalizeHttps")&&(e.forceHttp=e.normalizeHttps),Reflect.has(e,"normalizeHttp")&&(e.forceHttps=e.normalizeHttp),Reflect.has(e,"stripFragment")&&(e.stripHash=e.stripFragment),t=t.trim();let r=t.startsWith("//");!r&&/^\.*\//.test(t)||(t=t.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let n=new cze(t);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&n.protocol==="https:"&&(n.protocol="http:"),e.forceHttps&&n.protocol==="http:"&&(n.protocol="https:"),e.stripHash&&(n.hash=""),n.pathname&&(n.pathname=n.pathname.replace(/((?![https?:]).)\/{2,}/g,(s,o)=>/^(?!\/)/g.test(o)?`${o}/`:"/")),n.pathname&&(n.pathname=decodeURI(n.pathname)),e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let s=n.pathname.split("/"),o=s[s.length-1];PAe(o,e.removeDirectoryIndex)&&(s=s.slice(0,s.length-1),n.pathname=s.slice(1).join("/")+"/")}if(n.hostname&&(n.hostname=n.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.([a-z\-\d]{2,63})\.([a-z\.]{2,5})$/.test(n.hostname)&&(n.hostname=n.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let s of[...n.searchParams.keys()])PAe(s,e.removeQueryParameters)&&n.searchParams.delete(s);return e.sortQueryParameters&&n.searchParams.sort(),t=n.toString(),(e.removeTrailingSlash||n.pathname==="/")&&(t=t.replace(/\/$/,"")),r&&!e.normalizeProtocol&&(t=t.replace(/^http:\/\//,"//")),t}});var FAe=E((DBt,RAe)=>{"use strict";var uze=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},gze=xAe(),fze=DAe();function hze(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(typeof t!="string"||!t.trim())throw new Error("Invalid url.");e&&((typeof e=="undefined"?"undefined":uze(e))!=="object"&&(e={stripFragment:!1}),t=fze(t,e));var r=gze(t);return r}RAe.exports=hze});var TAe=E((RBt,NAe)=>{"use strict";var pze=FAe(),LAe=nL();function dze(t){var e=pze(t);e.token="";var r=e.user.split(":");return r.length===2&&(r[1]==="x-oauth-basic"?e.token=r[0]:r[0]==="x-token-auth"&&(e.token=r[1])),LAe(e.protocols)||LAe(t)?e.protocol="ssh":e.protocols.length?e.protocol=e.protocols[0]:e.protocol="file",e.href=e.href.replace(/\/$/,""),e}NAe.exports=dze});var OAe=E((FBt,MAe)=>{"use strict";var Cze=TAe();function sL(t){if(typeof t!="string")throw new Error("The url must be a string.");var e=Cze(t),r=e.resource.split("."),i=null;switch(e.toString=function(l){return sL.stringify(this,l)},e.source=r.length>2?r.slice(1-r.length).join("."):e.source=e.resource,e.git_suffix=/\.git$/.test(e.pathname),e.name=decodeURIComponent(e.pathname.replace(/^\//,"").replace(/\.git$/,"")),e.owner=decodeURIComponent(e.user),e.source){case"git.cloudforge.com":e.owner=e.user,e.organization=r[0],e.source="cloudforge.com";break;case"visualstudio.com":if(e.resource==="vs-ssh.visualstudio.com"){i=e.name.split("/"),i.length===4&&(e.organization=i[1],e.owner=i[2],e.name=i[3],e.full_name=i[2]+"/"+i[3]);break}else{i=e.name.split("/"),i.length===2?(e.owner=i[1],e.name=i[1],e.full_name="_git/"+e.name):i.length===3?(e.name=i[2],i[0]==="DefaultCollection"?(e.owner=i[2],e.organization=i[0],e.full_name=e.organization+"/_git/"+e.name):(e.owner=i[0],e.full_name=e.owner+"/_git/"+e.name)):i.length===4&&(e.organization=i[0],e.owner=i[1],e.name=i[3],e.full_name=e.organization+"/"+e.owner+"/_git/"+e.name);break}case"dev.azure.com":case"azure.com":if(e.resource==="ssh.dev.azure.com"){i=e.name.split("/"),i.length===4&&(e.organization=i[1],e.owner=i[2],e.name=i[3]);break}else{i=e.name.split("/"),i.length===5?(e.organization=i[0],e.owner=i[1],e.name=i[4],e.full_name="_git/"+e.name):i.length===3?(e.name=i[2],i[0]==="DefaultCollection"?(e.owner=i[2],e.organization=i[0],e.full_name=e.organization+"/_git/"+e.name):(e.owner=i[0],e.full_name=e.owner+"/_git/"+e.name)):i.length===4&&(e.organization=i[0],e.owner=i[1],e.name=i[3],e.full_name=e.organization+"/"+e.owner+"/_git/"+e.name);break}default:i=e.name.split("/");var n=i.length-1;if(i.length>=2){var s=i.indexOf("blob",2),o=i.indexOf("tree",2),a=i.indexOf("commit",2);n=s>0?s-1:o>0?o-1:a>0?a-1:n,e.owner=i.slice(0,n).join("/"),e.name=i[n],a&&(e.commit=i[n+2])}e.ref="",e.filepathtype="",e.filepath="",i.length>n+2&&["blob","tree"].indexOf(i[n+1])>=0&&(e.filepathtype=i[n+1],e.ref=i[n+2],i.length>n+3&&(e.filepath=i.slice(n+3).join("/"))),e.organization=e.owner;break}return e.full_name||(e.full_name=e.owner,e.name&&(e.full_name&&(e.full_name+="/"),e.full_name+=e.name)),e}sL.stringify=function(t,e){e=e||(t.protocols&&t.protocols.length?t.protocols.join("+"):t.protocol);var r=t.port?":"+t.port:"",i=t.user||"git",n=t.git_suffix?".git":"";switch(e){case"ssh":return r?"ssh://"+i+"@"+t.resource+r+"/"+t.full_name+n:i+"@"+t.resource+":"+t.full_name+n;case"git+ssh":case"ssh+git":case"ftp":case"ftps":return e+"://"+i+"@"+t.resource+r+"/"+t.full_name+n;case"http":case"https":var s=t.token?mze(t):t.user&&(t.protocols.includes("http")||t.protocols.includes("https"))?t.user+"@":"";return e+"://"+s+t.resource+r+"/"+t.full_name+n;default:return t.href}};function mze(t){switch(t.source){case"bitbucket.org":return"x-token-auth:"+t.token+"@";default:return t.token+"@"}}MAe.exports=sL});var NL=E((Obt,ole)=>{var Mze=jg(),Oze=Kg();function Kze(t,e,r){(r!==void 0&&!Oze(t[e],r)||r===void 0&&!(e in t))&&Mze(t,e,r)}ole.exports=Kze});var Ale=E((Kbt,ale)=>{var Uze=Hd(),Hze=Qo();function Gze(t){return Hze(t)&&Uze(t)}ale.exports=Gze});var ule=E((Ubt,lle)=>{var jze=Ac(),Yze=H0(),qze=Qo(),Jze="[object Object]",Wze=Function.prototype,zze=Object.prototype,cle=Wze.toString,Vze=zze.hasOwnProperty,_ze=cle.call(Object);function Xze(t){if(!qze(t)||jze(t)!=Jze)return!1;var e=Yze(t);if(e===null)return!0;var r=Vze.call(e,"constructor")&&e.constructor;return typeof r=="function"&&r instanceof r&&cle.call(r)==_ze}lle.exports=Xze});var LL=E((Hbt,gle)=>{function Zze(t,e){if(!(e==="constructor"&&typeof t[e]=="function")&&e!="__proto__")return t[e]}gle.exports=Zze});var hle=E((Gbt,fle)=>{var $ze=Af(),e5e=lf();function t5e(t){return $ze(t,e5e(t))}fle.exports=t5e});var Ile=E((jbt,ple)=>{var dle=NL(),r5e=UN(),i5e=jN(),n5e=HN(),s5e=YN(),Cle=Pd(),mle=As(),o5e=Ale(),a5e=Od(),A5e=zB(),l5e=Gs(),c5e=ule(),u5e=c0(),Ele=LL(),g5e=hle();function f5e(t,e,r,i,n,s,o){var a=Ele(t,r),l=Ele(e,r),c=o.get(l);if(c){dle(t,r,c);return}var u=s?s(a,l,r+"",t,e,o):void 0,g=u===void 0;if(g){var f=mle(l),h=!f&&a5e(l),p=!f&&!h&&u5e(l);u=l,f||h||p?mle(a)?u=a:o5e(a)?u=n5e(a):h?(g=!1,u=r5e(l,!0)):p?(g=!1,u=i5e(l,!0)):u=[]:c5e(l)||Cle(l)?(u=a,Cle(a)?u=g5e(a):(!l5e(a)||A5e(a))&&(u=s5e(l))):g=!1}g&&(o.set(l,u),n(u,l,i,s,o),o.delete(l)),dle(t,r,u)}ple.exports=f5e});var Ble=E((Ybt,yle)=>{var h5e=Gd(),p5e=NL(),d5e=BF(),C5e=Ile(),m5e=Gs(),E5e=lf(),I5e=LL();function wle(t,e,r,i,n){t!==e&&d5e(e,function(s,o){if(n||(n=new h5e),m5e(s))C5e(t,e,o,r,wle,i,n);else{var a=i?i(I5e(t,o),s,o+"",t,e,n):void 0;a===void 0&&(a=s),p5e(t,o,a)}},E5e)}yle.exports=wle});var ble=E((qbt,Qle)=>{var y5e=e0(),w5e=nF(),B5e=sF();function Q5e(t,e){return B5e(w5e(t,e,y5e),t+"")}Qle.exports=Q5e});var Sle=E((Jbt,vle)=>{var b5e=Kg(),v5e=Hd(),S5e=kd(),x5e=Gs();function k5e(t,e,r){if(!x5e(r))return!1;var i=typeof e;return(i=="number"?v5e(r)&&S5e(e,r.length):i=="string"&&e in r)?b5e(r[e],t):!1}vle.exports=k5e});var kle=E((Wbt,xle)=>{var P5e=ble(),D5e=Sle();function R5e(t){return P5e(function(e,r){var i=-1,n=r.length,s=n>1?r[n-1]:void 0,o=n>2?r[2]:void 0;for(s=t.length>3&&typeof s=="function"?(n--,s):void 0,o&&D5e(r[0],r[1],o)&&(s=n<3?void 0:s,n=1),e=Object(e);++i{var F5e=Ble(),N5e=kle(),L5e=N5e(function(t,e,r){F5e(t,e,r)});Ple.exports=L5e});var Wle=E(($vt,Jle)=>{var VL;Jle.exports=()=>(typeof VL=="undefined"&&(VL=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),VL)});var $le=E(XL=>{function pf(t,e){if(typeof t=="string")return t;if(t){let r,i;if(Array.isArray(t)){for(r=0;r0)return(f=pf(n[g],u))?f.replace("*",c.substring(g.length-1)):Gc(i,c,1)}return Gc(i,c)}}function l6e(t,e={}){let r=0,i,n=e.browser,s=e.fields||["module","main"];for(n&&!s.includes("browser")&&s.unshift("browser");r{var eT;nce.exports=()=>(typeof eT=="undefined"&&(eT=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),eT)});var gce=E((aT,AT)=>{(function(t){aT&&typeof aT=="object"&&typeof AT!="undefined"?AT.exports=t():typeof define=="function"&&define.amd?define([],t):typeof window!="undefined"?window.isWindows=t():typeof global!="undefined"?global.isWindows=t():typeof self!="undefined"?self.isWindows=t():this.isWindows=t()})(function(){"use strict";return function(){return process&&(process.platform==="win32"||/^(msys|cygwin)$/.test(process.env.OSTYPE))}})});var dce=E((Dxt,fce)=>{"use strict";lT.ifExists=E6e;var mf=require("util"),Es=require("path"),hce=gce(),I6e=/^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/,y6e={createPwshFile:!0,createCmdFile:hce(),fs:require("fs")},w6e=new Map([[".js","node"],[".cjs","node"],[".mjs","node"],[".cmd","cmd"],[".bat","cmd"],[".ps1","pwsh"],[".sh","sh"]]);function pce(t){let e=P(P({},y6e),t),r=e.fs;return e.fs_={chmod:r.chmod?mf.promisify(r.chmod):async()=>{},mkdir:mf.promisify(r.mkdir),readFile:mf.promisify(r.readFile),stat:mf.promisify(r.stat),unlink:mf.promisify(r.unlink),writeFile:mf.promisify(r.writeFile)},e}async function lT(t,e,r){let i=pce(r);await i.fs_.stat(t),await B6e(t,e,i)}function E6e(t,e,r){return lT(t,e,r).catch(()=>{})}function Q6e(t,e){return e.fs_.unlink(t).catch(()=>{})}async function B6e(t,e,r){let i=await S6e(t,r);return await b6e(e,r),v6e(t,e,i,r)}function b6e(t,e){return e.fs_.mkdir(Es.dirname(t),{recursive:!0})}function v6e(t,e,r,i){let n=pce(i),s=[{generator:P6e,extension:""}];return n.createCmdFile&&s.push({generator:k6e,extension:".cmd"}),n.createPwshFile&&s.push({generator:D6e,extension:".ps1"}),Promise.all(s.map(o=>x6e(t,e+o.extension,r,o.generator,n)))}function R6e(t,e){return Q6e(t,e)}function N6e(t,e){return F6e(t,e)}async function S6e(t,e){let n=(await e.fs_.readFile(t,"utf8")).trim().split(/\r*\n/)[0].match(I6e);if(!n){let s=Es.extname(t).toLowerCase();return{program:w6e.get(s)||null,additionalArgs:""}}return{program:n[1],additionalArgs:n[2]}}async function x6e(t,e,r,i,n){let s=n.preserveSymlinks?"--preserve-symlinks":"",o=[r.additionalArgs,s].filter(a=>a).join(" ");return n=Object.assign({},n,{prog:r.program,args:o}),await R6e(e,n),await n.fs_.writeFile(e,i(t,e,n),"utf8"),N6e(e,n)}function k6e(t,e,r){let n=Es.relative(Es.dirname(e),t).split("/").join("\\"),s=Es.isAbsolute(n)?`"${n}"`:`"%~dp0\\${n}"`,o,a=r.prog,l=r.args||"",c=cT(r.nodePath).win32;a?(o=`"%~dp0\\${a}.exe"`,n=s):(a=s,l="",n="");let u=r.progArgs?`${r.progArgs.join(" ")} `:"",g=c?`@SET NODE_PATH=${c}\r +`:"";return o?g+=`@IF EXIST ${o} (\r + ${o} ${l} ${n} ${u}%*\r +) ELSE (\r + @SETLOCAL\r + @SET PATHEXT=%PATHEXT:;.JS;=;%\r + ${a} ${l} ${n} ${u}%*\r +)\r +`:g+=`@${a} ${l} ${n} ${u}%*\r +`,g}function P6e(t,e,r){let i=Es.relative(Es.dirname(e),t),n=r.prog&&r.prog.split("\\").join("/"),s;i=i.split("\\").join("/");let o=Es.isAbsolute(i)?`"${i}"`:`"$basedir/${i}"`,a=r.args||"",l=cT(r.nodePath).posix;n?(s=`"$basedir/${r.prog}"`,i=o):(n=o,a="",i="");let c=r.progArgs?`${r.progArgs.join(" ")} `:"",u=`#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") + +case \`uname\` in + *CYGWIN*) basedir=\`cygpath -w "$basedir"\`;; +esac + +`,g=r.nodePath?`export NODE_PATH="${l}" +`:"";return s?u+=`${g}if [ -x ${s} ]; then + exec ${s} ${a} ${i} ${c}"$@" +else + exec ${n} ${a} ${i} ${c}"$@" +fi +`:u+=`${g}${n} ${a} ${i} ${c}"$@" +exit $? +`,u}function D6e(t,e,r){let i=Es.relative(Es.dirname(e),t),n=r.prog&&r.prog.split("\\").join("/"),s=n&&`"${n}$exe"`,o;i=i.split("\\").join("/");let a=Es.isAbsolute(i)?`"${i}"`:`"$basedir/${i}"`,l=r.args||"",c=cT(r.nodePath),u=c.win32,g=c.posix;s?(o=`"$basedir/${r.prog}$exe"`,i=a):(s=a,l="",i="");let f=r.progArgs?`${r.progArgs.join(" ")} `:"",h=`#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +${r.nodePath?`$env_node_path=$env:NODE_PATH +$env:NODE_PATH="${u}" +`:""}if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +}`;return r.nodePath&&(h+=` else { + $env:NODE_PATH="${g}" +}`),o?h+=` +$ret=0 +if (Test-Path ${o}) { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & ${o} ${l} ${i} ${f}$args + } else { + & ${o} ${l} ${i} ${f}$args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & ${s} ${l} ${i} ${f}$args + } else { + & ${s} ${l} ${i} ${f}$args + } + $ret=$LASTEXITCODE +} +${r.nodePath?`$env:NODE_PATH=$env_node_path +`:""}exit $ret +`:h+=` +# Support pipeline input +if ($MyInvocation.ExpectingInput) { + $input | & ${s} ${l} ${i} ${f}$args +} else { + & ${s} ${l} ${i} ${f}$args +} +${r.nodePath?`$env:NODE_PATH=$env_node_path +`:""}exit $LASTEXITCODE +`,h}function F6e(t,e){return e.fs_.chmod(t,493)}function cT(t){if(!t)return{win32:"",posix:""};let e=typeof t=="string"?t.split(Es.delimiter):Array.from(t),r={};for(let i=0;i`/mnt/${a.toLowerCase()}`):e[i];r.win32=r.win32?`${r.win32};${n}`:n,r.posix=r.posix?`${r.posix}:${s}`:s,r[i]={win32:n,posix:s}}return r}fce.exports=lT});var PT=E((fPt,Nce)=>{Nce.exports=require("stream")});var Oce=E((hPt,Lce)=>{"use strict";function Tce(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter(function(n){return Object.getOwnPropertyDescriptor(t,n).enumerable})),r.push.apply(r,i)}return r}function e9e(t){for(var e=1;e0?this.tail.next=i:this.head=i,this.tail=i,++this.length}},{key:"unshift",value:function(r){var i={data:r,next:this.head};this.length===0&&(this.tail=i),this.head=i,++this.length}},{key:"shift",value:function(){if(this.length!==0){var r=this.head.data;return this.length===1?this.head=this.tail=null:this.head=this.head.next,--this.length,r}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(r){if(this.length===0)return"";for(var i=this.head,n=""+i.data;i=i.next;)n+=r+i.data;return n}},{key:"concat",value:function(r){if(this.length===0)return iQ.alloc(0);for(var i=iQ.allocUnsafe(r>>>0),n=this.head,s=0;n;)o9e(n.data,i,s),s+=n.data.length,n=n.next;return i}},{key:"consume",value:function(r,i){var n;return ro.length?o.length:r;if(a===o.length?s+=o:s+=o.slice(0,r),r-=a,r===0){a===o.length?(++n,i.next?this.head=i.next:this.head=this.tail=null):(this.head=i,i.data=o.slice(a));break}++n}return this.length-=n,s}},{key:"_getBuffer",value:function(r){var i=iQ.allocUnsafe(r),n=this.head,s=1;for(n.data.copy(i),r-=n.data.length;n=n.next;){var o=n.data,a=r>o.length?o.length:r;if(o.copy(i,i.length-r,0,a),r-=a,r===0){a===o.length?(++s,n.next?this.head=n.next:this.head=this.tail=null):(this.head=n,n.data=o.slice(a));break}++s}return this.length-=s,i}},{key:s9e,value:function(r,i){return DT(this,e9e({},i,{depth:0,customInspect:!1}))}}]),t}()});var FT=E((pPt,Kce)=>{"use strict";function a9e(t,e){var r=this,i=this._readableState&&this._readableState.destroyed,n=this._writableState&&this._writableState.destroyed;return i||n?(e?e(t):t&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(RT,this,t)):process.nextTick(RT,this,t)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(t||null,function(s){!e&&s?r._writableState?r._writableState.errorEmitted?process.nextTick(nQ,r):(r._writableState.errorEmitted=!0,process.nextTick(Uce,r,s)):process.nextTick(Uce,r,s):e?(process.nextTick(nQ,r),e(s)):process.nextTick(nQ,r)}),this)}function Uce(t,e){RT(t,e),nQ(t)}function nQ(t){t._writableState&&!t._writableState.emitClose||t._readableState&&!t._readableState.emitClose||t.emit("close")}function A9e(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}function RT(t,e){t.emit("error",e)}function l9e(t,e){var r=t._readableState,i=t._writableState;r&&r.autoDestroy||i&&i.autoDestroy?t.destroy(e):t.emit("error",e)}Kce.exports={destroy:a9e,undestroy:A9e,errorOrDestroy:l9e}});var VA=E((dPt,Hce)=>{"use strict";var Gce={};function Is(t,e,r){r||(r=Error);function i(s,o,a){return typeof e=="string"?e:e(s,o,a)}class n extends r{constructor(o,a,l){super(i(o,a,l))}}n.prototype.name=r.name,n.prototype.code=t,Gce[t]=n}function jce(t,e){if(Array.isArray(t)){let r=t.length;return t=t.map(i=>String(i)),r>2?`one of ${e} ${t.slice(0,r-1).join(", ")}, or `+t[r-1]:r===2?`one of ${e} ${t[0]} or ${t[1]}`:`of ${e} ${t[0]}`}else return`of ${e} ${String(t)}`}function c9e(t,e,r){return t.substr(!r||r<0?0:+r,e.length)===e}function u9e(t,e,r){return(r===void 0||r>t.length)&&(r=t.length),t.substring(r-e.length,r)===e}function g9e(t,e,r){return typeof r!="number"&&(r=0),r+e.length>t.length?!1:t.indexOf(e,r)!==-1}Is("ERR_INVALID_OPT_VALUE",function(t,e){return'The value "'+e+'" is invalid for option "'+t+'"'},TypeError);Is("ERR_INVALID_ARG_TYPE",function(t,e,r){let i;typeof e=="string"&&c9e(e,"not ")?(i="must not be",e=e.replace(/^not /,"")):i="must be";let n;if(u9e(t," argument"))n=`The ${t} ${i} ${jce(e,"type")}`;else{let s=g9e(t,".")?"property":"argument";n=`The "${t}" ${s} ${i} ${jce(e,"type")}`}return n+=`. Received type ${typeof r}`,n},TypeError);Is("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF");Is("ERR_METHOD_NOT_IMPLEMENTED",function(t){return"The "+t+" method is not implemented"});Is("ERR_STREAM_PREMATURE_CLOSE","Premature close");Is("ERR_STREAM_DESTROYED",function(t){return"Cannot call "+t+" after a stream was destroyed"});Is("ERR_MULTIPLE_CALLBACK","Callback called multiple times");Is("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable");Is("ERR_STREAM_WRITE_AFTER_END","write after end");Is("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError);Is("ERR_UNKNOWN_ENCODING",function(t){return"Unknown encoding: "+t},TypeError);Is("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event");Hce.exports.codes=Gce});var NT=E((CPt,Yce)=>{"use strict";var f9e=VA().codes.ERR_INVALID_OPT_VALUE;function h9e(t,e,r){return t.highWaterMark!=null?t.highWaterMark:e?t[r]:null}function p9e(t,e,r,i){var n=h9e(e,i,r);if(n!=null){if(!(isFinite(n)&&Math.floor(n)===n)||n<0){var s=i?r:"highWaterMark";throw new f9e(s,n)}return Math.floor(n)}return t.objectMode?16:16*1024}Yce.exports={getHighWaterMark:p9e}});var qce=E((mPt,LT)=>{typeof Object.create=="function"?LT.exports=function(e,r){r&&(e.super_=r,e.prototype=Object.create(r.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:LT.exports=function(e,r){if(r){e.super_=r;var i=function(){};i.prototype=r.prototype,e.prototype=new i,e.prototype.constructor=e}}});var _A=E((EPt,TT)=>{try{if(MT=require("util"),typeof MT.inherits!="function")throw"";TT.exports=MT.inherits}catch(t){TT.exports=qce()}var MT});var Wce=E((IPt,Jce)=>{Jce.exports=require("util").deprecate});var UT=E((yPt,zce)=>{"use strict";zce.exports=Sr;function Vce(t){var e=this;this.next=null,this.entry=null,this.finish=function(){d9e(e,t)}}var If;Sr.WritableState=em;var C9e={deprecate:Wce()},_ce=PT(),sQ=require("buffer").Buffer,m9e=global.Uint8Array||function(){};function E9e(t){return sQ.from(t)}function I9e(t){return sQ.isBuffer(t)||t instanceof m9e}var OT=FT(),y9e=NT(),w9e=y9e.getHighWaterMark,XA=VA().codes,B9e=XA.ERR_INVALID_ARG_TYPE,Q9e=XA.ERR_METHOD_NOT_IMPLEMENTED,b9e=XA.ERR_MULTIPLE_CALLBACK,v9e=XA.ERR_STREAM_CANNOT_PIPE,S9e=XA.ERR_STREAM_DESTROYED,x9e=XA.ERR_STREAM_NULL_VALUES,k9e=XA.ERR_STREAM_WRITE_AFTER_END,P9e=XA.ERR_UNKNOWN_ENCODING,yf=OT.errorOrDestroy;_A()(Sr,_ce);function D9e(){}function em(t,e,r){If=If||Yc(),t=t||{},typeof r!="boolean"&&(r=e instanceof If),this.objectMode=!!t.objectMode,r&&(this.objectMode=this.objectMode||!!t.writableObjectMode),this.highWaterMark=w9e(this,t,"writableHighWaterMark",r),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var i=t.decodeStrings===!1;this.decodeStrings=!i,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(n){R9e(e,n)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=t.emitClose!==!1,this.autoDestroy=!!t.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new Vce(this)}em.prototype.getBuffer=function(){for(var e=this.bufferedRequest,r=[];e;)r.push(e),e=e.next;return r};(function(){try{Object.defineProperty(em.prototype,"buffer",{get:C9e.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(t){}})();var oQ;typeof Symbol=="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]=="function"?(oQ=Function.prototype[Symbol.hasInstance],Object.defineProperty(Sr,Symbol.hasInstance,{value:function(e){return oQ.call(this,e)?!0:this!==Sr?!1:e&&e._writableState instanceof em}})):oQ=function(e){return e instanceof this};function Sr(t){If=If||Yc();var e=this instanceof If;if(!e&&!oQ.call(Sr,this))return new Sr(t);this._writableState=new em(t,this,e),this.writable=!0,t&&(typeof t.write=="function"&&(this._write=t.write),typeof t.writev=="function"&&(this._writev=t.writev),typeof t.destroy=="function"&&(this._destroy=t.destroy),typeof t.final=="function"&&(this._final=t.final)),_ce.call(this)}Sr.prototype.pipe=function(){yf(this,new v9e)};function F9e(t,e){var r=new k9e;yf(t,r),process.nextTick(e,r)}function N9e(t,e,r,i){var n;return r===null?n=new x9e:typeof r!="string"&&!e.objectMode&&(n=new B9e("chunk",["string","Buffer"],r)),n?(yf(t,n),process.nextTick(i,n),!1):!0}Sr.prototype.write=function(t,e,r){var i=this._writableState,n=!1,s=!i.objectMode&&I9e(t);return s&&!sQ.isBuffer(t)&&(t=E9e(t)),typeof e=="function"&&(r=e,e=null),s?e="buffer":e||(e=i.defaultEncoding),typeof r!="function"&&(r=D9e),i.ending?F9e(this,r):(s||N9e(this,i,t,r))&&(i.pendingcb++,n=L9e(this,i,s,t,e,r)),n};Sr.prototype.cork=function(){this._writableState.corked++};Sr.prototype.uncork=function(){var t=this._writableState;t.corked&&(t.corked--,!t.writing&&!t.corked&&!t.bufferProcessing&&t.bufferedRequest&&Xce(this,t))};Sr.prototype.setDefaultEncoding=function(e){if(typeof e=="string"&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new P9e(e);return this._writableState.defaultEncoding=e,this};Object.defineProperty(Sr.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});function T9e(t,e,r){return!t.objectMode&&t.decodeStrings!==!1&&typeof e=="string"&&(e=sQ.from(e,r)),e}Object.defineProperty(Sr.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});function L9e(t,e,r,i,n,s){if(!r){var o=T9e(e,i,n);i!==o&&(r=!0,n="buffer",i=o)}var a=e.objectMode?1:i.length;e.length+=a;var l=e.length{"use strict";var j9e=Object.keys||function(t){var e=[];for(var r in t)e.push(r);return e};eue.exports=Mo;var tue=HT(),GT=UT();_A()(Mo,tue);for(jT=j9e(GT.prototype),aQ=0;aQ{var lQ=require("buffer"),qa=lQ.Buffer;function iue(t,e){for(var r in t)e[r]=t[r]}qa.from&&qa.alloc&&qa.allocUnsafe&&qa.allocUnsafeSlow?rue.exports=lQ:(iue(lQ,YT),YT.Buffer=wf);function wf(t,e,r){return qa(t,e,r)}iue(qa,wf);wf.from=function(t,e,r){if(typeof t=="number")throw new TypeError("Argument must not be a number");return qa(t,e,r)};wf.alloc=function(t,e,r){if(typeof t!="number")throw new TypeError("Argument must be a number");var i=qa(t);return e!==void 0?typeof r=="string"?i.fill(e,r):i.fill(e):i.fill(0),i};wf.allocUnsafe=function(t){if(typeof t!="number")throw new TypeError("Argument must be a number");return qa(t)};wf.allocUnsafeSlow=function(t){if(typeof t!="number")throw new TypeError("Argument must be a number");return lQ.SlowBuffer(t)}});var WT=E(sue=>{"use strict";var qT=nue().Buffer,oue=qT.isEncoding||function(t){switch(t=""+t,t&&t.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function J9e(t){if(!t)return"utf8";for(var e;;)switch(t){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return t;default:if(e)return;t=(""+t).toLowerCase(),e=!0}}function W9e(t){var e=J9e(t);if(typeof e!="string"&&(qT.isEncoding===oue||!oue(t)))throw new Error("Unknown encoding: "+t);return e||t}sue.StringDecoder=rm;function rm(t){this.encoding=W9e(t);var e;switch(this.encoding){case"utf16le":this.text=V9e,this.end=_9e,e=4;break;case"utf8":this.fillLast=z9e,e=4;break;case"base64":this.text=X9e,this.end=Z9e,e=3;break;default:this.write=$9e,this.end=eVe;return}this.lastNeed=0,this.lastTotal=0,this.lastChar=qT.allocUnsafe(e)}rm.prototype.write=function(t){if(t.length===0)return"";var e,r;if(this.lastNeed){if(e=this.fillLast(t),e===void 0)return"";r=this.lastNeed,this.lastNeed=0}else r=0;return r>5==6?2:t>>4==14?3:t>>3==30?4:t>>6==2?-1:-2}function iVe(t,e,r){var i=e.length-1;if(i=0?(n>0&&(t.lastNeed=n-1),n):--i=0?(n>0&&(t.lastNeed=n-2),n):--i=0?(n>0&&(n===2?n=0:t.lastNeed=n-3),n):0))}function nVe(t,e,r){if((e[0]&192)!=128)return t.lastNeed=0,"\uFFFD";if(t.lastNeed>1&&e.length>1){if((e[1]&192)!=128)return t.lastNeed=1,"\uFFFD";if(t.lastNeed>2&&e.length>2&&(e[2]&192)!=128)return t.lastNeed=2,"\uFFFD"}}function z9e(t){var e=this.lastTotal-this.lastNeed,r=nVe(this,t,e);if(r!==void 0)return r;if(this.lastNeed<=t.length)return t.copy(this.lastChar,e,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);t.copy(this.lastChar,e,0,t.length),this.lastNeed-=t.length}function rVe(t,e){var r=iVe(this,t,e);if(!this.lastNeed)return t.toString("utf8",e);this.lastTotal=r;var i=t.length-(r-this.lastNeed);return t.copy(this.lastChar,0,i),t.toString("utf8",e,i)}function tVe(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+"\uFFFD":e}function V9e(t,e){if((t.length-e)%2==0){var r=t.toString("utf16le",e);if(r){var i=r.charCodeAt(r.length-1);if(i>=55296&&i<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1],r.slice(0,-1)}return r}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=t[t.length-1],t.toString("utf16le",e,t.length-1)}function _9e(t){var e=t&&t.length?this.write(t):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return e+this.lastChar.toString("utf16le",0,r)}return e}function X9e(t,e){var r=(t.length-e)%3;return r===0?t.toString("base64",e):(this.lastNeed=3-r,this.lastTotal=3,r===1?this.lastChar[0]=t[t.length-1]:(this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1]),t.toString("base64",e,t.length-r))}function Z9e(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+this.lastChar.toString("base64",0,3-this.lastNeed):e}function $9e(t){return t.toString(this.encoding)}function eVe(t){return t&&t.length?this.write(t):""}});var cQ=E((QPt,aue)=>{"use strict";var Aue=VA().codes.ERR_STREAM_PREMATURE_CLOSE;function sVe(t){var e=!1;return function(){if(!e){e=!0;for(var r=arguments.length,i=new Array(r),n=0;n{"use strict";var uQ;function ZA(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}var AVe=cQ(),$A=Symbol("lastResolve"),qc=Symbol("lastReject"),im=Symbol("error"),gQ=Symbol("ended"),Jc=Symbol("lastPromise"),zT=Symbol("handlePromise"),Wc=Symbol("stream");function el(t,e){return{value:t,done:e}}function lVe(t){var e=t[$A];if(e!==null){var r=t[Wc].read();r!==null&&(t[Jc]=null,t[$A]=null,t[qc]=null,e(el(r,!1)))}}function cVe(t){process.nextTick(lVe,t)}function uVe(t,e){return function(r,i){t.then(function(){if(e[gQ]){r(el(void 0,!0));return}e[zT](r,i)},i)}}var gVe=Object.getPrototypeOf(function(){}),fVe=Object.setPrototypeOf((uQ={get stream(){return this[Wc]},next:function(){var e=this,r=this[im];if(r!==null)return Promise.reject(r);if(this[gQ])return Promise.resolve(el(void 0,!0));if(this[Wc].destroyed)return new Promise(function(o,a){process.nextTick(function(){e[im]?a(e[im]):o(el(void 0,!0))})});var i=this[Jc],n;if(i)n=new Promise(uVe(i,this));else{var s=this[Wc].read();if(s!==null)return Promise.resolve(el(s,!1));n=new Promise(this[zT])}return this[Jc]=n,n}},ZA(uQ,Symbol.asyncIterator,function(){return this}),ZA(uQ,"return",function(){var e=this;return new Promise(function(r,i){e[Wc].destroy(null,function(n){if(n){i(n);return}r(el(void 0,!0))})})}),uQ),gVe),hVe=function(e){var r,i=Object.create(fVe,(r={},ZA(r,Wc,{value:e,writable:!0}),ZA(r,$A,{value:null,writable:!0}),ZA(r,qc,{value:null,writable:!0}),ZA(r,im,{value:null,writable:!0}),ZA(r,gQ,{value:e._readableState.endEmitted,writable:!0}),ZA(r,zT,{value:function(s,o){var a=i[Wc].read();a?(i[Jc]=null,i[$A]=null,i[qc]=null,s(el(a,!1))):(i[$A]=s,i[qc]=o)},writable:!0}),r));return i[Jc]=null,AVe(e,function(n){if(n&&n.code!=="ERR_STREAM_PREMATURE_CLOSE"){var s=i[qc];s!==null&&(i[Jc]=null,i[$A]=null,i[qc]=null,s(n)),i[im]=n;return}var o=i[$A];o!==null&&(i[Jc]=null,i[$A]=null,i[qc]=null,o(el(void 0,!0))),i[gQ]=!0}),e.on("readable",cVe.bind(null,i)),i};cue.exports=hVe});var pue=E((vPt,gue)=>{"use strict";function fue(t,e,r,i,n,s,o){try{var a=t[s](o),l=a.value}catch(c){r(c);return}a.done?e(l):Promise.resolve(l).then(i,n)}function pVe(t){return function(){var e=this,r=arguments;return new Promise(function(i,n){var s=t.apply(e,r);function o(l){fue(s,i,n,o,a,"next",l)}function a(l){fue(s,i,n,o,a,"throw",l)}o(void 0)})}}function hue(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter(function(n){return Object.getOwnPropertyDescriptor(t,n).enumerable})),r.push.apply(r,i)}return r}function CVe(t){for(var e=1;e{"use strict";due.exports=kt;var Bf;kt.ReadableState=Cue;var SPt=require("events").EventEmitter,mue=function(e,r){return e.listeners(r).length},nm=PT(),fQ=require("buffer").Buffer,IVe=global.Uint8Array||function(){};function yVe(t){return fQ.from(t)}function wVe(t){return fQ.isBuffer(t)||t instanceof IVe}var VT=require("util"),Et;VT&&VT.debuglog?Et=VT.debuglog("stream"):Et=function(){};var BVe=Oce(),_T=FT(),QVe=NT(),bVe=QVe.getHighWaterMark,hQ=VA().codes,vVe=hQ.ERR_INVALID_ARG_TYPE,SVe=hQ.ERR_STREAM_PUSH_AFTER_EOF,xVe=hQ.ERR_METHOD_NOT_IMPLEMENTED,kVe=hQ.ERR_STREAM_UNSHIFT_AFTER_END_EVENT,Qf,XT,ZT;_A()(kt,nm);var sm=_T.errorOrDestroy,$T=["error","close","destroy","pause","resume"];function PVe(t,e,r){if(typeof t.prependListener=="function")return t.prependListener(e,r);!t._events||!t._events[e]?t.on(e,r):Array.isArray(t._events[e])?t._events[e].unshift(r):t._events[e]=[r,t._events[e]]}function Cue(t,e,r){Bf=Bf||Yc(),t=t||{},typeof r!="boolean"&&(r=e instanceof Bf),this.objectMode=!!t.objectMode,r&&(this.objectMode=this.objectMode||!!t.readableObjectMode),this.highWaterMark=bVe(this,t,"readableHighWaterMark",r),this.buffer=new BVe,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=t.emitClose!==!1,this.autoDestroy=!!t.autoDestroy,this.destroyed=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(Qf||(Qf=WT().StringDecoder),this.decoder=new Qf(t.encoding),this.encoding=t.encoding)}function kt(t){if(Bf=Bf||Yc(),!(this instanceof kt))return new kt(t);var e=this instanceof Bf;this._readableState=new Cue(t,this,e),this.readable=!0,t&&(typeof t.read=="function"&&(this._read=t.read),typeof t.destroy=="function"&&(this._destroy=t.destroy)),nm.call(this)}Object.defineProperty(kt.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0?!1:this._readableState.destroyed},set:function(e){!this._readableState||(this._readableState.destroyed=e)}});kt.prototype.destroy=_T.destroy;kt.prototype._undestroy=_T.undestroy;kt.prototype._destroy=function(t,e){e(t)};kt.prototype.push=function(t,e){var r=this._readableState,i;return r.objectMode?i=!0:typeof t=="string"&&(e=e||r.defaultEncoding,e!==r.encoding&&(t=fQ.from(t,e),e=""),i=!0),Eue(this,t,e,!1,i)};kt.prototype.unshift=function(t){return Eue(this,t,null,!0,!1)};function Eue(t,e,r,i,n){Et("readableAddChunk",e);var s=t._readableState;if(e===null)s.reading=!1,RVe(t,s);else{var o;if(n||(o=DVe(s,e)),o)sm(t,o);else if(s.objectMode||e&&e.length>0)if(typeof e!="string"&&!s.objectMode&&Object.getPrototypeOf(e)!==fQ.prototype&&(e=yVe(e)),i)s.endEmitted?sm(t,new kVe):eM(t,s,e,!0);else if(s.ended)sm(t,new SVe);else{if(s.destroyed)return!1;s.reading=!1,s.decoder&&!r?(e=s.decoder.write(e),s.objectMode||e.length!==0?eM(t,s,e,!1):tM(t,s)):eM(t,s,e,!1)}else i||(s.reading=!1,tM(t,s))}return!s.ended&&(s.length=Iue?t=Iue:(t--,t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,t|=t>>>16,t++),t}function yue(t,e){return t<=0||e.length===0&&e.ended?0:e.objectMode?1:t!==t?e.flowing&&e.length?e.buffer.head.data.length:e.length:(t>e.highWaterMark&&(e.highWaterMark=FVe(t)),t<=e.length?t:e.ended?e.length:(e.needReadable=!0,0))}kt.prototype.read=function(t){Et("read",t),t=parseInt(t,10);var e=this._readableState,r=t;if(t!==0&&(e.emittedReadable=!1),t===0&&e.needReadable&&((e.highWaterMark!==0?e.length>=e.highWaterMark:e.length>0)||e.ended))return Et("read: emitReadable",e.length,e.ended),e.length===0&&e.ended?rM(this):pQ(this),null;if(t=yue(t,e),t===0&&e.ended)return e.length===0&&rM(this),null;var i=e.needReadable;Et("need readable",i),(e.length===0||e.length-t0?n=wue(t,e):n=null,n===null?(e.needReadable=e.length<=e.highWaterMark,t=0):(e.length-=t,e.awaitDrain=0),e.length===0&&(e.ended||(e.needReadable=!0),r!==t&&e.ended&&rM(this)),n!==null&&this.emit("data",n),n};function RVe(t,e){if(Et("onEofChunk"),!e.ended){if(e.decoder){var r=e.decoder.end();r&&r.length&&(e.buffer.push(r),e.length+=e.objectMode?1:r.length)}e.ended=!0,e.sync?pQ(t):(e.needReadable=!1,e.emittedReadable||(e.emittedReadable=!0,Bue(t)))}}function pQ(t){var e=t._readableState;Et("emitReadable",e.needReadable,e.emittedReadable),e.needReadable=!1,e.emittedReadable||(Et("emitReadable",e.flowing),e.emittedReadable=!0,process.nextTick(Bue,t))}function Bue(t){var e=t._readableState;Et("emitReadable_",e.destroyed,e.length,e.ended),!e.destroyed&&(e.length||e.ended)&&(t.emit("readable"),e.emittedReadable=!1),e.needReadable=!e.flowing&&!e.ended&&e.length<=e.highWaterMark,iM(t)}function tM(t,e){e.readingMore||(e.readingMore=!0,process.nextTick(NVe,t,e))}function NVe(t,e){for(;!e.reading&&!e.ended&&(e.length1&&Que(i.pipes,t)!==-1)&&!c&&(Et("false write response, pause",i.awaitDrain),i.awaitDrain++),r.pause())}function f(m){Et("onerror",m),d(),t.removeListener("error",f),mue(t,"error")===0&&sm(t,m)}PVe(t,"error",f);function h(){t.removeListener("finish",p),d()}t.once("close",h);function p(){Et("onfinish"),t.removeListener("close",h),d()}t.once("finish",p);function d(){Et("unpipe"),r.unpipe(t)}return t.emit("pipe",r),i.flowing||(Et("pipe resume"),r.resume()),t};function LVe(t){return function(){var r=t._readableState;Et("pipeOnDrain",r.awaitDrain),r.awaitDrain&&r.awaitDrain--,r.awaitDrain===0&&mue(t,"data")&&(r.flowing=!0,iM(t))}}kt.prototype.unpipe=function(t){var e=this._readableState,r={hasUnpiped:!1};if(e.pipesCount===0)return this;if(e.pipesCount===1)return t&&t!==e.pipes?this:(t||(t=e.pipes),e.pipes=null,e.pipesCount=0,e.flowing=!1,t&&t.emit("unpipe",this,r),this);if(!t){var i=e.pipes,n=e.pipesCount;e.pipes=null,e.pipesCount=0,e.flowing=!1;for(var s=0;s0,i.flowing!==!1&&this.resume()):t==="readable"&&!i.endEmitted&&!i.readableListening&&(i.readableListening=i.needReadable=!0,i.flowing=!1,i.emittedReadable=!1,Et("on readable",i.length,i.reading),i.length?pQ(this):i.reading||process.nextTick(TVe,this)),r};kt.prototype.addListener=kt.prototype.on;kt.prototype.removeListener=function(t,e){var r=nm.prototype.removeListener.call(this,t,e);return t==="readable"&&process.nextTick(bue,this),r};kt.prototype.removeAllListeners=function(t){var e=nm.prototype.removeAllListeners.apply(this,arguments);return(t==="readable"||t===void 0)&&process.nextTick(bue,this),e};function bue(t){var e=t._readableState;e.readableListening=t.listenerCount("readable")>0,e.resumeScheduled&&!e.paused?e.flowing=!0:t.listenerCount("data")>0&&t.resume()}function TVe(t){Et("readable nexttick read 0"),t.read(0)}kt.prototype.resume=function(){var t=this._readableState;return t.flowing||(Et("resume"),t.flowing=!t.readableListening,MVe(this,t)),t.paused=!1,this};function MVe(t,e){e.resumeScheduled||(e.resumeScheduled=!0,process.nextTick(OVe,t,e))}function OVe(t,e){Et("resume",e.reading),e.reading||t.read(0),e.resumeScheduled=!1,t.emit("resume"),iM(t),e.flowing&&!e.reading&&t.read(0)}kt.prototype.pause=function(){return Et("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1&&(Et("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this};function iM(t){var e=t._readableState;for(Et("flow",e.flowing);e.flowing&&t.read()!==null;);}kt.prototype.wrap=function(t){var e=this,r=this._readableState,i=!1;t.on("end",function(){if(Et("wrapped end"),r.decoder&&!r.ended){var o=r.decoder.end();o&&o.length&&e.push(o)}e.push(null)}),t.on("data",function(o){if(Et("wrapped data"),r.decoder&&(o=r.decoder.write(o)),!(r.objectMode&&o==null)&&!(!r.objectMode&&(!o||!o.length))){var a=e.push(o);a||(i=!0,t.pause())}});for(var n in t)this[n]===void 0&&typeof t[n]=="function"&&(this[n]=function(a){return function(){return t[a].apply(t,arguments)}}(n));for(var s=0;s<$T.length;s++)t.on($T[s],this.emit.bind(this,$T[s]));return this._read=function(o){Et("wrapped _read",o),i&&(i=!1,t.resume())},this};typeof Symbol=="function"&&(kt.prototype[Symbol.asyncIterator]=function(){return XT===void 0&&(XT=uue()),XT(this)});Object.defineProperty(kt.prototype,"readableHighWaterMark",{enumerable:!1,get:function(){return this._readableState.highWaterMark}});Object.defineProperty(kt.prototype,"readableBuffer",{enumerable:!1,get:function(){return this._readableState&&this._readableState.buffer}});Object.defineProperty(kt.prototype,"readableFlowing",{enumerable:!1,get:function(){return this._readableState.flowing},set:function(e){this._readableState&&(this._readableState.flowing=e)}});kt._fromList=wue;Object.defineProperty(kt.prototype,"readableLength",{enumerable:!1,get:function(){return this._readableState.length}});function wue(t,e){if(e.length===0)return null;var r;return e.objectMode?r=e.buffer.shift():!t||t>=e.length?(e.decoder?r=e.buffer.join(""):e.buffer.length===1?r=e.buffer.first():r=e.buffer.concat(e.length),e.buffer.clear()):r=e.buffer.consume(t,e.decoder),r}function rM(t){var e=t._readableState;Et("endReadable",e.endEmitted),e.endEmitted||(e.ended=!0,process.nextTick(KVe,e,t))}function KVe(t,e){if(Et("endReadableNT",t.endEmitted,t.length),!t.endEmitted&&t.length===0&&(t.endEmitted=!0,e.readable=!1,e.emit("end"),t.autoDestroy)){var r=e._writableState;(!r||r.autoDestroy&&r.finished)&&e.destroy()}}typeof Symbol=="function"&&(kt.from=function(t,e){return ZT===void 0&&(ZT=pue()),ZT(kt,t,e)});function Que(t,e){for(var r=0,i=t.length;r{"use strict";vue.exports=Ja;var dQ=VA().codes,UVe=dQ.ERR_METHOD_NOT_IMPLEMENTED,HVe=dQ.ERR_MULTIPLE_CALLBACK,GVe=dQ.ERR_TRANSFORM_ALREADY_TRANSFORMING,jVe=dQ.ERR_TRANSFORM_WITH_LENGTH_0,CQ=Yc();_A()(Ja,CQ);function YVe(t,e){var r=this._transformState;r.transforming=!1;var i=r.writecb;if(i===null)return this.emit("error",new HVe);r.writechunk=null,r.writecb=null,e!=null&&this.push(e),i(t);var n=this._readableState;n.reading=!1,(n.needReadable||n.length{"use strict";xue.exports=om;var kue=nM();_A()(om,kue);function om(t){if(!(this instanceof om))return new om(t);kue.call(this,t)}om.prototype._transform=function(t,e,r){r(null,t)}});var Lue=E((DPt,Due)=>{"use strict";var sM;function JVe(t){var e=!1;return function(){e||(e=!0,t.apply(void 0,arguments))}}var Rue=VA().codes,WVe=Rue.ERR_MISSING_ARGS,zVe=Rue.ERR_STREAM_DESTROYED;function Fue(t){if(t)throw t}function VVe(t){return t.setHeader&&typeof t.abort=="function"}function _Ve(t,e,r,i){i=JVe(i);var n=!1;t.on("close",function(){n=!0}),sM===void 0&&(sM=cQ()),sM(t,{readable:e,writable:r},function(o){if(o)return i(o);n=!0,i()});var s=!1;return function(o){if(!n&&!s){if(s=!0,VVe(t))return t.abort();if(typeof t.destroy=="function")return t.destroy();i(o||new zVe("pipe"))}}}function Nue(t){t()}function XVe(t,e){return t.pipe(e)}function ZVe(t){return!t.length||typeof t[t.length-1]!="function"?Fue:t.pop()}function $Ve(){for(var t=arguments.length,e=new Array(t),r=0;r0;return _Ve(o,l,c,function(u){n||(n=u),u&&s.forEach(Nue),!l&&(s.forEach(Nue),i(n))})});return e.reduce(XVe)}Due.exports=$Ve});var bf=E((ys,am)=>{var Am=require("stream");process.env.READABLE_STREAM==="disable"&&Am?(am.exports=Am.Readable,Object.assign(am.exports,Am),am.exports.Stream=Am):(ys=am.exports=HT(),ys.Stream=Am||ys,ys.Readable=ys,ys.Writable=UT(),ys.Duplex=Yc(),ys.Transform=nM(),ys.PassThrough=Pue(),ys.finished=cQ(),ys.pipeline=Lue())});var Oue=E((RPt,Tue)=>{"use strict";var{Buffer:_s}=require("buffer"),Mue=Symbol.for("BufferList");function nr(t){if(!(this instanceof nr))return new nr(t);nr._init.call(this,t)}nr._init=function(e){Object.defineProperty(this,Mue,{value:!0}),this._bufs=[],this.length=0,e&&this.append(e)};nr.prototype._new=function(e){return new nr(e)};nr.prototype._offset=function(e){if(e===0)return[0,0];let r=0;for(let i=0;ithis.length||e<0)return;let r=this._offset(e);return this._bufs[r[0]][r[1]]};nr.prototype.slice=function(e,r){return typeof e=="number"&&e<0&&(e+=this.length),typeof r=="number"&&r<0&&(r+=this.length),this.copy(null,0,e,r)};nr.prototype.copy=function(e,r,i,n){if((typeof i!="number"||i<0)&&(i=0),(typeof n!="number"||n>this.length)&&(n=this.length),i>=this.length||n<=0)return e||_s.alloc(0);let s=!!e,o=this._offset(i),a=n-i,l=a,c=s&&r||0,u=o[1];if(i===0&&n===this.length){if(!s)return this._bufs.length===1?this._bufs[0]:_s.concat(this._bufs,this.length);for(let g=0;gf)this._bufs[g].copy(e,c,u),c+=f;else{this._bufs[g].copy(e,c,u,u+l),c+=f;break}l-=f,u&&(u=0)}return e.length>c?e.slice(0,c):e};nr.prototype.shallowSlice=function(e,r){if(e=e||0,r=typeof r!="number"?this.length:r,e<0&&(e+=this.length),r<0&&(r+=this.length),e===r)return this._new();let i=this._offset(e),n=this._offset(r),s=this._bufs.slice(i[0],n[0]+1);return n[1]===0?s.pop():s[s.length-1]=s[s.length-1].slice(0,n[1]),i[1]!==0&&(s[0]=s[0].slice(i[1])),this._new(s)};nr.prototype.toString=function(e,r,i){return this.slice(r,i).toString(e)};nr.prototype.consume=function(e){if(e=Math.trunc(e),Number.isNaN(e)||e<=0)return this;for(;this._bufs.length;)if(e>=this._bufs[0].length)e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift();else{this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}return this};nr.prototype.duplicate=function(){let e=this._new();for(let r=0;rthis.length?this.length:e;let i=this._offset(e),n=i[0],s=i[1];for(;n=t.length){let l=o.indexOf(t,s);if(l!==-1)return this._reverseOffset([n,l]);s=o.length-t.length+1}else{let l=this._reverseOffset([n,s]);if(this._match(l,t))return l;s++}s=0}return-1};nr.prototype._match=function(t,e){if(this.length-t{"use strict";var oM=bf().Duplex,e7e=_A(),lm=Oue();function Oi(t){if(!(this instanceof Oi))return new Oi(t);if(typeof t=="function"){this._callback=t;let e=function(i){this._callback&&(this._callback(i),this._callback=null)}.bind(this);this.on("pipe",function(i){i.on("error",e)}),this.on("unpipe",function(i){i.removeListener("error",e)}),t=null}lm._init.call(this,t),oM.call(this)}e7e(Oi,oM);Object.assign(Oi.prototype,lm.prototype);Oi.prototype._new=function(e){return new Oi(e)};Oi.prototype._write=function(e,r,i){this._appendBuffer(e),typeof i=="function"&&i()};Oi.prototype._read=function(e){if(!this.length)return this.push(null);e=Math.min(e,this.length),this.push(this.slice(0,e)),this.consume(e)};Oi.prototype.end=function(e){oM.prototype.end.call(this,e),this._callback&&(this._callback(null,this.slice()),this._callback=null)};Oi.prototype._destroy=function(e,r){this._bufs.length=0,this.length=0,r(e)};Oi.prototype._isBufferList=function(e){return e instanceof Oi||e instanceof lm||Oi.isBufferList(e)};Oi.isBufferList=lm.isBufferList;mQ.exports=Oi;mQ.exports.BufferListStream=Oi;mQ.exports.BufferList=lm});var lM=E(vf=>{var t7e=Buffer.alloc,r7e="0000000000000000000",i7e="7777777777777777777",Uue="0".charCodeAt(0),Hue=Buffer.from("ustar\0","binary"),n7e=Buffer.from("00","binary"),s7e=Buffer.from("ustar ","binary"),o7e=Buffer.from(" \0","binary"),a7e=parseInt("7777",8),cm=257,aM=263,A7e=function(t,e,r){return typeof t!="number"?r:(t=~~t,t>=e?e:t>=0||(t+=e,t>=0)?t:0)},l7e=function(t){switch(t){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null},c7e=function(t){switch(t){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0},Gue=function(t,e,r,i){for(;re?i7e.slice(0,e)+" ":r7e.slice(0,e-t.length)+t+" "};function u7e(t){var e;if(t[0]===128)e=!0;else if(t[0]===255)e=!1;else return null;for(var r=[],i=t.length-1;i>0;i--){var n=t[i];e?r.push(n):r.push(255-n)}var s=0,o=r.length;for(i=0;i=Math.pow(10,r)&&r++,e+r+t};vf.decodeLongPath=function(t,e){return Sf(t,0,t.length,e)};vf.encodePax=function(t){var e="";t.name&&(e+=AM(" path="+t.name+` +`)),t.linkname&&(e+=AM(" linkpath="+t.linkname+` +`));var r=t.pax;if(r)for(var i in r)e+=AM(" "+i+"="+r[i]+` +`);return Buffer.from(e)};vf.decodePax=function(t){for(var e={};t.length;){for(var r=0;r100;){var n=r.indexOf("/");if(n===-1)return null;i+=i?"/"+r.slice(0,n):r.slice(0,n),r=r.slice(n+1)}return Buffer.byteLength(r)>100||Buffer.byteLength(i)>155||t.linkname&&Buffer.byteLength(t.linkname)>100?null:(e.write(r),e.write(tl(t.mode&a7e,6),100),e.write(tl(t.uid,6),108),e.write(tl(t.gid,6),116),e.write(tl(t.size,11),124),e.write(tl(t.mtime.getTime()/1e3|0,11),136),e[156]=Uue+c7e(t.type),t.linkname&&e.write(t.linkname,157),Hue.copy(e,cm),n7e.copy(e,aM),t.uname&&e.write(t.uname,265),t.gname&&e.write(t.gname,297),e.write(tl(t.devmajor||0,6),329),e.write(tl(t.devminor||0,6),337),i&&e.write(i,345),e.write(tl(jue(e),6),148),e)};vf.decode=function(t,e,r){var i=t[156]===0?0:t[156]-Uue,n=Sf(t,0,100,e),s=rl(t,100,8),o=rl(t,108,8),a=rl(t,116,8),l=rl(t,124,12),c=rl(t,136,12),u=l7e(i),g=t[157]===0?null:Sf(t,157,100,e),f=Sf(t,265,32),h=Sf(t,297,32),p=rl(t,329,8),d=rl(t,337,8),m=jue(t);if(m===8*32)return null;if(m!==rl(t,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(Hue.compare(t,cm,cm+6)===0)t[345]&&(n=Sf(t,345,155,e)+"/"+n);else if(!(s7e.compare(t,cm,cm+6)===0&&o7e.compare(t,aM,aM+2)===0)){if(!r)throw new Error("Invalid tar header: unknown format.")}return i===0&&n&&n[n.length-1]==="/"&&(i=5),{name:n,mode:s,uid:o,gid:a,size:l,mtime:new Date(1e3*c),type:u,linkname:g,uname:f,gname:h,devmajor:p,devminor:d}}});var _ue=E((LPt,Yue)=>{var que=require("util"),g7e=Kue(),um=lM(),Jue=bf().Writable,Wue=bf().PassThrough,zue=function(){},Vue=function(t){return t&=511,t&&512-t},f7e=function(t,e){var r=new EQ(t,e);return r.end(),r},h7e=function(t,e){return e.path&&(t.name=e.path),e.linkpath&&(t.linkname=e.linkpath),e.size&&(t.size=parseInt(e.size,10)),t.pax=e,t},EQ=function(t,e){this._parent=t,this.offset=e,Wue.call(this,{autoDestroy:!1})};que.inherits(EQ,Wue);EQ.prototype.destroy=function(t){this._parent.destroy(t)};var Wa=function(t){if(!(this instanceof Wa))return new Wa(t);Jue.call(this,t),t=t||{},this._offset=0,this._buffer=g7e(),this._missing=0,this._partial=!1,this._onparse=zue,this._header=null,this._stream=null,this._overflow=null,this._cb=null,this._locked=!1,this._destroyed=!1,this._pax=null,this._paxGlobal=null,this._gnuLongPath=null,this._gnuLongLinkPath=null;var e=this,r=e._buffer,i=function(){e._continue()},n=function(f){if(e._locked=!1,f)return e.destroy(f);e._stream||i()},s=function(){e._stream=null;var f=Vue(e._header.size);f?e._parse(f,o):e._parse(512,g),e._locked||i()},o=function(){e._buffer.consume(Vue(e._header.size)),e._parse(512,g),i()},a=function(){var f=e._header.size;e._paxGlobal=um.decodePax(r.slice(0,f)),r.consume(f),s()},l=function(){var f=e._header.size;e._pax=um.decodePax(r.slice(0,f)),e._paxGlobal&&(e._pax=Object.assign({},e._paxGlobal,e._pax)),r.consume(f),s()},c=function(){var f=e._header.size;this._gnuLongPath=um.decodeLongPath(r.slice(0,f),t.filenameEncoding),r.consume(f),s()},u=function(){var f=e._header.size;this._gnuLongLinkPath=um.decodeLongPath(r.slice(0,f),t.filenameEncoding),r.consume(f),s()},g=function(){var f=e._offset,h;try{h=e._header=um.decode(r.slice(0,512),t.filenameEncoding,t.allowUnknownFormat)}catch(p){e.emit("error",p)}if(r.consume(512),!h){e._parse(512,g),i();return}if(h.type==="gnu-long-path"){e._parse(h.size,c),i();return}if(h.type==="gnu-long-link-path"){e._parse(h.size,u),i();return}if(h.type==="pax-global-header"){e._parse(h.size,a),i();return}if(h.type==="pax-header"){e._parse(h.size,l),i();return}if(e._gnuLongPath&&(h.name=e._gnuLongPath,e._gnuLongPath=null),e._gnuLongLinkPath&&(h.linkname=e._gnuLongLinkPath,e._gnuLongLinkPath=null),e._pax&&(e._header=h=h7e(h,e._pax),e._pax=null),e._locked=!0,!h.size||h.type==="directory"){e._parse(512,g),e.emit("entry",h,f7e(e,f),n);return}e._stream=new EQ(e,f),e.emit("entry",h,e._stream,n),e._parse(h.size,s),i()};this._onheader=g,this._parse(512,g)};que.inherits(Wa,Jue);Wa.prototype.destroy=function(t){this._destroyed||(this._destroyed=!0,t&&this.emit("error",t),this.emit("close"),this._stream&&this._stream.emit("close"))};Wa.prototype._parse=function(t,e){this._destroyed||(this._offset+=t,this._missing=t,e===this._onheader&&(this._partial=!1),this._onparse=e)};Wa.prototype._continue=function(){if(!this._destroyed){var t=this._cb;this._cb=zue,this._overflow?this._write(this._overflow,void 0,t):t()}};Wa.prototype._write=function(t,e,r){if(!this._destroyed){var i=this._stream,n=this._buffer,s=this._missing;if(t.length&&(this._partial=!0),t.lengths&&(o=t.slice(s),t=t.slice(0,s)),i?i.end(t):n.append(t),this._overflow=o,this._onparse()}};Wa.prototype._final=function(t){if(this._partial)return this.destroy(new Error("Unexpected end of data"));t()};Yue.exports=Wa});var Zue=E((TPt,Xue)=>{Xue.exports=require("fs").constants||require("constants")});var ige=E((MPt,$ue)=>{var xf=Zue(),ege=tk(),IQ=_A(),p7e=Buffer.alloc,tge=bf().Readable,kf=bf().Writable,d7e=require("string_decoder").StringDecoder,yQ=lM(),C7e=parseInt("755",8),m7e=parseInt("644",8),rge=p7e(1024),cM=function(){},uM=function(t,e){e&=511,e&&t.push(rge.slice(0,512-e))};function E7e(t){switch(t&xf.S_IFMT){case xf.S_IFBLK:return"block-device";case xf.S_IFCHR:return"character-device";case xf.S_IFDIR:return"directory";case xf.S_IFIFO:return"fifo";case xf.S_IFLNK:return"symlink"}return"file"}var wQ=function(t){kf.call(this),this.written=0,this._to=t,this._destroyed=!1};IQ(wQ,kf);wQ.prototype._write=function(t,e,r){if(this.written+=t.length,this._to.push(t))return r();this._to._drain=r};wQ.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var BQ=function(){kf.call(this),this.linkname="",this._decoder=new d7e("utf-8"),this._destroyed=!1};IQ(BQ,kf);BQ.prototype._write=function(t,e,r){this.linkname+=this._decoder.write(t),r()};BQ.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var gm=function(){kf.call(this),this._destroyed=!1};IQ(gm,kf);gm.prototype._write=function(t,e,r){r(new Error("No body allowed for this entry"))};gm.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var Oo=function(t){if(!(this instanceof Oo))return new Oo(t);tge.call(this,t),this._drain=cM,this._finalized=!1,this._finalizing=!1,this._destroyed=!1,this._stream=null};IQ(Oo,tge);Oo.prototype.entry=function(t,e,r){if(this._stream)throw new Error("already piping an entry");if(!(this._finalized||this._destroyed)){typeof e=="function"&&(r=e,e=null),r||(r=cM);var i=this;if((!t.size||t.type==="symlink")&&(t.size=0),t.type||(t.type=E7e(t.mode)),t.mode||(t.mode=t.type==="directory"?C7e:m7e),t.uid||(t.uid=0),t.gid||(t.gid=0),t.mtime||(t.mtime=new Date),typeof e=="string"&&(e=Buffer.from(e)),Buffer.isBuffer(e)){t.size=e.length,this._encode(t);var n=this.push(e);return uM(i,t.size),n?process.nextTick(r):this._drain=r,new gm}if(t.type==="symlink"&&!t.linkname){var s=new BQ;return ege(s,function(a){if(a)return i.destroy(),r(a);t.linkname=s.linkname,i._encode(t),r()}),s}if(this._encode(t),t.type!=="file"&&t.type!=="contiguous-file")return process.nextTick(r),new gm;var o=new wQ(this);return this._stream=o,ege(o,function(a){if(i._stream=null,a)return i.destroy(),r(a);if(o.written!==t.size)return i.destroy(),r(new Error("size mismatch"));uM(i,t.size),i._finalizing&&i.finalize(),r()}),o}};Oo.prototype.finalize=function(){if(this._stream){this._finalizing=!0;return}this._finalized||(this._finalized=!0,this.push(rge),this.push(null))};Oo.prototype.destroy=function(t){this._destroyed||(this._destroyed=!0,t&&this.emit("error",t),this.emit("close"),this._stream&&this._stream.destroy&&this._stream.destroy())};Oo.prototype._encode=function(t){if(!t.pax){var e=yQ.encode(t);if(e){this.push(e);return}}this._encodePax(t)};Oo.prototype._encodePax=function(t){var e=yQ.encodePax({name:t.name,linkname:t.linkname,pax:t.pax}),r={name:"PaxHeader",mode:t.mode,uid:t.uid,gid:t.gid,size:e.length,mtime:t.mtime,type:"pax-header",linkname:t.linkname&&"PaxHeader",uname:t.uname,gname:t.gname,devmajor:t.devmajor,devminor:t.devminor};this.push(yQ.encode(r)),this.push(e),uM(this,e.length),r.size=t.size,r.type=t.type,this.push(yQ.encode(r))};Oo.prototype._read=function(t){var e=this._drain;this._drain=cM,e()};$ue.exports=Oo});var nge=E(gM=>{gM.extract=_ue();gM.pack=ige()});var Cge=E((oDt,fge)=>{"use strict";var Pf=class{constructor(e,r,i){this.__specs=e||{},Object.keys(this.__specs).forEach(n=>{if(typeof this.__specs[n]=="string"){let s=this.__specs[n],o=this.__specs[s];if(o){let a=o.aliases||[];a.push(n,s),o.aliases=[...new Set(a)],this.__specs[n]=o}else throw new Error(`Alias refers to invalid key: ${s} -> ${n}`)}}),this.__opts=r||{},this.__providers=pge(i.filter(n=>n!=null&&typeof n=="object")),this.__isFiggyPudding=!0}get(e){return mM(this,e,!0)}get[Symbol.toStringTag](){return"FiggyPudding"}forEach(e,r=this){for(let[i,n]of this.entries())e.call(r,n,i,this)}toJSON(){let e={};return this.forEach((r,i)=>{e[i]=r}),e}*entries(e){for(let i of Object.keys(this.__specs))yield[i,this.get(i)];let r=e||this.__opts.other;if(r){let i=new Set;for(let n of this.__providers){let s=n.entries?n.entries(r):R7e(n);for(let[o,a]of s)r(o)&&!i.has(o)&&(i.add(o),yield[o,a])}}}*[Symbol.iterator](){for(let[e,r]of this.entries())yield[e,r]}*keys(){for(let[e]of this.entries())yield e}*values(){for(let[,e]of this.entries())yield e}concat(...e){return new Proxy(new Pf(this.__specs,this.__opts,pge(this.__providers).concat(e)),hge)}};try{let t=require("util");Pf.prototype[t.inspect.custom]=function(e,r){return this[Symbol.toStringTag]+" "+t.inspect(this.toJSON(),r)}}catch(t){}function F7e(t){throw Object.assign(new Error(`invalid config key requested: ${t}`),{code:"EBADKEY"})}function mM(t,e,r){let i=t.__specs[e];if(r&&!i&&(!t.__opts.other||!t.__opts.other(e)))F7e(e);else{i||(i={});let n;for(let s of t.__providers){if(n=dge(e,s),n===void 0&&i.aliases&&i.aliases.length){for(let o of i.aliases)if(o!==e&&(n=dge(o,s),n!==void 0))break}if(n!==void 0)break}return n===void 0&&i.default!==void 0?typeof i.default=="function"?i.default(t):i.default:n}}function dge(t,e){let r;return e.__isFiggyPudding?r=mM(e,t,!1):typeof e.get=="function"?r=e.get(t):r=e[t],r}var hge={has(t,e){return e in t.__specs&&mM(t,e,!1)!==void 0},ownKeys(t){return Object.keys(t.__specs)},get(t,e){return typeof e=="symbol"||e.slice(0,2)==="__"||e in Pf.prototype?t[e]:t.get(e)},set(t,e,r){if(typeof e=="symbol"||e.slice(0,2)==="__")return t[e]=r,!0;throw new Error("figgyPudding options cannot be modified. Use .concat() instead.")},deleteProperty(){throw new Error("figgyPudding options cannot be deleted. Use .concat() and shadow them instead.")}};fge.exports=N7e;function N7e(t,e){function r(...i){return new Proxy(new Pf(t,e,i),hge)}return r}function pge(t){let e=[];return t.forEach(r=>e.unshift(r)),e}function R7e(t){return Object.keys(t).map(e=>[e,t[e]])}});var Ige=E((aDt,Ko)=>{"use strict";var hm=require("crypto"),L7e=Cge(),T7e=require("stream").Transform,mge=["sha256","sha384","sha512"],M7e=/^[a-z0-9+/]+(?:=?=?)$/i,O7e=/^([^-]+)-([^?]+)([?\S*]*)$/,K7e=/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/,U7e=/^[\x21-\x7E]+$/,on=L7e({algorithms:{default:["sha512"]},error:{default:!1},integrity:{},options:{default:[]},pickAlgorithm:{default:()=>H7e},Promise:{default:()=>Promise},sep:{default:" "},single:{default:!1},size:{},strict:{default:!1}}),zc=class{get isHash(){return!0}constructor(e,r){r=on(r);let i=!!r.strict;this.source=e.trim();let n=this.source.match(i?K7e:O7e);if(!n||i&&!mge.some(o=>o===n[1]))return;this.algorithm=n[1],this.digest=n[2];let s=n[3];this.options=s?s.slice(1).split("?"):[]}hexDigest(){return this.digest&&Buffer.from(this.digest,"base64").toString("hex")}toJSON(){return this.toString()}toString(e){if(e=on(e),e.strict&&!(mge.some(i=>i===this.algorithm)&&this.digest.match(M7e)&&(this.options||[]).every(i=>i.match(U7e))))return"";let r=this.options&&this.options.length?`?${this.options.join("?")}`:"";return`${this.algorithm}-${this.digest}${r}`}},Df=class{get isIntegrity(){return!0}toJSON(){return this.toString()}toString(e){e=on(e);let r=e.sep||" ";return e.strict&&(r=r.replace(/\S+/g," ")),Object.keys(this).map(i=>this[i].map(n=>zc.prototype.toString.call(n,e)).filter(n=>n.length).join(r)).filter(i=>i.length).join(r)}concat(e,r){r=on(r);let i=typeof e=="string"?e:pm(e,r);return Uo(`${this.toString(r)} ${i}`,r)}hexDigest(){return Uo(this,{single:!0}).hexDigest()}match(e,r){r=on(r);let i=Uo(e,r),n=i.pickAlgorithm(r);return this[n]&&i[n]&&this[n].find(s=>i[n].find(o=>s.digest===o.digest))||!1}pickAlgorithm(e){e=on(e);let r=e.pickAlgorithm,i=Object.keys(this);if(!i.length)throw new Error(`No algorithms available for ${JSON.stringify(this.toString())}`);return i.reduce((n,s)=>r(n,s)||n)}};Ko.exports.parse=Uo;function Uo(t,e){if(e=on(e),typeof t=="string")return EM(t,e);if(t.algorithm&&t.digest){let r=new Df;return r[t.algorithm]=[t],EM(pm(r,e),e)}else return EM(pm(t,e),e)}function EM(t,e){return e.single?new zc(t,e):t.trim().split(/\s+/).reduce((r,i)=>{let n=new zc(i,e);if(n.algorithm&&n.digest){let s=n.algorithm;r[s]||(r[s]=[]),r[s].push(n)}return r},new Df)}Ko.exports.stringify=pm;function pm(t,e){return e=on(e),t.algorithm&&t.digest?zc.prototype.toString.call(t,e):typeof t=="string"?pm(Uo(t,e),e):Df.prototype.toString.call(t,e)}Ko.exports.fromHex=G7e;function G7e(t,e,r){r=on(r);let i=r.options&&r.options.length?`?${r.options.join("?")}`:"";return Uo(`${e}-${Buffer.from(t,"hex").toString("base64")}${i}`,r)}Ko.exports.fromData=j7e;function j7e(t,e){e=on(e);let r=e.algorithms,i=e.options&&e.options.length?`?${e.options.join("?")}`:"";return r.reduce((n,s)=>{let o=hm.createHash(s).update(t).digest("base64"),a=new zc(`${s}-${o}${i}`,e);if(a.algorithm&&a.digest){let l=a.algorithm;n[l]||(n[l]=[]),n[l].push(a)}return n},new Df)}Ko.exports.fromStream=Y7e;function Y7e(t,e){e=on(e);let r=e.Promise||Promise,i=IM(e);return new r((n,s)=>{t.pipe(i),t.on("error",s),i.on("error",s);let o;i.on("integrity",a=>{o=a}),i.on("end",()=>n(o)),i.on("data",()=>{})})}Ko.exports.checkData=q7e;function q7e(t,e,r){if(r=on(r),e=Uo(e,r),!Object.keys(e).length){if(r.error)throw Object.assign(new Error("No valid integrity hashes to check against"),{code:"EINTEGRITY"});return!1}let i=e.pickAlgorithm(r),n=hm.createHash(i).update(t).digest("base64"),s=Uo({algorithm:i,digest:n}),o=s.match(e,r);if(o||!r.error)return o;if(typeof r.size=="number"&&t.length!==r.size){let a=new Error(`data size mismatch when checking ${e}. + Wanted: ${r.size} + Found: ${t.length}`);throw a.code="EBADSIZE",a.found=t.length,a.expected=r.size,a.sri=e,a}else{let a=new Error(`Integrity checksum failed when using ${i}: Wanted ${e}, but got ${s}. (${t.length} bytes)`);throw a.code="EINTEGRITY",a.found=s,a.expected=e,a.algorithm=i,a.sri=e,a}}Ko.exports.checkStream=J7e;function J7e(t,e,r){r=on(r);let i=r.Promise||Promise,n=IM(r.concat({integrity:e}));return new i((s,o)=>{t.pipe(n),t.on("error",o),n.on("error",o);let a;n.on("verified",l=>{a=l}),n.on("end",()=>s(a)),n.on("data",()=>{})})}Ko.exports.integrityStream=IM;function IM(t){t=on(t);let e=t.integrity&&Uo(t.integrity,t),r=e&&Object.keys(e).length,i=r&&e.pickAlgorithm(t),n=r&&e[i],s=Array.from(new Set(t.algorithms.concat(i?[i]:[]))),o=s.map(hm.createHash),a=0,l=new T7e({transform(c,u,g){a+=c.length,o.forEach(f=>f.update(c,u)),g(null,c,u)}}).on("end",()=>{let c=t.options&&t.options.length?`?${t.options.join("?")}`:"",u=Uo(o.map((f,h)=>`${s[h]}-${f.digest("base64")}${c}`).join(" "),t),g=r&&u.match(e,t);if(typeof t.size=="number"&&a!==t.size){let f=new Error(`stream size mismatch when checking ${e}. + Wanted: ${t.size} + Found: ${a}`);f.code="EBADSIZE",f.found=a,f.expected=t.size,f.sri=e,l.emit("error",f)}else if(t.integrity&&!g){let f=new Error(`${e} integrity checksum failed when using ${i}: wanted ${n} but got ${u}. (${a} bytes)`);f.code="EINTEGRITY",f.found=u,f.expected=n,f.algorithm=i,f.sri=e,l.emit("error",f)}else l.emit("size",a),l.emit("integrity",u),g&&l.emit("verified",g)});return l}Ko.exports.create=W7e;function W7e(t){t=on(t);let e=t.algorithms,r=t.options.length?`?${t.options.join("?")}`:"",i=e.map(hm.createHash);return{update:function(n,s){return i.forEach(o=>o.update(n,s)),this},digest:function(n){return e.reduce((o,a)=>{let l=i.shift().digest("base64"),c=new zc(`${a}-${l}${r}`,t);if(c.algorithm&&c.digest){let u=c.algorithm;o[u]||(o[u]=[]),o[u].push(c)}return o},new Df)}}}var z7e=new Set(hm.getHashes()),Ege=["md5","whirlpool","sha1","sha224","sha256","sha384","sha512","sha3","sha3-256","sha3-384","sha3-512","sha3_256","sha3_384","sha3_512"].filter(t=>z7e.has(t));function H7e(t,e){return Ege.indexOf(t.toLowerCase())>=Ege.indexOf(e.toLowerCase())?t:e}});var Fd={};it(Fd,{BuildType:()=>Gn,Cache:()=>Qt,Configuration:()=>fe,DEFAULT_LOCK_FILENAME:()=>DR,DEFAULT_RC_FILENAME:()=>PR,FormatType:()=>ps,InstallMode:()=>li,LightReport:()=>Fa,LinkType:()=>gt,Manifest:()=>Ze,MessageName:()=>z,PackageExtensionStatus:()=>ki,PackageExtensionType:()=>oi,Project:()=>Ke,ProjectLookup:()=>KA,Report:()=>Xi,ReportError:()=>nt,SettingsType:()=>ge,StreamReport:()=>Fe,TAG_REGEXP:()=>Rg,TelemetryManager:()=>Rd,ThrowReport:()=>ei,VirtualFetcher:()=>dd,Workspace:()=>Dd,WorkspaceResolver:()=>Yr,YarnVersion:()=>Zr,execUtils:()=>hr,folderUtils:()=>Pb,formatUtils:()=>ue,hashUtils:()=>mn,httpUtils:()=>Zt,miscUtils:()=>de,scriptUtils:()=>Kt,semverUtils:()=>qt,structUtils:()=>S,tgzUtils:()=>Ai,treeUtils:()=>Hs});var hr={};it(hr,{EndStrategy:()=>Pn,execvp:()=>Nhe,pipevp:()=>to});var ch={};it(ch,{AliasFS:()=>Xo,CwdFS:()=>Ft,DEFAULT_COMPRESSION_LEVEL:()=>pl,FakeFS:()=>eA,Filename:()=>wt,JailFS:()=>Zo,LazyFS:()=>oh,LinkStrategy:()=>eh,NoFS:()=>bE,NodeFS:()=>Wt,PortablePath:()=>Se,PosixFS:()=>ah,ProxiedFS:()=>fi,VirtualFS:()=>Pr,ZipFS:()=>Jr,ZipOpenFS:()=>Jn,constants:()=>mr,extendFs:()=>SE,normalizeLineEndings:()=>ul,npath:()=>M,opendir:()=>wE,patchFs:()=>pb,ppath:()=>v,statUtils:()=>rb,toFilename:()=>kr,xfs:()=>T});var mr={};it(mr,{SAFE_TIME:()=>tb,S_IFDIR:()=>zo,S_IFLNK:()=>_o,S_IFMT:()=>kn,S_IFREG:()=>Vo});var kn=61440,zo=16384,Vo=32768,_o=40960,tb=456789e3;var rb={};it(rb,{BigIntStatsEntry:()=>Xf,DEFAULT_MODE:()=>_f,DirEntry:()=>uO,StatEntry:()=>Za,areStatsEqual:()=>nb,clearStats:()=>pE,convertToBigIntStats:()=>dE,makeDefaultStats:()=>Zf,makeEmptyStats:()=>Jfe});var ib=ie(require("util"));var _f=Vo|420,uO=class{constructor(){this.name="";this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&kn)===zo}isFIFO(){return!1}isFile(){return(this.mode&kn)===Vo}isSocket(){return!1}isSymbolicLink(){return(this.mode&kn)===_o}},Za=class{constructor(){this.uid=0;this.gid=0;this.size=0;this.blksize=0;this.atimeMs=0;this.mtimeMs=0;this.ctimeMs=0;this.birthtimeMs=0;this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=0;this.ino=0;this.mode=_f;this.nlink=1;this.rdev=0;this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&kn)===zo}isFIFO(){return!1}isFile(){return(this.mode&kn)===Vo}isSocket(){return!1}isSymbolicLink(){return(this.mode&kn)===_o}},Xf=class{constructor(){this.uid=BigInt(0);this.gid=BigInt(0);this.size=BigInt(0);this.blksize=BigInt(0);this.atimeMs=BigInt(0);this.mtimeMs=BigInt(0);this.ctimeMs=BigInt(0);this.birthtimeMs=BigInt(0);this.atimeNs=BigInt(0);this.mtimeNs=BigInt(0);this.ctimeNs=BigInt(0);this.birthtimeNs=BigInt(0);this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=BigInt(0);this.ino=BigInt(0);this.mode=BigInt(_f);this.nlink=BigInt(1);this.rdev=BigInt(0);this.blocks=BigInt(1)}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&BigInt(kn))===BigInt(zo)}isFIFO(){return!1}isFile(){return(this.mode&BigInt(kn))===BigInt(Vo)}isSocket(){return!1}isSymbolicLink(){return(this.mode&BigInt(kn))===BigInt(_o)}};function Zf(){return new Za}function Jfe(){return pE(Zf())}function pE(t){for(let e in t)if(Object.prototype.hasOwnProperty.call(t,e)){let r=t[e];typeof r=="number"?t[e]=0:typeof r=="bigint"?t[e]=BigInt(0):ib.types.isDate(r)&&(t[e]=new Date(0))}return t}function dE(t){let e=new Xf;for(let r in t)if(Object.prototype.hasOwnProperty.call(t,r)){let i=t[r];typeof i=="number"?e[r]=BigInt(i):ib.types.isDate(i)&&(e[r]=new Date(i))}return e.atimeNs=e.atimeMs*BigInt(1e6),e.mtimeNs=e.mtimeMs*BigInt(1e6),e.ctimeNs=e.ctimeMs*BigInt(1e6),e.birthtimeNs=e.birthtimeMs*BigInt(1e6),e}function nb(t,e){if(t.atimeMs!==e.atimeMs||t.birthtimeMs!==e.birthtimeMs||t.blksize!==e.blksize||t.blocks!==e.blocks||t.ctimeMs!==e.ctimeMs||t.dev!==e.dev||t.gid!==e.gid||t.ino!==e.ino||t.isBlockDevice()!==e.isBlockDevice()||t.isCharacterDevice()!==e.isCharacterDevice()||t.isDirectory()!==e.isDirectory()||t.isFIFO()!==e.isFIFO()||t.isFile()!==e.isFile()||t.isSocket()!==e.isSocket()||t.isSymbolicLink()!==e.isSymbolicLink()||t.mode!==e.mode||t.mtimeMs!==e.mtimeMs||t.nlink!==e.nlink||t.rdev!==e.rdev||t.size!==e.size||t.uid!==e.uid)return!1;let r=t,i=e;return!(r.atimeNs!==i.atimeNs||r.mtimeNs!==i.mtimeNs||r.ctimeNs!==i.ctimeNs||r.birthtimeNs!==i.birthtimeNs)}var mE=ie(require("fs"));var $f=ie(require("path")),gO;(function(i){i[i.File=0]="File",i[i.Portable=1]="Portable",i[i.Native=2]="Native"})(gO||(gO={}));var Se={root:"/",dot:"."},wt={nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",virtual:"__virtual__",pnpJs:".pnp.js",pnpCjs:".pnp.cjs",rc:".yarnrc.yml"},M=Object.create($f.default),v=Object.create($f.default.posix);M.cwd=()=>process.cwd();v.cwd=()=>sb(process.cwd());v.resolve=(...t)=>t.length>0&&v.isAbsolute(t[0])?$f.default.posix.resolve(...t):$f.default.posix.resolve(v.cwd(),...t);var fO=function(t,e,r){return e=t.normalize(e),r=t.normalize(r),e===r?".":(e.endsWith(t.sep)||(e=e+t.sep),r.startsWith(e)?r.slice(e.length):null)};M.fromPortablePath=hO;M.toPortablePath=sb;M.contains=(t,e)=>fO(M,t,e);v.contains=(t,e)=>fO(v,t,e);var Wfe=/^([a-zA-Z]:.*)$/,zfe=/^\\\\(\.\\)?(.*)$/,Vfe=/^\/([a-zA-Z]:.*)$/,_fe=/^\/unc\/(\.dot\/)?(.*)$/;function hO(t){if(process.platform!=="win32")return t;let e,r;if(e=t.match(Vfe))t=e[1];else if(r=t.match(_fe))t=`\\\\${r[1]?".\\":""}${r[2]}`;else return t;return t.replace(/\//g,"\\")}function sb(t){if(process.platform!=="win32")return t;let e,r;return(e=t.match(Wfe))?t=`/${e[1]}`:(r=t.match(zfe))&&(t=`/unc/${r[1]?".dot/":""}${r[2]}`),t.replace(/\\/g,"/")}function CE(t,e){return t===M?hO(e):sb(e)}function kr(t){if(M.parse(t).dir!==""||v.parse(t).dir!=="")throw new Error(`Invalid filename: "${t}"`);return t}var EE=new Date(tb*1e3),eh;(function(r){r.Allow="allow",r.ReadOnly="readOnly"})(eh||(eh={}));async function pO(t,e,r,i,n){let s=t.pathUtils.normalize(e),o=r.pathUtils.normalize(i),a=[],l=[],c=n.stableTime?{mtime:EE,atime:EE}:await r.lstatPromise(o);await t.mkdirpPromise(t.pathUtils.dirname(e),{utimes:[c.atime,c.mtime]});let u=typeof t.lutimesPromise=="function"?t.lutimesPromise.bind(t):t.utimesPromise.bind(t);await ob(a,l,u,t,s,r,o,n);for(let g of a)await g();await Promise.all(l.map(g=>g()))}async function ob(t,e,r,i,n,s,o,a){var f,h;let l=await Xfe(i,n),c=await s.lstatPromise(o),u=a.stableTime?{mtime:EE,atime:EE}:c,g;switch(!0){case c.isDirectory():g=await Zfe(t,e,r,i,n,l,s,o,c,a);break;case c.isFile():g=await $fe(t,e,r,i,n,l,s,o,c,a);break;case c.isSymbolicLink():g=await ehe(t,e,r,i,n,l,s,o,c,a);break;default:throw new Error(`Unsupported file type (${c.mode})`)}return(g||((f=l==null?void 0:l.mtime)==null?void 0:f.getTime())!==u.mtime.getTime()||((h=l==null?void 0:l.atime)==null?void 0:h.getTime())!==u.atime.getTime())&&(e.push(()=>r(n,u.atime,u.mtime)),g=!0),(l===null||(l.mode&511)!=(c.mode&511))&&(e.push(()=>i.chmodPromise(n,c.mode&511)),g=!0),g}async function Xfe(t,e){try{return await t.lstatPromise(e)}catch(r){return null}}async function Zfe(t,e,r,i,n,s,o,a,l,c){if(s!==null&&!s.isDirectory())if(c.overwrite)t.push(async()=>i.removePromise(n)),s=null;else return!1;let u=!1;s===null&&(t.push(async()=>{try{await i.mkdirPromise(n,{mode:l.mode})}catch(f){if(f.code!=="EEXIST")throw f}}),u=!0);let g=await o.readdirPromise(a);if(c.stableSort)for(let f of g.sort())await ob(t,e,r,i,i.pathUtils.join(n,f),o,o.pathUtils.join(a,f),c)&&(u=!0);else(await Promise.all(g.map(async h=>{await ob(t,e,r,i,i.pathUtils.join(n,h),o,o.pathUtils.join(a,h),c)}))).some(h=>h)&&(u=!0);return u}var ab=new WeakMap;function Ab(t,e,r,i,n){return async()=>{await t.linkPromise(r,e),n===eh.ReadOnly&&(i.mode&=~146,await t.chmodPromise(e,i.mode))}}function the(t,e,r,i,n){let s=ab.get(t);return typeof s=="undefined"?async()=>{try{await t.copyFilePromise(r,e,mE.default.constants.COPYFILE_FICLONE_FORCE),ab.set(t,!0)}catch(o){if(o.code==="ENOSYS"||o.code==="ENOTSUP")ab.set(t,!1),await Ab(t,e,r,i,n)();else throw o}}:s?async()=>t.copyFilePromise(r,e,mE.default.constants.COPYFILE_FICLONE_FORCE):Ab(t,e,r,i,n)}async function $fe(t,e,r,i,n,s,o,a,l,c){var f;if(s!==null)if(c.overwrite)t.push(async()=>i.removePromise(n)),s=null;else return!1;let u=(f=c.linkStrategy)!=null?f:null,g=i===o?u!==null?the(i,n,a,l,u):async()=>i.copyFilePromise(a,n,mE.default.constants.COPYFILE_FICLONE):u!==null?Ab(i,n,a,l,u):async()=>i.writeFilePromise(n,await o.readFilePromise(a));return t.push(async()=>g()),!0}async function ehe(t,e,r,i,n,s,o,a,l,c){if(s!==null)if(c.overwrite)t.push(async()=>i.removePromise(n)),s=null;else return!1;return t.push(async()=>{await i.symlinkPromise(CE(i.pathUtils,await o.readlinkPromise(a)),n)}),!0}function qn(t,e){return Object.assign(new Error(`${t}: ${e}`),{code:t})}function IE(t){return qn("EBUSY",t)}function th(t,e){return qn("ENOSYS",`${t}, ${e}`)}function $a(t){return qn("EINVAL",`invalid argument, ${t}`)}function Hi(t){return qn("EBADF",`bad file descriptor, ${t}`)}function bs(t){return qn("ENOENT",`no such file or directory, ${t}`)}function eo(t){return qn("ENOTDIR",`not a directory, ${t}`)}function rh(t){return qn("EISDIR",`illegal operation on a directory, ${t}`)}function yE(t){return qn("EEXIST",`file already exists, ${t}`)}function ln(t){return qn("EROFS",`read-only filesystem, ${t}`)}function dO(t){return qn("ENOTEMPTY",`directory not empty, ${t}`)}function CO(t){return qn("EOPNOTSUPP",`operation not supported, ${t}`)}function mO(){return qn("ERR_DIR_CLOSED","Directory handle was closed")}var lb=class extends Error{constructor(e,r){super(e);this.name="Libzip Error",this.code=r}};var EO=class{constructor(e,r,i={}){this.path=e;this.nextDirent=r;this.opts=i;this.closed=!1}throwIfClosed(){if(this.closed)throw mO()}async*[Symbol.asyncIterator](){try{let e;for(;(e=await this.read())!==null;)yield e}finally{await this.close()}}read(e){let r=this.readSync();return typeof e!="undefined"?e(null,r):Promise.resolve(r)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),typeof e!="undefined"?e(null):Promise.resolve()}closeSync(){var e,r;this.throwIfClosed(),(r=(e=this.opts).onClose)==null||r.call(e),this.closed=!0}};function wE(t,e,r,i){let n=()=>{let s=r.shift();return typeof s=="undefined"?null:Object.assign(t.statSync(t.pathUtils.join(e,s)),{name:s})};return new EO(e,n,i)}var IO=ie(require("os"));var eA=class{constructor(e){this.pathUtils=e}async*genTraversePromise(e,{stableSort:r=!1}={}){let i=[e];for(;i.length>0;){let n=i.shift();if((await this.lstatPromise(n)).isDirectory()){let o=await this.readdirPromise(n);if(r)for(let a of o.sort())i.push(this.pathUtils.join(n,a));else throw new Error("Not supported")}else yield n}}async removePromise(e,{recursive:r=!0,maxRetries:i=5}={}){let n;try{n=await this.lstatPromise(e)}catch(s){if(s.code==="ENOENT")return;throw s}if(n.isDirectory()){if(r){let o=await this.readdirPromise(e);await Promise.all(o.map(a=>this.removePromise(this.pathUtils.resolve(e,a))))}let s=0;do try{await this.rmdirPromise(e);break}catch(o){if(o.code==="EBUSY"||o.code==="ENOTEMPTY"){if(i===0)break;await new Promise(a=>setTimeout(a,s*100));continue}else throw o}while(s++{let l;try{[l]=await this.readJsonPromise(i)}catch(c){return Date.now()-s<500}try{return process.kill(l,0),!0}catch(c){return!1}};for(;o===null;)try{o=await this.openPromise(i,"wx")}catch(l){if(l.code==="EEXIST"){if(!await a())try{await this.unlinkPromise(i);continue}catch(c){}if(Date.now()-s<60*1e3)await new Promise(c=>setTimeout(c,n));else throw new Error(`Couldn't acquire a lock in a reasonable time (via ${i})`)}else throw l}await this.writePromise(o,JSON.stringify([process.pid]));try{return await r()}finally{try{await this.closePromise(o),await this.unlinkPromise(i)}catch(l){}}}async readJsonPromise(e){let r=await this.readFilePromise(e,"utf8");try{return JSON.parse(r)}catch(i){throw i.message+=` (in ${e})`,i}}readJsonSync(e){let r=this.readFileSync(e,"utf8");try{return JSON.parse(r)}catch(i){throw i.message+=` (in ${e})`,i}}async writeJsonPromise(e,r){return await this.writeFilePromise(e,`${JSON.stringify(r,null,2)} +`)}writeJsonSync(e,r){return this.writeFileSync(e,`${JSON.stringify(r,null,2)} +`)}async preserveTimePromise(e,r){let i=await this.lstatPromise(e),n=await r();typeof n!="undefined"&&(e=n),this.lutimesPromise?await this.lutimesPromise(e,i.atime,i.mtime):i.isSymbolicLink()||await this.utimesPromise(e,i.atime,i.mtime)}async preserveTimeSync(e,r){let i=this.lstatSync(e),n=r();typeof n!="undefined"&&(e=n),this.lutimesSync?this.lutimesSync(e,i.atime,i.mtime):i.isSymbolicLink()||this.utimesSync(e,i.atime,i.mtime)}},gl=class extends eA{constructor(){super(v)}};function rhe(t){let e=t.match(/\r?\n/g);if(e===null)return IO.EOL;let r=e.filter(n=>n===`\r +`).length,i=e.length-r;return r>i?`\r +`:` +`}function ul(t,e){return e.replace(/\r?\n/g,rhe(t))}var $c=ie(require("fs")),cb=ie(require("stream")),QO=ie(require("util")),ub=ie(require("zlib"));var yO=ie(require("fs"));var Wt=class extends gl{constructor(e=yO.default){super();this.realFs=e,typeof this.realFs.lutimes!="undefined"&&(this.lutimesPromise=this.lutimesPromiseImpl,this.lutimesSync=this.lutimesSyncImpl)}getExtractHint(){return!1}getRealPath(){return Se.root}resolve(e){return v.resolve(e)}async openPromise(e,r,i){return await new Promise((n,s)=>{this.realFs.open(M.fromPortablePath(e),r,i,this.makeCallback(n,s))})}openSync(e,r,i){return this.realFs.openSync(M.fromPortablePath(e),r,i)}async opendirPromise(e,r){return await new Promise((i,n)=>{typeof r!="undefined"?this.realFs.opendir(M.fromPortablePath(e),r,this.makeCallback(i,n)):this.realFs.opendir(M.fromPortablePath(e),this.makeCallback(i,n))}).then(i=>Object.defineProperty(i,"path",{value:e,configurable:!0,writable:!0}))}opendirSync(e,r){let i=typeof r!="undefined"?this.realFs.opendirSync(M.fromPortablePath(e),r):this.realFs.opendirSync(M.fromPortablePath(e));return Object.defineProperty(i,"path",{value:e,configurable:!0,writable:!0})}async readPromise(e,r,i=0,n=0,s=-1){return await new Promise((o,a)=>{this.realFs.read(e,r,i,n,s,(l,c)=>{l?a(l):o(c)})})}readSync(e,r,i,n,s){return this.realFs.readSync(e,r,i,n,s)}async writePromise(e,r,i,n,s){return await new Promise((o,a)=>typeof r=="string"?this.realFs.write(e,r,i,this.makeCallback(o,a)):this.realFs.write(e,r,i,n,s,this.makeCallback(o,a)))}writeSync(e,r,i,n,s){return typeof r=="string"?this.realFs.writeSync(e,r,i):this.realFs.writeSync(e,r,i,n,s)}async closePromise(e){await new Promise((r,i)=>{this.realFs.close(e,this.makeCallback(r,i))})}closeSync(e){this.realFs.closeSync(e)}createReadStream(e,r){let i=e!==null?M.fromPortablePath(e):e;return this.realFs.createReadStream(i,r)}createWriteStream(e,r){let i=e!==null?M.fromPortablePath(e):e;return this.realFs.createWriteStream(i,r)}async realpathPromise(e){return await new Promise((r,i)=>{this.realFs.realpath(M.fromPortablePath(e),{},this.makeCallback(r,i))}).then(r=>M.toPortablePath(r))}realpathSync(e){return M.toPortablePath(this.realFs.realpathSync(M.fromPortablePath(e),{}))}async existsPromise(e){return await new Promise(r=>{this.realFs.exists(M.fromPortablePath(e),r)})}accessSync(e,r){return this.realFs.accessSync(M.fromPortablePath(e),r)}async accessPromise(e,r){return await new Promise((i,n)=>{this.realFs.access(M.fromPortablePath(e),r,this.makeCallback(i,n))})}existsSync(e){return this.realFs.existsSync(M.fromPortablePath(e))}async statPromise(e,r){return await new Promise((i,n)=>{r?this.realFs.stat(M.fromPortablePath(e),r,this.makeCallback(i,n)):this.realFs.stat(M.fromPortablePath(e),this.makeCallback(i,n))})}statSync(e,r){return r?this.realFs.statSync(M.fromPortablePath(e),r):this.realFs.statSync(M.fromPortablePath(e))}async fstatPromise(e,r){return await new Promise((i,n)=>{r?this.realFs.fstat(e,r,this.makeCallback(i,n)):this.realFs.fstat(e,this.makeCallback(i,n))})}fstatSync(e,r){return r?this.realFs.fstatSync(e,r):this.realFs.fstatSync(e)}async lstatPromise(e,r){return await new Promise((i,n)=>{r?this.realFs.lstat(M.fromPortablePath(e),r,this.makeCallback(i,n)):this.realFs.lstat(M.fromPortablePath(e),this.makeCallback(i,n))})}lstatSync(e,r){return r?this.realFs.lstatSync(M.fromPortablePath(e),r):this.realFs.lstatSync(M.fromPortablePath(e))}async chmodPromise(e,r){return await new Promise((i,n)=>{this.realFs.chmod(M.fromPortablePath(e),r,this.makeCallback(i,n))})}chmodSync(e,r){return this.realFs.chmodSync(M.fromPortablePath(e),r)}async chownPromise(e,r,i){return await new Promise((n,s)=>{this.realFs.chown(M.fromPortablePath(e),r,i,this.makeCallback(n,s))})}chownSync(e,r,i){return this.realFs.chownSync(M.fromPortablePath(e),r,i)}async renamePromise(e,r){return await new Promise((i,n)=>{this.realFs.rename(M.fromPortablePath(e),M.fromPortablePath(r),this.makeCallback(i,n))})}renameSync(e,r){return this.realFs.renameSync(M.fromPortablePath(e),M.fromPortablePath(r))}async copyFilePromise(e,r,i=0){return await new Promise((n,s)=>{this.realFs.copyFile(M.fromPortablePath(e),M.fromPortablePath(r),i,this.makeCallback(n,s))})}copyFileSync(e,r,i=0){return this.realFs.copyFileSync(M.fromPortablePath(e),M.fromPortablePath(r),i)}async appendFilePromise(e,r,i){return await new Promise((n,s)=>{let o=typeof e=="string"?M.fromPortablePath(e):e;i?this.realFs.appendFile(o,r,i,this.makeCallback(n,s)):this.realFs.appendFile(o,r,this.makeCallback(n,s))})}appendFileSync(e,r,i){let n=typeof e=="string"?M.fromPortablePath(e):e;i?this.realFs.appendFileSync(n,r,i):this.realFs.appendFileSync(n,r)}async writeFilePromise(e,r,i){return await new Promise((n,s)=>{let o=typeof e=="string"?M.fromPortablePath(e):e;i?this.realFs.writeFile(o,r,i,this.makeCallback(n,s)):this.realFs.writeFile(o,r,this.makeCallback(n,s))})}writeFileSync(e,r,i){let n=typeof e=="string"?M.fromPortablePath(e):e;i?this.realFs.writeFileSync(n,r,i):this.realFs.writeFileSync(n,r)}async unlinkPromise(e){return await new Promise((r,i)=>{this.realFs.unlink(M.fromPortablePath(e),this.makeCallback(r,i))})}unlinkSync(e){return this.realFs.unlinkSync(M.fromPortablePath(e))}async utimesPromise(e,r,i){return await new Promise((n,s)=>{this.realFs.utimes(M.fromPortablePath(e),r,i,this.makeCallback(n,s))})}utimesSync(e,r,i){this.realFs.utimesSync(M.fromPortablePath(e),r,i)}async lutimesPromiseImpl(e,r,i){let n=this.realFs.lutimes;if(typeof n=="undefined")throw th("unavailable Node binding",`lutimes '${e}'`);return await new Promise((s,o)=>{n.call(this.realFs,M.fromPortablePath(e),r,i,this.makeCallback(s,o))})}lutimesSyncImpl(e,r,i){let n=this.realFs.lutimesSync;if(typeof n=="undefined")throw th("unavailable Node binding",`lutimes '${e}'`);n.call(this.realFs,M.fromPortablePath(e),r,i)}async mkdirPromise(e,r){return await new Promise((i,n)=>{this.realFs.mkdir(M.fromPortablePath(e),r,this.makeCallback(i,n))})}mkdirSync(e,r){return this.realFs.mkdirSync(M.fromPortablePath(e),r)}async rmdirPromise(e,r){return await new Promise((i,n)=>{r?this.realFs.rmdir(M.fromPortablePath(e),r,this.makeCallback(i,n)):this.realFs.rmdir(M.fromPortablePath(e),this.makeCallback(i,n))})}rmdirSync(e,r){return this.realFs.rmdirSync(M.fromPortablePath(e),r)}async linkPromise(e,r){return await new Promise((i,n)=>{this.realFs.link(M.fromPortablePath(e),M.fromPortablePath(r),this.makeCallback(i,n))})}linkSync(e,r){return this.realFs.linkSync(M.fromPortablePath(e),M.fromPortablePath(r))}async symlinkPromise(e,r,i){return await new Promise((n,s)=>{this.realFs.symlink(M.fromPortablePath(e.replace(/\/+$/,"")),M.fromPortablePath(r),i,this.makeCallback(n,s))})}symlinkSync(e,r,i){return this.realFs.symlinkSync(M.fromPortablePath(e.replace(/\/+$/,"")),M.fromPortablePath(r),i)}async readFilePromise(e,r){return await new Promise((i,n)=>{let s=typeof e=="string"?M.fromPortablePath(e):e;this.realFs.readFile(s,r,this.makeCallback(i,n))})}readFileSync(e,r){let i=typeof e=="string"?M.fromPortablePath(e):e;return this.realFs.readFileSync(i,r)}async readdirPromise(e,r){return await new Promise((i,n)=>{(r==null?void 0:r.withFileTypes)?this.realFs.readdir(M.fromPortablePath(e),{withFileTypes:!0},this.makeCallback(i,n)):this.realFs.readdir(M.fromPortablePath(e),this.makeCallback(s=>i(s),n))})}readdirSync(e,r){return(r==null?void 0:r.withFileTypes)?this.realFs.readdirSync(M.fromPortablePath(e),{withFileTypes:!0}):this.realFs.readdirSync(M.fromPortablePath(e))}async readlinkPromise(e){return await new Promise((r,i)=>{this.realFs.readlink(M.fromPortablePath(e),this.makeCallback(r,i))}).then(r=>M.toPortablePath(r))}readlinkSync(e){return M.toPortablePath(this.realFs.readlinkSync(M.fromPortablePath(e)))}async truncatePromise(e,r){return await new Promise((i,n)=>{this.realFs.truncate(M.fromPortablePath(e),r,this.makeCallback(i,n))})}truncateSync(e,r){return this.realFs.truncateSync(M.fromPortablePath(e),r)}watch(e,r,i){return this.realFs.watch(M.fromPortablePath(e),r,i)}watchFile(e,r,i){return this.realFs.watchFile(M.fromPortablePath(e),r,i)}unwatchFile(e,r){return this.realFs.unwatchFile(M.fromPortablePath(e),r)}makeCallback(e,r){return(i,n)=>{i?r(i):e(n)}}};var wO=ie(require("events"));var fl;(function(r){r.Change="change",r.Stop="stop"})(fl||(fl={}));var hl;(function(i){i.Ready="ready",i.Running="running",i.Stopped="stopped"})(hl||(hl={}));function BO(t,e){if(t!==e)throw new Error(`Invalid StatWatcher status: expected '${e}', got '${t}'`)}var ih=class extends wO.EventEmitter{constructor(e,r,{bigint:i=!1}={}){super();this.status=hl.Ready;this.changeListeners=new Map;this.startTimeout=null;this.fakeFs=e,this.path=r,this.bigint=i,this.lastStats=this.stat()}static create(e,r,i){let n=new ih(e,r,i);return n.start(),n}start(){BO(this.status,hl.Ready),this.status=hl.Running,this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit(fl.Change,this.lastStats,this.lastStats)},3)}stop(){BO(this.status,hl.Running),this.status=hl.Stopped,this.startTimeout!==null&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit(fl.Stop)}stat(){try{return this.fakeFs.statSync(this.path,{bigint:this.bigint})}catch(e){let r=this.bigint?new Xf:new Za;return pE(r)}}makeInterval(e){let r=setInterval(()=>{let i=this.stat(),n=this.lastStats;nb(i,n)||(this.lastStats=i,this.emit(fl.Change,i,n))},e.interval);return e.persistent?r:r.unref()}registerChangeListener(e,r){this.addListener(fl.Change,e),this.changeListeners.set(e,this.makeInterval(r))}unregisterChangeListener(e){this.removeListener(fl.Change,e);let r=this.changeListeners.get(e);typeof r!="undefined"&&clearInterval(r),this.changeListeners.delete(e)}unregisterAllChangeListeners(){for(let e of this.changeListeners.keys())this.unregisterChangeListener(e)}hasChangeListeners(){return this.changeListeners.size>0}ref(){for(let e of this.changeListeners.values())e.ref();return this}unref(){for(let e of this.changeListeners.values())e.unref();return this}};var BE=new WeakMap;function QE(t,e,r,i){let n,s,o,a;switch(typeof r){case"function":n=!1,s=!0,o=5007,a=r;break;default:({bigint:n=!1,persistent:s=!0,interval:o=5007}=r),a=i;break}let l=BE.get(t);typeof l=="undefined"&&BE.set(t,l=new Map);let c=l.get(e);return typeof c=="undefined"&&(c=ih.create(t,e,{bigint:n}),l.set(e,c)),c.registerChangeListener(a,{persistent:s,interval:o}),c}function nh(t,e,r){let i=BE.get(t);if(typeof i=="undefined")return;let n=i.get(e);typeof n!="undefined"&&(typeof r=="undefined"?n.unregisterAllChangeListeners():n.unregisterChangeListener(r),n.hasChangeListeners()||(n.stop(),i.delete(e)))}function sh(t){let e=BE.get(t);if(typeof e!="undefined")for(let r of e.keys())nh(t,r)}var pl="mixed";function ihe(t){if(typeof t=="string"&&String(+t)===t)return+t;if(Number.isFinite(t))return t<0?Date.now()/1e3:t;if((0,QO.isDate)(t))return t.getTime()/1e3;throw new Error("Invalid time")}function bO(){return Buffer.from([80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])}var Jr=class extends gl{constructor(e,r){super();this.lzSource=null;this.listings=new Map;this.entries=new Map;this.fileSources=new Map;this.fds=new Map;this.nextFd=0;this.ready=!1;this.readOnly=!1;this.libzip=r.libzip;let i=r;if(this.level=typeof i.level!="undefined"?i.level:pl,e!=null||(e=bO()),typeof e=="string"){let{baseFs:o=new Wt}=i;this.baseFs=o,this.path=e}else this.path=null,this.baseFs=null;if(r.stats)this.stats=r.stats;else if(typeof e=="string")try{this.stats=this.baseFs.statSync(e)}catch(o){if(o.code==="ENOENT"&&i.create)this.stats=Zf();else throw o}else this.stats=Zf();let n=this.libzip.malloc(4);try{let o=0;if(typeof e=="string"&&i.create&&(o|=this.libzip.ZIP_CREATE|this.libzip.ZIP_TRUNCATE),r.readOnly&&(o|=this.libzip.ZIP_RDONLY,this.readOnly=!0),typeof e=="string")this.zip=this.libzip.open(M.fromPortablePath(e),o,n);else{let a=this.allocateUnattachedSource(e);try{this.zip=this.libzip.openFromSource(a,o,n),this.lzSource=a}catch(l){throw this.libzip.source.free(a),l}}if(this.zip===0){let a=this.libzip.struct.errorS();throw this.libzip.error.initWithCode(a,this.libzip.getValue(n,"i32")),this.makeLibzipError(a)}}finally{this.libzip.free(n)}this.listings.set(Se.root,new Set);let s=this.libzip.getNumEntries(this.zip,0);for(let o=0;oe)throw new Error("Overread");let n=this.libzip.HEAPU8.subarray(r,r+e);return Buffer.from(n)}finally{this.libzip.free(r)}}finally{this.libzip.source.close(this.lzSource),this.libzip.source.free(this.lzSource),this.ready=!1}}prepareClose(){if(!this.ready)throw IE("archive closed, close");sh(this)}saveAndClose(){if(!this.path||!this.baseFs)throw new Error("ZipFS cannot be saved and must be discarded when loaded from a buffer");if(this.prepareClose(),this.readOnly){this.discardAndClose();return}let e=this.baseFs.existsSync(this.path)||this.stats.mode===_f?void 0:this.stats.mode;if(this.entries.size===0)this.discardAndClose(),this.baseFs.writeFileSync(this.path,bO(),{mode:e});else{if(this.libzip.close(this.zip)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));typeof e!="undefined"&&this.baseFs.chmodSync(this.path,e)}this.ready=!1}discardAndClose(){this.prepareClose(),this.libzip.discard(this.zip),this.ready=!1}resolve(e){return v.resolve(Se.root,e)}async openPromise(e,r,i){return this.openSync(e,r,i)}openSync(e,r,i){let n=this.nextFd++;return this.fds.set(n,{cursor:0,p:e}),n}hasOpenFileHandles(){return!!this.fds.size}async opendirPromise(e,r){return this.opendirSync(e,r)}opendirSync(e,r={}){let i=this.resolveFilename(`opendir '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw bs(`opendir '${e}'`);let n=this.listings.get(i);if(!n)throw eo(`opendir '${e}'`);let s=[...n],o=this.openSync(i,"r");return wE(this,i,s,{onClose:()=>{this.closeSync(o)}})}async readPromise(e,r,i,n,s){return this.readSync(e,r,i,n,s)}readSync(e,r,i=0,n=r.byteLength,s=-1){let o=this.fds.get(e);if(typeof o=="undefined")throw Hi("read");let a;s===-1||s===null?a=o.cursor:a=s;let l=this.readFileSync(o.p);l.copy(r,i,a,a+n);let c=Math.max(0,Math.min(l.length-a,n));return(s===-1||s===null)&&(o.cursor+=c),c}async writePromise(e,r,i,n,s){return typeof r=="string"?this.writeSync(e,r,s):this.writeSync(e,r,i,n,s)}writeSync(e,r,i,n,s){throw typeof this.fds.get(e)=="undefined"?Hi("read"):new Error("Unimplemented")}async closePromise(e){return this.closeSync(e)}closeSync(e){if(typeof this.fds.get(e)=="undefined")throw Hi("read");this.fds.delete(e)}createReadStream(e,{encoding:r}={}){if(e===null)throw new Error("Unimplemented");let i=this.openSync(e,"r"),n=Object.assign(new cb.PassThrough({emitClose:!0,autoDestroy:!0,destroy:(o,a)=>{clearImmediate(s),this.closeSync(i),a(o)}}),{close(){n.destroy()},bytesRead:0,path:e}),s=setImmediate(async()=>{try{let o=await this.readFilePromise(e,r);n.bytesRead=o.length,n.end(o)}catch(o){n.destroy(o)}});return n}createWriteStream(e,{encoding:r}={}){if(this.readOnly)throw ln(`open '${e}'`);if(e===null)throw new Error("Unimplemented");let i=[],n=this.openSync(e,"w"),s=Object.assign(new cb.PassThrough({autoDestroy:!0,emitClose:!0,destroy:(o,a)=>{try{o?a(o):(this.writeFileSync(e,Buffer.concat(i),r),a(null))}catch(l){a(l)}finally{this.closeSync(n)}}}),{bytesWritten:0,path:e,close(){s.destroy()}});return s.on("data",o=>{let a=Buffer.from(o);s.bytesWritten+=a.length,i.push(a)}),s}async realpathPromise(e){return this.realpathSync(e)}realpathSync(e){let r=this.resolveFilename(`lstat '${e}'`,e);if(!this.entries.has(r)&&!this.listings.has(r))throw bs(`lstat '${e}'`);return r}async existsPromise(e){return this.existsSync(e)}existsSync(e){if(!this.ready)throw IE(`archive closed, existsSync '${e}'`);if(this.symlinkCount===0){let i=v.resolve(Se.root,e);return this.entries.has(i)||this.listings.has(i)}let r;try{r=this.resolveFilename(`stat '${e}'`,e)}catch(i){return!1}return this.entries.has(r)||this.listings.has(r)}async accessPromise(e,r){return this.accessSync(e,r)}accessSync(e,r=$c.constants.F_OK){let i=this.resolveFilename(`access '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw bs(`access '${e}'`);if(this.readOnly&&r&$c.constants.W_OK)throw ln(`access '${e}'`)}async statPromise(e,r){return this.statSync(e,r)}statSync(e,r){let i=this.resolveFilename(`stat '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw bs(`stat '${e}'`);if(e[e.length-1]==="/"&&!this.listings.has(i))throw eo(`stat '${e}'`);return this.statImpl(`stat '${e}'`,i,r)}async fstatPromise(e,r){return this.fstatSync(e,r)}fstatSync(e,r){let i=this.fds.get(e);if(typeof i=="undefined")throw Hi("fstatSync");let{p:n}=i,s=this.resolveFilename(`stat '${n}'`,n);if(!this.entries.has(s)&&!this.listings.has(s))throw bs(`stat '${n}'`);if(n[n.length-1]==="/"&&!this.listings.has(s))throw eo(`stat '${n}'`);return this.statImpl(`fstat '${n}'`,s,r)}async lstatPromise(e,r){return this.lstatSync(e,r)}lstatSync(e,r){let i=this.resolveFilename(`lstat '${e}'`,e,!1);if(!this.entries.has(i)&&!this.listings.has(i))throw bs(`lstat '${e}'`);if(e[e.length-1]==="/"&&!this.listings.has(i))throw eo(`lstat '${e}'`);return this.statImpl(`lstat '${e}'`,i,r)}statImpl(e,r,i={}){let n=this.entries.get(r);if(typeof n!="undefined"){let s=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,n,0,0,s)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let a=this.stats.uid,l=this.stats.gid,c=this.libzip.struct.statSize(s)>>>0,u=512,g=Math.ceil(c/u),f=(this.libzip.struct.statMtime(s)>>>0)*1e3,h=f,p=f,d=f,m=new Date(h),I=new Date(p),B=new Date(d),b=new Date(f),R=this.listings.has(r)?zo:this.isSymbolicLink(n)?_o:Vo,H=R===zo?493:420,L=R|this.getUnixMode(n,H)&511,K=this.libzip.struct.statCrc(s),J=Object.assign(new Za,{uid:a,gid:l,size:c,blksize:u,blocks:g,atime:m,birthtime:I,ctime:B,mtime:b,atimeMs:h,birthtimeMs:p,ctimeMs:d,mtimeMs:f,mode:L,crc:K});return i.bigint===!0?dE(J):J}if(this.listings.has(r)){let s=this.stats.uid,o=this.stats.gid,a=0,l=512,c=0,u=this.stats.mtimeMs,g=this.stats.mtimeMs,f=this.stats.mtimeMs,h=this.stats.mtimeMs,p=new Date(u),d=new Date(g),m=new Date(f),I=new Date(h),B=zo|493,b=0,R=Object.assign(new Za,{uid:s,gid:o,size:a,blksize:l,blocks:c,atime:p,birthtime:d,ctime:m,mtime:I,atimeMs:u,birthtimeMs:g,ctimeMs:f,mtimeMs:h,mode:B,crc:b});return i.bigint===!0?dE(R):R}throw new Error("Unreachable")}getUnixMode(e,r){if(this.libzip.file.getExternalAttributes(this.zip,e,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?r:this.libzip.getValue(this.libzip.uint32S,"i32")>>>16}registerListing(e){let r=this.listings.get(e);if(r)return r;let i=this.registerListing(v.dirname(e));return r=new Set,i.add(v.basename(e)),this.listings.set(e,r),r}registerEntry(e,r){this.registerListing(v.dirname(e)).add(v.basename(e)),this.entries.set(e,r)}unregisterListing(e){this.listings.delete(e);let r=this.listings.get(v.dirname(e));r==null||r.delete(v.basename(e))}unregisterEntry(e){this.unregisterListing(e);let r=this.entries.get(e);this.entries.delete(e),typeof r!="undefined"&&(this.fileSources.delete(r),this.isSymbolicLink(r)&&this.symlinkCount--)}deleteEntry(e,r){if(this.unregisterEntry(e),this.libzip.delete(this.zip,r)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}resolveFilename(e,r,i=!0){if(!this.ready)throw IE(`archive closed, ${e}`);let n=v.resolve(Se.root,r);if(n==="/")return Se.root;let s=this.entries.get(n);if(i&&s!==void 0)if(this.symlinkCount!==0&&this.isSymbolicLink(s)){let o=this.getFileSource(s).toString();return this.resolveFilename(e,v.resolve(v.dirname(n),o),!0)}else return n;for(;;){let o=this.resolveFilename(e,v.dirname(n),!0),a=this.listings.has(o),l=this.entries.has(o);if(!a&&!l)throw bs(e);if(!a)throw eo(e);if(n=v.resolve(o,v.basename(n)),!i||this.symlinkCount===0)break;let c=this.libzip.name.locate(this.zip,n.slice(1));if(c===-1)break;if(this.isSymbolicLink(c)){let u=this.getFileSource(c).toString();n=v.resolve(v.dirname(n),u)}else break}return n}allocateBuffer(e){Buffer.isBuffer(e)||(e=Buffer.from(e));let r=this.libzip.malloc(e.byteLength);if(!r)throw new Error("Couldn't allocate enough memory");return new Uint8Array(this.libzip.HEAPU8.buffer,r,e.byteLength).set(e),{buffer:r,byteLength:e.byteLength}}allocateUnattachedSource(e){let r=this.libzip.struct.errorS(),{buffer:i,byteLength:n}=this.allocateBuffer(e),s=this.libzip.source.fromUnattachedBuffer(i,n,0,!0,r);if(s===0)throw this.libzip.free(r),this.makeLibzipError(r);return s}allocateSource(e){let{buffer:r,byteLength:i}=this.allocateBuffer(e),n=this.libzip.source.fromBuffer(this.zip,r,i,0,!0);if(n===0)throw this.libzip.free(r),this.makeLibzipError(this.libzip.getError(this.zip));return n}setFileSource(e,r){let i=Buffer.isBuffer(r)?r:Buffer.from(r),n=v.relative(Se.root,e),s=this.allocateSource(r);try{let o=this.libzip.file.add(this.zip,n,s,this.libzip.ZIP_FL_OVERWRITE);if(o===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.level!=="mixed"){let a;if(this.level===0?a=this.libzip.ZIP_CM_STORE:a=this.libzip.ZIP_CM_DEFLATE,this.libzip.file.setCompression(this.zip,o,0,a,this.level)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}return this.fileSources.set(o,i),o}catch(o){throw this.libzip.source.free(s),o}}isSymbolicLink(e){if(this.symlinkCount===0)return!1;if(this.libzip.file.getExternalAttributes(this.zip,e,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?!1:(this.libzip.getValue(this.libzip.uint32S,"i32")>>>16&kn)===_o}getFileSource(e,r={asyncDecompress:!1}){let i=this.fileSources.get(e);if(typeof i!="undefined")return i;let n=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,e,0,0,n)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let o=this.libzip.struct.statCompSize(n),a=this.libzip.struct.statCompMethod(n),l=this.libzip.malloc(o);try{let c=this.libzip.fopenIndex(this.zip,e,0,this.libzip.ZIP_FL_COMPRESSED);if(c===0)throw this.makeLibzipError(this.libzip.getError(this.zip));try{let u=this.libzip.fread(c,l,o,0);if(u===-1)throw this.makeLibzipError(this.libzip.file.getError(c));if(uo)throw new Error("Overread");let g=this.libzip.HEAPU8.subarray(l,l+o),f=Buffer.from(g);if(a===0)return this.fileSources.set(e,f),f;if(r.asyncDecompress)return new Promise((h,p)=>{ub.default.inflateRaw(f,(d,m)=>{d?p(d):(this.fileSources.set(e,m),h(m))})});{let h=ub.default.inflateRawSync(f);return this.fileSources.set(e,h),h}}finally{this.libzip.fclose(c)}}finally{this.libzip.free(l)}}async chmodPromise(e,r){return this.chmodSync(e,r)}chmodSync(e,r){if(this.readOnly)throw ln(`chmod '${e}'`);r&=493;let i=this.resolveFilename(`chmod '${e}'`,e,!1),n=this.entries.get(i);if(typeof n=="undefined")throw new Error(`Assertion failed: The entry should have been registered (${i})`);let o=this.getUnixMode(n,Vo|0)&~511|r;if(this.libzip.file.setExternalAttributes(this.zip,n,0,0,this.libzip.ZIP_OPSYS_UNIX,o<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async chownPromise(e,r,i){return this.chownSync(e,r,i)}chownSync(e,r,i){throw new Error("Unimplemented")}async renamePromise(e,r){return this.renameSync(e,r)}renameSync(e,r){throw new Error("Unimplemented")}async copyFilePromise(e,r,i){let{indexSource:n,indexDest:s,resolvedDestP:o}=this.prepareCopyFile(e,r,i),a=await this.getFileSource(n,{asyncDecompress:!0}),l=this.setFileSource(o,a);l!==s&&this.registerEntry(o,l)}copyFileSync(e,r,i=0){let{indexSource:n,indexDest:s,resolvedDestP:o}=this.prepareCopyFile(e,r,i),a=this.getFileSource(n),l=this.setFileSource(o,a);l!==s&&this.registerEntry(o,l)}prepareCopyFile(e,r,i=0){if(this.readOnly)throw ln(`copyfile '${e} -> '${r}'`);if((i&$c.constants.COPYFILE_FICLONE_FORCE)!=0)throw th("unsupported clone operation",`copyfile '${e}' -> ${r}'`);let n=this.resolveFilename(`copyfile '${e} -> ${r}'`,e),s=this.entries.get(n);if(typeof s=="undefined")throw $a(`copyfile '${e}' -> '${r}'`);let o=this.resolveFilename(`copyfile '${e}' -> ${r}'`,r),a=this.entries.get(o);if((i&($c.constants.COPYFILE_EXCL|$c.constants.COPYFILE_FICLONE_FORCE))!=0&&typeof a!="undefined")throw yE(`copyfile '${e}' -> '${r}'`);return{indexSource:s,resolvedDestP:o,indexDest:a}}async appendFilePromise(e,r,i){if(this.readOnly)throw ln(`open '${e}'`);return typeof i=="undefined"?i={flag:"a"}:typeof i=="string"?i={flag:"a",encoding:i}:typeof i.flag=="undefined"&&(i=P({flag:"a"},i)),this.writeFilePromise(e,r,i)}appendFileSync(e,r,i={}){if(this.readOnly)throw ln(`open '${e}'`);return typeof i=="undefined"?i={flag:"a"}:typeof i=="string"?i={flag:"a",encoding:i}:typeof i.flag=="undefined"&&(i=P({flag:"a"},i)),this.writeFileSync(e,r,i)}fdToPath(e,r){var n;let i=(n=this.fds.get(e))==null?void 0:n.p;if(typeof i=="undefined")throw Hi(r);return i}async writeFilePromise(e,r,i){let{encoding:n,mode:s,index:o,resolvedP:a}=this.prepareWriteFile(e,i);o!==void 0&&typeof i=="object"&&i.flag&&i.flag.includes("a")&&(r=Buffer.concat([await this.getFileSource(o,{asyncDecompress:!0}),Buffer.from(r)])),n!==null&&(r=r.toString(n));let l=this.setFileSource(a,r);l!==o&&this.registerEntry(a,l),s!==null&&await this.chmodPromise(a,s)}writeFileSync(e,r,i){let{encoding:n,mode:s,index:o,resolvedP:a}=this.prepareWriteFile(e,i);o!==void 0&&typeof i=="object"&&i.flag&&i.flag.includes("a")&&(r=Buffer.concat([this.getFileSource(o),Buffer.from(r)])),n!==null&&(r=r.toString(n));let l=this.setFileSource(a,r);l!==o&&this.registerEntry(a,l),s!==null&&this.chmodSync(a,s)}prepareWriteFile(e,r){if(typeof e=="number"&&(e=this.fdToPath(e,"read")),this.readOnly)throw ln(`open '${e}'`);let i=this.resolveFilename(`open '${e}'`,e);if(this.listings.has(i))throw rh(`open '${e}'`);let n=null,s=null;typeof r=="string"?n=r:typeof r=="object"&&({encoding:n=null,mode:s=null}=r);let o=this.entries.get(i);return{encoding:n,mode:s,resolvedP:i,index:o}}async unlinkPromise(e){return this.unlinkSync(e)}unlinkSync(e){if(this.readOnly)throw ln(`unlink '${e}'`);let r=this.resolveFilename(`unlink '${e}'`,e);if(this.listings.has(r))throw rh(`unlink '${e}'`);let i=this.entries.get(r);if(typeof i=="undefined")throw $a(`unlink '${e}'`);this.deleteEntry(r,i)}async utimesPromise(e,r,i){return this.utimesSync(e,r,i)}utimesSync(e,r,i){if(this.readOnly)throw ln(`utimes '${e}'`);let n=this.resolveFilename(`utimes '${e}'`,e);this.utimesImpl(n,i)}async lutimesPromise(e,r,i){return this.lutimesSync(e,r,i)}lutimesSync(e,r,i){if(this.readOnly)throw ln(`lutimes '${e}'`);let n=this.resolveFilename(`utimes '${e}'`,e,!1);this.utimesImpl(n,i)}utimesImpl(e,r){this.listings.has(e)&&(this.entries.has(e)||this.hydrateDirectory(e));let i=this.entries.get(e);if(i===void 0)throw new Error("Unreachable");if(this.libzip.file.setMtime(this.zip,i,0,ihe(r),0)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async mkdirPromise(e,r){return this.mkdirSync(e,r)}mkdirSync(e,{mode:r=493,recursive:i=!1}={}){if(i){this.mkdirpSync(e,{chmod:r});return}if(this.readOnly)throw ln(`mkdir '${e}'`);let n=this.resolveFilename(`mkdir '${e}'`,e);if(this.entries.has(n)||this.listings.has(n))throw yE(`mkdir '${e}'`);this.hydrateDirectory(n),this.chmodSync(n,r)}async rmdirPromise(e,r){return this.rmdirSync(e,r)}rmdirSync(e,{recursive:r=!1}={}){if(this.readOnly)throw ln(`rmdir '${e}'`);if(r){this.removeSync(e);return}let i=this.resolveFilename(`rmdir '${e}'`,e),n=this.listings.get(i);if(!n)throw eo(`rmdir '${e}'`);if(n.size>0)throw dO(`rmdir '${e}'`);let s=this.entries.get(i);if(typeof s=="undefined")throw $a(`rmdir '${e}'`);this.deleteEntry(e,s)}hydrateDirectory(e){let r=this.libzip.dir.add(this.zip,v.relative(Se.root,e));if(r===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.registerListing(e),this.registerEntry(e,r),r}async linkPromise(e,r){return this.linkSync(e,r)}linkSync(e,r){throw CO(`link '${e}' -> '${r}'`)}async symlinkPromise(e,r){return this.symlinkSync(e,r)}symlinkSync(e,r){if(this.readOnly)throw ln(`symlink '${e}' -> '${r}'`);let i=this.resolveFilename(`symlink '${e}' -> '${r}'`,r);if(this.listings.has(i))throw rh(`symlink '${e}' -> '${r}'`);if(this.entries.has(i))throw yE(`symlink '${e}' -> '${r}'`);let n=this.setFileSource(i,e);if(this.registerEntry(i,n),this.libzip.file.setExternalAttributes(this.zip,n,0,0,this.libzip.ZIP_OPSYS_UNIX,(_o|511)<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.symlinkCount+=1}async readFilePromise(e,r){typeof r=="object"&&(r=r?r.encoding:void 0);let i=await this.readFileBuffer(e,{asyncDecompress:!0});return r?i.toString(r):i}readFileSync(e,r){typeof r=="object"&&(r=r?r.encoding:void 0);let i=this.readFileBuffer(e);return r?i.toString(r):i}readFileBuffer(e,r={asyncDecompress:!1}){typeof e=="number"&&(e=this.fdToPath(e,"read"));let i=this.resolveFilename(`open '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw bs(`open '${e}'`);if(e[e.length-1]==="/"&&!this.listings.has(i))throw eo(`open '${e}'`);if(this.listings.has(i))throw rh("read");let n=this.entries.get(i);if(n===void 0)throw new Error("Unreachable");return this.getFileSource(n,r)}async readdirPromise(e,r){return this.readdirSync(e,r)}readdirSync(e,r){let i=this.resolveFilename(`scandir '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw bs(`scandir '${e}'`);let n=this.listings.get(i);if(!n)throw eo(`scandir '${e}'`);let s=[...n];return(r==null?void 0:r.withFileTypes)?s.map(o=>Object.assign(this.statImpl("lstat",v.join(e,o)),{name:o})):s}async readlinkPromise(e){let r=this.prepareReadlink(e);return(await this.getFileSource(r,{asyncDecompress:!0})).toString()}readlinkSync(e){let r=this.prepareReadlink(e);return this.getFileSource(r).toString()}prepareReadlink(e){let r=this.resolveFilename(`readlink '${e}'`,e,!1);if(!this.entries.has(r)&&!this.listings.has(r))throw bs(`readlink '${e}'`);if(e[e.length-1]==="/"&&!this.listings.has(r))throw eo(`open '${e}'`);if(this.listings.has(r))throw $a(`readlink '${e}'`);let i=this.entries.get(r);if(i===void 0)throw new Error("Unreachable");if(!this.isSymbolicLink(i))throw $a(`readlink '${e}'`);return i}async truncatePromise(e,r=0){let i=this.resolveFilename(`open '${e}'`,e),n=this.entries.get(i);if(typeof n=="undefined")throw $a(`open '${e}'`);let s=await this.getFileSource(n,{asyncDecompress:!0}),o=Buffer.alloc(r,0);return s.copy(o),await this.writeFilePromise(e,o)}truncateSync(e,r=0){let i=this.resolveFilename(`open '${e}'`,e),n=this.entries.get(i);if(typeof n=="undefined")throw $a(`open '${e}'`);let s=this.getFileSource(n),o=Buffer.alloc(r,0);return s.copy(o),this.writeFileSync(e,o)}watch(e,r,i){let n;switch(typeof r){case"function":case"string":case"undefined":n=!0;break;default:({persistent:n=!0}=r);break}if(!n)return{on:()=>{},close:()=>{}};let s=setInterval(()=>{},24*60*60*1e3);return{on:()=>{},close:()=>{clearInterval(s)}}}watchFile(e,r,i){let n=v.resolve(Se.root,e);return QE(this,n,r,i)}unwatchFile(e,r){let i=v.resolve(Se.root,e);return nh(this,i,r)}};var fi=class extends eA{getExtractHint(e){return this.baseFs.getExtractHint(e)}resolve(e){return this.mapFromBase(this.baseFs.resolve(this.mapToBase(e)))}getRealPath(){return this.mapFromBase(this.baseFs.getRealPath())}async openPromise(e,r,i){return this.baseFs.openPromise(this.mapToBase(e),r,i)}openSync(e,r,i){return this.baseFs.openSync(this.mapToBase(e),r,i)}async opendirPromise(e,r){return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(e),r),{path:e})}opendirSync(e,r){return Object.assign(this.baseFs.opendirSync(this.mapToBase(e),r),{path:e})}async readPromise(e,r,i,n,s){return await this.baseFs.readPromise(e,r,i,n,s)}readSync(e,r,i,n,s){return this.baseFs.readSync(e,r,i,n,s)}async writePromise(e,r,i,n,s){return typeof r=="string"?await this.baseFs.writePromise(e,r,i):await this.baseFs.writePromise(e,r,i,n,s)}writeSync(e,r,i,n,s){return typeof r=="string"?this.baseFs.writeSync(e,r,i):this.baseFs.writeSync(e,r,i,n,s)}async closePromise(e){return this.baseFs.closePromise(e)}closeSync(e){this.baseFs.closeSync(e)}createReadStream(e,r){return this.baseFs.createReadStream(e!==null?this.mapToBase(e):e,r)}createWriteStream(e,r){return this.baseFs.createWriteStream(e!==null?this.mapToBase(e):e,r)}async realpathPromise(e){return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(e)))}realpathSync(e){return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(e)))}async existsPromise(e){return this.baseFs.existsPromise(this.mapToBase(e))}existsSync(e){return this.baseFs.existsSync(this.mapToBase(e))}accessSync(e,r){return this.baseFs.accessSync(this.mapToBase(e),r)}async accessPromise(e,r){return this.baseFs.accessPromise(this.mapToBase(e),r)}async statPromise(e,r){return this.baseFs.statPromise(this.mapToBase(e),r)}statSync(e,r){return this.baseFs.statSync(this.mapToBase(e),r)}async fstatPromise(e,r){return this.baseFs.fstatPromise(e,r)}fstatSync(e,r){return this.baseFs.fstatSync(e,r)}async lstatPromise(e,r){return this.baseFs.lstatPromise(this.mapToBase(e),r)}lstatSync(e,r){return this.baseFs.lstatSync(this.mapToBase(e),r)}async chmodPromise(e,r){return this.baseFs.chmodPromise(this.mapToBase(e),r)}chmodSync(e,r){return this.baseFs.chmodSync(this.mapToBase(e),r)}async chownPromise(e,r,i){return this.baseFs.chownPromise(this.mapToBase(e),r,i)}chownSync(e,r,i){return this.baseFs.chownSync(this.mapToBase(e),r,i)}async renamePromise(e,r){return this.baseFs.renamePromise(this.mapToBase(e),this.mapToBase(r))}renameSync(e,r){return this.baseFs.renameSync(this.mapToBase(e),this.mapToBase(r))}async copyFilePromise(e,r,i=0){return this.baseFs.copyFilePromise(this.mapToBase(e),this.mapToBase(r),i)}copyFileSync(e,r,i=0){return this.baseFs.copyFileSync(this.mapToBase(e),this.mapToBase(r),i)}async appendFilePromise(e,r,i){return this.baseFs.appendFilePromise(this.fsMapToBase(e),r,i)}appendFileSync(e,r,i){return this.baseFs.appendFileSync(this.fsMapToBase(e),r,i)}async writeFilePromise(e,r,i){return this.baseFs.writeFilePromise(this.fsMapToBase(e),r,i)}writeFileSync(e,r,i){return this.baseFs.writeFileSync(this.fsMapToBase(e),r,i)}async unlinkPromise(e){return this.baseFs.unlinkPromise(this.mapToBase(e))}unlinkSync(e){return this.baseFs.unlinkSync(this.mapToBase(e))}async utimesPromise(e,r,i){return this.baseFs.utimesPromise(this.mapToBase(e),r,i)}utimesSync(e,r,i){return this.baseFs.utimesSync(this.mapToBase(e),r,i)}async mkdirPromise(e,r){return this.baseFs.mkdirPromise(this.mapToBase(e),r)}mkdirSync(e,r){return this.baseFs.mkdirSync(this.mapToBase(e),r)}async rmdirPromise(e,r){return this.baseFs.rmdirPromise(this.mapToBase(e),r)}rmdirSync(e,r){return this.baseFs.rmdirSync(this.mapToBase(e),r)}async linkPromise(e,r){return this.baseFs.linkPromise(this.mapToBase(e),this.mapToBase(r))}linkSync(e,r){return this.baseFs.linkSync(this.mapToBase(e),this.mapToBase(r))}async symlinkPromise(e,r,i){let n=this.mapToBase(r);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkPromise(this.mapToBase(e),n,i);let s=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(r),e)),o=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(n),s);return this.baseFs.symlinkPromise(o,n,i)}symlinkSync(e,r,i){let n=this.mapToBase(r);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkSync(this.mapToBase(e),n,i);let s=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(r),e)),o=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(n),s);return this.baseFs.symlinkSync(o,n,i)}async readFilePromise(e,r){return r==="utf8"?this.baseFs.readFilePromise(this.fsMapToBase(e),r):this.baseFs.readFilePromise(this.fsMapToBase(e),r)}readFileSync(e,r){return r==="utf8"?this.baseFs.readFileSync(this.fsMapToBase(e),r):this.baseFs.readFileSync(this.fsMapToBase(e),r)}async readdirPromise(e,r){return this.baseFs.readdirPromise(this.mapToBase(e),r)}readdirSync(e,r){return this.baseFs.readdirSync(this.mapToBase(e),r)}async readlinkPromise(e){return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(e)))}readlinkSync(e){return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(e)))}async truncatePromise(e,r){return this.baseFs.truncatePromise(this.mapToBase(e),r)}truncateSync(e,r){return this.baseFs.truncateSync(this.mapToBase(e),r)}watch(e,r,i){return this.baseFs.watch(this.mapToBase(e),r,i)}watchFile(e,r,i){return this.baseFs.watchFile(this.mapToBase(e),r,i)}unwatchFile(e,r){return this.baseFs.unwatchFile(this.mapToBase(e),r)}fsMapToBase(e){return typeof e=="number"?e:this.mapToBase(e)}};var Xo=class extends fi{constructor(e,{baseFs:r,pathUtils:i}){super(i);this.target=e,this.baseFs=r}getRealPath(){return this.target}getBaseFs(){return this.baseFs}mapFromBase(e){return e}mapToBase(e){return e}};var Ft=class extends fi{constructor(e,{baseFs:r=new Wt}={}){super(v);this.target=this.pathUtils.normalize(e),this.baseFs=r}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.target)}resolve(e){return this.pathUtils.isAbsolute(e)?v.normalize(e):this.baseFs.resolve(v.join(this.target,e))}mapFromBase(e){return e}mapToBase(e){return this.pathUtils.isAbsolute(e)?e:this.pathUtils.join(this.target,e)}};var vO=Se.root,Zo=class extends fi{constructor(e,{baseFs:r=new Wt}={}){super(v);this.target=this.pathUtils.resolve(Se.root,e),this.baseFs=r}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.pathUtils.relative(Se.root,this.target))}getTarget(){return this.target}getBaseFs(){return this.baseFs}mapToBase(e){let r=this.pathUtils.normalize(e);if(this.pathUtils.isAbsolute(e))return this.pathUtils.resolve(this.target,this.pathUtils.relative(vO,e));if(r.match(/^\.\.\/?/))throw new Error(`Resolving this path (${e}) would escape the jail`);return this.pathUtils.resolve(this.target,e)}mapFromBase(e){return this.pathUtils.resolve(vO,this.pathUtils.relative(this.target,e))}};var oh=class extends fi{constructor(e,r){super(r);this.instance=null;this.factory=e}get baseFs(){return this.instance||(this.instance=this.factory()),this.instance}set baseFs(e){this.instance=e}mapFromBase(e){return e}mapToBase(e){return e}};var ze=()=>Object.assign(new Error("ENOSYS: unsupported filesystem access"),{code:"ENOSYS"}),gb=class extends eA{constructor(){super(v)}getExtractHint(){throw ze()}getRealPath(){throw ze()}resolve(){throw ze()}async openPromise(){throw ze()}openSync(){throw ze()}async opendirPromise(){throw ze()}opendirSync(){throw ze()}async readPromise(){throw ze()}readSync(){throw ze()}async writePromise(){throw ze()}writeSync(){throw ze()}async closePromise(){throw ze()}closeSync(){throw ze()}createWriteStream(){throw ze()}createReadStream(){throw ze()}async realpathPromise(){throw ze()}realpathSync(){throw ze()}async readdirPromise(){throw ze()}readdirSync(){throw ze()}async existsPromise(e){throw ze()}existsSync(e){throw ze()}async accessPromise(){throw ze()}accessSync(){throw ze()}async statPromise(){throw ze()}statSync(){throw ze()}async fstatPromise(e){throw ze()}fstatSync(e){throw ze()}async lstatPromise(e){throw ze()}lstatSync(e){throw ze()}async chmodPromise(){throw ze()}chmodSync(){throw ze()}async chownPromise(){throw ze()}chownSync(){throw ze()}async mkdirPromise(){throw ze()}mkdirSync(){throw ze()}async rmdirPromise(){throw ze()}rmdirSync(){throw ze()}async linkPromise(){throw ze()}linkSync(){throw ze()}async symlinkPromise(){throw ze()}symlinkSync(){throw ze()}async renamePromise(){throw ze()}renameSync(){throw ze()}async copyFilePromise(){throw ze()}copyFileSync(){throw ze()}async appendFilePromise(){throw ze()}appendFileSync(){throw ze()}async writeFilePromise(){throw ze()}writeFileSync(){throw ze()}async unlinkPromise(){throw ze()}unlinkSync(){throw ze()}async utimesPromise(){throw ze()}utimesSync(){throw ze()}async readFilePromise(){throw ze()}readFileSync(){throw ze()}async readlinkPromise(){throw ze()}readlinkSync(){throw ze()}async truncatePromise(){throw ze()}truncateSync(){throw ze()}watch(){throw ze()}watchFile(){throw ze()}unwatchFile(){throw ze()}},bE=gb;bE.instance=new gb;var ah=class extends fi{constructor(e){super(M);this.baseFs=e}mapFromBase(e){return M.fromPortablePath(e)}mapToBase(e){return M.toPortablePath(e)}};var nhe=/^[0-9]+$/,fb=/^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/,she=/^([^/]+-)?[a-f0-9]+$/,Pr=class extends fi{static makeVirtualPath(e,r,i){if(v.basename(e)!=="__virtual__")throw new Error('Assertion failed: Virtual folders must be named "__virtual__"');if(!v.basename(r).match(she))throw new Error("Assertion failed: Virtual components must be ended by an hexadecimal hash");let s=v.relative(v.dirname(e),i).split("/"),o=0;for(;o{let r=t.indexOf(e);if(r<=0)return null;let i=r;for(;r>=0&&(i=r+e.length,t[i]!==v.sep);){if(t[r-1]===v.sep)return null;r=t.indexOf(e,i)}return t.length>i&&t[i]!==v.sep?null:t.slice(0,i)},Jn=class extends gl{constructor({libzip:e,baseFs:r=new Wt,filter:i=null,maxOpenFiles:n=Infinity,readOnlyArchives:s=!1,useCache:o=!0,maxAge:a=5e3,fileExtensions:l=null}){super();this.fdMap=new Map;this.nextFd=3;this.isZip=new Set;this.notZip=new Set;this.realPaths=new Map;this.limitOpenFilesTimeout=null;this.libzipFactory=typeof e!="function"?()=>e:e,this.baseFs=r,this.zipInstances=o?new Map:null,this.filter=i,this.maxOpenFiles=n,this.readOnlyArchives=s,this.maxAge=a,this.fileExtensions=l}static async openPromise(e,r){let i=new Jn(r);try{return await e(i)}finally{i.saveAndClose()}}get libzip(){return typeof this.libzipInstance=="undefined"&&(this.libzipInstance=this.libzipFactory()),this.libzipInstance}getExtractHint(e){return this.baseFs.getExtractHint(e)}getRealPath(){return this.baseFs.getRealPath()}saveAndClose(){if(sh(this),this.zipInstances)for(let[e,{zipFs:r}]of this.zipInstances.entries())r.saveAndClose(),this.zipInstances.delete(e)}discardAndClose(){if(sh(this),this.zipInstances)for(let[e,{zipFs:r}]of this.zipInstances.entries())r.discardAndClose(),this.zipInstances.delete(e)}resolve(e){return this.baseFs.resolve(e)}remapFd(e,r){let i=this.nextFd++|$o;return this.fdMap.set(i,[e,r]),i}async openPromise(e,r,i){return await this.makeCallPromise(e,async()=>await this.baseFs.openPromise(e,r,i),async(n,{subPath:s})=>this.remapFd(n,await n.openPromise(s,r,i)))}openSync(e,r,i){return this.makeCallSync(e,()=>this.baseFs.openSync(e,r,i),(n,{subPath:s})=>this.remapFd(n,n.openSync(s,r,i)))}async opendirPromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.opendirPromise(e,r),async(i,{subPath:n})=>await i.opendirPromise(n,r),{requireSubpath:!1})}opendirSync(e,r){return this.makeCallSync(e,()=>this.baseFs.opendirSync(e,r),(i,{subPath:n})=>i.opendirSync(n,r),{requireSubpath:!1})}async readPromise(e,r,i,n,s){if((e&$o)==0)return await this.baseFs.readPromise(e,r,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Hi("read");let[a,l]=o;return await a.readPromise(l,r,i,n,s)}readSync(e,r,i,n,s){if((e&$o)==0)return this.baseFs.readSync(e,r,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Hi("readSync");let[a,l]=o;return a.readSync(l,r,i,n,s)}async writePromise(e,r,i,n,s){if((e&$o)==0)return typeof r=="string"?await this.baseFs.writePromise(e,r,i):await this.baseFs.writePromise(e,r,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Hi("write");let[a,l]=o;return typeof r=="string"?await a.writePromise(l,r,i):await a.writePromise(l,r,i,n,s)}writeSync(e,r,i,n,s){if((e&$o)==0)return typeof r=="string"?this.baseFs.writeSync(e,r,i):this.baseFs.writeSync(e,r,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Hi("writeSync");let[a,l]=o;return typeof r=="string"?a.writeSync(l,r,i):a.writeSync(l,r,i,n,s)}async closePromise(e){if((e&$o)==0)return await this.baseFs.closePromise(e);let r=this.fdMap.get(e);if(typeof r=="undefined")throw Hi("close");this.fdMap.delete(e);let[i,n]=r;return await i.closePromise(n)}closeSync(e){if((e&$o)==0)return this.baseFs.closeSync(e);let r=this.fdMap.get(e);if(typeof r=="undefined")throw Hi("closeSync");this.fdMap.delete(e);let[i,n]=r;return i.closeSync(n)}createReadStream(e,r){return e===null?this.baseFs.createReadStream(e,r):this.makeCallSync(e,()=>this.baseFs.createReadStream(e,r),(i,{subPath:n})=>i.createReadStream(n,r))}createWriteStream(e,r){return e===null?this.baseFs.createWriteStream(e,r):this.makeCallSync(e,()=>this.baseFs.createWriteStream(e,r),(i,{subPath:n})=>i.createWriteStream(n,r))}async realpathPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.realpathPromise(e),async(r,{archivePath:i,subPath:n})=>{let s=this.realPaths.get(i);return typeof s=="undefined"&&(s=await this.baseFs.realpathPromise(i),this.realPaths.set(i,s)),this.pathUtils.join(s,this.pathUtils.relative(Se.root,await r.realpathPromise(n)))})}realpathSync(e){return this.makeCallSync(e,()=>this.baseFs.realpathSync(e),(r,{archivePath:i,subPath:n})=>{let s=this.realPaths.get(i);return typeof s=="undefined"&&(s=this.baseFs.realpathSync(i),this.realPaths.set(i,s)),this.pathUtils.join(s,this.pathUtils.relative(Se.root,r.realpathSync(n)))})}async existsPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.existsPromise(e),async(r,{subPath:i})=>await r.existsPromise(i))}existsSync(e){return this.makeCallSync(e,()=>this.baseFs.existsSync(e),(r,{subPath:i})=>r.existsSync(i))}async accessPromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.accessPromise(e,r),async(i,{subPath:n})=>await i.accessPromise(n,r))}accessSync(e,r){return this.makeCallSync(e,()=>this.baseFs.accessSync(e,r),(i,{subPath:n})=>i.accessSync(n,r))}async statPromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.statPromise(e,r),async(i,{subPath:n})=>await i.statPromise(n,r))}statSync(e,r){return this.makeCallSync(e,()=>this.baseFs.statSync(e,r),(i,{subPath:n})=>i.statSync(n,r))}async fstatPromise(e,r){if((e&$o)==0)return this.baseFs.fstatPromise(e,r);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Hi("fstat");let[n,s]=i;return n.fstatPromise(s,r)}fstatSync(e,r){if((e&$o)==0)return this.baseFs.fstatSync(e,r);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Hi("fstatSync");let[n,s]=i;return n.fstatSync(s,r)}async lstatPromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.lstatPromise(e,r),async(i,{subPath:n})=>await i.lstatPromise(n,r))}lstatSync(e,r){return this.makeCallSync(e,()=>this.baseFs.lstatSync(e,r),(i,{subPath:n})=>i.lstatSync(n,r))}async chmodPromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.chmodPromise(e,r),async(i,{subPath:n})=>await i.chmodPromise(n,r))}chmodSync(e,r){return this.makeCallSync(e,()=>this.baseFs.chmodSync(e,r),(i,{subPath:n})=>i.chmodSync(n,r))}async chownPromise(e,r,i){return await this.makeCallPromise(e,async()=>await this.baseFs.chownPromise(e,r,i),async(n,{subPath:s})=>await n.chownPromise(s,r,i))}chownSync(e,r,i){return this.makeCallSync(e,()=>this.baseFs.chownSync(e,r,i),(n,{subPath:s})=>n.chownSync(s,r,i))}async renamePromise(e,r){return await this.makeCallPromise(e,async()=>await this.makeCallPromise(r,async()=>await this.baseFs.renamePromise(e,r),async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),async(i,{subPath:n})=>await this.makeCallPromise(r,async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},async(s,{subPath:o})=>{if(i!==s)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return await i.renamePromise(n,o)}))}renameSync(e,r){return this.makeCallSync(e,()=>this.makeCallSync(r,()=>this.baseFs.renameSync(e,r),()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),(i,{subPath:n})=>this.makeCallSync(r,()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},(s,{subPath:o})=>{if(i!==s)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return i.renameSync(n,o)}))}async copyFilePromise(e,r,i=0){let n=async(s,o,a,l)=>{if((i&Ah.constants.COPYFILE_FICLONE_FORCE)!=0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${o}' -> ${l}'`),{code:"EXDEV"});if(i&Ah.constants.COPYFILE_EXCL&&await this.existsPromise(o))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${o}' -> '${l}'`),{code:"EEXIST"});let c;try{c=await s.readFilePromise(o)}catch(u){throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${o}' -> '${l}'`),{code:"EINVAL"})}await a.writeFilePromise(l,c)};return await this.makeCallPromise(e,async()=>await this.makeCallPromise(r,async()=>await this.baseFs.copyFilePromise(e,r,i),async(s,{subPath:o})=>await n(this.baseFs,e,s,o)),async(s,{subPath:o})=>await this.makeCallPromise(r,async()=>await n(s,o,this.baseFs,r),async(a,{subPath:l})=>s!==a?await n(s,o,a,l):await s.copyFilePromise(o,l,i)))}copyFileSync(e,r,i=0){let n=(s,o,a,l)=>{if((i&Ah.constants.COPYFILE_FICLONE_FORCE)!=0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${o}' -> ${l}'`),{code:"EXDEV"});if(i&Ah.constants.COPYFILE_EXCL&&this.existsSync(o))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${o}' -> '${l}'`),{code:"EEXIST"});let c;try{c=s.readFileSync(o)}catch(u){throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${o}' -> '${l}'`),{code:"EINVAL"})}a.writeFileSync(l,c)};return this.makeCallSync(e,()=>this.makeCallSync(r,()=>this.baseFs.copyFileSync(e,r,i),(s,{subPath:o})=>n(this.baseFs,e,s,o)),(s,{subPath:o})=>this.makeCallSync(r,()=>n(s,o,this.baseFs,r),(a,{subPath:l})=>s!==a?n(s,o,a,l):s.copyFileSync(o,l,i)))}async appendFilePromise(e,r,i){return await this.makeCallPromise(e,async()=>await this.baseFs.appendFilePromise(e,r,i),async(n,{subPath:s})=>await n.appendFilePromise(s,r,i))}appendFileSync(e,r,i){return this.makeCallSync(e,()=>this.baseFs.appendFileSync(e,r,i),(n,{subPath:s})=>n.appendFileSync(s,r,i))}async writeFilePromise(e,r,i){return await this.makeCallPromise(e,async()=>await this.baseFs.writeFilePromise(e,r,i),async(n,{subPath:s})=>await n.writeFilePromise(s,r,i))}writeFileSync(e,r,i){return this.makeCallSync(e,()=>this.baseFs.writeFileSync(e,r,i),(n,{subPath:s})=>n.writeFileSync(s,r,i))}async unlinkPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.unlinkPromise(e),async(r,{subPath:i})=>await r.unlinkPromise(i))}unlinkSync(e){return this.makeCallSync(e,()=>this.baseFs.unlinkSync(e),(r,{subPath:i})=>r.unlinkSync(i))}async utimesPromise(e,r,i){return await this.makeCallPromise(e,async()=>await this.baseFs.utimesPromise(e,r,i),async(n,{subPath:s})=>await n.utimesPromise(s,r,i))}utimesSync(e,r,i){return this.makeCallSync(e,()=>this.baseFs.utimesSync(e,r,i),(n,{subPath:s})=>n.utimesSync(s,r,i))}async mkdirPromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.mkdirPromise(e,r),async(i,{subPath:n})=>await i.mkdirPromise(n,r))}mkdirSync(e,r){return this.makeCallSync(e,()=>this.baseFs.mkdirSync(e,r),(i,{subPath:n})=>i.mkdirSync(n,r))}async rmdirPromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.rmdirPromise(e,r),async(i,{subPath:n})=>await i.rmdirPromise(n,r))}rmdirSync(e,r){return this.makeCallSync(e,()=>this.baseFs.rmdirSync(e,r),(i,{subPath:n})=>i.rmdirSync(n,r))}async linkPromise(e,r){return await this.makeCallPromise(r,async()=>await this.baseFs.linkPromise(e,r),async(i,{subPath:n})=>await i.linkPromise(e,n))}linkSync(e,r){return this.makeCallSync(r,()=>this.baseFs.linkSync(e,r),(i,{subPath:n})=>i.linkSync(e,n))}async symlinkPromise(e,r,i){return await this.makeCallPromise(r,async()=>await this.baseFs.symlinkPromise(e,r,i),async(n,{subPath:s})=>await n.symlinkPromise(e,s))}symlinkSync(e,r,i){return this.makeCallSync(r,()=>this.baseFs.symlinkSync(e,r,i),(n,{subPath:s})=>n.symlinkSync(e,s))}async readFilePromise(e,r){return this.makeCallPromise(e,async()=>{switch(r){case"utf8":return await this.baseFs.readFilePromise(e,r);default:return await this.baseFs.readFilePromise(e,r)}},async(i,{subPath:n})=>await i.readFilePromise(n,r))}readFileSync(e,r){return this.makeCallSync(e,()=>{switch(r){case"utf8":return this.baseFs.readFileSync(e,r);default:return this.baseFs.readFileSync(e,r)}},(i,{subPath:n})=>i.readFileSync(n,r))}async readdirPromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.readdirPromise(e,r),async(i,{subPath:n})=>await i.readdirPromise(n,r),{requireSubpath:!1})}readdirSync(e,r){return this.makeCallSync(e,()=>this.baseFs.readdirSync(e,r),(i,{subPath:n})=>i.readdirSync(n,r),{requireSubpath:!1})}async readlinkPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.readlinkPromise(e),async(r,{subPath:i})=>await r.readlinkPromise(i))}readlinkSync(e){return this.makeCallSync(e,()=>this.baseFs.readlinkSync(e),(r,{subPath:i})=>r.readlinkSync(i))}async truncatePromise(e,r){return await this.makeCallPromise(e,async()=>await this.baseFs.truncatePromise(e,r),async(i,{subPath:n})=>await i.truncatePromise(n,r))}truncateSync(e,r){return this.makeCallSync(e,()=>this.baseFs.truncateSync(e,r),(i,{subPath:n})=>i.truncateSync(n,r))}watch(e,r,i){return this.makeCallSync(e,()=>this.baseFs.watch(e,r,i),(n,{subPath:s})=>n.watch(s,r,i))}watchFile(e,r,i){return this.makeCallSync(e,()=>this.baseFs.watchFile(e,r,i),()=>QE(this,e,r,i))}unwatchFile(e,r){return this.makeCallSync(e,()=>this.baseFs.unwatchFile(e,r),()=>nh(this,e,r))}async makeCallPromise(e,r,i,{requireSubpath:n=!0}={}){if(typeof e!="string")return await r();let s=this.resolve(e),o=this.findZip(s);return o?n&&o.subPath==="/"?await r():await this.getZipPromise(o.archivePath,async a=>await i(a,o)):await r()}makeCallSync(e,r,i,{requireSubpath:n=!0}={}){if(typeof e!="string")return r();let s=this.resolve(e),o=this.findZip(s);return!o||n&&o.subPath==="/"?r():this.getZipSync(o.archivePath,a=>i(a,o))}findZip(e){if(this.filter&&!this.filter.test(e))return null;let r="";for(;;){let i=e.substr(r.length),n;if(!this.fileExtensions)n=SO(i,".zip");else for(let s of this.fileExtensions)if(n=SO(i,s),n)break;if(!n)return null;if(r=this.pathUtils.join(r,n),this.isZip.has(r)===!1){if(this.notZip.has(r))continue;try{if(!this.baseFs.lstatSync(r).isFile()){this.notZip.add(r);continue}}catch{return null}this.isZip.add(r)}return{archivePath:r,subPath:this.pathUtils.join(Se.root,e.substr(r.length))}}}limitOpenFiles(e){if(this.zipInstances===null)return;let r=Date.now(),i=r+this.maxAge,n=e===null?0:this.zipInstances.size-e;for(let[s,{zipFs:o,expiresAt:a,refCount:l}]of this.zipInstances.entries())if(!(l!==0||o.hasOpenFileHandles())){if(r>=a){o.saveAndClose(),this.zipInstances.delete(s),n-=1;continue}else if(e===null||n<=0){i=a;break}o.saveAndClose(),this.zipInstances.delete(s),n-=1}this.limitOpenFilesTimeout===null&&(e===null&&this.zipInstances.size>0||e!==null)&&(this.limitOpenFilesTimeout=setTimeout(()=>{this.limitOpenFilesTimeout=null,this.limitOpenFiles(null)},i-r).unref())}async getZipPromise(e,r){let i=async()=>({baseFs:this.baseFs,libzip:this.libzip,readOnly:this.readOnlyArchives,stats:await this.baseFs.statPromise(e)});if(this.zipInstances){let n=this.zipInstances.get(e);if(!n){let s=await i();n=this.zipInstances.get(e),n||(n={zipFs:new Jr(e,s),expiresAt:0,refCount:0})}this.zipInstances.delete(e),this.limitOpenFiles(this.maxOpenFiles-1),this.zipInstances.set(e,n),n.expiresAt=Date.now()+this.maxAge,n.refCount+=1;try{return await r(n.zipFs)}finally{n.refCount-=1}}else{let n=new Jr(e,await i());try{return await r(n)}finally{n.saveAndClose()}}}getZipSync(e,r){let i=()=>({baseFs:this.baseFs,libzip:this.libzip,readOnly:this.readOnlyArchives,stats:this.baseFs.statSync(e)});if(this.zipInstances){let n=this.zipInstances.get(e);return n||(n={zipFs:new Jr(e,i()),expiresAt:0,refCount:0}),this.zipInstances.delete(e),this.limitOpenFiles(this.maxOpenFiles-1),this.zipInstances.set(e,n),n.expiresAt=Date.now()+this.maxAge,r(n.zipFs)}else{let n=new Jr(e,i());try{return r(n)}finally{n.saveAndClose()}}}};var lh=ie(require("util"));var vE=ie(require("url"));var hb=class extends fi{constructor(e){super(M);this.baseFs=e}mapFromBase(e){return e}mapToBase(e){return e instanceof vE.URL?(0,vE.fileURLToPath)(e):e}};var ohe=new Set(["accessSync","appendFileSync","createReadStream","createWriteStream","chmodSync","chownSync","closeSync","copyFileSync","linkSync","lstatSync","fstatSync","lutimesSync","mkdirSync","openSync","opendirSync","readSync","readlinkSync","readFileSync","readdirSync","readlinkSync","realpathSync","renameSync","rmdirSync","statSync","symlinkSync","truncateSync","unlinkSync","unwatchFile","utimesSync","watch","watchFile","writeFileSync","writeSync"]),xO=new Set(["accessPromise","appendFilePromise","chmodPromise","chownPromise","closePromise","copyFilePromise","linkPromise","fstatPromise","lstatPromise","lutimesPromise","mkdirPromise","openPromise","opendirPromise","readdirPromise","realpathPromise","readFilePromise","readdirPromise","readlinkPromise","renamePromise","rmdirPromise","statPromise","symlinkPromise","truncatePromise","unlinkPromise","utimesPromise","writeFilePromise","writeSync"]),ahe=new Set(["appendFilePromise","chmodPromise","chownPromise","closePromise","readPromise","readFilePromise","statPromise","truncatePromise","utimesPromise","writePromise","writeFilePromise"]);function pb(t,e){e=new hb(e);let r=(i,n,s)=>{let o=i[n];i[n]=s,typeof(o==null?void 0:o[lh.promisify.custom])!="undefined"&&(s[lh.promisify.custom]=o[lh.promisify.custom])};{r(t,"exists",(i,...n)=>{let o=typeof n[n.length-1]=="function"?n.pop():()=>{};process.nextTick(()=>{e.existsPromise(i).then(a=>{o(a)},()=>{o(!1)})})}),r(t,"read",(i,n,...s)=>{let a=typeof s[s.length-1]=="function"?s.pop():()=>{};process.nextTick(()=>{e.readPromise(i,n,...s).then(l=>{a(null,l,n)},l=>{a(l,0,n)})})});for(let i of xO){let n=i.replace(/Promise$/,"");if(typeof t[n]=="undefined")continue;let s=e[i];if(typeof s=="undefined")continue;r(t,n,(...a)=>{let c=typeof a[a.length-1]=="function"?a.pop():()=>{};process.nextTick(()=>{s.apply(e,a).then(u=>{c(null,u)},u=>{c(u)})})})}t.realpath.native=t.realpath}{r(t,"existsSync",i=>{try{return e.existsSync(i)}catch(n){return!1}});for(let i of ohe){let n=i;if(typeof t[n]=="undefined")continue;let s=e[i];typeof s!="undefined"&&r(t,n,s.bind(e))}t.realpathSync.native=t.realpathSync}{let i=process.emitWarning;process.emitWarning=()=>{};let n;try{n=t.promises}finally{process.emitWarning=i}if(typeof n!="undefined"){for(let o of xO){let a=o.replace(/Promise$/,"");if(typeof n[a]=="undefined")continue;let l=e[o];typeof l!="undefined"&&o!=="open"&&r(n,a,l.bind(e))}class s{constructor(a){this.fd=a}}for(let o of ahe){let a=o.replace(/Promise$/,""),l=e[o];typeof l!="undefined"&&r(s.prototype,a,function(...c){return l.call(e,this.fd,...c)})}r(n,"open",async(...o)=>{let a=await e.openPromise(...o);return new s(a)})}}t.read[lh.promisify.custom]=async(i,n,...s)=>({bytesRead:await e.readPromise(i,n,...s),buffer:n})}function SE(t,e){let r=Object.create(t);return pb(r,e),r}var kO=ie(require("os"));function PO(t){let e=M.toPortablePath(kO.default.tmpdir()),r=Math.ceil(Math.random()*4294967296).toString(16).padStart(8,"0");return v.join(e,`${t}${r}`)}var vs=new Set,DO=!1;function RO(){DO||(DO=!0,process.once("exit",()=>{T.rmtempSync()}))}var T=Object.assign(new Wt,{detachTemp(t){vs.delete(t)},mktempSync(t){for(RO();;){let e=PO("xfs-");try{this.mkdirSync(e)}catch(i){if(i.code==="EEXIST")continue;throw i}let r=this.realpathSync(e);if(vs.add(r),typeof t!="undefined")try{return t(r)}finally{if(vs.has(r)){vs.delete(r);try{this.removeSync(r)}catch{}}}else return r}},async mktempPromise(t){for(RO();;){let e=PO("xfs-");try{await this.mkdirPromise(e)}catch(i){if(i.code==="EEXIST")continue;throw i}let r=await this.realpathPromise(e);if(vs.add(r),typeof t!="undefined")try{return await t(r)}finally{if(vs.has(r)){vs.delete(r);try{await this.removePromise(r)}catch{}}}else return r}},async rmtempPromise(){await Promise.all(Array.from(vs.values()).map(async t=>{try{await T.removePromise(t,{maxRetries:0}),vs.delete(t)}catch{}}))},rmtempSync(){for(let t of vs)try{T.removeSync(t),vs.delete(t)}catch{}}});var vb=ie(bb()),Pn;(function(i){i[i.Never=0]="Never",i[i.ErrorCode=1]="ErrorCode",i[i.Always=2]="Always"})(Pn||(Pn={}));function dl(t){return t!==null&&typeof t.fd=="number"}var Cl=new Set;function Sb(){}function xb(){for(let t of Cl)t.kill()}async function to(t,e,{cwd:r,env:i=process.env,strict:n=!1,stdin:s=null,stdout:o,stderr:a,end:l=2}){let c=["pipe","pipe","pipe"];s===null?c[0]="ignore":dl(s)&&(c[0]=s),dl(o)&&(c[1]=o),dl(a)&&(c[2]=a);let u=(0,vb.default)(t,e,{cwd:M.fromPortablePath(r),env:_(P({},i),{PWD:M.fromPortablePath(r)}),stdio:c});Cl.add(u),Cl.size===1&&(process.on("SIGINT",Sb),process.on("SIGTERM",xb)),!dl(s)&&s!==null&&s.pipe(u.stdin),dl(o)||u.stdout.pipe(o,{end:!1}),dl(a)||u.stderr.pipe(a,{end:!1});let g=()=>{for(let f of new Set([o,a]))dl(f)||f.end()};return new Promise((f,h)=>{u.on("error",p=>{Cl.delete(u),Cl.size===0&&(process.off("SIGINT",Sb),process.off("SIGTERM",xb)),(l===2||l===1)&&g(),h(p)}),u.on("close",(p,d)=>{Cl.delete(u),Cl.size===0&&(process.off("SIGINT",Sb),process.off("SIGTERM",xb)),(l===2||l===1&&p>0)&&g(),p===0||!n?f({code:kb(p,d)}):h(p!==null?new Error(`Child "${t}" exited with exit code ${p}`):new Error(`Child "${t}" exited with signal ${d}`))})})}async function Nhe(t,e,{cwd:r,env:i=process.env,encoding:n="utf8",strict:s=!1}){let o=["ignore","pipe","pipe"],a=[],l=[],c=M.fromPortablePath(r);typeof i.PWD!="undefined"&&(i=_(P({},i),{PWD:c}));let u=(0,vb.default)(t,e,{cwd:c,env:i,stdio:o});return u.stdout.on("data",g=>{a.push(g)}),u.stderr.on("data",g=>{l.push(g)}),await new Promise((g,f)=>{u.on("error",()=>{f()}),u.on("close",(h,p)=>{let d=n==="buffer"?Buffer.concat(a):Buffer.concat(a).toString(n),m=n==="buffer"?Buffer.concat(l):Buffer.concat(l).toString(n);h===0||!s?g({code:kb(h,p),stdout:d,stderr:m}):f(Object.assign(new Error(`Child "${t}" exited with exit code ${h} + +${m}`),{code:kb(h,p),stdout:d,stderr:m}))})})}var Lhe=new Map([["SIGINT",2],["SIGQUIT",3],["SIGKILL",9],["SIGTERM",15]]);function kb(t,e){let r=Lhe.get(e);return typeof r!="undefined"?128+r:t!=null?t:1}var Pb={};it(Pb,{getDefaultGlobalFolder:()=>Rb,getHomeFolder:()=>uh,isFolderInside:()=>Fb});var Db=ie(require("os"));function Rb(){if(process.platform==="win32"){let t=M.toPortablePath(process.env.LOCALAPPDATA||M.join((0,Db.homedir)(),"AppData","Local"));return v.resolve(t,"Yarn/Berry")}if(process.env.XDG_DATA_HOME){let t=M.toPortablePath(process.env.XDG_DATA_HOME);return v.resolve(t,"yarn/berry")}return v.resolve(uh(),".yarn/berry")}function uh(){return M.toPortablePath((0,Db.homedir)()||"/usr/local/share")}function Fb(t,e){let r=v.relative(e,t);return r&&!r.startsWith("..")&&!v.isAbsolute(r)}var ue={};it(ue,{LogLevel:()=>Ts,Style:()=>Gl,Type:()=>Le,addLogFilterSupport:()=>Cp,applyColor:()=>On,applyHyperlink:()=>Ku,applyStyle:()=>Py,json:()=>Uu,mark:()=>xx,pretty:()=>Ve,prettyField:()=>Yl,prettyList:()=>Kx,supportsColor:()=>xy,supportsHyperlinks:()=>Mx,tuple:()=>jl});var pp=ie(jb()),dp=ie(ml()),o3=ie(Nn()),a3=ie(gU());var z;(function(te){te[te.UNNAMED=0]="UNNAMED",te[te.EXCEPTION=1]="EXCEPTION",te[te.MISSING_PEER_DEPENDENCY=2]="MISSING_PEER_DEPENDENCY",te[te.CYCLIC_DEPENDENCIES=3]="CYCLIC_DEPENDENCIES",te[te.DISABLED_BUILD_SCRIPTS=4]="DISABLED_BUILD_SCRIPTS",te[te.BUILD_DISABLED=5]="BUILD_DISABLED",te[te.SOFT_LINK_BUILD=6]="SOFT_LINK_BUILD",te[te.MUST_BUILD=7]="MUST_BUILD",te[te.MUST_REBUILD=8]="MUST_REBUILD",te[te.BUILD_FAILED=9]="BUILD_FAILED",te[te.RESOLVER_NOT_FOUND=10]="RESOLVER_NOT_FOUND",te[te.FETCHER_NOT_FOUND=11]="FETCHER_NOT_FOUND",te[te.LINKER_NOT_FOUND=12]="LINKER_NOT_FOUND",te[te.FETCH_NOT_CACHED=13]="FETCH_NOT_CACHED",te[te.YARN_IMPORT_FAILED=14]="YARN_IMPORT_FAILED",te[te.REMOTE_INVALID=15]="REMOTE_INVALID",te[te.REMOTE_NOT_FOUND=16]="REMOTE_NOT_FOUND",te[te.RESOLUTION_PACK=17]="RESOLUTION_PACK",te[te.CACHE_CHECKSUM_MISMATCH=18]="CACHE_CHECKSUM_MISMATCH",te[te.UNUSED_CACHE_ENTRY=19]="UNUSED_CACHE_ENTRY",te[te.MISSING_LOCKFILE_ENTRY=20]="MISSING_LOCKFILE_ENTRY",te[te.WORKSPACE_NOT_FOUND=21]="WORKSPACE_NOT_FOUND",te[te.TOO_MANY_MATCHING_WORKSPACES=22]="TOO_MANY_MATCHING_WORKSPACES",te[te.CONSTRAINTS_MISSING_DEPENDENCY=23]="CONSTRAINTS_MISSING_DEPENDENCY",te[te.CONSTRAINTS_INCOMPATIBLE_DEPENDENCY=24]="CONSTRAINTS_INCOMPATIBLE_DEPENDENCY",te[te.CONSTRAINTS_EXTRANEOUS_DEPENDENCY=25]="CONSTRAINTS_EXTRANEOUS_DEPENDENCY",te[te.CONSTRAINTS_INVALID_DEPENDENCY=26]="CONSTRAINTS_INVALID_DEPENDENCY",te[te.CANT_SUGGEST_RESOLUTIONS=27]="CANT_SUGGEST_RESOLUTIONS",te[te.FROZEN_LOCKFILE_EXCEPTION=28]="FROZEN_LOCKFILE_EXCEPTION",te[te.CROSS_DRIVE_VIRTUAL_LOCAL=29]="CROSS_DRIVE_VIRTUAL_LOCAL",te[te.FETCH_FAILED=30]="FETCH_FAILED",te[te.DANGEROUS_NODE_MODULES=31]="DANGEROUS_NODE_MODULES",te[te.NODE_GYP_INJECTED=32]="NODE_GYP_INJECTED",te[te.AUTHENTICATION_NOT_FOUND=33]="AUTHENTICATION_NOT_FOUND",te[te.INVALID_CONFIGURATION_KEY=34]="INVALID_CONFIGURATION_KEY",te[te.NETWORK_ERROR=35]="NETWORK_ERROR",te[te.LIFECYCLE_SCRIPT=36]="LIFECYCLE_SCRIPT",te[te.CONSTRAINTS_MISSING_FIELD=37]="CONSTRAINTS_MISSING_FIELD",te[te.CONSTRAINTS_INCOMPATIBLE_FIELD=38]="CONSTRAINTS_INCOMPATIBLE_FIELD",te[te.CONSTRAINTS_EXTRANEOUS_FIELD=39]="CONSTRAINTS_EXTRANEOUS_FIELD",te[te.CONSTRAINTS_INVALID_FIELD=40]="CONSTRAINTS_INVALID_FIELD",te[te.AUTHENTICATION_INVALID=41]="AUTHENTICATION_INVALID",te[te.PROLOG_UNKNOWN_ERROR=42]="PROLOG_UNKNOWN_ERROR",te[te.PROLOG_SYNTAX_ERROR=43]="PROLOG_SYNTAX_ERROR",te[te.PROLOG_EXISTENCE_ERROR=44]="PROLOG_EXISTENCE_ERROR",te[te.STACK_OVERFLOW_RESOLUTION=45]="STACK_OVERFLOW_RESOLUTION",te[te.AUTOMERGE_FAILED_TO_PARSE=46]="AUTOMERGE_FAILED_TO_PARSE",te[te.AUTOMERGE_IMMUTABLE=47]="AUTOMERGE_IMMUTABLE",te[te.AUTOMERGE_SUCCESS=48]="AUTOMERGE_SUCCESS",te[te.AUTOMERGE_REQUIRED=49]="AUTOMERGE_REQUIRED",te[te.DEPRECATED_CLI_SETTINGS=50]="DEPRECATED_CLI_SETTINGS",te[te.PLUGIN_NAME_NOT_FOUND=51]="PLUGIN_NAME_NOT_FOUND",te[te.INVALID_PLUGIN_REFERENCE=52]="INVALID_PLUGIN_REFERENCE",te[te.CONSTRAINTS_AMBIGUITY=53]="CONSTRAINTS_AMBIGUITY",te[te.CACHE_OUTSIDE_PROJECT=54]="CACHE_OUTSIDE_PROJECT",te[te.IMMUTABLE_INSTALL=55]="IMMUTABLE_INSTALL",te[te.IMMUTABLE_CACHE=56]="IMMUTABLE_CACHE",te[te.INVALID_MANIFEST=57]="INVALID_MANIFEST",te[te.PACKAGE_PREPARATION_FAILED=58]="PACKAGE_PREPARATION_FAILED",te[te.INVALID_RANGE_PEER_DEPENDENCY=59]="INVALID_RANGE_PEER_DEPENDENCY",te[te.INCOMPATIBLE_PEER_DEPENDENCY=60]="INCOMPATIBLE_PEER_DEPENDENCY",te[te.DEPRECATED_PACKAGE=61]="DEPRECATED_PACKAGE",te[te.INCOMPATIBLE_OS=62]="INCOMPATIBLE_OS",te[te.INCOMPATIBLE_CPU=63]="INCOMPATIBLE_CPU",te[te.FROZEN_ARTIFACT_EXCEPTION=64]="FROZEN_ARTIFACT_EXCEPTION",te[te.TELEMETRY_NOTICE=65]="TELEMETRY_NOTICE",te[te.PATCH_HUNK_FAILED=66]="PATCH_HUNK_FAILED",te[te.INVALID_CONFIGURATION_VALUE=67]="INVALID_CONFIGURATION_VALUE",te[te.UNUSED_PACKAGE_EXTENSION=68]="UNUSED_PACKAGE_EXTENSION",te[te.REDUNDANT_PACKAGE_EXTENSION=69]="REDUNDANT_PACKAGE_EXTENSION",te[te.AUTO_NM_SUCCESS=70]="AUTO_NM_SUCCESS",te[te.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK=71]="NM_CANT_INSTALL_EXTERNAL_SOFT_LINK",te[te.NM_PRESERVE_SYMLINKS_REQUIRED=72]="NM_PRESERVE_SYMLINKS_REQUIRED",te[te.UPDATE_LOCKFILE_ONLY_SKIP_LINK=73]="UPDATE_LOCKFILE_ONLY_SKIP_LINK",te[te.NM_HARDLINKS_MODE_DOWNGRADED=74]="NM_HARDLINKS_MODE_DOWNGRADED",te[te.PROLOG_INSTANTIATION_ERROR=75]="PROLOG_INSTANTIATION_ERROR",te[te.INCOMPATIBLE_ARCHITECTURE=76]="INCOMPATIBLE_ARCHITECTURE",te[te.GHOST_ARCHITECTURE=77]="GHOST_ARCHITECTURE"})(z||(z={}));function KE(t){return`YN${t.toString(10).padStart(4,"0")}`}var de={};it(de,{BufferStream:()=>OH,CachingStrategy:()=>Dl,DefaultStream:()=>KH,assertNever:()=>Lv,bufferStream:()=>Cu,buildIgnorePattern:()=>DEe,convertMapsToIndexableObjects:()=>aI,dynamicRequire:()=>mu,escapeRegExp:()=>SEe,getArrayWithDefault:()=>hu,getFactoryWithDefault:()=>na,getMapWithDefault:()=>pu,getSetWithDefault:()=>Pl,isIndexableObject:()=>Tv,isPathLike:()=>REe,isTaggedYarnVersion:()=>vEe,mapAndFilter:()=>kl,mapAndFind:()=>MH,overrideType:()=>Nv,parseBoolean:()=>Hh,parseOptionalBoolean:()=>jH,prettifyAsyncErrors:()=>du,prettifySyncErrors:()=>Mv,releaseAfterUseAsync:()=>kEe,replaceEnvVariables:()=>Ov,sortMap:()=>gn,tryParseOptionalBoolean:()=>Kv,validateEnum:()=>xEe});var vh={};it(vh,{Builtins:()=>Iv,Cli:()=>oo,Command:()=>ye,Option:()=>Y,UsageError:()=>me});var yl=0,Eh=1,Gi=2,sv="",hi="\0",Au=-1,ov=/^(-h|--help)(?:=([0-9]+))?$/,UE=/^(--[a-z]+(?:-[a-z]+)*|-[a-zA-Z]+)$/,fU=/^-[a-zA-Z]{2,}$/,av=/^([^=]+)=([\s\S]*)$/,Av=process.env.DEBUG_CLI==="1";var me=class extends Error{constructor(e){super(e);this.clipanion={type:"usage"},this.name="UsageError"}},Ih=class extends Error{constructor(e,r){super();if(this.input=e,this.candidates=r,this.clipanion={type:"none"},this.name="UnknownSyntaxError",this.candidates.length===0)this.message="Command not found, but we're not sure what's the alternative.";else if(this.candidates.every(i=>i.reason!==null&&i.reason===r[0].reason)){let[{reason:i}]=this.candidates;this.message=`${i} + +${this.candidates.map(({usage:n})=>`$ ${n}`).join(` +`)}`}else if(this.candidates.length===1){let[{usage:i}]=this.candidates;this.message=`Command not found; did you mean: + +$ ${i} +${lv(e)}`}else this.message=`Command not found; did you mean one of: + +${this.candidates.map(({usage:i},n)=>`${`${n}.`.padStart(4)} ${i}`).join(` +`)} + +${lv(e)}`}},cv=class extends Error{constructor(e,r){super();this.input=e,this.usages=r,this.clipanion={type:"none"},this.name="AmbiguousSyntaxError",this.message=`Cannot find which to pick amongst the following alternatives: + +${this.usages.map((i,n)=>`${`${n}.`.padStart(4)} ${i}`).join(` +`)} + +${lv(e)}`}},lv=t=>`While running ${t.filter(e=>e!==hi).map(e=>{let r=JSON.stringify(e);return e.match(/\s/)||e.length===0||r!==`"${e}"`?r:e}).join(" ")}`;var yh=Symbol("clipanion/isOption");function ji(t){return _(P({},t),{[yh]:!0})}function so(t,e){return typeof t=="undefined"?[t,e]:typeof t=="object"&&t!==null&&!Array.isArray(t)?[void 0,t]:[t,e]}function HE(t,e=!1){let r=t.replace(/^\.: /,"");return e&&(r=r[0].toLowerCase()+r.slice(1)),r}function wh(t,e){return e.length===1?new me(`${t}: ${HE(e[0],!0)}`):new me(`${t}: +${e.map(r=>` +- ${HE(r)}`).join("")}`)}function Bh(t,e,r){if(typeof r=="undefined")return e;let i=[],n=[],s=a=>{let l=e;return e=a,s.bind(null,l)};if(!r(e,{errors:i,coercions:n,coercion:s}))throw wh(`Invalid value for ${t}`,i);for(let[,a]of n)a();return e}var ye=class{constructor(){this.help=!1}static Usage(e){return e}async catch(e){throw e}async validateAndExecute(){let r=this.constructor.schema;if(typeof r!="undefined"){let{isDict:n,isUnknown:s,applyCascade:o}=await Promise.resolve().then(()=>(Ss(),lu)),a=o(n(s()),r),l=[],c=[];if(!a(this,{errors:l,coercions:c}))throw wh("Invalid option schema",l);for(let[,g]of c)g()}let i=await this.execute();return typeof i!="undefined"?i:0}};ye.isOption=yh;ye.Default=[];function un(t){Av&&console.log(t)}var BU={candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,path:[],positionals:[],options:[],remainder:null,selectedIndex:Au};function QU(){return{nodes:[qi(),qi(),qi()]}}function nCe(t){let e=QU(),r=[],i=e.nodes.length;for(let n of t){r.push(i);for(let s=0;s{if(e.has(i))return;e.add(i);let n=t.nodes[i];for(let o of Object.values(n.statics))for(let{to:a}of o)r(a);for(let[,{to:o}]of n.dynamics)r(o);for(let{to:o}of n.shortcuts)r(o);let s=new Set(n.shortcuts.map(({to:o})=>o));for(;n.shortcuts.length>0;){let{to:o}=n.shortcuts.shift(),a=t.nodes[o];for(let[l,c]of Object.entries(a.statics)){let u=Object.prototype.hasOwnProperty.call(n.statics,l)?n.statics[l]:n.statics[l]=[];for(let g of c)u.some(({to:f})=>g.to===f)||u.push(g)}for(let[l,c]of a.dynamics)n.dynamics.some(([u,{to:g}])=>l===u&&c.to===g)||n.dynamics.push([l,c]);for(let l of a.shortcuts)s.has(l.to)||(n.shortcuts.push(l),s.add(l.to))}};r(yl)}function oCe(t,{prefix:e=""}={}){if(Av){un(`${e}Nodes are:`);for(let r=0;rl!==Gi).map(({state:l})=>({usage:l.candidateUsage,reason:null})));if(a.every(({node:l})=>l===Gi))throw new Ih(e,a.map(({state:l})=>({usage:l.candidateUsage,reason:l.errorMessage})));i=aCe(a)}if(i.length>0){un(" Results:");for(let s of i)un(` - ${s.node} -> ${JSON.stringify(s.state)}`)}else un(" No results");return i}function ACe(t,e){if(e.selectedIndex!==null)return!0;if(Object.prototype.hasOwnProperty.call(t.statics,hi)){for(let{to:r}of t.statics[hi])if(r===Eh)return!0}return!1}function cCe(t,e,r){let i=r&&e.length>0?[""]:[],n=vU(t,e,r),s=[],o=new Set,a=(l,c,u=!0)=>{let g=[c];for(;g.length>0;){let h=g;g=[];for(let p of h){let d=t.nodes[p],m=Object.keys(d.statics);for(let I of Object.keys(d.statics)){let B=m[0];for(let{to:b,reducer:R}of d.statics[B])R==="pushPath"&&(u||l.push(B),g.push(b))}}u=!1}let f=JSON.stringify(l);o.has(f)||(s.push(l),o.add(f))};for(let{node:l,state:c}of n){if(c.remainder!==null){a([c.remainder],l);continue}let u=t.nodes[l],g=ACe(u,c);for(let[f,h]of Object.entries(u.statics))(g&&f!==hi||!f.startsWith("-")&&h.some(({reducer:p})=>p==="pushPath"))&&a([...i,f],l);if(!!g)for(let[f,{to:h}]of u.dynamics){if(h===Gi)continue;let p=lCe(f,c);if(p!==null)for(let d of p)a([...i,d],l)}}return[...s].sort()}function gCe(t,e){let r=vU(t,[...e,hi]);return uCe(e,r.map(({state:i})=>i))}function aCe(t){let e=0;for(let{state:r}of t)r.path.length>e&&(e=r.path.length);return t.filter(({state:r})=>r.path.length===e)}function uCe(t,e){let r=e.filter(g=>g.selectedIndex!==null);if(r.length===0)throw new Error;let i=r.filter(g=>g.requiredOptions.every(f=>f.some(h=>g.options.find(p=>p.name===h))));if(i.length===0)throw new Ih(t,r.map(g=>({usage:g.candidateUsage,reason:null})));let n=0;for(let g of i)g.path.length>n&&(n=g.path.length);let s=i.filter(g=>g.path.length===n),o=g=>g.positionals.filter(({extra:f})=>!f).length+g.options.length,a=s.map(g=>({state:g,positionalCount:o(g)})),l=0;for(let{positionalCount:g}of a)g>l&&(l=g);let c=a.filter(({positionalCount:g})=>g===l).map(({state:g})=>g),u=fCe(c);if(u.length>1)throw new cv(t,u.map(g=>g.candidateUsage));return u[0]}function fCe(t){let e=[],r=[];for(let i of t)i.selectedIndex===Au?r.push(i):e.push(i);return r.length>0&&e.push(_(P({},BU),{path:SU(...r.map(i=>i.path)),options:r.reduce((i,n)=>i.concat(n.options),[])})),e}function SU(t,e,...r){return e===void 0?Array.from(t):SU(t.filter((i,n)=>i===e[n]),...r)}function qi(){return{dynamics:[],shortcuts:[],statics:{}}}function bU(t){return t===Eh||t===Gi}function Cv(t,e=0){return{to:bU(t.to)?t.to:t.to>2?t.to+e-2:t.to+e,reducer:t.reducer}}function iCe(t,e=0){let r=qi();for(let[i,n]of t.dynamics)r.dynamics.push([i,Cv(n,e)]);for(let i of t.shortcuts)r.shortcuts.push(Cv(i,e));for(let[i,n]of Object.entries(t.statics))r.statics[i]=n.map(s=>Cv(s,e));return r}function pi(t,e,r,i,n){t.nodes[e].dynamics.push([r,{to:i,reducer:n}])}function cu(t,e,r,i){t.nodes[e].shortcuts.push({to:r,reducer:i})}function ta(t,e,r,i,n){(Object.prototype.hasOwnProperty.call(t.nodes[e].statics,r)?t.nodes[e].statics[r]:t.nodes[e].statics[r]=[]).push({to:i,reducer:n})}function jE(t,e,r,i){if(Array.isArray(e)){let[n,...s]=e;return t[n](r,i,...s)}else return t[e](r,i)}function lCe(t,e){let r=Array.isArray(t)?YE[t[0]]:YE[t];if(typeof r.suggest=="undefined")return null;let i=Array.isArray(t)?t.slice(1):[];return r.suggest(e,...i)}var YE={always:()=>!0,isOptionLike:(t,e)=>!t.ignoreOptions&&e!=="-"&&e.startsWith("-"),isNotOptionLike:(t,e)=>t.ignoreOptions||e==="-"||!e.startsWith("-"),isOption:(t,e,r,i)=>!t.ignoreOptions&&e===r,isBatchOption:(t,e,r)=>!t.ignoreOptions&&fU.test(e)&&[...e.slice(1)].every(i=>r.includes(`-${i}`)),isBoundOption:(t,e,r,i)=>{let n=e.match(av);return!t.ignoreOptions&&!!n&&UE.test(n[1])&&r.includes(n[1])&&i.filter(s=>s.names.includes(n[1])).every(s=>s.allowBinding)},isNegatedOption:(t,e,r)=>!t.ignoreOptions&&e===`--no-${r.slice(2)}`,isHelp:(t,e)=>!t.ignoreOptions&&ov.test(e),isUnsupportedOption:(t,e,r)=>!t.ignoreOptions&&e.startsWith("-")&&UE.test(e)&&!r.includes(e),isInvalidOption:(t,e)=>!t.ignoreOptions&&e.startsWith("-")&&!UE.test(e)};YE.isOption.suggest=(t,e,r=!0)=>r?null:[e];var dv={setCandidateState:(t,e,r)=>P(P({},t),r),setSelectedIndex:(t,e,r)=>_(P({},t),{selectedIndex:r}),pushBatch:(t,e)=>_(P({},t),{options:t.options.concat([...e.slice(1)].map(r=>({name:`-${r}`,value:!0})))}),pushBound:(t,e)=>{let[,r,i]=e.match(av);return _(P({},t),{options:t.options.concat({name:r,value:i})})},pushPath:(t,e)=>_(P({},t),{path:t.path.concat(e)}),pushPositional:(t,e)=>_(P({},t),{positionals:t.positionals.concat({value:e,extra:!1})}),pushExtra:(t,e)=>_(P({},t),{positionals:t.positionals.concat({value:e,extra:!0})}),pushExtraNoLimits:(t,e)=>_(P({},t),{positionals:t.positionals.concat({value:e,extra:Ln})}),pushTrue:(t,e,r=e)=>_(P({},t),{options:t.options.concat({name:e,value:!0})}),pushFalse:(t,e,r=e)=>_(P({},t),{options:t.options.concat({name:r,value:!1})}),pushUndefined:(t,e)=>_(P({},t),{options:t.options.concat({name:e,value:void 0})}),pushStringValue:(t,e)=>{var r;let i=_(P({},t),{options:[...t.options]}),n=t.options[t.options.length-1];return n.value=((r=n.value)!==null&&r!==void 0?r:[]).concat([e]),i},setStringValue:(t,e)=>{let r=_(P({},t),{options:[...t.options]}),i=t.options[t.options.length-1];return i.value=e,r},inhibateOptions:t=>_(P({},t),{ignoreOptions:!0}),useHelp:(t,e,r)=>{let[,,i]=e.match(ov);return typeof i!="undefined"?_(P({},t),{options:[{name:"-c",value:String(r)},{name:"-i",value:i}]}):_(P({},t),{options:[{name:"-c",value:String(r)}]})},setError:(t,e,r)=>e===hi?_(P({},t),{errorMessage:`${r}.`}):_(P({},t),{errorMessage:`${r} ("${e}").`}),setOptionArityError:(t,e)=>{let r=t.options[t.options.length-1];return _(P({},t),{errorMessage:`Not enough arguments to option ${r.name}.`})}},Ln=Symbol(),xU=class{constructor(e,r){this.allOptionNames=[],this.arity={leading:[],trailing:[],extra:[],proxy:!1},this.options=[],this.paths=[],this.cliIndex=e,this.cliOpts=r}addPath(e){this.paths.push(e)}setArity({leading:e=this.arity.leading,trailing:r=this.arity.trailing,extra:i=this.arity.extra,proxy:n=this.arity.proxy}){Object.assign(this.arity,{leading:e,trailing:r,extra:i,proxy:n})}addPositional({name:e="arg",required:r=!0}={}){if(!r&&this.arity.extra===Ln)throw new Error("Optional parameters cannot be declared when using .rest() or .proxy()");if(!r&&this.arity.trailing.length>0)throw new Error("Optional parameters cannot be declared after the required trailing positional arguments");!r&&this.arity.extra!==Ln?this.arity.extra.push(e):this.arity.extra!==Ln&&this.arity.extra.length===0?this.arity.leading.push(e):this.arity.trailing.push(e)}addRest({name:e="arg",required:r=0}={}){if(this.arity.extra===Ln)throw new Error("Infinite lists cannot be declared multiple times in the same command");if(this.arity.trailing.length>0)throw new Error("Infinite lists cannot be declared after the required trailing positional arguments");for(let i=0;i1)throw new Error("The arity cannot be higher than 1 when the option only supports the --arg=value syntax");if(!Number.isInteger(i))throw new Error(`The arity must be an integer, got ${i}`);if(i<0)throw new Error(`The arity must be positive, got ${i}`);this.allOptionNames.push(...e),this.options.push({names:e,description:r,arity:i,hidden:n,required:s,allowBinding:o})}setContext(e){this.context=e}usage({detailed:e=!0,inlineOptions:r=!0}={}){let i=[this.cliOpts.binaryName],n=[];if(this.paths.length>0&&i.push(...this.paths[0]),e){for(let{names:o,arity:a,hidden:l,description:c,required:u}of this.options){if(l)continue;let g=[];for(let h=0;h`:`[${f}]`)}i.push(...this.arity.leading.map(o=>`<${o}>`)),this.arity.extra===Ln?i.push("..."):i.push(...this.arity.extra.map(o=>`[${o}]`)),i.push(...this.arity.trailing.map(o=>`<${o}>`))}return{usage:i.join(" "),options:n}}compile(){if(typeof this.context=="undefined")throw new Error("Assertion failed: No context attached");let e=QU(),r=yl,i=this.usage().usage,n=this.options.filter(a=>a.required).map(a=>a.names);r=xs(e,qi()),ta(e,yl,sv,r,["setCandidateState",{candidateUsage:i,requiredOptions:n}]);let s=this.arity.proxy?"always":"isNotOptionLike",o=this.paths.length>0?this.paths:[[]];for(let a of o){let l=r;if(a.length>0){let f=xs(e,qi());cu(e,l,f),this.registerOptions(e,f),l=f}for(let f=0;f0||!this.arity.proxy){let f=xs(e,qi());pi(e,l,"isHelp",f,["useHelp",this.cliIndex]),ta(e,f,hi,Eh,["setSelectedIndex",Au]),this.registerOptions(e,l)}this.arity.leading.length>0&&ta(e,l,hi,Gi,["setError","Not enough positional arguments"]);let c=l;for(let f=0;f0||f+1!==this.arity.leading.length)&&ta(e,h,hi,Gi,["setError","Not enough positional arguments"]),pi(e,c,"isNotOptionLike",h,"pushPositional"),c=h}let u=c;if(this.arity.extra===Ln||this.arity.extra.length>0){let f=xs(e,qi());if(cu(e,c,f),this.arity.extra===Ln){let h=xs(e,qi());this.arity.proxy||this.registerOptions(e,h),pi(e,c,s,h,"pushExtraNoLimits"),pi(e,h,s,h,"pushExtraNoLimits"),cu(e,h,f)}else for(let h=0;h0&&ta(e,u,hi,Gi,["setError","Not enough positional arguments"]);let g=u;for(let f=0;fo.length>s.length?o:s,"");if(i.arity===0)for(let s of i.names)pi(e,r,["isOption",s,i.hidden||s!==n],r,"pushTrue"),s.startsWith("--")&&!s.startsWith("--no-")&&pi(e,r,["isNegatedOption",s],r,["pushFalse",s]);else{let s=xs(e,qi());for(let o of i.names)pi(e,r,["isOption",o,i.hidden||o!==n],s,"pushUndefined");for(let o=0;o=0&&egCe(i,n),suggest:(n,s)=>cCe(i,n,s)}}};var kU=80,mv=Array(kU).fill("\u2501");for(let t=0;t<=24;++t)mv[mv.length-t]=`[38;5;${232+t}m\u2501`;var Ev={header:t=>`\u2501\u2501\u2501 ${t}${t.length`${t}`,error:t=>`${t}`,code:t=>`${t}`},PU={header:t=>t,bold:t=>t,error:t=>t,code:t=>t};function hCe(t){let e=t.split(` +`),r=e.filter(n=>n.match(/\S/)),i=r.length>0?r.reduce((n,s)=>Math.min(n,s.length-s.trimStart().length),Number.MAX_VALUE):0;return e.map(n=>n.slice(i).trimRight()).join(` +`)}function Vn(t,{format:e,paragraphs:r}){return t=t.replace(/\r\n?/g,` +`),t=hCe(t),t=t.replace(/^\n+|\n+$/g,""),t=t.replace(/^(\s*)-([^\n]*?)\n+/gm,`$1-$2 + +`),t=t.replace(/\n(\n)?\n*/g,"$1"),r&&(t=t.split(/\n/).map(i=>{let n=i.match(/^\s*[*-][\t ]+(.*)/);if(!n)return i.match(/(.{1,80})(?: |$)/g).join(` +`);let s=i.length-i.trimStart().length;return n[1].match(new RegExp(`(.{1,${78-s}})(?: |$)`,"g")).map((o,a)=>" ".repeat(s)+(a===0?"- ":" ")+o).join(` +`)}).join(` + +`)),t=t.replace(/(`+)((?:.|[\n])*?)\1/g,(i,n,s)=>e.code(n+s+n)),t=t.replace(/(\*\*)((?:.|[\n])*?)\1/g,(i,n,s)=>e.bold(n+s+n)),t?`${t} +`:""}var bh=class extends ye{constructor(e){super();this.contexts=e,this.commands=[]}static from(e,r){let i=new bh(r);i.path=e.path;for(let n of e.options)switch(n.name){case"-c":i.commands.push(Number(n.value));break;case"-i":i.index=Number(n.value);break}return i}async execute(){let e=this.commands;if(typeof this.index!="undefined"&&this.index>=0&&this.index1){this.context.stdout.write(`Multiple commands match your selection: +`),this.context.stdout.write(` +`);let r=0;for(let i of this.commands)this.context.stdout.write(this.cli.usage(this.contexts[i].commandClass,{prefix:`${r++}. `.padStart(5)}));this.context.stdout.write(` +`),this.context.stdout.write(`Run again with -h= to see the longer details of any of those commands. +`)}}};var DU=Symbol("clipanion/errorCommand");function pCe(){return process.env.FORCE_COLOR==="0"?!1:!!(process.env.FORCE_COLOR==="1"||typeof process.stdout!="undefined"&&process.stdout.isTTY)}var oo=class{constructor({binaryLabel:e,binaryName:r="...",binaryVersion:i,enableColors:n=pCe()}={}){this.registrations=new Map,this.builder=new Qh({binaryName:r}),this.binaryLabel=e,this.binaryName=r,this.binaryVersion=i,this.enableColors=n}static from(e,r={}){let i=new oo(r);for(let n of e)i.register(n);return i}register(e){var r;let i=new Map,n=new e;for(let l in n){let c=n[l];typeof c=="object"&&c!==null&&c[ye.isOption]&&i.set(l,c)}let s=this.builder.command(),o=s.cliIndex,a=(r=e.paths)!==null&&r!==void 0?r:n.paths;if(typeof a!="undefined")for(let l of a)s.addPath(l);this.registrations.set(e,{specs:i,builder:s,index:o});for(let[l,{definition:c}]of i.entries())c(s,l);s.setContext({commandClass:e})}process(e){let{contexts:r,process:i}=this.builder.compile(),n=i(e);switch(n.selectedIndex){case Au:return bh.from(n,r);default:{let{commandClass:s}=r[n.selectedIndex],o=this.registrations.get(s);if(typeof o=="undefined")throw new Error("Assertion failed: Expected the command class to have been registered.");let a=new s;a.path=n.path;try{for(let[l,{transformer:c}]of o.specs.entries())a[l]=c(o.builder,l,n);return a}catch(l){throw l[DU]=a,l}}break}}async run(e,r){let i;if(!Array.isArray(e))i=e;else try{i=this.process(e)}catch(s){return r.stdout.write(this.error(s)),1}if(i.help)return r.stdout.write(this.usage(i,{detailed:!0})),0;i.context=r,i.cli={binaryLabel:this.binaryLabel,binaryName:this.binaryName,binaryVersion:this.binaryVersion,enableColors:this.enableColors,definitions:()=>this.definitions(),error:(s,o)=>this.error(s,o),process:s=>this.process(s),run:(s,o)=>this.run(s,P(P({},r),o)),usage:(s,o)=>this.usage(s,o)};let n;try{n=await i.validateAndExecute().catch(s=>i.catch(s).then(()=>0))}catch(s){return r.stdout.write(this.error(s,{command:i})),1}return n}async runExit(e,r){process.exitCode=await this.run(e,r)}suggest(e,r){let{suggest:i}=this.builder.compile();return i(e,r)}definitions({colored:e=!1}={}){let r=[];for(let[i,{index:n}]of this.registrations){if(typeof i.usage=="undefined")continue;let{usage:s}=this.getUsageByIndex(n,{detailed:!1}),{usage:o,options:a}=this.getUsageByIndex(n,{detailed:!0,inlineOptions:!1}),l=typeof i.usage.category!="undefined"?Vn(i.usage.category,{format:this.format(e),paragraphs:!1}):void 0,c=typeof i.usage.description!="undefined"?Vn(i.usage.description,{format:this.format(e),paragraphs:!1}):void 0,u=typeof i.usage.details!="undefined"?Vn(i.usage.details,{format:this.format(e),paragraphs:!0}):void 0,g=typeof i.usage.examples!="undefined"?i.usage.examples.map(([f,h])=>[Vn(f,{format:this.format(e),paragraphs:!1}),h.replace(/\$0/g,this.binaryName)]):void 0;r.push({path:s,usage:o,category:l,description:c,details:u,examples:g,options:a})}return r}usage(e=null,{colored:r,detailed:i=!1,prefix:n="$ "}={}){var s;if(e===null){for(let l of this.registrations.keys()){let c=l.paths,u=typeof l.usage!="undefined";if(!c||c.length===0||c.length===1&&c[0].length===0||((s=c==null?void 0:c.some(h=>h.length===0))!==null&&s!==void 0?s:!1))if(e){e=null;break}else e=l;else if(u){e=null;continue}}e&&(i=!0)}let o=e!==null&&e instanceof ye?e.constructor:e,a="";if(o)if(i){let{description:l="",details:c="",examples:u=[]}=o.usage||{};l!==""&&(a+=Vn(l,{format:this.format(r),paragraphs:!1}).replace(/^./,h=>h.toUpperCase()),a+=` +`),(c!==""||u.length>0)&&(a+=`${this.format(r).header("Usage")} +`,a+=` +`);let{usage:g,options:f}=this.getUsageByRegistration(o,{inlineOptions:!1});if(a+=`${this.format(r).bold(n)}${g} +`,f.length>0){a+=` +`,a+=`${Ev.header("Options")} +`;let h=f.reduce((p,d)=>Math.max(p,d.definition.length),0);a+=` +`;for(let{definition:p,description:d}of f)a+=` ${this.format(r).bold(p.padEnd(h))} ${Vn(d,{format:this.format(r),paragraphs:!1})}`}if(c!==""&&(a+=` +`,a+=`${this.format(r).header("Details")} +`,a+=` +`,a+=Vn(c,{format:this.format(r),paragraphs:!0})),u.length>0){a+=` +`,a+=`${this.format(r).header("Examples")} +`;for(let[h,p]of u)a+=` +`,a+=Vn(h,{format:this.format(r),paragraphs:!1}),a+=`${p.replace(/^/m,` ${this.format(r).bold(n)}`).replace(/\$0/g,this.binaryName)} +`}}else{let{usage:l}=this.getUsageByRegistration(o);a+=`${this.format(r).bold(n)}${l} +`}else{let l=new Map;for(let[f,{index:h}]of this.registrations.entries()){if(typeof f.usage=="undefined")continue;let p=typeof f.usage.category!="undefined"?Vn(f.usage.category,{format:this.format(r),paragraphs:!1}):null,d=l.get(p);typeof d=="undefined"&&l.set(p,d=[]);let{usage:m}=this.getUsageByIndex(h);d.push({commandClass:f,usage:m})}let c=Array.from(l.keys()).sort((f,h)=>f===null?-1:h===null?1:f.localeCompare(h,"en",{usage:"sort",caseFirst:"upper"})),u=typeof this.binaryLabel!="undefined",g=typeof this.binaryVersion!="undefined";u||g?(u&&g?a+=`${this.format(r).header(`${this.binaryLabel} - ${this.binaryVersion}`)} + +`:u?a+=`${this.format(r).header(`${this.binaryLabel}`)} +`:a+=`${this.format(r).header(`${this.binaryVersion}`)} +`,a+=` ${this.format(r).bold(n)}${this.binaryName} +`):a+=`${this.format(r).bold(n)}${this.binaryName} +`;for(let f of c){let h=l.get(f).slice().sort((d,m)=>d.usage.localeCompare(m.usage,"en",{usage:"sort",caseFirst:"upper"})),p=f!==null?f.trim():"General commands";a+=` +`,a+=`${this.format(r).header(`${p}`)} +`;for(let{commandClass:d,usage:m}of h){let I=d.usage.description||"undocumented";a+=` +`,a+=` ${this.format(r).bold(m)} +`,a+=` ${Vn(I,{format:this.format(r),paragraphs:!1})}`}}a+=` +`,a+=Vn("You can also print more details about any of these commands by calling them with the `-h,--help` flag right after the command name.",{format:this.format(r),paragraphs:!0})}return a}error(e,r){var i,{colored:n,command:s=(i=e[DU])!==null&&i!==void 0?i:null}=r===void 0?{}:r;e instanceof Error||(e=new Error(`Execution failed with a non-error rejection (rejected value: ${JSON.stringify(e)})`));let o="",a=e.name.replace(/([a-z])([A-Z])/g,"$1 $2");a==="Error"&&(a="Internal Error"),o+=`${this.format(n).error(a)}: ${e.message} +`;let l=e.clipanion;return typeof l!="undefined"?l.type==="usage"&&(o+=` +`,o+=this.usage(s)):e.stack&&(o+=`${e.stack.replace(/^.*\n/,"")} +`),o}getUsageByRegistration(e,r){let i=this.registrations.get(e);if(typeof i=="undefined")throw new Error("Assertion failed: Unregistered command");return this.getUsageByIndex(i.index,r)}getUsageByIndex(e,r){return this.builder.getBuilderByIndex(e).usage(r)}format(e=this.enableColors){return e?Ev:PU}};oo.defaultContext={stdin:process.stdin,stdout:process.stdout,stderr:process.stderr};var Iv={};it(Iv,{DefinitionsCommand:()=>qE,HelpCommand:()=>JE,VersionCommand:()=>WE});var qE=class extends ye{async execute(){this.context.stdout.write(`${JSON.stringify(this.cli.definitions(),null,2)} +`)}};qE.paths=[["--clipanion=definitions"]];var JE=class extends ye{async execute(){this.context.stdout.write(this.cli.usage())}};JE.paths=[["-h"],["--help"]];var WE=class extends ye{async execute(){var e;this.context.stdout.write(`${(e=this.cli.binaryVersion)!==null&&e!==void 0?e:""} +`)}};WE.paths=[["-v"],["--version"]];var Y={};it(Y,{Array:()=>RU,Boolean:()=>FU,Counter:()=>NU,Proxy:()=>LU,Rest:()=>TU,String:()=>MU,applyValidator:()=>Bh,cleanValidationError:()=>HE,formatError:()=>wh,isOptionSymbol:()=>yh,makeCommandOption:()=>ji,rerouteArguments:()=>so});function RU(t,e,r){let[i,n]=so(e,r!=null?r:{}),{arity:s=1}=n,o=t.split(","),a=new Set(o);return ji({definition(l){l.addOption({names:o,arity:s,hidden:n==null?void 0:n.hidden,description:n==null?void 0:n.description,required:n.required})},transformer(l,c,u){let g=typeof i!="undefined"?[...i]:void 0;for(let{name:f,value:h}of u.options)!a.has(f)||(g=g!=null?g:[],g.push(h));return g}})}function FU(t,e,r){let[i,n]=so(e,r!=null?r:{}),s=t.split(","),o=new Set(s);return ji({definition(a){a.addOption({names:s,allowBinding:!1,arity:0,hidden:n.hidden,description:n.description,required:n.required})},transformer(a,l,c){let u=i;for(let{name:g,value:f}of c.options)!o.has(g)||(u=f);return u}})}function NU(t,e,r){let[i,n]=so(e,r!=null?r:{}),s=t.split(","),o=new Set(s);return ji({definition(a){a.addOption({names:s,allowBinding:!1,arity:0,hidden:n.hidden,description:n.description,required:n.required})},transformer(a,l,c){let u=i;for(let{name:g,value:f}of c.options)!o.has(g)||(u!=null||(u=0),f?u+=1:u=0);return u}})}function LU(t={}){return ji({definition(e,r){var i;e.addProxy({name:(i=t.name)!==null&&i!==void 0?i:r,required:t.required})},transformer(e,r,i){return i.positionals.map(({value:n})=>n)}})}function TU(t={}){return ji({definition(e,r){var i;e.addRest({name:(i=t.name)!==null&&i!==void 0?i:r,required:t.required})},transformer(e,r,i){let n=o=>{let a=i.positionals[o];return a.extra===Ln||a.extra===!1&&oo)}})}function dCe(t,e,r){let[i,n]=so(e,r!=null?r:{}),{arity:s=1}=n,o=t.split(","),a=new Set(o);return ji({definition(l){l.addOption({names:o,arity:n.tolerateBoolean?0:s,hidden:n.hidden,description:n.description,required:n.required})},transformer(l,c,u){let g,f=i;for(let{name:h,value:p}of u.options)!a.has(h)||(g=h,f=p);return typeof f=="string"?Bh(g!=null?g:c,f,n.validator):f}})}function CCe(t={}){let{required:e=!0}=t;return ji({definition(r,i){var n;r.addPositional({name:(n=t.name)!==null&&n!==void 0?n:i,required:t.required})},transformer(r,i,n){var s;for(let o=0;oJSON.stringify(i)).join(", ")})`);return e}function kl(t,e){let r=[];for(let i of t){let n=e(i);n!==LH&&r.push(n)}return r}var LH=Symbol();kl.skip=LH;function MH(t,e){for(let r of t){let i=e(r);if(i!==TH)return i}}var TH=Symbol();MH.skip=TH;function Tv(t){return typeof t=="object"&&t!==null}function aI(t){if(t instanceof Map&&(t=Object.fromEntries(t)),Tv(t))for(let e of Object.keys(t)){let r=t[e];Tv(r)&&(t[e]=aI(r))}return t}function na(t,e,r){let i=t.get(e);return typeof i=="undefined"&&t.set(e,i=r()),i}function hu(t,e){let r=t.get(e);return typeof r=="undefined"&&t.set(e,r=[]),r}function Pl(t,e){let r=t.get(e);return typeof r=="undefined"&&t.set(e,r=new Set),r}function pu(t,e){let r=t.get(e);return typeof r=="undefined"&&t.set(e,r=new Map),r}async function kEe(t,e){if(e==null)return await t();try{return await t()}finally{await e()}}async function du(t,e){try{return await t()}catch(r){throw r.message=e(r.message),r}}function Mv(t,e){try{return t()}catch(r){throw r.message=e(r.message),r}}async function Cu(t){return await new Promise((e,r)=>{let i=[];t.on("error",n=>{r(n)}),t.on("data",n=>{i.push(n)}),t.on("end",()=>{e(Buffer.concat(i))})})}var OH=class extends Fv.Transform{constructor(){super(...arguments);this.chunks=[]}_transform(e,r,i){if(r!=="buffer"||!Buffer.isBuffer(e))throw new Error("Assertion failed: BufferStream only accept buffers");this.chunks.push(e),i(null,null)}_flush(e){e(null,Buffer.concat(this.chunks))}},KH=class extends Fv.Transform{constructor(e=Buffer.alloc(0)){super();this.active=!0;this.ifEmpty=e}_transform(e,r,i){if(r!=="buffer"||!Buffer.isBuffer(e))throw new Error("Assertion failed: DefaultStream only accept buffers");this.active=!1,i(null,e)}_flush(e){this.active&&this.ifEmpty.length>0?e(null,this.ifEmpty):e(null)}},Uh=eval("require");function UH(t){return Uh(M.fromPortablePath(t))}function HH(path){let physicalPath=M.fromPortablePath(path),currentCacheEntry=Uh.cache[physicalPath];delete Uh.cache[physicalPath];let result;try{result=UH(physicalPath);let freshCacheEntry=Uh.cache[physicalPath],dynamicModule=eval("module"),freshCacheIndex=dynamicModule.children.indexOf(freshCacheEntry);freshCacheIndex!==-1&&dynamicModule.children.splice(freshCacheIndex,1)}finally{Uh.cache[physicalPath]=currentCacheEntry}return result}var GH=new Map;function PEe(t){let e=GH.get(t),r=T.statSync(t);if((e==null?void 0:e.mtime)===r.mtimeMs)return e.instance;let i=HH(t);return GH.set(t,{mtime:r.mtimeMs,instance:i}),i}var Dl;(function(i){i[i.NoCache=0]="NoCache",i[i.FsTime=1]="FsTime",i[i.Node=2]="Node"})(Dl||(Dl={}));function mu(t,{cachingStrategy:e=2}={}){switch(e){case 0:return HH(t);case 1:return PEe(t);case 2:return UH(t);default:throw new Error("Unsupported caching strategy")}}function gn(t,e){let r=Array.from(t);Array.isArray(e)||(e=[e]);let i=[];for(let s of e)i.push(r.map(o=>s(o)));let n=r.map((s,o)=>o);return n.sort((s,o)=>{for(let a of i){let l=a[s]a[o]?1:0;if(l!==0)return l}return 0}),n.map(s=>r[s])}function DEe(t){return t.length===0?null:t.map(e=>`(${FH.default.makeRe(e,{windows:!1,dot:!0}).source})`).join("|")}function Ov(t,{env:e}){let r=/\${(?[\d\w_]+)(?:)?(?:-(?[^}]*))?}/g;return t.replace(r,(...i)=>{let{variableName:n,colon:s,fallback:o}=i[i.length-1],a=Object.prototype.hasOwnProperty.call(e,n),l=e[n];if(l||a&&!s)return l;if(o!=null)return o;throw new me(`Environment variable not found (${n})`)})}function Hh(t){switch(t){case"true":case"1":case 1:case!0:return!0;case"false":case"0":case 0:case!1:return!1;default:throw new Error(`Couldn't parse "${t}" as a boolean`)}}function jH(t){return typeof t=="undefined"?t:Hh(t)}function Kv(t){try{return jH(t)}catch{return null}}function REe(t){return!!(M.isAbsolute(t)||t.match(/^(\.{1,2}|~)\//))}var S={};it(S,{areDescriptorsEqual:()=>i3,areIdentsEqual:()=>cp,areLocatorsEqual:()=>up,areVirtualPackagesEquivalent:()=>XQe,bindDescriptor:()=>VQe,bindLocator:()=>_Qe,convertDescriptorToLocator:()=>By,convertLocatorToDescriptor:()=>WQe,convertPackageToLocator:()=>zQe,convertToIdent:()=>JQe,convertToManifestRange:()=>ebe,copyPackage:()=>ap,devirtualizeDescriptor:()=>Ap,devirtualizeLocator:()=>lp,getIdentVendorPath:()=>Lx,isPackageCompatible:()=>Sy,isVirtualDescriptor:()=>hA,isVirtualLocator:()=>Io,makeDescriptor:()=>Yt,makeIdent:()=>Eo,makeLocator:()=>Vi,makeRange:()=>by,parseDescriptor:()=>pA,parseFileStyleRange:()=>ZQe,parseIdent:()=>En,parseLocator:()=>Hl,parseRange:()=>Tu,prettyDependent:()=>Nx,prettyDescriptor:()=>Xt,prettyIdent:()=>Vr,prettyLocator:()=>lt,prettyLocatorNoColors:()=>Rx,prettyRange:()=>yy,prettyReference:()=>fp,prettyResolution:()=>Fx,prettyWorkspace:()=>hp,renamePackage:()=>op,slugifyIdent:()=>Dx,slugifyLocator:()=>Mu,sortDescriptors:()=>Ou,stringifyDescriptor:()=>In,stringifyIdent:()=>St,stringifyLocator:()=>is,tryParseDescriptor:()=>gp,tryParseIdent:()=>n3,tryParseLocator:()=>Qy,virtualizeDescriptor:()=>kx,virtualizePackage:()=>Px});var Lu=ie(require("querystring")),e3=ie(Or()),t3=ie(wY());var mn={};it(mn,{checksumFile:()=>Ey,checksumPattern:()=>Iy,makeHash:()=>zi});var my=ie(require("crypto")),Sx=ie(vx());function zi(...t){let e=(0,my.createHash)("sha512"),r="";for(let i of t)typeof i=="string"?r+=i:i&&(r&&(e.update(r),r=""),e.update(i));return r&&e.update(r),e.digest("hex")}async function Ey(t,{baseFs:e,algorithm:r}={baseFs:T,algorithm:"sha512"}){let i=await e.openPromise(t,"r");try{let n=65536,s=Buffer.allocUnsafeSlow(n),o=(0,my.createHash)(r),a=0;for(;(a=await e.readPromise(i,s,0,n))!==0;)o.update(a===n?s:s.slice(0,a));return o.digest("hex")}finally{await e.closePromise(i)}}async function Iy(t,{cwd:e}){let i=(await(0,Sx.default)(t,{cwd:M.fromPortablePath(e),expandDirectories:!1,onlyDirectories:!0,unique:!0})).map(a=>`${a}/**/*`),n=await(0,Sx.default)([t,...i],{cwd:M.fromPortablePath(e),expandDirectories:!1,onlyFiles:!1,unique:!0});n.sort();let s=await Promise.all(n.map(async a=>{let l=[Buffer.from(a)],c=M.toPortablePath(a),u=await T.lstatPromise(c);return u.isSymbolicLink()?l.push(Buffer.from(await T.readlinkPromise(c))):u.isFile()&&l.push(await T.readFilePromise(c)),l.join("\0")})),o=(0,my.createHash)("sha512");for(let a of s)o.update(a);return o.digest("hex")}var wy="virtual:",YQe=5,r3=/(os|cpu)=([a-z0-9_-]+)/,qQe=(0,t3.makeParser)(r3);function Eo(t,e){if(t==null?void 0:t.startsWith("@"))throw new Error("Invalid scope: don't prefix it with '@'");return{identHash:zi(t,e),scope:t,name:e}}function Yt(t,e){return{identHash:t.identHash,scope:t.scope,name:t.name,descriptorHash:zi(t.identHash,e),range:e}}function Vi(t,e){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:zi(t.identHash,e),reference:e}}function JQe(t){return{identHash:t.identHash,scope:t.scope,name:t.name}}function By(t){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:t.descriptorHash,reference:t.range}}function WQe(t){return{identHash:t.identHash,scope:t.scope,name:t.name,descriptorHash:t.locatorHash,range:t.reference}}function zQe(t){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:t.locatorHash,reference:t.reference}}function op(t,e){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:e.locatorHash,reference:e.reference,version:t.version,languageName:t.languageName,linkType:t.linkType,conditions:t.conditions,dependencies:new Map(t.dependencies),peerDependencies:new Map(t.peerDependencies),dependenciesMeta:new Map(t.dependenciesMeta),peerDependenciesMeta:new Map(t.peerDependenciesMeta),bin:new Map(t.bin)}}function ap(t){return op(t,t)}function kx(t,e){if(e.includes("#"))throw new Error("Invalid entropy");return Yt(t,`virtual:${e}#${t.range}`)}function Px(t,e){if(e.includes("#"))throw new Error("Invalid entropy");return op(t,Vi(t,`virtual:${e}#${t.reference}`))}function hA(t){return t.range.startsWith(wy)}function Io(t){return t.reference.startsWith(wy)}function Ap(t){if(!hA(t))throw new Error("Not a virtual descriptor");return Yt(t,t.range.replace(/^[^#]*#/,""))}function lp(t){if(!Io(t))throw new Error("Not a virtual descriptor");return Vi(t,t.reference.replace(/^[^#]*#/,""))}function VQe(t,e){return t.range.includes("::")?t:Yt(t,`${t.range}::${Lu.default.stringify(e)}`)}function _Qe(t,e){return t.reference.includes("::")?t:Vi(t,`${t.reference}::${Lu.default.stringify(e)}`)}function cp(t,e){return t.identHash===e.identHash}function i3(t,e){return t.descriptorHash===e.descriptorHash}function up(t,e){return t.locatorHash===e.locatorHash}function XQe(t,e){if(!Io(t))throw new Error("Invalid package type");if(!Io(e))throw new Error("Invalid package type");if(!cp(t,e)||t.dependencies.size!==e.dependencies.size)return!1;for(let r of t.dependencies.values()){let i=e.dependencies.get(r.identHash);if(!i||!i3(r,i))return!1}return!0}function En(t){let e=n3(t);if(!e)throw new Error(`Invalid ident (${t})`);return e}function n3(t){let e=t.match(/^(?:@([^/]+?)\/)?([^/]+)$/);if(!e)return null;let[,r,i]=e,n=typeof r!="undefined"?r:null;return Eo(n,i)}function pA(t,e=!1){let r=gp(t,e);if(!r)throw new Error(`Invalid descriptor (${t})`);return r}function gp(t,e=!1){let r=e?t.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):t.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!r)return null;let[,i,n,s]=r;if(s==="unknown")throw new Error(`Invalid range (${t})`);let o=typeof i!="undefined"?i:null,a=typeof s!="undefined"?s:"unknown";return Yt(Eo(o,n),a)}function Hl(t,e=!1){let r=Qy(t,e);if(!r)throw new Error(`Invalid locator (${t})`);return r}function Qy(t,e=!1){let r=e?t.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):t.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!r)return null;let[,i,n,s]=r;if(s==="unknown")throw new Error(`Invalid reference (${t})`);let o=typeof i!="undefined"?i:null,a=typeof s!="undefined"?s:"unknown";return Vi(Eo(o,n),a)}function Tu(t,e){let r=t.match(/^([^#:]*:)?((?:(?!::)[^#])*)(?:#((?:(?!::).)*))?(?:::(.*))?$/);if(r===null)throw new Error(`Invalid range (${t})`);let i=typeof r[1]!="undefined"?r[1]:null;if(typeof(e==null?void 0:e.requireProtocol)=="string"&&i!==e.requireProtocol)throw new Error(`Invalid protocol (${i})`);if((e==null?void 0:e.requireProtocol)&&i===null)throw new Error(`Missing protocol (${i})`);let n=typeof r[3]!="undefined"?decodeURIComponent(r[2]):null;if((e==null?void 0:e.requireSource)&&n===null)throw new Error(`Missing source (${t})`);let s=typeof r[3]!="undefined"?decodeURIComponent(r[3]):decodeURIComponent(r[2]),o=(e==null?void 0:e.parseSelector)?Lu.default.parse(s):s,a=typeof r[4]!="undefined"?Lu.default.parse(r[4]):null;return{protocol:i,source:n,selector:o,params:a}}function ZQe(t,{protocol:e}){let{selector:r,params:i}=Tu(t,{requireProtocol:e,requireBindings:!0});if(typeof i.locator!="string")throw new Error(`Assertion failed: Invalid bindings for ${t}`);return{parentLocator:Hl(i.locator,!0),path:r}}function s3(t){return t=t.replace(/%/g,"%25"),t=t.replace(/:/g,"%3A"),t=t.replace(/#/g,"%23"),t}function $Qe(t){return t===null?!1:Object.entries(t).length>0}function by({protocol:t,source:e,selector:r,params:i}){let n="";return t!==null&&(n+=`${t}`),e!==null&&(n+=`${s3(e)}#`),n+=s3(r),$Qe(i)&&(n+=`::${Lu.default.stringify(i)}`),n}function ebe(t){let{params:e,protocol:r,source:i,selector:n}=Tu(t);for(let s in e)s.startsWith("__")&&delete e[s];return by({protocol:r,source:i,params:e,selector:n})}function St(t){return t.scope?`@${t.scope}/${t.name}`:`${t.name}`}function In(t){return t.scope?`@${t.scope}/${t.name}@${t.range}`:`${t.name}@${t.range}`}function is(t){return t.scope?`@${t.scope}/${t.name}@${t.reference}`:`${t.name}@${t.reference}`}function Dx(t){return t.scope!==null?`@${t.scope}-${t.name}`:t.name}function Mu(t){let{protocol:e,selector:r}=Tu(t.reference),i=e!==null?e.replace(/:$/,""):"exotic",n=e3.default.valid(r),s=n!==null?`${i}-${n}`:`${i}`,o=10,a=t.scope?`${Dx(t)}-${s}-${t.locatorHash.slice(0,o)}`:`${Dx(t)}-${s}-${t.locatorHash.slice(0,o)}`;return kr(a)}function Vr(t,e){return e.scope?`${Ve(t,`@${e.scope}/`,Le.SCOPE)}${Ve(t,e.name,Le.NAME)}`:`${Ve(t,e.name,Le.NAME)}`}function vy(t){if(t.startsWith(wy)){let e=vy(t.substr(t.indexOf("#")+1)),r=t.substr(wy.length,YQe);return`${e} [${r}]`}else return t.replace(/\?.*/,"?[...]")}function yy(t,e){return`${Ve(t,vy(e),Le.RANGE)}`}function Xt(t,e){return`${Vr(t,e)}${Ve(t,"@",Le.RANGE)}${yy(t,e.range)}`}function fp(t,e){return`${Ve(t,vy(e),Le.REFERENCE)}`}function lt(t,e){return`${Vr(t,e)}${Ve(t,"@",Le.REFERENCE)}${fp(t,e.reference)}`}function Rx(t){return`${St(t)}@${vy(t.reference)}`}function Ou(t){return gn(t,[e=>St(e),e=>e.range])}function hp(t,e){return Vr(t,e.locator)}function Fx(t,e,r){let i=hA(e)?Ap(e):e;return r===null?`${Xt(t,i)} \u2192 ${xx(t).Cross}`:i.identHash===r.identHash?`${Xt(t,i)} \u2192 ${fp(t,r.reference)}`:`${Xt(t,i)} \u2192 ${lt(t,r)}`}function Nx(t,e,r){return r===null?`${lt(t,e)}`:`${lt(t,e)} (via ${yy(t,r.range)})`}function Lx(t){return`node_modules/${St(t)}`}function Sy(t,e){return t.conditions?qQe(t.conditions,r=>{let[,i,n]=r.match(r3),s=e[i];return s?s.includes(n):!0}):!0}var gt;(function(r){r.HARD="HARD",r.SOFT="SOFT"})(gt||(gt={}));var oi;(function(i){i.Dependency="Dependency",i.PeerDependency="PeerDependency",i.PeerDependencyMeta="PeerDependencyMeta"})(oi||(oi={}));var ki;(function(i){i.Inactive="inactive",i.Redundant="redundant",i.Active="active"})(ki||(ki={}));var Le={NO_HINT:"NO_HINT",NULL:"NULL",SCOPE:"SCOPE",NAME:"NAME",RANGE:"RANGE",REFERENCE:"REFERENCE",NUMBER:"NUMBER",PATH:"PATH",URL:"URL",ADDED:"ADDED",REMOVED:"REMOVED",CODE:"CODE",DURATION:"DURATION",SIZE:"SIZE",IDENT:"IDENT",DESCRIPTOR:"DESCRIPTOR",LOCATOR:"LOCATOR",RESOLUTION:"RESOLUTION",DEPENDENT:"DEPENDENT",PACKAGE_EXTENSION:"PACKAGE_EXTENSION",SETTING:"SETTING"},Gl;(function(e){e[e.BOLD=2]="BOLD"})(Gl||(Gl={}));var Tx=dp.default.GITHUB_ACTIONS?{level:2}:pp.default.supportsColor?{level:pp.default.supportsColor.level}:{level:0},xy=Tx.level!==0,Mx=xy&&!dp.default.GITHUB_ACTIONS&&!dp.default.CIRCLE&&!dp.default.GITLAB,Ox=new pp.default.Instance(Tx),tbe=new Map([[Le.NO_HINT,null],[Le.NULL,["#a853b5",129]],[Le.SCOPE,["#d75f00",166]],[Le.NAME,["#d7875f",173]],[Le.RANGE,["#00afaf",37]],[Le.REFERENCE,["#87afff",111]],[Le.NUMBER,["#ffd700",220]],[Le.PATH,["#d75fd7",170]],[Le.URL,["#d75fd7",170]],[Le.ADDED,["#5faf00",70]],[Le.REMOVED,["#d70000",160]],[Le.CODE,["#87afff",111]],[Le.SIZE,["#ffd700",220]]]),Ls=t=>t,ky={[Le.NUMBER]:Ls({pretty:(t,e)=>`${e}`,json:t=>t}),[Le.IDENT]:Ls({pretty:(t,e)=>Vr(t,e),json:t=>St(t)}),[Le.LOCATOR]:Ls({pretty:(t,e)=>lt(t,e),json:t=>is(t)}),[Le.DESCRIPTOR]:Ls({pretty:(t,e)=>Xt(t,e),json:t=>In(t)}),[Le.RESOLUTION]:Ls({pretty:(t,{descriptor:e,locator:r})=>Fx(t,e,r),json:({descriptor:t,locator:e})=>({descriptor:In(t),locator:e!==null?is(e):null})}),[Le.DEPENDENT]:Ls({pretty:(t,{locator:e,descriptor:r})=>Nx(t,e,r),json:({locator:t,descriptor:e})=>({locator:is(t),descriptor:In(e)})}),[Le.PACKAGE_EXTENSION]:Ls({pretty:(t,e)=>{switch(e.type){case oi.Dependency:return`${Vr(t,e.parentDescriptor)} \u27A4 ${On(t,"dependencies",Le.CODE)} \u27A4 ${Vr(t,e.descriptor)}`;case oi.PeerDependency:return`${Vr(t,e.parentDescriptor)} \u27A4 ${On(t,"peerDependencies",Le.CODE)} \u27A4 ${Vr(t,e.descriptor)}`;case oi.PeerDependencyMeta:return`${Vr(t,e.parentDescriptor)} \u27A4 ${On(t,"peerDependenciesMeta",Le.CODE)} \u27A4 ${Vr(t,En(e.selector))} \u27A4 ${On(t,e.key,Le.CODE)}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${e.type}`)}},json:t=>{switch(t.type){case oi.Dependency:return`${St(t.parentDescriptor)} > ${St(t.descriptor)}`;case oi.PeerDependency:return`${St(t.parentDescriptor)} >> ${St(t.descriptor)}`;case oi.PeerDependencyMeta:return`${St(t.parentDescriptor)} >> ${t.selector} / ${t.key}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${t.type}`)}}}),[Le.SETTING]:Ls({pretty:(t,e)=>(t.get(e),Ku(t,On(t,e,Le.CODE),`https://yarnpkg.com/configuration/yarnrc#${e}`)),json:t=>t}),[Le.DURATION]:Ls({pretty:(t,e)=>{if(e>1e3*60){let r=Math.floor(e/1e3/60),i=Math.ceil((e-r*60*1e3)/1e3);return i===0?`${r}m`:`${r}m ${i}s`}else{let r=Math.floor(e/1e3),i=e-r*1e3;return i===0?`${r}s`:`${r}s ${i}ms`}},json:t=>t}),[Le.SIZE]:Ls({pretty:(t,e)=>{let r=["KB","MB","GB","TB"],i=r.length;for(;i>1&&e<1024**i;)i-=1;let n=1024**i,s=Math.floor(e*100/n)/100;return On(t,`${s} ${r[i-1]}`,Le.NUMBER)},json:t=>t}),[Le.PATH]:Ls({pretty:(t,e)=>On(t,M.fromPortablePath(e),Le.PATH),json:t=>M.fromPortablePath(t)})};function jl(t,e){return[e,t]}function Py(t,e,r){return t.get("enableColors")&&r&2&&(e=pp.default.bold(e)),e}function On(t,e,r){if(!t.get("enableColors"))return e;let i=tbe.get(r);if(i===null)return e;let n=typeof i=="undefined"?r:Tx.level>=3?i[0]:i[1],s=typeof n=="number"?Ox.ansi256(n):n.startsWith("#")?Ox.hex(n):Ox[n];if(typeof s!="function")throw new Error(`Invalid format type ${n}`);return s(e)}var rbe=!!process.env.KONSOLE_VERSION;function Ku(t,e,r){return t.get("enableHyperlinks")?rbe?`]8;;${r}\\${e}]8;;\\`:`]8;;${r}\x07${e}]8;;\x07`:e}function Ve(t,e,r){if(e===null)return On(t,"null",Le.NULL);if(Object.prototype.hasOwnProperty.call(ky,r))return ky[r].pretty(t,e);if(typeof e!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof e}`);return On(t,e,r)}function Kx(t,e,r,{separator:i=", "}={}){return[...e].map(n=>Ve(t,n,r)).join(i)}function Uu(t,e){if(t===null)return null;if(Object.prototype.hasOwnProperty.call(ky,e))return Nv(e),ky[e].json(t);if(typeof t!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof t}`);return t}function xx(t){return{Check:On(t,"\u2713","green"),Cross:On(t,"\u2718","red"),Question:On(t,"?","cyan")}}function Yl(t,{label:e,value:[r,i]}){return`${Ve(t,e,Le.CODE)}: ${Ve(t,r,i)}`}var Ts;(function(n){n.Error="error",n.Warning="warning",n.Info="info",n.Discard="discard"})(Ts||(Ts={}));function Cp(t,{configuration:e}){let r=e.get("logFilters"),i=new Map,n=new Map,s=[];for(let g of r){let f=g.get("level");if(typeof f=="undefined")continue;let h=g.get("code");typeof h!="undefined"&&i.set(h,f);let p=g.get("text");typeof p!="undefined"&&n.set(p,f);let d=g.get("pattern");typeof d!="undefined"&&s.push([o3.default.matcher(d,{contains:!0}),f])}s.reverse();let o=(g,f,h)=>{if(g===null||g===z.UNNAMED)return h;let p=n.size>0||s.length>0?(0,a3.default)(f):f;if(n.size>0){let d=n.get(p);if(typeof d!="undefined")return d!=null?d:h}if(s.length>0){for(let[d,m]of s)if(d(p))return m!=null?m:h}if(i.size>0){let d=i.get(KE(g));if(typeof d!="undefined")return d!=null?d:h}return h},a=t.reportInfo,l=t.reportWarning,c=t.reportError,u=function(g,f,h,p){switch(o(f,h,p)){case Ts.Info:a.call(g,f,h);break;case Ts.Warning:l.call(g,f!=null?f:z.UNNAMED,h);break;case Ts.Error:c.call(g,f!=null?f:z.UNNAMED,h);break}};t.reportInfo=function(...g){return u(this,...g,Ts.Info)},t.reportWarning=function(...g){return u(this,...g,Ts.Warning)},t.reportError=function(...g){return u(this,...g,Ts.Error)}}var Zt={};it(Zt,{Method:()=>Jl,RequestError:()=>z8.RequestError,del:()=>pxe,get:()=>fxe,getNetworkSettings:()=>Z8,post:()=>iP,put:()=>hxe,request:()=>xp});var q8=ie(zy()),J8=ie(require("https")),W8=ie(require("http")),tP=ie(Nn()),rP=ie(G8()),Vy=ie(require("url"));var j8=ie(require("stream")),Y8=ie(require("string_decoder"));var nt=class extends Error{constructor(e,r,i){super(r);this.reportExtra=i;this.reportCode=e}};function Axe(t){return typeof t.reportCode!="undefined"}var Xi=class{constructor(){this.reportedInfos=new Set;this.reportedWarnings=new Set;this.reportedErrors=new Set}static progressViaCounter(e){let r=0,i,n=new Promise(l=>{i=l}),s=l=>{let c=i;n=new Promise(u=>{i=u}),r=l,c()},o=(l=0)=>{s(r+1)},a=async function*(){for(;r{let o=i.write(s),a;do if(a=o.indexOf(` +`),a!==-1){let l=n+o.substr(0,a);o=o.substr(a+1),n="",e!==null?this.reportInfo(null,`${e} ${l}`):this.reportInfo(null,l)}while(a!==-1);n+=o}),r.on("end",()=>{let s=i.end();s!==""&&(e!==null?this.reportInfo(null,`${e} ${s}`):this.reportInfo(null,s))}),r}};var z8=ie(zy()),V8=new Map,_8=new Map,lxe=new W8.Agent({keepAlive:!0}),cxe=new J8.Agent({keepAlive:!0});function X8(t){let e=new Vy.URL(t),r={host:e.hostname,headers:{}};return e.port&&(r.port=Number(e.port)),{proxy:r}}async function uxe(t){return na(_8,t,()=>T.readFilePromise(t).then(e=>(_8.set(t,e),e)))}function gxe({statusCode:t,statusMessage:e},r){let i=Ve(r,t,Le.NUMBER),n=`https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/${t}`;return Ku(r,`${i}${e?` (${e})`:""}`,n)}async function _y(t,{configuration:e,customErrorMessage:r}){var i,n;try{return await t}catch(s){if(s.name!=="HTTPError")throw s;let o=(n=r==null?void 0:r(s))!=null?n:(i=s.response.body)==null?void 0:i.error;o==null&&(s.message.startsWith("Response code")?o="The remote server failed to provide the requested resource":o=s.message),s instanceof q8.TimeoutError&&s.event==="socket"&&(o+=`(can be increased via ${Ve(e,"httpTimeout",Le.SETTING)})`);let a=new nt(z.NETWORK_ERROR,o,l=>{s.response&&l.reportError(z.NETWORK_ERROR,` ${Yl(e,{label:"Response Code",value:jl(Le.NO_HINT,gxe(s.response,e))})}`),s.request&&(l.reportError(z.NETWORK_ERROR,` ${Yl(e,{label:"Request Method",value:jl(Le.NO_HINT,s.request.options.method)})}`),l.reportError(z.NETWORK_ERROR,` ${Yl(e,{label:"Request URL",value:jl(Le.URL,s.request.requestUrl)})}`)),s.request.redirects.length>0&&l.reportError(z.NETWORK_ERROR,` ${Yl(e,{label:"Request Redirects",value:jl(Le.NO_HINT,Kx(e,s.request.redirects,Le.URL))})}`),s.request.retryCount===s.request.options.retry.limit&&l.reportError(z.NETWORK_ERROR,` ${Yl(e,{label:"Request Retry Count",value:jl(Le.NO_HINT,`${Ve(e,s.request.retryCount,Le.NUMBER)} (can be increased via ${Ve(e,"httpRetry",Le.SETTING)})`)})}`)});throw a.originalError=s,a}}function Z8(t,e){let r=[...e.configuration.get("networkSettings")].sort(([o],[a])=>a.length-o.length),i={enableNetwork:void 0,caFilePath:void 0,httpProxy:void 0,httpsProxy:void 0},n=Object.keys(i),s=typeof t=="string"?new Vy.URL(t):t;for(let[o,a]of r)if(tP.default.isMatch(s.hostname,o))for(let l of n){let c=a.get(l);c!==null&&typeof i[l]=="undefined"&&(i[l]=c)}for(let o of n)typeof i[o]=="undefined"&&(i[o]=e.configuration.get(o));return i}var Jl;(function(n){n.GET="GET",n.PUT="PUT",n.POST="POST",n.DELETE="DELETE"})(Jl||(Jl={}));async function xp(t,e,{configuration:r,headers:i,jsonRequest:n,jsonResponse:s,method:o=Jl.GET}){let a=typeof t=="string"?new Vy.URL(t):t,l=Z8(a,{configuration:r});if(l.enableNetwork===!1)throw new Error(`Request to '${a.href}' has been blocked because of your configuration settings`);if(a.protocol==="http:"&&!tP.default.isMatch(a.hostname,r.get("unsafeHttpWhitelist")))throw new Error(`Unsafe http requests must be explicitly whitelisted in your configuration (${a.hostname})`);let u={agent:{http:l.httpProxy?rP.default.httpOverHttp(X8(l.httpProxy)):lxe,https:l.httpsProxy?rP.default.httpsOverHttp(X8(l.httpsProxy)):cxe},headers:i,method:o};u.responseType=s?"json":"buffer",e!==null&&(Buffer.isBuffer(e)||!n&&typeof e=="string"?u.body=e:u.json=e);let g=r.get("httpTimeout"),f=r.get("httpRetry"),h=r.get("enableStrictSsl"),p=l.caFilePath,{default:d}=await Promise.resolve().then(()=>ie(zy())),m=p?await uxe(p):void 0,I=d.extend(P({timeout:{socket:g},retry:f,https:{rejectUnauthorized:h,certificateAuthority:m}},u));return r.getLimit("networkConcurrency")(()=>I(a))}async function fxe(t,n){var s=n,{configuration:e,jsonResponse:r}=s,i=qr(s,["configuration","jsonResponse"]);let o=na(V8,t,()=>_y(xp(t,null,P({configuration:e},i)),{configuration:e}).then(a=>(V8.set(t,a.body),a.body)));return Buffer.isBuffer(o)===!1&&(o=await o),r?JSON.parse(o.toString()):o}async function hxe(t,e,n){var s=n,{customErrorMessage:r}=s,i=qr(s,["customErrorMessage"]);return(await _y(xp(t,e,_(P({},i),{method:Jl.PUT})),i)).body}async function iP(t,e,n){var s=n,{customErrorMessage:r}=s,i=qr(s,["customErrorMessage"]);return(await _y(xp(t,e,_(P({},i),{method:Jl.POST})),i)).body}async function pxe(t,i){var n=i,{customErrorMessage:e}=n,r=qr(n,["customErrorMessage"]);return(await _y(xp(t,null,_(P({},r),{method:Jl.DELETE})),r)).body}var Kt={};it(Kt,{PackageManager:()=>tn,detectPackageManager:()=>a9,executePackageAccessibleBinary:()=>g9,executePackageScript:()=>Uw,executePackageShellcode:()=>rD,executeWorkspaceAccessibleBinary:()=>qFe,executeWorkspaceLifecycleScript:()=>u9,executeWorkspaceScript:()=>c9,getPackageAccessibleBinaries:()=>Hw,getWorkspaceAccessibleBinaries:()=>l9,hasPackageScript:()=>GFe,hasWorkspaceScript:()=>tD,makeScriptEnv:()=>Vp,maybeExecuteWorkspaceLifecycleScript:()=>YFe,prepareExternalProject:()=>HFe});var Fp={};it(Fp,{getLibzipPromise:()=>$i,getLibzipSync:()=>v4});var yA=["number","number"],nP;(function(D){D[D.ZIP_ER_OK=0]="ZIP_ER_OK",D[D.ZIP_ER_MULTIDISK=1]="ZIP_ER_MULTIDISK",D[D.ZIP_ER_RENAME=2]="ZIP_ER_RENAME",D[D.ZIP_ER_CLOSE=3]="ZIP_ER_CLOSE",D[D.ZIP_ER_SEEK=4]="ZIP_ER_SEEK",D[D.ZIP_ER_READ=5]="ZIP_ER_READ",D[D.ZIP_ER_WRITE=6]="ZIP_ER_WRITE",D[D.ZIP_ER_CRC=7]="ZIP_ER_CRC",D[D.ZIP_ER_ZIPCLOSED=8]="ZIP_ER_ZIPCLOSED",D[D.ZIP_ER_NOENT=9]="ZIP_ER_NOENT",D[D.ZIP_ER_EXISTS=10]="ZIP_ER_EXISTS",D[D.ZIP_ER_OPEN=11]="ZIP_ER_OPEN",D[D.ZIP_ER_TMPOPEN=12]="ZIP_ER_TMPOPEN",D[D.ZIP_ER_ZLIB=13]="ZIP_ER_ZLIB",D[D.ZIP_ER_MEMORY=14]="ZIP_ER_MEMORY",D[D.ZIP_ER_CHANGED=15]="ZIP_ER_CHANGED",D[D.ZIP_ER_COMPNOTSUPP=16]="ZIP_ER_COMPNOTSUPP",D[D.ZIP_ER_EOF=17]="ZIP_ER_EOF",D[D.ZIP_ER_INVAL=18]="ZIP_ER_INVAL",D[D.ZIP_ER_NOZIP=19]="ZIP_ER_NOZIP",D[D.ZIP_ER_INTERNAL=20]="ZIP_ER_INTERNAL",D[D.ZIP_ER_INCONS=21]="ZIP_ER_INCONS",D[D.ZIP_ER_REMOVE=22]="ZIP_ER_REMOVE",D[D.ZIP_ER_DELETED=23]="ZIP_ER_DELETED",D[D.ZIP_ER_ENCRNOTSUPP=24]="ZIP_ER_ENCRNOTSUPP",D[D.ZIP_ER_RDONLY=25]="ZIP_ER_RDONLY",D[D.ZIP_ER_NOPASSWD=26]="ZIP_ER_NOPASSWD",D[D.ZIP_ER_WRONGPASSWD=27]="ZIP_ER_WRONGPASSWD",D[D.ZIP_ER_OPNOTSUPP=28]="ZIP_ER_OPNOTSUPP",D[D.ZIP_ER_INUSE=29]="ZIP_ER_INUSE",D[D.ZIP_ER_TELL=30]="ZIP_ER_TELL",D[D.ZIP_ER_COMPRESSED_DATA=31]="ZIP_ER_COMPRESSED_DATA"})(nP||(nP={}));var $8=t=>({get HEAP8(){return t.HEAP8},get HEAPU8(){return t.HEAPU8},errors:nP,SEEK_SET:0,SEEK_CUR:1,SEEK_END:2,ZIP_CHECKCONS:4,ZIP_CREATE:1,ZIP_EXCL:2,ZIP_TRUNCATE:8,ZIP_RDONLY:16,ZIP_FL_OVERWRITE:8192,ZIP_FL_COMPRESSED:4,ZIP_OPSYS_DOS:0,ZIP_OPSYS_AMIGA:1,ZIP_OPSYS_OPENVMS:2,ZIP_OPSYS_UNIX:3,ZIP_OPSYS_VM_CMS:4,ZIP_OPSYS_ATARI_ST:5,ZIP_OPSYS_OS_2:6,ZIP_OPSYS_MACINTOSH:7,ZIP_OPSYS_Z_SYSTEM:8,ZIP_OPSYS_CPM:9,ZIP_OPSYS_WINDOWS_NTFS:10,ZIP_OPSYS_MVS:11,ZIP_OPSYS_VSE:12,ZIP_OPSYS_ACORN_RISC:13,ZIP_OPSYS_VFAT:14,ZIP_OPSYS_ALTERNATE_MVS:15,ZIP_OPSYS_BEOS:16,ZIP_OPSYS_TANDEM:17,ZIP_OPSYS_OS_400:18,ZIP_OPSYS_OS_X:19,ZIP_CM_DEFAULT:-1,ZIP_CM_STORE:0,ZIP_CM_DEFLATE:8,uint08S:t._malloc(1),uint16S:t._malloc(2),uint32S:t._malloc(4),uint64S:t._malloc(8),malloc:t._malloc,free:t._free,getValue:t.getValue,open:t.cwrap("zip_open","number",["string","number","number"]),openFromSource:t.cwrap("zip_open_from_source","number",["number","number","number"]),close:t.cwrap("zip_close","number",["number"]),discard:t.cwrap("zip_discard",null,["number"]),getError:t.cwrap("zip_get_error","number",["number"]),getName:t.cwrap("zip_get_name","string",["number","number","number"]),getNumEntries:t.cwrap("zip_get_num_entries","number",["number","number"]),delete:t.cwrap("zip_delete","number",["number","number"]),stat:t.cwrap("zip_stat","number",["number","string","number","number"]),statIndex:t.cwrap("zip_stat_index","number",["number",...yA,"number","number"]),fopen:t.cwrap("zip_fopen","number",["number","string","number"]),fopenIndex:t.cwrap("zip_fopen_index","number",["number",...yA,"number"]),fread:t.cwrap("zip_fread","number",["number","number","number","number"]),fclose:t.cwrap("zip_fclose","number",["number"]),dir:{add:t.cwrap("zip_dir_add","number",["number","string"])},file:{add:t.cwrap("zip_file_add","number",["number","string","number","number"]),getError:t.cwrap("zip_file_get_error","number",["number"]),getExternalAttributes:t.cwrap("zip_file_get_external_attributes","number",["number",...yA,"number","number","number"]),setExternalAttributes:t.cwrap("zip_file_set_external_attributes","number",["number",...yA,"number","number","number"]),setMtime:t.cwrap("zip_file_set_mtime","number",["number",...yA,"number","number"]),setCompression:t.cwrap("zip_set_file_compression","number",["number",...yA,"number","number"])},ext:{countSymlinks:t.cwrap("zip_ext_count_symlinks","number",["number"])},error:{initWithCode:t.cwrap("zip_error_init_with_code",null,["number","number"]),strerror:t.cwrap("zip_error_strerror","string",["number"])},name:{locate:t.cwrap("zip_name_locate","number",["number","string","number"])},source:{fromUnattachedBuffer:t.cwrap("zip_source_buffer_create","number",["number","number","number","number"]),fromBuffer:t.cwrap("zip_source_buffer","number",["number","number",...yA,"number"]),free:t.cwrap("zip_source_free",null,["number"]),keep:t.cwrap("zip_source_keep",null,["number"]),open:t.cwrap("zip_source_open","number",["number"]),close:t.cwrap("zip_source_close","number",["number"]),seek:t.cwrap("zip_source_seek","number",["number",...yA,"number"]),tell:t.cwrap("zip_source_tell","number",["number"]),read:t.cwrap("zip_source_read","number",["number","number","number"]),error:t.cwrap("zip_source_error","number",["number"]),setMtime:t.cwrap("zip_source_set_mtime","number",["number","number"])},struct:{stat:t.cwrap("zipstruct_stat","number",[]),statS:t.cwrap("zipstruct_statS","number",[]),statName:t.cwrap("zipstruct_stat_name","string",["number"]),statIndex:t.cwrap("zipstruct_stat_index","number",["number"]),statSize:t.cwrap("zipstruct_stat_size","number",["number"]),statCompSize:t.cwrap("zipstruct_stat_comp_size","number",["number"]),statCompMethod:t.cwrap("zipstruct_stat_comp_method","number",["number"]),statMtime:t.cwrap("zipstruct_stat_mtime","number",["number"]),statCrc:t.cwrap("zipstruct_stat_crc","number",["number"]),error:t.cwrap("zipstruct_error","number",[]),errorS:t.cwrap("zipstruct_errorS","number",[]),errorCodeZip:t.cwrap("zipstruct_error_code_zip","number",["number"])}});var BP=null;function v4(){return BP===null&&(BP=$8(b4())),BP}async function $i(){return v4()}var jp={};it(jp,{ShellError:()=>as,execute:()=>Fw,globUtils:()=>bw});var Hp={};it(Hp,{parseResolution:()=>gw,parseShell:()=>Aw,parseSyml:()=>Ii,stringifyArgument:()=>SP,stringifyArgumentSegment:()=>xP,stringifyArithmeticExpression:()=>uw,stringifyCommand:()=>vP,stringifyCommandChain:()=>rg,stringifyCommandChainThen:()=>bP,stringifyCommandLine:()=>lw,stringifyCommandLineThen:()=>QP,stringifyEnvSegment:()=>cw,stringifyRedirectArgument:()=>Np,stringifyResolution:()=>fw,stringifyShell:()=>tg,stringifyShellLine:()=>tg,stringifySyml:()=>Qa,stringifyValueArgument:()=>ig});var k4=ie(x4());function Aw(t,e={isGlobPattern:()=>!1}){try{return(0,k4.parse)(t,e)}catch(r){throw r.location&&(r.message=r.message.replace(/(\.)?$/,` (line ${r.location.start.line}, column ${r.location.start.column})$1`)),r}}function tg(t,{endSemicolon:e=!1}={}){return t.map(({command:r,type:i},n)=>`${lw(r)}${i===";"?n!==t.length-1||e?";":"":" &"}`).join(" ")}function lw(t){return`${rg(t.chain)}${t.then?` ${QP(t.then)}`:""}`}function QP(t){return`${t.type} ${lw(t.line)}`}function rg(t){return`${vP(t)}${t.then?` ${bP(t.then)}`:""}`}function bP(t){return`${t.type} ${rg(t.chain)}`}function vP(t){switch(t.type){case"command":return`${t.envs.length>0?`${t.envs.map(e=>cw(e)).join(" ")} `:""}${t.args.map(e=>SP(e)).join(" ")}`;case"subshell":return`(${tg(t.subshell)})${t.args.length>0?` ${t.args.map(e=>Np(e)).join(" ")}`:""}`;case"group":return`{ ${tg(t.group,{endSemicolon:!0})} }${t.args.length>0?` ${t.args.map(e=>Np(e)).join(" ")}`:""}`;case"envs":return t.envs.map(e=>cw(e)).join(" ");default:throw new Error(`Unsupported command type: "${t.type}"`)}}function cw(t){return`${t.name}=${t.args[0]?ig(t.args[0]):""}`}function SP(t){switch(t.type){case"redirection":return Np(t);case"argument":return ig(t);default:throw new Error(`Unsupported argument type: "${t.type}"`)}}function Np(t){return`${t.subtype} ${t.args.map(e=>ig(e)).join(" ")}`}function ig(t){return t.segments.map(e=>xP(e)).join("")}function xP(t){let e=(i,n)=>n?`"${i}"`:i,r=i=>i===""?'""':i.match(/[(){}<>$|&; \t"']/)?`$'${i.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\f/g,"\\f").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\v/g,"\\v").replace(/\0/g,"\\0")}'`:i;switch(t.type){case"text":return r(t.text);case"glob":return t.pattern;case"shell":return e(`\${${tg(t.shell)}}`,t.quoted);case"variable":return e(typeof t.defaultValue=="undefined"?`\${${t.name}}`:t.defaultValue.length===0?`\${${t.name}:-}`:`\${${t.name}:-${t.defaultValue.map(i=>ig(i)).join(" ")}}`,t.quoted);case"arithmetic":return`$(( ${uw(t.arithmetic)} ))`;default:throw new Error(`Unsupported argument segment type: "${t.type}"`)}}function uw(t){let e=n=>{switch(n){case"addition":return"+";case"subtraction":return"-";case"multiplication":return"*";case"division":return"/";default:throw new Error(`Can't extract operator from arithmetic expression of type "${n}"`)}},r=(n,s)=>s?`( ${n} )`:n,i=n=>r(uw(n),!["number","variable"].includes(n.type));switch(t.type){case"number":return String(t.value);case"variable":return t.name;default:return`${i(t.left)} ${e(t.type)} ${i(t.right)}`}}var R4=ie(D4());function gw(t){let e=t.match(/^\*{1,2}\/(.*)/);if(e)throw new Error(`The override for '${t}' includes a glob pattern. Glob patterns have been removed since their behaviours don't match what you'd expect. Set the override to '${e[1]}' instead.`);try{return(0,R4.parse)(t)}catch(r){throw r.location&&(r.message=r.message.replace(/(\.)?$/,` (line ${r.location.start.line}, column ${r.location.start.column})$1`)),r}}function fw(t){let e="";return t.from&&(e+=t.from.fullName,t.from.description&&(e+=`@${t.from.description}`),e+="/"),e+=t.descriptor.fullName,t.descriptor.description&&(e+=`@${t.descriptor.description}`),e}var Qw=ie(w5()),b5=ie(Q5()),$De=/^(?![-?:,\][{}#&*!|>'"%@` \t\r\n]).([ \t]*(?![,\][{}:# \t\r\n]).)*$/,v5=["__metadata","version","resolution","dependencies","peerDependencies","dependenciesMeta","peerDependenciesMeta","binaries"],HP=class{constructor(e){this.data=e}};function S5(t){return t.match($De)?t:JSON.stringify(t)}function x5(t){return typeof t=="undefined"?!0:typeof t=="object"&&t!==null?Object.keys(t).every(e=>x5(t[e])):!1}function GP(t,e,r){if(t===null)return`null +`;if(typeof t=="number"||typeof t=="boolean")return`${t.toString()} +`;if(typeof t=="string")return`${S5(t)} +`;if(Array.isArray(t)){if(t.length===0)return`[] +`;let i=" ".repeat(e);return` +${t.map(s=>`${i}- ${GP(s,e+1,!1)}`).join("")}`}if(typeof t=="object"&&t){let i,n;t instanceof HP?(i=t.data,n=!1):(i=t,n=!0);let s=" ".repeat(e),o=Object.keys(i);n&&o.sort((l,c)=>{let u=v5.indexOf(l),g=v5.indexOf(c);return u===-1&&g===-1?lc?1:0:u!==-1&&g===-1?-1:u===-1&&g!==-1?1:u-g});let a=o.filter(l=>!x5(i[l])).map((l,c)=>{let u=i[l],g=S5(l),f=GP(u,e+1,!0),h=c>0||r?s:"";return f.startsWith(` +`)?`${h}${g}:${f}`:`${h}${g}: ${f}`}).join(e===0?` +`:"")||` +`;return r?` +${a}`:`${a}`}throw new Error(`Unsupported value type (${t})`)}function Qa(t){try{let e=GP(t,0,!1);return e!==` +`?e:""}catch(e){throw e.location&&(e.message=e.message.replace(/(\.)?$/,` (line ${e.location.start.line}, column ${e.location.start.column})$1`)),e}}Qa.PreserveOrdering=HP;function eRe(t){return t.endsWith(` +`)||(t+=` +`),(0,b5.parse)(t)}var tRe=/^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i;function rRe(t){if(tRe.test(t))return eRe(t);let e=(0,Qw.safeLoad)(t,{schema:Qw.FAILSAFE_SCHEMA,json:!0});if(e==null)return{};if(typeof e!="object")throw new Error(`Expected an indexed object, got a ${typeof e} instead. Does your file follow Yaml's rules?`);if(Array.isArray(e))throw new Error("Expected an indexed object, got an array instead. Does your file follow Yaml's rules?");return e}function Ii(t){return rRe(t)}var U5=ie(jb()),H5=ie(require("os")),Kn=ie(require("stream")),G5=ie(require("util"));var as=class extends Error{constructor(e){super(e);this.name="ShellError"}};var bw={};it(bw,{fastGlobOptions:()=>D5,isBraceExpansion:()=>R5,isGlobPattern:()=>iRe,match:()=>nRe,micromatchOptions:()=>Sw});var k5=ie(gy()),P5=ie(require("fs")),vw=ie(Nn()),Sw={strictBrackets:!0},D5={onlyDirectories:!1,onlyFiles:!1};function iRe(t){if(!vw.default.scan(t,Sw).isGlob)return!1;try{vw.default.parse(t,Sw)}catch{return!1}return!0}function nRe(t,{cwd:e,baseFs:r}){return(0,k5.default)(t,_(P({},D5),{cwd:M.fromPortablePath(e),fs:SE(P5.default,new ah(r))}))}function R5(t){return vw.default.scan(t,Sw).isBrace}var F5=ie(bb()),Bo=ie(require("stream")),N5=ie(require("string_decoder")),wn;(function(i){i[i.STDIN=0]="STDIN",i[i.STDOUT=1]="STDOUT",i[i.STDERR=2]="STDERR"})(wn||(wn={}));var sc=new Set;function jP(){}function YP(){for(let t of sc)t.kill()}function L5(t,e,r,i){return n=>{let s=n[0]instanceof Bo.Transform?"pipe":n[0],o=n[1]instanceof Bo.Transform?"pipe":n[1],a=n[2]instanceof Bo.Transform?"pipe":n[2],l=(0,F5.default)(t,e,_(P({},i),{stdio:[s,o,a]}));return sc.add(l),sc.size===1&&(process.on("SIGINT",jP),process.on("SIGTERM",YP)),n[0]instanceof Bo.Transform&&n[0].pipe(l.stdin),n[1]instanceof Bo.Transform&&l.stdout.pipe(n[1],{end:!1}),n[2]instanceof Bo.Transform&&l.stderr.pipe(n[2],{end:!1}),{stdin:l.stdin,promise:new Promise(c=>{l.on("error",u=>{switch(sc.delete(l),sc.size===0&&(process.off("SIGINT",jP),process.off("SIGTERM",YP)),u.code){case"ENOENT":n[2].write(`command not found: ${t} +`),c(127);break;case"EACCES":n[2].write(`permission denied: ${t} +`),c(128);break;default:n[2].write(`uncaught error: ${u.message} +`),c(1);break}}),l.on("exit",u=>{sc.delete(l),sc.size===0&&(process.off("SIGINT",jP),process.off("SIGTERM",YP)),c(u!==null?u:129)})})}}}function T5(t){return e=>{let r=e[0]==="pipe"?new Bo.PassThrough:e[0];return{stdin:r,promise:Promise.resolve().then(()=>t({stdin:r,stdout:e[1],stderr:e[2]}))}}}var Os=class{constructor(e){this.stream=e}close(){}get(){return this.stream}},M5=class{constructor(){this.stream=null}close(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");this.stream.end()}attach(e){this.stream=e}get(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");return this.stream}},Gp=class{constructor(e,r){this.stdin=null;this.stdout=null;this.stderr=null;this.pipe=null;this.ancestor=e,this.implementation=r}static start(e,{stdin:r,stdout:i,stderr:n}){let s=new Gp(null,e);return s.stdin=r,s.stdout=i,s.stderr=n,s}pipeTo(e,r=1){let i=new Gp(this,e),n=new M5;return i.pipe=n,i.stdout=this.stdout,i.stderr=this.stderr,(r&1)==1?this.stdout=n:this.ancestor!==null&&(this.stderr=this.ancestor.stdout),(r&2)==2?this.stderr=n:this.ancestor!==null&&(this.stderr=this.ancestor.stderr),i}async exec(){let e=["ignore","ignore","ignore"];if(this.pipe)e[0]="pipe";else{if(this.stdin===null)throw new Error("Assertion failed: No input stream registered");e[0]=this.stdin.get()}let r;if(this.stdout===null)throw new Error("Assertion failed: No output stream registered");r=this.stdout,e[1]=r.get();let i;if(this.stderr===null)throw new Error("Assertion failed: No error stream registered");i=this.stderr,e[2]=i.get();let n=this.implementation(e);return this.pipe&&this.pipe.attach(n.stdin),await n.promise.then(s=>(r.close(),i.close(),s))}async run(){let e=[];for(let i=this;i;i=i.ancestor)e.push(i.exec());return(await Promise.all(e))[0]}};function xw(t,e){return Gp.start(t,e)}function O5(t,e=null){let r=new Bo.PassThrough,i=new N5.StringDecoder,n="";return r.on("data",s=>{let o=i.write(s),a;do if(a=o.indexOf(` +`),a!==-1){let l=n+o.substr(0,a);o=o.substr(a+1),n="",t(e!==null?`${e} ${l}`:l)}while(a!==-1);n+=o}),r.on("end",()=>{let s=i.end();s!==""&&t(e!==null?`${e} ${s}`:s)}),r}function K5(t,{prefix:e}){return{stdout:O5(r=>t.stdout.write(`${r} +`),t.stdout.isTTY?e:null),stderr:O5(r=>t.stderr.write(`${r} +`),t.stderr.isTTY?e:null)}}var sRe=(0,G5.promisify)(setTimeout);var Fi;(function(r){r[r.Readable=1]="Readable",r[r.Writable=2]="Writable"})(Fi||(Fi={}));function j5(t,e,r){let i=new Kn.PassThrough({autoDestroy:!0});switch(t){case wn.STDIN:(e&1)==1&&r.stdin.pipe(i,{end:!1}),(e&2)==2&&r.stdin instanceof Kn.Writable&&i.pipe(r.stdin,{end:!1});break;case wn.STDOUT:(e&1)==1&&r.stdout.pipe(i,{end:!1}),(e&2)==2&&i.pipe(r.stdout,{end:!1});break;case wn.STDERR:(e&1)==1&&r.stderr.pipe(i,{end:!1}),(e&2)==2&&i.pipe(r.stderr,{end:!1});break;default:throw new as(`Bad file descriptor: "${t}"`)}return i}function kw(t,e={}){let r=P(P({},t),e);return r.environment=P(P({},t.environment),e.environment),r.variables=P(P({},t.variables),e.variables),r}var oRe=new Map([["cd",async([t=(0,H5.homedir)(),...e],r,i)=>{let n=v.resolve(i.cwd,M.toPortablePath(t));if(!(await r.baseFs.statPromise(n).catch(o=>{throw o.code==="ENOENT"?new as(`cd: no such file or directory: ${t}`):o})).isDirectory())throw new as(`cd: not a directory: ${t}`);return i.cwd=n,0}],["pwd",async(t,e,r)=>(r.stdout.write(`${M.fromPortablePath(r.cwd)} +`),0)],[":",async(t,e,r)=>0],["true",async(t,e,r)=>0],["false",async(t,e,r)=>1],["exit",async([t,...e],r,i)=>i.exitCode=parseInt(t!=null?t:i.variables["?"],10)],["echo",async(t,e,r)=>(r.stdout.write(`${t.join(" ")} +`),0)],["sleep",async([t],e,r)=>{if(typeof t=="undefined")throw new as("sleep: missing operand");let i=Number(t);if(Number.isNaN(i))throw new as(`sleep: invalid time interval '${t}'`);return await sRe(1e3*i,0)}],["__ysh_run_procedure",async(t,e,r)=>{let i=r.procedures[t[0]];return await xw(i,{stdin:new Os(r.stdin),stdout:new Os(r.stdout),stderr:new Os(r.stderr)}).run()}],["__ysh_set_redirects",async(t,e,r)=>{let i=r.stdin,n=r.stdout,s=r.stderr,o=[],a=[],l=[],c=0;for(;t[c]!=="--";){let g=t[c++],{type:f,fd:h}=JSON.parse(g),p=B=>{switch(h){case null:case 0:o.push(B);break;default:throw new Error(`Unsupported file descriptor: "${h}"`)}},d=B=>{switch(h){case null:case 1:a.push(B);break;case 2:l.push(B);break;default:throw new Error(`Unsupported file descriptor: "${h}"`)}},m=Number(t[c++]),I=c+m;for(let B=c;Be.baseFs.createReadStream(v.resolve(r.cwd,M.toPortablePath(t[B]))));break;case"<<<":p(()=>{let b=new Kn.PassThrough;return process.nextTick(()=>{b.write(`${t[B]} +`),b.end()}),b});break;case"<&":p(()=>j5(Number(t[B]),1,r));break;case">":case">>":{let b=v.resolve(r.cwd,M.toPortablePath(t[B]));d(b==="/dev/null"?new Kn.Writable({autoDestroy:!0,emitClose:!0,write(R,H,L){setImmediate(L)}}):e.baseFs.createWriteStream(b,f===">>"?{flags:"a"}:void 0))}break;case">&":d(j5(Number(t[B]),2,r));break;default:throw new Error(`Assertion failed: Unsupported redirection type: "${f}"`)}}if(o.length>0){let g=new Kn.PassThrough;i=g;let f=h=>{if(h===o.length)g.end();else{let p=o[h]();p.pipe(g,{end:!1}),p.on("end",()=>{f(h+1)})}};f(0)}if(a.length>0){let g=new Kn.PassThrough;n=g;for(let f of a)g.pipe(f)}if(l.length>0){let g=new Kn.PassThrough;s=g;for(let f of l)g.pipe(f)}let u=await xw(Yp(t.slice(c+1),e,r),{stdin:new Os(i),stdout:new Os(n),stderr:new Os(s)}).run();return await Promise.all(a.map(g=>new Promise((f,h)=>{g.on("error",p=>{h(p)}),g.on("close",()=>{f()}),g.end()}))),await Promise.all(l.map(g=>new Promise((f,h)=>{g.on("error",p=>{h(p)}),g.on("close",()=>{f()}),g.end()}))),u}]]);async function aRe(t,e,r){let i=[],n=new Kn.PassThrough;return n.on("data",s=>i.push(s)),await Pw(t,e,kw(r,{stdout:n})),Buffer.concat(i).toString().replace(/[\r\n]+$/,"")}async function Y5(t,e,r){let i=t.map(async s=>{let o=await oc(s.args,e,r);return{name:s.name,value:o.join(" ")}});return(await Promise.all(i)).reduce((s,o)=>(s[o.name]=o.value,s),{})}function Dw(t){return t.match(/[^ \r\n\t]+/g)||[]}async function q5(t,e,r,i,n=i){switch(t.name){case"$":i(String(process.pid));break;case"#":i(String(e.args.length));break;case"@":if(t.quoted)for(let s of e.args)n(s);else for(let s of e.args){let o=Dw(s);for(let a=0;a=0&&st+e,subtraction:(t,e)=>t-e,multiplication:(t,e)=>t*e,division:(t,e)=>Math.trunc(t/e)};async function qp(t,e,r){if(t.type==="number"){if(Number.isInteger(t.value))return t.value;throw new Error(`Invalid number: "${t.value}", only integers are allowed`)}else if(t.type==="variable"){let i=[];await q5(_(P({},t),{quoted:!0}),e,r,s=>i.push(s));let n=Number(i.join(" "));return Number.isNaN(n)?qp({type:"variable",name:i.join(" ")},e,r):qp({type:"number",value:n},e,r)}else return ARe[t.type](await qp(t.left,e,r),await qp(t.right,e,r))}async function oc(t,e,r){let i=new Map,n=[],s=[],o=u=>{s.push(u)},a=()=>{s.length>0&&n.push(s.join("")),s=[]},l=u=>{o(u),a()},c=(u,g,f)=>{let h=JSON.stringify({type:u,fd:g}),p=i.get(h);typeof p=="undefined"&&i.set(h,p=[]),p.push(f)};for(let u of t){let g=!1;switch(u.type){case"redirection":{let f=await oc(u.args,e,r);for(let h of f)c(u.subtype,u.fd,h)}break;case"argument":for(let f of u.segments)switch(f.type){case"text":o(f.text);break;case"glob":o(f.pattern),g=!0;break;case"shell":{let h=await aRe(f.shell,e,r);if(f.quoted)o(h);else{let p=Dw(h);for(let d=0;d0){let u=[];for(let[g,f]of i.entries())u.splice(u.length,0,g,String(f.length),...f);n.splice(0,0,"__ysh_set_redirects",...u,"--")}return n}function Yp(t,e,r){e.builtins.has(t[0])||(t=["command",...t]);let i=M.fromPortablePath(r.cwd),n=r.environment;typeof n.PWD!="undefined"&&(n=_(P({},n),{PWD:i}));let[s,...o]=t;if(s==="command")return L5(o[0],o.slice(1),e,{cwd:i,env:n});let a=e.builtins.get(s);if(typeof a=="undefined")throw new Error(`Assertion failed: A builtin should exist for "${s}"`);return T5(async({stdin:l,stdout:c,stderr:u})=>{let{stdin:g,stdout:f,stderr:h}=r;r.stdin=l,r.stdout=c,r.stderr=u;try{return await a(o,e,r)}finally{r.stdin=g,r.stdout=f,r.stderr=h}})}function lRe(t,e,r){return i=>{let n=new Kn.PassThrough,s=Pw(t,e,kw(r,{stdin:n}));return{stdin:n,promise:s}}}function cRe(t,e,r){return i=>{let n=new Kn.PassThrough,s=Pw(t,e,r);return{stdin:n,promise:s}}}function J5(t,e,r,i){if(e.length===0)return t;{let n;do n=String(Math.random());while(Object.prototype.hasOwnProperty.call(i.procedures,n));return i.procedures=P({},i.procedures),i.procedures[n]=t,Yp([...e,"__ysh_run_procedure",n],r,i)}}async function W5(t,e,r){let i=t,n=null,s=null;for(;i;){let o=i.then?P({},r):r,a;switch(i.type){case"command":{let l=await oc(i.args,e,r),c=await Y5(i.envs,e,r);a=i.envs.length?Yp(l,e,kw(o,{environment:c})):Yp(l,e,o)}break;case"subshell":{let l=await oc(i.args,e,r),c=lRe(i.subshell,e,o);a=J5(c,l,e,o)}break;case"group":{let l=await oc(i.args,e,r),c=cRe(i.group,e,o);a=J5(c,l,e,o)}break;case"envs":{let l=await Y5(i.envs,e,r);o.environment=P(P({},o.environment),l),a=Yp(["true"],e,o)}break}if(typeof a=="undefined")throw new Error("Assertion failed: An action should have been generated");if(n===null)s=xw(a,{stdin:new Os(o.stdin),stdout:new Os(o.stdout),stderr:new Os(o.stderr)});else{if(s===null)throw new Error("Assertion failed: The execution pipeline should have been setup");switch(n){case"|":s=s.pipeTo(a,wn.STDOUT);break;case"|&":s=s.pipeTo(a,wn.STDOUT|wn.STDERR);break}}i.then?(n=i.then.type,i=i.then.chain):i=null}if(s===null)throw new Error("Assertion failed: The execution pipeline should have been setup");return await s.run()}async function uRe(t,e,r,{background:i=!1}={}){function n(s){let o=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],a=o[s%o.length];return U5.default.hex(a)}if(i){let s=r.nextBackgroundJobIndex++,o=n(s),a=`[${s}]`,l=o(a),{stdout:c,stderr:u}=K5(r,{prefix:l});return r.backgroundJobs.push(W5(t,e,kw(r,{stdout:c,stderr:u})).catch(g=>u.write(`${g.message} +`)).finally(()=>{r.stdout.isTTY&&r.stdout.write(`Job ${l}, '${o(rg(t))}' has ended +`)})),0}return await W5(t,e,r)}async function gRe(t,e,r,{background:i=!1}={}){let n,s=a=>{n=a,r.variables["?"]=String(a)},o=async a=>{try{return await uRe(a.chain,e,r,{background:i&&typeof a.then=="undefined"})}catch(l){if(!(l instanceof as))throw l;return r.stderr.write(`${l.message} +`),1}};for(s(await o(t));t.then;){if(r.exitCode!==null)return r.exitCode;switch(t.then.type){case"&&":n===0&&s(await o(t.then.line));break;case"||":n!==0&&s(await o(t.then.line));break;default:throw new Error(`Assertion failed: Unsupported command type: "${t.then.type}"`)}t=t.then.line}return n}async function Pw(t,e,r){let i=r.backgroundJobs;r.backgroundJobs=[];let n=0;for(let{command:s,type:o}of t){if(n=await gRe(s,e,r,{background:o==="&"}),r.exitCode!==null)return r.exitCode;r.variables["?"]=String(n)}return await Promise.all(r.backgroundJobs),r.backgroundJobs=i,n}function z5(t){switch(t.type){case"variable":return t.name==="@"||t.name==="#"||t.name==="*"||Number.isFinite(parseInt(t.name,10))||"defaultValue"in t&&!!t.defaultValue&&t.defaultValue.some(e=>Rw(e));case"arithmetic":return qP(t.arithmetic);case"shell":return JP(t.shell);default:return!1}}function Rw(t){switch(t.type){case"redirection":return t.args.some(e=>Rw(e));case"argument":return t.segments.some(e=>z5(e));default:throw new Error(`Assertion failed: Unsupported argument type: "${t.type}"`)}}function qP(t){switch(t.type){case"variable":return z5(t);case"number":return!1;default:return qP(t.left)||qP(t.right)}}function JP(t){return t.some(({command:e})=>{for(;e;){let r=e.chain;for(;r;){let i;switch(r.type){case"subshell":i=JP(r.subshell);break;case"command":i=r.envs.some(n=>n.args.some(s=>Rw(s)))||r.args.some(n=>Rw(n));break}if(i)return!0;if(!r.then)break;r=r.then.chain}if(!e.then)break;e=e.then.line}return!1})}async function Fw(t,e=[],{baseFs:r=new Wt,builtins:i={},cwd:n=M.toPortablePath(process.cwd()),env:s=process.env,stdin:o=process.stdin,stdout:a=process.stdout,stderr:l=process.stderr,variables:c={},glob:u=bw}={}){let g={};for(let[p,d]of Object.entries(s))typeof d!="undefined"&&(g[p]=d);let f=new Map(oRe);for(let[p,d]of Object.entries(i))f.set(p,d);o===null&&(o=new Kn.PassThrough,o.end());let h=Aw(t,u);if(!JP(h)&&h.length>0&&e.length>0){let{command:p}=h[h.length-1];for(;p.then;)p=p.then.line;let d=p.chain;for(;d.then;)d=d.then.chain;d.type==="command"&&(d.args=d.args.concat(e.map(m=>({type:"argument",segments:[{type:"text",text:m}]}))))}return await Pw(h,{args:e,baseFs:r,builtins:f,initialStdin:o,initialStdout:a,initialStderr:l,glob:u},{cwd:n,environment:g,exitCode:null,procedures:{},stdin:o,stdout:a,stderr:l,variables:Object.assign({},c,{["?"]:0}),nextBackgroundJobIndex:1,backgroundJobs:[]})}var s9=ie(ZP()),o9=ie(Wp()),cc=ie(require("stream"));var J6=ie(Or());var zp=class{supportsDescriptor(e,r){return!!(e.range.startsWith(zp.protocol)||r.project.tryWorkspaceByDescriptor(e)!==null)}supportsLocator(e,r){return!!e.reference.startsWith(zp.protocol)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,i){return e}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){return[i.project.getWorkspaceByDescriptor(e).anchoredLocator]}async getSatisfying(e,r,i){return null}async resolve(e,r){let i=r.project.getWorkspaceByCwd(e.reference.slice(zp.protocol.length));return _(P({},e),{version:i.manifest.version||"0.0.0",languageName:"unknown",linkType:gt.SOFT,conditions:null,dependencies:new Map([...i.manifest.dependencies,...i.manifest.devDependencies]),peerDependencies:new Map([...i.manifest.peerDependencies]),dependenciesMeta:i.manifest.dependenciesMeta,peerDependenciesMeta:i.manifest.peerDependenciesMeta,bin:i.manifest.bin})}},Yr=zp;Yr.protocol="workspace:";var qt={};it(qt,{SemVer:()=>j6.SemVer,satisfiesWithPrereleases:()=>lc,validRange:()=>Us});var Lw=ie(Or()),j6=ie(Or()),Y6=new Map;function lc(t,e,r=!1){if(!t)return!1;let i=`${e}${r}`,n=Y6.get(i);if(typeof n=="undefined")try{n=new Lw.default.Range(e,{includePrerelease:!0,loose:r})}catch{return!1}finally{Y6.set(i,n||null)}else if(n===null)return!1;let s;try{s=new Lw.default.SemVer(t,n)}catch(o){return!1}return n.test(s)?!0:(s.prerelease&&(s.prerelease=[]),n.set.some(o=>{for(let a of o)a.semver.prerelease&&(a.semver.prerelease=[]);return o.every(a=>a.test(s))}))}var q6=new Map;function Us(t){if(t.indexOf(":")!==-1)return null;let e=q6.get(t);if(typeof e!="undefined")return e;try{e=new Lw.default.Range(t)}catch{e=null}return q6.set(t,e),e}var vA=class{constructor(){this.indent=" ";this.name=null;this.version=null;this.os=null;this.cpu=null;this.type=null;this.packageManager=null;this.private=!1;this.license=null;this.main=null;this.module=null;this.browser=null;this.languageName=null;this.bin=new Map;this.scripts=new Map;this.dependencies=new Map;this.devDependencies=new Map;this.peerDependencies=new Map;this.workspaceDefinitions=[];this.dependenciesMeta=new Map;this.peerDependenciesMeta=new Map;this.resolutions=[];this.files=null;this.publishConfig=null;this.installConfig=null;this.preferUnplugged=null;this.raw={};this.errors=[]}static async tryFind(e,{baseFs:r=new Wt}={}){let i=v.join(e,"package.json");return await r.existsPromise(i)?await vA.fromFile(i,{baseFs:r}):null}static async find(e,{baseFs:r}={}){let i=await vA.tryFind(e,{baseFs:r});if(i===null)throw new Error("Manifest not found");return i}static async fromFile(e,{baseFs:r=new Wt}={}){let i=new vA;return await i.loadFile(e,{baseFs:r}),i}static fromText(e){let r=new vA;return r.loadFromText(e),r}static isManifestFieldCompatible(e,r){if(e===null)return!0;let i=!0,n=!1;for(let s of e)if(s[0]==="!"){if(n=!0,r===s.slice(1))return!1}else if(i=!1,s===r)return!0;return n&&i}loadFromText(e){let r;try{r=JSON.parse(z6(e)||"{}")}catch(i){throw i.message+=` (when parsing ${e})`,i}this.load(r),this.indent=W6(e)}async loadFile(e,{baseFs:r=new Wt}){let i=await r.readFilePromise(e,"utf8"),n;try{n=JSON.parse(z6(i)||"{}")}catch(s){throw s.message+=` (when parsing ${e})`,s}this.load(n),this.indent=W6(i)}load(e,{yamlCompatibilityMode:r=!1}={}){if(typeof e!="object"||e===null)throw new Error(`Utterly invalid manifest data (${e})`);this.raw=e;let i=[];if(this.name=null,typeof e.name=="string")try{this.name=En(e.name)}catch(s){i.push(new Error("Parsing failed for the 'name' field"))}if(typeof e.version=="string"?this.version=e.version:this.version=null,Array.isArray(e.os)){let s=[];this.os=s;for(let o of e.os)typeof o!="string"?i.push(new Error("Parsing failed for the 'os' field")):s.push(o)}else this.os=null;if(Array.isArray(e.cpu)){let s=[];this.cpu=s;for(let o of e.cpu)typeof o!="string"?i.push(new Error("Parsing failed for the 'cpu' field")):s.push(o)}else this.cpu=null;if(typeof e.type=="string"?this.type=e.type:this.type=null,typeof e.packageManager=="string"?this.packageManager=e.packageManager:this.packageManager=null,typeof e.private=="boolean"?this.private=e.private:this.private=!1,typeof e.license=="string"?this.license=e.license:this.license=null,typeof e.languageName=="string"?this.languageName=e.languageName:this.languageName=null,typeof e.main=="string"?this.main=en(e.main):this.main=null,typeof e.module=="string"?this.module=en(e.module):this.module=null,e.browser!=null)if(typeof e.browser=="string")this.browser=en(e.browser);else{this.browser=new Map;for(let[s,o]of Object.entries(e.browser))this.browser.set(en(s),typeof o=="string"?en(o):o)}else this.browser=null;if(this.bin=new Map,typeof e.bin=="string")this.name!==null?this.bin.set(this.name.name,en(e.bin)):i.push(new Error("String bin field, but no attached package name"));else if(typeof e.bin=="object"&&e.bin!==null)for(let[s,o]of Object.entries(e.bin)){if(typeof o!="string"){i.push(new Error(`Invalid bin definition for '${s}'`));continue}this.bin.set(s,en(o))}if(this.scripts=new Map,typeof e.scripts=="object"&&e.scripts!==null)for(let[s,o]of Object.entries(e.scripts)){if(typeof o!="string"){i.push(new Error(`Invalid script definition for '${s}'`));continue}this.scripts.set(s,o)}if(this.dependencies=new Map,typeof e.dependencies=="object"&&e.dependencies!==null)for(let[s,o]of Object.entries(e.dependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=En(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=Yt(a,o);this.dependencies.set(l.identHash,l)}if(this.devDependencies=new Map,typeof e.devDependencies=="object"&&e.devDependencies!==null)for(let[s,o]of Object.entries(e.devDependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=En(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=Yt(a,o);this.devDependencies.set(l.identHash,l)}if(this.peerDependencies=new Map,typeof e.peerDependencies=="object"&&e.peerDependencies!==null)for(let[s,o]of Object.entries(e.peerDependencies)){let a;try{a=En(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}(typeof o!="string"||!o.startsWith(Yr.protocol)&&!Us(o))&&(i.push(new Error(`Invalid dependency range for '${s}'`)),o="*");let l=Yt(a,o);this.peerDependencies.set(l.identHash,l)}typeof e.workspaces=="object"&&e.workspaces.nohoist&&i.push(new Error("'nohoist' is deprecated, please use 'installConfig.hoistingLimits' instead"));let n=Array.isArray(e.workspaces)?e.workspaces:typeof e.workspaces=="object"&&e.workspaces!==null&&Array.isArray(e.workspaces.packages)?e.workspaces.packages:[];this.workspaceDefinitions=[];for(let s of n){if(typeof s!="string"){i.push(new Error(`Invalid workspace definition for '${s}'`));continue}this.workspaceDefinitions.push({pattern:s})}if(this.dependenciesMeta=new Map,typeof e.dependenciesMeta=="object"&&e.dependenciesMeta!==null)for(let[s,o]of Object.entries(e.dependenciesMeta)){if(typeof o!="object"||o===null){i.push(new Error(`Invalid meta field for '${s}`));continue}let a=pA(s),l=this.ensureDependencyMeta(a),c=Tw(o.built,{yamlCompatibilityMode:r});if(c===null){i.push(new Error(`Invalid built meta field for '${s}'`));continue}let u=Tw(o.optional,{yamlCompatibilityMode:r});if(u===null){i.push(new Error(`Invalid optional meta field for '${s}'`));continue}let g=Tw(o.unplugged,{yamlCompatibilityMode:r});if(g===null){i.push(new Error(`Invalid unplugged meta field for '${s}'`));continue}Object.assign(l,{built:c,optional:u,unplugged:g})}if(this.peerDependenciesMeta=new Map,typeof e.peerDependenciesMeta=="object"&&e.peerDependenciesMeta!==null)for(let[s,o]of Object.entries(e.peerDependenciesMeta)){if(typeof o!="object"||o===null){i.push(new Error(`Invalid meta field for '${s}'`));continue}let a=pA(s),l=this.ensurePeerDependencyMeta(a),c=Tw(o.optional,{yamlCompatibilityMode:r});if(c===null){i.push(new Error(`Invalid optional meta field for '${s}'`));continue}Object.assign(l,{optional:c})}if(this.resolutions=[],typeof e.resolutions=="object"&&e.resolutions!==null)for(let[s,o]of Object.entries(e.resolutions)){if(typeof o!="string"){i.push(new Error(`Invalid resolution entry for '${s}'`));continue}try{this.resolutions.push({pattern:gw(s),reference:o})}catch(a){i.push(a);continue}}if(Array.isArray(e.files)){this.files=new Set;for(let s of e.files){if(typeof s!="string"){i.push(new Error(`Invalid files entry for '${s}'`));continue}this.files.add(s)}}else this.files=null;if(typeof e.publishConfig=="object"&&e.publishConfig!==null){if(this.publishConfig={},typeof e.publishConfig.access=="string"&&(this.publishConfig.access=e.publishConfig.access),typeof e.publishConfig.main=="string"&&(this.publishConfig.main=en(e.publishConfig.main)),typeof e.publishConfig.module=="string"&&(this.publishConfig.module=en(e.publishConfig.module)),e.publishConfig.browser!=null)if(typeof e.publishConfig.browser=="string")this.publishConfig.browser=en(e.publishConfig.browser);else{this.publishConfig.browser=new Map;for(let[s,o]of Object.entries(e.publishConfig.browser))this.publishConfig.browser.set(en(s),typeof o=="string"?en(o):o)}if(typeof e.publishConfig.registry=="string"&&(this.publishConfig.registry=e.publishConfig.registry),typeof e.publishConfig.bin=="string")this.name!==null?this.publishConfig.bin=new Map([[this.name.name,en(e.publishConfig.bin)]]):i.push(new Error("String bin field, but no attached package name"));else if(typeof e.publishConfig.bin=="object"&&e.publishConfig.bin!==null){this.publishConfig.bin=new Map;for(let[s,o]of Object.entries(e.publishConfig.bin)){if(typeof o!="string"){i.push(new Error(`Invalid bin definition for '${s}'`));continue}this.publishConfig.bin.set(s,en(o))}}if(Array.isArray(e.publishConfig.executableFiles)){this.publishConfig.executableFiles=new Set;for(let s of e.publishConfig.executableFiles){if(typeof s!="string"){i.push(new Error("Invalid executable file definition"));continue}this.publishConfig.executableFiles.add(en(s))}}}else this.publishConfig=null;if(typeof e.installConfig=="object"&&e.installConfig!==null){this.installConfig={};for(let s of Object.keys(e.installConfig))s==="hoistingLimits"?typeof e.installConfig.hoistingLimits=="string"?this.installConfig.hoistingLimits=e.installConfig.hoistingLimits:i.push(new Error("Invalid hoisting limits definition")):s=="selfReferences"?typeof e.installConfig.selfReferences=="boolean"?this.installConfig.selfReferences=e.installConfig.selfReferences:i.push(new Error("Invalid selfReferences definition, must be a boolean value")):i.push(new Error(`Unrecognized installConfig key: ${s}`))}else this.installConfig=null;if(typeof e.optionalDependencies=="object"&&e.optionalDependencies!==null)for(let[s,o]of Object.entries(e.optionalDependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=En(s)}catch(g){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=Yt(a,o);this.dependencies.set(l.identHash,l);let c=Yt(a,"unknown"),u=this.ensureDependencyMeta(c);Object.assign(u,{optional:!0})}typeof e.preferUnplugged=="boolean"?this.preferUnplugged=e.preferUnplugged:this.preferUnplugged=null,this.errors=i}getForScope(e){switch(e){case"dependencies":return this.dependencies;case"devDependencies":return this.devDependencies;case"peerDependencies":return this.peerDependencies;default:throw new Error(`Unsupported value ("${e}")`)}}hasConsumerDependency(e){return!!(this.dependencies.has(e.identHash)||this.peerDependencies.has(e.identHash))}hasHardDependency(e){return!!(this.dependencies.has(e.identHash)||this.devDependencies.has(e.identHash))}hasSoftDependency(e){return!!this.peerDependencies.has(e.identHash)}hasDependency(e){return!!(this.hasHardDependency(e)||this.hasSoftDependency(e))}getConditions(){let e=[];return this.os&&this.os.length>0&&e.push(V6("os",this.os)),this.cpu&&this.cpu.length>0&&e.push(V6("cpu",this.cpu)),e.length>0?e.join(" & "):null}isCompatibleWithOS(e){return vA.isManifestFieldCompatible(this.os,e)}isCompatibleWithCPU(e){return vA.isManifestFieldCompatible(this.cpu,e)}ensureDependencyMeta(e){if(e.range!=="unknown"&&!J6.default.valid(e.range))throw new Error(`Invalid meta field range for '${In(e)}'`);let r=St(e),i=e.range!=="unknown"?e.range:null,n=this.dependenciesMeta.get(r);n||this.dependenciesMeta.set(r,n=new Map);let s=n.get(i);return s||n.set(i,s={}),s}ensurePeerDependencyMeta(e){if(e.range!=="unknown")throw new Error(`Invalid meta field range for '${In(e)}'`);let r=St(e),i=this.peerDependenciesMeta.get(r);return i||this.peerDependenciesMeta.set(r,i={}),i}setRawField(e,r,{after:i=[]}={}){let n=new Set(i.filter(s=>Object.prototype.hasOwnProperty.call(this.raw,s)));if(n.size===0||Object.prototype.hasOwnProperty.call(this.raw,e))this.raw[e]=r;else{let s=this.raw,o=this.raw={},a=!1;for(let l of Object.keys(s))o[l]=s[l],a||(n.delete(l),n.size===0&&(o[e]=r,a=!0))}}exportTo(e,{compatibilityMode:r=!0}={}){var s;if(Object.assign(e,this.raw),this.name!==null?e.name=St(this.name):delete e.name,this.version!==null?e.version=this.version:delete e.version,this.os!==null?e.os=this.os:delete e.os,this.cpu!==null?e.cpu=this.cpu:delete e.cpu,this.type!==null?e.type=this.type:delete e.type,this.packageManager!==null?e.packageManager=this.packageManager:delete e.packageManager,this.private?e.private=!0:delete e.private,this.license!==null?e.license=this.license:delete e.license,this.languageName!==null?e.languageName=this.languageName:delete e.languageName,this.main!==null?e.main=this.main:delete e.main,this.module!==null?e.module=this.module:delete e.module,this.browser!==null){let o=this.browser;typeof o=="string"?e.browser=o:o instanceof Map&&(e.browser=Object.assign({},...Array.from(o.keys()).sort().map(a=>({[a]:o.get(a)}))))}else delete e.browser;this.bin.size===1&&this.name!==null&&this.bin.has(this.name.name)?e.bin=this.bin.get(this.name.name):this.bin.size>0?e.bin=Object.assign({},...Array.from(this.bin.keys()).sort().map(o=>({[o]:this.bin.get(o)}))):delete e.bin,this.workspaceDefinitions.length>0?this.raw.workspaces&&!Array.isArray(this.raw.workspaces)?e.workspaces=_(P({},this.raw.workspaces),{packages:this.workspaceDefinitions.map(({pattern:o})=>o)}):e.workspaces=this.workspaceDefinitions.map(({pattern:o})=>o):this.raw.workspaces&&!Array.isArray(this.raw.workspaces)&&Object.keys(this.raw.workspaces).length>0?e.workspaces=this.raw.workspaces:delete e.workspaces;let i=[],n=[];for(let o of this.dependencies.values()){let a=this.dependenciesMeta.get(St(o)),l=!1;if(r&&a){let c=a.get(null);c&&c.optional&&(l=!0)}l?n.push(o):i.push(o)}i.length>0?e.dependencies=Object.assign({},...Ou(i).map(o=>({[St(o)]:o.range}))):delete e.dependencies,n.length>0?e.optionalDependencies=Object.assign({},...Ou(n).map(o=>({[St(o)]:o.range}))):delete e.optionalDependencies,this.devDependencies.size>0?e.devDependencies=Object.assign({},...Ou(this.devDependencies.values()).map(o=>({[St(o)]:o.range}))):delete e.devDependencies,this.peerDependencies.size>0?e.peerDependencies=Object.assign({},...Ou(this.peerDependencies.values()).map(o=>({[St(o)]:o.range}))):delete e.peerDependencies,e.dependenciesMeta={};for(let[o,a]of gn(this.dependenciesMeta.entries(),([l,c])=>l))for(let[l,c]of gn(a.entries(),([u,g])=>u!==null?`0${u}`:"1")){let u=l!==null?In(Yt(En(o),l)):o,g=P({},c);r&&l===null&&delete g.optional,Object.keys(g).length!==0&&(e.dependenciesMeta[u]=g)}if(Object.keys(e.dependenciesMeta).length===0&&delete e.dependenciesMeta,this.peerDependenciesMeta.size>0?e.peerDependenciesMeta=Object.assign({},...gn(this.peerDependenciesMeta.entries(),([o,a])=>o).map(([o,a])=>({[o]:a}))):delete e.peerDependenciesMeta,this.resolutions.length>0?e.resolutions=Object.assign({},...this.resolutions.map(({pattern:o,reference:a})=>({[fw(o)]:a}))):delete e.resolutions,this.files!==null?e.files=Array.from(this.files):delete e.files,this.preferUnplugged!==null?e.preferUnplugged=this.preferUnplugged:delete e.preferUnplugged,this.scripts!==null&&this.scripts.size>0){(s=e.scripts)!=null||(e.scripts={});for(let o of Object.keys(e.scripts))this.scripts.has(o)||delete e.scripts[o];for(let[o,a]of this.scripts.entries())e.scripts[o]=a}else delete e.scripts;return e}},Ze=vA;Ze.fileName="package.json",Ze.allDependencies=["dependencies","devDependencies","peerDependencies"],Ze.hardDependencies=["dependencies","devDependencies"];function W6(t){let e=t.match(/^[ \t]+/m);return e?e[0]:" "}function z6(t){return t.charCodeAt(0)===65279?t.slice(1):t}function en(t){return t.replace(/\\/g,"/")}function Tw(t,{yamlCompatibilityMode:e}){return e?Kv(t):typeof t=="undefined"||typeof t=="boolean"?t:null}function _6(t,e){let r=e.search(/[^!]/);if(r===-1)return"invalid";let i=r%2==0?"":"!",n=e.slice(r);return`${i}${t}=${n}`}function V6(t,e){return e.length===1?_6(t,e[0]):`(${e.map(r=>_6(t,r)).join(" | ")})`}var e9=ie($6()),Ow=ie(ml());var t9=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],r9=80,NFe=new Set([z.FETCH_NOT_CACHED,z.UNUSED_CACHE_ENTRY]),LFe=5,SA=Ow.default.GITHUB_ACTIONS?{start:t=>`::group::${t} +`,end:t=>`::endgroup:: +`}:Ow.default.TRAVIS?{start:t=>`travis_fold:start:${t} +`,end:t=>`travis_fold:end:${t} +`}:Ow.default.GITLAB?{start:t=>`section_start:${Math.floor(Date.now()/1e3)}:${t.toLowerCase().replace(/\W+/g,"_")}[collapsed=true]\r${t} +`,end:t=>`section_end:${Math.floor(Date.now()/1e3)}:${t.toLowerCase().replace(/\W+/g,"_")}\r`}:null,i9=new Date,TFe=["iTerm.app","Apple_Terminal"].includes(process.env.TERM_PROGRAM)||!!process.env.WT_SESSION,MFe=t=>t,Kw=MFe({patrick:{date:[17,3],chars:["\u{1F340}","\u{1F331}"],size:40},simba:{date:[19,7],chars:["\u{1F981}","\u{1F334}"],size:40},jack:{date:[31,10],chars:["\u{1F383}","\u{1F987}"],size:40},hogsfather:{date:[31,12],chars:["\u{1F389}","\u{1F384}"],size:40},default:{chars:["=","-"],size:80}}),OFe=TFe&&Object.keys(Kw).find(t=>{let e=Kw[t];return!(e.date&&(e.date[0]!==i9.getDate()||e.date[1]!==i9.getMonth()+1))})||"default";function n9(t,{configuration:e,json:r}){if(!e.get("enableMessageNames"))return"";let n=KE(t===null?0:t);return!r&&t===null?Ve(e,n,"grey"):n}function eD(t,{configuration:e,json:r}){let i=n9(t,{configuration:e,json:r});if(!i||t===null||t===z.UNNAMED)return i;let n=z[t],s=`https://yarnpkg.com/advanced/error-codes#${i}---${n}`.toLowerCase();return Ku(e,i,s)}var Fe=class extends Xi{constructor({configuration:e,stdout:r,json:i=!1,includeFooter:n=!0,includeLogs:s=!i,includeInfos:o=s,includeWarnings:a=s,forgettableBufferSize:l=LFe,forgettableNames:c=new Set}){super();this.uncommitted=new Set;this.cacheHitCount=0;this.cacheMissCount=0;this.lastCacheMiss=null;this.warningCount=0;this.errorCount=0;this.startTime=Date.now();this.indent=0;this.progress=new Map;this.progressTime=0;this.progressFrame=0;this.progressTimeout=null;this.forgettableLines=[];Cp(this,{configuration:e}),this.configuration=e,this.forgettableBufferSize=l,this.forgettableNames=new Set([...c,...NFe]),this.includeFooter=n,this.includeInfos=o,this.includeWarnings=a,this.json=i,this.stdout=r;let u=this.configuration.get("progressBarStyle")||OFe;if(!Object.prototype.hasOwnProperty.call(Kw,u))throw new Error("Assertion failed: Invalid progress bar style");this.progressStyle=Kw[u];let g="\u27A4 YN0000: \u250C ".length,f=Math.max(0,Math.min(process.stdout.columns-g,80));this.progressMaxScaledSize=Math.floor(this.progressStyle.size*f/80)}static async start(e,r){let i=new this(e),n=process.emitWarning;process.emitWarning=(s,o)=>{if(typeof s!="string"){let l=s;s=l.message,o=o!=null?o:l.name}let a=typeof o!="undefined"?`${o}: ${s}`:s;i.reportWarning(z.UNNAMED,a)};try{await r(i)}catch(s){i.reportExceptionOnce(s)}finally{await i.finalize(),process.emitWarning=n}return i}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(e){this.cacheHitCount+=1}reportCacheMiss(e,r){this.lastCacheMiss=e,this.cacheMissCount+=1,typeof r!="undefined"&&!this.configuration.get("preferAggregateCacheInfo")&&this.reportInfo(z.FETCH_NOT_CACHED,r)}startTimerSync(e,r,i){let n=typeof r=="function"?{}:r,s=typeof r=="function"?r:i,o={committed:!1,action:()=>{this.reportInfo(null,`\u250C ${e}`),this.indent+=1,SA!==null&&!this.json&&this.includeInfos&&this.stdout.write(SA.start(e))}};n.skipIfEmpty?this.uncommitted.add(o):(o.action(),o.committed=!0);let a=Date.now();try{return s()}catch(l){throw this.reportExceptionOnce(l),l}finally{let l=Date.now();this.uncommitted.delete(o),o.committed&&(this.indent-=1,SA!==null&&!this.json&&this.includeInfos&&this.stdout.write(SA.end(e)),this.configuration.get("enableTimers")&&l-a>200?this.reportInfo(null,`\u2514 Completed in ${Ve(this.configuration,l-a,Le.DURATION)}`):this.reportInfo(null,"\u2514 Completed"))}}async startTimerPromise(e,r,i){let n=typeof r=="function"?{}:r,s=typeof r=="function"?r:i,o={committed:!1,action:()=>{this.reportInfo(null,`\u250C ${e}`),this.indent+=1,SA!==null&&!this.json&&this.includeInfos&&this.stdout.write(SA.start(e))}};n.skipIfEmpty?this.uncommitted.add(o):(o.action(),o.committed=!0);let a=Date.now();try{return await s()}catch(l){throw this.reportExceptionOnce(l),l}finally{let l=Date.now();this.uncommitted.delete(o),o.committed&&(this.indent-=1,SA!==null&&!this.json&&this.includeInfos&&this.stdout.write(SA.end(e)),this.configuration.get("enableTimers")&&l-a>200?this.reportInfo(null,`\u2514 Completed in ${Ve(this.configuration,l-a,Le.DURATION)}`):this.reportInfo(null,"\u2514 Completed"))}}async startCacheReport(e){let r=this.configuration.get("preferAggregateCacheInfo")?{cacheHitCount:this.cacheHitCount,cacheMissCount:this.cacheMissCount}:null;try{return await e()}catch(i){throw this.reportExceptionOnce(i),i}finally{r!==null&&this.reportCacheChanges(r)}}reportSeparator(){this.indent===0?this.writeLineWithForgettableReset(""):this.reportInfo(null,"")}reportInfo(e,r){if(!this.includeInfos)return;this.commit();let i=this.formatNameWithHyperlink(e),n=i?`${i}: `:"",s=`${Ve(this.configuration,"\u27A4","blueBright")} ${n}${this.formatIndent()}${r}`;if(this.json)this.reportJson({type:"info",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:r});else if(this.forgettableNames.has(e))if(this.forgettableLines.push(s),this.forgettableLines.length>this.forgettableBufferSize){for(;this.forgettableLines.length>this.forgettableBufferSize;)this.forgettableLines.shift();this.writeLines(this.forgettableLines,{truncate:!0})}else this.writeLine(s,{truncate:!0});else this.writeLineWithForgettableReset(s)}reportWarning(e,r){if(this.warningCount+=1,!this.includeWarnings)return;this.commit();let i=this.formatNameWithHyperlink(e),n=i?`${i}: `:"";this.json?this.reportJson({type:"warning",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:r}):this.writeLineWithForgettableReset(`${Ve(this.configuration,"\u27A4","yellowBright")} ${n}${this.formatIndent()}${r}`)}reportError(e,r){this.errorCount+=1,this.commit();let i=this.formatNameWithHyperlink(e),n=i?`${i}: `:"";this.json?this.reportJson({type:"error",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:r}):this.writeLineWithForgettableReset(`${Ve(this.configuration,"\u27A4","redBright")} ${n}${this.formatIndent()}${r}`,{truncate:!1})}reportProgress(e){let r=!1,i=Promise.resolve().then(async()=>{let s={progress:0,title:void 0};this.progress.set(e,{definition:s,lastScaledSize:-1}),this.refreshProgress(-1);for await(let{progress:o,title:a}of e)r||s.progress===o&&s.title===a||(s.progress=o,s.title=a,this.refreshProgress());n()}),n=()=>{r||(r=!0,this.progress.delete(e),this.refreshProgress(1))};return _(P({},i),{stop:n})}reportJson(e){this.json&&this.writeLineWithForgettableReset(`${JSON.stringify(e)}`)}async finalize(){if(!this.includeFooter)return;let e="";this.errorCount>0?e="Failed with errors":this.warningCount>0?e="Done with warnings":e="Done";let r=Ve(this.configuration,Date.now()-this.startTime,Le.DURATION),i=this.configuration.get("enableTimers")?`${e} in ${r}`:e;this.errorCount>0?this.reportError(z.UNNAMED,i):this.warningCount>0?this.reportWarning(z.UNNAMED,i):this.reportInfo(z.UNNAMED,i)}writeLine(e,{truncate:r}={}){this.clearProgress({clear:!0}),this.stdout.write(`${this.truncate(e,{truncate:r})} +`),this.writeProgress()}writeLineWithForgettableReset(e,{truncate:r}={}){this.forgettableLines=[],this.writeLine(e,{truncate:r})}writeLines(e,{truncate:r}={}){this.clearProgress({delta:e.length});for(let i of e)this.stdout.write(`${this.truncate(i,{truncate:r})} +`);this.writeProgress()}reportCacheChanges({cacheHitCount:e,cacheMissCount:r}){let i=this.cacheHitCount-e,n=this.cacheMissCount-r;if(i===0&&n===0)return;let s="";this.cacheHitCount>1?s+=`${this.cacheHitCount} packages were already cached`:this.cacheHitCount===1?s+=" - one package was already cached":s+="No packages were cached",this.cacheHitCount>0?this.cacheMissCount>1?s+=`, ${this.cacheMissCount} had to be fetched`:this.cacheMissCount===1&&(s+=`, one had to be fetched (${lt(this.configuration,this.lastCacheMiss)})`):this.cacheMissCount>1?s+=` - ${this.cacheMissCount} packages had to be fetched`:this.cacheMissCount===1&&(s+=` - one package had to be fetched (${lt(this.configuration,this.lastCacheMiss)})`),this.reportInfo(z.FETCH_NOT_CACHED,s)}commit(){let e=this.uncommitted;this.uncommitted=new Set;for(let r of e)r.committed=!0,r.action()}clearProgress({delta:e=0,clear:r=!1}){!this.configuration.get("enableProgressBars")||this.json||this.progress.size+e>0&&(this.stdout.write(`[${this.progress.size+e}A`),(e>0||r)&&this.stdout.write(""))}writeProgress(){if(!this.configuration.get("enableProgressBars")||this.json||(this.progressTimeout!==null&&clearTimeout(this.progressTimeout),this.progressTimeout=null,this.progress.size===0))return;let e=Date.now();e-this.progressTime>r9&&(this.progressFrame=(this.progressFrame+1)%t9.length,this.progressTime=e);let r=t9[this.progressFrame];for(let i of this.progress.values()){let n=this.progressStyle.chars[0].repeat(i.lastScaledSize),s=this.progressStyle.chars[1].repeat(this.progressMaxScaledSize-i.lastScaledSize),o=this.formatName(null),a=o?`${o}: `:"";this.stdout.write(`${Ve(this.configuration,"\u27A4","blueBright")} ${a}${r} ${n}${s} +`)}this.progressTimeout=setTimeout(()=>{this.refreshProgress()},r9)}refreshProgress(e=0){let r=!1;if(this.progress.size===0)r=!0;else for(let i of this.progress.values()){let n=Math.trunc(this.progressMaxScaledSize*i.definition.progress),s=i.lastScaledSize;if(i.lastScaledSize=n,n!==s){r=!0;break}}r&&(this.clearProgress({delta:e}),this.writeProgress())}truncate(e,{truncate:r}={}){return this.configuration.get("enableProgressBars")||(r=!1),typeof r=="undefined"&&(r=this.configuration.get("preferTruncatedLines")),r&&(e=(0,e9.default)(e,0,process.stdout.columns-1)),e}formatName(e){return n9(e,{configuration:this.configuration,json:this.json})}formatNameWithHyperlink(e){return eD(e,{configuration:this.configuration,json:this.json})}formatIndent(){return"\u2502 ".repeat(this.indent)}};var Zr="3.1.1";var tn;(function(n){n.Yarn1="Yarn Classic",n.Yarn2="Yarn",n.Npm="npm",n.Pnpm="pnpm"})(tn||(tn={}));async function ba(t,e,r,i=[]){if(process.platform==="win32"){let n=`@goto #_undefined_# 2>NUL || @title %COMSPEC% & @setlocal & @"${r}" ${i.map(s=>`"${s.replace('"','""')}"`).join(" ")} %*`;await T.writeFilePromise(v.format({dir:t,name:e,ext:".cmd"}),n)}await T.writeFilePromise(v.join(t,e),`#!/bin/sh +exec "${r}" ${i.map(n=>`'${n.replace(/'/g,`'"'"'`)}'`).join(" ")} "$@" +`,{mode:493})}async function a9(t){let e=await Ze.tryFind(t);if(e==null?void 0:e.packageManager){let i=Qy(e.packageManager);if(i==null?void 0:i.name){let n=`found ${JSON.stringify({packageManager:e.packageManager})} in manifest`,[s]=i.reference.split(".");switch(i.name){case"yarn":return{packageManager:Number(s)===1?tn.Yarn1:tn.Yarn2,reason:n};case"npm":return{packageManager:tn.Npm,reason:n};case"pnpm":return{packageManager:tn.Pnpm,reason:n}}}}let r;try{r=await T.readFilePromise(v.join(t,wt.lockfile),"utf8")}catch{}return r!==void 0?r.match(/^__metadata:$/m)?{packageManager:tn.Yarn2,reason:'"__metadata" key found in yarn.lock'}:{packageManager:tn.Yarn1,reason:'"__metadata" key not found in yarn.lock, must be a Yarn classic lockfile'}:T.existsSync(v.join(t,"package-lock.json"))?{packageManager:tn.Npm,reason:`found npm's "package-lock.json" lockfile`}:T.existsSync(v.join(t,"pnpm-lock.yaml"))?{packageManager:tn.Pnpm,reason:`found pnpm's "pnpm-lock.yaml" lockfile`}:null}async function Vp({project:t,locator:e,binFolder:r,lifecycleScript:i}){var l,c;let n={};for(let[u,g]of Object.entries(process.env))typeof g!="undefined"&&(n[u.toLowerCase()!=="path"?u:"PATH"]=g);let s=M.fromPortablePath(r);n.BERRY_BIN_FOLDER=M.fromPortablePath(s);let o=process.env.COREPACK_ROOT?M.join(process.env.COREPACK_ROOT,"dist/yarn.js"):process.argv[1];if(await Promise.all([ba(r,"node",process.execPath),...Zr!==null?[ba(r,"run",process.execPath,[o,"run"]),ba(r,"yarn",process.execPath,[o]),ba(r,"yarnpkg",process.execPath,[o]),ba(r,"node-gyp",process.execPath,[o,"run","--top-level","node-gyp"])]:[]]),t&&(n.INIT_CWD=M.fromPortablePath(t.configuration.startingCwd),n.PROJECT_CWD=M.fromPortablePath(t.cwd)),n.PATH=n.PATH?`${s}${M.delimiter}${n.PATH}`:`${s}`,n.npm_execpath=`${s}${M.sep}yarn`,n.npm_node_execpath=`${s}${M.sep}node`,e){if(!t)throw new Error("Assertion failed: Missing project");let u=t.tryWorkspaceByLocator(e),g=u?(l=u.manifest.version)!=null?l:"":(c=t.storedPackages.get(e.locatorHash).version)!=null?c:"";n.npm_package_name=St(e),n.npm_package_version=g}let a=Zr!==null?`yarn/${Zr}`:`yarn/${mu("@yarnpkg/core").version}-core`;return n.npm_config_user_agent=`${a} npm/? node/${process.versions.node} ${process.platform} ${process.arch}`,i&&(n.npm_lifecycle_event=i),t&&await t.configuration.triggerHook(u=>u.setupScriptEnvironment,t,n,async(u,g,f)=>await ba(r,kr(u),g,f)),n}var KFe=2,UFe=(0,o9.default)(KFe);async function HFe(t,e,{configuration:r,report:i,workspace:n=null,locator:s=null}){await UFe(async()=>{await T.mktempPromise(async o=>{let a=v.join(o,"pack.log"),l=null,{stdout:c,stderr:u}=r.getSubprocessStreams(a,{prefix:M.fromPortablePath(t),report:i}),g=s&&Io(s)?lp(s):s,f=g?is(g):"an external project";c.write(`Packing ${f} from sources +`);let h=await a9(t),p;h!==null?(c.write(`Using ${h.packageManager} for bootstrap. Reason: ${h.reason} + +`),p=h.packageManager):(c.write(`No package manager configuration detected; defaulting to Yarn + +`),p=tn.Yarn2),await T.mktempPromise(async d=>{let m=await Vp({binFolder:d}),B=new Map([[tn.Yarn1,async()=>{let R=n!==null?["workspace",n]:[],H=await to("yarn",["set","version","classic","--only-if-needed"],{cwd:t,env:m,stdin:l,stdout:c,stderr:u,end:Pn.ErrorCode});if(H.code!==0)return H.code;await T.appendFilePromise(v.join(t,".npmignore"),`/.yarn +`),c.write(` +`);let L=await to("yarn",["install"],{cwd:t,env:m,stdin:l,stdout:c,stderr:u,end:Pn.ErrorCode});if(L.code!==0)return L.code;c.write(` +`);let K=await to("yarn",[...R,"pack","--filename",M.fromPortablePath(e)],{cwd:t,env:m,stdin:l,stdout:c,stderr:u});return K.code!==0?K.code:0}],[tn.Yarn2,async()=>{let R=n!==null?["workspace",n]:[];m.YARN_ENABLE_INLINE_BUILDS="1";let H=v.join(t,wt.lockfile);await T.existsPromise(H)||await T.writeFilePromise(H,"");let L=await to("yarn",[...R,"pack","--install-if-needed","--filename",M.fromPortablePath(e)],{cwd:t,env:m,stdin:l,stdout:c,stderr:u});return L.code!==0?L.code:0}],[tn.Npm,async()=>{if(n!==null){let A=new cc.PassThrough,V=Cu(A);A.pipe(c,{end:!1});let W=await to("npm",["--version"],{cwd:t,env:m,stdin:l,stdout:A,stderr:u,end:Pn.Never});if(A.end(),W.code!==0)return c.end(),u.end(),W.code;let X=(await V).toString().trim();if(!lc(X,">=7.x")){let F=Eo(null,"npm"),D=Yt(F,X),he=Yt(F,">=7.x");throw new Error(`Workspaces aren't supported by ${Xt(r,D)}; please upgrade to ${Xt(r,he)} (npm has been detected as the primary package manager for ${Ve(r,t,Le.PATH)})`)}}let R=n!==null?["--workspace",n]:[];delete m.npm_config_user_agent;let H=await to("npm",["install"],{cwd:t,env:m,stdin:l,stdout:c,stderr:u,end:Pn.ErrorCode});if(H.code!==0)return H.code;let L=new cc.PassThrough,K=Cu(L);L.pipe(c);let J=await to("npm",["pack","--silent",...R],{cwd:t,env:m,stdin:l,stdout:L,stderr:u});if(J.code!==0)return J.code;let ne=(await K).toString().trim().replace(/^.*\n/s,""),q=v.resolve(t,M.toPortablePath(ne));return await T.renamePromise(q,e),0}]]).get(p);if(typeof B=="undefined")throw new Error("Assertion failed: Unsupported workflow");let b=await B();if(!(b===0||typeof b=="undefined"))throw T.detachTemp(o),new nt(z.PACKAGE_PREPARATION_FAILED,`Packing the package failed (exit code ${b}, logs can be found here: ${Ve(r,a,Le.PATH)})`)})})})}async function GFe(t,e,{project:r}){let i=r.tryWorkspaceByLocator(t);if(i!==null)return tD(i,e);let n=r.storedPackages.get(t.locatorHash);if(!n)throw new Error(`Package for ${lt(r.configuration,t)} not found in the project`);return await Jn.openPromise(async s=>{let o=r.configuration,a=r.configuration.getLinkers(),l={project:r,report:new Fe({stdout:new cc.PassThrough,configuration:o})},c=a.find(h=>h.supportsPackage(n,l));if(!c)throw new Error(`The package ${lt(r.configuration,n)} isn't supported by any of the available linkers`);let u=await c.findPackageLocation(n,l),g=new Ft(u,{baseFs:s});return(await Ze.find(Se.dot,{baseFs:g})).scripts.has(e)},{libzip:await $i()})}async function Uw(t,e,r,{cwd:i,project:n,stdin:s,stdout:o,stderr:a}){return await T.mktempPromise(async l=>{let{manifest:c,env:u,cwd:g}=await A9(t,{project:n,binFolder:l,cwd:i,lifecycleScript:e}),f=c.scripts.get(e);if(typeof f=="undefined")return 1;let h=async()=>await Fw(f,r,{cwd:g,env:u,stdin:s,stdout:o,stderr:a});return await(await n.configuration.reduceHook(d=>d.wrapScriptExecution,h,n,t,e,{script:f,args:r,cwd:g,env:u,stdin:s,stdout:o,stderr:a}))()})}async function rD(t,e,r,{cwd:i,project:n,stdin:s,stdout:o,stderr:a}){return await T.mktempPromise(async l=>{let{env:c,cwd:u}=await A9(t,{project:n,binFolder:l,cwd:i});return await Fw(e,r,{cwd:u,env:c,stdin:s,stdout:o,stderr:a})})}async function jFe(t,{binFolder:e,cwd:r,lifecycleScript:i}){let n=await Vp({project:t.project,locator:t.anchoredLocator,binFolder:e,lifecycleScript:i});return await Promise.all(Array.from(await l9(t),([s,[,o]])=>ba(e,kr(s),process.execPath,[o]))),typeof r=="undefined"&&(r=v.dirname(await T.realpathPromise(v.join(t.cwd,"package.json")))),{manifest:t.manifest,binFolder:e,env:n,cwd:r}}async function A9(t,{project:e,binFolder:r,cwd:i,lifecycleScript:n}){let s=e.tryWorkspaceByLocator(t);if(s!==null)return jFe(s,{binFolder:r,cwd:i,lifecycleScript:n});let o=e.storedPackages.get(t.locatorHash);if(!o)throw new Error(`Package for ${lt(e.configuration,t)} not found in the project`);return await Jn.openPromise(async a=>{let l=e.configuration,c=e.configuration.getLinkers(),u={project:e,report:new Fe({stdout:new cc.PassThrough,configuration:l})},g=c.find(m=>m.supportsPackage(o,u));if(!g)throw new Error(`The package ${lt(e.configuration,o)} isn't supported by any of the available linkers`);let f=await Vp({project:e,locator:t,binFolder:r,lifecycleScript:n});await Promise.all(Array.from(await Hw(t,{project:e}),([m,[,I]])=>ba(r,kr(m),process.execPath,[I])));let h=await g.findPackageLocation(o,u),p=new Ft(h,{baseFs:a}),d=await Ze.find(Se.dot,{baseFs:p});return typeof i=="undefined"&&(i=h),{manifest:d,binFolder:r,env:f,cwd:i}},{libzip:await $i()})}async function c9(t,e,r,{cwd:i,stdin:n,stdout:s,stderr:o}){return await Uw(t.anchoredLocator,e,r,{cwd:i,project:t.project,stdin:n,stdout:s,stderr:o})}function tD(t,e){return t.manifest.scripts.has(e)}async function u9(t,e,{cwd:r,report:i}){let{configuration:n}=t.project,s=null;await T.mktempPromise(async o=>{let a=v.join(o,`${e}.log`),l=`# This file contains the result of Yarn calling the "${e}" lifecycle script inside a workspace ("${M.fromPortablePath(t.cwd)}") +`,{stdout:c,stderr:u}=n.getSubprocessStreams(a,{report:i,prefix:lt(n,t.anchoredLocator),header:l});i.reportInfo(z.LIFECYCLE_SCRIPT,`Calling the "${e}" lifecycle script`);let g=await c9(t,e,[],{cwd:r,stdin:s,stdout:c,stderr:u});if(c.end(),u.end(),g!==0)throw T.detachTemp(o),new nt(z.LIFECYCLE_SCRIPT,`${(0,s9.default)(e)} script failed (exit code ${Ve(n,g,Le.NUMBER)}, logs can be found here: ${Ve(n,a,Le.PATH)}); run ${Ve(n,`yarn ${e}`,Le.CODE)} to investigate`)})}async function YFe(t,e,r){tD(t,e)&&await u9(t,e,r)}async function Hw(t,{project:e}){let r=e.configuration,i=new Map,n=e.storedPackages.get(t.locatorHash);if(!n)throw new Error(`Package for ${lt(r,t)} not found in the project`);let s=new cc.Writable,o=r.getLinkers(),a={project:e,report:new Fe({configuration:r,stdout:s})},l=new Set([t.locatorHash]);for(let u of n.dependencies.values()){let g=e.storedResolutions.get(u.descriptorHash);if(!g)throw new Error(`Assertion failed: The resolution (${Xt(r,u)}) should have been registered`);l.add(g)}let c=await Promise.all(Array.from(l,async u=>{let g=e.storedPackages.get(u);if(!g)throw new Error(`Assertion failed: The package (${u}) should have been registered`);if(g.bin.size===0)return kl.skip;let f=o.find(p=>p.supportsPackage(g,a));if(!f)return kl.skip;let h=null;try{h=await f.findPackageLocation(g,a)}catch(p){if(p.code==="LOCATOR_NOT_INSTALLED")return kl.skip;throw p}return{dependency:g,packageLocation:h}}));for(let u of c){if(u===kl.skip)continue;let{dependency:g,packageLocation:f}=u;for(let[h,p]of g.bin)i.set(h,[g,M.fromPortablePath(v.resolve(f,p))])}return i}async function l9(t){return await Hw(t.anchoredLocator,{project:t.project})}async function g9(t,e,r,{cwd:i,project:n,stdin:s,stdout:o,stderr:a,nodeArgs:l=[],packageAccessibleBinaries:c}){c!=null||(c=await Hw(t,{project:n}));let u=c.get(e);if(!u)throw new Error(`Binary not found (${e}) for ${lt(n.configuration,t)}`);return await T.mktempPromise(async g=>{let[,f]=u,h=await Vp({project:n,locator:t,binFolder:g});await Promise.all(Array.from(c,([d,[,m]])=>ba(h.BERRY_BIN_FOLDER,kr(d),process.execPath,[m])));let p;try{p=await to(process.execPath,[...l,f,...r],{cwd:i,env:h,stdin:s,stdout:o,stderr:a})}finally{await T.removePromise(h.BERRY_BIN_FOLDER)}return p.code})}async function qFe(t,e,r,{cwd:i,stdin:n,stdout:s,stderr:o,packageAccessibleBinaries:a}){return await g9(t.anchoredLocator,e,r,{project:t.project,cwd:i,stdin:n,stdout:s,stderr:o,packageAccessibleBinaries:a})}var Ai={};it(Ai,{convertToZip:()=>lTe,extractArchiveTo:()=>uTe,makeArchiveFromDirectory:()=>ATe});var d_=ie(require("stream")),C_=ie(Z7());var u_=ie(require("os")),g_=ie(c_()),f_=ie(require("worker_threads")),IR=class{constructor(e){this.source=e;this.pool=[];this.queue=new g_.default({concurrency:Math.max(1,(0,u_.cpus)().length)});let r=setTimeout(()=>{if(!(this.queue.size!==0||this.queue.pending!==0)){for(let i of this.pool)i.terminate();this.pool=[]}},1e3).unref();this.queue.on("idle",()=>{r.refresh()})}run(e){return this.queue.add(()=>{var i;let r=(i=this.pool.pop())!=null?i:new f_.Worker(this.source,{eval:!0,execArgv:[...process.execArgv,"--unhandled-rejections=strict"]});return r.ref(),new Promise((n,s)=>{let o=a=>{a!==0&&s(new Error(`Worker exited with code ${a}`))};r.once("message",a=>{this.pool.push(r),r.unref(),r.off("error",s),r.off("exit",o),n(a)}),r.once("error",s),r.once("exit",o),r.postMessage(e)})})}};var m_=ie(p_());async function ATe(t,{baseFs:e=new Wt,prefixPath:r=Se.root,compressionLevel:i,inMemory:n=!1}={}){let s=await $i(),o;if(n)o=new Jr(null,{libzip:s,level:i});else{let l=await T.mktempPromise(),c=v.join(l,"archive.zip");o=new Jr(c,{create:!0,libzip:s,level:i})}let a=v.resolve(Se.root,r);return await o.copyPromise(a,t,{baseFs:e,stableTime:!0,stableSort:!0}),o}var E_;async function lTe(t,e){let r=await T.mktempPromise(),i=v.join(r,"archive.zip");return E_||(E_=new IR((0,m_.getContent)())),await E_.run({tmpFile:i,tgz:t,opts:e}),new Jr(i,{libzip:await $i(),level:e.compressionLevel})}async function*cTe(t){let e=new C_.default.Parse,r=new d_.PassThrough({objectMode:!0,autoDestroy:!0,emitClose:!0});e.on("entry",i=>{r.write(i)}),e.on("error",i=>{r.destroy(i)}),e.on("close",()=>{r.destroyed||r.end()}),e.end(t);for await(let i of r){let n=i;yield n,n.resume()}}async function uTe(t,e,{stripComponents:r=0,prefixPath:i=Se.dot}={}){var s,o;function n(a){if(a.path[0]==="/")return!0;let l=a.path.split(/\//g);return!!(l.some(c=>c==="..")||l.length<=r)}for await(let a of cTe(t)){if(n(a))continue;let l=v.normalize(M.toPortablePath(a.path)).replace(/\/$/,"").split(/\//g);if(l.length<=r)continue;let c=l.slice(r).join("/"),u=v.join(i,c),g=420;switch((a.type==="Directory"||(((s=a.mode)!=null?s:0)&73)!=0)&&(g|=73),a.type){case"Directory":e.mkdirpSync(v.dirname(u),{chmod:493,utimes:[mr.SAFE_TIME,mr.SAFE_TIME]}),e.mkdirSync(u,{mode:g}),e.utimesSync(u,mr.SAFE_TIME,mr.SAFE_TIME);break;case"OldFile":case"File":e.mkdirpSync(v.dirname(u),{chmod:493,utimes:[mr.SAFE_TIME,mr.SAFE_TIME]}),e.writeFileSync(u,await Cu(a),{mode:g}),e.utimesSync(u,mr.SAFE_TIME,mr.SAFE_TIME);break;case"SymbolicLink":e.mkdirpSync(v.dirname(u),{chmod:493,utimes:[mr.SAFE_TIME,mr.SAFE_TIME]}),e.symlinkSync(a.linkpath,u),(o=e.lutimesSync)==null||o.call(e,u,mr.SAFE_TIME,mr.SAFE_TIME);break}}return e}var Hs={};it(Hs,{emitList:()=>gTe,emitTree:()=>b_,treeNodeToJson:()=>Q_,treeNodeToTreeify:()=>B_});var w_=ie(y_());function B_(t,{configuration:e}){let r={},i=(n,s)=>{let o=Array.isArray(n)?n.entries():Object.entries(n);for(let[a,{label:l,value:c,children:u}]of o){let g=[];typeof l!="undefined"&&g.push(Py(e,l,Gl.BOLD)),typeof c!="undefined"&&g.push(Ve(e,c[0],c[1])),g.length===0&&g.push(Py(e,`${a}`,Gl.BOLD));let f=g.join(": "),h=s[f]={};typeof u!="undefined"&&i(u,h)}};if(typeof t.children=="undefined")throw new Error("The root node must only contain children");return i(t.children,r),r}function Q_(t){let e=r=>{var s;if(typeof r.children=="undefined"){if(typeof r.value=="undefined")throw new Error("Assertion failed: Expected a value to be set if the children are missing");return Uu(r.value[0],r.value[1])}let i=Array.isArray(r.children)?r.children.entries():Object.entries((s=r.children)!=null?s:{}),n=Array.isArray(r.children)?[]:{};for(let[o,a]of i)n[o]=e(a);return typeof r.value=="undefined"?n:{value:Uu(r.value[0],r.value[1]),children:n}};return e(t)}function gTe(t,{configuration:e,stdout:r,json:i}){let n=t.map(s=>({value:s}));b_({children:n},{configuration:e,stdout:r,json:i})}function b_(t,{configuration:e,stdout:r,json:i,separators:n=0}){var o;if(i){let a=Array.isArray(t.children)?t.children.values():Object.values((o=t.children)!=null?o:{});for(let l of a)r.write(`${JSON.stringify(Q_(l))} +`);return}let s=(0,w_.asTree)(B_(t,{configuration:e}),!1,!1);if(n>=1&&(s=s.replace(/^([├└]─)/gm,`\u2502 +$1`).replace(/^│\n/,"")),n>=2)for(let a=0;a<2;++a)s=s.replace(/^([│ ].{2}[├│ ].{2}[^\n]+\n)(([│ ]).{2}[├└].{2}[^\n]*\n[│ ].{2}[│ ].{2}[├└]─)/gm,`$1$3 \u2502 +$2`).replace(/^│\n/,"");if(n>=3)throw new Error("Only the first two levels are accepted by treeUtils.emitTree");r.write(s)}var v_=ie(require("crypto")),BR=ie(require("fs"));var fTe=8,Qt=class{constructor(e,{configuration:r,immutable:i=r.get("enableImmutableCache"),check:n=!1}){this.markedFiles=new Set;this.mutexes=new Map;this.cacheId=`-${(0,v_.randomBytes)(8).toString("hex")}.tmp`;this.configuration=r,this.cwd=e,this.immutable=i,this.check=n;let s=r.get("cacheKeyOverride");if(s!==null)this.cacheKey=`${s}`;else{let o=r.get("compressionLevel"),a=o!==pl?`c${o}`:"";this.cacheKey=[fTe,a].join("")}}static async find(e,{immutable:r,check:i}={}){let n=new Qt(e.get("cacheFolder"),{configuration:e,immutable:r,check:i});return await n.setup(),n}get mirrorCwd(){if(!this.configuration.get("enableMirror"))return null;let e=`${this.configuration.get("globalFolder")}/cache`;return e!==this.cwd?e:null}getVersionFilename(e){return`${Mu(e)}-${this.cacheKey}.zip`}getChecksumFilename(e,r){let n=hTe(r).slice(0,10);return`${Mu(e)}-${n}.zip`}getLocatorPath(e,r,i={}){var s;return this.mirrorCwd===null||((s=i.unstablePackages)==null?void 0:s.has(e.locatorHash))?v.resolve(this.cwd,this.getVersionFilename(e)):r===null||QR(r)!==this.cacheKey?null:v.resolve(this.cwd,this.getChecksumFilename(e,r))}getLocatorMirrorPath(e){let r=this.mirrorCwd;return r!==null?v.resolve(r,this.getVersionFilename(e)):null}async setup(){if(!this.configuration.get("enableGlobalCache"))if(this.immutable){if(!await T.existsPromise(this.cwd))throw new nt(z.IMMUTABLE_CACHE,"Cache path does not exist.")}else{await T.mkdirPromise(this.cwd,{recursive:!0});let e=v.resolve(this.cwd,".gitignore");await T.changeFilePromise(e,`/.gitignore +*.flock +*.tmp +`)}(this.mirrorCwd||!this.immutable)&&await T.mkdirPromise(this.mirrorCwd||this.cwd,{recursive:!0})}async fetchPackageFromCache(e,r,a){var l=a,{onHit:i,onMiss:n,loader:s}=l,o=qr(l,["onHit","onMiss","loader"]);var A;let c=this.getLocatorMirrorPath(e),u=new Wt,g=()=>{let V=new Jr(null,{libzip:H}),W=v.join(Se.root,Lx(e));return V.mkdirSync(W,{recursive:!0}),V.writeJsonSync(v.join(W,wt.manifest),{name:St(e),mocked:!0}),V},f=async(V,W=null)=>{let X=!o.skipIntegrityCheck||!r?`${this.cacheKey}/${await Ey(V)}`:r;if(W!==null){let F=!o.skipIntegrityCheck||!r?`${this.cacheKey}/${await Ey(W)}`:r;if(X!==F)throw new nt(z.CACHE_CHECKSUM_MISMATCH,"The remote archive doesn't match the local checksum - has the local cache been corrupted?")}if(r!==null&&X!==r){let F;switch(this.check?F="throw":QR(r)!==QR(X)?F="update":F=this.configuration.get("checksumBehavior"),F){case"ignore":return r;case"update":return X;default:case"throw":throw new nt(z.CACHE_CHECKSUM_MISMATCH,"The remote archive doesn't match the expected checksum")}}return X},h=async V=>{if(!s)throw new Error(`Cache check required but no loader configured for ${lt(this.configuration,e)}`);let W=await s(),X=W.getRealPath();return W.saveAndClose(),await T.chmodPromise(X,420),await f(V,X)},p=async()=>{if(c===null||!await T.existsPromise(c)){let V=await s(),W=V.getRealPath();return V.saveAndClose(),{source:"loader",path:W}}return{source:"mirror",path:c}},d=async()=>{if(!s)throw new Error(`Cache entry required but missing for ${lt(this.configuration,e)}`);if(this.immutable)throw new nt(z.IMMUTABLE_CACHE,`Cache entry required but missing for ${lt(this.configuration,e)}`);let{path:V,source:W}=await p(),X=await f(V),F=this.getLocatorPath(e,X,o);if(!F)throw new Error("Assertion failed: Expected the cache path to be available");let D=[];W!=="mirror"&&c!==null&&D.push(async()=>{let pe=`${c}${this.cacheId}`;await T.copyFilePromise(V,pe,BR.default.constants.COPYFILE_FICLONE),await T.chmodPromise(pe,420),await T.renamePromise(pe,c)}),(!o.mirrorWriteOnly||c===null)&&D.push(async()=>{let pe=`${F}${this.cacheId}`;await T.copyFilePromise(V,pe,BR.default.constants.COPYFILE_FICLONE),await T.chmodPromise(pe,420),await T.renamePromise(pe,F)});let he=o.mirrorWriteOnly&&c!=null?c:F;return await Promise.all(D.map(pe=>pe())),[!1,he,X]},m=async()=>{let W=(async()=>{var Ne;let X=this.getLocatorPath(e,r,o),F=X!==null?await u.existsPromise(X):!1,D=!!((Ne=o.mockedPackages)==null?void 0:Ne.has(e.locatorHash))&&(!this.check||!F),he=D||F,pe=he?i:n;if(pe&&pe(),he){let Pe=null,qe=X;return D||(Pe=this.check?await h(qe):await f(qe)),[D,qe,Pe]}else return d()})();this.mutexes.set(e.locatorHash,W);try{return await W}finally{this.mutexes.delete(e.locatorHash)}};for(let V;V=this.mutexes.get(e.locatorHash);)await V;let[I,B,b]=await m();this.markedFiles.add(B);let R,H=await $i(),L=I?()=>g():()=>new Jr(B,{baseFs:u,libzip:H,readOnly:!0}),K=new oh(()=>Mv(()=>R=L(),V=>`Failed to open the cache entry for ${lt(this.configuration,e)}: ${V}`),v),J=new Xo(B,{baseFs:K,pathUtils:v}),ne=()=>{R==null||R.discardAndClose()},q=((A=o.unstablePackages)==null?void 0:A.has(e.locatorHash))?null:b;return[J,ne,q]}};function QR(t){let e=t.indexOf("/");return e!==-1?t.slice(0,e):null}function hTe(t){let e=t.indexOf("/");return e!==-1?t.slice(e+1):t}var F_=ie(x_()),NB=ie(ml());var N_=ie(Wp()),kR=ie(require("stream"));var k_={hooks:{reduceDependency:(t,e,r,i,{resolver:n,resolveOptions:s})=>{for(let{pattern:o,reference:a}of e.topLevelWorkspace.manifest.resolutions){if(o.from&&o.from.fullName!==St(r)||o.from&&o.from.description&&o.from.description!==r.reference||o.descriptor.fullName!==St(t)||o.descriptor.description&&o.descriptor.description!==t.range)continue;return n.bindDescriptor(Yt(t,a),e.topLevelWorkspace.anchoredLocator,s)}return t},validateProject:async(t,e)=>{for(let r of t.workspaces){let i=hp(t.configuration,r);await t.configuration.triggerHook(n=>n.validateWorkspace,r,{reportWarning:(n,s)=>e.reportWarning(n,`${i}: ${s}`),reportError:(n,s)=>e.reportError(n,`${i}: ${s}`)})}},validateWorkspace:async(t,e)=>{let{manifest:r}=t;r.resolutions.length&&t.cwd!==t.project.cwd&&r.errors.push(new Error("Resolutions field will be ignored"));for(let i of r.errors)e.reportWarning(z.INVALID_MANIFEST,i.message)}}};var vR=class{constructor(e){this.fetchers=e}supports(e,r){return!!this.tryFetcher(e,r)}getLocalPath(e,r){return this.getFetcher(e,r).getLocalPath(e,r)}async fetch(e,r){return await this.getFetcher(e,r).fetch(e,r)}tryFetcher(e,r){let i=this.fetchers.find(n=>n.supports(e,r));return i||null}getFetcher(e,r){let i=this.fetchers.find(n=>n.supports(e,r));if(!i)throw new nt(z.FETCHER_NOT_FOUND,`${lt(r.project.configuration,e)} isn't supported by any available fetcher`);return i}};var pd=class{constructor(e){this.resolvers=e.filter(r=>r)}supportsDescriptor(e,r){return!!this.tryResolverByDescriptor(e,r)}supportsLocator(e,r){return!!this.tryResolverByLocator(e,r)}shouldPersistResolution(e,r){return this.getResolverByLocator(e,r).shouldPersistResolution(e,r)}bindDescriptor(e,r,i){return this.getResolverByDescriptor(e,i).bindDescriptor(e,r,i)}getResolutionDependencies(e,r){return this.getResolverByDescriptor(e,r).getResolutionDependencies(e,r)}async getCandidates(e,r,i){return await this.getResolverByDescriptor(e,i).getCandidates(e,r,i)}async getSatisfying(e,r,i){return this.getResolverByDescriptor(e,i).getSatisfying(e,r,i)}async resolve(e,r){return await this.getResolverByLocator(e,r).resolve(e,r)}tryResolverByDescriptor(e,r){let i=this.resolvers.find(n=>n.supportsDescriptor(e,r));return i||null}getResolverByDescriptor(e,r){let i=this.resolvers.find(n=>n.supportsDescriptor(e,r));if(!i)throw new Error(`${Xt(r.project.configuration,e)} isn't supported by any available resolver`);return i}tryResolverByLocator(e,r){let i=this.resolvers.find(n=>n.supportsLocator(e,r));return i||null}getResolverByLocator(e,r){let i=this.resolvers.find(n=>n.supportsLocator(e,r));if(!i)throw new Error(`${lt(r.project.configuration,e)} isn't supported by any available resolver`);return i}};var P_=ie(Or());var Rg=/^(?!v)[a-z0-9._-]+$/i,SR=class{supportsDescriptor(e,r){return!!(Us(e.range)||Rg.test(e.range))}supportsLocator(e,r){return!!(P_.default.valid(e.reference)||Rg.test(e.reference))}shouldPersistResolution(e,r){return r.resolver.shouldPersistResolution(this.forwardLocator(e,r),r)}bindDescriptor(e,r,i){return i.resolver.bindDescriptor(this.forwardDescriptor(e,i),r,i)}getResolutionDependencies(e,r){return r.resolver.getResolutionDependencies(this.forwardDescriptor(e,r),r)}async getCandidates(e,r,i){return await i.resolver.getCandidates(this.forwardDescriptor(e,i),r,i)}async getSatisfying(e,r,i){return await i.resolver.getSatisfying(this.forwardDescriptor(e,i),r,i)}async resolve(e,r){let i=await r.resolver.resolve(this.forwardLocator(e,r),r);return op(i,e)}forwardDescriptor(e,r){return Yt(e,`${r.project.configuration.get("defaultProtocol")}${e.range}`)}forwardLocator(e,r){return Vi(e,`${r.project.configuration.get("defaultProtocol")}${e.reference}`)}};var dd=class{supports(e){return!!e.reference.startsWith("virtual:")}getLocalPath(e,r){let i=e.reference.indexOf("#");if(i===-1)throw new Error("Invalid virtual package reference");let n=e.reference.slice(i+1),s=Vi(e,n);return r.fetcher.getLocalPath(s,r)}async fetch(e,r){let i=e.reference.indexOf("#");if(i===-1)throw new Error("Invalid virtual package reference");let n=e.reference.slice(i+1),s=Vi(e,n),o=await r.fetcher.fetch(s,r);return await this.ensureVirtualLink(e,o,r)}getLocatorFilename(e){return Mu(e)}async ensureVirtualLink(e,r,i){let n=r.packageFs.getRealPath(),s=i.project.configuration.get("virtualFolder"),o=this.getLocatorFilename(e),a=Pr.makeVirtualPath(s,o,n),l=new Xo(a,{baseFs:r.packageFs,pathUtils:v});return _(P({},r),{packageFs:l})}};var Fg=class{static isVirtualDescriptor(e){return!!e.range.startsWith(Fg.protocol)}static isVirtualLocator(e){return!!e.reference.startsWith(Fg.protocol)}supportsDescriptor(e,r){return Fg.isVirtualDescriptor(e)}supportsLocator(e,r){return Fg.isVirtualLocator(e)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,i){throw new Error('Assertion failed: calling "bindDescriptor" on a virtual descriptor is unsupported')}getResolutionDependencies(e,r){throw new Error('Assertion failed: calling "getResolutionDependencies" on a virtual descriptor is unsupported')}async getCandidates(e,r,i){throw new Error('Assertion failed: calling "getCandidates" on a virtual descriptor is unsupported')}async getSatisfying(e,r,i){throw new Error('Assertion failed: calling "getSatisfying" on a virtual descriptor is unsupported')}async resolve(e,r){throw new Error('Assertion failed: calling "resolve" on a virtual locator is unsupported')}},FB=Fg;FB.protocol="virtual:";var xR=class{supports(e){return!!e.reference.startsWith(Yr.protocol)}getLocalPath(e,r){return this.getWorkspace(e,r).cwd}async fetch(e,r){let i=this.getWorkspace(e,r).cwd;return{packageFs:new Ft(i),prefixPath:Se.dot,localPath:i}}getWorkspace(e,r){return r.project.getWorkspaceByCwd(e.reference.slice(Yr.protocol.length))}};var D_=ie(require("module"));function R_(){return new Set(D_.default.builtinModules||Object.keys(process.binding("natives")))}var dTe=new Set(["binFolder","version","flags","profile","gpg","ignoreNode","wrapOutput","home","confDir"]),LB="yarn_",PR=".yarnrc.yml",DR="yarn.lock",CTe="********",ge;(function(u){u.ANY="ANY",u.BOOLEAN="BOOLEAN",u.ABSOLUTE_PATH="ABSOLUTE_PATH",u.LOCATOR="LOCATOR",u.LOCATOR_LOOSE="LOCATOR_LOOSE",u.NUMBER="NUMBER",u.STRING="STRING",u.SECRET="SECRET",u.SHAPE="SHAPE",u.MAP="MAP"})(ge||(ge={}));var ps=Le,RR={lastUpdateCheck:{description:"Last timestamp we checked whether new Yarn versions were available",type:ge.STRING,default:null},yarnPath:{description:"Path to the local executable that must be used over the global one",type:ge.ABSOLUTE_PATH,default:null},ignorePath:{description:"If true, the local executable will be ignored when using the global one",type:ge.BOOLEAN,default:!1},ignoreCwd:{description:"If true, the `--cwd` flag will be ignored",type:ge.BOOLEAN,default:!1},cacheKeyOverride:{description:"A global cache key override; used only for test purposes",type:ge.STRING,default:null},globalFolder:{description:"Folder where are stored the system-wide settings",type:ge.ABSOLUTE_PATH,default:Rb()},cacheFolder:{description:"Folder where the cache files must be written",type:ge.ABSOLUTE_PATH,default:"./.yarn/cache"},compressionLevel:{description:"Zip files compression level, from 0 to 9 or mixed (a variant of 9, which stores some files uncompressed, when compression doesn't yield good results)",type:ge.NUMBER,values:["mixed",0,1,2,3,4,5,6,7,8,9],default:pl},virtualFolder:{description:"Folder where the virtual packages (cf doc) will be mapped on the disk (must be named __virtual__)",type:ge.ABSOLUTE_PATH,default:"./.yarn/__virtual__"},lockfileFilename:{description:"Name of the files where the Yarn dependency tree entries must be stored",type:ge.STRING,default:DR},installStatePath:{description:"Path of the file where the install state will be persisted",type:ge.ABSOLUTE_PATH,default:"./.yarn/install-state.gz"},immutablePatterns:{description:"Array of glob patterns; files matching them won't be allowed to change during immutable installs",type:ge.STRING,default:[],isArray:!0},rcFilename:{description:"Name of the files where the configuration can be found",type:ge.STRING,default:TB()},enableGlobalCache:{description:"If true, the system-wide cache folder will be used regardless of `cache-folder`",type:ge.BOOLEAN,default:!1},enableColors:{description:"If true, the CLI is allowed to use colors in its output",type:ge.BOOLEAN,default:xy,defaultText:""},enableHyperlinks:{description:"If true, the CLI is allowed to use hyperlinks in its output",type:ge.BOOLEAN,default:Mx,defaultText:""},enableInlineBuilds:{description:"If true, the CLI will print the build output on the command line",type:ge.BOOLEAN,default:NB.isCI,defaultText:""},enableMessageNames:{description:"If true, the CLI will prefix most messages with codes suitable for search engines",type:ge.BOOLEAN,default:!0},enableProgressBars:{description:"If true, the CLI is allowed to show a progress bar for long-running events",type:ge.BOOLEAN,default:!NB.isCI&&process.stdout.isTTY&&process.stdout.columns>22,defaultText:""},enableTimers:{description:"If true, the CLI is allowed to print the time spent executing commands",type:ge.BOOLEAN,default:!0},preferAggregateCacheInfo:{description:"If true, the CLI will only print a one-line report of any cache changes",type:ge.BOOLEAN,default:NB.isCI},preferInteractive:{description:"If true, the CLI will automatically use the interactive mode when called from a TTY",type:ge.BOOLEAN,default:!1},preferTruncatedLines:{description:"If true, the CLI will truncate lines that would go beyond the size of the terminal",type:ge.BOOLEAN,default:!1},progressBarStyle:{description:"Which style of progress bar should be used (only when progress bars are enabled)",type:ge.STRING,default:void 0,defaultText:""},defaultLanguageName:{description:"Default language mode that should be used when a package doesn't offer any insight",type:ge.STRING,default:"node"},defaultProtocol:{description:"Default resolution protocol used when resolving pure semver and tag ranges",type:ge.STRING,default:"npm:"},enableTransparentWorkspaces:{description:"If false, Yarn won't automatically resolve workspace dependencies unless they use the `workspace:` protocol",type:ge.BOOLEAN,default:!0},supportedArchitectures:{description:"Architectures that Yarn will fetch and inject into the resolver",type:ge.SHAPE,properties:{os:{description:"Array of supported process.platform strings, or null to target them all",type:ge.STRING,isArray:!0,isNullable:!0,default:["current"]},cpu:{description:"Array of supported process.arch strings, or null to target them all",type:ge.STRING,isArray:!0,isNullable:!0,default:["current"]}}},enableMirror:{description:"If true, the downloaded packages will be retrieved and stored in both the local and global folders",type:ge.BOOLEAN,default:!0},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:ge.BOOLEAN,default:!0},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:ge.STRING,default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:ge.STRING,default:null},unsafeHttpWhitelist:{description:"List of the hostnames for which http queries are allowed (glob patterns are supported)",type:ge.STRING,default:[],isArray:!0},httpTimeout:{description:"Timeout of each http request in milliseconds",type:ge.NUMBER,default:6e4},httpRetry:{description:"Retry times on http failure",type:ge.NUMBER,default:3},networkConcurrency:{description:"Maximal number of concurrent requests",type:ge.NUMBER,default:50},networkSettings:{description:"Network settings per hostname (glob patterns are supported)",type:ge.MAP,valueDefinition:{description:"",type:ge.SHAPE,properties:{caFilePath:{description:"Path to file containing one or multiple Certificate Authority signing certificates",type:ge.ABSOLUTE_PATH,default:null},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:ge.BOOLEAN,default:null},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:ge.STRING,default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:ge.STRING,default:null}}}},caFilePath:{description:"A path to a file containing one or multiple Certificate Authority signing certificates",type:ge.ABSOLUTE_PATH,default:null},enableStrictSsl:{description:"If false, SSL certificate errors will be ignored",type:ge.BOOLEAN,default:!0},logFilters:{description:"Overrides for log levels",type:ge.SHAPE,isArray:!0,concatenateValues:!0,properties:{code:{description:"Code of the messages covered by this override",type:ge.STRING,default:void 0},text:{description:"Code of the texts covered by this override",type:ge.STRING,default:void 0},pattern:{description:"Code of the patterns covered by this override",type:ge.STRING,default:void 0},level:{description:"Log level override, set to null to remove override",type:ge.STRING,values:Object.values(Ts),isNullable:!0,default:void 0}}},enableTelemetry:{description:"If true, telemetry will be periodically sent, following the rules in https://yarnpkg.com/advanced/telemetry",type:ge.BOOLEAN,default:!0},telemetryInterval:{description:"Minimal amount of time between two telemetry uploads, in days",type:ge.NUMBER,default:7},telemetryUserId:{description:"If you desire to tell us which project you are, you can set this field. Completely optional and opt-in.",type:ge.STRING,default:null},enableScripts:{description:"If true, packages are allowed to have install scripts by default",type:ge.BOOLEAN,default:!0},enableStrictSettings:{description:"If true, unknown settings will cause Yarn to abort",type:ge.BOOLEAN,default:!0},enableImmutableCache:{description:"If true, the cache is reputed immutable and actions that would modify it will throw",type:ge.BOOLEAN,default:!1},checksumBehavior:{description:"Enumeration defining what to do when a checksum doesn't match expectations",type:ge.STRING,default:"throw"},packageExtensions:{description:"Map of package corrections to apply on the dependency tree",type:ge.MAP,valueDefinition:{description:"The extension that will be applied to any package whose version matches the specified range",type:ge.SHAPE,properties:{dependencies:{description:"The set of dependencies that must be made available to the current package in order for it to work properly",type:ge.MAP,valueDefinition:{description:"A range",type:ge.STRING}},peerDependencies:{description:"Inherited dependencies - the consumer of the package will be tasked to provide them",type:ge.MAP,valueDefinition:{description:"A semver range",type:ge.STRING}},peerDependenciesMeta:{description:"Extra information related to the dependencies listed in the peerDependencies field",type:ge.MAP,valueDefinition:{description:"The peerDependency meta",type:ge.SHAPE,properties:{optional:{description:"If true, the selected peer dependency will be marked as optional by the package manager and the consumer omitting it won't be reported as an error",type:ge.BOOLEAN,default:!1}}}}}}}};function NR(t,e,r,i,n){if(i.isArray||i.type===ge.ANY&&Array.isArray(r))return Array.isArray(r)?r.map((s,o)=>FR(t,`${e}[${o}]`,s,i,n)):String(r).split(/,/).map(s=>FR(t,e,s,i,n));if(Array.isArray(r))throw new Error(`Non-array configuration settings "${e}" cannot be an array`);return FR(t,e,r,i,n)}function FR(t,e,r,i,n){var a;switch(i.type){case ge.ANY:return r;case ge.SHAPE:return mTe(t,e,r,i,n);case ge.MAP:return ETe(t,e,r,i,n)}if(r===null&&!i.isNullable&&i.default!==null)throw new Error(`Non-nullable configuration settings "${e}" cannot be set to null`);if((a=i.values)==null?void 0:a.includes(r))return r;let o=(()=>{if(i.type===ge.BOOLEAN&&typeof r!="string")return Hh(r);if(typeof r!="string")throw new Error(`Expected value (${r}) to be a string`);let l=Ov(r,{env:process.env});switch(i.type){case ge.ABSOLUTE_PATH:return v.resolve(n,M.toPortablePath(l));case ge.LOCATOR_LOOSE:return Hl(l,!1);case ge.NUMBER:return parseInt(l);case ge.LOCATOR:return Hl(l);case ge.BOOLEAN:return Hh(l);default:return l}})();if(i.values&&!i.values.includes(o))throw new Error(`Invalid value, expected one of ${i.values.join(", ")}`);return o}function mTe(t,e,r,i,n){if(typeof r!="object"||Array.isArray(r))throw new me(`Object configuration settings "${e}" must be an object`);let s=LR(t,i,{ignoreArrays:!0});if(r===null)return s;for(let[o,a]of Object.entries(r)){let l=`${e}.${o}`;if(!i.properties[o])throw new me(`Unrecognized configuration settings found: ${e}.${o} - run "yarn config -v" to see the list of settings supported in Yarn`);s.set(o,NR(t,l,a,i.properties[o],n))}return s}function ETe(t,e,r,i,n){let s=new Map;if(typeof r!="object"||Array.isArray(r))throw new me(`Map configuration settings "${e}" must be an object`);if(r===null)return s;for(let[o,a]of Object.entries(r)){let l=i.normalizeKeys?i.normalizeKeys(o):o,c=`${e}['${l}']`,u=i.valueDefinition;s.set(l,NR(t,c,a,u,n))}return s}function LR(t,e,{ignoreArrays:r=!1}={}){switch(e.type){case ge.SHAPE:{if(e.isArray&&!r)return[];let i=new Map;for(let[n,s]of Object.entries(e.properties))i.set(n,LR(t,s));return i}break;case ge.MAP:return e.isArray&&!r?[]:new Map;case ge.ABSOLUTE_PATH:return e.default===null?null:t.projectCwd===null?v.isAbsolute(e.default)?v.normalize(e.default):e.isNullable?null:void 0:Array.isArray(e.default)?e.default.map(i=>v.resolve(t.projectCwd,i)):v.resolve(t.projectCwd,e.default);default:return e.default}}function MB(t,e,r){if(e.type===ge.SECRET&&typeof t=="string"&&r.hideSecrets)return CTe;if(e.type===ge.ABSOLUTE_PATH&&typeof t=="string"&&r.getNativePaths)return M.fromPortablePath(t);if(e.isArray&&Array.isArray(t)){let i=[];for(let n of t)i.push(MB(n,e,r));return i}if(e.type===ge.MAP&&t instanceof Map){let i=new Map;for(let[n,s]of t.entries())i.set(n,MB(s,e.valueDefinition,r));return i}if(e.type===ge.SHAPE&&t instanceof Map){let i=new Map;for(let[n,s]of t.entries()){let o=e.properties[n];i.set(n,MB(s,o,r))}return i}return t}function ITe(){let t={};for(let[e,r]of Object.entries(process.env))e=e.toLowerCase(),!!e.startsWith(LB)&&(e=(0,F_.default)(e.slice(LB.length)),t[e]=r);return t}function TB(){let t=`${LB}rc_filename`;for(let[e,r]of Object.entries(process.env))if(e.toLowerCase()===t&&typeof r=="string")return r;return PR}var KA;(function(i){i[i.LOCKFILE=0]="LOCKFILE",i[i.MANIFEST=1]="MANIFEST",i[i.NONE=2]="NONE"})(KA||(KA={}));var Ra=class{constructor(e){this.projectCwd=null;this.plugins=new Map;this.settings=new Map;this.values=new Map;this.sources=new Map;this.invalid=new Map;this.packageExtensions=new Map;this.limits=new Map;this.startingCwd=e}static create(e,r,i){let n=new Ra(e);typeof r!="undefined"&&!(r instanceof Map)&&(n.projectCwd=r),n.importSettings(RR);let s=typeof i!="undefined"?i:r instanceof Map?r:new Map;for(let[o,a]of s)n.activatePlugin(o,a);return n}static async find(e,r,{lookup:i=0,strict:n=!0,usePath:s=!1,useRc:o=!0}={}){let a=ITe();delete a.rcFilename;let l=await Ra.findRcFiles(e),c=await Ra.findHomeRcFile();if(c){let I=l.find(B=>B.path===c.path);I?I.strict=!1:l.push(_(P({},c),{strict:!1}))}let u=({ignoreCwd:I,yarnPath:B,ignorePath:b,lockfileFilename:R})=>({ignoreCwd:I,yarnPath:B,ignorePath:b,lockfileFilename:R}),g=L=>{var K=L,{ignoreCwd:I,yarnPath:B,ignorePath:b,lockfileFilename:R}=K,H=qr(K,["ignoreCwd","yarnPath","ignorePath","lockfileFilename"]);return H},f=new Ra(e);f.importSettings(u(RR)),f.useWithSource("",u(a),e,{strict:!1});for(let{path:I,cwd:B,data:b}of l)f.useWithSource(I,u(b),B,{strict:!1});if(s){let I=f.get("yarnPath"),B=f.get("ignorePath");if(I!==null&&!B)return f}let h=f.get("lockfileFilename"),p;switch(i){case 0:p=await Ra.findProjectCwd(e,h);break;case 1:p=await Ra.findProjectCwd(e,null);break;case 2:T.existsSync(v.join(e,"package.json"))?p=v.resolve(e):p=null;break}f.startingCwd=e,f.projectCwd=p,f.importSettings(g(RR));let d=new Map([["@@core",k_]]),m=I=>"default"in I?I.default:I;if(r!==null){for(let R of r.plugins.keys())d.set(R,m(r.modules.get(R)));let I=new Map;for(let R of R_())I.set(R,()=>mu(R));for(let[R,H]of r.modules)I.set(R,()=>H);let B=new Set,b=async(R,H)=>{let{factory:L,name:K}=mu(R);if(B.has(K))return;let J=new Map(I),ne=A=>{if(J.has(A))return J.get(A)();throw new me(`This plugin cannot access the package referenced via ${A} which is neither a builtin, nor an exposed entry`)},q=await du(async()=>m(await L(ne)),A=>`${A} (when initializing ${K}, defined in ${H})`);I.set(K,()=>q),B.add(K),d.set(K,q)};if(a.plugins)for(let R of a.plugins.split(";")){let H=v.resolve(e,M.toPortablePath(R));await b(H,"")}for(let{path:R,cwd:H,data:L}of l)if(!!o&&!!Array.isArray(L.plugins))for(let K of L.plugins){let J=typeof K!="string"?K.path:K,ne=v.resolve(H,M.toPortablePath(J));await b(ne,R)}}for(let[I,B]of d)f.activatePlugin(I,B);f.useWithSource("",g(a),e,{strict:n});for(let{path:I,cwd:B,data:b,strict:R}of l)f.useWithSource(I,g(b),B,{strict:R!=null?R:n});return f.get("enableGlobalCache")&&(f.values.set("cacheFolder",`${f.get("globalFolder")}/cache`),f.sources.set("cacheFolder","")),await f.refreshPackageExtensions(),f}static async findRcFiles(e){let r=TB(),i=[],n=e,s=null;for(;n!==s;){s=n;let o=v.join(s,r);if(T.existsSync(o)){let a=await T.readFilePromise(o,"utf8"),l;try{l=Ii(a)}catch(c){let u="";throw a.match(/^\s+(?!-)[^:]+\s+\S+/m)&&(u=" (in particular, make sure you list the colons after each key name)"),new me(`Parse error when loading ${o}; please check it's proper Yaml${u}`)}i.push({path:o,cwd:s,data:l})}n=v.dirname(s)}return i}static async findHomeRcFile(){let e=TB(),r=uh(),i=v.join(r,e);if(T.existsSync(i)){let n=await T.readFilePromise(i,"utf8"),s=Ii(n);return{path:i,cwd:r,data:s}}return null}static async findProjectCwd(e,r){let i=null,n=e,s=null;for(;n!==s;){if(s=n,T.existsSync(v.join(s,"package.json"))&&(i=s),r!==null){if(T.existsSync(v.join(s,r))){i=s;break}}else if(i!==null)break;n=v.dirname(s)}return i}static async updateConfiguration(e,r){let i=TB(),n=v.join(e,i),s=T.existsSync(n)?Ii(await T.readFilePromise(n,"utf8")):{},o=!1,a;if(typeof r=="function"){try{a=r(s)}catch{a=r({})}if(a===s)return}else{a=s;for(let l of Object.keys(r)){let c=s[l],u=r[l],g;if(typeof u=="function")try{g=u(c)}catch{g=u(void 0)}else g=u;c!==g&&(a[l]=g,o=!0)}if(!o)return}await T.changeFilePromise(n,Qa(a),{automaticNewlines:!0})}static async updateHomeConfiguration(e){let r=uh();return await Ra.updateConfiguration(r,e)}activatePlugin(e,r){this.plugins.set(e,r),typeof r.configuration!="undefined"&&this.importSettings(r.configuration)}importSettings(e){for(let[r,i]of Object.entries(e))if(i!=null){if(this.settings.has(r))throw new Error(`Cannot redefine settings "${r}"`);this.settings.set(r,i),this.values.set(r,LR(this,i))}}useWithSource(e,r,i,n){try{this.use(e,r,i,n)}catch(s){throw s.message+=` (in ${Ve(this,e,Le.PATH)})`,s}}use(e,r,i,{strict:n=!0,overwrite:s=!1}={}){n=n&&this.get("enableStrictSettings");for(let o of["enableStrictSettings",...Object.keys(r)]){if(typeof r[o]=="undefined"||o==="plugins"||e===""&&dTe.has(o))continue;if(o==="rcFilename")throw new me(`The rcFilename settings can only be set via ${`${LB}RC_FILENAME`.toUpperCase()}, not via a rc file`);let l=this.settings.get(o);if(!l){if(n)throw new me(`Unrecognized or legacy configuration settings found: ${o} - run "yarn config -v" to see the list of settings supported in Yarn`);this.invalid.set(o,e);continue}if(this.sources.has(o)&&!(s||l.type===ge.MAP||l.isArray&&l.concatenateValues))continue;let c;try{c=NR(this,o,r[o],l,i)}catch(u){throw u.message+=` in ${Ve(this,e,Le.PATH)}`,u}if(o==="enableStrictSettings"&&e!==""){n=c;continue}if(l.type===ge.MAP){let u=this.values.get(o);this.values.set(o,new Map(s?[...u,...c]:[...c,...u])),this.sources.set(o,`${this.sources.get(o)}, ${e}`)}else if(l.isArray&&l.concatenateValues){let u=this.values.get(o);this.values.set(o,s?[...u,...c]:[...c,...u]),this.sources.set(o,`${this.sources.get(o)}, ${e}`)}else this.values.set(o,c),this.sources.set(o,e)}}get(e){if(!this.values.has(e))throw new Error(`Invalid configuration key "${e}"`);return this.values.get(e)}getSpecial(e,{hideSecrets:r=!1,getNativePaths:i=!1}){let n=this.get(e),s=this.settings.get(e);if(typeof s=="undefined")throw new me(`Couldn't find a configuration settings named "${e}"`);return MB(n,s,{hideSecrets:r,getNativePaths:i})}getSubprocessStreams(e,{header:r,prefix:i,report:n}){let s,o,a=T.createWriteStream(e);if(this.get("enableInlineBuilds")){let l=n.createStreamReporter(`${i} ${Ve(this,"STDOUT","green")}`),c=n.createStreamReporter(`${i} ${Ve(this,"STDERR","red")}`);s=new kR.PassThrough,s.pipe(l),s.pipe(a),o=new kR.PassThrough,o.pipe(c),o.pipe(a)}else s=a,o=a,typeof r!="undefined"&&s.write(`${r} +`);return{stdout:s,stderr:o}}makeResolver(){let e=[];for(let r of this.plugins.values())for(let i of r.resolvers||[])e.push(new i);return new pd([new FB,new Yr,new SR,...e])}makeFetcher(){let e=[];for(let r of this.plugins.values())for(let i of r.fetchers||[])e.push(new i);return new vR([new dd,new xR,...e])}getLinkers(){let e=[];for(let r of this.plugins.values())for(let i of r.linkers||[])e.push(new i);return e}getSupportedArchitectures(){let e=this.get("supportedArchitectures"),r=e.get("os");r!==null&&(r=r.map(n=>n==="current"?process.platform:n));let i=e.get("cpu");return i!==null&&(i=i.map(n=>n==="current"?process.arch:n)),{os:r,cpu:i}}async refreshPackageExtensions(){this.packageExtensions=new Map;let e=this.packageExtensions,r=(i,n,{userProvided:s=!1}={})=>{if(!Us(i.range))throw new Error("Only semver ranges are allowed as keys for the packageExtensions setting");let o=new Ze;o.load(n,{yamlCompatibilityMode:!0});let a=hu(e,i.identHash),l=[];a.push([i.range,l]);let c={status:ki.Inactive,userProvided:s,parentDescriptor:i};for(let u of o.dependencies.values())l.push(_(P({},c),{type:oi.Dependency,descriptor:u}));for(let u of o.peerDependencies.values())l.push(_(P({},c),{type:oi.PeerDependency,descriptor:u}));for(let[u,g]of o.peerDependenciesMeta)for(let[f,h]of Object.entries(g))l.push(_(P({},c),{type:oi.PeerDependencyMeta,selector:u,key:f,value:h}))};await this.triggerHook(i=>i.registerPackageExtensions,this,r);for(let[i,n]of this.get("packageExtensions"))r(pA(i,!0),aI(n),{userProvided:!0})}normalizePackage(e){let r=ap(e);if(this.packageExtensions==null)throw new Error("refreshPackageExtensions has to be called before normalizing packages");let i=this.packageExtensions.get(e.identHash);if(typeof i!="undefined"){let s=e.version;if(s!==null){for(let[o,a]of i)if(!!lc(s,o))for(let l of a)switch(l.status===ki.Inactive&&(l.status=ki.Redundant),l.type){case oi.Dependency:typeof r.dependencies.get(l.descriptor.identHash)=="undefined"&&(l.status=ki.Active,r.dependencies.set(l.descriptor.identHash,l.descriptor));break;case oi.PeerDependency:typeof r.peerDependencies.get(l.descriptor.identHash)=="undefined"&&(l.status=ki.Active,r.peerDependencies.set(l.descriptor.identHash,l.descriptor));break;case oi.PeerDependencyMeta:{let c=r.peerDependenciesMeta.get(l.selector);(typeof c=="undefined"||!Object.prototype.hasOwnProperty.call(c,l.key)||c[l.key]!==l.value)&&(l.status=ki.Active,na(r.peerDependenciesMeta,l.selector,()=>({}))[l.key]=l.value)}break;default:Lv(l);break}}}let n=s=>s.scope?`${s.scope}__${s.name}`:`${s.name}`;for(let s of r.peerDependenciesMeta.keys()){let o=En(s);r.peerDependencies.has(o.identHash)||r.peerDependencies.set(o.identHash,Yt(o,"*"))}for(let s of r.peerDependencies.values()){if(s.scope==="types")continue;let o=n(s),a=Eo("types",o),l=St(a);r.peerDependencies.has(a.identHash)||r.peerDependenciesMeta.has(l)||(r.peerDependencies.set(a.identHash,Yt(a,"*")),r.peerDependenciesMeta.set(l,{optional:!0}))}return r.dependencies=new Map(gn(r.dependencies,([,s])=>In(s))),r.peerDependencies=new Map(gn(r.peerDependencies,([,s])=>In(s))),r}getLimit(e){return na(this.limits,e,()=>(0,N_.default)(this.get(e)))}async triggerHook(e,...r){for(let i of this.plugins.values()){let n=i.hooks;if(!n)continue;let s=e(n);!s||await s(...r)}}async triggerMultipleHooks(e,r){for(let i of r)await this.triggerHook(e,...i)}async reduceHook(e,r,...i){let n=r;for(let s of this.plugins.values()){let o=s.hooks;if(!o)continue;let a=e(o);!a||(n=await a(n,...i))}return n}async firstHook(e,...r){for(let i of this.plugins.values()){let n=i.hooks;if(!n)continue;let s=e(n);if(!s)continue;let o=await s(...r);if(typeof o!="undefined")return o}return null}},fe=Ra;fe.telemetry=null;var Gn;(function(r){r[r.SCRIPT=0]="SCRIPT",r[r.SHELLCODE=1]="SHELLCODE"})(Gn||(Gn={}));var Fa=class extends Xi{constructor({configuration:e,stdout:r,suggestInstall:i=!0}){super();this.errorCount=0;Cp(this,{configuration:e}),this.configuration=e,this.stdout=r,this.suggestInstall=i}static async start(e,r){let i=new this(e);try{await r(i)}catch(n){i.reportExceptionOnce(n)}finally{await i.finalize()}return i}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(e){}reportCacheMiss(e){}startTimerSync(e,r,i){return(typeof r=="function"?r:i)()}async startTimerPromise(e,r,i){return await(typeof r=="function"?r:i)()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,r){}reportWarning(e,r){}reportError(e,r){this.errorCount+=1,this.stdout.write(`${Ve(this.configuration,"\u27A4","redBright")} ${this.formatNameWithHyperlink(e)}: ${r} +`)}reportProgress(e){let r=Promise.resolve().then(async()=>{for await(let{}of e);}),i=()=>{};return _(P({},r),{stop:i})}reportJson(e){}async finalize(){this.errorCount>0&&(this.stdout.write(` +`),this.stdout.write(`${Ve(this.configuration,"\u27A4","redBright")} Errors happened when preparing the environment required to run this command. +`),this.suggestInstall&&this.stdout.write(`${Ve(this.configuration,"\u27A4","redBright")} This might be caused by packages being missing from the lockfile, in which case running "yarn install" might help. +`))}formatNameWithHyperlink(e){return eD(e,{configuration:this.configuration,json:!1})}};var t0=ie(require("crypto")),v$=ie(CX()),r0=ie(Q$()),S$=ie(Wp()),x$=ie(Or()),lF=ie(require("util")),cF=ie(require("v8")),uF=ie(require("zlib"));var iUe=[[/^(git(?:\+(?:https|ssh))?:\/\/.*(?:\.git)?)#(.*)$/,(t,e,r,i)=>`${r}#commit=${i}`],[/^https:\/\/((?:[^/]+?)@)?codeload\.github\.com\/([^/]+\/[^/]+)\/tar\.gz\/([0-9a-f]+)$/,(t,e,r="",i,n)=>`https://${r}github.com/${i}.git#commit=${n}`],[/^https:\/\/((?:[^/]+?)@)?github\.com\/([^/]+\/[^/]+?)(?:\.git)?#([0-9a-f]+)$/,(t,e,r="",i,n)=>`https://${r}github.com/${i}.git#commit=${n}`],[/^https?:\/\/[^/]+\/(?:[^/]+\/)*(?:@.+(?:\/|(?:%2f)))?([^/]+)\/(?:-|download)\/\1-[^/]+\.tgz(?:#|$)/,t=>`npm:${t}`],[/^https:\/\/npm\.pkg\.github\.com\/download\/(?:@[^/]+)\/(?:[^/]+)\/(?:[^/]+)\/(?:[0-9a-f]+)(?:#|$)/,t=>`npm:${t}`],[/^https:\/\/npm\.fontawesome\.com\/(?:@[^/]+)\/([^/]+)\/-\/([^/]+)\/\1-\2.tgz(?:#|$)/,t=>`npm:${t}`],[/^https?:\/\/(?:[^\\.]+)\.jfrog\.io\/.*\/(@[^/]+)\/([^/]+)\/-\/\1\/\2-(?:[.\d\w-]+)\.tgz(?:#|$)/,(t,e)=>by({protocol:"npm:",source:null,selector:t,params:{__archiveUrl:e}})],[/^[^/]+\.tgz#[0-9a-f]+$/,t=>`npm:${t}`]],oF=class{constructor(){this.resolutions=null}async setup(e,{report:r}){let i=v.join(e.cwd,e.configuration.get("lockfileFilename"));if(!T.existsSync(i))return;let n=await T.readFilePromise(i,"utf8"),s=Ii(n);if(Object.prototype.hasOwnProperty.call(s,"__metadata"))return;let o=this.resolutions=new Map;for(let a of Object.keys(s)){let l=gp(a);if(!l){r.reportWarning(z.YARN_IMPORT_FAILED,`Failed to parse the string "${a}" into a proper descriptor`);continue}Us(l.range)&&(l=Yt(l,`npm:${l.range}`));let{version:c,resolved:u}=s[a];if(!u)continue;let g;for(let[h,p]of iUe){let d=u.match(h);if(d){g=p(c,...d);break}}if(!g){r.reportWarning(z.YARN_IMPORT_FAILED,`${Xt(e.configuration,l)}: Only some patterns can be imported from legacy lockfiles (not "${u}")`);continue}let f=l;try{let h=Tu(l.range),p=gp(h.selector,!0);p&&(f=p)}catch{}o.set(l.descriptorHash,Vi(f,g))}}supportsDescriptor(e,r){return this.resolutions?this.resolutions.has(e.descriptorHash):!1}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}bindDescriptor(e,r,i){return e}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){if(!this.resolutions)throw new Error("Assertion failed: The resolution store should have been setup");let n=this.resolutions.get(e.descriptorHash);if(!n)throw new Error("Assertion failed: The resolution should have been registered");return[n]}async getSatisfying(e,r,i){return null}async resolve(e,r){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}};var aF=class{constructor(e){this.resolver=e}supportsDescriptor(e,r){return!!(r.project.storedResolutions.get(e.descriptorHash)||r.project.originalPackages.has(By(e).locatorHash))}supportsLocator(e,r){return!!(r.project.originalPackages.has(e.locatorHash)&&!r.project.lockfileNeedsRefresh)}shouldPersistResolution(e,r){throw new Error("The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes")}bindDescriptor(e,r,i){return e}getResolutionDependencies(e,r){return this.resolver.getResolutionDependencies(e,r)}async getCandidates(e,r,i){let n=i.project.originalPackages.get(By(e).locatorHash);if(n)return[n];let s=i.project.storedResolutions.get(e.descriptorHash);if(!s)throw new Error("Expected the resolution to have been successful - resolution not found");if(n=i.project.originalPackages.get(s),!n)throw new Error("Expected the resolution to have been successful - package not found");return[n]}async getSatisfying(e,r,i){return null}async resolve(e,r){let i=r.project.originalPackages.get(e.locatorHash);if(!i)throw new Error("The lockfile resolver isn't meant to resolve packages - they should already have been stored into a cache");return i}};var AF=class{constructor(e){this.resolver=e}supportsDescriptor(e,r){return this.resolver.supportsDescriptor(e,r)}supportsLocator(e,r){return this.resolver.supportsLocator(e,r)}shouldPersistResolution(e,r){return this.resolver.shouldPersistResolution(e,r)}bindDescriptor(e,r,i){return this.resolver.bindDescriptor(e,r,i)}getResolutionDependencies(e,r){return this.resolver.getResolutionDependencies(e,r)}async getCandidates(e,r,i){throw new nt(z.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async getSatisfying(e,r,i){throw new nt(z.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async resolve(e,r){throw new nt(z.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}};var ei=class extends Xi{reportCacheHit(e){}reportCacheMiss(e){}startTimerSync(e,r,i){return(typeof r=="function"?r:i)()}async startTimerPromise(e,r,i){return await(typeof r=="function"?r:i)()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,r){}reportWarning(e,r){}reportError(e,r){}reportProgress(e){let r=Promise.resolve().then(async()=>{for await(let{}of e);}),i=()=>{};return _(P({},r),{stop:i})}reportJson(e){}async finalize(){}};var b$=ie(vx());var Dd=class{constructor(e,{project:r}){this.workspacesCwds=new Set;this.dependencies=new Map;this.project=r,this.cwd=e}async setup(){this.manifest=T.existsSync(v.join(this.cwd,Ze.fileName))?await Ze.find(this.cwd):new Ze,this.relativeCwd=v.relative(this.project.cwd,this.cwd)||Se.dot;let e=this.manifest.name?this.manifest.name:Eo(null,`${this.computeCandidateName()}-${zi(this.relativeCwd).substr(0,6)}`),r=this.manifest.version?this.manifest.version:"0.0.0";this.locator=Vi(e,r),this.anchoredDescriptor=Yt(this.locator,`${Yr.protocol}${this.relativeCwd}`),this.anchoredLocator=Vi(this.locator,`${Yr.protocol}${this.relativeCwd}`);let i=this.manifest.workspaceDefinitions.map(({pattern:s})=>s),n=await(0,b$.default)(i,{cwd:M.fromPortablePath(this.cwd),expandDirectories:!1,onlyDirectories:!0,onlyFiles:!1,ignore:["**/node_modules","**/.git","**/.yarn"]});n.sort();for(let s of n){let o=v.resolve(this.cwd,M.toPortablePath(s));T.existsSync(v.join(o,"package.json"))&&this.workspacesCwds.add(o)}}accepts(e){var o;let r=e.indexOf(":"),i=r!==-1?e.slice(0,r+1):null,n=r!==-1?e.slice(r+1):e;if(i===Yr.protocol&&v.normalize(n)===this.relativeCwd||i===Yr.protocol&&(n==="*"||n==="^"||n==="~"))return!0;let s=Us(n);return s?i===Yr.protocol?s.test((o=this.manifest.version)!=null?o:"0.0.0"):this.project.configuration.get("enableTransparentWorkspaces")&&this.manifest.version!==null?s.test(this.manifest.version):!1:!1}computeCandidateName(){return this.cwd===this.project.cwd?"root-workspace":`${v.basename(this.cwd)}`||"unnamed-workspace"}getRecursiveWorkspaceDependencies({dependencies:e=Ze.hardDependencies}={}){let r=new Set,i=n=>{for(let s of e)for(let o of n.manifest[s].values()){let a=this.project.tryWorkspaceByDescriptor(o);a===null||r.has(a)||(r.add(a),i(a))}};return i(this),r}getRecursiveWorkspaceDependents({dependencies:e=Ze.hardDependencies}={}){let r=new Set,i=n=>{for(let s of this.project.workspaces)e.some(a=>[...s.manifest[a].values()].some(l=>{let c=this.project.tryWorkspaceByDescriptor(l);return c!==null&&up(c.anchoredLocator,n.anchoredLocator)}))&&!r.has(s)&&(r.add(s),i(s))};return i(this),r}getRecursiveWorkspaceChildren(){let e=[];for(let r of this.workspacesCwds){let i=this.project.workspacesByCwd.get(r);i&&e.push(i,...i.getRecursiveWorkspaceChildren())}return e}async persistManifest(){let e={};this.manifest.exportTo(e);let r=v.join(this.cwd,Ze.fileName),i=`${JSON.stringify(e,null,this.manifest.indent)} +`;await T.changeFilePromise(r,i,{automaticNewlines:!0}),this.manifest.raw=e}};var k$=5,nUe=1,sUe=/ *, */g,P$=/\/$/,oUe=32,aUe=(0,lF.promisify)(uF.default.gzip),AUe=(0,lF.promisify)(uF.default.gunzip),li;(function(r){r.UpdateLockfile="update-lockfile",r.SkipBuild="skip-build"})(li||(li={}));var gF={restoreInstallersCustomData:["installersCustomData"],restoreResolutions:["accessibleLocators","conditionalLocators","disabledLocators","optionalBuilds","storedDescriptors","storedResolutions","storedPackages","lockFileChecksum"],restoreBuildState:["storedBuildState"]},D$=t=>zi(`${nUe}`,t),Ke=class{constructor(e,{configuration:r}){this.resolutionAliases=new Map;this.workspaces=[];this.workspacesByCwd=new Map;this.workspacesByIdent=new Map;this.storedResolutions=new Map;this.storedDescriptors=new Map;this.storedPackages=new Map;this.storedChecksums=new Map;this.storedBuildState=new Map;this.accessibleLocators=new Set;this.conditionalLocators=new Set;this.disabledLocators=new Set;this.originalPackages=new Map;this.optionalBuilds=new Set;this.lockfileNeedsRefresh=!1;this.peerRequirements=new Map;this.installersCustomData=new Map;this.lockFileChecksum=null;this.installStateChecksum=null;this.configuration=r,this.cwd=e}static async find(e,r){var c,u,g;if(!e.projectCwd)throw new me(`No project found in ${r}`);let i=e.projectCwd,n=r,s=null;for(;s!==e.projectCwd;){if(s=n,T.existsSync(v.join(s,wt.manifest))){i=s;break}n=v.dirname(s)}let o=new Ke(e.projectCwd,{configuration:e});(c=fe.telemetry)==null||c.reportProject(o.cwd),await o.setupResolutions(),await o.setupWorkspaces(),(u=fe.telemetry)==null||u.reportWorkspaceCount(o.workspaces.length),(g=fe.telemetry)==null||g.reportDependencyCount(o.workspaces.reduce((f,h)=>f+h.manifest.dependencies.size+h.manifest.devDependencies.size,0));let a=o.tryWorkspaceByCwd(i);if(a)return{project:o,workspace:a,locator:a.anchoredLocator};let l=await o.findLocatorForLocation(`${i}/`,{strict:!0});if(l)return{project:o,locator:l,workspace:null};throw new me(`The nearest package directory (${Ve(e,i,Le.PATH)}) doesn't seem to be part of the project declared in ${Ve(e,o.cwd,Le.PATH)}. + +- If the project directory is right, it might be that you forgot to list ${Ve(e,v.relative(o.cwd,i),Le.PATH)} as a workspace. +- If it isn't, it's likely because you have a yarn.lock or package.json file there, confusing the project root detection.`)}async setupResolutions(){var i;this.storedResolutions=new Map,this.storedDescriptors=new Map,this.storedPackages=new Map,this.lockFileChecksum=null;let e=v.join(this.cwd,this.configuration.get("lockfileFilename")),r=this.configuration.get("defaultLanguageName");if(T.existsSync(e)){let n=await T.readFilePromise(e,"utf8");this.lockFileChecksum=D$(n);let s=Ii(n);if(s.__metadata){let o=s.__metadata.version,a=s.__metadata.cacheKey;this.lockfileNeedsRefresh=o0;){let r=e;e=[];for(let i of r){if(this.workspacesByCwd.has(i))continue;let n=await this.addWorkspace(i),s=this.storedPackages.get(n.anchoredLocator.locatorHash);s&&(n.dependencies=s.dependencies);for(let o of n.workspacesCwds)e.push(o)}}}async addWorkspace(e){let r=new Dd(e,{project:this});await r.setup();let i=this.workspacesByIdent.get(r.locator.identHash);if(typeof i!="undefined")throw new Error(`Duplicate workspace name ${Vr(this.configuration,r.locator)}: ${M.fromPortablePath(e)} conflicts with ${M.fromPortablePath(i.cwd)}`);return this.workspaces.push(r),this.workspacesByCwd.set(e,r),this.workspacesByIdent.set(r.locator.identHash,r),r}get topLevelWorkspace(){return this.getWorkspaceByCwd(this.cwd)}tryWorkspaceByCwd(e){v.isAbsolute(e)||(e=v.resolve(this.cwd,e)),e=v.normalize(e).replace(/\/+$/,"");let r=this.workspacesByCwd.get(e);return r||null}getWorkspaceByCwd(e){let r=this.tryWorkspaceByCwd(e);if(!r)throw new Error(`Workspace not found (${e})`);return r}tryWorkspaceByFilePath(e){let r=null;for(let i of this.workspaces)v.relative(i.cwd,e).startsWith("../")||r&&r.cwd.length>=i.cwd.length||(r=i);return r||null}getWorkspaceByFilePath(e){let r=this.tryWorkspaceByFilePath(e);if(!r)throw new Error(`Workspace not found (${e})`);return r}tryWorkspaceByIdent(e){let r=this.workspacesByIdent.get(e.identHash);return typeof r=="undefined"?null:r}getWorkspaceByIdent(e){let r=this.tryWorkspaceByIdent(e);if(!r)throw new Error(`Workspace not found (${Vr(this.configuration,e)})`);return r}tryWorkspaceByDescriptor(e){let r=this.tryWorkspaceByIdent(e);return r===null||(hA(e)&&(e=Ap(e)),!r.accepts(e.range))?null:r}getWorkspaceByDescriptor(e){let r=this.tryWorkspaceByDescriptor(e);if(r===null)throw new Error(`Workspace not found (${Xt(this.configuration,e)})`);return r}tryWorkspaceByLocator(e){let r=this.tryWorkspaceByIdent(e);return r===null||(Io(e)&&(e=lp(e)),r.locator.locatorHash!==e.locatorHash&&r.anchoredLocator.locatorHash!==e.locatorHash)?null:r}getWorkspaceByLocator(e){let r=this.tryWorkspaceByLocator(e);if(!r)throw new Error(`Workspace not found (${lt(this.configuration,e)})`);return r}refreshWorkspaceDependencies(){for(let e of this.workspaces){let r=this.storedPackages.get(e.anchoredLocator.locatorHash);if(!r)throw new Error(`Assertion failed: Expected workspace ${hp(this.configuration,e)} (${Ve(this.configuration,v.join(e.cwd,wt.manifest),Le.PATH)}) to have been resolved. Run "yarn install" to update the lockfile`);e.dependencies=new Map(r.dependencies)}}forgetResolution(e){let r=n=>{this.storedResolutions.delete(n),this.storedDescriptors.delete(n)},i=n=>{this.originalPackages.delete(n),this.storedPackages.delete(n),this.accessibleLocators.delete(n)};if("descriptorHash"in e){let n=this.storedResolutions.get(e.descriptorHash);r(e.descriptorHash);let s=new Set(this.storedResolutions.values());typeof n!="undefined"&&!s.has(n)&&i(n)}if("locatorHash"in e){i(e.locatorHash);for(let[n,s]of this.storedResolutions)s===e.locatorHash&&r(n)}}forgetTransientResolutions(){let e=this.configuration.makeResolver();for(let r of this.originalPackages.values()){let i;try{i=e.shouldPersistResolution(r,{project:this,resolver:e})}catch{i=!1}i||this.forgetResolution(r)}}forgetVirtualResolutions(){for(let e of this.storedPackages.values())for(let[r,i]of e.dependencies)hA(i)&&e.dependencies.set(r,Ap(i))}getDependencyMeta(e,r){let i={},s=this.topLevelWorkspace.manifest.dependenciesMeta.get(St(e));if(!s)return i;let o=s.get(null);if(o&&Object.assign(i,o),r===null||!x$.default.valid(r))return i;for(let[a,l]of s)a!==null&&a===r&&Object.assign(i,l);return i}async findLocatorForLocation(e,{strict:r=!1}={}){let i=new ei,n=this.configuration.getLinkers(),s={project:this,report:i};for(let o of n){let a=await o.findPackageLocator(e,s);if(a){if(r&&(await o.findPackageLocation(a,s)).replace(P$,"")!==e.replace(P$,""))continue;return a}}return null}async resolveEverything(e){if(!this.workspacesByCwd||!this.workspacesByIdent)throw new Error("Workspaces must have been setup before calling this function");this.forgetVirtualResolutions(),e.lockfileOnly||this.forgetTransientResolutions();let r=e.resolver||this.configuration.makeResolver(),i=new oF;await i.setup(this,{report:e.report});let n=e.lockfileOnly?[new AF(r)]:[i,r],s=new pd([new aF(r),...n]),o=this.configuration.makeFetcher(),a=e.lockfileOnly?{project:this,report:e.report,resolver:s}:{project:this,report:e.report,resolver:s,fetchOptions:{project:this,cache:e.cache,checksums:this.storedChecksums,report:e.report,fetcher:o,cacheOptions:{mirrorWriteOnly:!0}}},l=new Map,c=new Map,u=new Map,g=new Map,f=new Map,h=new Map,p=this.topLevelWorkspace.anchoredLocator,d=new Set,m=[],I=async W=>{let X=await du(async()=>await s.resolve(W,a),D=>`${lt(this.configuration,W)}: ${D}`);if(!up(W,X))throw new Error(`Assertion failed: The locator cannot be changed by the resolver (went from ${lt(this.configuration,W)} to ${lt(this.configuration,X)})`);g.set(X.locatorHash,X);let F=this.configuration.normalizePackage(X);for(let[D,he]of F.dependencies){let pe=await this.configuration.reduceHook(Pe=>Pe.reduceDependency,he,this,F,he,{resolver:s,resolveOptions:a});if(!cp(he,pe))throw new Error("Assertion failed: The descriptor ident cannot be changed through aliases");let Ne=s.bindDescriptor(pe,W,a);F.dependencies.set(D,Ne)}return m.push(Promise.all([...F.dependencies.values()].map(D=>H(D)))),c.set(F.locatorHash,F),F},B=async W=>{let X=f.get(W.locatorHash);if(typeof X!="undefined")return X;let F=Promise.resolve().then(()=>I(W));return f.set(W.locatorHash,F),F},b=async(W,X)=>{let F=await H(X);return l.set(W.descriptorHash,W),u.set(W.descriptorHash,F.locatorHash),F},R=async W=>{let X=this.resolutionAliases.get(W.descriptorHash);if(typeof X!="undefined")return b(W,this.storedDescriptors.get(X));let F=s.getResolutionDependencies(W,a),D=new Map(await Promise.all(F.map(async Ne=>{let Pe=s.bindDescriptor(Ne,p,a),qe=await H(Pe);return d.add(qe.locatorHash),[Ne.descriptorHash,qe]}))),pe=(await du(async()=>await s.getCandidates(W,D,a),Ne=>`${Xt(this.configuration,W)}: ${Ne}`))[0];if(typeof pe=="undefined")throw new Error(`${Xt(this.configuration,W)}: No candidates found`);return l.set(W.descriptorHash,W),u.set(W.descriptorHash,pe.locatorHash),B(pe)},H=W=>{let X=h.get(W.descriptorHash);if(typeof X!="undefined")return X;l.set(W.descriptorHash,W);let F=Promise.resolve().then(()=>R(W));return h.set(W.descriptorHash,F),F};for(let W of this.workspaces){let X=W.anchoredDescriptor;m.push(H(X))}for(;m.length>0;){let W=[...m];m.length=0,await Promise.all(W)}let L=new Set(this.resolutionAliases.values()),K=new Set(c.keys()),J=new Set,ne=new Map;lUe({project:this,report:e.report,accessibleLocators:J,volatileDescriptors:L,optionalBuilds:K,peerRequirements:ne,allDescriptors:l,allResolutions:u,allPackages:c});for(let W of d)K.delete(W);for(let W of L)l.delete(W),u.delete(W);let q=this.configuration.getSupportedArchitectures(),A=new Set,V=new Set;for(let W of c.values())W.conditions!=null&&(!K.has(W.locatorHash)||(Sy(W,q)||(Sy(W,{os:[process.platform],cpu:[process.arch]})&&e.report.reportWarningOnce(z.GHOST_ARCHITECTURE,`${lt(this.configuration,W)}: Your current architecture (${process.platform}-${process.arch}) is supported by this package, but is missing from the ${Ve(this.configuration,"supportedArchitectures",ps.SETTING)} setting`),V.add(W.locatorHash)),A.add(W.locatorHash)));this.storedResolutions=u,this.storedDescriptors=l,this.storedPackages=c,this.accessibleLocators=J,this.conditionalLocators=A,this.disabledLocators=V,this.originalPackages=g,this.optionalBuilds=K,this.peerRequirements=ne,this.refreshWorkspaceDependencies()}async fetchEverything({cache:e,report:r,fetcher:i,mode:n}){let s={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators},o=i||this.configuration.makeFetcher(),a={checksums:this.storedChecksums,project:this,cache:e,fetcher:o,report:r,cacheOptions:s},l=Array.from(new Set(gn(this.storedResolutions.values(),[f=>{let h=this.storedPackages.get(f);if(!h)throw new Error("Assertion failed: The locator should have been registered");return is(h)}])));n===li.UpdateLockfile&&(l=l.filter(f=>!this.storedChecksums.has(f)));let c=!1,u=Xi.progressViaCounter(l.length);r.reportProgress(u);let g=(0,S$.default)(oUe);if(await r.startCacheReport(async()=>{await Promise.all(l.map(f=>g(async()=>{let h=this.storedPackages.get(f);if(!h)throw new Error("Assertion failed: The locator should have been registered");if(Io(h))return;let p;try{p=await o.fetch(h,a)}catch(d){d.message=`${lt(this.configuration,h)}: ${d.message}`,r.reportExceptionOnce(d),c=d;return}p.checksum!=null?this.storedChecksums.set(h.locatorHash,p.checksum):this.storedChecksums.delete(h.locatorHash),p.releaseFs&&p.releaseFs()}).finally(()=>{u.tick()})))}),c)throw c}async linkEverything({cache:e,report:r,fetcher:i,mode:n}){var A,V,W;let s={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators,skipIntegrityCheck:!0},o=i||this.configuration.makeFetcher(),a={checksums:this.storedChecksums,project:this,cache:e,fetcher:o,report:r,skipIntegrityCheck:!0,cacheOptions:s},l=this.configuration.getLinkers(),c={project:this,report:r},u=new Map(l.map(X=>{let F=X.makeInstaller(c),D=F.getCustomDataKey(),he=this.installersCustomData.get(D);return typeof he!="undefined"&&F.attachCustomData(he),[X,F]})),g=new Map,f=new Map,h=new Map,p=new Map(await Promise.all([...this.accessibleLocators].map(async X=>{let F=this.storedPackages.get(X);if(!F)throw new Error("Assertion failed: The locator should have been registered");return[X,await o.fetch(F,a)]}))),d=[];for(let X of this.accessibleLocators){let F=this.storedPackages.get(X);if(typeof F=="undefined")throw new Error("Assertion failed: The locator should have been registered");let D=p.get(F.locatorHash);if(typeof D=="undefined")throw new Error("Assertion failed: The fetch result should have been registered");let he=[],pe=Pe=>{he.push(Pe)},Ne=this.tryWorkspaceByLocator(F);if(Ne!==null){let Pe=[],{scripts:qe}=Ne.manifest;for(let se of["preinstall","install","postinstall"])qe.has(se)&&Pe.push([Gn.SCRIPT,se]);try{for(let[se,be]of u)if(se.supportsPackage(F,c)&&(await be.installPackage(F,D,{holdFetchResult:pe})).buildDirective!==null)throw new Error("Assertion failed: Linkers can't return build directives for workspaces; this responsibility befalls to the Yarn core")}finally{he.length===0?(A=D.releaseFs)==null||A.call(D):d.push(Promise.all(he).catch(()=>{}).then(()=>{var se;(se=D.releaseFs)==null||se.call(D)}))}let re=v.join(D.packageFs.getRealPath(),D.prefixPath);f.set(F.locatorHash,re),!Io(F)&&Pe.length>0&&h.set(F.locatorHash,{directives:Pe,buildLocations:[re]})}else{let Pe=l.find(se=>se.supportsPackage(F,c));if(!Pe)throw new nt(z.LINKER_NOT_FOUND,`${lt(this.configuration,F)} isn't supported by any available linker`);let qe=u.get(Pe);if(!qe)throw new Error("Assertion failed: The installer should have been registered");let re;try{re=await qe.installPackage(F,D,{holdFetchResult:pe})}finally{he.length===0?(V=D.releaseFs)==null||V.call(D):d.push(Promise.all(he).then(()=>{}).then(()=>{var se;(se=D.releaseFs)==null||se.call(D)}))}g.set(F.locatorHash,Pe),f.set(F.locatorHash,re.packageLocation),re.buildDirective&&re.buildDirective.length>0&&re.packageLocation&&h.set(F.locatorHash,{directives:re.buildDirective,buildLocations:[re.packageLocation]})}}let m=new Map;for(let X of this.accessibleLocators){let F=this.storedPackages.get(X);if(!F)throw new Error("Assertion failed: The locator should have been registered");let D=this.tryWorkspaceByLocator(F)!==null,he=async(pe,Ne)=>{let Pe=f.get(F.locatorHash);if(typeof Pe=="undefined")throw new Error(`Assertion failed: The package (${lt(this.configuration,F)}) should have been registered`);let qe=[];for(let re of F.dependencies.values()){let se=this.storedResolutions.get(re.descriptorHash);if(typeof se=="undefined")throw new Error(`Assertion failed: The resolution (${Xt(this.configuration,re)}, from ${lt(this.configuration,F)})should have been registered`);let be=this.storedPackages.get(se);if(typeof be=="undefined")throw new Error(`Assertion failed: The package (${se}, resolved from ${Xt(this.configuration,re)}) should have been registered`);let ae=this.tryWorkspaceByLocator(be)===null?g.get(se):null;if(typeof ae=="undefined")throw new Error(`Assertion failed: The package (${se}, resolved from ${Xt(this.configuration,re)}) should have been registered`);ae===pe||ae===null?f.get(be.locatorHash)!==null&&qe.push([re,be]):!D&&Pe!==null&&hu(m,se).push(Pe)}Pe!==null&&await Ne.attachInternalDependencies(F,qe)};if(D)for(let[pe,Ne]of u)pe.supportsPackage(F,c)&&await he(pe,Ne);else{let pe=g.get(F.locatorHash);if(!pe)throw new Error("Assertion failed: The linker should have been found");let Ne=u.get(pe);if(!Ne)throw new Error("Assertion failed: The installer should have been registered");await he(pe,Ne)}}for(let[X,F]of m){let D=this.storedPackages.get(X);if(!D)throw new Error("Assertion failed: The package should have been registered");let he=g.get(D.locatorHash);if(!he)throw new Error("Assertion failed: The linker should have been found");let pe=u.get(he);if(!pe)throw new Error("Assertion failed: The installer should have been registered");await pe.attachExternalDependents(D,F)}let I=new Map;for(let X of u.values()){let F=await X.finalizeInstall();for(let D of(W=F==null?void 0:F.records)!=null?W:[])h.set(D.locatorHash,{directives:D.buildDirective,buildLocations:D.buildLocations});typeof(F==null?void 0:F.customData)!="undefined"&&I.set(X.getCustomDataKey(),F.customData)}if(this.installersCustomData=I,await Promise.all(d),n===li.SkipBuild)return;let B=new Set(this.storedPackages.keys()),b=new Set(h.keys());for(let X of b)B.delete(X);let R=(0,t0.createHash)("sha512");R.update(process.versions.node),await this.configuration.triggerHook(X=>X.globalHashGeneration,this,X=>{R.update("\0"),R.update(X)});let H=R.digest("hex"),L=new Map,K=X=>{let F=L.get(X.locatorHash);if(typeof F!="undefined")return F;let D=this.storedPackages.get(X.locatorHash);if(typeof D=="undefined")throw new Error("Assertion failed: The package should have been registered");let he=(0,t0.createHash)("sha512");he.update(X.locatorHash),L.set(X.locatorHash,"");for(let pe of D.dependencies.values()){let Ne=this.storedResolutions.get(pe.descriptorHash);if(typeof Ne=="undefined")throw new Error(`Assertion failed: The resolution (${Xt(this.configuration,pe)}) should have been registered`);let Pe=this.storedPackages.get(Ne);if(typeof Pe=="undefined")throw new Error("Assertion failed: The package should have been registered");he.update(K(Pe))}return F=he.digest("hex"),L.set(X.locatorHash,F),F},J=(X,F)=>{let D=(0,t0.createHash)("sha512");D.update(H),D.update(K(X));for(let he of F)D.update(he);return D.digest("hex")},ne=new Map,q=!1;for(;b.size>0;){let X=b.size,F=[];for(let D of b){let he=this.storedPackages.get(D);if(!he)throw new Error("Assertion failed: The package should have been registered");let pe=!0;for(let qe of he.dependencies.values()){let re=this.storedResolutions.get(qe.descriptorHash);if(!re)throw new Error(`Assertion failed: The resolution (${Xt(this.configuration,qe)}) should have been registered`);if(b.has(re)){pe=!1;break}}if(!pe)continue;b.delete(D);let Ne=h.get(he.locatorHash);if(!Ne)throw new Error("Assertion failed: The build directive should have been registered");let Pe=J(he,Ne.buildLocations);if(this.storedBuildState.get(he.locatorHash)===Pe){ne.set(he.locatorHash,Pe);continue}q||(await this.persistInstallStateFile(),q=!0),this.storedBuildState.has(he.locatorHash)?r.reportInfo(z.MUST_REBUILD,`${lt(this.configuration,he)} must be rebuilt because its dependency tree changed`):r.reportInfo(z.MUST_BUILD,`${lt(this.configuration,he)} must be built because it never has been before or the last one failed`);for(let qe of Ne.buildLocations){if(!v.isAbsolute(qe))throw new Error(`Assertion failed: Expected the build location to be absolute (not ${qe})`);F.push((async()=>{for(let[re,se]of Ne.directives){let be=`# This file contains the result of Yarn building a package (${is(he)}) +`;switch(re){case Gn.SCRIPT:be+=`# Script name: ${se} +`;break;case Gn.SHELLCODE:be+=`# Script code: ${se} +`;break}let ae=null;if(!await T.mktempPromise(async De=>{let $=v.join(De,"build.log"),{stdout:G,stderr:Ce}=this.configuration.getSubprocessStreams($,{header:be,prefix:lt(this.configuration,he),report:r}),ee;try{switch(re){case Gn.SCRIPT:ee=await Uw(he,se,[],{cwd:qe,project:this,stdin:ae,stdout:G,stderr:Ce});break;case Gn.SHELLCODE:ee=await rD(he,se,[],{cwd:qe,project:this,stdin:ae,stdout:G,stderr:Ce});break}}catch(Oe){Ce.write(Oe.stack),ee=1}if(G.end(),Ce.end(),ee===0)return ne.set(he.locatorHash,Pe),!0;T.detachTemp(De);let Ue=`${lt(this.configuration,he)} couldn't be built successfully (exit code ${Ve(this.configuration,ee,Le.NUMBER)}, logs can be found here: ${Ve(this.configuration,$,Le.PATH)})`;return this.optionalBuilds.has(he.locatorHash)?(r.reportInfo(z.BUILD_FAILED,Ue),ne.set(he.locatorHash,Pe),!0):(r.reportError(z.BUILD_FAILED,Ue),!1)}))return}})())}}if(await Promise.all(F),X===b.size){let D=Array.from(b).map(he=>{let pe=this.storedPackages.get(he);if(!pe)throw new Error("Assertion failed: The package should have been registered");return lt(this.configuration,pe)}).join(", ");r.reportError(z.CYCLIC_DEPENDENCIES,`Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${D})`);break}}this.storedBuildState=ne}async install(e){var a,l;let r=this.configuration.get("nodeLinker");(a=fe.telemetry)==null||a.reportInstall(r),await e.report.startTimerPromise("Project validation",{skipIfEmpty:!0},async()=>{await this.configuration.triggerHook(c=>c.validateProject,this,{reportWarning:e.report.reportWarning.bind(e.report),reportError:e.report.reportError.bind(e.report)})});for(let c of this.configuration.packageExtensions.values())for(let[,u]of c)for(let g of u)g.status=ki.Inactive;let i=v.join(this.cwd,this.configuration.get("lockfileFilename")),n=null;if(e.immutable)try{n=await T.readFilePromise(i,"utf8")}catch(c){throw c.code==="ENOENT"?new nt(z.FROZEN_LOCKFILE_EXCEPTION,"The lockfile would have been created by this install, which is explicitly forbidden."):c}await e.report.startTimerPromise("Resolution step",async()=>{await this.resolveEverything(e)}),await e.report.startTimerPromise("Post-resolution validation",{skipIfEmpty:!0},async()=>{for(let[,c]of this.configuration.packageExtensions)for(let[,u]of c)for(let g of u)if(g.userProvided){let f=Ve(this.configuration,g,Le.PACKAGE_EXTENSION);switch(g.status){case ki.Inactive:e.report.reportWarning(z.UNUSED_PACKAGE_EXTENSION,`${f}: No matching package in the dependency tree; you may not need this rule anymore.`);break;case ki.Redundant:e.report.reportWarning(z.REDUNDANT_PACKAGE_EXTENSION,`${f}: This rule seems redundant when applied on the original package; the extension may have been applied upstream.`);break}}if(n!==null){let c=ul(n,this.generateLockfile());if(c!==n){let u=(0,v$.structuredPatch)(i,i,n,c);e.report.reportSeparator();for(let g of u.hunks){e.report.reportInfo(null,`@@ -${g.oldStart},${g.oldLines} +${g.newStart},${g.newLines} @@`);for(let f of g.lines)f.startsWith("+")?e.report.reportError(z.FROZEN_LOCKFILE_EXCEPTION,Ve(this.configuration,f,Le.ADDED)):f.startsWith("-")?e.report.reportError(z.FROZEN_LOCKFILE_EXCEPTION,Ve(this.configuration,f,Le.REMOVED)):e.report.reportInfo(null,Ve(this.configuration,f,"grey"))}throw e.report.reportSeparator(),new nt(z.FROZEN_LOCKFILE_EXCEPTION,"The lockfile would have been modified by this install, which is explicitly forbidden.")}}});for(let c of this.configuration.packageExtensions.values())for(let[,u]of c)for(let g of u)g.userProvided&&g.status===ki.Active&&((l=fe.telemetry)==null||l.reportPackageExtension(Uu(g,Le.PACKAGE_EXTENSION)));await e.report.startTimerPromise("Fetch step",async()=>{await this.fetchEverything(e),(typeof e.persistProject=="undefined"||e.persistProject)&&e.mode!==li.UpdateLockfile&&await this.cacheCleanup(e)});let s=e.immutable?[...new Set(this.configuration.get("immutablePatterns"))].sort():[],o=await Promise.all(s.map(async c=>Iy(c,{cwd:this.cwd})));(typeof e.persistProject=="undefined"||e.persistProject)&&await this.persist(),await e.report.startTimerPromise("Link step",async()=>{if(e.mode===li.UpdateLockfile){e.report.reportWarning(z.UPDATE_LOCKFILE_ONLY_SKIP_LINK,`Skipped due to ${Ve(this.configuration,"mode=update-lockfile",Le.CODE)}`);return}await this.linkEverything(e);let c=await Promise.all(s.map(async u=>Iy(u,{cwd:this.cwd})));for(let u=0;uc.afterAllInstalled,this,e)}generateLockfile(){let e=new Map;for(let[n,s]of this.storedResolutions.entries()){let o=e.get(s);o||e.set(s,o=new Set),o.add(n)}let r={};r.__metadata={version:k$,cacheKey:void 0};for(let[n,s]of e.entries()){let o=this.originalPackages.get(n);if(!o)continue;let a=[];for(let f of s){let h=this.storedDescriptors.get(f);if(!h)throw new Error("Assertion failed: The descriptor should have been registered");a.push(h)}let l=a.map(f=>In(f)).sort().join(", "),c=new Ze;c.version=o.linkType===gt.HARD?o.version:"0.0.0-use.local",c.languageName=o.languageName,c.dependencies=new Map(o.dependencies),c.peerDependencies=new Map(o.peerDependencies),c.dependenciesMeta=new Map(o.dependenciesMeta),c.peerDependenciesMeta=new Map(o.peerDependenciesMeta),c.bin=new Map(o.bin);let u,g=this.storedChecksums.get(o.locatorHash);if(typeof g!="undefined"){let f=g.indexOf("/");if(f===-1)throw new Error("Assertion failed: Expected the checksum to reference its cache key");let h=g.slice(0,f),p=g.slice(f+1);typeof r.__metadata.cacheKey=="undefined"&&(r.__metadata.cacheKey=h),h===r.__metadata.cacheKey?u=p:u=g}r[l]=_(P({},c.exportTo({},{compatibilityMode:!1})),{linkType:o.linkType.toLowerCase(),resolution:is(o),checksum:u,conditions:o.conditions||void 0})}return`${[`# This file is generated by running "yarn install" inside your project. +`,`# Manual changes might be lost - proceed with caution! +`].join("")} +`+Qa(r)}async persistLockfile(){let e=v.join(this.cwd,this.configuration.get("lockfileFilename")),r="";try{r=await T.readFilePromise(e,"utf8")}catch(s){}let i=this.generateLockfile(),n=ul(r,i);n!==r&&(await T.writeFilePromise(e,n),this.lockFileChecksum=D$(n),this.lockfileNeedsRefresh=!1)}async persistInstallStateFile(){let e=[];for(let o of Object.values(gF))e.push(...o);let r=(0,r0.default)(this,e),i=cF.default.serialize(r),n=zi(i);if(this.installStateChecksum===n)return;let s=this.configuration.get("installStatePath");await T.mkdirPromise(v.dirname(s),{recursive:!0}),await T.writeFilePromise(s,await aUe(i)),this.installStateChecksum=n}async restoreInstallState({restoreInstallersCustomData:e=!0,restoreResolutions:r=!0,restoreBuildState:i=!0}={}){let n=this.configuration.get("installStatePath");if(!T.existsSync(n)){r&&await this.applyLightResolution();return}let s=await AUe(await T.readFilePromise(n));this.installStateChecksum=zi(s);let o=cF.default.deserialize(s);e&&typeof o.installersCustomData!="undefined"&&(this.installersCustomData=o.installersCustomData),i&&Object.assign(this,(0,r0.default)(o,gF.restoreBuildState)),r&&(o.lockFileChecksum===this.lockFileChecksum?(Object.assign(this,(0,r0.default)(o,gF.restoreResolutions)),this.refreshWorkspaceDependencies()):await this.applyLightResolution())}async applyLightResolution(){await this.resolveEverything({lockfileOnly:!0,report:new ei}),await this.persistInstallStateFile()}async persist(){await this.persistLockfile();for(let e of this.workspacesByCwd.values())await e.persistManifest()}async cacheCleanup({cache:e,report:r}){let i=new Set([".gitignore"]);if(!Fb(e.cwd,this.cwd)||!await T.existsPromise(e.cwd))return;let n=this.configuration.get("preferAggregateCacheInfo"),s=0,o=null;for(let a of await T.readdirPromise(e.cwd)){if(i.has(a))continue;let l=v.resolve(e.cwd,a);e.markedFiles.has(l)||(o=a,e.immutable?r.reportError(z.IMMUTABLE_CACHE,`${Ve(this.configuration,v.basename(l),"magenta")} appears to be unused and would be marked for deletion, but the cache is immutable`):(n?s+=1:r.reportInfo(z.UNUSED_CACHE_ENTRY,`${Ve(this.configuration,v.basename(l),"magenta")} appears to be unused - removing`),await T.removePromise(l)))}n&&s!==0&&r.reportInfo(z.UNUSED_CACHE_ENTRY,s>1?`${s} packages appeared to be unused and were removed`:`${o} appeared to be unused and was removed`),e.markedFiles.clear()}};function lUe({project:t,allDescriptors:e,allResolutions:r,allPackages:i,accessibleLocators:n=new Set,optionalBuilds:s=new Set,volatileDescriptors:o=new Set,peerRequirements:a=new Map,report:l,tolerateMissingPackages:c=!1}){var ne;let u=new Map,g=[],f=new Map,h=new Map,p=new Map,d=new Map,m=new Map,I=new Map(t.workspaces.map(q=>{let A=q.anchoredLocator.locatorHash,V=i.get(A);if(typeof V=="undefined"){if(c)return[A,null];throw new Error("Assertion failed: The workspace should have an associated package")}return[A,ap(V)]})),B=()=>{let q=T.mktempSync(),A=v.join(q,"stacktrace.log"),V=String(g.length+1).length,W=g.map((X,F)=>`${`${F+1}.`.padStart(V," ")} ${is(X)} +`).join("");throw T.writeFileSync(A,W),T.detachTemp(q),new nt(z.STACK_OVERFLOW_RESOLUTION,`Encountered a stack overflow when resolving peer dependencies; cf ${M.fromPortablePath(A)}`)},b=q=>{let A=r.get(q.descriptorHash);if(typeof A=="undefined")throw new Error("Assertion failed: The resolution should have been registered");let V=i.get(A);if(!V)throw new Error("Assertion failed: The package could not be found");return V},R=(q,A,V,{top:W,optional:X})=>{g.length>1e3&&B(),g.push(A);let F=H(q,A,V,{top:W,optional:X});return g.pop(),F},H=(q,A,V,{top:W,optional:X})=>{if(n.has(A.locatorHash))return;n.add(A.locatorHash),X||s.delete(A.locatorHash);let F=i.get(A.locatorHash);if(!F){if(c)return;throw new Error(`Assertion failed: The package (${lt(t.configuration,A)}) should have been registered`)}let D=[],he=[],pe=[],Ne=[],Pe=[];for(let re of Array.from(F.dependencies.values())){if(F.peerDependencies.has(re.identHash)&&F.locatorHash!==W)continue;if(hA(re))throw new Error("Assertion failed: Virtual packages shouldn't be encountered when virtualizing a branch");o.delete(re.descriptorHash);let se=X;if(!se){let ee=F.dependenciesMeta.get(St(re));if(typeof ee!="undefined"){let Ue=ee.get(null);typeof Ue!="undefined"&&Ue.optional&&(se=!0)}}let be=r.get(re.descriptorHash);if(!be){if(c)continue;throw new Error(`Assertion failed: The resolution (${Xt(t.configuration,re)}) should have been registered`)}let ae=I.get(be)||i.get(be);if(!ae)throw new Error(`Assertion failed: The package (${be}, resolved from ${Xt(t.configuration,re)}) should have been registered`);if(ae.peerDependencies.size===0){R(re,ae,new Map,{top:W,optional:se});continue}let Ae=u.get(ae.locatorHash);typeof Ae=="number"&&Ae>=2&&B();let De,$,G=new Set,Ce;he.push(()=>{De=kx(re,A.locatorHash),$=Px(ae,A.locatorHash),F.dependencies.delete(re.identHash),F.dependencies.set(De.identHash,De),r.set(De.descriptorHash,$.locatorHash),e.set(De.descriptorHash,De),i.set($.locatorHash,$),D.push([ae,De,$])}),pe.push(()=>{var ee;Ce=new Map;for(let Ue of $.peerDependencies.values()){let Oe=F.dependencies.get(Ue.identHash);if(!Oe&&cp(A,Ue)&&(Oe=q),(!Oe||Oe.range==="missing:")&&$.dependencies.has(Ue.identHash)){$.peerDependencies.delete(Ue.identHash);continue}Oe||(Oe=Yt(Ue,"missing:")),$.dependencies.set(Oe.identHash,Oe),hA(Oe)&&Pl(p,Oe.descriptorHash).add($.locatorHash),f.set(Oe.identHash,Oe),Oe.range==="missing:"&&G.add(Oe.identHash),Ce.set(Ue.identHash,(ee=V.get(Ue.identHash))!=null?ee:$.locatorHash)}$.dependencies=new Map(gn($.dependencies,([Ue,Oe])=>St(Oe)))}),Ne.push(()=>{if(!i.has($.locatorHash))return;let ee=u.get(ae.locatorHash),Ue=typeof ee!="undefined"?ee+1:1;u.set(ae.locatorHash,Ue),R(De,$,Ce,{top:W,optional:se}),u.set(ae.locatorHash,Ue-1)}),Pe.push(()=>{let ee=F.dependencies.get(re.identHash);if(typeof ee=="undefined")throw new Error("Assertion failed: Expected the peer dependency to have been turned into a dependency");let Ue=r.get(ee.descriptorHash);if(typeof Ue=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");if(Pl(m,Ue).add(A.locatorHash),!!i.has($.locatorHash)){for(let Oe of $.peerDependencies.values()){let vt=Ce.get(Oe.identHash);if(typeof vt=="undefined")throw new Error("Assertion failed: Expected the peer dependency ident to be registered");hu(pu(d,vt),St(Oe)).push($.locatorHash)}for(let Oe of G)$.dependencies.delete(Oe)}})}for(let re of[...he,...pe])re();let qe;do{qe=!0;for(let[re,se,be]of D){if(!i.has(be.locatorHash))continue;let ae=pu(h,re.locatorHash),Ae=zi(...[...be.dependencies.values()].map(Ce=>{let ee=Ce.range!=="missing:"?r.get(Ce.descriptorHash):"missing:";if(typeof ee=="undefined")throw new Error(`Assertion failed: Expected the resolution for ${Xt(t.configuration,Ce)} to have been registered`);return ee===W?`${ee} (top)`:ee}),se.identHash),De=ae.get(Ae);if(typeof De=="undefined"){ae.set(Ae,se);continue}if(De===se)continue;qe=!1,i.delete(be.locatorHash),e.delete(se.descriptorHash),r.delete(se.descriptorHash),n.delete(be.locatorHash);let $=p.get(se.descriptorHash)||[],G=[F.locatorHash,...$];p.delete(se.descriptorHash);for(let Ce of G){let ee=i.get(Ce);typeof ee!="undefined"&&ee.dependencies.set(se.identHash,De)}}}while(!qe);for(let re of[...Ne,...Pe])re()};for(let q of t.workspaces){let A=q.anchoredLocator;o.delete(q.anchoredDescriptor.descriptorHash),R(q.anchoredDescriptor,A,new Map,{top:A.locatorHash,optional:!1})}var L;(function(V){V[V.NotProvided=0]="NotProvided",V[V.NotCompatible=1]="NotCompatible"})(L||(L={}));let K=[];for(let[q,A]of m){let V=i.get(q);if(typeof V=="undefined")throw new Error("Assertion failed: Expected the root to be registered");let W=d.get(q);if(typeof W!="undefined")for(let X of A){let F=i.get(X);if(typeof F!="undefined")for(let[D,he]of W){let pe=En(D);if(F.peerDependencies.has(pe.identHash))continue;let Ne=`p${zi(X,D,q).slice(0,5)}`;a.set(Ne,{subject:X,requested:pe,rootRequester:q,allRequesters:he});let Pe=V.dependencies.get(pe.identHash);if(typeof Pe!="undefined"){let qe=b(Pe),re=(ne=qe.version)!=null?ne:"0.0.0",se=new Set;for(let ae of he){let Ae=i.get(ae);if(typeof Ae=="undefined")throw new Error("Assertion failed: Expected the link to be registered");let De=Ae.peerDependencies.get(pe.identHash);if(typeof De=="undefined")throw new Error("Assertion failed: Expected the ident to be registered");se.add(De.range)}[...se].every(ae=>{if(ae.startsWith(Yr.protocol)){if(!t.tryWorkspaceByLocator(qe))return!1;ae=ae.slice(Yr.protocol.length),(ae==="^"||ae==="~")&&(ae="*")}return lc(re,ae)})||K.push({type:1,subject:F,requested:pe,requester:V,version:re,hash:Ne,requirementCount:he.length})}else{let qe=V.peerDependenciesMeta.get(D);(qe==null?void 0:qe.optional)||K.push({type:0,subject:F,requested:pe,requester:V,hash:Ne})}}}}let J=[q=>Rx(q.subject),q=>St(q.requested),q=>`${q.type}`];for(let q of gn(K,J))switch(q.type){case 0:l==null||l.reportWarning(z.MISSING_PEER_DEPENDENCY,`${lt(t.configuration,q.subject)} doesn't provide ${Vr(t.configuration,q.requested)} (${Ve(t.configuration,q.hash,Le.CODE)}), requested by ${Vr(t.configuration,q.requester)}`);break;case 1:{let A=q.requirementCount>1?"and some of its descendants request":"requests";l==null||l.reportWarning(z.INCOMPATIBLE_PEER_DEPENDENCY,`${lt(t.configuration,q.subject)} provides ${Vr(t.configuration,q.requested)} (${Ve(t.configuration,q.hash,Le.CODE)}) with version ${fp(t.configuration,q.version)}, which doesn't satisfy what ${Vr(t.configuration,q.requester)} ${A}`)}break}K.length>0&&(l==null||l.reportWarning(z.UNNAMED,`Some peer dependencies are incorrectly met; run ${Ve(t.configuration,"yarn explain peer-requirements ",Le.CODE)} for details, where ${Ve(t.configuration,"",Le.CODE)} is the six-letter p-prefixed code`))}var Po;(function(l){l.VERSION="version",l.COMMAND_NAME="commandName",l.PLUGIN_NAME="pluginName",l.INSTALL_COUNT="installCount",l.PROJECT_COUNT="projectCount",l.WORKSPACE_COUNT="workspaceCount",l.DEPENDENCY_COUNT="dependencyCount",l.EXTENSION="packageExtension"})(Po||(Po={}));var Rd=class{constructor(e,r){this.values=new Map;this.hits=new Map;this.enumerators=new Map;this.configuration=e;let i=this.getRegistryPath();this.isNew=!T.existsSync(i),this.sendReport(r),this.startBuffer()}reportVersion(e){this.reportValue(Po.VERSION,e.replace(/-git\..*/,"-git"))}reportCommandName(e){this.reportValue(Po.COMMAND_NAME,e||"")}reportPluginName(e){this.reportValue(Po.PLUGIN_NAME,e)}reportProject(e){this.reportEnumerator(Po.PROJECT_COUNT,e)}reportInstall(e){this.reportHit(Po.INSTALL_COUNT,e)}reportPackageExtension(e){this.reportValue(Po.EXTENSION,e)}reportWorkspaceCount(e){this.reportValue(Po.WORKSPACE_COUNT,String(e))}reportDependencyCount(e){this.reportValue(Po.DEPENDENCY_COUNT,String(e))}reportValue(e,r){Pl(this.values,e).add(r)}reportEnumerator(e,r){Pl(this.enumerators,e).add(zi(r))}reportHit(e,r="*"){let i=pu(this.hits,e),n=na(i,r,()=>0);i.set(r,n+1)}getRegistryPath(){let e=this.configuration.get("globalFolder");return v.join(e,"telemetry.json")}sendReport(e){var u,g,f;let r=this.getRegistryPath(),i;try{i=T.readJsonSync(r)}catch{i={}}let n=Date.now(),s=this.configuration.get("telemetryInterval")*24*60*60*1e3,a=((u=i.lastUpdate)!=null?u:n+s+Math.floor(s*Math.random()))+s;if(a>n&&i.lastUpdate!=null)return;try{T.mkdirSync(v.dirname(r),{recursive:!0}),T.writeJsonSync(r,{lastUpdate:n})}catch{return}if(a>n||!i.blocks)return;let l=`https://browser-http-intake.logs.datadoghq.eu/v1/input/${e}?ddsource=yarn`,c=h=>iP(l,h,{configuration:this.configuration}).catch(()=>{});for(let[h,p]of Object.entries((g=i.blocks)!=null?g:{})){if(Object.keys(p).length===0)continue;let d=p;d.userId=h,d.reportType="primary";for(let B of Object.keys((f=d.enumerators)!=null?f:{}))d.enumerators[B]=d.enumerators[B].length;c(d);let m=new Map,I=20;for(let[B,b]of Object.entries(d.values))b.length>0&&m.set(B,b.slice(0,I));for(;m.size>0;){let B={};B.userId=h,B.reportType="secondary",B.metrics={};for(let[b,R]of m)B.metrics[b]=R.shift(),R.length===0&&m.delete(b);c(B)}}}applyChanges(){var o,a,l,c,u,g,f,h,p;let e=this.getRegistryPath(),r;try{r=T.readJsonSync(e)}catch{r={}}let i=(o=this.configuration.get("telemetryUserId"))!=null?o:"*",n=r.blocks=(a=r.blocks)!=null?a:{},s=n[i]=(l=n[i])!=null?l:{};for(let d of this.hits.keys()){let m=s.hits=(c=s.hits)!=null?c:{},I=m[d]=(u=m[d])!=null?u:{};for(let[B,b]of this.hits.get(d))I[B]=((g=I[B])!=null?g:0)+b}for(let d of["values","enumerators"])for(let m of this[d].keys()){let I=s[d]=(f=s[d])!=null?f:{};I[m]=[...new Set([...(h=I[m])!=null?h:[],...(p=this[d].get(m))!=null?p:[]])]}T.mkdirSync(v.dirname(e),{recursive:!0}),T.writeJsonSync(e,r)}startBuffer(){process.on("exit",()=>{try{this.applyChanges()}catch{}})}};var fF=ie(require("child_process")),R$=ie(ml());var hF=ie(require("fs"));var Yg=new Map([["constraints",[["constraints","query"],["constraints","source"],["constraints"]]],["exec",[]],["interactive-tools",[["search"],["upgrade-interactive"]]],["stage",[["stage"]]],["typescript",[]],["version",[["version","apply"],["version","check"],["version"]]],["workspace-tools",[["workspaces","focus"],["workspaces","foreach"]]]]);function cUe(t){let e=M.fromPortablePath(t);process.on("SIGINT",()=>{}),e?(0,fF.execFileSync)(process.execPath,[e,...process.argv.slice(2)],{stdio:"inherit",env:_(P({},process.env),{YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"})}):(0,fF.execFileSync)(e,process.argv.slice(2),{stdio:"inherit",env:_(P({},process.env),{YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"})})}async function i0({binaryVersion:t,pluginConfiguration:e}){async function r(){let n=new oo({binaryLabel:"Yarn Package Manager",binaryName:"yarn",binaryVersion:t});try{await i(n)}catch(s){process.stdout.write(n.error(s)),process.exitCode=1}}async function i(n){var p,d,m,I,B;let s=process.versions.node,o=">=12 <14 || 14.2 - 14.9 || >14.10.0";if(process.env.YARN_IGNORE_NODE!=="1"&&!qt.satisfiesWithPrereleases(s,o))throw new me(`This tool requires a Node version compatible with ${o} (got ${s}). Upgrade Node, or set \`YARN_IGNORE_NODE=1\` in your environment.`);let a=await fe.find(M.toPortablePath(process.cwd()),e,{usePath:!0,strict:!1}),l=a.get("yarnPath"),c=a.get("ignorePath"),u=a.get("ignoreCwd"),g=M.toPortablePath(M.resolve(process.argv[1])),f=b=>T.readFilePromise(b).catch(()=>Buffer.of());if(!c&&!u&&await(async()=>l===g||Buffer.compare(...await Promise.all([f(l),f(g)]))===0)()){process.env.YARN_IGNORE_PATH="1",process.env.YARN_IGNORE_CWD="1",await i(n);return}else if(l!==null&&!c)if(!T.existsSync(l))process.stdout.write(n.error(new Error(`The "yarn-path" option has been set (in ${a.sources.get("yarnPath")}), but the specified location doesn't exist (${l}).`))),process.exitCode=1;else try{cUe(l)}catch(b){process.exitCode=b.code||1}else{c&&delete process.env.YARN_IGNORE_PATH,a.get("enableTelemetry")&&!R$.isCI&&process.stdout.isTTY&&(fe.telemetry=new Rd(a,"puba9cdc10ec5790a2cf4969dd413a47270")),(p=fe.telemetry)==null||p.reportVersion(t);for(let[L,K]of a.plugins.entries()){Yg.has((m=(d=L.match(/^@yarnpkg\/plugin-(.*)$/))==null?void 0:d[1])!=null?m:"")&&((I=fe.telemetry)==null||I.reportPluginName(L));for(let J of K.commands||[])n.register(J)}let R=n.process(process.argv.slice(2));R.help||(B=fe.telemetry)==null||B.reportCommandName(R.path.join(" "));let H=R.cwd;if(typeof H!="undefined"&&!u){let L=(0,hF.realpathSync)(process.cwd()),K=(0,hF.realpathSync)(H);if(L!==K){process.chdir(H),await r();return}}await n.runExit(R,{cwd:M.toPortablePath(process.cwd()),plugins:e,quiet:!1,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr})}}return r().catch(n=>{process.stdout.write(n.stack||n.message),process.exitCode=1}).finally(()=>T.rmtempPromise())}function F$(t){t.Command.Path=(...e)=>r=>{r.paths=r.paths||[],r.paths.push(e)};for(let e of["Array","Boolean","String","Proxy","Rest","Counter"])t.Command[e]=(...r)=>(i,n)=>{let s=t.Option[e](...r);Object.defineProperty(i,`__${n}`,{configurable:!1,enumerable:!0,get(){return s},set(o){this[n]=o}})};return t}var iC={};it(iC,{BaseCommand:()=>Be,WorkspaceRequiredError:()=>rt,getDynamicLibs:()=>Wie,getPluginConfiguration:()=>F0,main:()=>i0,openWorkspace:()=>rf,pluginCommands:()=>Yg});var Be=class extends ye{constructor(){super(...arguments);this.cwd=Y.String("--cwd",{hidden:!0})}};var rt=class extends me{constructor(e,r){let i=v.relative(e,r),n=v.join(e,Ze.fileName);super(`This command can only be run from within a workspace of your project (${i} isn't a workspace of ${n}).`)}};var dJe=ie(Or());Ss();var CJe=ie(gN()),Wie=()=>new Map([["@yarnpkg/cli",iC],["@yarnpkg/core",Fd],["@yarnpkg/fslib",ch],["@yarnpkg/libzip",Fp],["@yarnpkg/parsers",Hp],["@yarnpkg/shell",jp],["clipanion",vh],["semver",dJe],["typanion",lu],["yup",CJe]]);async function rf(t,e){let{project:r,workspace:i}=await Ke.find(t,e);if(!i)throw new rt(r.cwd,e);return i}var x_e=ie(Or());Ss();var k_e=ie(gN());var hL={};it(hL,{dedupeUtils:()=>zN,default:()=>Qze,suggestUtils:()=>LN});var WAe=ie(ml());var roe=ie(aC());Ss();var LN={};it(LN,{Modifier:()=>Lo,Strategy:()=>Fr,Target:()=>vr,WorkspaceModifier:()=>af,applyModifier:()=>Zse,extractDescriptorFromPath:()=>ON,extractRangeModifier:()=>Xse,fetchDescriptorFrom:()=>MN,findProjectDescriptors:()=>toe,getModifier:()=>AC,getSuggestedDescriptors:()=>lC,makeWorkspaceDescriptor:()=>eoe,toWorkspaceModifier:()=>$se});var TN=ie(Or()),L3e="workspace:",vr;(function(i){i.REGULAR="dependencies",i.DEVELOPMENT="devDependencies",i.PEER="peerDependencies"})(vr||(vr={}));var Lo;(function(i){i.CARET="^",i.TILDE="~",i.EXACT=""})(Lo||(Lo={}));var af;(function(i){i.CARET="^",i.TILDE="~",i.EXACT="*"})(af||(af={}));var Fr;(function(s){s.KEEP="keep",s.REUSE="reuse",s.PROJECT="project",s.LATEST="latest",s.CACHE="cache"})(Fr||(Fr={}));function AC(t,e){return t.exact?Lo.EXACT:t.caret?Lo.CARET:t.tilde?Lo.TILDE:e.configuration.get("defaultSemverRangePrefix")}var T3e=/^([\^~]?)[0-9]+(?:\.[0-9]+){0,2}(?:-\S+)?$/;function Xse(t,{project:e}){let r=t.match(T3e);return r?r[1]:e.configuration.get("defaultSemverRangePrefix")}function Zse(t,e){let{protocol:r,source:i,params:n,selector:s}=S.parseRange(t.range);return TN.default.valid(s)&&(s=`${e}${t.range}`),S.makeDescriptor(t,S.makeRange({protocol:r,source:i,params:n,selector:s}))}function $se(t){switch(t){case Lo.CARET:return af.CARET;case Lo.TILDE:return af.TILDE;case Lo.EXACT:return af.EXACT;default:throw new Error(`Assertion failed: Unknown modifier: "${t}"`)}}function eoe(t,e){return S.makeDescriptor(t.anchoredDescriptor,`${L3e}${$se(e)}`)}async function toe(t,{project:e,target:r}){let i=new Map,n=s=>{let o=i.get(s.descriptorHash);return o||i.set(s.descriptorHash,o={descriptor:s,locators:[]}),o};for(let s of e.workspaces)if(r===vr.PEER){let o=s.manifest.peerDependencies.get(t.identHash);o!==void 0&&n(o).locators.push(s.locator)}else{let o=s.manifest.dependencies.get(t.identHash),a=s.manifest.devDependencies.get(t.identHash);r===vr.DEVELOPMENT?a!==void 0?n(a).locators.push(s.locator):o!==void 0&&n(o).locators.push(s.locator):o!==void 0?n(o).locators.push(s.locator):a!==void 0&&n(a).locators.push(s.locator)}return i}async function ON(t,{cwd:e,workspace:r}){return await M3e(async i=>{v.isAbsolute(t)||(t=v.relative(r.cwd,v.resolve(e,t)),t.match(/^\.{0,2}\//)||(t=`./${t}`));let{project:n}=r,s=await MN(S.makeIdent(null,"archive"),t,{project:r.project,cache:i,workspace:r});if(!s)throw new Error("Assertion failed: The descriptor should have been found");let o=new ei,a=n.configuration.makeResolver(),l=n.configuration.makeFetcher(),c={checksums:n.storedChecksums,project:n,cache:i,fetcher:l,report:o,resolver:a},u=a.bindDescriptor(s,r.anchoredLocator,c),g=S.convertDescriptorToLocator(u),f=await l.fetch(g,c),h=await Ze.find(f.prefixPath,{baseFs:f.packageFs});if(!h.name)throw new Error("Target path doesn't have a name");return S.makeDescriptor(h.name,t)})}async function lC(t,{project:e,workspace:r,cache:i,target:n,modifier:s,strategies:o,maxResults:a=Infinity}){if(!(a>=0))throw new Error(`Invalid maxResults (${a})`);if(t.range!=="unknown")return{suggestions:[{descriptor:t,name:`Use ${S.prettyDescriptor(e.configuration,t)}`,reason:"(unambiguous explicit request)"}],rejections:[]};let l=typeof r!="undefined"&&r!==null&&r.manifest[n].get(t.identHash)||null,c=[],u=[],g=async f=>{try{await f()}catch(h){u.push(h)}};for(let f of o){if(c.length>=a)break;switch(f){case Fr.KEEP:await g(async()=>{l&&c.push({descriptor:l,name:`Keep ${S.prettyDescriptor(e.configuration,l)}`,reason:"(no changes)"})});break;case Fr.REUSE:await g(async()=>{for(let{descriptor:h,locators:p}of(await toe(t,{project:e,target:n})).values()){if(p.length===1&&p[0].locatorHash===r.anchoredLocator.locatorHash&&o.includes(Fr.KEEP))continue;let d=`(originally used by ${S.prettyLocator(e.configuration,p[0])}`;d+=p.length>1?` and ${p.length-1} other${p.length>2?"s":""})`:")",c.push({descriptor:h,name:`Reuse ${S.prettyDescriptor(e.configuration,h)}`,reason:d})}});break;case Fr.CACHE:await g(async()=>{for(let h of e.storedDescriptors.values())h.identHash===t.identHash&&c.push({descriptor:h,name:`Reuse ${S.prettyDescriptor(e.configuration,h)}`,reason:"(already used somewhere in the lockfile)"})});break;case Fr.PROJECT:await g(async()=>{if(r.manifest.name!==null&&t.identHash===r.manifest.name.identHash)return;let h=e.tryWorkspaceByIdent(t);if(h===null)return;let p=eoe(h,s);c.push({descriptor:p,name:`Attach ${S.prettyDescriptor(e.configuration,p)}`,reason:`(local workspace at ${ue.pretty(e.configuration,h.relativeCwd,ue.Type.PATH)})`})});break;case Fr.LATEST:await g(async()=>{if(t.range!=="unknown")c.push({descriptor:t,name:`Use ${S.prettyRange(e.configuration,t.range)}`,reason:"(explicit range requested)"});else if(n===vr.PEER)c.push({descriptor:S.makeDescriptor(t,"*"),name:"Use *",reason:"(catch-all peer dependency pattern)"});else if(!e.configuration.get("enableNetwork"))c.push({descriptor:null,name:"Resolve from latest",reason:ue.pretty(e.configuration,"(unavailable because enableNetwork is toggled off)","grey")});else{let h=await MN(t,"latest",{project:e,cache:i,workspace:r,preserveModifier:!1});h&&(h=Zse(h,s),c.push({descriptor:h,name:`Use ${S.prettyDescriptor(e.configuration,h)}`,reason:"(resolved from latest)"}))}});break}}return{suggestions:c.slice(0,a),rejections:u.slice(0,a)}}async function MN(t,e,{project:r,cache:i,workspace:n,preserveModifier:s=!0}){let o=S.makeDescriptor(t,e),a=new ei,l=r.configuration.makeFetcher(),c=r.configuration.makeResolver(),u={project:r,fetcher:l,cache:i,checksums:r.storedChecksums,report:a,cacheOptions:{skipIntegrityCheck:!0},skipIntegrityCheck:!0},g=_(P({},u),{resolver:c,fetchOptions:u}),f=c.bindDescriptor(o,n.anchoredLocator,g),h=await c.getCandidates(f,new Map,g);if(h.length===0)return null;let p=h[0],{protocol:d,source:m,params:I,selector:B}=S.parseRange(S.convertToManifestRange(p.reference));if(d===r.configuration.get("defaultProtocol")&&(d=null),TN.default.valid(B)&&s!==!1){let b=typeof s=="string"?s:o.range;B=Xse(b,{project:r})+B}return S.makeDescriptor(p,S.makeRange({protocol:d,source:m,params:I,selector:B}))}async function M3e(t){return await T.mktempPromise(async e=>{let r=fe.create(e);return r.useWithSource(e,{enableMirror:!1,compressionLevel:0},e,{overwrite:!0}),await t(new Qt(e,{configuration:r,check:!1,immutable:!1}))})}var cC=class extends Be{constructor(){super(...arguments);this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.exact=Y.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=Y.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=Y.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.dev=Y.Boolean("-D,--dev",!1,{description:"Add a package as a dev dependency"});this.peer=Y.Boolean("-P,--peer",!1,{description:"Add a package as a peer dependency"});this.optional=Y.Boolean("-O,--optional",!1,{description:"Add / upgrade a package to an optional regular / peer dependency"});this.preferDev=Y.Boolean("--prefer-dev",!1,{description:"Add / upgrade a package to a dev dependency"});this.interactive=Y.Boolean("-i,--interactive",{description:"Reuse the specified package from other workspaces in the project"});this.cached=Y.Boolean("--cached",!1,{description:"Reuse the highest version already used somewhere within the project"});this.mode=Y.String("--mode",{description:"Change what artifacts installs generate",validator:Yi(li)});this.silent=Y.Boolean("--silent",{hidden:!0});this.packages=Y.Rest()}async execute(){var d;let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState({restoreResolutions:!1});let s=(d=this.interactive)!=null?d:e.get("preferInteractive"),o=AC(this,r),a=[...s?[Fr.REUSE]:[],Fr.PROJECT,...this.cached?[Fr.CACHE]:[],Fr.LATEST],l=s?Infinity:1,c=await Promise.all(this.packages.map(async m=>{let I=m.match(/^\.{0,2}\//)?await ON(m,{cwd:this.context.cwd,workspace:i}):S.parseDescriptor(m),B=O3e(i,I,{dev:this.dev,peer:this.peer,preferDev:this.preferDev,optional:this.optional}),b=await lC(I,{project:r,workspace:i,cache:n,target:B,modifier:o,strategies:a,maxResults:l});return[I,b,B]})),u=await Fa.start({configuration:e,stdout:this.context.stdout,suggestInstall:!1},async m=>{for(let[I,{suggestions:B,rejections:b}]of c)if(B.filter(H=>H.descriptor!==null).length===0){let[H]=b;if(typeof H=="undefined")throw new Error("Assertion failed: Expected an error to have been set");r.configuration.get("enableNetwork")?m.reportError(z.CANT_SUGGEST_RESOLUTIONS,`${S.prettyDescriptor(e,I)} can't be resolved to a satisfying range`):m.reportError(z.CANT_SUGGEST_RESOLUTIONS,`${S.prettyDescriptor(e,I)} can't be resolved to a satisfying range (note: network resolution has been disabled)`),m.reportSeparator(),m.reportExceptionOnce(H)}});if(u.hasErrors())return u.exitCode();let g=!1,f=[],h=[];for(let[,{suggestions:m},I]of c){let B,b=m.filter(K=>K.descriptor!==null),R=b[0].descriptor,H=b.every(K=>S.areDescriptorsEqual(K.descriptor,R));b.length===1||H?B=R:(g=!0,{answer:B}=await(0,roe.prompt)({type:"select",name:"answer",message:"Which range do you want to use?",choices:m.map(({descriptor:K,name:J,reason:ne})=>K?{name:J,hint:ne,descriptor:K}:{name:J,hint:ne,disabled:!0}),onCancel:()=>process.exit(130),result(K){return this.find(K,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let L=i.manifest[I].get(B.identHash);(typeof L=="undefined"||L.descriptorHash!==B.descriptorHash)&&(i.manifest[I].set(B.identHash,B),this.optional&&(I==="dependencies"?i.manifest.ensureDependencyMeta(_(P({},B),{range:"unknown"})).optional=!0:I==="peerDependencies"&&(i.manifest.ensurePeerDependencyMeta(_(P({},B),{range:"unknown"})).optional=!0)),typeof L=="undefined"?f.push([i,I,B,a]):h.push([i,I,L,B]))}return await e.triggerMultipleHooks(m=>m.afterWorkspaceDependencyAddition,f),await e.triggerMultipleHooks(m=>m.afterWorkspaceDependencyReplacement,h),g&&this.context.stdout.write(` +`),(await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout,includeLogs:!this.context.quiet},async m=>{await r.install({cache:n,report:m,mode:this.mode})})).exitCode()}};cC.paths=[["add"]],cC.usage=ye.Usage({description:"add dependencies to the project",details:"\n This command adds a package to the package.json for the nearest workspace.\n\n - If it didn't exist before, the package will by default be added to the regular `dependencies` field, but this behavior can be overriden thanks to the `-D,--dev` flag (which will cause the dependency to be added to the `devDependencies` field instead) and the `-P,--peer` flag (which will do the same but for `peerDependencies`).\n\n - If the package was already listed in your dependencies, it will by default be upgraded whether it's part of your `dependencies` or `devDependencies` (it won't ever update `peerDependencies`, though).\n\n - If set, the `--prefer-dev` flag will operate as a more flexible `-D,--dev` in that it will add the package to your `devDependencies` if it isn't already listed in either `dependencies` or `devDependencies`, but it will also happily upgrade your `dependencies` if that's what you already use (whereas `-D,--dev` would throw an exception).\n\n - If set, the `-O,--optional` flag will add the package to the `optionalDependencies` field and, in combination with the `-P,--peer` flag, it will add the package as an optional peer dependency. If the package was already listed in your `dependencies`, it will be upgraded to `optionalDependencies`. If the package was already listed in your `peerDependencies`, in combination with the `-P,--peer` flag, it will be upgraded to an optional peer dependency: `\"peerDependenciesMeta\": { \"\": { \"optional\": true } }`\n\n - If the added package doesn't specify a range at all its `latest` tag will be resolved and the returned version will be used to generate a new semver range (using the `^` modifier by default unless otherwise configured via the `defaultSemverRangePrefix` configuration, or the `~` modifier if `-T,--tilde` is specified, or no modifier at all if `-E,--exact` is specified). Two exceptions to this rule: the first one is that if the package is a workspace then its local version will be used, and the second one is that if you use `-P,--peer` the default range will be `*` and won't be resolved at all.\n\n - If the added package specifies a range (such as `^1.0.0`, `latest`, or `rc`), Yarn will add this range as-is in the resulting package.json entry (in particular, tags such as `rc` will be encoded as-is rather than being converted into a semver range).\n\n If the `--cached` option is used, Yarn will preferably reuse the highest version already used somewhere within the project, even if through a transitive dependency.\n\n If the `-i,--interactive` option is used (or if the `preferInteractive` settings is toggled on) the command will first try to check whether other workspaces in the project use the specified package and, if so, will offer to reuse them.\n\n If the `--mode=` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n For a compilation of all the supported protocols, please consult the dedicated page from our website: https://yarnpkg.com/features/protocols.\n ",examples:[["Add a regular package to the current workspace","$0 add lodash"],["Add a specific version for a package to the current workspace","$0 add lodash@1.2.3"],["Add a package from a GitHub repository (the master branch) to the current workspace using a URL","$0 add lodash@https://github.com/lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol","$0 add lodash@github:lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol (shorthand)","$0 add lodash@lodash/lodash"],["Add a package from a specific branch of a GitHub repository to the current workspace using the GitHub protocol (shorthand)","$0 add lodash-es@lodash/lodash#es"]]});var ioe=cC;function O3e(t,e,{dev:r,peer:i,preferDev:n,optional:s}){let o=t.manifest[vr.REGULAR].has(e.identHash),a=t.manifest[vr.DEVELOPMENT].has(e.identHash),l=t.manifest[vr.PEER].has(e.identHash);if((r||i)&&o)throw new me(`Package "${S.prettyIdent(t.project.configuration,e)}" is already listed as a regular dependency - remove the -D,-P flags or remove it from your dependencies first`);if(!r&&!i&&l)throw new me(`Package "${S.prettyIdent(t.project.configuration,e)}" is already listed as a peer dependency - use either of -D or -P, or remove it from your peer dependencies first`);if(s&&a)throw new me(`Package "${S.prettyIdent(t.project.configuration,e)}" is already listed as a dev dependency - remove the -O flag or remove it from your dev dependencies first`);if(s&&!i&&l)throw new me(`Package "${S.prettyIdent(t.project.configuration,e)}" is already listed as a peer dependency - remove the -O flag or add the -P flag or remove it from your peer dependencies first`);if((r||n)&&s)throw new me(`Package "${S.prettyIdent(t.project.configuration,e)}" cannot simultaneously be a dev dependency and an optional dependency`);return i?vr.PEER:r||n?vr.DEVELOPMENT:o?vr.REGULAR:a?vr.DEVELOPMENT:vr.REGULAR}var uC=class extends Be{constructor(){super(...arguments);this.verbose=Y.Boolean("-v,--verbose",!1,{description:"Print both the binary name and the locator of the package that provides the binary"});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.name=Y.String({required:!1})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,locator:i}=await Ke.find(e,this.context.cwd);if(await r.restoreInstallState(),this.name){let o=(await Kt.getPackageAccessibleBinaries(i,{project:r})).get(this.name);if(!o)throw new me(`Couldn't find a binary named "${this.name}" for package "${S.prettyLocator(e,i)}"`);let[,a]=o;return this.context.stdout.write(`${a} +`),0}return(await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout},async s=>{let o=await Kt.getPackageAccessibleBinaries(i,{project:r}),l=Array.from(o.keys()).reduce((c,u)=>Math.max(c,u.length),0);for(let[c,[u,g]]of o)s.reportJson({name:c,source:S.stringifyIdent(u),path:g});if(this.verbose)for(let[c,[u]]of o)s.reportInfo(null,`${c.padEnd(l," ")} ${S.prettyLocator(e,u)}`);else for(let c of o.keys())s.reportInfo(null,c)})).exitCode()}};uC.paths=[["bin"]],uC.usage=ye.Usage({description:"get the path to a binary script",details:` + When used without arguments, this command will print the list of all the binaries available in the current workspace. Adding the \`-v,--verbose\` flag will cause the output to contain both the binary name and the locator of the package that provides the binary. + + When an argument is specified, this command will just print the path to the binary on the standard output and exit. Note that the reported path may be stored within a zip archive. + `,examples:[["List all the available binaries","$0 bin"],["Print the path to a specific binary","$0 bin eslint"]]});var noe=uC;var gC=class extends Be{constructor(){super(...arguments);this.mirror=Y.Boolean("--mirror",!1,{description:"Remove the global cache files instead of the local cache files"});this.all=Y.Boolean("--all",!1,{description:"Remove both the global cache files and the local cache files of the current project"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r=await Qt.find(e);return(await Fe.start({configuration:e,stdout:this.context.stdout},async()=>{let n=(this.all||this.mirror)&&r.mirrorCwd!==null,s=!this.mirror;n&&(await T.removePromise(r.mirrorCwd),await e.triggerHook(o=>o.cleanGlobalArtifacts,e)),s&&await T.removePromise(r.cwd)})).exitCode()}};gC.paths=[["cache","clean"],["cache","clear"]],gC.usage=ye.Usage({description:"remove the shared cache files",details:` + This command will remove all the files from the cache. + `,examples:[["Remove all the local archives","$0 cache clean"],["Remove all the archives stored in the ~/.yarn directory","$0 cache clean --mirror"]]});var soe=gC;var ooe=ie(p0()),KN=ie(require("util")),fC=class extends Be{constructor(){super(...arguments);this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.unsafe=Y.Boolean("--no-redacted",!1,{description:"Don't redact secrets (such as tokens) from the output"});this.name=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r=this.name.replace(/[.[].*$/,""),i=this.name.replace(/^[^.[]*/,"");if(typeof e.settings.get(r)=="undefined")throw new me(`Couldn't find a configuration settings named "${r}"`);let s=e.getSpecial(r,{hideSecrets:!this.unsafe,getNativePaths:!0}),o=de.convertMapsToIndexableObjects(s),a=i?(0,ooe.default)(o,i):o,l=await Fe.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async c=>{c.reportJson(a)});if(!this.json){if(typeof a=="string")return this.context.stdout.write(`${a} +`),l.exitCode();KN.inspect.styles.name="cyan",this.context.stdout.write(`${(0,KN.inspect)(a,{depth:Infinity,colors:e.get("enableColors"),compact:!1})} +`)}return l.exitCode()}};fC.paths=[["config","get"]],fC.usage=ye.Usage({description:"read a configuration settings",details:` + This command will print a configuration setting. + + Secrets (such as tokens) will be redacted from the output by default. If this behavior isn't desired, set the \`--no-redacted\` to get the untransformed value. + `,examples:[["Print a simple configuration setting","yarn config get yarnPath"],["Print a complex configuration setting","yarn config get packageExtensions"],["Print a nested field from the configuration",`yarn config get 'npmScopes["my-company"].npmRegistryServer'`],["Print a token from the configuration","yarn config get npmAuthToken --no-redacted"],["Print a configuration setting as JSON","yarn config get packageExtensions --json"]]});var aoe=fC;var Eae=ie(qN()),Iae=ie(p0()),yae=ie(mae()),JN=ie(require("util")),pC=class extends Be{constructor(){super(...arguments);this.json=Y.Boolean("--json",!1,{description:"Set complex configuration settings to JSON values"});this.home=Y.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=Y.String();this.value=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r=()=>{if(!e.projectCwd)throw new me("This command must be run from within a project folder");return e.projectCwd},i=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*\.?/,"");if(typeof e.settings.get(i)=="undefined")throw new me(`Couldn't find a configuration settings named "${i}"`);if(i==="enableStrictSettings")throw new me("This setting only affects the file it's in, and thus cannot be set from the CLI");let o=this.json?JSON.parse(this.value):this.value;await(this.home?h=>fe.updateHomeConfiguration(h):h=>fe.updateConfiguration(r(),h))(h=>{if(n){let p=(0,Eae.default)(h);return(0,yae.default)(p,this.name,o),p}else return _(P({},h),{[i]:o})});let c=(await fe.find(this.context.cwd,this.context.plugins)).getSpecial(i,{hideSecrets:!0,getNativePaths:!0}),u=de.convertMapsToIndexableObjects(c),g=n?(0,Iae.default)(u,n):u;return(await Fe.start({configuration:e,includeFooter:!1,stdout:this.context.stdout},async h=>{JN.inspect.styles.name="cyan",h.reportInfo(z.UNNAMED,`Successfully set ${this.name} to ${(0,JN.inspect)(g,{depth:Infinity,colors:e.get("enableColors"),compact:!1})}`)})).exitCode()}};pC.paths=[["config","set"]],pC.usage=ye.Usage({description:"change a configuration settings",details:` + This command will set a configuration setting. + + When used without the \`--json\` flag, it can only set a simple configuration setting (a string, a number, or a boolean). + + When used with the \`--json\` flag, it can set both simple and complex configuration settings, including Arrays and Objects. + `,examples:[["Set a simple configuration setting (a string, a number, or a boolean)","yarn config set initScope myScope"],["Set a simple configuration setting (a string, a number, or a boolean) using the `--json` flag",'yarn config set initScope --json \\"myScope\\"'],["Set a complex configuration setting (an Array) using the `--json` flag",`yarn config set unsafeHttpWhitelist --json '["*.example.com", "example.com"]'`],["Set a complex configuration setting (an Object) using the `--json` flag",`yarn config set packageExtensions --json '{ "@babel/parser@*": { "dependencies": { "@babel/types": "*" } } }'`],["Set a nested configuration setting",'yarn config set npmScopes.company.npmRegistryServer "https://npm.example.com"'],["Set a nested configuration setting using indexed access for non-simple keys",`yarn config set 'npmRegistries["//npm.example.com"].npmAuthToken' "ffffffff-ffff-ffff-ffff-ffffffffffff"`]]});var wae=pC;var Dae=ie(qN()),Rae=ie(Ld()),Fae=ie(Pae()),dC=class extends Be{constructor(){super(...arguments);this.home=Y.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r=()=>{if(!e.projectCwd)throw new me("This command must be run from within a project folder");return e.projectCwd},i=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*\.?/,"");if(typeof e.settings.get(i)=="undefined")throw new me(`Couldn't find a configuration settings named "${i}"`);let o=this.home?l=>fe.updateHomeConfiguration(l):l=>fe.updateConfiguration(r(),l);return(await Fe.start({configuration:e,includeFooter:!1,stdout:this.context.stdout},async l=>{let c=!1;await o(u=>{if(!(0,Rae.default)(u,this.name))return l.reportWarning(z.UNNAMED,`Configuration doesn't contain setting ${this.name}; there is nothing to unset`),c=!0,u;let g=n?(0,Dae.default)(u):P({},u);return(0,Fae.default)(g,this.name),g}),c||l.reportInfo(z.UNNAMED,`Successfully unset ${this.name}`)})).exitCode()}};dC.paths=[["config","unset"]],dC.usage=ye.Usage({description:"unset a configuration setting",details:` + This command will unset a configuration setting. + `,examples:[["Unset a simple configuration setting","yarn config unset initScope"],["Unset a complex configuration setting","yarn config unset packageExtensions"],["Unset a nested configuration setting","yarn config unset npmScopes.company.npmRegistryServer"]]});var Nae=dC;var WN=ie(require("util")),CC=class extends Be{constructor(){super(...arguments);this.verbose=Y.Boolean("-v,--verbose",!1,{description:"Print the setting description on top of the regular key/value information"});this.why=Y.Boolean("--why",!1,{description:"Print the reason why a setting is set a particular way"});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins,{strict:!1});return(await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout},async i=>{if(e.invalid.size>0&&!this.json){for(let[n,s]of e.invalid)i.reportError(z.INVALID_CONFIGURATION_KEY,`Invalid configuration key "${n}" in ${s}`);i.reportSeparator()}if(this.json){let n=de.sortMap(e.settings.keys(),s=>s);for(let s of n){let o=e.settings.get(s),a=e.getSpecial(s,{hideSecrets:!0,getNativePaths:!0}),l=e.sources.get(s);this.verbose?i.reportJson({key:s,effective:a,source:l}):i.reportJson(P({key:s,effective:a,source:l},o))}}else{let n=de.sortMap(e.settings.keys(),a=>a),s=n.reduce((a,l)=>Math.max(a,l.length),0),o={breakLength:Infinity,colors:e.get("enableColors"),maxArrayLength:2};if(this.why||this.verbose){let a=n.map(c=>{let u=e.settings.get(c);if(!u)throw new Error(`Assertion failed: This settings ("${c}") should have been registered`);let g=this.why?e.sources.get(c)||"":u.description;return[c,g]}),l=a.reduce((c,[,u])=>Math.max(c,u.length),0);for(let[c,u]of a)i.reportInfo(null,`${c.padEnd(s," ")} ${u.padEnd(l," ")} ${(0,WN.inspect)(e.getSpecial(c,{hideSecrets:!0,getNativePaths:!0}),o)}`)}else for(let a of n)i.reportInfo(null,`${a.padEnd(s," ")} ${(0,WN.inspect)(e.getSpecial(a,{hideSecrets:!0,getNativePaths:!0}),o)}`)}})).exitCode()}};CC.paths=[["config"]],CC.usage=ye.Usage({description:"display the current configuration",details:` + This command prints the current active configuration settings. + `,examples:[["Print the active configuration settings","$0 config"]]});var Lae=CC;Ss();var zN={};it(zN,{Strategy:()=>Oc,acceptedStrategies:()=>H4e,dedupe:()=>VN});var Tae=ie(Nn()),Oc;(function(e){e.HIGHEST="highest"})(Oc||(Oc={}));var H4e=new Set(Object.values(Oc)),G4e={highest:async(t,e,{resolver:r,fetcher:i,resolveOptions:n,fetchOptions:s})=>{let o=new Map;for(let[a,l]of t.storedResolutions){let c=t.storedDescriptors.get(a);if(typeof c=="undefined")throw new Error(`Assertion failed: The descriptor (${a}) should have been registered`);de.getSetWithDefault(o,c.identHash).add(l)}return Array.from(t.storedDescriptors.values(),async a=>{if(e.length&&!Tae.default.isMatch(S.stringifyIdent(a),e))return null;let l=t.storedResolutions.get(a.descriptorHash);if(typeof l=="undefined")throw new Error(`Assertion failed: The resolution (${a.descriptorHash}) should have been registered`);let c=t.originalPackages.get(l);if(typeof c=="undefined"||!r.shouldPersistResolution(c,n))return null;let u=o.get(a.identHash);if(typeof u=="undefined")throw new Error(`Assertion failed: The resolutions (${a.identHash}) should have been registered`);if(u.size===1)return null;let g=[...u].map(m=>{let I=t.originalPackages.get(m);if(typeof I=="undefined")throw new Error(`Assertion failed: The package (${m}) should have been registered`);return I.reference}),f=await r.getSatisfying(a,g,n),h=f==null?void 0:f[0];if(typeof h=="undefined")return null;let p=h.locatorHash,d=t.originalPackages.get(p);if(typeof d=="undefined")throw new Error(`Assertion failed: The package (${p}) should have been registered`);return p===l?null:{descriptor:a,currentPackage:c,updatedPackage:d}})}};async function VN(t,{strategy:e,patterns:r,cache:i,report:n}){let{configuration:s}=t,o=new ei,a=s.makeResolver(),l=s.makeFetcher(),c={cache:i,checksums:t.storedChecksums,fetcher:l,project:t,report:o,skipIntegrityCheck:!0,cacheOptions:{skipIntegrityCheck:!0}},u={project:t,resolver:a,report:o,fetchOptions:c};return await n.startTimerPromise("Deduplication step",async()=>{let f=await G4e[e](t,r,{resolver:a,resolveOptions:u,fetcher:l,fetchOptions:c}),h=Xi.progressViaCounter(f.length);n.reportProgress(h);let p=0;await Promise.all(f.map(I=>I.then(B=>{if(B===null)return;p++;let{descriptor:b,currentPackage:R,updatedPackage:H}=B;n.reportInfo(z.UNNAMED,`${S.prettyDescriptor(s,b)} can be deduped from ${S.prettyLocator(s,R)} to ${S.prettyLocator(s,H)}`),n.reportJson({descriptor:S.stringifyDescriptor(b),currentResolution:S.stringifyLocator(R),updatedResolution:S.stringifyLocator(H)}),t.storedResolutions.set(b.descriptorHash,H.locatorHash)}).finally(()=>h.tick())));let d;switch(p){case 0:d="No packages";break;case 1:d="One package";break;default:d=`${p} packages`}let m=ue.pretty(s,e,ue.Type.CODE);return n.reportInfo(z.UNNAMED,`${d} can be deduped using the ${m} strategy`),p})}var mC=class extends Be{constructor(){super(...arguments);this.strategy=Y.String("-s,--strategy",Oc.HIGHEST,{description:"The strategy to use when deduping dependencies",validator:Yi(Oc)});this.check=Y.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when duplicates are found, without persisting the dependency tree"});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.mode=Y.String("--mode",{description:"Change what artifacts installs generate",validator:Yi(li)});this.patterns=Y.Rest()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r}=await Ke.find(e,this.context.cwd),i=await Qt.find(e);await r.restoreInstallState({restoreResolutions:!1});let n=0,s=await Fe.start({configuration:e,includeFooter:!1,stdout:this.context.stdout,json:this.json},async o=>{n=await VN(r,{strategy:this.strategy,patterns:this.patterns,cache:i,report:o})});return s.hasErrors()?s.exitCode():this.check?n?1:0:(await Fe.start({configuration:e,stdout:this.context.stdout,json:this.json},async a=>{await r.install({cache:i,report:a,mode:this.mode})})).exitCode()}};mC.paths=[["dedupe"]],mC.usage=ye.Usage({description:"deduplicate dependencies with overlapping ranges",details:"\n Duplicates are defined as descriptors with overlapping ranges being resolved and locked to different locators. They are a natural consequence of Yarn's deterministic installs, but they can sometimes pile up and unnecessarily increase the size of your project.\n\n This command dedupes dependencies in the current project using different strategies (only one is implemented at the moment):\n\n - `highest`: Reuses (where possible) the locators with the highest versions. This means that dependencies can only be upgraded, never downgraded. It's also guaranteed that it never takes more than a single pass to dedupe the entire dependency tree.\n\n **Note:** Even though it never produces a wrong dependency tree, this command should be used with caution, as it modifies the dependency tree, which can sometimes cause problems when packages don't strictly follow semver recommendations. Because of this, it is recommended to also review the changes manually.\n\n If set, the `-c,--check` flag will only report the found duplicates, without persisting the modified dependency tree. If changes are found, the command will exit with a non-zero exit code, making it suitable for CI purposes.\n\n If the `--mode=` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n ### In-depth explanation:\n\n Yarn doesn't deduplicate dependencies by default, otherwise installs wouldn't be deterministic and the lockfile would be useless. What it actually does is that it tries to not duplicate dependencies in the first place.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@*`will cause Yarn to reuse `foo@2.3.4`, even if the latest `foo` is actually `foo@2.10.14`, thus preventing unnecessary duplication.\n\n Duplication happens when Yarn can't unlock dependencies that have already been locked inside the lockfile.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@2.10.14` will cause Yarn to install `foo@2.10.14` because the existing resolution doesn't satisfy the range `2.10.14`. This behavior can lead to (sometimes) unwanted duplication, since now the lockfile contains 2 separate resolutions for the 2 `foo` descriptors, even though they have overlapping ranges, which means that the lockfile can be simplified so that both descriptors resolve to `foo@2.10.14`.\n ",examples:[["Dedupe all packages","$0 dedupe"],["Dedupe all packages using a specific strategy","$0 dedupe --strategy highest"],["Dedupe a specific package","$0 dedupe lodash"],["Dedupe all packages with the `@babel/*` scope","$0 dedupe '@babel/*'"],["Check for duplicates (can be used as a CI step)","$0 dedupe --check"]]});var Mae=mC;var Y0=class extends Be{async execute(){let{plugins:e}=await fe.find(this.context.cwd,this.context.plugins),r=[];for(let o of e){let{commands:a}=o[1];if(a){let c=oo.from(a).definitions();r.push([o[0],c])}}let i=this.cli.definitions(),n=(o,a)=>o.split(" ").slice(1).join()===a.split(" ").slice(1).join(),s=Kae()["@yarnpkg/builder"].bundles.standard;for(let o of r){let a=o[1];for(let l of a)i.find(c=>n(c.path,l.path)).plugin={name:o[0],isDefault:s.includes(o[0])}}this.context.stdout.write(`${JSON.stringify(i,null,2)} +`)}};Y0.paths=[["--clipanion=definitions"]];var Uae=Y0;var q0=class extends Be{async execute(){this.context.stdout.write(this.cli.usage(null))}};q0.paths=[["help"],["--help"],["-h"]];var Hae=q0;var _N=class extends Be{constructor(){super(...arguments);this.leadingArgument=Y.String();this.args=Y.Proxy()}async execute(){if(this.leadingArgument.match(/[\\/]/)&&!S.tryParseIdent(this.leadingArgument)){let e=v.resolve(this.context.cwd,M.toPortablePath(this.leadingArgument));return await this.cli.run(this.args,{cwd:e})}else return await this.cli.run(["run",this.leadingArgument,...this.args])}},Gae=_N;var J0=class extends Be{async execute(){this.context.stdout.write(`${Zr||""} +`)}};J0.paths=[["-v"],["--version"]];var jae=J0;var EC=class extends Be{constructor(){super(...arguments);this.commandName=Y.String();this.args=Y.Proxy()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,locator:i}=await Ke.find(e,this.context.cwd);return await r.restoreInstallState(),await Kt.executePackageShellcode(i,this.commandName,this.args,{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,project:r})}};EC.paths=[["exec"]],EC.usage=ye.Usage({description:"execute a shell script",details:` + This command simply executes a shell script within the context of the root directory of the active workspace using the portable shell. + + It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). + `,examples:[["Execute a single shell command","$0 exec echo Hello World"],["Execute a shell script",'$0 exec "tsc & babel src --out-dir lib"']]});var Yae=EC;Ss();var IC=class extends Be{constructor(){super(...arguments);this.hash=Y.String({required:!1,validator:fv(gv(),[hv(/^p[0-9a-f]{5}$/)])})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r}=await Ke.find(e,this.context.cwd);return await r.restoreInstallState({restoreResolutions:!1}),await r.applyLightResolution(),typeof this.hash!="undefined"?await j4e(this.hash,r,{stdout:this.context.stdout}):(await Fe.start({configuration:e,stdout:this.context.stdout,includeFooter:!1},async n=>{var o;let s=[([,a])=>S.stringifyLocator(r.storedPackages.get(a.subject)),([,a])=>S.stringifyIdent(a.requested)];for(let[a,l]of de.sortMap(r.peerRequirements,s)){let c=r.storedPackages.get(l.subject);if(typeof c=="undefined")throw new Error("Assertion failed: Expected the subject package to have been registered");let u=r.storedPackages.get(l.rootRequester);if(typeof u=="undefined")throw new Error("Assertion failed: Expected the root package to have been registered");let g=(o=c.dependencies.get(l.requested.identHash))!=null?o:null,f=ue.pretty(e,a,ue.Type.CODE),h=S.prettyLocator(e,c),p=S.prettyIdent(e,l.requested),d=S.prettyIdent(e,u),m=l.allRequesters.length-1,I=`descendant${m===1?"":"s"}`,B=m>0?` and ${m} ${I}`:"",b=g!==null?"provides":"doesn't provide";n.reportInfo(null,`${f} \u2192 ${h} ${b} ${p} to ${d}${B}`)}})).exitCode()}};IC.paths=[["explain","peer-requirements"]],IC.usage=ye.Usage({description:"explain a set of peer requirements",details:` + A set of peer requirements represents all peer requirements that a dependent must satisfy when providing a given peer request to a requester and its descendants. + + When the hash argument is specified, this command prints a detailed explanation of all requirements of the set corresponding to the hash and whether they're satisfied or not. + + When used without arguments, this command lists all sets of peer requirements and the corresponding hash that can be used to get detailed information about a given set. + + **Note:** A hash is a six-letter p-prefixed code that can be obtained from peer dependency warnings or from the list of all peer requirements (\`yarn explain peer-requirements\`). + `,examples:[["Explain the corresponding set of peer requirements for a hash","$0 explain peer-requirements p1a4ed"],["List all sets of peer requirements","$0 explain peer-requirements"]]});var qae=IC;async function j4e(t,e,r){let{configuration:i}=e,n=e.peerRequirements.get(t);if(typeof n=="undefined")throw new Error(`No peerDependency requirements found for hash: "${t}"`);return(await Fe.start({configuration:i,stdout:r.stdout,includeFooter:!1},async o=>{var I,B;let a=e.storedPackages.get(n.subject);if(typeof a=="undefined")throw new Error("Assertion failed: Expected the subject package to have been registered");let l=e.storedPackages.get(n.rootRequester);if(typeof l=="undefined")throw new Error("Assertion failed: Expected the root package to have been registered");let c=(I=a.dependencies.get(n.requested.identHash))!=null?I:null,u=c!==null?e.storedResolutions.get(c.descriptorHash):null;if(typeof u=="undefined")throw new Error("Assertion failed: Expected the resolution to have been registered");let g=u!==null?e.storedPackages.get(u):null;if(typeof g=="undefined")throw new Error("Assertion failed: Expected the provided package to have been registered");let f=[...n.allRequesters.values()].map(b=>{let R=e.storedPackages.get(b);if(typeof R=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let H=S.devirtualizeLocator(R),L=e.storedPackages.get(H.locatorHash);if(typeof L=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let K=L.peerDependencies.get(n.requested.identHash);if(typeof K=="undefined")throw new Error("Assertion failed: Expected the peer dependency to be registered");return{pkg:R,peerDependency:K}});if(g!==null){let b=f.every(({peerDependency:R})=>qt.satisfiesWithPrereleases(g.version,R.range));o.reportInfo(z.UNNAMED,`${S.prettyLocator(i,a)} provides ${S.prettyLocator(i,g)} with version ${S.prettyReference(i,(B=g.version)!=null?B:"")}, which ${b?"satisfies":"doesn't satisfy"} the following requirements:`)}else o.reportInfo(z.UNNAMED,`${S.prettyLocator(i,a)} doesn't provide ${S.prettyIdent(i,n.requested)}, breaking the following requirements:`);o.reportSeparator();let h=ue.mark(i),p=[];for(let{pkg:b,peerDependency:R}of de.sortMap(f,H=>S.stringifyLocator(H.pkg))){let L=(g!==null?qt.satisfiesWithPrereleases(g.version,R.range):!1)?h.Check:h.Cross;p.push({stringifiedLocator:S.stringifyLocator(b),prettyLocator:S.prettyLocator(i,b),prettyRange:S.prettyRange(i,R.range),mark:L})}let d=Math.max(...p.map(({stringifiedLocator:b})=>b.length)),m=Math.max(...p.map(({prettyRange:b})=>b.length));for(let{stringifiedLocator:b,prettyLocator:R,prettyRange:H,mark:L}of de.sortMap(p,({stringifiedLocator:K})=>K))o.reportInfo(null,`${R.padEnd(d+(R.length-b.length)," ")} \u2192 ${H.padEnd(m," ")} ${L}`);p.length>1&&(o.reportSeparator(),o.reportInfo(z.UNNAMED,`Note: these requirements start with ${S.prettyLocator(e.configuration,l)}`))})).exitCode()}var Jae=ie(Nn()),yC=class extends Be{constructor(){super(...arguments);this.all=Y.Boolean("-A,--all",!1,{description:"Print versions of a package from the whole project"});this.recursive=Y.Boolean("-R,--recursive",!1,{description:"Print information for all packages, including transitive dependencies"});this.extra=Y.Array("-X,--extra",[],{description:"An array of requests of extra data provided by plugins"});this.cache=Y.Boolean("--cache",!1,{description:"Print information about the cache entry of a package (path, size, checksum)"});this.dependents=Y.Boolean("--dependents",!1,{description:"Print all dependents for each matching package"});this.manifest=Y.Boolean("--manifest",!1,{description:"Print data obtained by looking at the package archive (license, homepage, ...)"});this.nameOnly=Y.Boolean("--name-only",!1,{description:"Only print the name for the matching packages"});this.virtuals=Y.Boolean("--virtuals",!1,{description:"Print each instance of the virtual packages"});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=Y.Rest()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i&&!this.all)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState();let s=new Set(this.extra);this.cache&&s.add("cache"),this.dependents&&s.add("dependents"),this.manifest&&s.add("manifest");let o=(b,{recursive:R})=>{let H=b.anchoredLocator.locatorHash,L=new Map,K=[H];for(;K.length>0;){let J=K.shift();if(L.has(J))continue;let ne=r.storedPackages.get(J);if(typeof ne=="undefined")throw new Error("Assertion failed: Expected the package to be registered");if(L.set(J,ne),S.isVirtualLocator(ne)&&K.push(S.devirtualizeLocator(ne).locatorHash),!(!R&&J!==H))for(let q of ne.dependencies.values()){let A=r.storedResolutions.get(q.descriptorHash);if(typeof A=="undefined")throw new Error("Assertion failed: Expected the resolution to be registered");K.push(A)}}return L.values()},a=({recursive:b})=>{let R=new Map;for(let H of r.workspaces)for(let L of o(H,{recursive:b}))R.set(L.locatorHash,L);return R.values()},l=({all:b,recursive:R})=>b&&R?r.storedPackages.values():b?a({recursive:R}):o(i,{recursive:R}),c=({all:b,recursive:R})=>{let H=l({all:b,recursive:R}),L=this.patterns.map(ne=>{let q=S.parseLocator(ne),A=Jae.default.makeRe(S.stringifyIdent(q)),V=S.isVirtualLocator(q),W=V?S.devirtualizeLocator(q):q;return X=>{let F=S.stringifyIdent(X);if(!A.test(F))return!1;if(q.reference==="unknown")return!0;let D=S.isVirtualLocator(X),he=D?S.devirtualizeLocator(X):X;return!(V&&D&&q.reference!==X.reference||W.reference!==he.reference)}}),K=de.sortMap([...H],ne=>S.stringifyLocator(ne));return{selection:K.filter(ne=>L.length===0||L.some(q=>q(ne))),sortedLookup:K}},{selection:u,sortedLookup:g}=c({all:this.all,recursive:this.recursive});if(u.length===0)throw new me("No package matched your request");let f=new Map;if(this.dependents)for(let b of g)for(let R of b.dependencies.values()){let H=r.storedResolutions.get(R.descriptorHash);if(typeof H=="undefined")throw new Error("Assertion failed: Expected the resolution to be registered");de.getArrayWithDefault(f,H).push(b)}let h=new Map;for(let b of g){if(!S.isVirtualLocator(b))continue;let R=S.devirtualizeLocator(b);de.getArrayWithDefault(h,R.locatorHash).push(b)}let p={},d={children:p},m=e.makeFetcher(),I={project:r,fetcher:m,cache:n,checksums:r.storedChecksums,report:new ei,cacheOptions:{skipIntegrityCheck:!0},skipIntegrityCheck:!0},B=[async(b,R,H)=>{var J,ne;if(!R.has("manifest"))return;let L=await m.fetch(b,I),K;try{K=await Ze.find(L.prefixPath,{baseFs:L.packageFs})}finally{(J=L.releaseFs)==null||J.call(L)}H("Manifest",{License:ue.tuple(ue.Type.NO_HINT,K.license),Homepage:ue.tuple(ue.Type.URL,(ne=K.raw.homepage)!=null?ne:null)})},async(b,R,H)=>{var A;if(!R.has("cache"))return;let L={mockedPackages:r.disabledLocators,unstablePackages:r.conditionalLocators},K=(A=r.storedChecksums.get(b.locatorHash))!=null?A:null,J=n.getLocatorPath(b,K,L),ne;if(J!==null)try{ne=T.statSync(J)}catch{}let q=typeof ne!="undefined"?[ne.size,ue.Type.SIZE]:void 0;H("Cache",{Checksum:ue.tuple(ue.Type.NO_HINT,K),Path:ue.tuple(ue.Type.PATH,J),Size:q})}];for(let b of u){let R=S.isVirtualLocator(b);if(!this.virtuals&&R)continue;let H={},L={value:[b,ue.Type.LOCATOR],children:H};if(p[S.stringifyLocator(b)]=L,this.nameOnly){delete L.children;continue}let K=h.get(b.locatorHash);typeof K!="undefined"&&(H.Instances={label:"Instances",value:ue.tuple(ue.Type.NUMBER,K.length)}),H.Version={label:"Version",value:ue.tuple(ue.Type.NO_HINT,b.version)};let J=(q,A)=>{let V={};if(H[q]=V,Array.isArray(A))V.children=A.map(W=>({value:W}));else{let W={};V.children=W;for(let[X,F]of Object.entries(A))typeof F!="undefined"&&(W[X]={label:X,value:F})}};if(!R){for(let q of B)await q(b,s,J);await e.triggerHook(q=>q.fetchPackageInfo,b,s,J)}b.bin.size>0&&!R&&J("Exported Binaries",[...b.bin.keys()].map(q=>ue.tuple(ue.Type.PATH,q)));let ne=f.get(b.locatorHash);typeof ne!="undefined"&&ne.length>0&&J("Dependents",ne.map(q=>ue.tuple(ue.Type.LOCATOR,q))),b.dependencies.size>0&&!R&&J("Dependencies",[...b.dependencies.values()].map(q=>{var W;let A=r.storedResolutions.get(q.descriptorHash),V=typeof A!="undefined"&&(W=r.storedPackages.get(A))!=null?W:null;return ue.tuple(ue.Type.RESOLUTION,{descriptor:q,locator:V})})),b.peerDependencies.size>0&&R&&J("Peer dependencies",[...b.peerDependencies.values()].map(q=>{var X,F;let A=b.dependencies.get(q.identHash),V=typeof A!="undefined"&&(X=r.storedResolutions.get(A.descriptorHash))!=null?X:null,W=V!==null&&(F=r.storedPackages.get(V))!=null?F:null;return ue.tuple(ue.Type.RESOLUTION,{descriptor:q,locator:W})}))}Hs.emitTree(d,{configuration:e,json:this.json,stdout:this.context.stdout,separators:this.nameOnly?0:2})}};yC.paths=[["info"]],yC.usage=ye.Usage({description:"see information related to packages",details:"\n This command prints various information related to the specified packages, accepting glob patterns.\n\n By default, if the locator reference is missing, Yarn will default to print the information about all the matching direct dependencies of the package for the active workspace. To instead print all versions of the package that are direct dependencies of any of your workspaces, use the `-A,--all` flag. Adding the `-R,--recursive` flag will also report transitive dependencies.\n\n Some fields will be hidden by default in order to keep the output readable, but can be selectively displayed by using additional options (`--dependents`, `--manifest`, `--virtuals`, ...) described in the option descriptions.\n\n Note that this command will only print the information directly related to the selected packages - if you wish to know why the package is there in the first place, use `yarn why` which will do just that (it also provides a `-R,--recursive` flag that may be of some help).\n ",examples:[["Show information about Lodash","$0 info lodash"]]});var Wae=yC;var W0=ie(ml());Ss();var wC=class extends Be{constructor(){super(...arguments);this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.immutable=Y.Boolean("--immutable",{description:"Abort with an error exit code if the lockfile was to be modified"});this.immutableCache=Y.Boolean("--immutable-cache",{description:"Abort with an error exit code if the cache folder was to be modified"});this.checkCache=Y.Boolean("--check-cache",!1,{description:"Always refetch the packages and ensure that their checksums are consistent"});this.inlineBuilds=Y.Boolean("--inline-builds",{description:"Verbosely print the output of the build steps of dependencies"});this.mode=Y.String("--mode",{description:"Change what artifacts installs generate",validator:Yi(li)});this.cacheFolder=Y.String("--cache-folder",{hidden:!0});this.frozenLockfile=Y.Boolean("--frozen-lockfile",{hidden:!0});this.ignoreEngines=Y.Boolean("--ignore-engines",{hidden:!0});this.nonInteractive=Y.Boolean("--non-interactive",{hidden:!0});this.preferOffline=Y.Boolean("--prefer-offline",{hidden:!0});this.production=Y.Boolean("--production",{hidden:!0});this.registry=Y.String("--registry",{hidden:!0});this.silent=Y.Boolean("--silent",{hidden:!0});this.networkTimeout=Y.String("--network-timeout",{hidden:!0})}async execute(){var c;let e=await fe.find(this.context.cwd,this.context.plugins);typeof this.inlineBuilds!="undefined"&&e.useWithSource("",{enableInlineBuilds:this.inlineBuilds},e.startingCwd,{overwrite:!0});let r=!!process.env.FUNCTION_TARGET||!!process.env.GOOGLE_RUNTIME,i=async(u,{error:g})=>{let f=await Fe.start({configuration:e,stdout:this.context.stdout,includeFooter:!1},async h=>{g?h.reportError(z.DEPRECATED_CLI_SETTINGS,u):h.reportWarning(z.DEPRECATED_CLI_SETTINGS,u)});return f.hasErrors()?f.exitCode():null};if(typeof this.ignoreEngines!="undefined"){let u=await i("The --ignore-engines option is deprecated; engine checking isn't a core feature anymore",{error:!W0.default.VERCEL});if(u!==null)return u}if(typeof this.registry!="undefined"){let u=await i("The --registry option is deprecated; prefer setting npmRegistryServer in your .yarnrc.yml file",{error:!1});if(u!==null)return u}if(typeof this.preferOffline!="undefined"){let u=await i("The --prefer-offline flag is deprecated; use the --cached flag with 'yarn add' instead",{error:!W0.default.VERCEL});if(u!==null)return u}if(typeof this.production!="undefined"){let u=await i("The --production option is deprecated on 'install'; use 'yarn workspaces focus' instead",{error:!0});if(u!==null)return u}if(typeof this.nonInteractive!="undefined"){let u=await i("The --non-interactive option is deprecated",{error:!r});if(u!==null)return u}if(typeof this.frozenLockfile!="undefined"&&(await i("The --frozen-lockfile option is deprecated; use --immutable and/or --immutable-cache instead",{error:!1}),this.immutable=this.frozenLockfile),typeof this.cacheFolder!="undefined"){let u=await i("The cache-folder option has been deprecated; use rc settings instead",{error:!W0.default.NETLIFY});if(u!==null)return u}let n=(c=this.immutable)!=null?c:e.get("enableImmutableInstalls");if(e.projectCwd!==null){let u=await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async g=>{await Y4e(e,n)&&(g.reportInfo(z.AUTOMERGE_SUCCESS,"Automatically fixed merge conflicts \u{1F44D}"),g.reportSeparator())});if(u.hasErrors())return u.exitCode()}if(e.projectCwd!==null&&typeof e.sources.get("nodeLinker")=="undefined"){let u=e.projectCwd,g;try{g=await T.readFilePromise(v.join(u,wt.lockfile),"utf8")}catch{}if(g==null?void 0:g.includes("yarn lockfile v1")){let f=await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async h=>{h.reportInfo(z.AUTO_NM_SUCCESS,"Migrating from Yarn 1; automatically enabling the compatibility node-modules linker \u{1F44D}"),h.reportSeparator(),e.use("",{nodeLinker:"node-modules"},u,{overwrite:!0}),await fe.updateConfiguration(u,{nodeLinker:"node-modules"})});if(f.hasErrors())return f.exitCode()}}if(e.projectCwd!==null){let u=await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async g=>{var f;((f=fe.telemetry)==null?void 0:f.isNew)&&(g.reportInfo(z.TELEMETRY_NOTICE,"Yarn will periodically gather anonymous telemetry: https://yarnpkg.com/advanced/telemetry"),g.reportInfo(z.TELEMETRY_NOTICE,`Run ${ue.pretty(e,"yarn config set --home enableTelemetry 0",ue.Type.CODE)} to disable`),g.reportSeparator())});if(u.hasErrors())return u.exitCode()}let{project:s,workspace:o}=await Ke.find(e,this.context.cwd),a=await Qt.find(e,{immutable:this.immutableCache,check:this.checkCache});if(!o)throw new rt(s.cwd,this.context.cwd);return await s.restoreInstallState({restoreResolutions:!1}),(await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout,includeLogs:!0},async u=>{await s.install({cache:a,report:u,immutable:n,mode:this.mode})})).exitCode()}};wC.paths=[["install"],ye.Default],wC.usage=ye.Usage({description:"install the project dependencies",details:` + This command sets up your project if needed. The installation is split into four different steps that each have their own characteristics: + + - **Resolution:** First the package manager will resolve your dependencies. The exact way a dependency version is privileged over another isn't standardized outside of the regular semver guarantees. If a package doesn't resolve to what you would expect, check that all dependencies are correctly declared (also check our website for more information: ). + + - **Fetch:** Then we download all the dependencies if needed, and make sure that they're all stored within our cache (check the value of \`cacheFolder\` in \`yarn config\` to see where the cache files are stored). + + - **Link:** Then we send the dependency tree information to internal plugins tasked with writing them on the disk in some form (for example by generating the .pnp.cjs file you might know). + + - **Build:** Once the dependency tree has been written on the disk, the package manager will now be free to run the build scripts for all packages that might need it, in a topological order compatible with the way they depend on one another. See https://yarnpkg.com/advanced/lifecycle-scripts for detail. + + Note that running this command is not part of the recommended workflow. Yarn supports zero-installs, which means that as long as you store your cache and your .pnp.cjs file inside your repository, everything will work without requiring any install right after cloning your repository or switching branches. + + If the \`--immutable\` option is set (defaults to true on CI), Yarn will abort with an error exit code if the lockfile was to be modified (other paths can be added using the \`immutablePatterns\` configuration setting). For backward compatibility we offer an alias under the name of \`--frozen-lockfile\`, but it will be removed in a later release. + + If the \`--immutable-cache\` option is set, Yarn will abort with an error exit code if the cache folder was to be modified (either because files would be added, or because they'd be removed). + + If the \`--check-cache\` option is set, Yarn will always refetch the packages and will ensure that their checksum matches what's 1/ described in the lockfile 2/ inside the existing cache files (if present). This is recommended as part of your CI workflow if you're both following the Zero-Installs model and accepting PRs from third-parties, as they'd otherwise have the ability to alter the checked-in packages before submitting them. + + If the \`--inline-builds\` option is set, Yarn will verbosely print the output of the build steps of your dependencies (instead of writing them into individual files). This is likely useful mostly for debug purposes only when using Docker-like environments. + + If the \`--mode=\` option is set, Yarn will change which artifacts are generated. The modes currently supported are: + + - \`skip-build\` will not run the build scripts at all. Note that this is different from setting \`enableScripts\` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run. + + - \`update-lockfile\` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost. + `,examples:[["Install the project","$0 install"],["Validate a project when using Zero-Installs","$0 install --immutable --immutable-cache"],["Validate a project when using Zero-Installs (slightly safer if you accept external PRs)","$0 install --immutable --immutable-cache --check-cache"]]});var zae=wC,q4e="|||||||",J4e=">>>>>>>",W4e="=======",Vae="<<<<<<<";async function Y4e(t,e){if(!t.projectCwd)return!1;let r=v.join(t.projectCwd,t.get("lockfileFilename"));if(!await T.existsPromise(r))return!1;let i=await T.readFilePromise(r,"utf8");if(!i.includes(Vae))return!1;if(e)throw new nt(z.AUTOMERGE_IMMUTABLE,"Cannot autofix a lockfile when running an immutable install");let[n,s]=z4e(i),o,a;try{o=Ii(n),a=Ii(s)}catch(c){throw new nt(z.AUTOMERGE_FAILED_TO_PARSE,"The individual variants of the lockfile failed to parse")}let l=P(P({},o),a);for(let[c,u]of Object.entries(l))typeof u=="string"&&delete l[c];return await T.changeFilePromise(r,Qa(l),{automaticNewlines:!0}),!0}function z4e(t){let e=[[],[]],r=t.split(/\r?\n/g),i=!1;for(;r.length>0;){let n=r.shift();if(typeof n=="undefined")throw new Error("Assertion failed: Some lines should remain");if(n.startsWith(Vae)){for(;r.length>0;){let s=r.shift();if(typeof s=="undefined")throw new Error("Assertion failed: Some lines should remain");if(s===W4e){i=!1;break}else if(i||s.startsWith(q4e)){i=!0;continue}else e[0].push(s)}for(;r.length>0;){let s=r.shift();if(typeof s=="undefined")throw new Error("Assertion failed: Some lines should remain");if(s.startsWith(J4e))break;e[1].push(s)}}else e[0].push(n),e[1].push(n)}return[e[0].join(` +`),e[1].join(` +`)]}var BC=class extends Be{constructor(){super(...arguments);this.all=Y.Boolean("-A,--all",!1,{description:"Link all workspaces belonging to the target project to the current one"});this.private=Y.Boolean("-p,--private",!1,{description:"Also link private workspaces belonging to the target project to the current one"});this.relative=Y.Boolean("-r,--relative",!1,{description:"Link workspaces using relative paths instead of absolute paths"});this.destination=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState({restoreResolutions:!1});let s=v.resolve(this.context.cwd,M.toPortablePath(this.destination)),o=await fe.find(s,this.context.plugins,{useRc:!1,strict:!1}),{project:a,workspace:l}=await Ke.find(o,s);if(r.cwd===a.cwd)throw new me("Invalid destination; Can't link the project to itself");if(!l)throw new rt(a.cwd,s);let c=r.topLevelWorkspace,u=[];if(this.all){for(let f of a.workspaces)f.manifest.name&&(!f.manifest.private||this.private)&&u.push(f);if(u.length===0)throw new me("No workspace found to be linked in the target project")}else{if(!l.manifest.name)throw new me("The target workspace doesn't have a name and thus cannot be linked");if(l.manifest.private&&!this.private)throw new me("The target workspace is marked private - use the --private flag to link it anyway");u.push(l)}for(let f of u){let h=S.stringifyIdent(f.locator),p=this.relative?v.relative(r.cwd,f.cwd):f.cwd;c.manifest.resolutions.push({pattern:{descriptor:{fullName:h}},reference:`portal:${p}`})}return(await Fe.start({configuration:e,stdout:this.context.stdout},async f=>{await r.install({cache:n,report:f})})).exitCode()}};BC.paths=[["link"]],BC.usage=ye.Usage({description:"connect the local project to another one",details:"\n This command will set a new `resolutions` field in the project-level manifest and point it to the workspace at the specified location (even if part of another project).\n ",examples:[["Register a remote workspace for use in the current project","$0 link ~/ts-loader"],["Register all workspaces from a remote project for use in the current project","$0 link ~/jest --all"]]});var _ae=BC;var QC=class extends Be{constructor(){super(...arguments);this.args=Y.Proxy()}async execute(){return this.cli.run(["exec","node",...this.args])}};QC.paths=[["node"]],QC.usage=ye.Usage({description:"run node with the hook already setup",details:` + This command simply runs Node. It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). + + The Node process will use the exact same version of Node as the one used to run Yarn itself, which might be a good way to ensure that your commands always use a consistent Node version. + `,examples:[["Run a Node script","$0 node ./my-script.js"]]});var Xae=QC;var lAe=ie(require("os"));var rAe=ie(require("os"));var V4e="https://raw.githubusercontent.com/yarnpkg/berry/master/plugins.yml";async function Kc(t){let e=await Zt.get(V4e,{configuration:t});return Ii(e.toString())}var bC=class extends Be{constructor(){super(...arguments);this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins);return(await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout},async i=>{let n=await Kc(e);for(let s of Object.entries(n)){let[l,o]=s,a=o,{experimental:c}=a,u=qr(a,["experimental"]);let g=l;c&&(g+=" [experimental]"),i.reportJson(P({name:l,experimental:c},u)),i.reportInfo(null,g)}})).exitCode()}};bC.paths=[["plugin","list"]],bC.usage=ye.Usage({category:"Plugin-related commands",description:"list the available official plugins",details:"\n This command prints the plugins available directly from the Yarn repository. Only those plugins can be referenced by name in `yarn plugin import`.\n ",examples:[["List the official plugins","$0 plugin list"]]});var Zae=bC;var $ae=ie(Or()),vC=class extends Be{constructor(){super(...arguments);this.onlyIfNeeded=Y.Boolean("--only-if-needed",!1,{description:"Only lock the Yarn version if it isn't already locked"});this.version=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins);if(e.get("yarnPath")&&this.onlyIfNeeded)return 0;let r=()=>{if(typeof Zr=="undefined")throw new me("The --install flag can only be used without explicit version specifier from the Yarn CLI");return`file://${process.argv[1]}`},i;if(this.version==="self")i=r();else if(this.version==="latest"||this.version==="berry"||this.version==="stable")i=`https://repo.yarnpkg.com/${await eAe(e,"stable")}/packages/yarnpkg-cli/bin/yarn.js`;else if(this.version==="canary")i=`https://repo.yarnpkg.com/${await eAe(e,"canary")}/packages/yarnpkg-cli/bin/yarn.js`;else if(this.version==="classic")i="https://nightly.yarnpkg.com/latest.js";else if(this.version.match(/^\.{0,2}[\\/]/)||M.isAbsolute(this.version))i=`file://${M.resolve(this.version)}`;else if(qt.satisfiesWithPrereleases(this.version,">=2.0.0"))i=`https://repo.yarnpkg.com/${this.version}/packages/yarnpkg-cli/bin/yarn.js`;else if(qt.satisfiesWithPrereleases(this.version,"^0.x || ^1.x"))i=`https://github.com/yarnpkg/yarn/releases/download/v${this.version}/yarn-${this.version}.js`;else if(qt.validRange(this.version))i=`https://repo.yarnpkg.com/${await _4e(e,this.version)}/packages/yarnpkg-cli/bin/yarn.js`;else throw new me(`Invalid version descriptor "${this.version}"`);return(await Fe.start({configuration:e,stdout:this.context.stdout,includeLogs:!this.context.quiet},async s=>{let o="file://",a;i.startsWith(o)?(s.reportInfo(z.UNNAMED,`Downloading ${ue.pretty(e,i,ps.URL)}`),a=await T.readFilePromise(M.toPortablePath(i.slice(o.length)))):(s.reportInfo(z.UNNAMED,`Retrieving ${ue.pretty(e,i,ps.PATH)}`),a=await Zt.get(i,{configuration:e})),await XN(e,null,a,{report:s})})).exitCode()}};vC.paths=[["set","version"]],vC.usage=ye.Usage({description:"lock the Yarn version used by the project",details:"\n This command will download a specific release of Yarn directly from the Yarn GitHub repository, will store it inside your project, and will change the `yarnPath` settings from your project `.yarnrc.yml` file to point to the new file.\n\n A very good use case for this command is to enforce the version of Yarn used by the any single member of your team inside a same project - by doing this you ensure that you have control on Yarn upgrades and downgrades (including on your deployment servers), and get rid of most of the headaches related to someone using a slightly different version and getting a different behavior than you.\n\n The version specifier can be:\n\n - a tag:\n - `latest` / `berry` / `stable` -> the most recent stable berry (`>=2.0.0`) release\n - `canary` -> the most recent canary (release candidate) berry (`>=2.0.0`) release\n - `classic` -> the most recent classic (`^0.x || ^1.x`) release\n\n - a semver range (e.g. `2.x`) -> the most recent version satisfying the range (limited to berry releases)\n\n - a semver version (e.g. `2.4.1`, `1.22.1`)\n\n - a local file referenced through either a relative or absolute path\n\n - `self` -> the version used to invoke the command\n ",examples:[["Download the latest release from the Yarn repository","$0 set version latest"],["Download the latest canary release from the Yarn repository","$0 set version canary"],["Download the latest classic release from the Yarn repository","$0 set version classic"],["Download the most recent Yarn 3 build","$0 set version 3.x"],["Download a specific Yarn 2 build","$0 set version 2.0.0-rc.30"],["Switch back to a specific Yarn 1 release","$0 set version 1.22.1"],["Use a release from the local filesystem","$0 set version ./yarn.cjs"],["Download the version used to invoke the command","$0 set version self"]]});var tAe=vC;async function _4e(t,e){let i=(await Zt.get("https://repo.yarnpkg.com/tags",{configuration:t,jsonResponse:!0})).tags.filter(n=>qt.satisfiesWithPrereleases(n,e));if(i.length===0)throw new me(`No matching release found for range ${ue.pretty(t,e,ue.Type.RANGE)}.`);return i[0]}async function eAe(t,e){let r=await Zt.get("https://repo.yarnpkg.com/tags",{configuration:t,jsonResponse:!0});if(!r.latest[e])throw new me(`Tag ${ue.pretty(t,e,ue.Type.RANGE)} not found`);return r.latest[e]}async function XN(t,e,r,{report:i}){var g;e===null&&await T.mktempPromise(async f=>{let h=v.join(f,"yarn.cjs");await T.writeFilePromise(h,r);let{stdout:p}=await hr.execvp(process.execPath,[M.fromPortablePath(h),"--version"],{cwd:f,env:_(P({},process.env),{YARN_IGNORE_PATH:"1"})});if(e=p.trim(),!$ae.default.valid(e))throw new Error(`Invalid semver version. ${ue.pretty(t,"yarn --version",ue.Type.CODE)} returned: +${e}`)});let n=(g=t.projectCwd)!=null?g:t.startingCwd,s=v.resolve(n,".yarn/releases"),o=v.resolve(s,`yarn-${e}.cjs`),a=v.relative(t.startingCwd,o),l=v.relative(n,o),c=t.get("yarnPath"),u=c===null||c.startsWith(`${s}/`);if(i.reportInfo(z.UNNAMED,`Saving the new release in ${ue.pretty(t,a,"magenta")}`),await T.removePromise(v.dirname(o)),await T.mkdirPromise(v.dirname(o),{recursive:!0}),await T.writeFilePromise(o,r,{mode:493}),u){await fe.updateConfiguration(n,{yarnPath:l});let f=await Ze.tryFind(n)||new Ze;e&&de.isTaggedYarnVersion(e)&&(f.packageManager=`yarn@${e}`);let h={};f.exportTo(h);let p=v.join(n,Ze.fileName),d=`${JSON.stringify(h,null,f.indent)} +`;await T.changeFilePromise(p,d,{automaticNewlines:!0})}}var X4e=/^[0-9]+$/;function iAe(t){return X4e.test(t)?`pull/${t}/head`:t}var Z4e=({repository:t,branch:e},r)=>[["git","init",M.fromPortablePath(r)],["git","remote","add","origin",t],["git","fetch","origin",iAe(e)],["git","reset","--hard","FETCH_HEAD"]],$4e=({branch:t})=>[["git","fetch","origin",iAe(t),"--force"],["git","reset","--hard","FETCH_HEAD"],["git","clean","-dfx"]],eze=({plugins:t,noMinify:e},r)=>[["yarn","build:cli",...new Array().concat(...t.map(i=>["--plugin",v.resolve(r,i)])),...e?["--no-minify"]:[],"|"]],SC=class extends Be{constructor(){super(...arguments);this.installPath=Y.String("--path",{description:"The path where the repository should be cloned to"});this.repository=Y.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=Y.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.plugins=Y.Array("--plugin",[],{description:"An array of additional plugins that should be included in the bundle"});this.noMinify=Y.Boolean("--no-minify",!1,{description:"Build a bundle for development (debugging) - non-minified and non-mangled"});this.force=Y.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.skipPlugins=Y.Boolean("--skip-plugins",!1,{description:"Skip updating the contrib plugins"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r}=await Ke.find(e,this.context.cwd),i=typeof this.installPath!="undefined"?v.resolve(this.context.cwd,M.toPortablePath(this.installPath)):v.resolve(M.toPortablePath((0,rAe.tmpdir)()),"yarnpkg-sources",mn.makeHash(this.repository).slice(0,6));return(await Fe.start({configuration:e,stdout:this.context.stdout},async s=>{await $N(this,{configuration:e,report:s,target:i}),s.reportSeparator(),s.reportInfo(z.UNNAMED,"Building a fresh bundle"),s.reportSeparator(),await xC(eze(this,i),{configuration:e,context:this.context,target:i}),s.reportSeparator();let o=v.resolve(i,"packages/yarnpkg-cli/bundles/yarn.js"),a=await T.readFilePromise(o);await XN(e,"sources",a,{report:s}),this.skipPlugins||await tze(this,{project:r,report:s,target:i})})).exitCode()}};SC.paths=[["set","version","from","sources"]],SC.usage=ye.Usage({description:"build Yarn from master",details:` + This command will clone the Yarn repository into a temporary folder, then build it. The resulting bundle will then be copied into the local project. + + By default, it also updates all contrib plugins to the same commit the bundle is built from. This behavior can be disabled by using the \`--skip-plugins\` flag. + `,examples:[["Build Yarn from master","$0 set version from sources"]]});var nAe=SC;async function xC(t,{configuration:e,context:r,target:i}){for(let[n,...s]of t){let o=s[s.length-1]==="|";if(o&&s.pop(),o)await hr.pipevp(n,s,{cwd:i,stdin:r.stdin,stdout:r.stdout,stderr:r.stderr,strict:!0});else{r.stdout.write(`${ue.pretty(e,` $ ${[n,...s].join(" ")}`,"grey")} +`);try{await hr.execvp(n,s,{cwd:i,strict:!0})}catch(a){throw r.stdout.write(a.stdout||a.stack),a}}}}async function $N(t,{configuration:e,report:r,target:i}){let n=!1;if(!t.force&&T.existsSync(v.join(i,".git"))){r.reportInfo(z.UNNAMED,"Fetching the latest commits"),r.reportSeparator();try{await xC($4e(t),{configuration:e,context:t.context,target:i}),n=!0}catch(s){r.reportSeparator(),r.reportWarning(z.UNNAMED,"Repository update failed; we'll try to regenerate it")}}n||(r.reportInfo(z.UNNAMED,"Cloning the remote repository"),r.reportSeparator(),await T.removePromise(i),await T.mkdirPromise(i,{recursive:!0}),await xC(Z4e(t,i),{configuration:e,context:t.context,target:i}))}async function tze(t,{project:e,report:r,target:i}){let n=await Kc(e.configuration),s=new Set(Object.keys(n));for(let o of e.configuration.plugins.keys())!s.has(o)||await ZN(o,t,{project:e,report:r,target:i})}var sAe=ie(Or()),oAe=ie(require("url")),aAe=ie(require("vm"));var kC=class extends Be{constructor(){super(...arguments);this.name=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins);return(await Fe.start({configuration:e,stdout:this.context.stdout},async i=>{let{project:n}=await Ke.find(e,this.context.cwd),s,o;if(this.name.match(/^\.{0,2}[\\/]/)||M.isAbsolute(this.name)){let a=v.resolve(this.context.cwd,M.toPortablePath(this.name));i.reportInfo(z.UNNAMED,`Reading ${ue.pretty(e,a,ue.Type.PATH)}`),s=v.relative(n.cwd,a),o=await T.readFilePromise(a)}else{let a;if(this.name.match(/^https?:/)){try{new oAe.URL(this.name)}catch{throw new nt(z.INVALID_PLUGIN_REFERENCE,`Plugin specifier "${this.name}" is neither a plugin name nor a valid url`)}s=this.name,a=this.name}else{let l=S.parseLocator(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-"));if(l.reference!=="unknown"&&!sAe.default.valid(l.reference))throw new nt(z.UNNAMED,"Official plugins only accept strict version references. Use an explicit URL if you wish to download them from another location.");let c=S.stringifyIdent(l),u=await Kc(e);if(!Object.prototype.hasOwnProperty.call(u,c))throw new nt(z.PLUGIN_NAME_NOT_FOUND,`Couldn't find a plugin named "${c}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be referenced by their name; any other plugin will have to be referenced through its public url (for example https://github.com/yarnpkg/berry/raw/master/packages/plugin-typescript/bin/%40yarnpkg/plugin-typescript.js).`);s=c,a=u[c].url,l.reference!=="unknown"?a=a.replace(/\/master\//,`/${c}/${l.reference}/`):Zr!==null&&(a=a.replace(/\/master\//,`/@yarnpkg/cli/${Zr}/`))}i.reportInfo(z.UNNAMED,`Downloading ${ue.pretty(e,a,"green")}`),o=await Zt.get(a,{configuration:e})}await eL(s,o,{project:n,report:i})})).exitCode()}};kC.paths=[["plugin","import"]],kC.usage=ye.Usage({category:"Plugin-related commands",description:"download a plugin",details:` + This command downloads the specified plugin from its remote location and updates the configuration to reference it in further CLI invocations. + + Three types of plugin references are accepted: + + - If the plugin is stored within the Yarn repository, it can be referenced by name. + - Third-party plugins can be referenced directly through their public urls. + - Local plugins can be referenced by their path on the disk. + + Plugins cannot be downloaded from the npm registry, and aren't allowed to have dependencies (they need to be bundled into a single file, possibly thanks to the \`@yarnpkg/builder\` package). + `,examples:[['Download and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import @yarnpkg/plugin-exec"],['Download and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import exec"],["Download and activate a community plugin","$0 plugin import https://example.org/path/to/plugin.js"],["Activate a local plugin","$0 plugin import ./path/to/plugin.js"]]});var AAe=kC;async function eL(t,e,{project:r,report:i}){let{configuration:n}=r,s={},o={exports:s};(0,aAe.runInNewContext)(e.toString(),{module:o,exports:s});let a=o.exports.name,l=`.yarn/plugins/${a}.cjs`,c=v.resolve(r.cwd,l);i.reportInfo(z.UNNAMED,`Saving the new plugin in ${ue.pretty(n,l,"magenta")}`),await T.mkdirPromise(v.dirname(c),{recursive:!0}),await T.writeFilePromise(c,e);let u={path:l,spec:t};await fe.updateConfiguration(r.cwd,g=>{let f=[],h=!1;for(let p of g.plugins||[]){let d=typeof p!="string"?p.path:p,m=v.resolve(r.cwd,M.toPortablePath(d)),{name:I}=de.dynamicRequire(m);I!==a?f.push(p):(f.push(u),h=!0)}return h||f.push(u),_(P({},g),{plugins:f})})}var rze=({pluginName:t,noMinify:e},r)=>[["yarn",`build:${t}`,...e?["--no-minify"]:[],"|"]],PC=class extends Be{constructor(){super(...arguments);this.installPath=Y.String("--path",{description:"The path where the repository should be cloned to"});this.repository=Y.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=Y.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.noMinify=Y.Boolean("--no-minify",!1,{description:"Build a plugin for development (debugging) - non-minified and non-mangled"});this.force=Y.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.name=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r=typeof this.installPath!="undefined"?v.resolve(this.context.cwd,M.toPortablePath(this.installPath)):v.resolve(M.toPortablePath((0,lAe.tmpdir)()),"yarnpkg-sources",mn.makeHash(this.repository).slice(0,6));return(await Fe.start({configuration:e,stdout:this.context.stdout},async n=>{let{project:s}=await Ke.find(e,this.context.cwd),o=S.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-")),a=S.stringifyIdent(o),l=await Kc(e);if(!Object.prototype.hasOwnProperty.call(l,a))throw new nt(z.PLUGIN_NAME_NOT_FOUND,`Couldn't find a plugin named "${a}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be built and imported from sources.`);let c=a;await $N(this,{configuration:e,report:n,target:r}),await ZN(c,this,{project:s,report:n,target:r})})).exitCode()}};PC.paths=[["plugin","import","from","sources"]],PC.usage=ye.Usage({category:"Plugin-related commands",description:"build a plugin from sources",details:` + This command clones the Yarn repository into a temporary folder, builds the specified contrib plugin and updates the configuration to reference it in further CLI invocations. + + The plugins can be referenced by their short name if sourced from the official Yarn repository. + `,examples:[['Build and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import from sources @yarnpkg/plugin-exec"],['Build and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import from sources exec"]]});var cAe=PC;async function ZN(t,{context:e,noMinify:r},{project:i,report:n,target:s}){let o=t.replace(/@yarnpkg\//,""),{configuration:a}=i;n.reportSeparator(),n.reportInfo(z.UNNAMED,`Building a fresh ${o}`),n.reportSeparator(),await xC(rze({pluginName:o,noMinify:r},s),{configuration:a,context:e,target:s}),n.reportSeparator();let l=v.resolve(s,`packages/${o}/bundles/${t}.js`),c=await T.readFilePromise(l);await eL(t,c,{project:i,report:n})}var DC=class extends Be{constructor(){super(...arguments);this.name=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r}=await Ke.find(e,this.context.cwd);return(await Fe.start({configuration:e,stdout:this.context.stdout},async n=>{let s=this.name,o=S.parseIdent(s);if(!e.plugins.has(s))throw new me(`${S.prettyIdent(e,o)} isn't referenced by the current configuration`);let a=`.yarn/plugins/${s}.cjs`,l=v.resolve(r.cwd,a);T.existsSync(l)&&(n.reportInfo(z.UNNAMED,`Removing ${ue.pretty(e,a,ue.Type.PATH)}...`),await T.removePromise(l)),n.reportInfo(z.UNNAMED,"Updating the configuration..."),await fe.updateConfiguration(r.cwd,c=>{if(!Array.isArray(c.plugins))return c;let u=c.plugins.filter(g=>g.path!==a);return c.plugins.length===u.length?c:_(P({},c),{plugins:u})})})).exitCode()}};DC.paths=[["plugin","remove"]],DC.usage=ye.Usage({category:"Plugin-related commands",description:"remove a plugin",details:` + This command deletes the specified plugin from the .yarn/plugins folder and removes it from the configuration. + + **Note:** The plugins have to be referenced by their name property, which can be obtained using the \`yarn plugin runtime\` command. Shorthands are not allowed. + `,examples:[["Remove a plugin imported from the Yarn repository","$0 plugin remove @yarnpkg/plugin-typescript"],["Remove a plugin imported from a local file","$0 plugin remove my-local-plugin"]]});var uAe=DC;var RC=class extends Be{constructor(){super(...arguments);this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins);return(await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout},async i=>{for(let n of e.plugins.keys()){let s=this.context.plugins.plugins.has(n),o=n;s&&(o+=" [builtin]"),i.reportJson({name:n,builtin:s}),i.reportInfo(null,`${o}`)}})).exitCode()}};RC.paths=[["plugin","runtime"]],RC.usage=ye.Usage({category:"Plugin-related commands",description:"list the active plugins",details:` + This command prints the currently active plugins. Will be displayed both builtin plugins and external plugins. + `,examples:[["List the currently active plugins","$0 plugin runtime"]]});var gAe=RC;var FC=class extends Be{constructor(){super(...arguments);this.idents=Y.Rest()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);let s=new Set;for(let a of this.idents)s.add(S.parseIdent(a).identHash);if(await r.restoreInstallState({restoreResolutions:!1}),await r.resolveEverything({cache:n,report:new ei}),s.size>0)for(let a of r.storedPackages.values())s.has(a.identHash)&&r.storedBuildState.delete(a.locatorHash);else r.storedBuildState.clear();return(await Fe.start({configuration:e,stdout:this.context.stdout,includeLogs:!this.context.quiet},async a=>{await r.install({cache:n,report:a})})).exitCode()}};FC.paths=[["rebuild"]],FC.usage=ye.Usage({description:"rebuild the project's native packages",details:` + This command will automatically cause Yarn to forget about previous compilations of the given packages and to run them again. + + Note that while Yarn forgets the compilation, the previous artifacts aren't erased from the filesystem and may affect the next builds (in good or bad). To avoid this, you may remove the .yarn/unplugged folder, or any other relevant location where packages might have been stored (Yarn may offer a way to do that automatically in the future). + + By default all packages will be rebuilt, but you can filter the list by specifying the names of the packages you want to clear from memory. + `,examples:[["Rebuild all packages","$0 rebuild"],["Rebuild fsevents only","$0 rebuild fsevents"]]});var fAe=FC;var tL=ie(Nn());Ss();var NC=class extends Be{constructor(){super(...arguments);this.all=Y.Boolean("-A,--all",!1,{description:"Apply the operation to all workspaces from the current project"});this.mode=Y.String("--mode",{description:"Change what artifacts installs generate",validator:Yi(li)});this.patterns=Y.Rest()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState({restoreResolutions:!1});let s=this.all?r.workspaces:[i],o=[vr.REGULAR,vr.DEVELOPMENT,vr.PEER],a=[],l=!1,c=[];for(let h of this.patterns){let p=!1,d=S.parseIdent(h);for(let m of s){let I=[...m.manifest.peerDependenciesMeta.keys()];for(let B of(0,tL.default)(I,h))m.manifest.peerDependenciesMeta.delete(B),l=!0,p=!0;for(let B of o){let b=m.manifest.getForScope(B),R=[...b.values()].map(H=>S.stringifyIdent(H));for(let H of(0,tL.default)(R,S.stringifyIdent(d))){let{identHash:L}=S.parseIdent(H),K=b.get(L);if(typeof K=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");m.manifest[B].delete(L),c.push([m,B,K]),l=!0,p=!0}}}p||a.push(h)}let u=a.length>1?"Patterns":"Pattern",g=a.length>1?"don't":"doesn't",f=this.all?"any":"this";if(a.length>0)throw new me(`${u} ${ue.prettyList(e,a,ps.CODE)} ${g} match any packages referenced by ${f} workspace`);return l?(await e.triggerMultipleHooks(p=>p.afterWorkspaceDependencyRemoval,c),(await Fe.start({configuration:e,stdout:this.context.stdout},async p=>{await r.install({cache:n,report:p,mode:this.mode})})).exitCode()):0}};NC.paths=[["remove"]],NC.usage=ye.Usage({description:"remove dependencies from the project",details:` + This command will remove the packages matching the specified patterns from the current workspace. + + If the \`--mode=\` option is set, Yarn will change which artifacts are generated. The modes currently supported are: + + - \`skip-build\` will not run the build scripts at all. Note that this is different from setting \`enableScripts\` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run. + + - \`update-lockfile\` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost. + + This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them. + `,examples:[["Remove a dependency from the current project","$0 remove lodash"],["Remove a dependency from all workspaces at once","$0 remove lodash --all"],["Remove all dependencies starting with `eslint-`","$0 remove 'eslint-*'"],["Remove all dependencies with the `@babel` scope","$0 remove '@babel/*'"],["Remove all dependencies matching `react-dom` or `react-helmet`","$0 remove 'react-{dom,helmet}'"]]});var hAe=NC;var pAe=ie(require("util")),z0=class extends Be{async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd);if(!i)throw new rt(r.cwd,this.context.cwd);return(await Fe.start({configuration:e,stdout:this.context.stdout},async s=>{let o=i.manifest.scripts,a=de.sortMap(o.keys(),u=>u),l={breakLength:Infinity,colors:e.get("enableColors"),maxArrayLength:2},c=a.reduce((u,g)=>Math.max(u,g.length),0);for(let[u,g]of o.entries())s.reportInfo(null,`${u.padEnd(c," ")} ${(0,pAe.inspect)(g,l)}`)})).exitCode()}};z0.paths=[["run"]];var dAe=z0;var LC=class extends Be{constructor(){super(...arguments);this.inspect=Y.String("--inspect",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.inspectBrk=Y.String("--inspect-brk",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.topLevel=Y.Boolean("-T,--top-level",!1,{description:"Check the root workspace for scripts and/or binaries instead of the current one"});this.binariesOnly=Y.Boolean("-B,--binaries-only",!1,{description:"Ignore any user defined scripts and only check for binaries"});this.silent=Y.Boolean("--silent",{hidden:!0});this.scriptName=Y.String();this.args=Y.Proxy()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i,locator:n}=await Ke.find(e,this.context.cwd);await r.restoreInstallState();let s=this.topLevel?r.topLevelWorkspace.anchoredLocator:n;if(!this.binariesOnly&&await Kt.hasPackageScript(s,this.scriptName,{project:r}))return await Kt.executePackageScript(s,this.scriptName,this.args,{project:r,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});let o=await Kt.getPackageAccessibleBinaries(s,{project:r});if(o.get(this.scriptName)){let l=[];return this.inspect&&(typeof this.inspect=="string"?l.push(`--inspect=${this.inspect}`):l.push("--inspect")),this.inspectBrk&&(typeof this.inspectBrk=="string"?l.push(`--inspect-brk=${this.inspectBrk}`):l.push("--inspect-brk")),await Kt.executePackageAccessibleBinary(s,this.scriptName,this.args,{cwd:this.context.cwd,project:r,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,nodeArgs:l,packageAccessibleBinaries:o})}if(!this.topLevel&&!this.binariesOnly&&i&&this.scriptName.includes(":")){let c=(await Promise.all(r.workspaces.map(async u=>u.manifest.scripts.has(this.scriptName)?u:null))).filter(u=>u!==null);if(c.length===1)return await Kt.executeWorkspaceScript(c[0],this.scriptName,this.args,{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})}if(this.topLevel)throw this.scriptName==="node-gyp"?new me(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${S.prettyLocator(e,n)}). This typically happens because some package depends on "node-gyp" to build itself, but didn't list it in their dependencies. To fix that, please run "yarn add node-gyp" into your top-level workspace. You also can open an issue on the repository of the specified package to suggest them to use an optional peer dependency.`):new me(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${S.prettyLocator(e,n)}).`);{if(this.scriptName==="global")throw new me("The 'yarn global' commands have been removed in 2.x - consider using 'yarn dlx' or a third-party plugin instead");let l=[this.scriptName].concat(this.args);for(let[c,u]of Yg)for(let g of u)if(l.length>=g.length&&JSON.stringify(l.slice(0,g.length))===JSON.stringify(g))throw new me(`Couldn't find a script named "${this.scriptName}", but a matching command can be found in the ${c} plugin. You can install it with "yarn plugin import ${c}".`);throw new me(`Couldn't find a script named "${this.scriptName}".`)}}};LC.paths=[["run"]],LC.usage=ye.Usage({description:"run a script defined in the package.json",details:` + This command will run a tool. The exact tool that will be executed will depend on the current state of your workspace: + + - If the \`scripts\` field from your local package.json contains a matching script name, its definition will get executed. + + - Otherwise, if one of the local workspace's dependencies exposes a binary with a matching name, this binary will get executed. + + - Otherwise, if the specified name contains a colon character and if one of the workspaces in the project contains exactly one script with a matching name, then this script will get executed. + + Whatever happens, the cwd of the spawned process will be the workspace that declares the script (which makes it possible to call commands cross-workspaces using the third syntax). + `,examples:[["Run the tests from the local workspace","$0 run test"],['Same thing, but without the "run" keyword',"$0 test"],["Inspect Webpack while running","$0 run --inspect-brk webpack"]]});var CAe=LC;var TC=class extends Be{constructor(){super(...arguments);this.save=Y.Boolean("-s,--save",!1,{description:"Persist the resolution inside the top-level manifest"});this.descriptor=Y.String();this.resolution=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(await r.restoreInstallState({restoreResolutions:!1}),!i)throw new rt(r.cwd,this.context.cwd);let s=S.parseDescriptor(this.descriptor,!0),o=S.makeDescriptor(s,this.resolution);return r.storedDescriptors.set(s.descriptorHash,s),r.storedDescriptors.set(o.descriptorHash,o),r.resolutionAliases.set(s.descriptorHash,o.descriptorHash),(await Fe.start({configuration:e,stdout:this.context.stdout},async l=>{await r.install({cache:n,report:l})})).exitCode()}};TC.paths=[["set","resolution"]],TC.usage=ye.Usage({description:"enforce a package resolution",details:'\n This command updates the resolution table so that `descriptor` is resolved by `resolution`.\n\n Note that by default this command only affect the current resolution table - meaning that this "manual override" will disappear if you remove the lockfile, or if the package disappear from the table. If you wish to make the enforced resolution persist whatever happens, add the `-s,--save` flag which will also edit the `resolutions` field from your top-level manifest.\n\n Note that no attempt is made at validating that `resolution` is a valid resolution entry for `descriptor`.\n ',examples:[["Force all instances of lodash@npm:^1.2.3 to resolve to 1.5.0","$0 set resolution lodash@npm:^1.2.3 1.5.0"]]});var mAe=TC;var EAe=ie(Nn()),MC=class extends Be{constructor(){super(...arguments);this.all=Y.Boolean("-A,--all",!1,{description:"Unlink all workspaces belonging to the target project from the current one"});this.leadingArguments=Y.Rest()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);let s=r.topLevelWorkspace,o=new Set;if(this.leadingArguments.length===0&&this.all)for(let{pattern:l,reference:c}of s.manifest.resolutions)c.startsWith("portal:")&&o.add(l.descriptor.fullName);if(this.leadingArguments.length>0)for(let l of this.leadingArguments){let c=v.resolve(this.context.cwd,M.toPortablePath(l));if(de.isPathLike(l)){let u=await fe.find(c,this.context.plugins,{useRc:!1,strict:!1}),{project:g,workspace:f}=await Ke.find(u,c);if(!f)throw new rt(g.cwd,c);if(this.all){for(let h of g.workspaces)h.manifest.name&&o.add(S.stringifyIdent(h.locator));if(o.size===0)throw new me("No workspace found to be unlinked in the target project")}else{if(!f.manifest.name)throw new me("The target workspace doesn't have a name and thus cannot be unlinked");o.add(S.stringifyIdent(f.locator))}}else{let u=[...s.manifest.resolutions.map(({pattern:g})=>g.descriptor.fullName)];for(let g of(0,EAe.default)(u,l))o.add(g)}}return s.manifest.resolutions=s.manifest.resolutions.filter(({pattern:l})=>!o.has(l.descriptor.fullName)),(await Fe.start({configuration:e,stdout:this.context.stdout},async l=>{await r.install({cache:n,report:l})})).exitCode()}};MC.paths=[["unlink"]],MC.usage=ye.Usage({description:"disconnect the local project from another one",details:` + This command will remove any resolutions in the project-level manifest that would have been added via a yarn link with similar arguments. + `,examples:[["Unregister a remote workspace in the current project","$0 unlink ~/ts-loader"],["Unregister all workspaces from a remote project in the current project","$0 unlink ~/jest --all"],["Unregister all previously linked workspaces","$0 unlink --all"],["Unregister all workspaces matching a glob","$0 unlink '@babel/*' 'pkg-{a,b}'"]]});var IAe=MC;var yAe=ie(aC()),rL=ie(Nn());Ss();var uf=class extends Be{constructor(){super(...arguments);this.interactive=Y.Boolean("-i,--interactive",{description:"Offer various choices, depending on the detected upgrade paths"});this.exact=Y.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=Y.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=Y.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.recursive=Y.Boolean("-R,--recursive",!1,{description:"Resolve again ALL resolutions for those packages"});this.mode=Y.String("--mode",{description:"Change what artifacts installs generate",validator:Yi(li)});this.patterns=Y.Rest()}async execute(){return this.recursive?await this.executeUpRecursive():await this.executeUpClassic()}async executeUpRecursive(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState({restoreResolutions:!1});let s=[...r.storedDescriptors.values()],o=s.map(u=>S.stringifyIdent(u)),a=new Set;for(let u of this.patterns){if(S.parseDescriptor(u).range!=="unknown")throw new me("Ranges aren't allowed when using --recursive");for(let g of(0,rL.default)(o,u)){let f=S.parseIdent(g);a.add(f.identHash)}}let l=s.filter(u=>a.has(u.identHash));for(let u of l)r.storedDescriptors.delete(u.descriptorHash),r.storedResolutions.delete(u.descriptorHash);return(await Fe.start({configuration:e,stdout:this.context.stdout},async u=>{await r.install({cache:n,report:u})})).exitCode()}async executeUpClassic(){var d;let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState({restoreResolutions:!1});let s=(d=this.interactive)!=null?d:e.get("preferInteractive"),o=AC(this,r),a=s?[Fr.KEEP,Fr.REUSE,Fr.PROJECT,Fr.LATEST]:[Fr.PROJECT,Fr.LATEST],l=[],c=[];for(let m of this.patterns){let I=!1,B=S.parseDescriptor(m);for(let b of r.workspaces)for(let R of[vr.REGULAR,vr.DEVELOPMENT]){let L=[...b.manifest.getForScope(R).values()].map(K=>S.stringifyIdent(K));for(let K of(0,rL.default)(L,S.stringifyIdent(B))){let J=S.parseIdent(K),ne=b.manifest[R].get(J.identHash);if(typeof ne=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");let q=S.makeDescriptor(J,B.range);l.push(Promise.resolve().then(async()=>[b,R,ne,await lC(q,{project:r,workspace:b,cache:n,target:R,modifier:o,strategies:a})])),I=!0}}I||c.push(m)}if(c.length>1)throw new me(`Patterns ${ue.prettyList(e,c,ps.CODE)} don't match any packages referenced by any workspace`);if(c.length>0)throw new me(`Pattern ${ue.prettyList(e,c,ps.CODE)} doesn't match any packages referenced by any workspace`);let u=await Promise.all(l),g=await Fa.start({configuration:e,stdout:this.context.stdout,suggestInstall:!1},async m=>{for(let[,,I,{suggestions:B,rejections:b}]of u){let R=B.filter(H=>H.descriptor!==null);if(R.length===0){let[H]=b;if(typeof H=="undefined")throw new Error("Assertion failed: Expected an error to have been set");let L=this.cli.error(H);r.configuration.get("enableNetwork")?m.reportError(z.CANT_SUGGEST_RESOLUTIONS,`${S.prettyDescriptor(e,I)} can't be resolved to a satisfying range + +${L}`):m.reportError(z.CANT_SUGGEST_RESOLUTIONS,`${S.prettyDescriptor(e,I)} can't be resolved to a satisfying range (note: network resolution has been disabled) + +${L}`)}else R.length>1&&!s&&m.reportError(z.CANT_SUGGEST_RESOLUTIONS,`${S.prettyDescriptor(e,I)} has multiple possible upgrade strategies; use -i to disambiguate manually`)}});if(g.hasErrors())return g.exitCode();let f=!1,h=[];for(let[m,I,,{suggestions:B}]of u){let b,R=B.filter(J=>J.descriptor!==null),H=R[0].descriptor,L=R.every(J=>S.areDescriptorsEqual(J.descriptor,H));R.length===1||L?b=H:(f=!0,{answer:b}=await(0,yAe.prompt)({type:"select",name:"answer",message:`Which range to you want to use in ${S.prettyWorkspace(e,m)} \u276F ${I}?`,choices:B.map(({descriptor:J,name:ne,reason:q})=>J?{name:ne,hint:q,descriptor:J}:{name:ne,hint:q,disabled:!0}),onCancel:()=>process.exit(130),result(J){return this.find(J,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let K=m.manifest[I].get(b.identHash);if(typeof K=="undefined")throw new Error("Assertion failed: This descriptor should have a matching entry");if(K.descriptorHash!==b.descriptorHash)m.manifest[I].set(b.identHash,b),h.push([m,I,K,b]);else{let J=e.makeResolver(),ne={project:r,resolver:J},q=J.bindDescriptor(K,m.anchoredLocator,ne);r.forgetResolution(q)}}return await e.triggerMultipleHooks(m=>m.afterWorkspaceDependencyReplacement,h),f&&this.context.stdout.write(` +`),(await Fe.start({configuration:e,stdout:this.context.stdout},async m=>{await r.install({cache:n,report:m,mode:this.mode})})).exitCode()}};uf.paths=[["up"]],uf.usage=ye.Usage({description:"upgrade dependencies across the project",details:"\n This command upgrades the packages matching the list of specified patterns to their latest available version across the whole project (regardless of whether they're part of `dependencies` or `devDependencies` - `peerDependencies` won't be affected). This is a project-wide command: all workspaces will be upgraded in the process.\n\n If `-R,--recursive` is set the command will change behavior and no other switch will be allowed. When operating under this mode `yarn up` will force all ranges matching the selected packages to be resolved again (often to the highest available versions) before being stored in the lockfile. It however won't touch your manifests anymore, so depending on your needs you might want to run both `yarn up` and `yarn up -R` to cover all bases.\n\n If `-i,--interactive` is set (or if the `preferInteractive` settings is toggled on) the command will offer various choices, depending on the detected upgrade paths. Some upgrades require this flag in order to resolve ambiguities.\n\n The, `-C,--caret`, `-E,--exact` and `-T,--tilde` options have the same meaning as in the `add` command (they change the modifier used when the range is missing or a tag, and are ignored when the range is explicitly set).\n\n If the `--mode=` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n Generally you can see `yarn up` as a counterpart to what was `yarn upgrade --latest` in Yarn 1 (ie it ignores the ranges previously listed in your manifests), but unlike `yarn upgrade` which only upgraded dependencies in the current workspace, `yarn up` will upgrade all workspaces at the same time.\n\n This command accepts glob patterns as arguments (if valid Descriptors and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n **Note:** The ranges have to be static, only the package scopes and names can contain glob patterns.\n ",examples:[["Upgrade all instances of lodash to the latest release","$0 up lodash"],["Upgrade all instances of lodash to the latest release, but ask confirmation for each","$0 up lodash -i"],["Upgrade all instances of lodash to 1.2.3","$0 up lodash@1.2.3"],["Upgrade all instances of packages with the `@babel` scope to the latest release","$0 up '@babel/*'"],["Upgrade all instances of packages containing the word `jest` to the latest release","$0 up '*jest*'"],["Upgrade all instances of packages with the `@babel` scope to 7.0.0","$0 up '@babel/*@7.0.0'"]]}),uf.schema=[pv("recursive",Bl.Forbids,["interactive","exact","tilde","caret"],{ignore:[void 0,!1]})];var wAe=uf;var OC=class extends Be{constructor(){super(...arguments);this.recursive=Y.Boolean("-R,--recursive",!1,{description:"List, for each workspace, what are all the paths that lead to the dependency"});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.peers=Y.Boolean("--peers",!1,{description:"Also print the peer dependencies that match the specified name"});this.package=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState();let n=S.parseIdent(this.package).identHash,s=this.recursive?nze(r,n,{configuration:e,peers:this.peers}):ize(r,n,{configuration:e,peers:this.peers});Hs.emitTree(s,{configuration:e,stdout:this.context.stdout,json:this.json,separators:1})}};OC.paths=[["why"]],OC.usage=ye.Usage({description:"display the reason why a package is needed",details:` + This command prints the exact reasons why a package appears in the dependency tree. + + If \`-R,--recursive\` is set, the listing will go in depth and will list, for each workspaces, what are all the paths that lead to the dependency. Note that the display is somewhat optimized in that it will not print the package listing twice for a single package, so if you see a leaf named "Foo" when looking for "Bar", it means that "Foo" already got printed higher in the tree. + `,examples:[["Explain why lodash is used in your project","$0 why lodash"]]});var BAe=OC;function ize(t,e,{configuration:r,peers:i}){let n=de.sortMap(t.storedPackages.values(),a=>S.stringifyLocator(a)),s={},o={children:s};for(let a of n){let l={},c=null;for(let u of a.dependencies.values()){if(!i&&a.peerDependencies.has(u.identHash))continue;let g=t.storedResolutions.get(u.descriptorHash);if(!g)throw new Error("Assertion failed: The resolution should have been registered");let f=t.storedPackages.get(g);if(!f)throw new Error("Assertion failed: The package should have been registered");if(f.identHash!==e)continue;if(c===null){let p=S.stringifyLocator(a);s[p]={value:[a,ue.Type.LOCATOR],children:l}}let h=S.stringifyLocator(f);l[h]={value:[{descriptor:u,locator:f},ue.Type.DEPENDENT]}}}return o}function nze(t,e,{configuration:r,peers:i}){let n=de.sortMap(t.workspaces,f=>S.stringifyLocator(f.anchoredLocator)),s=new Set,o=new Set,a=f=>{if(s.has(f.locatorHash))return o.has(f.locatorHash);if(s.add(f.locatorHash),f.identHash===e)return o.add(f.locatorHash),!0;let h=!1;f.identHash===e&&(h=!0);for(let p of f.dependencies.values()){if(!i&&f.peerDependencies.has(p.identHash))continue;let d=t.storedResolutions.get(p.descriptorHash);if(!d)throw new Error("Assertion failed: The resolution should have been registered");let m=t.storedPackages.get(d);if(!m)throw new Error("Assertion failed: The package should have been registered");a(m)&&(h=!0)}return h&&o.add(f.locatorHash),h};for(let f of n){let h=t.storedPackages.get(f.anchoredLocator.locatorHash);if(!h)throw new Error("Assertion failed: The package should have been registered");a(h)}let l=new Set,c={},u={children:c},g=(f,h,p)=>{if(!o.has(f.locatorHash))return;let d=p!==null?ue.tuple(ue.Type.DEPENDENT,{locator:f,descriptor:p}):ue.tuple(ue.Type.LOCATOR,f),m={},I={value:d,children:m},B=S.stringifyLocator(f);if(h[B]=I,!l.has(f.locatorHash)&&(l.add(f.locatorHash),!(p!==null&&t.tryWorkspaceByLocator(f))))for(let b of f.dependencies.values()){if(!i&&f.peerDependencies.has(b.identHash))continue;let R=t.storedResolutions.get(b.descriptorHash);if(!R)throw new Error("Assertion failed: The resolution should have been registered");let H=t.storedPackages.get(R);if(!H)throw new Error("Assertion failed: The package should have been registered");g(H,m,b)}};for(let f of n){let h=t.storedPackages.get(f.anchoredLocator.locatorHash);if(!h)throw new Error("Assertion failed: The package should have been registered");g(h,c,null)}return u}var fL={};it(fL,{default:()=>wze,gitUtils:()=>Uc});var Uc={};it(Uc,{TreeishProtocols:()=>vn,clone:()=>cL,fetchBase:()=>jAe,fetchChangedFiles:()=>YAe,fetchChangedWorkspaces:()=>Ize,fetchRoot:()=>GAe,isGitUrl:()=>ff,lsRemote:()=>HAe,normalizeLocator:()=>AL,normalizeRepoUrl:()=>KC,resolveUrl:()=>lL,splitRepoUrl:()=>UC});var oL=ie(OAe()),gf=ie(require("querystring")),aL=ie(Or()),KAe=ie(require("url"));function UAe(){return _(P({},process.env),{GIT_SSH_COMMAND:"ssh -o BatchMode=yes"})}var Eze=[/^ssh:/,/^git(?:\+[^:]+)?:/,/^(?:git\+)?https?:[^#]+\/[^#]+(?:\.git)(?:#.*)?$/,/^git@[^#]+\/[^#]+\.git(?:#.*)?$/,/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z._0-9-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z._0-9-]+?)(?:\.git)?(?:#.*)?$/,/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/],vn;(function(n){n.Commit="commit",n.Head="head",n.Tag="tag",n.Semver="semver"})(vn||(vn={}));function ff(t){return t?Eze.some(e=>!!t.match(e)):!1}function UC(t){t=KC(t);let e=t.indexOf("#");if(e===-1)return{repo:t,treeish:{protocol:vn.Head,request:"HEAD"},extra:{}};let r=t.slice(0,e),i=t.slice(e+1);if(i.match(/^[a-z]+=/)){let n=gf.default.parse(i);for(let[l,c]of Object.entries(n))if(typeof c!="string")throw new Error(`Assertion failed: The ${l} parameter must be a literal string`);let s=Object.values(vn).find(l=>Object.prototype.hasOwnProperty.call(n,l)),o,a;typeof s!="undefined"?(o=s,a=n[s]):(o=vn.Head,a="HEAD");for(let l of Object.values(vn))delete n[l];return{repo:r,treeish:{protocol:o,request:a},extra:n}}else{let n=i.indexOf(":"),s,o;return n===-1?(s=null,o=i):(s=i.slice(0,n),o=i.slice(n+1)),{repo:r,treeish:{protocol:s,request:o},extra:{}}}}function KC(t,{git:e=!1}={}){var r;if(t=t.replace(/^git\+https:/,"https:"),t=t.replace(/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)(?:\.git)?(#.*)?$/,"https://github.com/$1/$2.git$3"),t=t.replace(/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/,"https://github.com/$1/$2.git#$3"),e){t=t.replace(/^git\+([^:]+):/,"$1:");let i;try{i=KAe.default.parse(t)}catch{i=null}i&&i.protocol==="ssh:"&&((r=i.path)==null?void 0:r.startsWith("/:"))&&(t=t.replace(/^ssh:\/\//,""))}return t}function AL(t){return S.makeLocator(t,KC(t.reference))}async function HAe(t,e){let r=KC(t,{git:!0});if(!Zt.getNetworkSettings(`https://${(0,oL.default)(r).resource}`,{configuration:e}).enableNetwork)throw new Error(`Request to '${r}' has been blocked because of your configuration settings`);let n;try{n=await hr.execvp("git",["ls-remote",r],{cwd:e.startingCwd,env:UAe(),strict:!0})}catch(l){throw l.message=`Listing the refs for ${t} failed`,l}let s=new Map,o=/^([a-f0-9]{40})\t([^\n]+)/gm,a;for(;(a=o.exec(n.stdout))!==null;)s.set(a[2],a[1]);return s}async function lL(t,e){let{repo:r,treeish:{protocol:i,request:n},extra:s}=UC(t),o=await HAe(r,e),a=(c,u)=>{switch(c){case vn.Commit:{if(!u.match(/^[a-f0-9]{40}$/))throw new Error("Invalid commit hash");return gf.default.stringify(_(P({},s),{commit:u}))}case vn.Head:{let g=o.get(u==="HEAD"?u:`refs/heads/${u}`);if(typeof g=="undefined")throw new Error(`Unknown head ("${u}")`);return gf.default.stringify(_(P({},s),{commit:g}))}case vn.Tag:{let g=o.get(`refs/tags/${u}`);if(typeof g=="undefined")throw new Error(`Unknown tag ("${u}")`);return gf.default.stringify(_(P({},s),{commit:g}))}case vn.Semver:{let g=qt.validRange(u);if(!g)throw new Error(`Invalid range ("${u}")`);let f=new Map([...o.entries()].filter(([p])=>p.startsWith("refs/tags/")).map(([p,d])=>[aL.default.parse(p.slice(10)),d]).filter(p=>p[0]!==null)),h=aL.default.maxSatisfying([...f.keys()],g);if(h===null)throw new Error(`No matching range ("${u}")`);return gf.default.stringify(_(P({},s),{commit:f.get(h)}))}case null:{let g;if((g=l(vn.Commit,u))!==null||(g=l(vn.Tag,u))!==null||(g=l(vn.Head,u))!==null)return g;throw u.match(/^[a-f0-9]+$/)?new Error(`Couldn't resolve "${u}" as either a commit, a tag, or a head - if a commit, use the 40-characters commit hash`):new Error(`Couldn't resolve "${u}" as either a commit, a tag, or a head`)}default:throw new Error(`Invalid Git resolution protocol ("${c}")`)}},l=(c,u)=>{try{return a(c,u)}catch(g){return null}};return`${r}#${a(i,n)}`}async function cL(t,e){return await e.getLimit("cloneConcurrency")(async()=>{let{repo:r,treeish:{protocol:i,request:n}}=UC(t);if(i!=="commit")throw new Error("Invalid treeish protocol when cloning");let s=KC(r,{git:!0});if(Zt.getNetworkSettings(`https://${(0,oL.default)(s).resource}`,{configuration:e}).enableNetwork===!1)throw new Error(`Request to '${s}' has been blocked because of your configuration settings`);let o=await T.mktempPromise(),a={cwd:o,env:UAe(),strict:!0};try{await hr.execvp("git",["clone","-c core.autocrlf=false",s,M.fromPortablePath(o)],a),await hr.execvp("git",["checkout",`${n}`],a)}catch(l){throw l.message=`Repository clone failed: ${l.message}`,l}return o})}async function GAe(t){let e=null,r,i=t;do r=i,await T.existsPromise(v.join(r,".git"))&&(e=r),i=v.dirname(r);while(e===null&&i!==r);return e}async function jAe(t,{baseRefs:e}){if(e.length===0)throw new me("Can't run this command with zero base refs specified.");let r=[];for(let a of e){let{code:l}=await hr.execvp("git",["merge-base",a,"HEAD"],{cwd:t});l===0&&r.push(a)}if(r.length===0)throw new me(`No ancestor could be found between any of HEAD and ${e.join(", ")}`);let{stdout:i}=await hr.execvp("git",["merge-base","HEAD",...r],{cwd:t,strict:!0}),n=i.trim(),{stdout:s}=await hr.execvp("git",["show","--quiet","--pretty=format:%s",n],{cwd:t,strict:!0}),o=s.trim();return{hash:n,title:o}}async function YAe(t,{base:e,project:r}){let i=de.buildIgnorePattern(r.configuration.get("changesetIgnorePatterns")),{stdout:n}=await hr.execvp("git",["diff","--name-only",`${e}`],{cwd:t,strict:!0}),s=n.split(/\r\n|\r|\n/).filter(c=>c.length>0).map(c=>v.resolve(t,M.toPortablePath(c))),{stdout:o}=await hr.execvp("git",["ls-files","--others","--exclude-standard"],{cwd:t,strict:!0}),a=o.split(/\r\n|\r|\n/).filter(c=>c.length>0).map(c=>v.resolve(t,M.toPortablePath(c))),l=[...new Set([...s,...a].sort())];return i?l.filter(c=>!v.relative(r.cwd,c).match(i)):l}async function Ize({ref:t,project:e}){if(e.configuration.projectCwd===null)throw new me("This command can only be run from within a Yarn project");let r=[v.resolve(e.cwd,e.configuration.get("cacheFolder")),v.resolve(e.cwd,e.configuration.get("installStatePath")),v.resolve(e.cwd,e.configuration.get("lockfileFilename")),v.resolve(e.cwd,e.configuration.get("virtualFolder"))];await e.configuration.triggerHook(o=>o.populateYarnPaths,e,o=>{o!=null&&r.push(o)});let i=await GAe(e.configuration.projectCwd);if(i==null)throw new me("This command can only be run on Git repositories");let n=await jAe(i,{baseRefs:typeof t=="string"?[t]:e.configuration.get("changesetBaseRefs")}),s=await YAe(i,{base:n.hash,project:e});return new Set(de.mapAndFilter(s,o=>{let a=e.tryWorkspaceByFilePath(o);return a===null?de.mapAndFilter.skip:r.some(l=>o.startsWith(l))?de.mapAndFilter.skip:a}))}var uL=class{supports(e,r){return ff(e.reference)}getLocalPath(e,r){return null}async fetch(e,r){let i=r.checksums.get(e.locatorHash)||null,n=AL(e),s=new Map(r.checksums);s.set(n.locatorHash,i);let o=_(P({},r),{checksums:s}),a=await this.downloadHosted(n,o);if(a!==null)return a;let[l,c,u]=await r.cache.fetchPackageFromCache(e,i,P({onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${S.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote repository`),loader:()=>this.cloneFromRemote(n,o),skipIntegrityCheck:r.skipIntegrityCheck},r.cacheOptions));return{packageFs:l,releaseFs:c,prefixPath:S.getIdentVendorPath(e),checksum:u}}async downloadHosted(e,r){return r.project.configuration.reduceHook(i=>i.fetchHostedRepository,null,e,r)}async cloneFromRemote(e,r){let i=await cL(e.reference,r.project.configuration),n=UC(e.reference),s=v.join(i,"package.tgz");await Kt.prepareExternalProject(i,s,{configuration:r.project.configuration,report:r.report,workspace:n.extra.workspace,locator:e});let o=await T.readFilePromise(s);return await de.releaseAfterUseAsync(async()=>await Ai.convertToZip(o,{compressionLevel:r.project.configuration.get("compressionLevel"),prefixPath:S.getIdentVendorPath(e),stripComponents:1}))}};var gL=class{supportsDescriptor(e,r){return ff(e.range)}supportsLocator(e,r){return ff(e.reference)}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,i){return e}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){let n=await lL(e.range,i.project.configuration);return[S.makeLocator(e,n)]}async getSatisfying(e,r,i){return null}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),n=await de.releaseAfterUseAsync(async()=>await Ze.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return _(P({},e),{version:n.version||"0.0.0",languageName:n.languageName||r.project.configuration.get("defaultLanguageName"),linkType:gt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var yze={configuration:{changesetBaseRefs:{description:"The base git refs that the current HEAD is compared against when detecting changes. Supports git branches, tags, and commits.",type:ge.STRING,isArray:!0,isNullable:!1,default:["master","origin/master","upstream/master","main","origin/main","upstream/main"]},changesetIgnorePatterns:{description:"Array of glob patterns; files matching them will be ignored when fetching the changed files",type:ge.STRING,default:[],isArray:!0},cloneConcurrency:{description:"Maximal number of concurrent clones",type:ge.NUMBER,default:2}},fetchers:[uL],resolvers:[gL]};var wze=yze;var HC=class extends Be{constructor(){super(...arguments);this.since=Y.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.recursive=Y.Boolean("-R,--recursive",!1,{description:"Find packages via dependencies/devDependencies instead of using the workspaces field"});this.verbose=Y.Boolean("-v,--verbose",!1,{description:"Also return the cross-dependencies between workspaces"});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r}=await Ke.find(e,this.context.cwd);return(await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout},async n=>{let s=this.since?await Uc.fetchChangedWorkspaces({ref:this.since,project:r}):r.workspaces,o=new Set(s);if(this.recursive)for(let a of[...s].map(l=>l.getRecursiveWorkspaceDependents()))for(let l of a)o.add(l);for(let a of o){let{manifest:l}=a,c;if(this.verbose){let u=new Set,g=new Set;for(let f of Ze.hardDependencies)for(let[h,p]of l.getForScope(f)){let d=r.tryWorkspaceByDescriptor(p);d===null?r.workspacesByIdent.has(h)&&g.add(p):u.add(d)}c={workspaceDependencies:Array.from(u).map(f=>f.relativeCwd),mismatchedWorkspaceDependencies:Array.from(g).map(f=>S.stringifyDescriptor(f))}}n.reportInfo(null,`${a.relativeCwd}`),n.reportJson(P({location:a.relativeCwd,name:l.name?S.stringifyIdent(l.name):null},c))}})).exitCode()}};HC.paths=[["workspaces","list"]],HC.usage=ye.Usage({category:"Workspace-related commands",description:"list all available workspaces",details:"\n This command will print the list of all workspaces in the project.\n\n - If `--since` is set, Yarn will only list workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If both the `-v,--verbose` and `--json` options are set, Yarn will also return the cross-dependencies between each workspaces (useful when you wish to automatically generate Buck / Bazel rules).\n "});var qAe=HC;var GC=class extends Be{constructor(){super(...arguments);this.workspaceName=Y.String();this.commandName=Y.String();this.args=Y.Proxy()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd);if(!i)throw new rt(r.cwd,this.context.cwd);let n=r.workspaces,s=new Map(n.map(a=>{let l=S.convertToIdent(a.locator);return[S.stringifyIdent(l),a]})),o=s.get(this.workspaceName);if(o===void 0){let a=Array.from(s.keys()).sort();throw new me(`Workspace '${this.workspaceName}' not found. Did you mean any of the following: + - ${a.join(` + - `)}?`)}return this.cli.run([this.commandName,...this.args],{cwd:o.cwd})}};GC.paths=[["workspace"]],GC.usage=ye.Usage({category:"Workspace-related commands",description:"run a command within the specified workspace",details:` + This command will run a given sub-command on a single workspace. + `,examples:[["Add a package to a single workspace","yarn workspace components add -D react"],["Run build script on a single workspace","yarn workspace components run build"]]});var JAe=GC;var Bze={configuration:{enableImmutableInstalls:{description:"If true (the default on CI), prevents the install command from modifying the lockfile",type:ge.BOOLEAN,default:WAe.isCI},defaultSemverRangePrefix:{description:"The default save prefix: '^', '~' or ''",type:ge.STRING,values:["^","~",""],default:Lo.CARET}},commands:[soe,aoe,wae,Nae,mAe,nAe,tAe,qAe,Uae,Hae,Gae,jae,ioe,noe,Lae,Mae,Yae,qae,Wae,zae,_ae,IAe,Xae,cAe,AAe,uAe,Zae,gAe,fAe,hAe,dAe,CAe,wAe,BAe,JAe]},Qze=Bze;var mL={};it(mL,{default:()=>vze});var Me={optional:!0},zAe=[["@tailwindcss/aspect-ratio@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@tailwindcss/line-clamp@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@fullhuman/postcss-purgecss@3.1.3 || 3.1.3-alpha.0",{peerDependencies:{postcss:"^8.0.0"}}],["@samverschueren/stream-to-observable@<0.3.1",{peerDependenciesMeta:{rxjs:Me,zenObservable:Me}}],["any-observable@<0.5.1",{peerDependenciesMeta:{rxjs:Me,zenObservable:Me}}],["@pm2/agent@<1.0.4",{dependencies:{debug:"*"}}],["debug@<4.2.0",{peerDependenciesMeta:{["supports-color"]:Me}}],["got@<11",{dependencies:{["@types/responselike"]:"^1.0.0",["@types/keyv"]:"^3.1.1"}}],["cacheable-lookup@<4.1.2",{dependencies:{["@types/keyv"]:"^3.1.1"}}],["http-link-dataloader@*",{peerDependencies:{graphql:"^0.13.1 || ^14.0.0"}}],["typescript-language-server@*",{dependencies:{["vscode-jsonrpc"]:"^5.0.1",["vscode-languageserver-protocol"]:"^3.15.0"}}],["postcss-syntax@*",{peerDependenciesMeta:{["postcss-html"]:Me,["postcss-jsx"]:Me,["postcss-less"]:Me,["postcss-markdown"]:Me,["postcss-scss"]:Me}}],["jss-plugin-rule-value-function@<=10.1.1",{dependencies:{["tiny-warning"]:"^1.0.2"}}],["ink-select-input@<4.1.0",{peerDependencies:{react:"^16.8.2"}}],["license-webpack-plugin@<2.3.18",{peerDependenciesMeta:{webpack:Me}}],["snowpack@>=3.3.0",{dependencies:{["node-gyp"]:"^7.1.0"}}],["promise-inflight@*",{peerDependenciesMeta:{bluebird:Me}}],["reactcss@*",{peerDependencies:{react:"*"}}],["react-color@<=2.19.0",{peerDependencies:{react:"*"}}],["gatsby-plugin-i18n@*",{dependencies:{ramda:"^0.24.1"}}],["useragent@^2.0.0",{dependencies:{request:"^2.88.0",yamlparser:"0.0.x",semver:"5.5.x"}}],["@apollographql/apollo-tools@*",{peerDependencies:{graphql:"^14.2.1 || ^15.0.0"}}],["material-table@^2.0.0",{dependencies:{"@babel/runtime":"^7.11.2"}}],["@babel/parser@*",{dependencies:{"@babel/types":"^7.8.3"}}],["fork-ts-checker-webpack-plugin@<=6.3.4",{peerDependencies:{eslint:">= 6",typescript:">= 2.7",webpack:">= 4","vue-template-compiler":"*"},peerDependenciesMeta:{eslint:Me,"vue-template-compiler":Me}}],["rc-animate@<=3.1.1",{peerDependencies:{react:">=16.9.0","react-dom":">=16.9.0"}}],["react-bootstrap-table2-paginator@*",{dependencies:{classnames:"^2.2.6"}}],["react-draggable@<=4.4.3",{peerDependencies:{react:">= 16.3.0","react-dom":">= 16.3.0"}}],["apollo-upload-client@<14",{peerDependencies:{graphql:"14 - 15"}}],["react-instantsearch-core@<=6.7.0",{peerDependencies:{algoliasearch:">= 3.1 < 5"}}],["react-instantsearch-dom@<=6.7.0",{dependencies:{"react-fast-compare":"^3.0.0"}}],["ws@<7.2.1",{peerDependencies:{bufferutil:"^4.0.1","utf-8-validate":"^5.0.2"},peerDependenciesMeta:{bufferutil:Me,"utf-8-validate":Me}}],["react-portal@*",{peerDependencies:{"react-dom":"^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0"}}],["react-scripts@<=4.0.1",{peerDependencies:{react:"*"}}],["testcafe@<=1.10.1",{dependencies:{"@babel/plugin-transform-for-of":"^7.12.1","@babel/runtime":"^7.12.5"}}],["testcafe-legacy-api@<=4.2.0",{dependencies:{"testcafe-hammerhead":"^17.0.1","read-file-relative":"^1.2.0"}}],["@google-cloud/firestore@<=4.9.3",{dependencies:{protobufjs:"^6.8.6"}}],["gatsby-source-apiserver@*",{dependencies:{["babel-polyfill"]:"^6.26.0"}}],["@webpack-cli/package-utils@<=1.0.1-alpha.4",{dependencies:{["cross-spawn"]:"^7.0.3"}}],["gatsby-remark-prismjs@<3.3.28",{dependencies:{lodash:"^4"}}],["gatsby-plugin-favicon@*",{peerDependencies:{webpack:"*"}}],["gatsby-plugin-sharp@*",{dependencies:{debug:"^4.3.1"}}],["gatsby-react-router-scroll@*",{dependencies:{["prop-types"]:"^15.7.2"}}],["@rebass/forms@*",{dependencies:{["@styled-system/should-forward-prop"]:"^5.0.0"},peerDependencies:{react:"^16.8.6"}}],["rebass@*",{peerDependencies:{react:"^16.8.6"}}],["@ant-design/react-slick@<=0.28.3",{peerDependencies:{react:">=16.0.0"}}],["mqtt@<4.2.7",{dependencies:{duplexify:"^4.1.1"}}],["vue-cli-plugin-vuetify@<=2.0.3",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":Me,"vuetify-loader":Me}}],["vue-cli-plugin-vuetify@<=2.0.4",{dependencies:{"null-loader":"^3.0.0"}}],["@vuetify/cli-plugin-utils@<=0.0.4",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":Me}}],["@vue/cli-plugin-typescript@<=5.0.0-alpha.0",{dependencies:{"babel-loader":"^8.1.0"}}],["@vue/cli-plugin-typescript@<=5.0.0-beta.0",{dependencies:{"@babel/core":"^7.12.16"},peerDependencies:{"vue-template-compiler":"^2.0.0"},peerDependenciesMeta:{"vue-template-compiler":Me}}],["cordova-ios@<=6.3.0",{dependencies:{underscore:"^1.9.2"}}],["cordova-lib@<=10.0.1",{dependencies:{underscore:"^1.9.2"}}],["git-node-fs@*",{peerDependencies:{"js-git":"^0.7.8"},peerDependenciesMeta:{"js-git":Me}}],["consolidate@*",{peerDependencies:{velocityjs:"^2.0.1",tinyliquid:"^0.2.34","liquid-node":"^3.0.1",jade:"^1.11.0","then-jade":"*",dust:"^0.3.0","dustjs-helpers":"^1.7.4","dustjs-linkedin":"^2.7.5",swig:"^1.4.2","swig-templates":"^2.0.3","razor-tmpl":"^1.3.1",atpl:">=0.7.6",liquor:"^0.0.5",twig:"^1.15.2",ejs:"^3.1.5",eco:"^1.1.0-rc-3",jazz:"^0.0.18",jqtpl:"~1.1.0",hamljs:"^0.6.2",hamlet:"^0.3.3",whiskers:"^0.4.0","haml-coffee":"^1.14.1","hogan.js":"^3.0.2",templayed:">=0.2.3",handlebars:"^4.7.6",underscore:"^1.11.0",lodash:"^4.17.20",pug:"^3.0.0","then-pug":"*",qejs:"^3.0.5",walrus:"^0.10.1",mustache:"^4.0.1",just:"^0.1.8",ect:"^0.5.9",mote:"^0.2.0",toffee:"^0.3.6",dot:"^1.1.3","bracket-template":"^1.1.5",ractive:"^1.3.12",nunjucks:"^3.2.2",htmling:"^0.0.8","babel-core":"^6.26.3",plates:"~0.4.11","react-dom":"^16.13.1",react:"^16.13.1","arc-templates":"^0.5.3",vash:"^0.13.0",slm:"^2.0.0",marko:"^3.14.4",teacup:"^2.0.0","coffee-script":"^1.12.7",squirrelly:"^5.1.0",twing:"^5.0.2"},peerDependenciesMeta:{velocityjs:Me,tinyliquid:Me,"liquid-node":Me,jade:Me,"then-jade":Me,dust:Me,"dustjs-helpers":Me,"dustjs-linkedin":Me,swig:Me,"swig-templates":Me,"razor-tmpl":Me,atpl:Me,liquor:Me,twig:Me,ejs:Me,eco:Me,jazz:Me,jqtpl:Me,hamljs:Me,hamlet:Me,whiskers:Me,"haml-coffee":Me,"hogan.js":Me,templayed:Me,handlebars:Me,underscore:Me,lodash:Me,pug:Me,"then-pug":Me,qejs:Me,walrus:Me,mustache:Me,just:Me,ect:Me,mote:Me,toffee:Me,dot:Me,"bracket-template":Me,ractive:Me,nunjucks:Me,htmling:Me,"babel-core":Me,plates:Me,"react-dom":Me,react:Me,"arc-templates":Me,vash:Me,slm:Me,marko:Me,teacup:Me,"coffee-script":Me,squirrelly:Me,twing:Me}}],["vue-loader@<=16.3.1",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",webpack:"^4.1.0 || ^5.0.0-0"}}],["scss-parser@*",{dependencies:{lodash:"^4.17.21"}}],["query-ast@*",{dependencies:{lodash:"^4.17.21"}}],["redux-thunk@<=2.3.0",{peerDependencies:{redux:"^4.0.0"}}],["skypack@<=0.3.2",{dependencies:{tar:"^6.1.0"}}],["@npmcli/metavuln-calculator@*",{dependencies:{"json-parse-even-better-errors":"^2.3.1"}}],["bin-links@*",{dependencies:{"mkdirp-infer-owner":"^1.0.2"}}],["rollup-plugin-polyfill-node@*",{peerDependencies:{rollup:"^1.20.0 || ^2.0.0"}}],["snowpack@*",{dependencies:{"magic-string":"^0.25.7"}}],["elm-webpack-loader@*",{dependencies:{temp:"^0.9.4"}}],["winston-transport@<=4.4.0",{dependencies:{logform:"^2.2.0"}}],["jest-vue-preprocessor@*",{dependencies:{"@babel/core":"7.8.7","@babel/template":"7.8.6"},peerDependencies:{pug:"^2.0.4"},peerDependenciesMeta:{pug:Me}}],["redux-persist@*",{peerDependencies:{react:">=16"},peerDependenciesMeta:{react:Me}}],["sodium@>=3",{dependencies:{"node-gyp":"^3.8.0"}}],["babel-plugin-graphql-tag@<=3.1.0",{peerDependencies:{graphql:"^14.0.0 || ^15.0.0"}}],["@playwright/test@<=1.14.1",{dependencies:{"jest-matcher-utils":"^26.4.2"}}],...["babel-plugin-remove-graphql-queries@<3.14.0-next.1","babel-preset-gatsby-package@<1.14.0-next.1","create-gatsby@<1.14.0-next.1","gatsby-admin@<0.24.0-next.1","gatsby-cli@<3.14.0-next.1","gatsby-core-utils@<2.14.0-next.1","gatsby-design-tokens@<3.14.0-next.1","gatsby-legacy-polyfills@<1.14.0-next.1","gatsby-plugin-benchmark-reporting@<1.14.0-next.1","gatsby-plugin-graphql-config@<0.23.0-next.1","gatsby-plugin-image@<1.14.0-next.1","gatsby-plugin-mdx@<2.14.0-next.1","gatsby-plugin-netlify-cms@<5.14.0-next.1","gatsby-plugin-no-sourcemaps@<3.14.0-next.1","gatsby-plugin-page-creator@<3.14.0-next.1","gatsby-plugin-preact@<5.14.0-next.1","gatsby-plugin-preload-fonts@<2.14.0-next.1","gatsby-plugin-schema-snapshot@<2.14.0-next.1","gatsby-plugin-styletron@<6.14.0-next.1","gatsby-plugin-subfont@<3.14.0-next.1","gatsby-plugin-utils@<1.14.0-next.1","gatsby-recipes@<0.25.0-next.1","gatsby-source-shopify@<5.6.0-next.1","gatsby-source-wikipedia@<3.14.0-next.1","gatsby-transformer-screenshot@<3.14.0-next.1","gatsby-worker@<0.5.0-next.1"].map(t=>[t,{dependencies:{"@babel/runtime":"^7.14.8"}}]),["gatsby-core-utils@<2.14.0-next.1",{dependencies:{got:"8.3.2"}}],["gatsby-plugin-gatsby-cloud@<=3.1.0-next.0",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["gatsby-plugin-gatsby-cloud@<=3.2.0-next.1",{peerDependencies:{webpack:"*"}}],["babel-plugin-remove-graphql-queries@<=3.14.0-next.1",{dependencies:{"gatsby-core-utils":"^2.8.0-next.1"}}],["gatsby-plugin-netlify@3.13.0-next.1",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["clipanion-v3-codemod@<=0.2.0",{peerDependencies:{jscodeshift:"^0.11.0"}}],["react-live@*",{peerDependencies:{"react-dom":"*",react:"*"}}],["webpack@<4.44.1",{peerDependenciesMeta:{"webpack-cli":Me,"webpack-command":Me}}],["webpack@<5.0.0-beta.23",{peerDependenciesMeta:{"webpack-cli":Me}}],["webpack-dev-server@<3.10.2",{peerDependenciesMeta:{"webpack-cli":Me}}]];var pL;function VAe(){return typeof pL=="undefined"&&(pL=require("zlib").brotliDecompressSync(Buffer.from("G7weAByFTVk3Vs7UfHhq4yykgEM7pbW7TI43SG2S5tvGrwHBAzdz+s/npQ6tgEvobvxisrPIadkXeUAJotBn5bDZ5kAhcRqsIHe3F75Walet5hNalwgFDtxb0BiDUjiUQkjG0yW2hto9HPgiCkm316d6bC0kST72YN7D7rfkhCE9x4J0XwB0yavalxpUu2t9xszHrmtwalOxT7VslsxWcB1qpqZwERUra4psWhTV8BgwWeizurec82Caf1ABL11YMfbf8FJ9JBceZOkgmvrQPbC9DUldX/yMbmX06UQluCEjSwUoyO+EZPIjofr+/oAZUck2enraRD+oWLlnlYnj8xB+gwSo9lmmks4fXv574qSqcWA6z21uYkzMu3EWj+K23RxeQlLqiE35/rC8GcS4CGkKHKKq+zAIQwD9iRDNfiAqueLLpicFFrNsAI4zeTD/eO9MHcnRa5m8UT+M2+V+AkFST4BlKneiAQRSdST8KEAIyFlULt6wa9EBd0Ds28VmpaxquJdVt+nwdEs5xUskI13OVtFyY0UrQIRAlCuvvWivvlSKQfTO+2Q8OyUR1W5RvetaPz4jD27hdtwHFFA1Ptx6Ee/t2cY2rg2G46M1pNDRf2pWhvpy8pqMnuI3++4OF3+7OFIWXGjh+o7Nr2jNvbiYcQdQS1h903/jVFgOpA0yJ78z+x759bFA0rq+6aY5qPB4FzS3oYoLupDUhD9nDz6F6H7hpnlMf18KNKDu4IKjTWwrAnY6MFQw1W6ymOALHlFyCZmQhldg1MQHaMVVQTVgDC60TfaBqG++Y8PEoFhN/PBTZT175KNP/BlHDYGOOBmnBdzqJKplZ/ljiVG0ZBzfqeBRrrUkn6rA54462SgiliKoYVnbeptMdXNfAuaupIEi0bApF10TlgHfmEJAPUVidRVFyDupSem5po5vErPqWKhKbUIp0LozpYsIKK57dM/HKr+nguF+7924IIWMICkQ8JUigs9D+W+c4LnNoRtPPKNRUiCYmP+Jfo2lfKCKw8qpraEeWU3uiNRO6zcyKQoXPR5htmzzLznke7b4YbXW3I1lIRzmgG02Udb58U+7TpwyN7XymCgH+wuPDthZVQvRZuEP+SnLtMicz9m5zASWOBiAcLmkuFlTKuHspSIhCBD0yUPKcxu81A+4YD78rA2vtwsUEday9WNyrShyrl60rWmA+SmbYZkQOwFJWArxRYYc5jGhA5ikxYw1rx3ei4NmeX/lKiwpZ9Ln1tV2Ae7sArvxuVLbJjqJRjW1vFXAyHpvLG+8MJ6T2Ubx5M2KDa2SN6vuIGxJ9WQM9Mk3Q7aCNiZONXllhqq24DmoLbQfW2rYWsOgHWjtOmIQMyMKdiHZDjoyIq5+U700nZ6odJAoYXPQBvFNiQ78d5jaXliBqLTJEqUCwi+LiH2mx92EmNKDsJL74Z613+3lf20pxkV1+erOrjj8pW00vsPaahKUM+05ssd5uwM7K482KWEf3TCwlg/o3e5ngto7qSMz7YteIgCsF1UOcsLk7F7MxWbvrPMY473ew0G+noVL8EPbkmEMftMSeL6HFub/zy+2JQ==","base64")).toString()),pL}var dL;function _Ae(){return typeof dL=="undefined"&&(dL=require("zlib").brotliDecompressSync(Buffer.from("G8MSIIzURnVBnObTcvb3XE6v2S9Qgc2K801Oa5otNKEtK8BINZNcaQHy+9/vf/WXBimwutXC33P2DPc64pps5rz7NGGWaOKNSPL4Y2KRE8twut2lFOIN+OXPtRmPMRhMTILib2bEQx43az2I5d3YS8Roa5UZpF/ujHb3Djd3GDvYUfvFYSUQ39vb2cmifp/rgB4J/65JK3wRBTvMBoNBmn3mbXC63/gbBkW/2IRPri0O8bcsRBsmarF328pAln04nyJFkwUAvNu934supAqLtyerZZpJ8I8suJHhf/ocMV+scKwa8NOiDKIPXw6Ex/EEZD6TEGaW8N5zvNHYF10l6Lfooj7D5W2k3dgvQSbp2Wv8TGOayS978gxlOLVjTGXs66ozewbrjwElLtyrYNnWTfzzdEutgROUFPVMhnMoy8EjJLLlWwIEoySxliim9kYW30JUHiPVyjt0iAw/ZpPmCbUCltYPnq6ZNblIKhTNhqS/oqC9iya5sGKZTOVsTEg34n92uZTf2iPpcZih8rPW8CzA+adIGmyCPcKdLMsBLShd+zuEbTrqpwuh+DLmracZcjPC5Sdf5odDAhKpFuOsQS67RT+1VgWWygSv3YwxDnylc04/PYuaMeIzhBkLrvs7e/OUzRTF56MmfY6rI63QtEjEQzq637zQqJ39nNhu3NmoRRhW/086bHGBUtx0PE0j3aEGvkdh9WJC8y8j8mqqke9/dQ5la+Q3ba4RlhvTbnfQhPDDab3tUifkjKuOsp13mXEmO00Mu88F/M67R7LXfoFDFLNtgCSWjWX+3Jn1371pJTK9xPBiMJafvDjtFyAzu8rxeQ0TKMQXNPs5xxiBOd+BRJP8KP88XPtJIbZKh/cdW8KvBUkpqKpGoiIaA32c3/JnQr4efXt85mXvidOvn/eU3Pase1typLYBalJ14mCso9h79nuMOuCa/kZAOkJHmTjP5RM2WNoPasZUAnT1TAE/NH25hUxcQv6hQWR/m1PKk4ooXMcM4SR1iYU3fUohvqk4RY2hbmTVVIXv6TvqO+0doOjgeVFAcom+RlwJQmOVH7pr1Q9LoJT6n1DeQEB+NHygsATbIwTcOKZlJsY8G4+suX1uQLjUWwLjjs0mvSvZcLTpIGAekeR7GCgl8eo3ndAqEe2XCav4huliHjdbIPBsGJuPX7lrO9HX1UbXRH5opOe1x6JsOSgHZR+EaxuXVhpLLxm6jk1LJtZfHSc6BKPun3CpYYVMJGwEUyk8MTGG0XL5MfEwaXpnc9TKnBmlGn6nHiGREc3ysn47XIBDzA+YvFdjZzVIEDcKGpS6PbUJehFRjEne8D0lVU1XuRtlgszq6pTNlQ/3MzNOEgCWPyTct22V2mEi2krizn5VDo9B19/X2DB3hCGRMM7ONbtnAcIx/OWB1u5uPbW1gsH8irXxT/IzG0PoXWYjhbMsH3KTuoOl5o17PulcgvsfTSnKFM354GWI8luqZnrswWjiXy3G+Vbyo1KMopFmmvBwNELgaS8z8dNZchx/Cl/xjddxhMcyqtzFyONb2Zdu90NkI8pAeufe7YlXrp53v8Dj/l8vWeVspRKBGXScBBPI/HinSTGmLDOGGOCIyH0JFdOZx0gWsacNlQLJMIrBhqRxXxHF/5pseWwejlAAvZ3klZSDSYY8mkToaWejXhgNomeGtx1DTLEUFMRkgF5yFB22WYdJnaWN14r1YJj81hGi45+jrADS5nYRhCiSlCJJ1nL8pYX+HDSMhdTEWyRcgHVp/IsUIZYMfT+YYncUQPgcxNGCHfZ88vDdrcUuaGIl6zhAsiaq7R5dfqrqXH/JcBhfjT8D0azayIyEz75Nxp6YkcyDxlJq3EXnJUpqDohJJOysL1t1uNiHESlvsxPb5cpbW0+ICZqJmUZus1BMW0F5IVBODLIo2zHHjA0=","base64")).toString()),dL}var CL;function XAe(){return typeof CL=="undefined"&&(CL=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),CL}var ZAe=new Map([[S.makeIdent(null,"fsevents").identHash,VAe],[S.makeIdent(null,"resolve").identHash,_Ae],[S.makeIdent(null,"typescript").identHash,XAe]]),bze={hooks:{registerPackageExtensions:async(t,e)=>{for(let[r,i]of zAe)e(S.parseDescriptor(r,!0),i)},getBuiltinPatch:async(t,e)=>{var s;let r="compat/";if(!e.startsWith(r))return;let i=S.parseIdent(e.slice(r.length)),n=(s=ZAe.get(i.identHash))==null?void 0:s();return typeof n!="undefined"?n:null},reduceDependency:async(t,e,r,i)=>typeof ZAe.get(t.identHash)=="undefined"?t:S.makeDescriptor(t,S.makeRange({protocol:"patch:",source:S.stringifyDescriptor(t),selector:`~builtin`,params:null}))}},vze=bze;var EL={};it(EL,{default:()=>xze});var V0=class extends Be{constructor(){super(...arguments);this.pkg=Y.String("-p,--package",{description:"The package to run the provided command from"});this.quiet=Y.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=Y.String();this.args=Y.Proxy()}async execute(){let e=[];this.pkg&&e.push("--package",this.pkg),this.quiet&&e.push("--quiet");let r=S.parseIdent(this.command),i=S.makeIdent(r.scope,`create-${r.name}`);return this.cli.run(["dlx",...e,S.stringifyIdent(i),...this.args])}};V0.paths=[["create"]];var $Ae=V0;var jC=class extends Be{constructor(){super(...arguments);this.packages=Y.Array("-p,--package",{description:"The package(s) to install before running the command"});this.quiet=Y.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=Y.String();this.args=Y.Proxy()}async execute(){return fe.telemetry=null,await T.mktempPromise(async e=>{var p;let r=v.join(e,`dlx-${process.pid}`);await T.mkdirPromise(r),await T.writeFilePromise(v.join(r,"package.json"),`{} +`),await T.writeFilePromise(v.join(r,"yarn.lock"),"");let i=v.join(r,".yarnrc.yml"),n=await fe.findProjectCwd(this.context.cwd,wt.lockfile),s=!(await fe.find(this.context.cwd,null,{strict:!1})).get("enableGlobalCache"),o=n!==null?v.join(n,".yarnrc.yml"):null;o!==null&&T.existsSync(o)?(await T.copyFilePromise(o,i),await fe.updateConfiguration(r,d=>{let m=_(P({},d),{enableGlobalCache:s,enableTelemetry:!1});return Array.isArray(d.plugins)&&(m.plugins=d.plugins.map(I=>{let B=typeof I=="string"?I:I.path,b=M.isAbsolute(B)?B:M.resolve(M.fromPortablePath(n),B);return typeof I=="string"?b:{path:b,spec:I.spec}})),m})):await T.writeFilePromise(i,`enableGlobalCache: ${s} +enableTelemetry: false +`);let a=(p=this.packages)!=null?p:[this.command],l=S.parseDescriptor(this.command).name,c=await this.cli.run(["add","--",...a],{cwd:r,quiet:this.quiet});if(c!==0)return c;this.quiet||this.context.stdout.write(` +`);let u=await fe.find(r,this.context.plugins),{project:g,workspace:f}=await Ke.find(u,r);if(f===null)throw new rt(g.cwd,r);await g.restoreInstallState();let h=await Kt.getWorkspaceAccessibleBinaries(f);return h.has(l)===!1&&h.size===1&&typeof this.packages=="undefined"&&(l=Array.from(h)[0][0]),await Kt.executeWorkspaceAccessibleBinary(f,l,this.args,{packageAccessibleBinaries:h,cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})})}};jC.paths=[["dlx"]],jC.usage=ye.Usage({description:"run a package in a temporary environment",details:"\n This command will install a package within a temporary environment, and run its binary script if it contains any. The binary will run within the current cwd.\n\n By default Yarn will download the package named `command`, but this can be changed through the use of the `-p,--package` flag which will instruct Yarn to still run the same command but from a different package.\n\n Using `yarn dlx` as a replacement of `yarn add` isn't recommended, as it makes your project non-deterministic (Yarn doesn't keep track of the packages installed through `dlx` - neither their name, nor their version).\n ",examples:[["Use create-react-app to create a new React app","yarn dlx create-react-app ./my-app"],["Install multiple packages for a single command",`yarn dlx -p typescript -p ts-node ts-node --transpile-only -e "console.log('hello!')"`]]});var ele=jC;var Sze={commands:[$Ae,ele]},xze=Sze;var xL={};it(xL,{default:()=>Dze,fileUtils:()=>IL});var hf=/^(?:[a-zA-Z]:[\\/]|\.{0,2}\/)/,YC=/^[^?]*\.(?:tar\.gz|tgz)(?:::.*)?$/,Nr="file:";var IL={};it(IL,{makeArchiveFromLocator:()=>_0,makeBufferFromLocator:()=>BL,makeLocator:()=>wL,makeSpec:()=>tle,parseSpec:()=>yL});function yL(t){let{params:e,selector:r}=S.parseRange(t),i=M.toPortablePath(r);return{parentLocator:e&&typeof e.locator=="string"?S.parseLocator(e.locator):null,path:i}}function tle({parentLocator:t,path:e,folderHash:r,protocol:i}){let n=t!==null?{locator:S.stringifyLocator(t)}:{},s=typeof r!="undefined"?{hash:r}:{};return S.makeRange({protocol:i,source:e,selector:e,params:P(P({},s),n)})}function wL(t,{parentLocator:e,path:r,folderHash:i,protocol:n}){return S.makeLocator(t,tle({parentLocator:e,path:r,folderHash:i,protocol:n}))}async function _0(t,{protocol:e,fetchOptions:r,inMemory:i=!1}){let{parentLocator:n,path:s}=S.parseFileStyleRange(t.reference,{protocol:e}),o=v.isAbsolute(s)?{packageFs:new Ft(Se.root),prefixPath:Se.dot,localPath:Se.root}:await r.fetcher.fetch(n,r),a=o.localPath?{packageFs:new Ft(Se.root),prefixPath:v.relative(Se.root,o.localPath)}:o;o!==a&&o.releaseFs&&o.releaseFs();let l=a.packageFs,c=v.join(a.prefixPath,s);return await de.releaseAfterUseAsync(async()=>await Ai.makeArchiveFromDirectory(c,{baseFs:l,prefixPath:S.getIdentVendorPath(t),compressionLevel:r.project.configuration.get("compressionLevel"),inMemory:i}),a.releaseFs)}async function BL(t,{protocol:e,fetchOptions:r}){return(await _0(t,{protocol:e,fetchOptions:r,inMemory:!0})).getBufferAndClose()}var QL=class{supports(e,r){return!!e.reference.startsWith(Nr)}getLocalPath(e,r){let{parentLocator:i,path:n}=S.parseFileStyleRange(e.reference,{protocol:Nr});if(v.isAbsolute(n))return n;let s=r.fetcher.getLocalPath(i,r);return s===null?null:v.resolve(s,n)}async fetch(e,r){let i=r.checksums.get(e.locatorHash)||null,[n,s,o]=await r.cache.fetchPackageFromCache(e,i,P({onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${S.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,r),skipIntegrityCheck:r.skipIntegrityCheck},r.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:S.getIdentVendorPath(e),localPath:this.getLocalPath(e,r),checksum:o}}async fetchFromDisk(e,r){return _0(e,{protocol:Nr,fetchOptions:r})}};var kze=2,bL=class{supportsDescriptor(e,r){return e.range.match(hf)?!0:!!e.range.startsWith(Nr)}supportsLocator(e,r){return!!e.reference.startsWith(Nr)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,i){return hf.test(e.range)&&(e=S.makeDescriptor(e,`${Nr}${e.range}`)),S.bindDescriptor(e,{locator:S.stringifyLocator(r)})}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){if(!i.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:n,parentLocator:s}=yL(e.range);if(s===null)throw new Error("Assertion failed: The descriptor should have been bound");let o=await BL(S.makeLocator(e,S.makeRange({protocol:Nr,source:n,selector:n,params:{locator:S.stringifyLocator(s)}})),{protocol:Nr,fetchOptions:i.fetchOptions}),a=mn.makeHash(`${kze}`,o).slice(0,6);return[wL(e,{parentLocator:s,path:n,folderHash:a,protocol:Nr})]}async getSatisfying(e,r,i){return null}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),n=await de.releaseAfterUseAsync(async()=>await Ze.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return _(P({},e),{version:n.version||"0.0.0",languageName:n.languageName||r.project.configuration.get("defaultLanguageName"),linkType:gt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var vL=class{supports(e,r){return YC.test(e.reference)?!!e.reference.startsWith(Nr):!1}getLocalPath(e,r){return null}async fetch(e,r){let i=r.checksums.get(e.locatorHash)||null,[n,s,o]=await r.cache.fetchPackageFromCache(e,i,P({onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${S.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,r),skipIntegrityCheck:r.skipIntegrityCheck},r.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:S.getIdentVendorPath(e),checksum:o}}async fetchFromDisk(e,r){let{parentLocator:i,path:n}=S.parseFileStyleRange(e.reference,{protocol:Nr}),s=v.isAbsolute(n)?{packageFs:new Ft(Se.root),prefixPath:Se.dot,localPath:Se.root}:await r.fetcher.fetch(i,r),o=s.localPath?{packageFs:new Ft(Se.root),prefixPath:v.relative(Se.root,s.localPath)}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=v.join(o.prefixPath,n),c=await a.readFilePromise(l);return await de.releaseAfterUseAsync(async()=>await Ai.convertToZip(c,{compressionLevel:r.project.configuration.get("compressionLevel"),prefixPath:S.getIdentVendorPath(e),stripComponents:1}),o.releaseFs)}};var SL=class{supportsDescriptor(e,r){return YC.test(e.range)?!!(e.range.startsWith(Nr)||hf.test(e.range)):!1}supportsLocator(e,r){return YC.test(e.reference)?!!e.reference.startsWith(Nr):!1}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,i){return hf.test(e.range)&&(e=S.makeDescriptor(e,`${Nr}${e.range}`)),S.bindDescriptor(e,{locator:S.stringifyLocator(r)})}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){let n=e.range;return n.startsWith(Nr)&&(n=n.slice(Nr.length)),[S.makeLocator(e,`${Nr}${M.toPortablePath(n)}`)]}async getSatisfying(e,r,i){return null}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),n=await de.releaseAfterUseAsync(async()=>await Ze.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return _(P({},e),{version:n.version||"0.0.0",languageName:n.languageName||r.project.configuration.get("defaultLanguageName"),linkType:gt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var Pze={fetchers:[vL,QL],resolvers:[SL,bL]},Dze=Pze;var PL={};it(PL,{default:()=>Nze});var rle=ie(require("querystring")),ile=[/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+)\/tarball\/([^/#]+)(?:#(.*))?$/,/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+?)(?:\.git)?(?:#(.*))?$/];function nle(t){return t?ile.some(e=>!!t.match(e)):!1}function sle(t){let e;for(let a of ile)if(e=t.match(a),e)break;if(!e)throw new Error(Rze(t));let[,r,i,n,s="master"]=e,{commit:o}=rle.default.parse(s);return s=o||s.replace(/[^:]*:/,""),{auth:r,username:i,reponame:n,treeish:s}}function Rze(t){return`Input cannot be parsed as a valid GitHub URL ('${t}').`}var kL=class{supports(e,r){return!!nle(e.reference)}getLocalPath(e,r){return null}async fetch(e,r){let i=r.checksums.get(e.locatorHash)||null,[n,s,o]=await r.cache.fetchPackageFromCache(e,i,P({onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${S.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from GitHub`),loader:()=>this.fetchFromNetwork(e,r),skipIntegrityCheck:r.skipIntegrityCheck},r.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:S.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,r){let i=await Zt.get(this.getLocatorUrl(e,r),{configuration:r.project.configuration});return await T.mktempPromise(async n=>{let s=new Ft(n);await Ai.extractArchiveTo(i,s,{stripComponents:1});let o=Uc.splitRepoUrl(e.reference),a=v.join(n,"package.tgz");await Kt.prepareExternalProject(n,a,{configuration:r.project.configuration,report:r.report,workspace:o.extra.workspace,locator:e});let l=await T.readFilePromise(a);return await Ai.convertToZip(l,{compressionLevel:r.project.configuration.get("compressionLevel"),prefixPath:S.getIdentVendorPath(e),stripComponents:1})})}getLocatorUrl(e,r){let{auth:i,username:n,reponame:s,treeish:o}=sle(e.reference);return`https://${i?`${i}@`:""}github.com/${n}/${s}/archive/${o}.tar.gz`}};var Fze={hooks:{async fetchHostedRepository(t,e,r){if(t!==null)return t;let i=new kL;if(!i.supports(e,r))return null;try{return await i.fetch(e,r)}catch(n){return null}}}},Nze=Fze;var FL={};it(FL,{default:()=>Tze});var qC=/^[^?]*\.(?:tar\.gz|tgz)(?:\?.*)?$/,JC=/^https?:/;var DL=class{supports(e,r){return qC.test(e.reference)?!!JC.test(e.reference):!1}getLocalPath(e,r){return null}async fetch(e,r){let i=r.checksums.get(e.locatorHash)||null,[n,s,o]=await r.cache.fetchPackageFromCache(e,i,P({onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${S.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,r),skipIntegrityCheck:r.skipIntegrityCheck},r.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:S.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,r){let i=await Zt.get(e.reference,{configuration:r.project.configuration});return await Ai.convertToZip(i,{compressionLevel:r.project.configuration.get("compressionLevel"),prefixPath:S.getIdentVendorPath(e),stripComponents:1})}};var RL=class{supportsDescriptor(e,r){return qC.test(e.range)?!!JC.test(e.range):!1}supportsLocator(e,r){return qC.test(e.reference)?!!JC.test(e.reference):!1}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,i){return e}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){return[S.convertDescriptorToLocator(e)]}async getSatisfying(e,r,i){return null}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),n=await de.releaseAfterUseAsync(async()=>await Ze.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return _(P({},e),{version:n.version||"0.0.0",languageName:n.languageName||r.project.configuration.get("defaultLanguageName"),linkType:gt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var Lze={fetchers:[DL],resolvers:[RL]},Tze=Lze;var ML={};it(ML,{default:()=>M5e});var Rle=ie(Dle()),TL=ie(require("util")),WC=class extends Be{constructor(){super(...arguments);this.private=Y.Boolean("-p,--private",!1,{description:"Initialize a private package"});this.workspace=Y.Boolean("-w,--workspace",!1,{description:"Initialize a workspace root with a `packages/` directory"});this.install=Y.String("-i,--install",!1,{tolerateBoolean:!0,description:"Initialize a package with a specific bundle that will be locked in the project"});this.usev2=Y.Boolean("-2",!1,{hidden:!0});this.yes=Y.Boolean("-y,--yes",{hidden:!0});this.assumeFreshProject=Y.Boolean("--assume-fresh-project",!1,{hidden:!0})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r=typeof this.install=="string"?this.install:this.usev2||this.install===!0?"latest":null;return r!==null?await this.executeProxy(e,r):await this.executeRegular(e)}async executeProxy(e,r){if(e.projectCwd!==null&&e.projectCwd!==this.context.cwd)throw new me("Cannot use the --install flag from within a project subdirectory");T.existsSync(this.context.cwd)||await T.mkdirPromise(this.context.cwd,{recursive:!0});let i=v.join(this.context.cwd,e.get("lockfileFilename"));T.existsSync(i)||await T.writeFilePromise(i,"");let n=await this.cli.run(["set","version",r],{quiet:!0});if(n!==0)return n;let s=[];return this.private&&s.push("-p"),this.workspace&&s.push("-w"),this.yes&&s.push("-y"),await T.mktempPromise(async o=>{let{code:a}=await hr.pipevp("yarn",["init",...s],{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,env:await Kt.makeScriptEnv({binFolder:o})});return a})}async executeRegular(e){var l;let r=null;try{r=(await Ke.find(e,this.context.cwd)).project}catch{r=null}T.existsSync(this.context.cwd)||await T.mkdirPromise(this.context.cwd,{recursive:!0});let i=await Ze.tryFind(this.context.cwd)||new Ze,n=Object.fromEntries(e.get("initFields").entries());i.load(n),i.name=(l=i.name)!=null?l:S.makeIdent(e.get("initScope"),v.basename(this.context.cwd)),i.packageManager=Zr&&de.isTaggedYarnVersion(Zr)?`yarn@${Zr}`:null,typeof i.raw.private=="undefined"&&(this.private||this.workspace&&i.workspaceDefinitions.length===0)&&(i.private=!0),this.workspace&&i.workspaceDefinitions.length===0&&(await T.mkdirPromise(v.join(this.context.cwd,"packages"),{recursive:!0}),i.workspaceDefinitions=[{pattern:"packages/*"}]);let s={};i.exportTo(s),TL.inspect.styles.name="cyan",this.context.stdout.write(`${(0,TL.inspect)(s,{depth:Infinity,colors:!0,compact:!1})} +`);let o=v.join(this.context.cwd,Ze.fileName);await T.changeFilePromise(o,`${JSON.stringify(s,null,2)} +`,{automaticNewlines:!0});let a=v.join(this.context.cwd,"README.md");if(T.existsSync(a)||await T.writeFilePromise(a,`# ${S.stringifyIdent(i.name)} +`),!r||r.cwd===this.context.cwd){let c=v.join(this.context.cwd,wt.lockfile);T.existsSync(c)||await T.writeFilePromise(c,"");let g=["/.yarn/*","!/.yarn/patches","!/.yarn/plugins","!/.yarn/releases","!/.yarn/sdks","","# Swap the comments on the following lines if you don't wish to use zero-installs","# Documentation here: https://yarnpkg.com/features/zero-installs","!/.yarn/cache","#/.pnp.*"].map(m=>`${m} +`).join(""),f=v.join(this.context.cwd,".gitignore");T.existsSync(f)||await T.writeFilePromise(f,g);let h={["*"]:{endOfLine:"lf",insertFinalNewline:!0},["*.{js,json,yml}"]:{charset:"utf-8",indentStyle:"space",indentSize:2}};(0,Rle.default)(h,e.get("initEditorConfig"));let p=`root = true +`;for(let[m,I]of Object.entries(h)){p+=` +[${m}] +`;for(let[B,b]of Object.entries(I))p+=`${B.replace(/[A-Z]/g,H=>`_${H.toLowerCase()}`)} = ${b} +`}let d=v.join(this.context.cwd,".editorconfig");T.existsSync(d)||await T.writeFilePromise(d,p),T.existsSync(v.join(this.context.cwd,".git"))||await hr.execvp("git",["init"],{cwd:this.context.cwd})}}};WC.paths=[["init"]],WC.usage=ye.Usage({description:"create a new package",details:"\n This command will setup a new package in your local directory.\n\n If the `-p,--private` or `-w,--workspace` options are set, the package will be private by default.\n\n If the `-w,--workspace` option is set, the package will be configured to accept a set of workspaces in the `packages/` directory.\n\n If the `-i,--install` option is given a value, Yarn will first download it using `yarn set version` and only then forward the init call to the newly downloaded bundle. Without arguments, the downloaded bundle will be `latest`.\n\n The initial settings of the manifest can be changed by using the `initScope` and `initFields` configuration values. Additionally, Yarn will generate an EditorConfig file whose rules can be altered via `initEditorConfig`, and will initialize a Git repository in the current directory.\n ",examples:[["Create a new package in the local directory","yarn init"],["Create a new private package in the local directory","yarn init -p"],["Create a new package and store the Yarn release inside","yarn init -i=latest"],["Create a new private package and defines it as a workspace root","yarn init -w"]]});var Fle=WC;var T5e={configuration:{initScope:{description:"Scope used when creating packages via the init command",type:ge.STRING,default:null},initFields:{description:"Additional fields to set when creating packages via the init command",type:ge.MAP,valueDefinition:{description:"",type:ge.ANY}},initEditorConfig:{description:"Extra rules to define in the generator editorconfig",type:ge.MAP,valueDefinition:{description:"",type:ge.ANY}}},commands:[Fle]},M5e=T5e;var GL={};it(GL,{default:()=>K5e});var Ua="portal:",Ha="link:";var OL=class{supports(e,r){return!!e.reference.startsWith(Ua)}getLocalPath(e,r){let{parentLocator:i,path:n}=S.parseFileStyleRange(e.reference,{protocol:Ua});if(v.isAbsolute(n))return n;let s=r.fetcher.getLocalPath(i,r);return s===null?null:v.resolve(s,n)}async fetch(e,r){var c;let{parentLocator:i,path:n}=S.parseFileStyleRange(e.reference,{protocol:Ua}),s=v.isAbsolute(n)?{packageFs:new Ft(Se.root),prefixPath:Se.dot,localPath:Se.root}:await r.fetcher.fetch(i,r),o=s.localPath?{packageFs:new Ft(Se.root),prefixPath:v.relative(Se.root,s.localPath),localPath:Se.root}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=v.resolve((c=o.localPath)!=null?c:o.packageFs.getRealPath(),o.prefixPath,n);return s.localPath?{packageFs:new Ft(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Se.dot,localPath:l}:{packageFs:new Zo(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Se.dot}}};var KL=class{supportsDescriptor(e,r){return!!e.range.startsWith(Ua)}supportsLocator(e,r){return!!e.reference.startsWith(Ua)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,i){return S.bindDescriptor(e,{locator:S.stringifyLocator(r)})}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){let n=e.range.slice(Ua.length);return[S.makeLocator(e,`${Ua}${M.toPortablePath(n)}`)]}async getSatisfying(e,r,i){return null}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),n=await de.releaseAfterUseAsync(async()=>await Ze.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return _(P({},e),{version:n.version||"0.0.0",languageName:n.languageName||r.project.configuration.get("defaultLanguageName"),linkType:gt.SOFT,conditions:n.getConditions(),dependencies:new Map([...n.dependencies]),peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var UL=class{supports(e,r){return!!e.reference.startsWith(Ha)}getLocalPath(e,r){let{parentLocator:i,path:n}=S.parseFileStyleRange(e.reference,{protocol:Ha});if(v.isAbsolute(n))return n;let s=r.fetcher.getLocalPath(i,r);return s===null?null:v.resolve(s,n)}async fetch(e,r){var c;let{parentLocator:i,path:n}=S.parseFileStyleRange(e.reference,{protocol:Ha}),s=v.isAbsolute(n)?{packageFs:new Ft(Se.root),prefixPath:Se.dot,localPath:Se.root}:await r.fetcher.fetch(i,r),o=s.localPath?{packageFs:new Ft(Se.root),prefixPath:v.relative(Se.root,s.localPath),localPath:Se.root}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=v.resolve((c=o.localPath)!=null?c:o.packageFs.getRealPath(),o.prefixPath,n);return s.localPath?{packageFs:new Ft(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Se.dot,discardFromLookup:!0,localPath:l}:{packageFs:new Zo(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Se.dot,discardFromLookup:!0}}};var HL=class{supportsDescriptor(e,r){return!!e.range.startsWith(Ha)}supportsLocator(e,r){return!!e.reference.startsWith(Ha)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,i){return S.bindDescriptor(e,{locator:S.stringifyLocator(r)})}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){let n=e.range.slice(Ha.length);return[S.makeLocator(e,`${Ha}${M.toPortablePath(n)}`)]}async getSatisfying(e,r,i){return null}async resolve(e,r){return _(P({},e),{version:"0.0.0",languageName:r.project.configuration.get("defaultLanguageName"),linkType:gt.SOFT,conditions:null,dependencies:new Map,peerDependencies:new Map,dependenciesMeta:new Map,peerDependenciesMeta:new Map,bin:new Map})}};var O5e={fetchers:[UL,OL],resolvers:[HL,KL]},K5e=O5e;var mT={};it(mT,{default:()=>Y6e});var Ga;(function(i){i[i.YES=0]="YES",i[i.NO=1]="NO",i[i.DEPENDS=2]="DEPENDS"})(Ga||(Ga={}));var jL=(t,e)=>`${t}@${e}`,Nle=(t,e)=>{let r=e.indexOf("#"),i=r>=0?e.substring(r+1):e;return jL(t,i)},qs;(function(s){s[s.NONE=-1]="NONE",s[s.PERF=0]="PERF",s[s.CHECK=1]="CHECK",s[s.REASONS=2]="REASONS",s[s.INTENSIVE_CHECK=9]="INTENSIVE_CHECK"})(qs||(qs={}));var Tle=(t,e={})=>{let r=e.debugLevel||Number(process.env.NM_DEBUG_LEVEL||-1),i=e.check||r>=9,n=e.hoistingLimits||new Map,s={check:i,debugLevel:r,hoistingLimits:n,fastLookupPossible:!0},o;s.debugLevel>=0&&(o=Date.now());let a=U5e(t,s),l=!1,c=0;do l=YL(a,[a],new Set([a.locator]),new Map,s).anotherRoundNeeded,s.fastLookupPossible=!1,c++;while(l);if(s.debugLevel>=0&&console.log(`hoist time: ${Date.now()-o}ms, rounds: ${c}`),s.debugLevel>=1){let u=zC(a);if(YL(a,[a],new Set([a.locator]),new Map,s).isGraphChanged)throw new Error(`The hoisting result is not terminal, prev tree: +${u}, next tree: +${zC(a)}`);let f=Lle(a);if(f)throw new Error(`${f}, after hoisting finished: +${zC(a)}`)}return s.debugLevel>=2&&console.log(zC(a)),H5e(a)},G5e=t=>{let e=t[t.length-1],r=new Map,i=new Set,n=s=>{if(!i.has(s)){i.add(s);for(let o of s.hoistedDependencies.values())r.set(o.name,o);for(let o of s.dependencies.values())s.peerNames.has(o.name)||n(o)}};return n(e),r},j5e=t=>{let e=t[t.length-1],r=new Map,i=new Set,n=new Set,s=(o,a)=>{if(i.has(o))return;i.add(o);for(let c of o.hoistedDependencies.values())if(!a.has(c.name)){let u;for(let g of t)u=g.dependencies.get(c.name),u&&r.set(u.name,u)}let l=new Set;for(let c of o.dependencies.values())l.add(c.name);for(let c of o.dependencies.values())o.peerNames.has(c.name)||s(c,l)};return s(e,n),r},Mle=(t,e)=>{if(e.decoupled)return e;let{name:r,references:i,ident:n,locator:s,dependencies:o,originalDependencies:a,hoistedDependencies:l,peerNames:c,reasons:u,isHoistBorder:g,hoistPriority:f,isWorkspace:h,hoistedFrom:p,hoistedTo:d}=e,m={name:r,references:new Set(i),ident:n,locator:s,dependencies:new Map(o),originalDependencies:new Map(a),hoistedDependencies:new Map(l),peerNames:new Set(c),reasons:new Map(u),decoupled:!0,isHoistBorder:g,hoistPriority:f,isWorkspace:h,hoistedFrom:new Map(p),hoistedTo:new Map(d)},I=m.dependencies.get(r);return I&&I.ident==m.ident&&m.dependencies.set(r,m),t.dependencies.set(m.name,m),m},Y5e=(t,e)=>{let r=new Map([[t.name,[t.ident]]]);for(let n of t.dependencies.values())t.peerNames.has(n.name)||r.set(n.name,[n.ident]);let i=Array.from(e.keys());i.sort((n,s)=>{let o=e.get(n),a=e.get(s);return a.hoistPriority!==o.hoistPriority?a.hoistPriority-o.hoistPriority:a.peerDependents.size!==o.peerDependents.size?a.peerDependents.size-o.peerDependents.size:a.dependents.size-o.dependents.size});for(let n of i){let s=n.substring(0,n.indexOf("@",1)),o=n.substring(s.length+1);if(!t.peerNames.has(s)){let a=r.get(s);a||(a=[],r.set(s,a)),a.indexOf(o)<0&&a.push(o)}}return r},qL=t=>{let e=new Set,r=(i,n=new Set)=>{if(!n.has(i)){n.add(i);for(let s of i.peerNames)if(!t.peerNames.has(s)){let o=t.dependencies.get(s);o&&!e.has(o)&&r(o,n)}e.add(i)}};for(let i of t.dependencies.values())t.peerNames.has(i.name)||r(i);return e},YL=(t,e,r,i,n,s=new Set)=>{let o=e[e.length-1];if(s.has(o))return{anotherRoundNeeded:!1,isGraphChanged:!1};s.add(o);let a=J5e(o),l=Y5e(o,a),c=t==o?new Map:n.fastLookupPossible?G5e(e):j5e(e),u,g=!1,f=!1,h=new Map(Array.from(l.entries()).map(([d,m])=>[d,m[0]])),p=new Map;do{let d=q5e(t,e,r,c,h,l,i,p,n);d.isGraphChanged&&(f=!0),d.anotherRoundNeeded&&(g=!0),u=!1;for(let[m,I]of l)I.length>1&&!o.dependencies.has(m)&&(h.delete(m),I.shift(),h.set(m,I[0]),u=!0)}while(u);for(let d of o.dependencies.values())if(!o.peerNames.has(d.name)&&!r.has(d.locator)){r.add(d.locator);let m=YL(t,[...e,d],r,p,n);m.isGraphChanged&&(f=!0),m.anotherRoundNeeded&&(g=!0),r.delete(d.locator)}return{anotherRoundNeeded:g,isGraphChanged:f}},W5e=(t,e,r,i,n,s,o,a,{outputReason:l,fastLookupPossible:c})=>{let u,g=null,f=new Set;l&&(u=`${Array.from(e).map(m=>wi(m)).join("\u2192")}`);let h=r[r.length-1],d=!(i.ident===h.ident);if(l&&!d&&(g="- self-reference"),d&&(d=!i.isWorkspace,l&&!d&&(g="- workspace")),d&&(d=!h.isWorkspace||h.hoistedFrom.has(i.name)||e.size===1,l&&!d&&(g=h.reasons.get(i.name))),d&&(d=!t.peerNames.has(i.name),l&&!d&&(g=`- cannot shadow peer: ${wi(t.originalDependencies.get(i.name).locator)} at ${u}`)),d){let m=!1,I=n.get(i.name);if(m=!I||I.ident===i.ident,l&&!m&&(g=`- filled by: ${wi(I.locator)} at ${u}`),m)for(let B=r.length-1;B>=1;B--){let R=r[B].dependencies.get(i.name);if(R&&R.ident!==i.ident){m=!1;let H=a.get(h);H||(H=new Set,a.set(h,H)),H.add(i.name),l&&(g=`- filled by ${wi(R.locator)} at ${r.slice(0,B).map(L=>wi(L.locator)).join("\u2192")}`);break}}d=m}if(d&&(d=s.get(i.name)===i.ident,l&&!d&&(g=`- filled by: ${wi(o.get(i.name)[0])} at ${u}`)),d){let m=!0,I=new Set(i.peerNames);for(let B=r.length-1;B>=1;B--){let b=r[B];for(let R of I){if(b.peerNames.has(R)&&b.originalDependencies.has(R))continue;let H=b.dependencies.get(R);H&&t.dependencies.get(R)!==H&&(B===r.length-1?f.add(H):(f=null,m=!1,l&&(g=`- peer dependency ${wi(H.locator)} from parent ${wi(b.locator)} was not hoisted to ${u}`))),I.delete(R)}if(!m)break}d=m}if(d&&!c)for(let m of i.hoistedDependencies.values()){let I=n.get(m.name);if(!I||m.ident!==I.ident){d=!1,l&&(g=`- previously hoisted dependency mismatch, needed: ${wi(m.locator)}, available: ${wi(I==null?void 0:I.locator)}`);break}}return f!==null&&f.size>0?{isHoistable:2,dependsOn:f,reason:g}:{isHoistable:d?0:1,reason:g}},q5e=(t,e,r,i,n,s,o,a,l)=>{let c=e[e.length-1],u=new Set,g=!1,f=!1,h=(m,I,B,b)=>{if(u.has(B))return;let R=[...I,B.locator],H=new Map,L=new Map;for(let q of qL(B)){let A=W5e(c,r,[c,...m,B],q,i,n,s,a,{outputReason:l.debugLevel>=2,fastLookupPossible:l.fastLookupPossible});if(L.set(q,A),A.isHoistable===2)for(let V of A.dependsOn){let W=H.get(V.name)||new Set;W.add(q.name),H.set(V.name,W)}}let K=new Set,J=(q,A,V)=>{if(!K.has(q)){K.add(q),L.set(q,{isHoistable:1,reason:V});for(let W of H.get(q.name)||[])J(B.dependencies.get(W),A,l.debugLevel>=2?`- peer dependency ${wi(q.locator)} from parent ${wi(B.locator)} was not hoisted`:"")}};for(let[q,A]of L)A.isHoistable===1&&J(q,A,A.reason);for(let q of L.keys())if(!K.has(q)){f=!0;let A=o.get(B);A&&A.has(q.name)&&(g=!0),B.dependencies.delete(q.name),B.hoistedDependencies.set(q.name,q),B.reasons.delete(q.name);let V=c.dependencies.get(q.name);if(l.debugLevel>=2){let W=Array.from(I).concat([B.locator]).map(F=>wi(F)).join("\u2192"),X=c.hoistedFrom.get(q.name);X||(X=[],c.hoistedFrom.set(q.name,X)),X.push(W),B.hoistedTo.set(q.name,Array.from(e).map(F=>wi(F.locator)).join("\u2192"))}if(!V)c.ident!==q.ident&&(c.dependencies.set(q.name,q),b.add(q));else for(let W of q.references)V.references.add(W)}if(l.check){let q=Lle(t);if(q)throw new Error(`${q}, after hoisting dependencies of ${[c,...m,B].map(A=>wi(A.locator)).join("\u2192")}: +${zC(t)}`)}let ne=qL(B);for(let q of ne)if(K.has(q)){let A=L.get(q);if((n.get(q.name)===q.ident||!B.reasons.has(q.name))&&A.isHoistable!==0&&B.reasons.set(q.name,A.reason),!q.isHoistBorder&&R.indexOf(q.locator)<0){u.add(B);let W=Mle(B,q);h([...m,B],[...I,B.locator],W,d),u.delete(B)}}},p,d=new Set(qL(c));do{p=d,d=new Set;for(let m of p){if(m.locator===c.locator||m.isHoistBorder)continue;let I=Mle(c,m);h([],Array.from(r),I,d)}}while(d.size>0);return{anotherRoundNeeded:g,isGraphChanged:f}},Lle=t=>{let e=[],r=new Set,i=new Set,n=(s,o,a)=>{if(r.has(s)||(r.add(s),i.has(s)))return;let l=new Map(o);for(let c of s.dependencies.values())s.peerNames.has(c.name)||l.set(c.name,c);for(let c of s.originalDependencies.values()){let u=l.get(c.name),g=()=>`${Array.from(i).concat([s]).map(f=>wi(f.locator)).join("\u2192")}`;if(s.peerNames.has(c.name)){let f=o.get(c.name);(f!==u||!f||f.ident!==c.ident)&&e.push(`${g()} - broken peer promise: expected ${c.ident} but found ${f&&f.ident}`)}else{let f=a.hoistedFrom.get(s.name),h=s.hoistedTo.get(c.name),p=`${f?` hoisted from ${f.join(", ")}`:""}`,d=`${h?` hoisted to ${h}`:""}`,m=`${g()}${p}`;u?u.ident!==c.ident&&e.push(`${m} - broken require promise for ${c.name}${d}: expected ${c.ident}, but found: ${u.ident}`):e.push(`${m} - broken require promise: no required dependency ${c.name}${d} found`)}}i.add(s);for(let c of s.dependencies.values())s.peerNames.has(c.name)||n(c,l,s);i.delete(s)};return n(t,t.dependencies,t),e.join(` +`)},U5e=(t,e)=>{let{identName:r,name:i,reference:n,peerNames:s}=t,o={name:i,references:new Set([n]),locator:jL(r,n),ident:Nle(r,n),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(s),reasons:new Map,decoupled:!0,isHoistBorder:!0,hoistPriority:0,isWorkspace:!0,hoistedFrom:new Map,hoistedTo:new Map},a=new Map([[t,o]]),l=(c,u)=>{let g=a.get(c),f=!!g;if(!g){let{name:h,identName:p,reference:d,peerNames:m,hoistPriority:I,isWorkspace:B}=c,b=e.hoistingLimits.get(u.locator);g={name:h,references:new Set([d]),locator:jL(p,d),ident:Nle(p,d),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(m),reasons:new Map,decoupled:!0,isHoistBorder:b?b.has(h):!1,hoistPriority:I||0,isWorkspace:B||!1,hoistedFrom:new Map,hoistedTo:new Map},a.set(c,g)}if(u.dependencies.set(c.name,g),u.originalDependencies.set(c.name,g),f){let h=new Set,p=d=>{if(!h.has(d)){h.add(d),d.decoupled=!1;for(let m of d.dependencies.values())d.peerNames.has(m.name)||p(m)}};p(g)}else for(let h of c.dependencies)l(h,g)};for(let c of t.dependencies)l(c,o);return o},JL=t=>t.substring(0,t.indexOf("@",1)),H5e=t=>{let e={name:t.name,identName:JL(t.locator),references:new Set(t.references),dependencies:new Set},r=new Set([t]),i=(n,s,o)=>{let a=r.has(n),l;if(s===n)l=o;else{let{name:c,references:u,locator:g}=n;l={name:c,identName:JL(g),references:u,dependencies:new Set}}if(o.dependencies.add(l),!a){r.add(n);for(let c of n.dependencies.values())n.peerNames.has(c.name)||i(c,n,l);r.delete(n)}};for(let n of t.dependencies.values())i(n,t,e);return e},J5e=t=>{let e=new Map,r=new Set([t]),i=o=>`${o.name}@${o.ident}`,n=o=>{let a=i(o),l=e.get(a);return l||(l={dependents:new Set,peerDependents:new Set,hoistPriority:0},e.set(a,l)),l},s=(o,a)=>{let l=!!r.has(a);if(n(a).dependents.add(o.ident),!l){r.add(a);for(let u of a.dependencies.values()){let g=n(u);g.hoistPriority=Math.max(g.hoistPriority,u.hoistPriority),a.peerNames.has(u.name)?g.peerDependents.add(a.ident):s(a,u)}}};for(let o of t.dependencies.values())t.peerNames.has(o.name)||s(t,o);return e},wi=t=>{if(!t)return"none";let e=t.indexOf("@",1),r=t.substring(0,e);r.endsWith("$wsroot$")&&(r=`wh:${r.replace("$wsroot$","")}`);let i=t.substring(e+1);if(i==="workspace:.")return".";if(i){let n=(i.indexOf("#")>0?i.split("#")[1]:i).replace("npm:","");return i.startsWith("virtual")&&(r=`v:${r}`),n.startsWith("workspace")&&(r=`w:${r}`,n=""),`${r}${n?`@${n}`:""}`}else return`${r}`},Ole=5e4,zC=t=>{let e=0,r=(n,s,o="")=>{if(e>Ole||s.has(n))return"";e++;let a=Array.from(n.dependencies.values()).sort((c,u)=>c.name.localeCompare(u.name)),l="";s.add(n);for(let c=0;c":"")+(f!==u.name?`a:${u.name}:`:"")+wi(u.locator)+(g?` ${g}`:"")+(u!==n&&h.length>0?`, hoisted from: ${h.join(", ")}`:"")} +`,l+=r(u,s,`${o}${cOle?` +Tree is too large, part of the tree has been dunped +`:"")};var Js;(function(r){r.HARD="HARD",r.SOFT="SOFT"})(Js||(Js={}));var Sn;(function(i){i.WORKSPACES="workspaces",i.DEPENDENCIES="dependencies",i.NONE="none"})(Sn||(Sn={}));var Kle="node_modules",Hc="$wsroot$";var VC=(t,e)=>{let{packageTree:r,hoistingLimits:i,errors:n,preserveSymlinksRequired:s}=z5e(t,e),o=null;if(n.length===0){let a=Tle(r,{hoistingLimits:i});o=V5e(t,a,e)}return{tree:o,errors:n,preserveSymlinksRequired:s}},ms=t=>`${t.name}@${t.reference}`,WL=t=>{let e=new Map;for(let[r,i]of t.entries())if(!i.dirList){let n=e.get(i.locator);n||(n={target:i.target,linkType:i.linkType,locations:[],aliases:i.aliases},e.set(i.locator,n)),n.locations.push(r)}for(let r of e.values())r.locations=r.locations.sort((i,n)=>{let s=i.split(v.delimiter).length,o=n.split(v.delimiter).length;return s!==o?o-s:n.localeCompare(i)});return e},Ule=(t,e)=>{let r=S.isVirtualLocator(t)?S.devirtualizeLocator(t):t,i=S.isVirtualLocator(e)?S.devirtualizeLocator(e):e;return S.areLocatorsEqual(r,i)},zL=(t,e,r,i)=>{if(t.linkType!==Js.SOFT)return!1;let n=M.toPortablePath(r.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?r.resolveVirtual(t.packageLocation):t.packageLocation);return v.contains(i,n)===null},_5e=t=>{let e=t.getPackageInformation(t.topLevel);if(e===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");if(t.findPackageLocator(e.packageLocation)===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let i=M.toPortablePath(e.packageLocation.slice(0,-1)),n=new Map,s={children:new Map},o=t.getDependencyTreeRoots(),a=new Map,l=new Set,c=(f,h)=>{let p=ms(f);if(l.has(p))return;l.add(p);let d=t.getPackageInformation(f);if(d){let m=h?ms(h):"";if(ms(f)!==m&&d.linkType===Js.SOFT&&!zL(d,f,t,i)){let I=Hle(d,f,t);(!a.get(I)||f.reference.startsWith("workspace:"))&&a.set(I,f)}for(let[I,B]of d.packageDependencies)B!==null&&(d.packagePeers.has(I)||c(t.getLocator(I,B),f))}};for(let f of o)c(f,null);let u=i.split(v.sep);for(let f of a.values()){let h=t.getPackageInformation(f),d=M.toPortablePath(h.packageLocation.slice(0,-1)).split(v.sep).slice(u.length),m=s;for(let I of d){let B=m.children.get(I);B||(B={children:new Map},m.children.set(I,B)),m=B}m.workspaceLocator=f}let g=(f,h)=>{if(f.workspaceLocator){let p=ms(h),d=n.get(p);d||(d=new Set,n.set(p,d)),d.add(f.workspaceLocator)}for(let p of f.children.values())g(p,f.workspaceLocator||h)};for(let f of s.children.values())g(f,s.workspaceLocator);return n},z5e=(t,e)=>{let r=[],i=!1,n=new Map,s=_5e(t),o=t.getPackageInformation(t.topLevel);if(o===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");let a=t.findPackageLocator(o.packageLocation);if(a===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let l=M.toPortablePath(o.packageLocation.slice(0,-1)),c={name:a.name,identName:a.name,reference:a.reference,peerNames:o.packagePeers,dependencies:new Set,isWorkspace:!0},u=new Map,g=(h,p)=>`${ms(p)}:${h}`,f=(h,p,d,m,I,B,b,R)=>{var X,F;let H=g(h,d),L=u.get(H),K=!!L;!K&&d.name===a.name&&d.reference===a.reference&&(L=c,u.set(H,c));let J=zL(p,d,t,l);if(!L){let D=p.linkType===Js.SOFT&&d.name.endsWith(Hc);L={name:h,identName:d.name,reference:d.reference,dependencies:new Set,peerNames:D?new Set:p.packagePeers,isWorkspace:D},u.set(H,L)}let ne;if(J?ne=2:I.linkType===Js.SOFT?ne=1:ne=0,L.hoistPriority=Math.max(L.hoistPriority||0,ne),R&&!J){let D=ms({name:m.identName,reference:m.reference}),he=n.get(D)||new Set;n.set(D,he),he.add(L.name)}let q=new Map(p.packageDependencies);if(e.project){let D=e.project.workspacesByCwd.get(M.toPortablePath(p.packageLocation.slice(0,-1)));if(D){let he=new Set([...Array.from(D.manifest.peerDependencies.values(),pe=>S.stringifyIdent(pe)),...Array.from(D.manifest.peerDependenciesMeta.keys())]);for(let pe of he)q.has(pe)||(q.set(pe,B.get(pe)||null),L.peerNames.add(pe))}}let A=ms({name:d.name.replace(Hc,""),reference:d.reference}),V=s.get(A);if(V)for(let D of V)q.set(`${D.name}${Hc}`,D.reference);(p!==I||p.linkType!==Js.SOFT||!e.selfReferencesByCwd||e.selfReferencesByCwd.get(b))&&m.dependencies.add(L);let W=d!==a&&p.linkType===Js.SOFT&&!d.name.endsWith(Hc)&&!J;if(!K&&!W){let D=new Map;for(let[he,pe]of q)if(pe!==null){let Ne=t.getLocator(he,pe),Pe=t.getLocator(he.replace(Hc,""),pe),qe=t.getPackageInformation(Pe);if(qe===null)throw new Error("Assertion failed: Expected the package to have been registered");let re=zL(qe,Ne,t,l);if(e.validateExternalSoftLinks&&e.project&&re){qe.packageDependencies.size>0&&(i=!0);for(let[De,$]of qe.packageDependencies)if($!==null){let G=S.parseLocator(Array.isArray($)?`${$[0]}@${$[1]}`:`${De}@${$}`);if(ms(G)!==ms(Ne)){let Ce=q.get(De);if(Ce){let ee=S.parseLocator(Array.isArray(Ce)?`${Ce[0]}@${Ce[1]}`:`${De}@${Ce}`);Ule(ee,G)||r.push({messageName:z.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK,text:`Cannot link ${S.prettyIdent(e.project.configuration,S.parseIdent(Ne.name))} into ${S.prettyLocator(e.project.configuration,S.parseLocator(`${d.name}@${d.reference}`))} dependency ${S.prettyLocator(e.project.configuration,G)} conflicts with parent dependency ${S.prettyLocator(e.project.configuration,ee)}`})}else{let ee=D.get(De);if(ee){let Ue=ee.target,Oe=S.parseLocator(Array.isArray(Ue)?`${Ue[0]}@${Ue[1]}`:`${De}@${Ue}`);Ule(Oe,G)||r.push({messageName:z.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK,text:`Cannot link ${S.prettyIdent(e.project.configuration,S.parseIdent(Ne.name))} into ${S.prettyLocator(e.project.configuration,S.parseLocator(`${d.name}@${d.reference}`))} dependency ${S.prettyLocator(e.project.configuration,G)} conflicts with dependency ${S.prettyLocator(e.project.configuration,Oe)} from sibling portal ${S.prettyIdent(e.project.configuration,S.parseIdent(ee.portal.name))}`})}else D.set(De,{target:G.reference,portal:Ne})}}}}let se=(X=e.hoistingLimitsByCwd)==null?void 0:X.get(b),be=re?b:v.relative(l,M.toPortablePath(qe.packageLocation))||Se.dot,ae=(F=e.hoistingLimitsByCwd)==null?void 0:F.get(be),Ae=se===Sn.DEPENDENCIES||ae===Sn.DEPENDENCIES||ae===Sn.WORKSPACES;f(ms(Ne)===ms(d)?h:he,qe,Ne,L,p,q,be,Ae)}}};return f(a.name,o,a,c,o,o.packageDependencies,Se.dot,!1),{packageTree:c,hoistingLimits:n,errors:r,preserveSymlinksRequired:i}};function Hle(t,e,r){let i=r.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?r.resolveVirtual(t.packageLocation):t.packageLocation;return M.toPortablePath(i||t.packageLocation)}function X5e(t,e,r){let i=e.getLocator(t.name.replace(Hc,""),t.reference),n=e.getPackageInformation(i);if(n===null)throw new Error("Assertion failed: Expected the package to be registered");let s,o;return r.pnpifyFs?(o=M.toPortablePath(n.packageLocation),s=Js.SOFT):(o=Hle(n,t,e),s=n.linkType),{linkType:s,target:o}}var V5e=(t,e,r)=>{let i=new Map,n=(u,g,f)=>{let{linkType:h,target:p}=X5e(u,t,r);return{locator:ms(u),nodePath:g,target:p,linkType:h,aliases:f}},s=u=>{let[g,f]=u.split("/");return f?{scope:kr(g),name:kr(f)}:{scope:null,name:kr(g)}},o=new Set,a=(u,g,f)=>{if(!o.has(u)){o.add(u);for(let h of u.dependencies){if(h===u)continue;let p=Array.from(h.references).sort(),d={name:h.identName,reference:p[0]},{name:m,scope:I}=s(h.name),B=I?[I,m]:[m],b=v.join(g,Kle),R=v.join(b,...B),H=`${f}/${d.name}`,L=n(d,f,p.slice(1)),K=!1;if(L.linkType===Js.SOFT&&r.project){let J=r.project.workspacesByCwd.get(L.target.slice(0,-1));K=!!(J&&!J.manifest.name)}if(!h.name.endsWith(Hc)&&!K){let J=i.get(R);if(J){if(J.dirList)throw new Error(`Assertion failed: ${R} cannot merge dir node with leaf node`);{let V=S.parseLocator(J.locator),W=S.parseLocator(L.locator);if(J.linkType!==L.linkType)throw new Error(`Assertion failed: ${R} cannot merge nodes with different link types ${J.nodePath}/${S.stringifyLocator(V)} and ${f}/${S.stringifyLocator(W)}`);if(V.identHash!==W.identHash)throw new Error(`Assertion failed: ${R} cannot merge nodes with different idents ${J.nodePath}/${S.stringifyLocator(V)} and ${f}/s${S.stringifyLocator(W)}`);L.aliases=[...L.aliases,...J.aliases,S.parseLocator(J.locator).reference]}}i.set(R,L);let ne=R.split("/"),q=ne.indexOf(Kle),A=ne.length-1;for(;q>=0&&A>q;){let V=M.toPortablePath(ne.slice(0,A).join(v.sep)),W=kr(ne[A]),X=i.get(V);if(!X)i.set(V,{dirList:new Set([W])});else if(X.dirList){if(X.dirList.has(W))break;X.dirList.add(W)}A--}}a(h,L.linkType===Js.SOFT?L.target:R,H)}}},l=n({name:e.name,reference:Array.from(e.references)[0]},"",[]),c=l.target;return i.set(c,l),a(e,c,""),i};var oT={};it(oT,{PnpInstaller:()=>Cf,PnpLinker:()=>jc,default:()=>m6e,getPnpPath:()=>qA,jsInstallUtils:()=>Ws,pnpUtils:()=>nT,quotePathIfNeeded:()=>uce});var lce=ie(Or()),cce=ie(require("url"));var Gle;(function(r){r.HARD="HARD",r.SOFT="SOFT"})(Gle||(Gle={}));var Ht;(function(f){f.DEFAULT="DEFAULT",f.TOP_LEVEL="TOP_LEVEL",f.FALLBACK_EXCLUSION_LIST="FALLBACK_EXCLUSION_LIST",f.FALLBACK_EXCLUSION_ENTRIES="FALLBACK_EXCLUSION_ENTRIES",f.FALLBACK_EXCLUSION_DATA="FALLBACK_EXCLUSION_DATA",f.PACKAGE_REGISTRY_DATA="PACKAGE_REGISTRY_DATA",f.PACKAGE_REGISTRY_ENTRIES="PACKAGE_REGISTRY_ENTRIES",f.PACKAGE_STORE_DATA="PACKAGE_STORE_DATA",f.PACKAGE_STORE_ENTRIES="PACKAGE_STORE_ENTRIES",f.PACKAGE_INFORMATION_DATA="PACKAGE_INFORMATION_DATA",f.PACKAGE_DEPENDENCIES="PACKAGE_DEPENDENCIES",f.PACKAGE_DEPENDENCY="PACKAGE_DEPENDENCY"})(Ht||(Ht={}));var jle={[Ht.DEFAULT]:{collapsed:!1,next:{["*"]:Ht.DEFAULT}},[Ht.TOP_LEVEL]:{collapsed:!1,next:{fallbackExclusionList:Ht.FALLBACK_EXCLUSION_LIST,packageRegistryData:Ht.PACKAGE_REGISTRY_DATA,["*"]:Ht.DEFAULT}},[Ht.FALLBACK_EXCLUSION_LIST]:{collapsed:!1,next:{["*"]:Ht.FALLBACK_EXCLUSION_ENTRIES}},[Ht.FALLBACK_EXCLUSION_ENTRIES]:{collapsed:!0,next:{["*"]:Ht.FALLBACK_EXCLUSION_DATA}},[Ht.FALLBACK_EXCLUSION_DATA]:{collapsed:!0,next:{["*"]:Ht.DEFAULT}},[Ht.PACKAGE_REGISTRY_DATA]:{collapsed:!1,next:{["*"]:Ht.PACKAGE_REGISTRY_ENTRIES}},[Ht.PACKAGE_REGISTRY_ENTRIES]:{collapsed:!0,next:{["*"]:Ht.PACKAGE_STORE_DATA}},[Ht.PACKAGE_STORE_DATA]:{collapsed:!1,next:{["*"]:Ht.PACKAGE_STORE_ENTRIES}},[Ht.PACKAGE_STORE_ENTRIES]:{collapsed:!0,next:{["*"]:Ht.PACKAGE_INFORMATION_DATA}},[Ht.PACKAGE_INFORMATION_DATA]:{collapsed:!1,next:{packageDependencies:Ht.PACKAGE_DEPENDENCIES,["*"]:Ht.DEFAULT}},[Ht.PACKAGE_DEPENDENCIES]:{collapsed:!1,next:{["*"]:Ht.PACKAGE_DEPENDENCY}},[Ht.PACKAGE_DEPENDENCY]:{collapsed:!0,next:{["*"]:Ht.DEFAULT}}};function Z5e(t,e,r){let i="";i+="[";for(let n=0,s=t.length;ns(o)));let n=r.map((s,o)=>o);return n.sort((s,o)=>{for(let a of i){let l=a[s]a[o]?1:0;if(l!==0)return l}return 0}),n.map(s=>r[s])}function r6e(t){let e=new Map,r=_C(t.fallbackExclusionList||[],[({name:i,reference:n})=>i,({name:i,reference:n})=>n]);for(let{name:i,reference:n}of r){let s=e.get(i);typeof s=="undefined"&&e.set(i,s=new Set),s.add(n)}return Array.from(e).map(([i,n])=>[i,Array.from(n)])}function i6e(t){return _C(t.fallbackPool||[],([e])=>e)}function n6e(t){let e=[];for(let[r,i]of _C(t.packageRegistry,([n])=>n===null?"0":`1${n}`)){let n=[];e.push([r,n]);for(let[s,{packageLocation:o,packageDependencies:a,packagePeers:l,linkType:c,discardFromLookup:u}]of _C(i,([g])=>g===null?"0":`1${g}`)){let g=[];r!==null&&s!==null&&!a.has(r)&&g.push([r,s]);for(let[p,d]of _C(a.entries(),([m])=>m))g.push([p,d]);let f=l&&l.size>0?Array.from(l):void 0,h=u||void 0;n.push([s,{packageLocation:o,packageDependencies:g,packagePeers:f,linkType:c,discardFromLookup:h}])}}return e}function XC(t){return{__info:["This file is automatically generated. Do not touch it, or risk","your modifications being lost. We also recommend you not to read","it either without using the @yarnpkg/pnp package, as the data layout","is entirely unspecified and WILL change from a version to another."],dependencyTreeRoots:t.dependencyTreeRoots,enableTopLevelFallback:t.enableTopLevelFallback||!1,ignorePatternData:t.ignorePattern||null,fallbackExclusionList:r6e(t),fallbackPool:i6e(t),packageRegistryData:n6e(t)}}var zle=ie(Wle());function Vle(t,e){return[t?`${t} +`:"",`/* eslint-disable */ + +`,`try { +`,` Object.freeze({}).detectStrictMode = true; +`,`} catch (error) { +`," throw new Error(`The whole PnP file got strict-mode-ified, which is known to break (Emscripten libraries aren't strict mode). This usually happens when the file goes through Babel.`);\n",`} +`,` +`,`var __non_webpack_module__ = module; +`,` +`,`function $$SETUP_STATE(hydrateRuntimeState, basePath) { +`,e.replace(/^/gm," "),`} +`,` +`,(0,zle.default)()].join("")}function s6e(t){return JSON.stringify(t,null,2)}function o6e(t){return[`return hydrateRuntimeState(${qle(t)}, {basePath: basePath || __dirname}); +`].join("")}function a6e(t){return[`var path = require('path'); +`,`var dataLocation = path.resolve(__dirname, ${JSON.stringify(t)}); +`,`return hydrateRuntimeState(require(dataLocation), {basePath: basePath || path.dirname(dataLocation)}); +`].join("")}function _le(t){let e=XC(t),r=o6e(e);return Vle(t.shebang,r)}function Xle(t){let e=XC(t),r=a6e(t.dataLocation),i=Vle(t.shebang,r);return{dataFile:s6e(e),loaderFile:i}}var tce=ie(require("fs")),u6e=ie(require("path")),rce=ie(require("util"));function _L(t,{basePath:e}){let r=M.toPortablePath(e),i=v.resolve(r),n=t.ignorePatternData!==null?new RegExp(t.ignorePatternData):null,s=new Map,o=new Map(t.packageRegistryData.map(([g,f])=>[g,new Map(f.map(([h,p])=>{var b;if(g===null!=(h===null))throw new Error("Assertion failed: The name and reference should be null, or neither should");let d=(b=p.discardFromLookup)!=null?b:!1,m={name:g,reference:h},I=s.get(p.packageLocation);I?(I.discardFromLookup=I.discardFromLookup&&d,d||(I.locator=m)):s.set(p.packageLocation,{locator:m,discardFromLookup:d});let B=null;return[h,{packageDependencies:new Map(p.packageDependencies),packagePeers:new Set(p.packagePeers),linkType:p.linkType,discardFromLookup:d,get packageLocation(){return B||(B=v.join(i,p.packageLocation))}}]}))])),a=new Map(t.fallbackExclusionList.map(([g,f])=>[g,new Set(f)])),l=new Map(t.fallbackPool),c=t.dependencyTreeRoots,u=t.enableTopLevelFallback;return{basePath:r,dependencyTreeRoots:c,enableTopLevelFallback:u,fallbackExclusionList:a,fallbackPool:l,ignorePattern:n,packageLocatorsByLocations:s,packageRegistry:o}}var df=ie(require("module")),ece=ie($le()),ZL=ie(require("util"));var ur;(function(l){l.API_ERROR="API_ERROR",l.BUILTIN_NODE_RESOLUTION_FAILED="BUILTIN_NODE_RESOLUTION_FAILED",l.MISSING_DEPENDENCY="MISSING_DEPENDENCY",l.MISSING_PEER_DEPENDENCY="MISSING_PEER_DEPENDENCY",l.QUALIFIED_PATH_RESOLUTION_FAILED="QUALIFIED_PATH_RESOLUTION_FAILED",l.INTERNAL="INTERNAL",l.UNDECLARED_DEPENDENCY="UNDECLARED_DEPENDENCY",l.UNSUPPORTED="UNSUPPORTED"})(ur||(ur={}));var c6e=new Set([ur.BUILTIN_NODE_RESOLUTION_FAILED,ur.MISSING_DEPENDENCY,ur.MISSING_PEER_DEPENDENCY,ur.QUALIFIED_PATH_RESOLUTION_FAILED,ur.UNDECLARED_DEPENDENCY]);function ui(t,e,r={}){let i=c6e.has(t)?"MODULE_NOT_FOUND":t,n={configurable:!0,writable:!0,enumerable:!1};return Object.defineProperties(new Error(e),{code:_(P({},n),{value:i}),pnpCode:_(P({},n),{value:t}),data:_(P({},n),{value:r})})}function YA(t){return M.normalize(M.fromPortablePath(t))}function $L(t,e){let r=Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK)>0,i=Number(process.env.PNP_DEBUG_LEVEL),n=new Set(df.Module.builtinModules||Object.keys(process.binding("natives"))),s=re=>n.has(re)||re.startsWith("node:"),o=/^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/,a=/^(\/|\.{1,2}(\/|$))/,l=/\/$/,c=/^\.{0,2}\//,u={name:null,reference:null},g=[],f=new Set;if(t.enableTopLevelFallback===!0&&g.push(u),e.compatibilityMode!==!1)for(let re of["react-scripts","gatsby"]){let se=t.packageRegistry.get(re);if(se)for(let be of se.keys()){if(be===null)throw new Error("Assertion failed: This reference shouldn't be null");g.push({name:re,reference:be})}}let{ignorePattern:h,packageRegistry:p,packageLocatorsByLocations:d}=t;function m(re,se){return{fn:re,args:se,error:null,result:null}}function I(re){var De,$,G,Ce,ee,Ue;let se=(G=($=(De=process.stderr)==null?void 0:De.hasColors)==null?void 0:$.call(De))!=null?G:process.stdout.isTTY,be=(Oe,vt)=>`[${Oe}m${vt}`,ae=re.error;console.error(ae?be("31;1",`\u2716 ${(Ce=re.error)==null?void 0:Ce.message.replace(/\n.*/s,"")}`):be("33;1","\u203C Resolution")),re.args.length>0&&console.error();for(let Oe of re.args)console.error(` ${be("37;1","In \u2190")} ${(0,ZL.inspect)(Oe,{colors:se,compact:!0})}`);re.result&&(console.error(),console.error(` ${be("37;1","Out \u2192")} ${(0,ZL.inspect)(re.result,{colors:se,compact:!0})}`));let Ae=(Ue=(ee=new Error().stack.match(/(?<=^ +)at.*/gm))==null?void 0:ee.slice(2))!=null?Ue:[];if(Ae.length>0){console.error();for(let Oe of Ae)console.error(` ${be("38;5;244",Oe)}`)}console.error()}function B(re,se){if(e.allowDebug===!1)return se;if(Number.isFinite(i)){if(i>=2)return(...be)=>{let ae=m(re,be);try{return ae.result=se(...be)}catch(Ae){throw ae.error=Ae}finally{I(ae)}};if(i>=1)return(...be)=>{try{return se(...be)}catch(ae){let Ae=m(re,be);throw Ae.error=ae,I(Ae),ae}}}return se}function b(re){let se=W(re);if(!se)throw ui(ur.INTERNAL,"Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)");return se}function R(re){if(re.name===null)return!0;for(let se of t.dependencyTreeRoots)if(se.name===re.name&&se.reference===re.reference)return!0;return!1}let H=new Set(["default","node","require"]);function L(re,se=H){let be=D(v.join(re,"internal.js"),{resolveIgnored:!0,includeDiscardFromLookup:!0});if(be===null)throw ui(ur.INTERNAL,`The locator that owns the "${re}" path can't be found inside the dependency tree (this is probably an internal error)`);let{packageLocation:ae}=b(be),Ae=v.join(ae,wt.manifest);if(!e.fakeFs.existsSync(Ae))return null;let De=JSON.parse(e.fakeFs.readFileSync(Ae,"utf8")),$=v.contains(ae,re);if($===null)throw ui(ur.INTERNAL,"unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)");c.test($)||($=`./${$}`);let G=(0,ece.resolve)(De,v.normalize($),{conditions:se,unsafe:!0});return typeof G=="string"?v.join(ae,G):null}function K(re,se,{extensions:be}){let ae;try{se.push(re),ae=e.fakeFs.statSync(re)}catch(Ae){}if(ae&&!ae.isDirectory())return e.fakeFs.realpathSync(re);if(ae&&ae.isDirectory()){let Ae;try{Ae=JSON.parse(e.fakeFs.readFileSync(v.join(re,wt.manifest),"utf8"))}catch($){}let De;if(Ae&&Ae.main&&(De=v.resolve(re,Ae.main)),De&&De!==re){let $=K(De,se,{extensions:be});if($!==null)return $}}for(let Ae=0,De=be.length;Ae{let G=JSON.stringify($.name);if(ae.has(G))return;ae.add(G);let Ce=X($);for(let ee of Ce)if(b(ee).packagePeers.has(re))Ae(ee);else{let Oe=be.get(ee.name);typeof Oe=="undefined"&&be.set(ee.name,Oe=new Set),Oe.add(ee.reference)}};Ae(se);let De=[];for(let $ of[...be.keys()].sort())for(let G of[...be.get($)].sort())De.push({name:$,reference:G});return De}function D(re,{resolveIgnored:se=!1,includeDiscardFromLookup:be=!1}={}){if(q(re)&&!se)return null;let ae=v.relative(t.basePath,re);ae.match(a)||(ae=`./${ae}`),ae.endsWith("/")||(ae=`${ae}/`);do{let Ae=d.get(ae);if(typeof Ae=="undefined"||Ae.discardFromLookup&&!be){ae=ae.substring(0,ae.lastIndexOf("/",ae.length-2)+1);continue}return Ae.locator}while(ae!=="");return null}function he(re,se,{considerBuiltins:be=!0}={}){if(re==="pnpapi")return M.toPortablePath(e.pnpapiResolution);if(be&&s(re))return null;let ae=YA(re),Ae=se&&YA(se);if(se&&q(se)&&(!v.isAbsolute(re)||D(re)===null)){let G=ne(re,se);if(G===!1)throw ui(ur.BUILTIN_NODE_RESOLUTION_FAILED,`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer was explicitely ignored by the regexp) + +Require request: "${ae}" +Required by: ${Ae} +`,{request:ae,issuer:Ae});return M.toPortablePath(G)}let De,$=re.match(o);if($){if(!se)throw ui(ur.API_ERROR,"The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:ae,issuer:Ae});let[,G,Ce]=$,ee=D(se);if(!ee){let yr=ne(re,se);if(yr===!1)throw ui(ur.BUILTIN_NODE_RESOLUTION_FAILED,`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree). + +Require path: "${ae}" +Required by: ${Ae} +`,{request:ae,issuer:Ae});return M.toPortablePath(yr)}let Oe=b(ee).packageDependencies.get(G),vt=null;if(Oe==null&&ee.name!==null){let yr=t.fallbackExclusionList.get(ee.name);if(!yr||!yr.has(ee.reference)){for(let Qi=0,Go=g.length;QiR(Ki))?dt=ui(ur.MISSING_PEER_DEPENDENCY,`${ee.name} tried to access ${G} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ae?` (via "${ae}")`:""} +Required by: ${ee.name}@${ee.reference} (via ${Ae}) +${yr.map(Ki=>`Ancestor breaking the chain: ${Ki.name}@${Ki.reference} +`).join("")} +`,{request:ae,issuer:Ae,issuerLocator:Object.assign({},ee),dependencyName:G,brokenAncestors:yr}):dt=ui(ur.MISSING_PEER_DEPENDENCY,`${ee.name} tried to access ${G} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ae?` (via "${ae}")`:""} +Required by: ${ee.name}@${ee.reference} (via ${Ae}) + +${yr.map(Ki=>`Ancestor breaking the chain: ${Ki.name}@${Ki.reference} +`).join("")} +`,{request:ae,issuer:Ae,issuerLocator:Object.assign({},ee),dependencyName:G,brokenAncestors:yr})}else Oe===void 0&&(!be&&s(re)?R(ee)?dt=ui(ur.UNDECLARED_DEPENDENCY,`Your application tried to access ${G}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${G} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ae?` (via "${ae}")`:""} +Required by: ${Ae} +`,{request:ae,issuer:Ae,dependencyName:G}):dt=ui(ur.UNDECLARED_DEPENDENCY,`${ee.name} tried to access ${G}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${G} isn't otherwise declared in ${ee.name}'s dependencies, this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ae?` (via "${ae}")`:""} +Required by: ${Ae} +`,{request:ae,issuer:Ae,issuerLocator:Object.assign({},ee),dependencyName:G}):R(ee)?dt=ui(ur.UNDECLARED_DEPENDENCY,`Your application tried to access ${G}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ae?` (via "${ae}")`:""} +Required by: ${Ae} +`,{request:ae,issuer:Ae,dependencyName:G}):dt=ui(ur.UNDECLARED_DEPENDENCY,`${ee.name} tried to access ${G}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ae?` (via "${ae}")`:""} +Required by: ${ee.name}@${ee.reference} (via ${Ae}) +`,{request:ae,issuer:Ae,issuerLocator:Object.assign({},ee),dependencyName:G}));if(Oe==null){if(vt===null||dt===null)throw dt||new Error("Assertion failed: Expected an error to have been set");Oe=vt;let yr=dt.message.replace(/\n.*/g,"");dt.message=yr,!f.has(yr)&&i!==0&&(f.add(yr),process.emitWarning(dt))}let ri=Array.isArray(Oe)?{name:Oe[0],reference:Oe[1]}:{name:G,reference:Oe},ii=b(ri);if(!ii.packageLocation)throw ui(ur.MISSING_DEPENDENCY,`A dependency seems valid but didn't get installed for some reason. This might be caused by a partial install, such as dev vs prod. + +Required package: ${ri.name}@${ri.reference}${ri.name!==ae?` (via "${ae}")`:""} +Required by: ${ee.name}@${ee.reference} (via ${Ae}) +`,{request:ae,issuer:Ae,dependencyLocator:Object.assign({},ri)});let an=ii.packageLocation;Ce?De=v.join(an,Ce):De=an}else if(v.isAbsolute(re))De=v.normalize(re);else{if(!se)throw ui(ur.API_ERROR,"The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:ae,issuer:Ae});let G=v.resolve(se);se.match(l)?De=v.normalize(v.join(G,re)):De=v.normalize(v.join(v.dirname(G),re))}return v.normalize(De)}function pe(re,se,be=H){if(a.test(re))return se;let ae=L(se,be);return ae?v.normalize(ae):se}function Ne(re,{extensions:se=Object.keys(df.Module._extensions)}={}){let be=[],ae=K(re,be,{extensions:se});if(ae)return v.normalize(ae);{let Ae=YA(re),De=D(re);if(De){let{packageLocation:$}=b(De);if(!e.fakeFs.existsSync($)){let G=$.includes("/unplugged/")?"Required unplugged package missing from disk. This may happen when switching branches without running installs (unplugged packages must be fully materialized on disk to work).":"Required package missing from disk. If you keep your packages inside your repository then restarting the Node process may be enough. Otherwise, try to run an install first.";throw ui(ur.QUALIFIED_PATH_RESOLUTION_FAILED,`${G} + +Missing package: ${De.name}@${De.reference} +Expected package location: ${YA($)} +`,{unqualifiedPath:Ae})}}throw ui(ur.QUALIFIED_PATH_RESOLUTION_FAILED,`Qualified path resolution failed - none of those files can be found on the disk. + +Source path: ${Ae} +${be.map($=>`Not found: ${YA($)} +`).join("")}`,{unqualifiedPath:Ae})}}function Pe(re,se,{considerBuiltins:be,extensions:ae,conditions:Ae}={}){let De=he(re,se,{considerBuiltins:be});if(re==="pnpapi")return De;if(De===null)return null;let $=()=>se!==null?q(se):!1,G=(!be||!s(re))&&!$()?pe(re,De,Ae):De;try{return Ne(G,{extensions:ae})}catch(Ce){throw Ce.pnpCode==="QUALIFIED_PATH_RESOLUTION_FAILED"&&Object.assign(Ce.data,{request:YA(re),issuer:se&&YA(se)}),Ce}}function qe(re){let se=v.normalize(re),be=Pr.resolveVirtual(se);return be!==se?be:null}return{VERSIONS:A,topLevel:V,getLocator:(re,se)=>Array.isArray(se)?{name:se[0],reference:se[1]}:{name:re,reference:se},getDependencyTreeRoots:()=>[...t.dependencyTreeRoots],getAllLocators(){let re=[];for(let[se,be]of p)for(let ae of be.keys())se!==null&&ae!==null&&re.push({name:se,reference:ae});return re},getPackageInformation:re=>{let se=W(re);if(se===null)return null;let be=M.fromPortablePath(se.packageLocation);return _(P({},se),{packageLocation:be})},findPackageLocator:re=>D(M.toPortablePath(re)),resolveToUnqualified:B("resolveToUnqualified",(re,se,be)=>{let ae=se!==null?M.toPortablePath(se):null,Ae=he(M.toPortablePath(re),ae,be);return Ae===null?null:M.fromPortablePath(Ae)}),resolveUnqualified:B("resolveUnqualified",(re,se)=>M.fromPortablePath(Ne(M.toPortablePath(re),se))),resolveRequest:B("resolveRequest",(re,se,be)=>{let ae=se!==null?M.toPortablePath(se):null,Ae=Pe(M.toPortablePath(re),ae,be);return Ae===null?null:M.fromPortablePath(Ae)}),resolveVirtual:B("resolveVirtual",re=>{let se=qe(M.toPortablePath(re));return se!==null?M.fromPortablePath(se):null})}}var ISt=(0,rce.promisify)(tce.readFile);var ice=(t,e,r)=>{let i=XC(t),n=_L(i,{basePath:e}),s=M.join(e,wt.pnpCjs);return $L(n,{fakeFs:r,pnpapiResolution:s})};var tT=ie(sce());var Ws={};it(Ws,{checkAndReportManifestCompatibility:()=>oce,extractBuildScripts:()=>Z0,getExtractHint:()=>rT,hasBindingGyp:()=>iT});function oce(t,e,{configuration:r,report:i}){return S.isPackageCompatible(t,{os:[process.platform],cpu:[process.arch]})?!0:(i==null||i.reportWarningOnce(z.INCOMPATIBLE_ARCHITECTURE,`${S.prettyLocator(r,t)} The ${process.platform}-${process.arch} architecture is incompatible with this module, ${e} skipped.`),!1)}function Z0(t,e,r,{configuration:i,report:n}){let s=[];for(let a of["preinstall","install","postinstall"])e.manifest.scripts.has(a)&&s.push([Gn.SCRIPT,a]);return!e.manifest.scripts.has("install")&&e.misc.hasBindingGyp&&s.push([Gn.SHELLCODE,"node-gyp rebuild"]),s.length===0?[]:t.linkType!==gt.HARD?(n==null||n.reportWarningOnce(z.SOFT_LINK_BUILD,`${S.prettyLocator(i,t)} lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored.`),[]):r&&r.built===!1?(n==null||n.reportInfoOnce(z.BUILD_DISABLED,`${S.prettyLocator(i,t)} lists build scripts, but its build has been explicitly disabled through configuration.`),[]):!i.get("enableScripts")&&!r.built?(n==null||n.reportWarningOnce(z.DISABLED_BUILD_SCRIPTS,`${S.prettyLocator(i,t)} lists build scripts, but all build scripts have been disabled.`),[]):oce(t,"build",{configuration:i,report:n})?s:[]}var g6e=new Set([".exe",".h",".hh",".hpp",".c",".cc",".cpp",".java",".jar",".node"]);function rT(t){return t.packageFs.getExtractHint({relevantExtensions:g6e})}function iT(t){let e=v.join(t.prefixPath,"binding.gyp");return t.packageFs.existsSync(e)}var nT={};it(nT,{getUnpluggedPath:()=>ZC});function ZC(t,{configuration:e}){return v.resolve(e.get("pnpUnpluggedFolder"),S.slugifyLocator(t))}var f6e=new Set([S.makeIdent(null,"nan").identHash,S.makeIdent(null,"node-gyp").identHash,S.makeIdent(null,"node-pre-gyp").identHash,S.makeIdent(null,"node-addon-api").identHash,S.makeIdent(null,"fsevents").identHash]),jc=class{constructor(){this.mode="strict";this.pnpCache=new Map}supportsPackage(e,r){return!(r.project.configuration.get("nodeLinker")!=="pnp"||r.project.configuration.get("pnpMode")!==this.mode)}async findPackageLocation(e,r){let i=qA(r.project).cjs;if(!T.existsSync(i))throw new me(`The project in ${ue.pretty(r.project.configuration,`${r.project.cwd}/package.json`,ue.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let n=de.getFactoryWithDefault(this.pnpCache,i,()=>de.dynamicRequire(i,{cachingStrategy:de.CachingStrategy.FsTime})),s={name:S.stringifyIdent(e),reference:e.reference},o=n.getPackageInformation(s);if(!o)throw new me(`Couldn't find ${S.prettyLocator(r.project.configuration,e)} in the currently installed PnP map - running an install might help`);return M.toPortablePath(o.packageLocation)}async findPackageLocator(e,r){let i=qA(r.project).cjs;if(!T.existsSync(i))return null;let s=de.getFactoryWithDefault(this.pnpCache,i,()=>de.dynamicRequire(i,{cachingStrategy:de.CachingStrategy.FsTime})).findPackageLocator(M.fromPortablePath(e));return s?S.makeLocator(S.parseIdent(s.name),s.reference):null}makeInstaller(e){return new Cf(e)}},Cf=class{constructor(e){this.opts=e;this.mode="strict";this.packageRegistry=new Map;this.virtualTemplates=new Map;this.isESMLoaderRequired=!1;this.customData={store:new Map};this.unpluggedPaths=new Set;this.opts=e}getCustomDataKey(){return JSON.stringify({name:"PnpInstaller",version:2})}attachCustomData(e){this.customData=e}async installPackage(e,r){let i=S.stringifyIdent(e),n=e.reference,s=!!this.opts.project.tryWorkspaceByLocator(e),o=S.isVirtualLocator(e),a=e.peerDependencies.size>0&&!o,l=!a&&!s,c=!a&&e.linkType!==gt.SOFT,u,g;if(l||c){let B=o?S.devirtualizeLocator(e):e;u=this.customData.store.get(B.locatorHash),typeof u=="undefined"&&(u=await h6e(r),e.linkType===gt.HARD&&this.customData.store.set(B.locatorHash,u)),u.manifest.type==="module"&&(this.isESMLoaderRequired=!0),g=this.opts.project.getDependencyMeta(B,e.version)}let f=l?Z0(e,u,g,{configuration:this.opts.project.configuration,report:this.opts.report}):[],h=c?await this.unplugPackageIfNeeded(e,u,r,g):r.packageFs;if(v.isAbsolute(r.prefixPath))throw new Error(`Assertion failed: Expected the prefix path (${r.prefixPath}) to be relative to the parent`);let p=v.resolve(h.getRealPath(),r.prefixPath),d=sT(this.opts.project.cwd,p),m=new Map,I=new Set;if(o){for(let B of e.peerDependencies.values())m.set(S.stringifyIdent(B),null),I.add(S.stringifyIdent(B));if(!s){let B=S.devirtualizeLocator(e);this.virtualTemplates.set(B.locatorHash,{location:sT(this.opts.project.cwd,Pr.resolveVirtual(p)),locator:B})}}return de.getMapWithDefault(this.packageRegistry,i).set(n,{packageLocation:d,packageDependencies:m,packagePeers:I,linkType:e.linkType,discardFromLookup:r.discardFromLookup||!1}),{packageLocation:p,buildDirective:f.length>0?f:null}}async attachInternalDependencies(e,r){let i=this.getPackageInformation(e);for(let[n,s]of r){let o=S.areIdentsEqual(n,s)?s.reference:[S.stringifyIdent(s),s.reference];i.packageDependencies.set(S.stringifyIdent(n),o)}}async attachExternalDependents(e,r){for(let i of r)this.getDiskInformation(i).packageDependencies.set(S.stringifyIdent(e),e.reference)}async finalizeInstall(){if(this.opts.project.configuration.get("pnpMode")!==this.mode)return;let e=qA(this.opts.project);if(T.existsSync(e.cjsLegacy)&&(this.opts.report.reportWarning(z.UNNAMED,`Removing the old ${ue.pretty(this.opts.project.configuration,wt.pnpJs,ue.Type.PATH)} file. You might need to manually update existing references to reference the new ${ue.pretty(this.opts.project.configuration,wt.pnpCjs,ue.Type.PATH)} file. If you use Editor SDKs, you'll have to rerun ${ue.pretty(this.opts.project.configuration,"yarn sdks",ue.Type.CODE)}.`),await T.removePromise(e.cjsLegacy)),this.isEsmEnabled()||await T.removePromise(e.esmLoader),this.opts.project.configuration.get("nodeLinker")!=="pnp"){await T.removePromise(e.cjs),await T.removePromise(this.opts.project.configuration.get("pnpDataPath")),await T.removePromise(e.esmLoader);return}for(let{locator:u,location:g}of this.virtualTemplates.values())de.getMapWithDefault(this.packageRegistry,S.stringifyIdent(u)).set(u.reference,{packageLocation:g,packageDependencies:new Map,packagePeers:new Set,linkType:gt.SOFT,discardFromLookup:!1});this.packageRegistry.set(null,new Map([[null,this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)]]));let r=this.opts.project.configuration.get("pnpFallbackMode"),i=this.opts.project.workspaces.map(({anchoredLocator:u})=>({name:S.stringifyIdent(u),reference:u.reference})),n=r!=="none",s=[],o=new Map,a=de.buildIgnorePattern([".yarn/sdks/**",...this.opts.project.configuration.get("pnpIgnorePatterns")]),l=this.packageRegistry,c=this.opts.project.configuration.get("pnpShebang");if(r==="dependencies-only")for(let u of this.opts.project.storedPackages.values())this.opts.project.tryWorkspaceByLocator(u)&&s.push({name:S.stringifyIdent(u),reference:u.reference});return await this.finalizeInstallWithPnp({dependencyTreeRoots:i,enableTopLevelFallback:n,fallbackExclusionList:s,fallbackPool:o,ignorePattern:a,packageRegistry:l,shebang:c}),{customData:this.customData}}async transformPnpSettings(e){}isEsmEnabled(){if(this.opts.project.configuration.sources.has("pnpEnableEsmLoader"))return this.opts.project.configuration.get("pnpEnableEsmLoader");if(this.isESMLoaderRequired)return!0;for(let e of this.opts.project.workspaces)if(e.manifest.type==="module")return!0;return!1}async finalizeInstallWithPnp(e){let r=qA(this.opts.project),i=this.opts.project.configuration.get("pnpDataPath"),n=await this.locateNodeModules(e.ignorePattern);if(n.length>0){this.opts.report.reportWarning(z.DANGEROUS_NODE_MODULES,"One or more node_modules have been detected and will be removed. This operation may take some time.");for(let o of n)await T.removePromise(o)}if(await this.transformPnpSettings(e),this.opts.project.configuration.get("pnpEnableInlining")){let o=_le(e);await T.changeFilePromise(r.cjs,o,{automaticNewlines:!0,mode:493}),await T.removePromise(i)}else{let o=v.relative(v.dirname(r.cjs),i),{dataFile:a,loaderFile:l}=Xle(_(P({},e),{dataLocation:o}));await T.changeFilePromise(r.cjs,l,{automaticNewlines:!0,mode:493}),await T.changeFilePromise(i,a,{automaticNewlines:!0,mode:420})}this.isEsmEnabled()&&(this.opts.report.reportWarning(z.UNNAMED,"ESM support for PnP uses the experimental loader API and is therefore experimental"),await T.changeFilePromise(r.esmLoader,(0,tT.default)(),{automaticNewlines:!0,mode:420}));let s=this.opts.project.configuration.get("pnpUnpluggedFolder");if(this.unpluggedPaths.size===0)await T.removePromise(s);else for(let o of await T.readdirPromise(s)){let a=v.resolve(s,o);this.unpluggedPaths.has(a)||await T.removePromise(a)}}async locateNodeModules(e){let r=[],i=e?new RegExp(e):null;for(let n of this.opts.project.workspaces){let s=v.join(n.cwd,"node_modules");if(i&&i.test(v.relative(this.opts.project.cwd,n.cwd))||!T.existsSync(s))continue;let o=await T.readdirPromise(s,{withFileTypes:!0}),a=o.filter(l=>!l.isDirectory()||l.name===".bin"||!l.name.startsWith("."));if(a.length===o.length)r.push(s);else for(let l of a)r.push(v.join(s,l.name))}return r}async unplugPackageIfNeeded(e,r,i,n){return this.shouldBeUnplugged(e,r,n)?this.unplugPackage(e,i):i.packageFs}shouldBeUnplugged(e,r,i){return typeof i.unplugged!="undefined"?i.unplugged:f6e.has(e.identHash)||e.conditions!=null?!0:r.manifest.preferUnplugged!==null?r.manifest.preferUnplugged:!!(Z0(e,r,i,{configuration:this.opts.project.configuration}).length>0||r.misc.extractHint)}async unplugPackage(e,r){let i=ZC(e,{configuration:this.opts.project.configuration});if(this.opts.project.disabledLocators.has(e.locatorHash))return new Xo(i,{baseFs:r.packageFs,pathUtils:v});this.unpluggedPaths.add(i);let n=v.join(i,r.prefixPath,".ready");return await T.existsPromise(n)?new Ft(i):(this.opts.project.storedBuildState.delete(e.locatorHash),await T.mkdirPromise(i,{recursive:!0}),await T.copyPromise(i,Se.dot,{baseFs:r.packageFs,overwrite:!1}),await T.writeFilePromise(n,""),new Ft(i))}getPackageInformation(e){let r=S.stringifyIdent(e),i=e.reference,n=this.packageRegistry.get(r);if(!n)throw new Error(`Assertion failed: The package information store should have been available (for ${S.prettyIdent(this.opts.project.configuration,e)})`);let s=n.get(i);if(!s)throw new Error(`Assertion failed: The package information should have been available (for ${S.prettyLocator(this.opts.project.configuration,e)})`);return s}getDiskInformation(e){let r=de.getMapWithDefault(this.packageRegistry,"@@disk"),i=sT(this.opts.project.cwd,e);return de.getFactoryWithDefault(r,i,()=>({packageLocation:i,packageDependencies:new Map,packagePeers:new Set,linkType:gt.SOFT,discardFromLookup:!1}))}};function sT(t,e){let r=v.relative(t,e);return r.match(/^\.{0,2}\//)||(r=`./${r}`),r.replace(/\/?$/,"/")}async function h6e(t){var i;let e=(i=await Ze.tryFind(t.prefixPath,{baseFs:t.packageFs}))!=null?i:new Ze,r=new Set(["preinstall","install","postinstall"]);for(let n of e.scripts.keys())r.has(n)||e.scripts.delete(n);return{manifest:{scripts:e.scripts,preferUnplugged:e.preferUnplugged,type:e.type},misc:{extractHint:rT(t),hasBindingGyp:iT(t)}}}var ace=ie(Nn());var $C=class extends Be{constructor(){super(...arguments);this.all=Y.Boolean("-A,--all",!1,{description:"Unplug direct dependencies from the entire project"});this.recursive=Y.Boolean("-R,--recursive",!1,{description:"Unplug both direct and transitive dependencies"});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=Y.Rest()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);if(e.get("nodeLinker")!=="pnp")throw new me("This command can only be used if the `nodeLinker` option is set to `pnp`");await r.restoreInstallState();let s=new Set(this.patterns),o=this.patterns.map(f=>{let h=S.parseDescriptor(f),p=h.range!=="unknown"?h:S.makeDescriptor(h,"*");if(!qt.validRange(p.range))throw new me(`The range of the descriptor patterns must be a valid semver range (${S.prettyDescriptor(e,p)})`);return d=>{let m=S.stringifyIdent(d);return!ace.default.isMatch(m,S.stringifyIdent(p))||d.version&&!qt.satisfiesWithPrereleases(d.version,p.range)?!1:(s.delete(f),!0)}}),a=()=>{let f=[];for(let h of r.storedPackages.values())!r.tryWorkspaceByLocator(h)&&!S.isVirtualLocator(h)&&o.some(p=>p(h))&&f.push(h);return f},l=f=>{let h=new Set,p=[],d=(m,I)=>{if(!h.has(m.locatorHash)&&(h.add(m.locatorHash),!r.tryWorkspaceByLocator(m)&&o.some(B=>B(m))&&p.push(m),!(I>0&&!this.recursive)))for(let B of m.dependencies.values()){let b=r.storedResolutions.get(B.descriptorHash);if(!b)throw new Error("Assertion failed: The resolution should have been registered");let R=r.storedPackages.get(b);if(!R)throw new Error("Assertion failed: The package should have been registered");d(R,I+1)}};for(let m of f){let I=r.storedPackages.get(m.anchoredLocator.locatorHash);if(!I)throw new Error("Assertion failed: The package should have been registered");d(I,0)}return p},c,u;if(this.all&&this.recursive?(c=a(),u="the project"):this.all?(c=l(r.workspaces),u="any workspace"):(c=l([i]),u="this workspace"),s.size>1)throw new me(`Patterns ${ue.prettyList(e,s,ue.Type.CODE)} don't match any packages referenced by ${u}`);if(s.size>0)throw new me(`Pattern ${ue.prettyList(e,s,ue.Type.CODE)} doesn't match any packages referenced by ${u}`);return c=de.sortMap(c,f=>S.stringifyLocator(f)),(await Fe.start({configuration:e,stdout:this.context.stdout,json:this.json},async f=>{var h;for(let p of c){let d=(h=p.version)!=null?h:"unknown",m=r.topLevelWorkspace.manifest.ensureDependencyMeta(S.makeDescriptor(p,d));m.unplugged=!0,f.reportInfo(z.UNNAMED,`Will unpack ${S.prettyLocator(e,p)} to ${ue.pretty(e,ZC(p,{configuration:e}),ue.Type.PATH)}`),f.reportJson({locator:S.stringifyLocator(p),version:d})}await r.topLevelWorkspace.persistManifest(),f.reportSeparator(),await r.install({cache:n,report:f})})).exitCode()}};$C.paths=[["unplug"]],$C.usage=ye.Usage({description:"force the unpacking of a list of packages",details:"\n This command will add the selectors matching the specified patterns to the list of packages that must be unplugged when installed.\n\n A package being unplugged means that instead of being referenced directly through its archive, it will be unpacked at install time in the directory configured via `pnpUnpluggedFolder`. Note that unpacking packages this way is generally not recommended because it'll make it harder to store your packages within the repository. However, it's a good approach to quickly and safely debug some packages, and can even sometimes be required depending on the context (for example when the package contains shellscripts).\n\n Running the command will set a persistent flag inside your top-level `package.json`, in the `dependenciesMeta` field. As such, to undo its effects, you'll need to revert the changes made to the manifest and run `yarn install` to apply the modification.\n\n By default, only direct dependencies from the current workspace are affected. If `-A,--all` is set, direct dependencies from the entire project are affected. Using the `-R,--recursive` flag will affect transitive dependencies as well as direct ones.\n\n This command accepts glob patterns inside the scope and name components (not the range). Make sure to escape the patterns to prevent your own shell from trying to expand them.\n ",examples:[["Unplug the lodash dependency from the active workspace","yarn unplug lodash"],["Unplug all instances of lodash referenced by any workspace","yarn unplug lodash -A"],["Unplug all instances of lodash referenced by the active workspace and its dependencies","yarn unplug lodash -R"],["Unplug all instances of lodash, anywhere","yarn unplug lodash -AR"],["Unplug one specific version of lodash","yarn unplug lodash@1.2.3"],["Unplug all packages with the `@babel` scope","yarn unplug '@babel/*'"],["Unplug all packages (only for testing, not recommended)","yarn unplug -R '*'"]]});var Ace=$C;var qA=t=>({cjs:v.join(t.cwd,wt.pnpCjs),cjsLegacy:v.join(t.cwd,wt.pnpJs),esmLoader:v.join(t.cwd,".pnp.loader.mjs")}),uce=t=>/\s/.test(t)?JSON.stringify(t):t;async function p6e(t,e,r){let i=qA(t),n=`--require ${uce(M.fromPortablePath(i.cjs))}`;if(T.existsSync(i.esmLoader)&&(n=`${n} --experimental-loader ${(0,cce.pathToFileURL)(M.fromPortablePath(i.esmLoader)).href}`),i.cjs.includes(" ")&&lce.default.lt(process.versions.node,"12.0.0"))throw new Error(`Expected the build location to not include spaces when using Node < 12.0.0 (${process.versions.node})`);if(T.existsSync(i.cjs)){let s=e.NODE_OPTIONS||"",o=/\s*--require\s+\S*\.pnp\.c?js\s*/g,a=/\s*--experimental-loader\s+\S*\.pnp\.loader\.mjs\s*/;s=s.replace(o," ").replace(a," ").trim(),s=s?`${n} ${s}`:n,e.NODE_OPTIONS=s}}async function d6e(t,e){let r=qA(t);e(r.cjs),e(r.esmLoader),e(t.configuration.get("pnpDataPath")),e(t.configuration.get("pnpUnpluggedFolder"))}var C6e={hooks:{populateYarnPaths:d6e,setupScriptEnvironment:p6e},configuration:{nodeLinker:{description:'The linker used for installing Node packages, one of: "pnp", "node-modules"',type:ge.STRING,default:"pnp"},pnpMode:{description:"If 'strict', generates standard PnP maps. If 'loose', merges them with the n_m resolution.",type:ge.STRING,default:"strict"},pnpShebang:{description:"String to prepend to the generated PnP script",type:ge.STRING,default:"#!/usr/bin/env node"},pnpIgnorePatterns:{description:"Array of glob patterns; files matching them will use the classic resolution",type:ge.STRING,default:[],isArray:!0},pnpEnableEsmLoader:{description:"If true, Yarn will generate an ESM loader (`.pnp.loader.mjs`). If this is not explicitly set Yarn tries to automatically detect whether ESM support is required.",type:ge.BOOLEAN,default:!1},pnpEnableInlining:{description:"If true, the PnP data will be inlined along with the generated loader",type:ge.BOOLEAN,default:!0},pnpFallbackMode:{description:"If true, the generated PnP loader will follow the top-level fallback rule",type:ge.STRING,default:"dependencies-only"},pnpUnpluggedFolder:{description:"Folder where the unplugged packages must be stored",type:ge.ABSOLUTE_PATH,default:"./.yarn/unplugged"},pnpDataPath:{description:"Path of the file where the PnP data (used by the loader) must be written",type:ge.ABSOLUTE_PATH,default:"./.pnp.data.json"}},linkers:[jc],commands:[Ace]},m6e=C6e;var Cce=ie(dce());var uT=ie(require("crypto")),mce=ie(require("fs")),Ece=1,gi="node_modules",gT=".bin",Ice=".yarn-state.yml",Bi;(function(i){i.CLASSIC="classic",i.HARDLINKS_LOCAL="hardlinks-local",i.HARDLINKS_GLOBAL="hardlinks-global"})(Bi||(Bi={}));var fT=class{constructor(){this.installStateCache=new Map}supportsPackage(e,r){return r.project.configuration.get("nodeLinker")==="node-modules"}async findPackageLocation(e,r){let i=r.project.tryWorkspaceByLocator(e);if(i)return i.cwd;let n=await de.getFactoryWithDefault(this.installStateCache,r.project.cwd,async()=>await hT(r.project,{unrollAliases:!0}));if(n===null)throw new me("Couldn't find the node_modules state file - running an install might help (findPackageLocation)");let s=n.locatorMap.get(S.stringifyLocator(e));if(!s){let a=new me(`Couldn't find ${S.prettyLocator(r.project.configuration,e)} in the currently installed node_modules map - running an install might help`);throw a.code="LOCATOR_NOT_INSTALLED",a}let o=r.project.configuration.startingCwd;return s.locations.find(a=>v.contains(o,a))||s.locations[0]}async findPackageLocator(e,r){let i=await de.getFactoryWithDefault(this.installStateCache,r.project.cwd,async()=>await hT(r.project,{unrollAliases:!0}));if(i===null)return null;let{locationRoot:n,segments:s}=$0(v.resolve(e),{skipPrefix:r.project.cwd}),o=i.locationTree.get(n);if(!o)return null;let a=o.locator;for(let l of s){if(o=o.children.get(l),!o)break;a=o.locator||a}return S.parseLocator(a)}makeInstaller(e){return new yce(e)}},yce=class{constructor(e){this.opts=e;this.localStore=new Map;this.realLocatorChecksums=new Map;this.customData={store:new Map}}getCustomDataKey(){return JSON.stringify({name:"NodeModulesInstaller",version:1})}attachCustomData(e){this.customData=e}async installPackage(e,r){var u;let i=v.resolve(r.packageFs.getRealPath(),r.prefixPath),n=this.customData.store.get(e.locatorHash);if(typeof n=="undefined"&&(n=await L6e(e,r),e.linkType===gt.HARD&&this.customData.store.set(e.locatorHash,n)),!Ws.checkAndReportManifestCompatibility(e,"link",{configuration:this.opts.project.configuration,report:this.opts.report}))return{packageLocation:null,buildDirective:null};let s=new Map,o=new Set;s.has(S.stringifyIdent(e))||s.set(S.stringifyIdent(e),e.reference);let a=e;if(S.isVirtualLocator(e)){a=S.devirtualizeLocator(e);for(let g of e.peerDependencies.values())s.set(S.stringifyIdent(g),null),o.add(S.stringifyIdent(g))}let l={packageLocation:`${M.fromPortablePath(i)}/`,packageDependencies:s,packagePeers:o,linkType:e.linkType,discardFromLookup:(u=r.discardFromLookup)!=null?u:!1};this.localStore.set(e.locatorHash,{pkg:e,customPackageData:n,dependencyMeta:this.opts.project.getDependencyMeta(e,e.version),pnpNode:l});let c=r.checksum?r.checksum.substring(r.checksum.indexOf("/")+1):null;return this.realLocatorChecksums.set(a.locatorHash,c),{packageLocation:i,buildDirective:null}}async attachInternalDependencies(e,r){let i=this.localStore.get(e.locatorHash);if(typeof i=="undefined")throw new Error("Assertion failed: Expected information object to have been registered");for(let[n,s]of r){let o=S.areIdentsEqual(n,s)?s.reference:[S.stringifyIdent(s),s.reference];i.pnpNode.packageDependencies.set(S.stringifyIdent(n),o)}}async attachExternalDependents(e,r){throw new Error("External dependencies haven't been implemented for the node-modules linker")}async finalizeInstall(){if(this.opts.project.configuration.get("nodeLinker")!=="node-modules")return;let e=new Pr({baseFs:new Jn({libzip:await $i(),maxOpenFiles:80,readOnlyArchives:!0})}),r=await hT(this.opts.project),i=this.opts.project.configuration.get("nmMode");(r===null||i!==r.nmMode)&&(this.opts.project.storedBuildState.clear(),r={locatorMap:new Map,binSymlinks:new Map,locationTree:new Map,nmMode:i});let n=new Map(this.opts.project.workspaces.map(f=>{var p,d;let h=this.opts.project.configuration.get("nmHoistingLimits");try{h=de.validateEnum(Sn,(d=(p=f.manifest.installConfig)==null?void 0:p.hoistingLimits)!=null?d:h)}catch(m){let I=S.prettyWorkspace(this.opts.project.configuration,f);this.opts.report.reportWarning(z.INVALID_MANIFEST,`${I}: Invalid 'installConfig.hoistingLimits' value. Expected one of ${Object.values(Sn).join(", ")}, using default: "${h}"`)}return[f.relativeCwd,h]})),s=new Map(this.opts.project.workspaces.map(f=>{var p,d;let h=this.opts.project.configuration.get("nmSelfReferences");return h=(d=(p=f.manifest.installConfig)==null?void 0:p.selfReferences)!=null?d:h,[f.relativeCwd,h]})),o={VERSIONS:{std:1},topLevel:{name:null,reference:null},getLocator:(f,h)=>Array.isArray(h)?{name:h[0],reference:h[1]}:{name:f,reference:h},getDependencyTreeRoots:()=>this.opts.project.workspaces.map(f=>{let h=f.anchoredLocator;return{name:S.stringifyIdent(f.locator),reference:h.reference}}),getPackageInformation:f=>{let h=f.reference===null?this.opts.project.topLevelWorkspace.anchoredLocator:S.makeLocator(S.parseIdent(f.name),f.reference),p=this.localStore.get(h.locatorHash);if(typeof p=="undefined")throw new Error("Assertion failed: Expected the package reference to have been registered");return p.pnpNode},findPackageLocator:f=>{let h=this.opts.project.tryWorkspaceByCwd(M.toPortablePath(f));if(h!==null){let p=h.anchoredLocator;return{name:S.stringifyIdent(p),reference:p.reference}}throw new Error("Assertion failed: Unimplemented")},resolveToUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveRequest:()=>{throw new Error("Assertion failed: Unimplemented")},resolveVirtual:f=>M.fromPortablePath(Pr.resolveVirtual(M.toPortablePath(f)))},{tree:a,errors:l,preserveSymlinksRequired:c}=VC(o,{pnpifyFs:!1,validateExternalSoftLinks:!0,hoistingLimitsByCwd:n,project:this.opts.project,selfReferencesByCwd:s});if(!a){for(let{messageName:f,text:h}of l)this.opts.report.reportError(f,h);return}let u=WL(a);await T6e(r,u,{baseFs:e,project:this.opts.project,report:this.opts.report,realLocatorChecksums:this.realLocatorChecksums,loadManifest:async f=>{let h=S.parseLocator(f),p=this.localStore.get(h.locatorHash);if(typeof p=="undefined")throw new Error("Assertion failed: Expected the slot to exist");return p.customPackageData.manifest}});let g=[];for(let[f,h]of u.entries()){if(wce(f))continue;let p=S.parseLocator(f),d=this.localStore.get(p.locatorHash);if(typeof d=="undefined")throw new Error("Assertion failed: Expected the slot to exist");if(this.opts.project.tryWorkspaceByLocator(d.pkg))continue;let m=Ws.extractBuildScripts(d.pkg,d.customPackageData,d.dependencyMeta,{configuration:this.opts.project.configuration,report:this.opts.report});m.length!==0&&g.push({buildLocations:h.locations,locatorHash:p.locatorHash,buildDirective:m})}return c&&this.opts.report.reportWarning(z.NM_PRESERVE_SYMLINKS_REQUIRED,`The application uses portals and that's why ${ue.pretty(this.opts.project.configuration,"--preserve-symlinks",ue.Type.CODE)} Node option is required for launching it`),{customData:this.customData,records:g}}};async function L6e(t,e){var n;let r=(n=await Ze.tryFind(e.prefixPath,{baseFs:e.packageFs}))!=null?n:new Ze,i=new Set(["preinstall","install","postinstall"]);for(let s of r.scripts.keys())i.has(s)||r.scripts.delete(s);return{manifest:{bin:r.bin,scripts:r.scripts},misc:{extractHint:Ws.getExtractHint(e),hasBindingGyp:Ws.hasBindingGyp(e)}}}async function M6e(t,e,r,i){let n="";n+=`# Warning: This file is automatically generated. Removing it is fine, but will +`,n+=`# cause your node_modules installation to become invalidated. +`,n+=` +`,n+=`__metadata: +`,n+=` version: ${Ece} +`,n+=` nmMode: ${i.value} +`;let s=Array.from(e.keys()).sort(),o=S.stringifyLocator(t.topLevelWorkspace.anchoredLocator);for(let c of s){let u=e.get(c);n+=` +`,n+=`${JSON.stringify(c)}: +`,n+=` locations: +`;for(let g of u.locations){let f=v.contains(t.cwd,g);if(f===null)throw new Error(`Assertion failed: Expected the path to be within the project (${g})`);n+=` - ${JSON.stringify(f)} +`}if(u.aliases.length>0){n+=` aliases: +`;for(let g of u.aliases)n+=` - ${JSON.stringify(g)} +`}if(c===o&&r.size>0){n+=` bin: +`;for(let[g,f]of r){let h=v.contains(t.cwd,g);if(h===null)throw new Error(`Assertion failed: Expected the path to be within the project (${g})`);n+=` ${JSON.stringify(h)}: +`;for(let[p,d]of f){let m=v.relative(v.join(g,gi),d);n+=` ${JSON.stringify(p)}: ${JSON.stringify(m)} +`}}}}let a=t.cwd,l=v.join(a,gi,Ice);await T.changeFilePromise(l,n,{automaticNewlines:!0})}async function hT(t,{unrollAliases:e=!1}={}){let r=t.cwd,i=v.join(r,gi,Ice);if(!T.existsSync(i))return null;let n=Ii(await T.readFilePromise(i,"utf8"));if(n.__metadata.version>Ece)return null;let s=n.__metadata.nmMode||Bi.CLASSIC,o=new Map,a=new Map;delete n.__metadata;for(let[l,c]of Object.entries(n)){let u=c.locations.map(f=>v.join(r,f)),g=c.bin;if(g)for(let[f,h]of Object.entries(g)){let p=v.join(r,M.toPortablePath(f)),d=de.getMapWithDefault(a,p);for(let[m,I]of Object.entries(h))d.set(kr(m),M.toPortablePath([p,gi,I].join(v.delimiter)))}if(o.set(l,{target:Se.dot,linkType:gt.HARD,locations:u,aliases:c.aliases||[]}),e&&c.aliases)for(let f of c.aliases){let{scope:h,name:p}=S.parseLocator(l),d=S.makeLocator(S.makeIdent(h,p),f),m=S.stringifyLocator(d);o.set(m,{target:Se.dot,linkType:gt.HARD,locations:u,aliases:[]})}}return{locatorMap:o,binSymlinks:a,locationTree:Bce(o,{skipPrefix:t.cwd}),nmMode:s}}var Ef=async(t,e)=>{if(t.split(v.sep).indexOf(gi)<0)throw new Error(`Assertion failed: trying to remove dir that doesn't contain node_modules: ${t}`);try{if(!e.innerLoop&&(await T.lstatPromise(t)).isSymbolicLink()){await T.unlinkPromise(t);return}let r=await T.readdirPromise(t,{withFileTypes:!0});for(let i of r){let n=v.join(t,kr(i.name));i.isDirectory()?(i.name!==gi||e&&e.innerLoop)&&await Ef(n,{innerLoop:!0,contentsOnly:!1}):await T.unlinkPromise(n)}e.contentsOnly||await T.rmdirPromise(t)}catch(r){if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw r}},Qce=4,$0=(t,{skipPrefix:e})=>{let r=v.contains(e,t);if(r===null)throw new Error(`Assertion failed: Writing attempt prevented to ${t} which is outside project root: ${e}`);let i=r.split(v.sep).filter(l=>l!==""),n=i.indexOf(gi),s=i.slice(0,n).join(v.sep),o=v.join(e,s),a=i.slice(n);return{locationRoot:o,segments:a}},Bce=(t,{skipPrefix:e})=>{let r=new Map;if(t===null)return r;let i=()=>({children:new Map,linkType:gt.HARD});for(let[n,s]of t.entries()){if(s.linkType===gt.SOFT&&v.contains(e,s.target)!==null){let a=de.getFactoryWithDefault(r,s.target,i);a.locator=n,a.linkType=s.linkType}for(let o of s.locations){let{locationRoot:a,segments:l}=$0(o,{skipPrefix:e}),c=de.getFactoryWithDefault(r,a,i);for(let u=0;u{let r;try{process.platform==="win32"&&(r=await T.lstatPromise(t))}catch(i){}process.platform=="win32"&&(!r||r.isDirectory())?await T.symlinkPromise(t,e,"junction"):await T.symlinkPromise(v.relative(v.dirname(e),t),e)};async function bce(t,e,r){let i=v.join(t,kr(`${uT.default.randomBytes(16).toString("hex")}.tmp`));try{await T.writeFilePromise(i,r);try{await T.linkPromise(i,e)}catch(n){}}finally{await T.unlinkPromise(i)}}async function O6e({srcPath:t,dstPath:e,srcMode:r,globalHardlinksStore:i,baseFs:n,nmMode:s,digest:o}){if(s.value===Bi.HARDLINKS_GLOBAL&&i&&o){let l=v.join(i,o.substring(0,2),`${o.substring(2)}.dat`),c;try{if(await mn.checksumFile(l,{baseFs:T,algorithm:"sha1"})!==o){let g=v.join(i,kr(`${uT.default.randomBytes(16).toString("hex")}.tmp`));await T.renamePromise(l,g);let f=await n.readFilePromise(t);await T.writeFilePromise(g,f);try{await T.linkPromise(g,l),await T.unlinkPromise(g)}catch(h){}}await T.linkPromise(l,e),c=!0}catch(u){c=!1}if(!c){let u=await n.readFilePromise(t);await bce(i,l,u);try{await T.linkPromise(l,e)}catch(g){g&&g.code&&g.code=="EXDEV"&&(s.value=Bi.HARDLINKS_LOCAL,await n.copyFilePromise(t,e))}}}else await n.copyFilePromise(t,e);let a=r&511;a!==420&&await T.chmodPromise(e,a)}var JA;(function(i){i.FILE="file",i.DIRECTORY="directory",i.SYMLINK="symlink"})(JA||(JA={}));var K6e=async(t,e,{baseFs:r,globalHardlinksStore:i,nmMode:n,packageChecksum:s})=>{await T.mkdirPromise(t,{recursive:!0});let o=async(l=Se.dot)=>{let c=v.join(e,l),u=await r.readdirPromise(c,{withFileTypes:!0}),g=new Map;for(let f of u){let h=v.join(l,f.name),p,d=v.join(c,f.name);if(f.isFile()){if(p={kind:JA.FILE,mode:(await r.lstatPromise(d)).mode},n.value===Bi.HARDLINKS_GLOBAL){let m=await mn.checksumFile(d,{baseFs:r,algorithm:"sha1"});p.digest=m}}else if(f.isDirectory())p={kind:JA.DIRECTORY};else if(f.isSymbolicLink())p={kind:JA.SYMLINK,symlinkTo:await r.readlinkPromise(d)};else throw new Error(`Unsupported file type (file: ${d}, mode: 0o${await r.statSync(d).mode.toString(8).padStart(6,"0")})`);if(g.set(h,p),f.isDirectory()&&h!==gi){let m=await o(h);for(let[I,B]of m)g.set(I,B)}}return g},a;if(n.value===Bi.HARDLINKS_GLOBAL&&i&&s){let l=v.join(i,s.substring(0,2),`${s.substring(2)}.json`);try{a=new Map(Object.entries(JSON.parse(await T.readFilePromise(l,"utf8"))))}catch(c){a=await o(),await bce(i,l,Buffer.from(JSON.stringify(Object.fromEntries(a))))}}else a=await o();for(let[l,c]of a){let u=v.join(e,l),g=v.join(t,l);c.kind===JA.DIRECTORY?await T.mkdirPromise(g,{recursive:!0}):c.kind===JA.FILE?await O6e({srcPath:u,dstPath:g,srcMode:c.mode,digest:c.digest,nmMode:n,baseFs:r,globalHardlinksStore:i}):c.kind===JA.SYMLINK&&await pT(v.resolve(v.dirname(g),c.symlinkTo),g)}};function U6e(t,e){let r=new Map([...t]),i=new Map([...e]);for(let[n,s]of t){let o=v.join(n,gi);if(!T.existsSync(o)){s.children.delete(gi);for(let a of i.keys())v.contains(o,a)!==null&&i.delete(a)}}return{locationTree:r,binSymlinks:i}}function wce(t){let e=S.parseDescriptor(t);return S.isVirtualDescriptor(e)&&(e=S.devirtualizeDescriptor(e)),e.range.startsWith("link:")}async function H6e(t,e,r,{loadManifest:i}){let n=new Map;for(let[a,{locations:l}]of t){let c=wce(a)?null:await i(a,l[0]),u=new Map;if(c)for(let[g,f]of c.bin){let h=v.join(l[0],f);f!==""&&T.existsSync(h)&&u.set(g,f)}n.set(a,u)}let s=new Map,o=(a,l,c)=>{let u=new Map,g=v.contains(r,a);if(c.locator&&g!==null){let f=n.get(c.locator);for(let[h,p]of f){let d=v.join(a,M.toPortablePath(p));u.set(kr(h),d)}for(let[h,p]of c.children){let d=v.join(a,h),m=o(d,d,p);m.size>0&&s.set(a,new Map([...s.get(a)||new Map,...m]))}}else for(let[f,h]of c.children){let p=o(v.join(a,f),l,h);for(let[d,m]of p)u.set(d,m)}return u};for(let[a,l]of e){let c=o(a,a,l);c.size>0&&s.set(a,new Map([...s.get(a)||new Map,...c]))}return s}var vce=(t,e)=>{if(!t||!e)return t===e;let r=S.parseLocator(t);S.isVirtualLocator(r)&&(r=S.devirtualizeLocator(r));let i=S.parseLocator(e);return S.isVirtualLocator(i)&&(i=S.devirtualizeLocator(i)),S.areLocatorsEqual(r,i)};function dT(t){return v.join(t.get("globalFolder"),"store")}async function T6e(t,e,{baseFs:r,project:i,report:n,loadManifest:s,realLocatorChecksums:o}){let a=v.join(i.cwd,gi),{locationTree:l,binSymlinks:c}=U6e(t.locationTree,t.binSymlinks),u=Bce(e,{skipPrefix:i.cwd}),g=[],f=async({srcDir:L,dstDir:K,linkType:J,globalHardlinksStore:ne,nmMode:q,packageChecksum:A})=>{let V=(async()=>{try{J===gt.SOFT?(await T.mkdirPromise(v.dirname(K),{recursive:!0}),await pT(v.resolve(L),K)):await K6e(K,L,{baseFs:r,globalHardlinksStore:ne,nmMode:q,packageChecksum:A})}catch(W){throw W.message=`While persisting ${L} -> ${K} ${W.message}`,W}finally{B.tick()}})().then(()=>g.splice(g.indexOf(V),1));g.push(V),g.length>Qce&&await Promise.race(g)},h=async(L,K,J)=>{let ne=(async()=>{let q=async(A,V,W)=>{try{W.innerLoop||await T.mkdirPromise(V,{recursive:!0});let X=await T.readdirPromise(A,{withFileTypes:!0});for(let F of X){if(!W.innerLoop&&F.name===gT)continue;let D=v.join(A,F.name),he=v.join(V,F.name);F.isDirectory()?(F.name!==gi||W&&W.innerLoop)&&(await T.mkdirPromise(he,{recursive:!0}),await q(D,he,_(P({},W),{innerLoop:!0}))):H.value===Bi.HARDLINKS_LOCAL||H.value===Bi.HARDLINKS_GLOBAL?await T.linkPromise(D,he):await T.copyFilePromise(D,he,mce.default.constants.COPYFILE_FICLONE)}}catch(X){throw W.innerLoop||(X.message=`While cloning ${A} -> ${V} ${X.message}`),X}finally{W.innerLoop||B.tick()}};await q(L,K,J)})().then(()=>g.splice(g.indexOf(ne),1));g.push(ne),g.length>Qce&&await Promise.race(g)},p=async(L,K,J)=>{if(!J)K.children.has(gi)&&await Ef(v.join(L,gi),{contentsOnly:!1}),await Ef(L,{contentsOnly:L===a});else for(let[ne,q]of K.children){let A=J.children.get(ne);await p(v.join(L,ne),q,A)}};for(let[L,K]of l){let J=u.get(L);for(let[ne,q]of K.children){if(ne===".")continue;let A=J&&J.children.get(ne);await p(v.join(L,ne),q,A)}}let d=async(L,K,J)=>{if(!J)K.children.has(gi)&&await Ef(v.join(L,gi),{contentsOnly:!0}),await Ef(L,{contentsOnly:K.linkType===gt.HARD});else{vce(K.locator,J.locator)||await Ef(L,{contentsOnly:K.linkType===gt.HARD});for(let[ne,q]of K.children){let A=J.children.get(ne);await d(v.join(L,ne),q,A)}}};for(let[L,K]of u){let J=l.get(L);for(let[ne,q]of K.children){if(ne===".")continue;let A=J&&J.children.get(ne);await d(v.join(L,ne),q,A)}}let m=new Map,I=[];for(let[L,{locations:K}]of t.locatorMap.entries())for(let J of K){let{locationRoot:ne,segments:q}=$0(J,{skipPrefix:i.cwd}),A=u.get(ne),V=ne;if(A){for(let W of q)if(V=v.join(V,W),A=A.children.get(W),!A)break;if(A){let W=vce(A.locator,L),X=e.get(A.locator),F=X.target,D=V,he=X.linkType;if(W)m.has(F)||m.set(F,D);else if(F!==D){let pe=S.parseLocator(A.locator);S.isVirtualLocator(pe)&&(pe=S.devirtualizeLocator(pe)),I.push({srcDir:F,dstDir:D,linkType:he,realLocatorHash:pe.locatorHash})}}}}for(let[L,{locations:K}]of e.entries())for(let J of K){let{locationRoot:ne,segments:q}=$0(J,{skipPrefix:i.cwd}),A=l.get(ne),V=u.get(ne),W=ne,X=e.get(L),F=S.parseLocator(L);S.isVirtualLocator(F)&&(F=S.devirtualizeLocator(F));let D=F.locatorHash,he=X.target,pe=J;if(he===pe)continue;let Ne=X.linkType;for(let Pe of q)V=V.children.get(Pe);if(!A)I.push({srcDir:he,dstDir:pe,linkType:Ne,realLocatorHash:D});else for(let Pe of q)if(W=v.join(W,Pe),A=A.children.get(Pe),!A){I.push({srcDir:he,dstDir:pe,linkType:Ne,realLocatorHash:D});break}}let B=Xi.progressViaCounter(I.length),b=n.reportProgress(B),R=i.configuration.get("nmMode"),H={value:R};try{let L=H.value===Bi.HARDLINKS_GLOBAL?`${dT(i.configuration)}/v1`:null;if(L&&!await T.existsPromise(L)){await T.mkdirpPromise(L);for(let J=0;J<256;J++)await T.mkdirPromise(v.join(L,J.toString(16).padStart(2,"0")))}for(let J of I)(J.linkType===gt.SOFT||!m.has(J.srcDir))&&(m.set(J.srcDir,J.dstDir),await f(_(P({},J),{globalHardlinksStore:L,nmMode:H,packageChecksum:o.get(J.realLocatorHash)||null})));await Promise.all(g),g.length=0;for(let J of I){let ne=m.get(J.srcDir);J.linkType!==gt.SOFT&&J.dstDir!==ne&&await h(ne,J.dstDir,{nmMode:H})}await Promise.all(g),await T.mkdirPromise(a,{recursive:!0});let K=await H6e(e,u,i.cwd,{loadManifest:s});await G6e(c,K,i.cwd),await M6e(i,e,K,H),R==Bi.HARDLINKS_GLOBAL&&H.value==Bi.HARDLINKS_LOCAL&&n.reportWarningOnce(z.NM_HARDLINKS_MODE_DOWNGRADED,"'nmMode' has been downgraded to 'hardlinks-local' due to global cache and install folder being on different devices")}finally{b.stop()}}async function G6e(t,e,r){for(let i of t.keys()){if(v.contains(r,i)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${i}`);if(!e.has(i)){let n=v.join(i,gi,gT);await T.removePromise(n)}}for(let[i,n]of e){if(v.contains(r,i)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${i}`);let s=v.join(i,gi,gT),o=t.get(i)||new Map;await T.mkdirPromise(s,{recursive:!0});for(let a of o.keys())n.has(a)||(await T.removePromise(v.join(s,a)),process.platform==="win32"&&await T.removePromise(v.join(s,kr(`${a}.cmd`))));for(let[a,l]of n){let c=o.get(a),u=v.join(s,a);c!==l&&(process.platform==="win32"?await(0,Cce.default)(M.fromPortablePath(l),M.fromPortablePath(u),{createPwshFile:!1}):(await T.removePromise(u),await pT(l,u),v.contains(r,await T.realpathPromise(l))!==null&&await T.chmodPromise(l,493)))}}}var CT=class extends jc{constructor(){super(...arguments);this.mode="loose"}makeInstaller(e){return new Sce(e)}},Sce=class extends Cf{constructor(){super(...arguments);this.mode="loose"}async transformPnpSettings(e){let r=new Pr({baseFs:new Jn({libzip:await $i(),maxOpenFiles:80,readOnlyArchives:!0})}),i=ice(e,this.opts.project.cwd,r),{tree:n,errors:s}=VC(i,{pnpifyFs:!1,project:this.opts.project});if(!n){for(let{messageName:u,text:g}of s)this.opts.report.reportError(u,g);return}let o=new Map;e.fallbackPool=o;let a=(u,g)=>{let f=S.parseLocator(g.locator),h=S.stringifyIdent(f);h===u?o.set(u,f.reference):o.set(u,[h,f.reference])},l=v.join(this.opts.project.cwd,wt.nodeModules),c=n.get(l);if(typeof c!="undefined"){if("target"in c)throw new Error("Assertion failed: Expected the root junction point to be a directory");for(let u of c.dirList){let g=v.join(l,u),f=n.get(g);if(typeof f=="undefined")throw new Error("Assertion failed: Expected the child to have been registered");if("target"in f)a(u,f);else for(let h of f.dirList){let p=v.join(g,h),d=n.get(p);if(typeof d=="undefined")throw new Error("Assertion failed: Expected the subchild to have been registered");if("target"in d)a(`${u}/${h}`,d);else throw new Error("Assertion failed: Expected the leaf junction to be a package")}}}}};var j6e={hooks:{cleanGlobalArtifacts:async t=>{let e=dT(t);await T.removePromise(e)}},configuration:{nmHoistingLimits:{description:"Prevent packages to be hoisted past specific levels",type:ge.STRING,values:[Sn.WORKSPACES,Sn.DEPENDENCIES,Sn.NONE],default:Sn.NONE},nmMode:{description:'If set to "hardlinks-local" Yarn will utilize hardlinks to reduce disk space consumption inside "node_modules" directories. With "hardlinks-global" Yarn will use global content addressable storage to reduce "node_modules" size across all the projects using this option.',type:ge.STRING,values:[Bi.CLASSIC,Bi.HARDLINKS_LOCAL,Bi.HARDLINKS_GLOBAL],default:Bi.CLASSIC},nmSelfReferences:{description:"If set to 'false' the workspace will not be allowed to require itself and corresponding self-referencing symlink will not be created",type:ge.BOOLEAN,default:!0}},linkers:[fT,CT]},Y6e=j6e;var yM={};it(yM,{default:()=>Z7e,npmConfigUtils:()=>gr,npmHttpUtils:()=>Lt,npmPublishUtils:()=>Rf});var Rce=ie(Or());var ir="npm:";var Lt={};it(Lt,{AuthType:()=>jn,customPackageError:()=>W6e,del:()=>_6e,get:()=>zs,getIdentUrl:()=>zA,handleInvalidAuthenticationError:()=>WA,post:()=>z6e,put:()=>V6e});var Pce=ie(aC()),Dce=ie(require("url"));var gr={};it(gr,{RegistryType:()=>ja,getAuditRegistry:()=>q6e,getAuthConfiguration:()=>IT,getDefaultRegistry:()=>eQ,getPublishRegistry:()=>xce,getRegistryConfiguration:()=>kce,getScopeConfiguration:()=>ET,getScopeRegistry:()=>Ya,normalizeRegistry:()=>To});var ja;(function(i){i.AUDIT_REGISTRY="npmAuditRegistry",i.FETCH_REGISTRY="npmRegistryServer",i.PUBLISH_REGISTRY="npmPublishRegistry"})(ja||(ja={}));function To(t){return t.replace(/\/$/,"")}function q6e(t,{configuration:e}){let r=e.get(ja.AUDIT_REGISTRY);return r!==null?To(r):xce(t,{configuration:e})}function xce(t,{configuration:e}){var r;return((r=t.publishConfig)==null?void 0:r.registry)?To(t.publishConfig.registry):t.name?Ya(t.name.scope,{configuration:e,type:ja.PUBLISH_REGISTRY}):eQ({configuration:e,type:ja.PUBLISH_REGISTRY})}function Ya(t,{configuration:e,type:r=ja.FETCH_REGISTRY}){let i=ET(t,{configuration:e});if(i===null)return eQ({configuration:e,type:r});let n=i.get(r);return n===null?eQ({configuration:e,type:r}):To(n)}function eQ({configuration:t,type:e=ja.FETCH_REGISTRY}){let r=t.get(e);return To(r!==null?r:t.get(ja.FETCH_REGISTRY))}function kce(t,{configuration:e}){let r=e.get("npmRegistries"),i=To(t),n=r.get(i);if(typeof n!="undefined")return n;let s=r.get(i.replace(/^[a-z]+:/,""));return typeof s!="undefined"?s:null}function ET(t,{configuration:e}){if(t===null)return null;let i=e.get("npmScopes").get(t);return i||null}function IT(t,{configuration:e,ident:r}){let i=r&&ET(r.scope,{configuration:e});return(i==null?void 0:i.get("npmAuthIdent"))||(i==null?void 0:i.get("npmAuthToken"))?i:kce(t,{configuration:e})||e}var jn;(function(n){n[n.NO_AUTH=0]="NO_AUTH",n[n.BEST_EFFORT=1]="BEST_EFFORT",n[n.CONFIGURATION=2]="CONFIGURATION",n[n.ALWAYS_AUTH=3]="ALWAYS_AUTH"})(jn||(jn={}));async function WA(t,{attemptedAs:e,registry:r,headers:i,configuration:n}){var s,o;if(((s=t.originalError)==null?void 0:s.name)==="HTTPError"&&((o=t.originalError)==null?void 0:o.response.statusCode)===401)throw new nt(z.AUTHENTICATION_INVALID,`Invalid authentication (${typeof e!="string"?`as ${await J6e(r,i,{configuration:n})}`:`attempted as ${e}`})`)}function W6e(t){var e;return((e=t.response)==null?void 0:e.statusCode)===404?"Package not found":null}function zA(t){return t.scope?`/@${t.scope}%2f${t.name}`:`/${t.name}`}async function zs(t,a){var l=a,{configuration:e,headers:r,ident:i,authType:n,registry:s}=l,o=qr(l,["configuration","headers","ident","authType","registry"]);if(i&&typeof s=="undefined"&&(s=Ya(i.scope,{configuration:e})),i&&i.scope&&typeof n=="undefined"&&(n=1),typeof s!="string")throw new Error("Assertion failed: The registry should be a string");let c=await tQ(s,{authType:n,configuration:e,ident:i});c&&(r=_(P({},r),{authorization:c}));try{return await Zt.get(t.charAt(0)==="/"?`${s}${t}`:t,P({configuration:e,headers:r},o))}catch(u){throw await WA(u,{registry:s,configuration:e,headers:r}),u}}async function z6e(t,e,c){var u=c,{attemptedAs:r,configuration:i,headers:n,ident:s,authType:o=3,registry:a}=u,l=qr(u,["attemptedAs","configuration","headers","ident","authType","registry"]);if(s&&typeof a=="undefined"&&(a=Ya(s.scope,{configuration:i})),typeof a!="string")throw new Error("Assertion failed: The registry should be a string");let g=await tQ(a,{authType:o,configuration:i,ident:s});g&&(n=_(P({},n),{authorization:g}));try{return await Zt.post(a+t,e,P({configuration:i,headers:n},l))}catch(f){if(!wT(f))throw await WA(f,{attemptedAs:r,registry:a,configuration:i,headers:n}),f;let h=await yT(),p=P(P({},n),BT(h));try{return await Zt.post(`${a}${t}`,e,P({configuration:i,headers:p},l))}catch(d){throw await WA(d,{attemptedAs:r,registry:a,configuration:i,headers:n}),d}}}async function V6e(t,e,c){var u=c,{attemptedAs:r,configuration:i,headers:n,ident:s,authType:o=3,registry:a}=u,l=qr(u,["attemptedAs","configuration","headers","ident","authType","registry"]);if(s&&typeof a=="undefined"&&(a=Ya(s.scope,{configuration:i})),typeof a!="string")throw new Error("Assertion failed: The registry should be a string");let g=await tQ(a,{authType:o,configuration:i,ident:s});g&&(n=_(P({},n),{authorization:g}));try{return await Zt.put(a+t,e,P({configuration:i,headers:n},l))}catch(f){if(!wT(f))throw await WA(f,{attemptedAs:r,registry:a,configuration:i,headers:n}),f;let h=await yT(),p=P(P({},n),BT(h));try{return await Zt.put(`${a}${t}`,e,P({configuration:i,headers:p},l))}catch(d){throw await WA(d,{attemptedAs:r,registry:a,configuration:i,headers:n}),d}}}async function _6e(t,l){var c=l,{attemptedAs:e,configuration:r,headers:i,ident:n,authType:s=3,registry:o}=c,a=qr(c,["attemptedAs","configuration","headers","ident","authType","registry"]);if(n&&typeof o=="undefined"&&(o=Ya(n.scope,{configuration:r})),typeof o!="string")throw new Error("Assertion failed: The registry should be a string");let u=await tQ(o,{authType:s,configuration:r,ident:n});u&&(i=_(P({},i),{authorization:u}));try{return await Zt.del(o+t,P({configuration:r,headers:i},a))}catch(g){if(!wT(g))throw await WA(g,{attemptedAs:e,registry:o,configuration:r,headers:i}),g;let f=await yT(),h=P(P({},i),BT(f));try{return await Zt.del(`${o}${t}`,P({configuration:r,headers:h},a))}catch(p){throw await WA(p,{attemptedAs:e,registry:o,configuration:r,headers:i}),p}}}async function tQ(t,{authType:e=2,configuration:r,ident:i}){let n=IT(t,{configuration:r,ident:i}),s=X6e(n,e);if(!s)return null;let o=await r.reduceHook(a=>a.getNpmAuthenticationHeader,void 0,t,{configuration:r,ident:i});if(o)return o;if(n.get("npmAuthToken"))return`Bearer ${n.get("npmAuthToken")}`;if(n.get("npmAuthIdent")){let a=n.get("npmAuthIdent");return a.includes(":")?`Basic ${Buffer.from(a).toString("base64")}`:`Basic ${a}`}if(s&&e!==1)throw new nt(z.AUTHENTICATION_NOT_FOUND,"No authentication configured for request");return null}function X6e(t,e){switch(e){case 2:return t.get("npmAlwaysAuth");case 1:case 3:return!0;case 0:return!1;default:throw new Error("Unreachable")}}async function J6e(t,e,{configuration:r}){var i;if(typeof e=="undefined"||typeof e.authorization=="undefined")return"an anonymous user";try{return(i=(await Zt.get(new Dce.URL(`${t}/-/whoami`).href,{configuration:r,headers:e,jsonResponse:!0})).username)!=null?i:"an unknown user"}catch{return"an unknown user"}}async function yT(){if(process.env.TEST_ENV)return process.env.TEST_NPM_2FA_TOKEN||"";let{otp:t}=await(0,Pce.prompt)({type:"password",name:"otp",message:"One-time password:",required:!0,onCancel:()=>process.exit(130)});return t}function wT(t){var e,r;if(((e=t.originalError)==null?void 0:e.name)!=="HTTPError")return!1;try{return((r=t.originalError)==null?void 0:r.response.headers["www-authenticate"].split(/,\s*/).map(n=>n.toLowerCase())).includes("otp")}catch(i){return!1}}function BT(t){return{["npm-otp"]:t}}var QT=class{supports(e,r){if(!e.reference.startsWith(ir))return!1;let{selector:i,params:n}=S.parseRange(e.reference);return!(!Rce.default.valid(i)||n===null||typeof n.__archiveUrl!="string")}getLocalPath(e,r){return null}async fetch(e,r){let i=r.checksums.get(e.locatorHash)||null,[n,s,o]=await r.cache.fetchPackageFromCache(e,i,P({onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${S.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,r),skipIntegrityCheck:r.skipIntegrityCheck},r.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:S.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,r){let{params:i}=S.parseRange(e.reference);if(i===null||typeof i.__archiveUrl!="string")throw new Error("Assertion failed: The archiveUrl querystring parameter should have been available");let n=await zs(i.__archiveUrl,{configuration:r.project.configuration,ident:e});return await Ai.convertToZip(n,{compressionLevel:r.project.configuration.get("compressionLevel"),prefixPath:S.getIdentVendorPath(e),stripComponents:1})}};var bT=class{supportsDescriptor(e,r){return!(!e.range.startsWith(ir)||!S.tryParseDescriptor(e.range.slice(ir.length),!0))}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Unreachable")}bindDescriptor(e,r,i){return e}getResolutionDependencies(e,r){let i=S.parseDescriptor(e.range.slice(ir.length),!0);return r.resolver.getResolutionDependencies(i,r)}async getCandidates(e,r,i){let n=S.parseDescriptor(e.range.slice(ir.length),!0);return await i.resolver.getCandidates(n,r,i)}async getSatisfying(e,r,i){let n=S.parseDescriptor(e.range.slice(ir.length),!0);return i.resolver.getSatisfying(n,r,i)}resolve(e,r){throw new Error("Unreachable")}};var vT=ie(Or()),Fce=ie(require("url"));var Vs=class{supports(e,r){if(!e.reference.startsWith(ir))return!1;let i=new Fce.URL(e.reference);return!(!vT.default.valid(i.pathname)||i.searchParams.has("__archiveUrl"))}getLocalPath(e,r){return null}async fetch(e,r){let i=r.checksums.get(e.locatorHash)||null,[n,s,o]=await r.cache.fetchPackageFromCache(e,i,P({onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${S.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote registry`),loader:()=>this.fetchFromNetwork(e,r),skipIntegrityCheck:r.skipIntegrityCheck},r.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:S.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,r){let i;try{i=await zs(Vs.getLocatorUrl(e),{configuration:r.project.configuration,ident:e})}catch(n){i=await zs(Vs.getLocatorUrl(e).replace(/%2f/g,"/"),{configuration:r.project.configuration,ident:e})}return await Ai.convertToZip(i,{compressionLevel:r.project.configuration.get("compressionLevel"),prefixPath:S.getIdentVendorPath(e),stripComponents:1})}static isConventionalTarballUrl(e,r,{configuration:i}){let n=Ya(e.scope,{configuration:i}),s=Vs.getLocatorUrl(e);return r=r.replace(/^https?:(\/\/(?:[^/]+\.)?npmjs.org(?:$|\/))/,"https:$1"),n=n.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),r=r.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),r===n+s||r===n+s.replace(/%2f/g,"/")}static getLocatorUrl(e){let r=vT.default.clean(e.reference.slice(ir.length));if(r===null)throw new nt(z.RESOLVER_NOT_FOUND,"The npm semver resolver got selected, but the version isn't semver");return`${zA(e)}/-/${e.name}-${r}.tgz`}};var ST=ie(Or());var rQ=S.makeIdent(null,"node-gyp"),Z6e=/\b(node-gyp|prebuild-install)\b/,xT=class{supportsDescriptor(e,r){return e.range.startsWith(ir)?!!qt.validRange(e.range.slice(ir.length)):!1}supportsLocator(e,r){if(!e.reference.startsWith(ir))return!1;let{selector:i}=S.parseRange(e.reference);return!!ST.default.valid(i)}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,i){return e}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){let n=qt.validRange(e.range.slice(ir.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(ir.length)}`);let s=await zs(zA(e),{configuration:i.project.configuration,ident:e,jsonResponse:!0}),o=de.mapAndFilter(Object.keys(s.versions),c=>{try{let u=new qt.SemVer(c);if(n.test(u))return u}catch{}return de.mapAndFilter.skip}),a=o.filter(c=>!s.versions[c.raw].deprecated),l=a.length>0?a:o;return l.sort((c,u)=>-c.compare(u)),l.map(c=>{let u=S.makeLocator(e,`${ir}${c.raw}`),g=s.versions[c.raw].dist.tarball;return Vs.isConventionalTarballUrl(u,g,{configuration:i.project.configuration})?u:S.bindLocator(u,{__archiveUrl:g})})}async getSatisfying(e,r,i){let n=qt.validRange(e.range.slice(ir.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(ir.length)}`);return de.mapAndFilter(r,s=>{try{let{selector:o}=S.parseRange(s,{requireProtocol:ir}),a=new qt.SemVer(o);if(n.test(a))return{reference:s,version:a}}catch{}return de.mapAndFilter.skip}).sort((s,o)=>-s.version.compare(o.version)).map(({reference:s})=>S.makeLocator(e,s))}async resolve(e,r){let{selector:i}=S.parseRange(e.reference),n=ST.default.clean(i);if(n===null)throw new nt(z.RESOLVER_NOT_FOUND,"The npm semver resolver got selected, but the version isn't semver");let s=await zs(zA(e),{configuration:r.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(s,"versions"))throw new nt(z.REMOTE_INVALID,'Registry returned invalid data for - missing "versions" field');if(!Object.prototype.hasOwnProperty.call(s.versions,n))throw new nt(z.REMOTE_NOT_FOUND,`Registry failed to return reference "${n}"`);let o=new Ze;if(o.load(s.versions[n]),!o.dependencies.has(rQ.identHash)&&!o.peerDependencies.has(rQ.identHash)){for(let a of o.scripts.values())if(a.match(Z6e)){o.dependencies.set(rQ.identHash,S.makeDescriptor(rQ,"latest")),r.report.reportWarningOnce(z.NODE_GYP_INJECTED,`${S.prettyLocator(r.project.configuration,e)}: Implicit dependencies on node-gyp are discouraged`);break}}return typeof o.raw.deprecated=="string"&&r.report.reportWarningOnce(z.DEPRECATED_PACKAGE,`${S.prettyLocator(r.project.configuration,e)} is deprecated: ${o.raw.deprecated}`),_(P({},e),{version:n,languageName:"node",linkType:gt.HARD,conditions:o.getConditions(),dependencies:o.dependencies,peerDependencies:o.peerDependencies,dependenciesMeta:o.dependenciesMeta,peerDependenciesMeta:o.peerDependenciesMeta,bin:o.bin})}};var kT=class{supportsDescriptor(e,r){return!(!e.range.startsWith(ir)||!Rg.test(e.range.slice(ir.length)))}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Unreachable")}bindDescriptor(e,r,i){return e}getResolutionDependencies(e,r){return[]}async getCandidates(e,r,i){let n=e.range.slice(ir.length),s=await zs(zA(e),{configuration:i.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(s,"dist-tags"))throw new nt(z.REMOTE_INVALID,'Registry returned invalid data - missing "dist-tags" field');let o=s["dist-tags"];if(!Object.prototype.hasOwnProperty.call(o,n))throw new nt(z.REMOTE_NOT_FOUND,`Registry failed to return tag "${n}"`);let a=o[n],l=S.makeLocator(e,`${ir}${a}`),c=s.versions[a].dist.tarball;return Vs.isConventionalTarballUrl(l,c,{configuration:i.project.configuration})?[l]:[S.bindLocator(l,{__archiveUrl:c})]}async getSatisfying(e,r,i){return null}async resolve(e,r){throw new Error("Unreachable")}};var Rf={};it(Rf,{getGitHead:()=>_7e,makePublishBody:()=>V7e});var CM={};it(CM,{default:()=>D7e,packUtils:()=>za});var za={};it(za,{genPackList:()=>QQ,genPackStream:()=>dM,genPackageManifest:()=>age,hasPackScripts:()=>hM,prepareForPack:()=>pM});var fM=ie(Nn()),sge=ie(nge()),oge=ie(require("zlib")),I7e=["/package.json","/readme","/readme.*","/license","/license.*","/licence","/licence.*","/changelog","/changelog.*"],y7e=["/package.tgz",".github",".git",".hg","node_modules",".npmignore",".gitignore",".#*",".DS_Store"];async function hM(t){return!!(Kt.hasWorkspaceScript(t,"prepack")||Kt.hasWorkspaceScript(t,"postpack"))}async function pM(t,{report:e},r){await Kt.maybeExecuteWorkspaceLifecycleScript(t,"prepack",{report:e});try{let i=v.join(t.cwd,Ze.fileName);await T.existsPromise(i)&&await t.manifest.loadFile(i,{baseFs:T}),await r()}finally{await Kt.maybeExecuteWorkspaceLifecycleScript(t,"postpack",{report:e})}}async function dM(t,e){var s,o;typeof e=="undefined"&&(e=await QQ(t));let r=new Set;for(let a of(o=(s=t.manifest.publishConfig)==null?void 0:s.executableFiles)!=null?o:new Set)r.add(v.normalize(a));for(let a of t.manifest.bin.values())r.add(v.normalize(a));let i=sge.default.pack();process.nextTick(async()=>{for(let a of e){let l=v.normalize(a),c=v.resolve(t.cwd,l),u=v.join("package",l),g=await T.lstatPromise(c),f={name:u,mtime:new Date(mr.SAFE_TIME*1e3)},h=r.has(l)?493:420,p,d,m=new Promise((B,b)=>{p=B,d=b}),I=B=>{B?d(B):p()};if(g.isFile()){let B;l==="package.json"?B=Buffer.from(JSON.stringify(await age(t),null,2)):B=await T.readFilePromise(c),i.entry(_(P({},f),{mode:h,type:"file"}),B,I)}else g.isSymbolicLink()?i.entry(_(P({},f),{mode:h,type:"symlink",linkname:await T.readlinkPromise(c)}),I):I(new Error(`Unsupported file type ${g.mode} for ${M.fromPortablePath(l)}`));await m}i.finalize()});let n=(0,oge.createGzip)();return i.pipe(n),n}async function age(t){let e=JSON.parse(JSON.stringify(t.manifest.raw));return await t.project.configuration.triggerHook(r=>r.beforeWorkspacePacking,t,e),e}async function QQ(t){var g,f,h,p,d,m,I,B;let e=t.project,r=e.configuration,i={accept:[],reject:[]};for(let b of y7e)i.reject.push(b);for(let b of I7e)i.accept.push(b);i.reject.push(r.get("rcFilename"));let n=b=>{if(b===null||!b.startsWith(`${t.cwd}/`))return;let R=v.relative(t.cwd,b),H=v.resolve(Se.root,R);i.reject.push(H)};n(v.resolve(e.cwd,r.get("lockfileFilename"))),n(r.get("cacheFolder")),n(r.get("globalFolder")),n(r.get("installStatePath")),n(r.get("virtualFolder")),n(r.get("yarnPath")),await r.triggerHook(b=>b.populateYarnPaths,e,b=>{n(b)});for(let b of e.workspaces){let R=v.relative(t.cwd,b.cwd);R!==""&&!R.match(/^(\.\.)?\//)&&i.reject.push(`/${R}`)}let s={accept:[],reject:[]},o=(f=(g=t.manifest.publishConfig)==null?void 0:g.main)!=null?f:t.manifest.main,a=(p=(h=t.manifest.publishConfig)==null?void 0:h.module)!=null?p:t.manifest.module,l=(m=(d=t.manifest.publishConfig)==null?void 0:d.browser)!=null?m:t.manifest.browser,c=(B=(I=t.manifest.publishConfig)==null?void 0:I.bin)!=null?B:t.manifest.bin;o!=null&&s.accept.push(v.resolve(Se.root,o)),a!=null&&s.accept.push(v.resolve(Se.root,a)),typeof l=="string"&&s.accept.push(v.resolve(Se.root,l));for(let b of c.values())s.accept.push(v.resolve(Se.root,b));if(l instanceof Map)for(let[b,R]of l.entries())s.accept.push(v.resolve(Se.root,b)),typeof R=="string"&&s.accept.push(v.resolve(Se.root,R));let u=t.manifest.files!==null;if(u){s.reject.push("/*");for(let b of t.manifest.files)Age(s.accept,b,{cwd:Se.root})}return await w7e(t.cwd,{hasExplicitFileList:u,globalList:i,ignoreList:s})}async function w7e(t,{hasExplicitFileList:e,globalList:r,ignoreList:i}){let n=[],s=new Zo(t),o=[[Se.root,[i]]];for(;o.length>0;){let[a,l]=o.pop(),c=await s.lstatPromise(a);if(!cge(a,{globalList:r,ignoreLists:c.isDirectory()?null:l}))if(c.isDirectory()){let u=await s.readdirPromise(a),g=!1,f=!1;if(!e||a!==Se.root)for(let d of u)g=g||d===".gitignore",f=f||d===".npmignore";let h=f?await lge(s,a,".npmignore"):g?await lge(s,a,".gitignore"):null,p=h!==null?[h].concat(l):l;cge(a,{globalList:r,ignoreLists:l})&&(p=[...l,{accept:[],reject:["**/*"]}]);for(let d of u)o.push([v.resolve(a,d),p])}else(c.isFile()||c.isSymbolicLink())&&n.push(v.relative(Se.root,a))}return n.sort()}async function lge(t,e,r){let i={accept:[],reject:[]},n=await t.readFilePromise(v.join(e,r),"utf8");for(let s of n.split(/\n/g))Age(i.reject,s,{cwd:e});return i}function B7e(t,{cwd:e}){let r=t[0]==="!";return r&&(t=t.slice(1)),t.match(/\.{0,1}\//)&&(t=v.resolve(e,t)),r&&(t=`!${t}`),t}function Age(t,e,{cwd:r}){let i=e.trim();i===""||i[0]==="#"||t.push(B7e(i,{cwd:r}))}function cge(t,{globalList:e,ignoreLists:r}){if(bQ(t,e.accept))return!1;if(bQ(t,e.reject))return!0;if(r!==null)for(let i of r){if(bQ(t,i.accept))return!1;if(bQ(t,i.reject))return!0}return!1}function bQ(t,e){let r=e,i=[];for(let n=0;n{await pM(i,{report:l},async()=>{l.reportJson({base:M.fromPortablePath(i.cwd)});let c=await QQ(i);for(let u of c)l.reportInfo(null,M.fromPortablePath(u)),l.reportJson({location:M.fromPortablePath(u)});if(!this.dryRun){let u=await dM(i,c),g=T.createWriteStream(s);u.pipe(g),await new Promise(f=>{g.on("finish",f)})}}),this.dryRun||(l.reportInfo(z.UNNAMED,`Package archive generated in ${ue.pretty(e,s,ue.Type.PATH)}`),l.reportJson({output:M.fromPortablePath(s)}))})).exitCode()}};fm.paths=[["pack"]],fm.usage=ye.Usage({description:"generate a tarball from the active workspace",details:"\n This command will turn the active workspace into a compressed archive suitable for publishing. The archive will by default be stored at the root of the workspace (`package.tgz`).\n\n If the `-o,---out` is set the archive will be created at the specified path. The `%s` and `%v` variables can be used within the path and will be respectively replaced by the package name and version.\n ",examples:[["Create an archive from the active workspace","yarn pack"],["List the files that would be made part of the workspace's archive","yarn pack --dry-run"],["Name and output the archive in a dedicated folder","yarn pack --out /artifacts/%s-%v.tgz"]]});var gge=fm;function Q7e(t,{workspace:e}){let r=t.replace("%s",b7e(e)).replace("%v",v7e(e));return M.toPortablePath(r)}function b7e(t){return t.manifest.name!==null?S.slugifyIdent(t.manifest.name):"package"}function v7e(t){return t.manifest.version!==null?t.manifest.version:"unknown"}var S7e=["dependencies","devDependencies","peerDependencies"],x7e="workspace:",k7e=(t,e)=>{var i,n;e.publishConfig&&(e.publishConfig.main&&(e.main=e.publishConfig.main),e.publishConfig.browser&&(e.browser=e.publishConfig.browser),e.publishConfig.module&&(e.module=e.publishConfig.module),e.publishConfig.browser&&(e.browser=e.publishConfig.browser),e.publishConfig.exports&&(e.exports=e.publishConfig.exports),e.publishConfig.bin&&(e.bin=e.publishConfig.bin));let r=t.project;for(let s of S7e)for(let o of t.manifest.getForScope(s).values()){let a=r.tryWorkspaceByDescriptor(o),l=S.parseRange(o.range);if(l.protocol===x7e)if(a===null){if(r.tryWorkspaceByIdent(o)===null)throw new nt(z.WORKSPACE_NOT_FOUND,`${S.prettyDescriptor(r.configuration,o)}: No local workspace found for this range`)}else{let c;S.areDescriptorsEqual(o,a.anchoredDescriptor)||l.selector==="*"?c=(i=a.manifest.version)!=null?i:"0.0.0":l.selector==="~"||l.selector==="^"?c=`${l.selector}${(n=a.manifest.version)!=null?n:"0.0.0"}`:c=l.selector,e[s][S.stringifyIdent(o)]=c}}},P7e={hooks:{beforeWorkspacePacking:k7e},commands:[gge]},D7e=P7e;var yge=ie(require("crypto")),wge=ie(Ige()),Bge=ie(require("url"));async function V7e(t,e,{access:r,tag:i,registry:n,gitHead:s}){let o=t.project.configuration,a=t.manifest.name,l=t.manifest.version,c=S.stringifyIdent(a),u=(0,yge.createHash)("sha1").update(e).digest("hex"),g=wge.default.fromData(e).toString();typeof r=="undefined"&&(t.manifest.publishConfig&&typeof t.manifest.publishConfig.access=="string"?r=t.manifest.publishConfig.access:o.get("npmPublishAccess")!==null?r=o.get("npmPublishAccess"):a.scope?r="restricted":r="public");let f=await za.genPackageManifest(t),h=`${c}-${l}.tgz`,p=new Bge.URL(`${To(n)}/${c}/-/${h}`);return{_id:c,_attachments:{[h]:{content_type:"application/octet-stream",data:e.toString("base64"),length:e.length}},name:c,access:r,["dist-tags"]:{[i]:l},versions:{[l]:_(P({},f),{_id:`${c}@${l}`,name:c,version:l,gitHead:s,dist:{shasum:u,integrity:g,tarball:p.toString()}})}}}async function _7e(t){try{let{stdout:e}=await hr.execvp("git",["rev-parse","--revs-only","HEAD"],{cwd:t});return e.trim()===""?void 0:e.trim()}catch{return}}var wM={npmAlwaysAuth:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:ge.BOOLEAN,default:!1},npmAuthIdent:{description:"Authentication identity for the npm registry (_auth in npm and yarn v1)",type:ge.SECRET,default:null},npmAuthToken:{description:"Authentication token for the npm registry (_authToken in npm and yarn v1)",type:ge.SECRET,default:null}},Qge={npmAuditRegistry:{description:"Registry to query for audit reports",type:ge.STRING,default:null},npmPublishRegistry:{description:"Registry to push packages to",type:ge.STRING,default:null},npmRegistryServer:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:ge.STRING,default:"https://registry.yarnpkg.com"}},X7e={configuration:_(P(P({},wM),Qge),{npmScopes:{description:"Settings per package scope",type:ge.MAP,valueDefinition:{description:"",type:ge.SHAPE,properties:P(P({},wM),Qge)}},npmRegistries:{description:"Settings per registry",type:ge.MAP,normalizeKeys:To,valueDefinition:{description:"",type:ge.SHAPE,properties:P({},wM)}}}),fetchers:[QT,Vs],resolvers:[bT,xT,kT]},Z7e=X7e;var vM={};it(vM,{default:()=>a_e});Ss();var Ho;(function(i){i.All="all",i.Production="production",i.Development="development"})(Ho||(Ho={}));var Xs;(function(s){s.Info="info",s.Low="low",s.Moderate="moderate",s.High="high",s.Critical="critical"})(Xs||(Xs={}));var vQ=[Xs.Info,Xs.Low,Xs.Moderate,Xs.High,Xs.Critical];function bge(t,e){let r=[],i=new Set,n=o=>{i.has(o)||(i.add(o),r.push(o))};for(let o of e)n(o);let s=new Set;for(;r.length>0;){let o=r.shift(),a=t.storedResolutions.get(o);if(typeof a=="undefined")throw new Error("Assertion failed: Expected the resolution to have been registered");let l=t.storedPackages.get(a);if(!!l){s.add(o);for(let c of l.dependencies.values())n(c.descriptorHash)}}return s}function $7e(t,e){return new Set([...t].filter(r=>!e.has(r)))}function e_e(t,e,{all:r}){let i=r?t.workspaces:[e],n=i.map(f=>f.manifest),s=new Set(n.map(f=>[...f.dependencies].map(([h,p])=>h)).flat()),o=new Set(n.map(f=>[...f.devDependencies].map(([h,p])=>h)).flat()),a=i.map(f=>[...f.dependencies.values()]).flat(),l=a.filter(f=>s.has(f.identHash)).map(f=>f.descriptorHash),c=a.filter(f=>o.has(f.identHash)).map(f=>f.descriptorHash),u=bge(t,l),g=bge(t,c);return $7e(g,u)}function vge(t){let e={};for(let r of t)e[S.stringifyIdent(r)]=S.parseRange(r.range).selector;return e}function Sge(t){if(typeof t=="undefined")return new Set;let e=vQ.indexOf(t),r=vQ.slice(e);return new Set(r)}function t_e(t,e){let r=Sge(e),i={};for(let n of r)i[n]=t[n];return i}function xge(t,e){var i;let r=t_e(t,e);for(let n of Object.keys(r))if((i=r[n])!=null?i:0>0)return!0;return!1}function kge(t,e){var s;let r={},i={children:r},n=Object.values(t.advisories);if(e!=null){let o=Sge(e);n=n.filter(a=>o.has(a.severity))}for(let o of de.sortMap(n,a=>a.module_name))r[o.module_name]={label:o.module_name,value:ue.tuple(ue.Type.RANGE,o.findings.map(a=>a.version).join(", ")),children:{Issue:{label:"Issue",value:ue.tuple(ue.Type.NO_HINT,o.title)},URL:{label:"URL",value:ue.tuple(ue.Type.URL,o.url)},Severity:{label:"Severity",value:ue.tuple(ue.Type.NO_HINT,o.severity)},["Vulnerable Versions"]:{label:"Vulnerable Versions",value:ue.tuple(ue.Type.RANGE,o.vulnerable_versions)},["Patched Versions"]:{label:"Patched Versions",value:ue.tuple(ue.Type.RANGE,o.patched_versions)},Via:{label:"Via",value:ue.tuple(ue.Type.NO_HINT,Array.from(new Set(o.findings.map(a=>a.paths).flat().map(a=>a.split(">")[0]))).join(", "))},Recommendation:{label:"Recommendation",value:ue.tuple(ue.Type.NO_HINT,(s=o.recommendation)==null?void 0:s.replace(/\n/g," "))}}};return i}function Pge(t,e,{all:r,environment:i}){let n=r?t.workspaces:[e],s=[Ho.All,Ho.Production].includes(i),o=[];if(s)for(let c of n)for(let u of c.manifest.dependencies.values())o.push(u);let a=[Ho.All,Ho.Development].includes(i),l=[];if(a)for(let c of n)for(let u of c.manifest.devDependencies.values())l.push(u);return vge([...o,...l].filter(c=>S.parseRange(c.range).protocol===null))}function Dge(t,e,{all:r}){var s;let i=e_e(t,e,{all:r}),n={};for(let o of t.storedPackages.values())n[S.stringifyIdent(o)]={version:(s=o.version)!=null?s:"0.0.0",integrity:o.identHash,requires:vge(o.dependencies.values()),dev:i.has(S.convertLocatorToDescriptor(o).descriptorHash)};return n}var dm=class extends Be{constructor(){super(...arguments);this.all=Y.Boolean("-A,--all",!1,{description:"Audit dependencies from all workspaces"});this.recursive=Y.Boolean("-R,--recursive",!1,{description:"Audit transitive dependencies as well"});this.environment=Y.String("--environment",Ho.All,{description:"Which environments to cover",validator:Yi(Ho)});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.severity=Y.String("--severity",Xs.Info,{description:"Minimal severity requested for packages to be displayed",validator:Yi(Xs)})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState();let n=Pge(r,i,{all:this.all,environment:this.environment}),s=Dge(r,i,{all:this.all});if(!this.recursive)for(let f of Object.keys(s))Object.prototype.hasOwnProperty.call(n,f)?s[f].requires={}:delete s[f];let o={requires:n,dependencies:s},a=gr.getAuditRegistry(i.manifest,{configuration:e}),l,c=await Fa.start({configuration:e,stdout:this.context.stdout},async()=>{l=await Lt.post("/-/npm/v1/security/audits/quick",o,{authType:Lt.AuthType.BEST_EFFORT,configuration:e,jsonResponse:!0,registry:a})});if(c.hasErrors())return c.exitCode();let u=xge(l.metadata.vulnerabilities,this.severity);return!this.json&&u?(Hs.emitTree(kge(l,this.severity),{configuration:e,json:this.json,stdout:this.context.stdout,separators:2}),1):(await Fe.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async f=>{f.reportJson(l),u||f.reportInfo(z.EXCEPTION,"No audit suggestions")})).exitCode()}};dm.paths=[["npm","audit"]],dm.usage=ye.Usage({description:"perform a vulnerability audit against the installed packages",details:` + This command checks for known security reports on the packages you use. The reports are by default extracted from the npm registry, and may or may not be relevant to your actual program (not all vulnerabilities affect all code paths). + + For consistency with our other commands the default is to only check the direct dependencies for the active workspace. To extend this search to all workspaces, use \`-A,--all\`. To extend this search to both direct and transitive dependencies, use \`-R,--recursive\`. + + Applying the \`--severity\` flag will limit the audit table to vulnerabilities of the corresponding severity and above. Valid values are ${vQ.map(e=>`\`${e}\``).join(", ")}. + + If the \`--json\` flag is set, Yarn will print the output exactly as received from the registry. Regardless of this flag, the process will exit with a non-zero exit code if a report is found for the selected packages. + + To understand the dependency tree requiring vulnerable packages, check the raw report with the \`--json\` flag or use \`yarn why \` to get more information as to who depends on them. + `,examples:[["Checks for known security issues with the installed packages. The output is a list of known issues.","yarn npm audit"],["Audit dependencies in all workspaces","yarn npm audit --all"],["Limit auditing to `dependencies` (excludes `devDependencies`)","yarn npm audit --environment production"],["Show audit report as valid JSON","yarn npm audit --json"],["Audit all direct and transitive dependencies","yarn npm audit --recursive"],["Output moderate (or more severe) vulnerabilities","yarn npm audit --severity moderate"]]});var Rge=dm;var BM=ie(Or()),QM=ie(require("util")),Cm=class extends Be{constructor(){super(...arguments);this.fields=Y.String("-f,--fields",{description:"A comma-separated list of manifest fields that should be displayed"});this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.packages=Y.Rest()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r}=await Ke.find(e,this.context.cwd),i=typeof this.fields!="undefined"?new Set(["name",...this.fields.split(/\s*,\s*/)]):null,n=[],s=!1,o=await Fe.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async a=>{for(let l of this.packages){let c;if(l==="."){let b=r.topLevelWorkspace;if(!b.manifest.name)throw new me(`Missing 'name' field in ${M.fromPortablePath(v.join(b.cwd,wt.manifest))}`);c=S.makeDescriptor(b.manifest.name,"unknown")}else c=S.parseDescriptor(l);let u=Lt.getIdentUrl(c),g=bM(await Lt.get(u,{configuration:e,ident:c,jsonResponse:!0,customErrorMessage:Lt.customPackageError})),f=Object.keys(g.versions).sort(BM.default.compareLoose),p=g["dist-tags"].latest||f[f.length-1],d=qt.validRange(c.range);if(d){let b=BM.default.maxSatisfying(f,d);b!==null?p=b:(a.reportWarning(z.UNNAMED,`Unmet range ${S.prettyRange(e,c.range)}; falling back to the latest version`),s=!0)}else c.range!=="unknown"&&(a.reportWarning(z.UNNAMED,`Invalid range ${S.prettyRange(e,c.range)}; falling back to the latest version`),s=!0);let m=g.versions[p],I=_(P(P({},g),m),{version:p,versions:f}),B;if(i!==null){B={};for(let b of i){let R=I[b];if(typeof R!="undefined")B[b]=R;else{a.reportWarning(z.EXCEPTION,`The '${b}' field doesn't exist inside ${S.prettyIdent(e,c)}'s informations`),s=!0;continue}}}else this.json||(delete I.dist,delete I.readme,delete I.users),B=I;a.reportJson(B),this.json||n.push(B)}});QM.inspect.styles.name="cyan";for(let a of n)(a!==n[0]||s)&&this.context.stdout.write(` +`),this.context.stdout.write(`${(0,QM.inspect)(a,{depth:Infinity,colors:!0,compact:!1})} +`);return o.exitCode()}};Cm.paths=[["npm","info"]],Cm.usage=ye.Usage({category:"Npm-related commands",description:"show information about a package",details:"\n This command will fetch information about a package from the npm registry, and prints it in a tree format.\n\n The package does not have to be installed locally, but needs to have been published (in particular, local changes will be ignored even for workspaces).\n\n Append `@` to the package argument to provide information specific to the latest version that satisfies the range. If the range is invalid or if there is no version satisfying the range, the command will print a warning and fall back to the latest version.\n\n If the `-f,--fields` option is set, it's a comma-separated list of fields which will be used to only display part of the package informations.\n\n By default, this command won't return the `dist`, `readme`, and `users` fields, since they are often very long. To explicitly request those fields, explicitly list them with the `--fields` flag or request the output in JSON mode.\n ",examples:[["Show all available information about react (except the `dist`, `readme`, and `users` fields)","yarn npm info react"],["Show all available information about react as valid JSON (including the `dist`, `readme`, and `users` fields)","yarn npm info react --json"],["Show all available information about react 16.12.0","yarn npm info react@16.12.0"],["Show the description of react","yarn npm info react --fields description"],["Show all available versions of react","yarn npm info react --fields versions"],["Show the readme of react","yarn npm info react --fields readme"],["Show a few fields of react","yarn npm info react --fields homepage,repository"]]});var Fge=Cm;function bM(t){if(Array.isArray(t)){let e=[];for(let r of t)r=bM(r),r&&e.push(r);return e}else if(typeof t=="object"&&t!==null){let e={};for(let r of Object.keys(t)){if(r.startsWith("_"))continue;let i=bM(t[r]);i&&(e[r]=i)}return e}else return t||null}var Nge=ie(aC()),mm=class extends Be{constructor(){super(...arguments);this.scope=Y.String("-s,--scope",{description:"Login to the registry configured for a given scope"});this.publish=Y.Boolean("--publish",!1,{description:"Login to the publish registry"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r=await SQ({configuration:e,cwd:this.context.cwd,publish:this.publish,scope:this.scope});return(await Fe.start({configuration:e,stdout:this.context.stdout},async n=>{let s=await i_e({registry:r,report:n,stdin:this.context.stdin,stdout:this.context.stdout}),o=`/-/user/org.couchdb.user:${encodeURIComponent(s.name)}`,a=await Lt.put(o,s,{attemptedAs:s.name,configuration:e,registry:r,jsonResponse:!0,authType:Lt.AuthType.NO_AUTH});return await r_e(r,a.token,{configuration:e,scope:this.scope}),n.reportInfo(z.UNNAMED,"Successfully logged in")})).exitCode()}};mm.paths=[["npm","login"]],mm.usage=ye.Usage({category:"Npm-related commands",description:"store new login info to access the npm registry",details:"\n This command will ask you for your username, password, and 2FA One-Time-Password (when it applies). It will then modify your local configuration (in your home folder, never in the project itself) to reference the new tokens thus generated.\n\n Adding the `-s,--scope` flag will cause the authentication to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the authentication to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n ",examples:[["Login to the default registry","yarn npm login"],["Login to the registry linked to the @my-scope registry","yarn npm login --scope my-scope"],["Login to the publish registry for the current package","yarn npm login --publish"]]});var Lge=mm;async function SQ({scope:t,publish:e,configuration:r,cwd:i}){return t&&e?gr.getScopeRegistry(t,{configuration:r,type:gr.RegistryType.PUBLISH_REGISTRY}):t?gr.getScopeRegistry(t,{configuration:r}):e?gr.getPublishRegistry((await rf(r,i)).manifest,{configuration:r}):gr.getDefaultRegistry({configuration:r})}async function r_e(t,e,{configuration:r,scope:i}){let n=o=>a=>{let l=de.isIndexableObject(a)?a:{},c=l[o],u=de.isIndexableObject(c)?c:{};return _(P({},l),{[o]:_(P({},u),{npmAuthToken:e})})},s=i?{npmScopes:n(i)}:{npmRegistries:n(t)};return await fe.updateHomeConfiguration(s)}async function i_e({registry:t,report:e,stdin:r,stdout:i}){if(process.env.TEST_ENV)return{name:process.env.TEST_NPM_USER||"",password:process.env.TEST_NPM_PASSWORD||""};e.reportInfo(z.UNNAMED,`Logging in to ${t}`);let n=!1;t.match(/^https:\/\/npm\.pkg\.github\.com(\/|$)/)&&(e.reportInfo(z.UNNAMED,"You seem to be using the GitHub Package Registry. Tokens must be generated with the 'repo', 'write:packages', and 'read:packages' permissions."),n=!0),e.reportSeparator();let{username:s,password:o}=await(0,Nge.prompt)([{type:"input",name:"username",message:"Username:",required:!0,onCancel:()=>process.exit(130),stdin:r,stdout:i},{type:"password",name:"password",message:n?"Token:":"Password:",required:!0,onCancel:()=>process.exit(130),stdin:r,stdout:i}]);return e.reportSeparator(),{name:s,password:o}}var Ff=new Set(["npmAuthIdent","npmAuthToken"]),Em=class extends Be{constructor(){super(...arguments);this.scope=Y.String("-s,--scope",{description:"Logout of the registry configured for a given scope"});this.publish=Y.Boolean("--publish",!1,{description:"Logout of the publish registry"});this.all=Y.Boolean("-A,--all",!1,{description:"Logout of all registries"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r=async()=>{var l;let n=await SQ({configuration:e,cwd:this.context.cwd,publish:this.publish,scope:this.scope}),s=await fe.find(this.context.cwd,this.context.plugins),o=S.makeIdent((l=this.scope)!=null?l:null,"pkg");return!gr.getAuthConfiguration(n,{configuration:s,ident:o}).get("npmAuthToken")};return(await Fe.start({configuration:e,stdout:this.context.stdout},async n=>{if(this.all&&(await n_e(),n.reportInfo(z.UNNAMED,"Successfully logged out from everything")),this.scope){await Tge("npmScopes",this.scope),await r()?n.reportInfo(z.UNNAMED,`Successfully logged out from ${this.scope}`):n.reportWarning(z.UNNAMED,"Scope authentication settings removed, but some other ones settings still apply to it");return}let s=await SQ({configuration:e,cwd:this.context.cwd,publish:this.publish});await Tge("npmRegistries",s),await r()?n.reportInfo(z.UNNAMED,`Successfully logged out from ${s}`):n.reportWarning(z.UNNAMED,"Registry authentication settings removed, but some other ones settings still apply to it")})).exitCode()}};Em.paths=[["npm","logout"]],Em.usage=ye.Usage({category:"Npm-related commands",description:"logout of the npm registry",details:"\n This command will log you out by modifying your local configuration (in your home folder, never in the project itself) to delete all credentials linked to a registry.\n\n Adding the `-s,--scope` flag will cause the deletion to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the deletion to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n\n Adding the `-A,--all` flag will cause the deletion to be done against all registries and scopes.\n ",examples:[["Logout of the default registry","yarn npm logout"],["Logout of the @my-scope scope","yarn npm logout --scope my-scope"],["Logout of the publish registry for the current package","yarn npm logout --publish"],["Logout of all registries","yarn npm logout --all"]]});var Mge=Em;function s_e(t,e){let r=t[e];if(!de.isIndexableObject(r))return!1;let i=new Set(Object.keys(r));if([...Ff].every(s=>!i.has(s)))return!1;for(let s of Ff)i.delete(s);if(i.size===0)return t[e]=void 0,!0;let n=P({},r);for(let s of Ff)delete n[s];return t[e]=n,!0}async function n_e(){let t=e=>{let r=!1,i=de.isIndexableObject(e)?P({},e):{};i.npmAuthToken&&(delete i.npmAuthToken,r=!0);for(let n of Object.keys(i))s_e(i,n)&&(r=!0);if(Object.keys(i).length!==0)return r?i:e};return await fe.updateHomeConfiguration({npmRegistries:t,npmScopes:t})}async function Tge(t,e){return await fe.updateHomeConfiguration({[t]:r=>{let i=de.isIndexableObject(r)?r:{};if(!Object.prototype.hasOwnProperty.call(i,e))return r;let n=i[e],s=de.isIndexableObject(n)?n:{},o=new Set(Object.keys(s));if([...Ff].every(l=>!o.has(l)))return r;for(let l of Ff)o.delete(l);if(o.size===0)return Object.keys(i).length===1?void 0:_(P({},i),{[e]:void 0});let a={};for(let l of Ff)a[l]=void 0;return _(P({},i),{[e]:P(P({},s),a)})}})}var Im=class extends Be{constructor(){super(...arguments);this.access=Y.String("--access",{description:"The access for the published package (public or restricted)"});this.tag=Y.String("--tag","latest",{description:"The tag on the registry that the package should be attached to"});this.tolerateRepublish=Y.Boolean("--tolerate-republish",!1,{description:"Warn and exit when republishing an already existing version of a package"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd);if(!i)throw new rt(r.cwd,this.context.cwd);if(i.manifest.private)throw new me("Private workspaces cannot be published");if(i.manifest.name===null||i.manifest.version===null)throw new me("Workspaces must have valid names and versions to be published on an external registry");await r.restoreInstallState();let n=i.manifest.name,s=i.manifest.version,o=gr.getPublishRegistry(i.manifest,{configuration:e});return(await Fe.start({configuration:e,stdout:this.context.stdout},async l=>{var c,u;if(this.tolerateRepublish)try{let g=await Lt.get(Lt.getIdentUrl(n),{configuration:e,registry:o,ident:n,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(g,"versions"))throw new nt(z.REMOTE_INVALID,'Registry returned invalid data for - missing "versions" field');if(Object.prototype.hasOwnProperty.call(g.versions,s)){l.reportWarning(z.UNNAMED,`Registry already knows about version ${s}; skipping.`);return}}catch(g){if(((u=(c=g.originalError)==null?void 0:c.response)==null?void 0:u.statusCode)!==404)throw g}await Kt.maybeExecuteWorkspaceLifecycleScript(i,"prepublish",{report:l}),await za.prepareForPack(i,{report:l},async()=>{let g=await za.genPackList(i);for(let m of g)l.reportInfo(null,m);let f=await za.genPackStream(i,g),h=await de.bufferStream(f),p=await Rf.getGitHead(i.cwd),d=await Rf.makePublishBody(i,h,{access:this.access,tag:this.tag,registry:o,gitHead:p});await Lt.put(Lt.getIdentUrl(n),d,{configuration:e,registry:o,ident:n,jsonResponse:!0})}),l.reportInfo(z.UNNAMED,"Package archive published")})).exitCode()}};Im.paths=[["npm","publish"]],Im.usage=ye.Usage({category:"Npm-related commands",description:"publish the active workspace to the npm registry",details:'\n This command will pack the active workspace into a fresh archive and upload it to the npm registry.\n\n The package will by default be attached to the `latest` tag on the registry, but this behavior can be overriden by using the `--tag` option.\n\n Note that for legacy reasons scoped packages are by default published with an access set to `restricted` (aka "private packages"). This requires you to register for a paid npm plan. In case you simply wish to publish a public scoped package to the registry (for free), just add the `--access public` flag. This behavior can be enabled by default through the `npmPublishAccess` settings.\n ',examples:[["Publish the active workspace","yarn npm publish"]]});var Oge=Im;var Uge=ie(Or());var ym=class extends Be{constructor(){super(...arguments);this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=Y.String({required:!1})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n;if(typeof this.package!="undefined")n=S.parseIdent(this.package);else{if(!i)throw new rt(r.cwd,this.context.cwd);if(!i.manifest.name)throw new me(`Missing 'name' field in ${M.fromPortablePath(v.join(i.cwd,wt.manifest))}`);n=i.manifest.name}let s=await wm(n,e),a={children:de.sortMap(Object.entries(s),([l])=>l).map(([l,c])=>({value:ue.tuple(ue.Type.RESOLUTION,{descriptor:S.makeDescriptor(n,l),locator:S.makeLocator(n,c)})}))};return Hs.emitTree(a,{configuration:e,json:this.json,stdout:this.context.stdout})}};ym.paths=[["npm","tag","list"]],ym.usage=ye.Usage({category:"Npm-related commands",description:"list all dist-tags of a package",details:` + This command will list all tags of a package from the npm registry. + + If the package is not specified, Yarn will default to the current workspace. + `,examples:[["List all tags of package `my-pkg`","yarn npm tag list my-pkg"]]});var Kge=ym;async function wm(t,e){let r=`/-/package${Lt.getIdentUrl(t)}/dist-tags`;return Lt.get(r,{configuration:e,ident:t,jsonResponse:!0,customErrorMessage:Lt.customPackageError})}var Bm=class extends Be{constructor(){super(...arguments);this.package=Y.String();this.tag=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd);if(!i)throw new rt(r.cwd,this.context.cwd);let n=S.parseDescriptor(this.package,!0),s=n.range;if(!Uge.default.valid(s))throw new me(`The range ${ue.pretty(e,n.range,ue.Type.RANGE)} must be a valid semver version`);let o=gr.getPublishRegistry(i.manifest,{configuration:e}),a=ue.pretty(e,n,ue.Type.IDENT),l=ue.pretty(e,s,ue.Type.RANGE),c=ue.pretty(e,this.tag,ue.Type.CODE);return(await Fe.start({configuration:e,stdout:this.context.stdout},async g=>{let f=await wm(n,e);Object.prototype.hasOwnProperty.call(f,this.tag)&&f[this.tag]===s&&g.reportWarning(z.UNNAMED,`Tag ${c} is already set to version ${l}`);let h=`/-/package${Lt.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await Lt.put(h,s,{configuration:e,registry:o,ident:n,jsonRequest:!0,jsonResponse:!0}),g.reportInfo(z.UNNAMED,`Tag ${c} added to version ${l} of package ${a}`)})).exitCode()}};Bm.paths=[["npm","tag","add"]],Bm.usage=ye.Usage({category:"Npm-related commands",description:"add a tag for a specific version of a package",details:` + This command will add a tag to the npm registry for a specific version of a package. If the tag already exists, it will be overwritten. + `,examples:[["Add a `beta` tag for version `2.3.4-beta.4` of package `my-pkg`","yarn npm tag add my-pkg@2.3.4-beta.4 beta"]]});var Hge=Bm;var Qm=class extends Be{constructor(){super(...arguments);this.package=Y.String();this.tag=Y.String()}async execute(){if(this.tag==="latest")throw new me("The 'latest' tag cannot be removed.");let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd);if(!i)throw new rt(r.cwd,this.context.cwd);let n=S.parseIdent(this.package),s=gr.getPublishRegistry(i.manifest,{configuration:e}),o=ue.pretty(e,this.tag,ue.Type.CODE),a=ue.pretty(e,n,ue.Type.IDENT),l=await wm(n,e);if(!Object.prototype.hasOwnProperty.call(l,this.tag))throw new me(`${o} is not a tag of package ${a}`);return(await Fe.start({configuration:e,stdout:this.context.stdout},async u=>{let g=`/-/package${Lt.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await Lt.del(g,{configuration:e,registry:s,ident:n,jsonResponse:!0}),u.reportInfo(z.UNNAMED,`Tag ${o} removed from package ${a}`)})).exitCode()}};Qm.paths=[["npm","tag","remove"]],Qm.usage=ye.Usage({category:"Npm-related commands",description:"remove a tag from a package",details:` + This command will remove a tag from a package from the npm registry. + `,examples:[["Remove the `beta` tag from package `my-pkg`","yarn npm tag remove my-pkg beta"]]});var Gge=Qm;var bm=class extends Be{constructor(){super(...arguments);this.scope=Y.String("-s,--scope",{description:"Print username for the registry configured for a given scope"});this.publish=Y.Boolean("--publish",!1,{description:"Print username for the publish registry"})}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),r;return this.scope&&this.publish?r=gr.getScopeRegistry(this.scope,{configuration:e,type:gr.RegistryType.PUBLISH_REGISTRY}):this.scope?r=gr.getScopeRegistry(this.scope,{configuration:e}):this.publish?r=gr.getPublishRegistry((await rf(e,this.context.cwd)).manifest,{configuration:e}):r=gr.getDefaultRegistry({configuration:e}),(await Fe.start({configuration:e,stdout:this.context.stdout},async n=>{var o,a;let s;try{s=await Lt.get("/-/whoami",{configuration:e,registry:r,authType:Lt.AuthType.ALWAYS_AUTH,jsonResponse:!0,ident:this.scope?S.makeIdent(this.scope,""):void 0})}catch(l){if(((o=l.response)==null?void 0:o.statusCode)===401||((a=l.response)==null?void 0:a.statusCode)===403){n.reportError(z.AUTHENTICATION_INVALID,"Authentication failed - your credentials may have expired");return}else throw l}n.reportInfo(z.UNNAMED,s.username)})).exitCode()}};bm.paths=[["npm","whoami"]],bm.usage=ye.Usage({category:"Npm-related commands",description:"display the name of the authenticated user",details:"\n Print the username associated with the current authentication settings to the standard output.\n\n When using `-s,--scope`, the username printed will be the one that matches the authentication settings of the registry associated with the given scope (those settings can be overriden using the `npmRegistries` map, and the registry associated with the scope is configured via the `npmScopes` map).\n\n When using `--publish`, the registry we'll select will by default be the one used when publishing packages (`publishConfig.registry` or `npmPublishRegistry` if available, otherwise we'll fallback to the regular `npmRegistryServer`).\n ",examples:[["Print username for the default registry","yarn npm whoami"],["Print username for the registry on a given scope","yarn npm whoami --scope company"]]});var jge=bm;var o_e={configuration:{npmPublishAccess:{description:"Default access of the published packages",type:ge.STRING,default:null}},commands:[Rge,Fge,Lge,Mge,Oge,Hge,Kge,Gge,jge]},a_e=o_e;var NM={};it(NM,{default:()=>B_e,patchUtils:()=>SM});var SM={};it(SM,{applyPatchFile:()=>PQ,diffFolders:()=>DM,extractPackageToDisk:()=>PM,extractPatchFlags:()=>Xge,isParentRequired:()=>kM,loadPatchFiles:()=>km,makeDescriptor:()=>I_e,makeLocator:()=>xM,parseDescriptor:()=>Sm,parseLocator:()=>xm,parsePatchFile:()=>kQ});var vm=class extends Error{constructor(e,r){super(`Cannot apply hunk #${e+1}`);this.hunk=r}};var A_e=/^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@.*/;function Nf(t){return v.relative(Se.root,v.resolve(Se.root,M.toPortablePath(t)))}function l_e(t){let e=t.trim().match(A_e);if(!e)throw new Error(`Bad header line: '${t}'`);return{original:{start:Math.max(Number(e[1]),1),length:Number(e[3]||1)},patched:{start:Math.max(Number(e[4]),1),length:Number(e[6]||1)}}}var c_e=420,u_e=493,Lr;(function(i){i.Context="context",i.Insertion="insertion",i.Deletion="deletion"})(Lr||(Lr={}));var Yge=()=>({semverExclusivity:null,diffLineFromPath:null,diffLineToPath:null,oldMode:null,newMode:null,deletedFileMode:null,newFileMode:null,renameFrom:null,renameTo:null,beforeHash:null,afterHash:null,fromPath:null,toPath:null,hunks:null}),g_e=t=>({header:l_e(t),parts:[]}),f_e={["@"]:"header",["-"]:Lr.Deletion,["+"]:Lr.Insertion,[" "]:Lr.Context,["\\"]:"pragma",undefined:Lr.Context};function p_e(t){let e=[],r=Yge(),i="parsing header",n=null,s=null;function o(){n&&(s&&(n.parts.push(s),s=null),r.hunks.push(n),n=null)}function a(){o(),e.push(r),r=Yge()}for(let l=0;l0?"patch":"mode change",B=null;switch(I){case"rename":{if(!u||!g)throw new Error("Bad parser state: rename from & to not given");e.push({type:"rename",semverExclusivity:i,fromPath:Nf(u),toPath:Nf(g)}),B=g}break;case"file deletion":{let b=n||p;if(!b)throw new Error("Bad parse state: no path given for file deletion");e.push({type:"file deletion",semverExclusivity:i,hunk:m&&m[0]||null,path:Nf(b),mode:xQ(l),hash:f})}break;case"file creation":{let b=s||d;if(!b)throw new Error("Bad parse state: no path given for file creation");e.push({type:"file creation",semverExclusivity:i,hunk:m&&m[0]||null,path:Nf(b),mode:xQ(c),hash:h})}break;case"patch":case"mode change":B=d||s;break;default:de.assertNever(I);break}B&&o&&a&&o!==a&&e.push({type:"mode change",semverExclusivity:i,path:Nf(B),oldMode:xQ(o),newMode:xQ(a)}),B&&m&&m.length&&e.push({type:"patch",semverExclusivity:i,path:Nf(B),hunks:m,beforeHash:f,afterHash:h})}if(e.length===0)throw new Error("Unable to parse patch file: No changes found. Make sure the patch is a valid UTF8 encoded string");return e}function xQ(t){let e=parseInt(t,8)&511;if(e!==c_e&&e!==u_e)throw new Error(`Unexpected file mode string: ${t}`);return e}function kQ(t){let e=t.split(/\n/g);return e[e.length-1]===""&&e.pop(),d_e(p_e(e))}function h_e(t){let e=0,r=0;for(let{type:i,lines:n}of t.parts)switch(i){case Lr.Context:r+=n.length,e+=n.length;break;case Lr.Deletion:e+=n.length;break;case Lr.Insertion:r+=n.length;break;default:de.assertNever(i);break}if(e!==t.header.original.length||r!==t.header.patched.length){let i=n=>n<0?n:`+${n}`;throw new Error(`hunk header integrity check failed (expected @@ ${i(t.header.original.length)} ${i(t.header.patched.length)} @@, got @@ ${i(e)} ${i(r)} @@)`)}}async function Lf(t,e,r){let i=await t.lstatPromise(e),n=await r();if(typeof n!="undefined"&&(e=n),t.lutimesPromise)await t.lutimesPromise(e,i.atime,i.mtime);else if(!i.isSymbolicLink())await t.utimesPromise(e,i.atime,i.mtime);else throw new Error("Cannot preserve the time values of a symlink")}async function PQ(t,{baseFs:e=new Wt,dryRun:r=!1,version:i=null}={}){for(let n of t)if(!(n.semverExclusivity!==null&&i!==null&&!qt.satisfiesWithPrereleases(i,n.semverExclusivity)))switch(n.type){case"file deletion":if(r){if(!e.existsSync(n.path))throw new Error(`Trying to delete a file that doesn't exist: ${n.path}`)}else await Lf(e,v.dirname(n.path),async()=>{await e.unlinkPromise(n.path)});break;case"rename":if(r){if(!e.existsSync(n.fromPath))throw new Error(`Trying to move a file that doesn't exist: ${n.fromPath}`)}else await Lf(e,v.dirname(n.fromPath),async()=>{await Lf(e,v.dirname(n.toPath),async()=>{await Lf(e,n.fromPath,async()=>(await e.movePromise(n.fromPath,n.toPath),n.toPath))})});break;case"file creation":if(r){if(e.existsSync(n.path))throw new Error(`Trying to create a file that already exists: ${n.path}`)}else{let s=n.hunk?n.hunk.parts[0].lines.join(` +`)+(n.hunk.parts[0].noNewlineAtEndOfFile?"":` +`):"";await e.mkdirpPromise(v.dirname(n.path),{chmod:493,utimes:[mr.SAFE_TIME,mr.SAFE_TIME]}),await e.writeFilePromise(n.path,s,{mode:n.mode}),await e.utimesPromise(n.path,mr.SAFE_TIME,mr.SAFE_TIME)}break;case"patch":await Lf(e,n.path,async()=>{await C_e(n,{baseFs:e,dryRun:r})});break;case"mode change":{let o=(await e.statPromise(n.path)).mode;if(qge(n.newMode)!==qge(o))continue;await Lf(e,n.path,async()=>{await e.chmodPromise(n.path,n.newMode)})}break;default:de.assertNever(n);break}}function qge(t){return(t&64)>0}function Jge(t){return t.replace(/\s+$/,"")}function m_e(t,e){return Jge(t)===Jge(e)}async function C_e({hunks:t,path:e},{baseFs:r,dryRun:i=!1}){let n=await r.statSync(e).mode,o=(await r.readFileSync(e,"utf8")).split(/\n/),a=[],l=0,c=0;for(let g of t){let f=Math.max(c,g.header.patched.start+l),h=Math.max(0,f-c),p=Math.max(0,o.length-f-g.header.original.length),d=Math.max(h,p),m=0,I=0,B=null;for(;m<=d;){if(m<=h&&(I=f-m,B=Wge(g,o,I),B!==null)){m=-m;break}if(m<=p&&(I=f+m,B=Wge(g,o,I),B!==null))break;m+=1}if(B===null)throw new vm(t.indexOf(g),g);a.push(B),l+=m,c=I+g.header.original.length}if(i)return;let u=0;for(let g of a)for(let f of g)switch(f.type){case"splice":{let h=f.index+u;o.splice(h,f.numToDelete,...f.linesToInsert),u+=f.linesToInsert.length-f.numToDelete}break;case"pop":o.pop();break;case"push":o.push(f.line);break;default:de.assertNever(f);break}await r.writeFilePromise(e,o.join(` +`),{mode:n})}function Wge(t,e,r){let i=[];for(let n of t.parts)switch(n.type){case Lr.Context:case Lr.Deletion:{for(let s of n.lines){let o=e[r];if(o==null||!m_e(o,s))return null;r+=1}n.type===Lr.Deletion&&(i.push({type:"splice",index:r-n.lines.length,numToDelete:n.lines.length,linesToInsert:[]}),n.noNewlineAtEndOfFile&&i.push({type:"push",line:""}))}break;case Lr.Insertion:i.push({type:"splice",index:r,numToDelete:0,linesToInsert:n.lines}),n.noNewlineAtEndOfFile&&i.push({type:"pop"});break;default:de.assertNever(n.type);break}return i}var E_e=/^builtin<([^>]+)>$/;function zge(t,e){let{source:r,selector:i,params:n}=S.parseRange(t);if(r===null)throw new Error("Patch locators must explicitly define their source");let s=i?i.split(/&/).map(c=>M.toPortablePath(c)):[],o=n&&typeof n.locator=="string"?S.parseLocator(n.locator):null,a=n&&typeof n.version=="string"?n.version:null,l=e(r);return{parentLocator:o,sourceItem:l,patchPaths:s,sourceVersion:a}}function Sm(t){let i=zge(t.range,S.parseDescriptor),{sourceItem:e}=i,r=qr(i,["sourceItem"]);return _(P({},r),{sourceDescriptor:e})}function xm(t){let i=zge(t.reference,S.parseLocator),{sourceItem:e}=i,r=qr(i,["sourceItem"]);return _(P({},r),{sourceLocator:e})}function Vge({parentLocator:t,sourceItem:e,patchPaths:r,sourceVersion:i,patchHash:n},s){let o=t!==null?{locator:S.stringifyLocator(t)}:{},a=typeof i!="undefined"?{version:i}:{},l=typeof n!="undefined"?{hash:n}:{};return S.makeRange({protocol:"patch:",source:s(e),selector:r.join("&"),params:P(P(P({},a),l),o)})}function I_e(t,{parentLocator:e,sourceDescriptor:r,patchPaths:i}){return S.makeLocator(t,Vge({parentLocator:e,sourceItem:r,patchPaths:i},S.stringifyDescriptor))}function xM(t,{parentLocator:e,sourcePackage:r,patchPaths:i,patchHash:n}){return S.makeLocator(t,Vge({parentLocator:e,sourceItem:r,sourceVersion:r.version,patchPaths:i,patchHash:n},S.stringifyLocator))}function _ge({onAbsolute:t,onRelative:e,onBuiltin:r},i){i.startsWith("~")&&(i=i.slice(1));let s=i.match(E_e);return s!==null?r(s[1]):v.isAbsolute(i)?t(i):e(i)}function Xge(t){let e=t.startsWith("~");return e&&(t=t.slice(1)),{optional:e}}function kM(t){return _ge({onAbsolute:()=>!1,onRelative:()=>!0,onBuiltin:()=>!1},t)}async function km(t,e,r){let i=t!==null?await r.fetcher.fetch(t,r):null,n=i&&i.localPath?{packageFs:new Ft(Se.root),prefixPath:v.relative(Se.root,i.localPath)}:i;i&&i!==n&&i.releaseFs&&i.releaseFs();let s=await de.releaseAfterUseAsync(async()=>await Promise.all(e.map(async o=>{let a=Xge(o),l=await _ge({onAbsolute:async()=>await T.readFilePromise(o,"utf8"),onRelative:async()=>{if(n===null)throw new Error("Assertion failed: The parent locator should have been fetched");return await n.packageFs.readFilePromise(v.join(n.prefixPath,o),"utf8")},onBuiltin:async c=>await r.project.configuration.firstHook(u=>u.getBuiltinPatch,r.project,c)},o);return _(P({},a),{source:l})})));for(let o of s)typeof o.source=="string"&&(o.source=o.source.replace(/\r\n?/g,` +`));return s}async function PM(t,{cache:e,project:r}){let i=r.storedPackages.get(t.locatorHash);if(typeof i=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let n=r.storedChecksums,s=new ei,o=r.configuration.makeFetcher(),a=await o.fetch(t,{cache:e,project:r,fetcher:o,checksums:n,report:s}),l=await T.mktempPromise(),c=v.join(l,"source"),u=v.join(l,"user"),g=v.join(l,".yarn-patch.json");return await Promise.all([T.copyPromise(c,a.prefixPath,{baseFs:a.packageFs}),T.copyPromise(u,a.prefixPath,{baseFs:a.packageFs}),T.writeJsonPromise(g,{locator:S.stringifyLocator(t),version:i.version})]),T.detachTemp(l),u}async function DM(t,e){let r=M.fromPortablePath(t).replace(/\\/g,"/"),i=M.fromPortablePath(e).replace(/\\/g,"/"),{stdout:n,stderr:s}=await hr.execvp("git",["-c","core.safecrlf=false","diff","--src-prefix=a/","--dst-prefix=b/","--ignore-cr-at-eol","--full-index","--no-index","--text",r,i],{cwd:M.toPortablePath(process.cwd()),env:_(P({},process.env),{GIT_CONFIG_NOSYSTEM:"1",HOME:"",XDG_CONFIG_HOME:"",USERPROFILE:""})});if(s.length>0)throw new Error(`Unable to diff directories. Make sure you have a recent version of 'git' available in PATH. +The following error was reported by 'git': +${s}`);let o=r.startsWith("/")?a=>a.slice(1):a=>a;return n.replace(new RegExp(`(a|b)(${de.escapeRegExp(`/${o(r)}/`)})`,"g"),"$1/").replace(new RegExp(`(a|b)${de.escapeRegExp(`/${o(i)}/`)}`,"g"),"$1/").replace(new RegExp(de.escapeRegExp(`${r}/`),"g"),"").replace(new RegExp(de.escapeRegExp(`${i}/`),"g"),"")}function Zge(t,{configuration:e,report:r}){for(let i of t.parts)for(let n of i.lines)switch(i.type){case Lr.Context:r.reportInfo(null,` ${ue.pretty(e,n,"grey")}`);break;case Lr.Deletion:r.reportError(z.FROZEN_LOCKFILE_EXCEPTION,`- ${ue.pretty(e,n,ue.Type.REMOVED)}`);break;case Lr.Insertion:r.reportError(z.FROZEN_LOCKFILE_EXCEPTION,`+ ${ue.pretty(e,n,ue.Type.ADDED)}`);break;default:de.assertNever(i.type)}}var RM=class{supports(e,r){return!!e.reference.startsWith("patch:")}getLocalPath(e,r){return null}async fetch(e,r){let i=r.checksums.get(e.locatorHash)||null,[n,s,o]=await r.cache.fetchPackageFromCache(e,i,P({onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${S.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.patchPackage(e,r),skipIntegrityCheck:r.skipIntegrityCheck},r.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:S.getIdentVendorPath(e),localPath:this.getLocalPath(e,r),checksum:o}}async patchPackage(e,r){let{parentLocator:i,sourceLocator:n,sourceVersion:s,patchPaths:o}=xm(e),a=await km(i,o,r),l=await T.mktempPromise(),c=v.join(l,"current.zip"),u=await r.fetcher.fetch(n,r),g=S.getIdentVendorPath(e),f=await $i(),h=new Jr(c,{libzip:f,create:!0,level:r.project.configuration.get("compressionLevel")});await de.releaseAfterUseAsync(async()=>{await h.copyPromise(g,u.prefixPath,{baseFs:u.packageFs,stableSort:!0})},u.releaseFs),h.saveAndClose();for(let{source:p,optional:d}of a){if(p===null)continue;let m=new Jr(c,{libzip:f,level:r.project.configuration.get("compressionLevel")}),I=new Ft(v.resolve(Se.root,g),{baseFs:m});try{await PQ(kQ(p),{baseFs:I,version:s})}catch(B){if(!(B instanceof vm))throw B;let b=r.project.configuration.get("enableInlineHunks"),R=!b&&!d?" (set enableInlineHunks for details)":"",H=`${S.prettyLocator(r.project.configuration,e)}: ${B.message}${R}`,L=K=>{!b||Zge(B.hunk,{configuration:r.project.configuration,report:K})};if(m.discardAndClose(),d){r.report.reportWarningOnce(z.PATCH_HUNK_FAILED,H,{reportExtra:L});continue}else throw new nt(z.PATCH_HUNK_FAILED,H,L)}m.saveAndClose()}return new Jr(c,{libzip:f,level:r.project.configuration.get("compressionLevel")})}};var y_e=3,FM=class{supportsDescriptor(e,r){return!!e.range.startsWith("patch:")}supportsLocator(e,r){return!!e.reference.startsWith("patch:")}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,i){let{patchPaths:n}=Sm(e);return n.every(s=>!kM(s))?e:S.bindDescriptor(e,{locator:S.stringifyLocator(r)})}getResolutionDependencies(e,r){let{sourceDescriptor:i}=Sm(e);return[i]}async getCandidates(e,r,i){if(!i.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{parentLocator:n,sourceDescriptor:s,patchPaths:o}=Sm(e),a=await km(n,o,i.fetchOptions),l=r.get(s.descriptorHash);if(typeof l=="undefined")throw new Error("Assertion failed: The dependency should have been resolved");let c=mn.makeHash(`${y_e}`,...a.map(u=>JSON.stringify(u))).slice(0,6);return[xM(e,{parentLocator:n,sourcePackage:l,patchPaths:o,patchHash:c})]}async getSatisfying(e,r,i){return null}async resolve(e,r){let{sourceLocator:i}=xm(e),n=await r.resolver.resolve(i,r);return P(P({},n),e)}};var Pm=class extends Be{constructor(){super(...arguments);this.save=Y.Boolean("-s,--save",!1,{description:"Add the patch to your resolution entries"});this.patchFolder=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState();let n=v.resolve(this.context.cwd,M.toPortablePath(this.patchFolder)),s=v.join(n,"../source"),o=v.join(n,"../.yarn-patch.json");if(!T.existsSync(s))throw new me("The argument folder didn't get created by 'yarn patch'");let a=await DM(s,n),l=await T.readJsonPromise(o),c=S.parseLocator(l.locator,!0);if(!r.storedPackages.has(c.locatorHash))throw new me("No package found in the project for the given locator");if(!this.save){this.context.stdout.write(a);return}let u=e.get("patchFolder"),g=v.join(u,S.slugifyLocator(c));await T.mkdirPromise(u,{recursive:!0}),await T.writeFilePromise(g,a);let f=v.relative(r.cwd,g);r.topLevelWorkspace.manifest.resolutions.push({pattern:{descriptor:{fullName:S.stringifyIdent(c),description:l.version}},reference:`patch:${S.stringifyLocator(c)}#${f}`}),await r.persist()}};Pm.paths=[["patch-commit"]],Pm.usage=ye.Usage({description:"generate a patch out of a directory",details:"\n This will print a patchfile on stdout based on the diff between the folder passed in and the original version of the package. Such file is suitable for consumption with the `patch:` protocol.\n\n Only folders generated by `yarn patch` are accepted as valid input for `yarn patch-commit`.\n "});var $ge=Pm;var Dm=class extends Be{constructor(){super(...arguments);this.json=Y.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=Y.String()}async execute(){let e=await fe.find(this.context.cwd,this.context.plugins),{project:r,workspace:i}=await Ke.find(e,this.context.cwd),n=await Qt.find(e);if(!i)throw new rt(r.cwd,this.context.cwd);await r.restoreInstallState();let s=S.parseLocator(this.package);if(s.reference==="unknown"){let o=de.mapAndFilter([...r.storedPackages.values()],a=>a.identHash!==s.identHash?de.mapAndFilter.skip:S.isVirtualLocator(a)?de.mapAndFilter.skip:a);if(o.length===0)throw new me("No package found in the project for the given locator");if(o.length>1)throw new me(`Multiple candidate packages found; explicitly choose one of them (use \`yarn why \` to get more information as to who depends on them): +${o.map(a=>` +- ${S.prettyLocator(e,a)}`).join("")}`);s=o[0]}if(!r.storedPackages.has(s.locatorHash))throw new me("No package found in the project for the given locator");await Fe.start({configuration:e,json:this.json,stdout:this.context.stdout},async o=>{let a=await PM(s,{cache:n,project:r});o.reportJson({locator:S.stringifyLocator(s),path:M.fromPortablePath(a)}),o.reportInfo(z.UNNAMED,`Package ${S.prettyLocator(e,s)} got extracted with success!`),o.reportInfo(z.UNNAMED,`You can now edit the following folder: ${ue.pretty(e,M.fromPortablePath(a),"magenta")}`),o.reportInfo(z.UNNAMED,`Once you are done run ${ue.pretty(e,`yarn patch-commit ${process.platform==="win32"?'"':""}${M.fromPortablePath(a)}${process.platform==="win32"?'"':""}`,"cyan")} and Yarn will store a patchfile based on your changes.`)})}};Dm.paths=[["patch"]],Dm.usage=ye.Usage({description:"prepare a package for patching",details:'\n This command will cause a package to be extracted in a temporary directory (under a folder named "patch-workdir"). This folder will be editable at will; running `yarn patch` inside it will then cause Yarn to generate a patchfile and register it into your top-level manifest (cf the `patch:` protocol).\n '});var efe=Dm;var w_e={configuration:{enableInlineHunks:{description:"If true, the installs will print unmatched patch hunks",type:ge.BOOLEAN,default:!1},patchFolder:{description:"Folder where the patch files must be written",type:ge.ABSOLUTE_PATH,default:"./.yarn/patches"}},commands:[$ge,efe],fetchers:[RM],resolvers:[FM]},B_e=w_e;var TM={};it(TM,{default:()=>S_e});var tfe=ie(Wp()),LM=class{supportsPackage(e,r){return r.project.configuration.get("nodeLinker")==="pnpm"}async findPackageLocation(e,r){return nfe(e,{project:r.project})}async findPackageLocator(e,r){let i=ife(),n=r.project.installersCustomData.get(i);if(!n)throw new me(`The project in ${ue.pretty(r.project.configuration,`${r.project.cwd}/package.json`,ue.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let s=e.match(/(^.*\/node_modules\/(@[^/]*\/)?[^/]+)(\/.*$)/);if(s){let l=n.locatorByPath.get(s[1]);if(l)return l}let o=e,a=e;do{a=o,o=v.dirname(a);let l=n.locatorByPath.get(a);if(l)return l}while(o!==a);return null}makeInstaller(e){return new rfe(e)}},rfe=class{constructor(e){this.opts=e;this.asyncActions=new afe;this.packageLocations=new Map;this.customData={locatorByPath:new Map}}getCustomDataKey(){return ife()}attachCustomData(e){this.customData=e}async installPackage(e,r,i){switch(e.linkType){case gt.SOFT:return this.installPackageSoft(e,r,i);case gt.HARD:return this.installPackageHard(e,r,i)}throw new Error("Assertion failed: Unsupported package link type")}async installPackageSoft(e,r,i){let n=v.resolve(r.packageFs.getRealPath(),r.prefixPath);return this.packageLocations.set(e.locatorHash,n),{packageLocation:n,buildDirective:null}}async installPackageHard(e,r,i){var u;let n=nfe(e,{project:this.opts.project});this.customData.locatorByPath.set(n,S.stringifyLocator(e)),this.packageLocations.set(e.locatorHash,n),i.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{await T.mkdirPromise(n,{recursive:!0}),await T.copyPromise(n,r.prefixPath,{baseFs:r.packageFs,overwrite:!1})}));let o=S.isVirtualLocator(e)?S.devirtualizeLocator(e):e,a={manifest:(u=await Ze.tryFind(r.prefixPath,{baseFs:r.packageFs}))!=null?u:new Ze,misc:{hasBindingGyp:Ws.hasBindingGyp(r)}},l=this.opts.project.getDependencyMeta(o,e.version),c=Ws.extractBuildScripts(e,a,l,{configuration:this.opts.project.configuration,report:this.opts.report});return{packageLocation:n,buildDirective:c}}async attachInternalDependencies(e,r){this.opts.project.configuration.get("nodeLinker")==="pnpm"&&(!ofe(e,{project:this.opts.project})||this.asyncActions.reduce(e.locatorHash,async i=>{await i;let n=this.packageLocations.get(e.locatorHash);if(typeof n=="undefined")throw new Error(`Assertion failed: Expected the package to have been registered (${S.stringifyLocator(e)})`);let s=v.join(n,wt.nodeModules);r.length>0&&await T.mkdirpPromise(s);let o=await Q_e(s),a=[];for(let[l,c]of r){let u=c;ofe(c,{project:this.opts.project})||(this.opts.report.reportWarning(z.UNNAMED,"The pnpm linker doesn't support providing different versions to workspaces' peer dependencies"),u=S.devirtualizeLocator(c));let g=this.packageLocations.get(u.locatorHash);if(typeof g=="undefined")throw new Error(`Assertion failed: Expected the package to have been registered (${S.stringifyLocator(c)})`);let f=S.stringifyIdent(l),h=v.join(s,f),p=v.relative(v.dirname(h),g),d=o.get(f);o.delete(f),a.push(Promise.resolve().then(async()=>{if(d){if(d.isSymbolicLink()&&await T.readlinkPromise(h)===p)return;await T.removePromise(h)}await T.mkdirpPromise(v.dirname(h)),process.platform=="win32"?await T.symlinkPromise(g,h,"junction"):await T.symlinkPromise(p,h)}))}for(let l of o.keys())a.push(T.removePromise(v.join(s,l)));await Promise.all(a)}))}async attachExternalDependents(e,r){throw new Error("External dependencies haven't been implemented for the pnpm linker")}async finalizeInstall(){let e=sfe(this.opts.project),r=new Set;for(let s of this.packageLocations.values())r.add(v.basename(s));let i;try{i=await T.readdirPromise(e)}catch{i=[]}let n=[];for(let s of i)r.has(s)||n.push(T.removePromise(v.join(e,s)));await Promise.all(n),await this.asyncActions.wait()}};function ife(){return JSON.stringify({name:"PnpmInstaller",version:1})}function sfe(t){return v.join(t.cwd,wt.nodeModules,".store")}function nfe(t,{project:e}){let r=S.slugifyLocator(t);return v.join(sfe(e),r)}function ofe(t,{project:e}){return!S.isVirtualLocator(t)||!e.tryWorkspaceByLocator(t)}async function Q_e(t){let e=new Map,r=[];try{r=await T.readdirPromise(t,{withFileTypes:!0})}catch(i){if(i.code!=="ENOENT")throw i}try{for(let i of r)if(!i.name.startsWith("."))if(i.name.startsWith("@"))for(let n of await T.readdirPromise(v.join(t,i.name),{withFileTypes:!0}))e.set(`${i.name}/${n.name}`,n);else e.set(i.name,i)}catch(i){if(i.code!=="ENOENT")throw i}return e}function b_e(){let t,e;return{promise:new Promise((i,n)=>{t=i,e=n}),resolve:t,reject:e}}var afe=class{constructor(){this.deferred=new Map;this.promises=new Map;this.limit=(0,tfe.default)(10)}set(e,r){let i=this.deferred.get(e);typeof i=="undefined"&&this.deferred.set(e,i=b_e());let n=this.limit(()=>r());return this.promises.set(e,n),n.then(()=>{this.promises.get(e)===n&&i.resolve()},s=>{this.promises.get(e)===n&&i.reject(s)}),i.promise}reduce(e,r){var n;let i=(n=this.promises.get(e))!=null?n:Promise.resolve();this.set(e,()=>r(i))}async wait(){await Promise.all(this.promises.values())}};var v_e={linkers:[LM]},S_e=v_e;var F0=()=>({modules:new Map([["@yarnpkg/cli",iC],["@yarnpkg/core",Fd],["@yarnpkg/fslib",ch],["@yarnpkg/libzip",Fp],["@yarnpkg/parsers",Hp],["@yarnpkg/shell",jp],["clipanion",F$(vh)],["semver",x_e],["typanion",lu],["yup",k_e],["@yarnpkg/plugin-essentials",hL],["@yarnpkg/plugin-compat",mL],["@yarnpkg/plugin-dlx",EL],["@yarnpkg/plugin-file",xL],["@yarnpkg/plugin-git",fL],["@yarnpkg/plugin-github",PL],["@yarnpkg/plugin-http",FL],["@yarnpkg/plugin-init",ML],["@yarnpkg/plugin-link",GL],["@yarnpkg/plugin-nm",mT],["@yarnpkg/plugin-npm",yM],["@yarnpkg/plugin-npm-cli",vM],["@yarnpkg/plugin-pack",CM],["@yarnpkg/plugin-patch",NM],["@yarnpkg/plugin-pnp",oT],["@yarnpkg/plugin-pnpm",TM]]),plugins:new Set(["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-dlx","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm"])});i0({binaryVersion:Zr||"",pluginConfiguration:F0()});})(); +/*! + * buildToken + * Builds OAuth token prefix (helper function) + * + * @name buildToken + * @function + * @param {GitUrl} obj The parsed Git url object. + * @return {String} token prefix + */ +/*! + * fill-range + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + */ +/*! + * is-extglob + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ +/*! + * is-glob + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * is-windows + * + * Copyright © 2015-2018, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * to-regex-range + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ diff --git a/.yarn/sdks/eslint/bin/eslint.js b/.yarn/sdks/eslint/bin/eslint.js new file mode 100755 index 00000000..4d327a49 --- /dev/null +++ b/.yarn/sdks/eslint/bin/eslint.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require eslint/bin/eslint.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real eslint/bin/eslint.js your application uses +module.exports = absRequire(`eslint/bin/eslint.js`); diff --git a/.yarn/sdks/eslint/lib/api.js b/.yarn/sdks/eslint/lib/api.js new file mode 100644 index 00000000..fc728d95 --- /dev/null +++ b/.yarn/sdks/eslint/lib/api.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require eslint + require(absPnpApiPath).setup(); + } +} + +// Defer to the real eslint your application uses +module.exports = absRequire(`eslint`); diff --git a/.yarn/sdks/eslint/package.json b/.yarn/sdks/eslint/package.json new file mode 100644 index 00000000..1a0ae379 --- /dev/null +++ b/.yarn/sdks/eslint/package.json @@ -0,0 +1,6 @@ +{ + "name": "eslint", + "version": "7.28.0-sdk", + "main": "./lib/api.js", + "type": "commonjs" +} diff --git a/.yarn/sdks/integrations.yml b/.yarn/sdks/integrations.yml new file mode 100644 index 00000000..7e42d188 --- /dev/null +++ b/.yarn/sdks/integrations.yml @@ -0,0 +1,6 @@ +# This file is automatically generated by @yarnpkg/sdks. +# Manual changes might be lost! + +integrations: + - vscode + - vim diff --git a/.yarn/sdks/prettier/index.js b/.yarn/sdks/prettier/index.js new file mode 100755 index 00000000..f6882d80 --- /dev/null +++ b/.yarn/sdks/prettier/index.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require prettier/index.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real prettier/index.js your application uses +module.exports = absRequire(`prettier/index.js`); diff --git a/.yarn/sdks/prettier/package.json b/.yarn/sdks/prettier/package.json new file mode 100644 index 00000000..045baae7 --- /dev/null +++ b/.yarn/sdks/prettier/package.json @@ -0,0 +1,6 @@ +{ + "name": "prettier", + "version": "2.2.1-sdk", + "main": "./index.js", + "type": "commonjs" +} diff --git a/.yarn/sdks/stylelint/bin/stylelint.js b/.yarn/sdks/stylelint/bin/stylelint.js new file mode 100755 index 00000000..04ffaf8e --- /dev/null +++ b/.yarn/sdks/stylelint/bin/stylelint.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require stylelint/bin/stylelint.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real stylelint/bin/stylelint.js your application uses +module.exports = absRequire(`stylelint/bin/stylelint.js`); diff --git a/.yarn/sdks/stylelint/lib/index.js b/.yarn/sdks/stylelint/lib/index.js new file mode 100644 index 00000000..1b0b443f --- /dev/null +++ b/.yarn/sdks/stylelint/lib/index.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require stylelint/lib/index.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real stylelint/lib/index.js your application uses +module.exports = absRequire(`stylelint/lib/index.js`); diff --git a/.yarn/sdks/stylelint/package.json b/.yarn/sdks/stylelint/package.json new file mode 100644 index 00000000..8afaf7a3 --- /dev/null +++ b/.yarn/sdks/stylelint/package.json @@ -0,0 +1,6 @@ +{ + "name": "stylelint", + "version": "14.0.1-sdk", + "main": "lib/index.js", + "type": "commonjs" +} diff --git a/.yarn/sdks/typescript/bin/tsc b/.yarn/sdks/typescript/bin/tsc new file mode 100755 index 00000000..5608e574 --- /dev/null +++ b/.yarn/sdks/typescript/bin/tsc @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/bin/tsc + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/bin/tsc your application uses +module.exports = absRequire(`typescript/bin/tsc`); diff --git a/.yarn/sdks/typescript/bin/tsserver b/.yarn/sdks/typescript/bin/tsserver new file mode 100755 index 00000000..cd7d557d --- /dev/null +++ b/.yarn/sdks/typescript/bin/tsserver @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/bin/tsserver + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/bin/tsserver your application uses +module.exports = absRequire(`typescript/bin/tsserver`); diff --git a/.yarn/sdks/typescript/lib/tsc.js b/.yarn/sdks/typescript/lib/tsc.js new file mode 100644 index 00000000..16042d01 --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsc.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsc.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/lib/tsc.js your application uses +module.exports = absRequire(`typescript/lib/tsc.js`); diff --git a/.yarn/sdks/typescript/lib/tsserver.js b/.yarn/sdks/typescript/lib/tsserver.js new file mode 100644 index 00000000..71e35cf6 --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsserver.js @@ -0,0 +1,184 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +const moduleWrapper = tsserver => { + if (!process.versions.pnp) { + return tsserver; + } + + const {isAbsolute} = require(`path`); + const pnpApi = require(`pnpapi`); + + const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); + + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); + + // VSCode sends the zip paths to TS using the "zip://" prefix, that TS + // doesn't understand. This layer makes sure to remove the protocol + // before forwarding it to TS, and to add it back on all returned paths. + + function toEditorPath(str) { + // We add the `zip:` prefix to both `.zip/` paths and virtual paths + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + // We also take the opportunity to turn virtual paths into physical ones; + // this makes it much easier to work with workspaces that list peer + // dependencies, since otherwise Ctrl+Click would bring us to the virtual + // file instances instead of the real ones. + // + // We only do this to modules owned by the the dependency tree roots. + // This avoids breaking the resolution when jumping inside a vendor + // with peer dep (otherwise jumping into react-dom would show resolution + // errors on react). + // + const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; + if (resolved) { + const locator = pnpApi.findPackageLocator(resolved); + if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) { + str = resolved; + } + } + + str = normalize(str); + + if (str.match(/\.zip\//)) { + switch (hostInfo) { + // Absolute VSCode `Uri.fsPath`s need to start with a slash. + // VSCode only adds it automatically for supported schemes, + // so we have to do it manually for the `zip` scheme. + // The path needs to start with a caret otherwise VSCode doesn't handle the protocol + // + // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 + // + // Update Oct 8 2021: VSCode changed their format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + + // To make "go to definition" work, + // We have to resolve the actual file system path from virtual path + // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; + + // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) + // We have to resolve the actual file system path from virtual path, + // everything else is up to neovim + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile:${str}`; + } break; + + default: { + str = `zip:${str}`; + } break; + } + } + } + + return str; + } + + function fromEditorPath(str) { + switch (hostInfo) { + case `coc-nvim`: + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `vscode`: + default: { + return process.platform === `win32` + ? str.replace(/^\^?(zip:|\/zip)\/+/, ``) + : str.replace(/^\^?(zip:|\/zip)\/+/, `/`); + } break; + } + } + + // Force enable 'allowLocalPluginLoads' + // TypeScript tries to resolve plugins using a path relative to itself + // which doesn't work when using the global cache + // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 + // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but + // TypeScript already does local loads and if this code is running the user trusts the workspace + // https://github.com/microsoft/vscode/issues/45856 + const ConfiguredProject = tsserver.server.ConfiguredProject; + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { + this.projectService.allowLocalPluginLoads = true; + return originalEnablePluginsWithOptions.apply(this, arguments); + }; + + // And here is the point where we hijack the VSCode <-> TS communications + // by adding ourselves in the middle. We locate everything that looks + // like an absolute path of ours and normalize it. + + const Session = tsserver.server.Session; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + let hostInfo = `unknown`; + + Object.assign(Session.prototype, { + onMessage(/** @type {string} */ message) { + const parsedMessage = JSON.parse(message) + + if ( + parsedMessage != null && + typeof parsedMessage === `object` && + parsedMessage.arguments && + typeof parsedMessage.arguments.hostInfo === `string` + ) { + hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK && process.env.VSCODE_IPC_HOOK.match(/Code\/1\.([1-5][0-9]|60)\./)) { + hostInfo += ` <1.61`; + } + } + + return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => { + return typeof value === `string` ? fromEditorPath(value) : value; + })); + }, + + send(/** @type {any} */ msg) { + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } + }); + + return tsserver; +}; + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsserver.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/lib/tsserver.js your application uses +module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`)); diff --git a/.yarn/sdks/typescript/lib/tsserverlibrary.js b/.yarn/sdks/typescript/lib/tsserverlibrary.js new file mode 100644 index 00000000..7a2d65ea --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsserverlibrary.js @@ -0,0 +1,184 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +const moduleWrapper = tsserver => { + if (!process.versions.pnp) { + return tsserver; + } + + const {isAbsolute} = require(`path`); + const pnpApi = require(`pnpapi`); + + const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); + + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); + + // VSCode sends the zip paths to TS using the "zip://" prefix, that TS + // doesn't understand. This layer makes sure to remove the protocol + // before forwarding it to TS, and to add it back on all returned paths. + + function toEditorPath(str) { + // We add the `zip:` prefix to both `.zip/` paths and virtual paths + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + // We also take the opportunity to turn virtual paths into physical ones; + // this makes it much easier to work with workspaces that list peer + // dependencies, since otherwise Ctrl+Click would bring us to the virtual + // file instances instead of the real ones. + // + // We only do this to modules owned by the the dependency tree roots. + // This avoids breaking the resolution when jumping inside a vendor + // with peer dep (otherwise jumping into react-dom would show resolution + // errors on react). + // + const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; + if (resolved) { + const locator = pnpApi.findPackageLocator(resolved); + if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) { + str = resolved; + } + } + + str = normalize(str); + + if (str.match(/\.zip\//)) { + switch (hostInfo) { + // Absolute VSCode `Uri.fsPath`s need to start with a slash. + // VSCode only adds it automatically for supported schemes, + // so we have to do it manually for the `zip` scheme. + // The path needs to start with a caret otherwise VSCode doesn't handle the protocol + // + // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 + // + // Update Oct 8 2021: VSCode changed their format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + + // To make "go to definition" work, + // We have to resolve the actual file system path from virtual path + // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; + + // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) + // We have to resolve the actual file system path from virtual path, + // everything else is up to neovim + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile:${str}`; + } break; + + default: { + str = `zip:${str}`; + } break; + } + } + } + + return str; + } + + function fromEditorPath(str) { + switch (hostInfo) { + case `coc-nvim`: + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `vscode`: + default: { + return process.platform === `win32` + ? str.replace(/^\^?(zip:|\/zip)\/+/, ``) + : str.replace(/^\^?(zip:|\/zip)\/+/, `/`); + } break; + } + } + + // Force enable 'allowLocalPluginLoads' + // TypeScript tries to resolve plugins using a path relative to itself + // which doesn't work when using the global cache + // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 + // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but + // TypeScript already does local loads and if this code is running the user trusts the workspace + // https://github.com/microsoft/vscode/issues/45856 + const ConfiguredProject = tsserver.server.ConfiguredProject; + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { + this.projectService.allowLocalPluginLoads = true; + return originalEnablePluginsWithOptions.apply(this, arguments); + }; + + // And here is the point where we hijack the VSCode <-> TS communications + // by adding ourselves in the middle. We locate everything that looks + // like an absolute path of ours and normalize it. + + const Session = tsserver.server.Session; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + let hostInfo = `unknown`; + + Object.assign(Session.prototype, { + onMessage(/** @type {string} */ message) { + const parsedMessage = JSON.parse(message) + + if ( + parsedMessage != null && + typeof parsedMessage === `object` && + parsedMessage.arguments && + typeof parsedMessage.arguments.hostInfo === `string` + ) { + hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK && process.env.VSCODE_IPC_HOOK.match(/Code\/1\.([1-5][0-9]|60)\./)) { + hostInfo += ` <1.61`; + } + } + + return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => { + return typeof value === `string` ? fromEditorPath(value) : value; + })); + }, + + send(/** @type {any} */ msg) { + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } + }); + + return tsserver; +}; + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsserverlibrary.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/lib/tsserverlibrary.js your application uses +module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`)); diff --git a/.yarn/sdks/typescript/lib/typescript.js b/.yarn/sdks/typescript/lib/typescript.js new file mode 100644 index 00000000..cbdbf150 --- /dev/null +++ b/.yarn/sdks/typescript/lib/typescript.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/typescript.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/lib/typescript.js your application uses +module.exports = absRequire(`typescript/lib/typescript.js`); diff --git a/.yarn/sdks/typescript/package.json b/.yarn/sdks/typescript/package.json new file mode 100644 index 00000000..fae7e416 --- /dev/null +++ b/.yarn/sdks/typescript/package.json @@ -0,0 +1,6 @@ +{ + "name": "typescript", + "version": "4.5.4-sdk", + "main": "./lib/typescript.js", + "type": "commonjs" +} diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 00000000..b55b52d6 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,85 @@ +enableTelemetry: false + +nodeLinker: pnp + +packageExtensions: + "@grafana/slate-react@0.22.10-grafana": + peerDependencies: + slate-react: ">=0.22.0" + "@mdx-js/loader@1.6.22": + peerDependencies: + react: 17.0.1 + "@storybook/addon-docs@6.4.4": + peerDependencies: + "@storybook/manager-webpack5": 6.4.4 + "@storybook/addon-essentials@6.4.4": + peerDependencies: + "@storybook/components": 6.4.4 + "@storybook/core-events": 6.4.4 + "@storybook/manager-webpack5": 6.4.4 + "@storybook/theming": 6.4.4 + "@storybook/core-server@6.4.4": + peerDependencies: + "@babel/core": ^7.0.0 + "@storybook/core@6.4.4": + peerDependencies: + "@babel/core": ^7.0.0 + "@storybook/manager-webpack5": 6.4.4 + "@storybook/csf-tools@6.4.4": + peerDependencies: + "@babel/core": ^7.0.0 + "@storybook/react@6.4.4": + peerDependencies: + "@storybook/manager-webpack5": 6.4.4 + doctrine@3.0.0: + dependencies: + assert: 2.0.0 + moveable@0.27.3: + dependencies: + "@daybrush/utils": 1.6.0 + framework-utils: ^1.1.0 + rc-time-picker@3.7.3: + peerDependencies: + react: 17.0.1 + react-dom: 17.0.1 + rc-trigger@2.6.5: + peerDependencies: + react: 17.0.1 + react-dom: 17.0.1 + react-compat-css-styled@1.0.8: + dependencies: + react-simple-compat: 1.2.1 + react-compat-moveable@0.15.2: + dependencies: + "@egjs/agent": ^2.2.1 + "@egjs/children-differ": ^1.0.1 + "@scena/matrix": 1.1.1 + css-to-mat: ^1.0.3 + gesto: ^1.4.0 + overlap-area: ^1.0.0 + react-simple-compat: 1.2.1 + peerDependencies: + framework-utils: ^1.1.0 + react-dev-utils@11.0.4: + peerDependencies: + typescript: 4.4.3 + webpack: 5.51.1 + react-docgen-typescript-loader@3.7.2: + peerDependencies: + webpack: 4.41.5 + react-icons@2.2.7: + peerDependencies: + prop-types: "*" + react-resizable@3.0.4: + peerDependencies: + react-dom: 17.0.1 + +plugins: + - path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs + spec: "@yarnpkg/plugin-typescript" + - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs + spec: "@yarnpkg/plugin-interactive-tools" + - path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs + spec: "https://mskelton.dev/yarn-outdated/v2" + +yarnPath: .yarn/releases/yarn-3.1.1.cjs diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..80e0d421 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4108 @@ + + +# 8.3.3 (2021-12-10) + +### Features and enhancements + +- **BarChart:** Use new data error view component to show actions in panel edit. [#42474](https://github.com/grafana/grafana/pull/42474), [@torkelo](https://github.com/torkelo) +- **CloudMonitor:** Iterate over pageToken for resources. [#42546](https://github.com/grafana/grafana/pull/42546), [@iwysiu](https://github.com/iwysiu) +- **Macaron:** Prevent WriteHeader invalid HTTP status code panic. [#42973](https://github.com/grafana/grafana/pull/42973), [@bergquist](https://github.com/bergquist) + +### Bug fixes + +- **AnnoListPanel:** Fix interpolation of variables in tags. [#42318](https://github.com/grafana/grafana/pull/42318), [@francoisdtm](https://github.com/francoisdtm) +- **CloudWatch:** Allow queries to have no dimensions specified. [#42800](https://github.com/grafana/grafana/pull/42800), [@sunker](https://github.com/sunker) +- **CloudWatch:** Fix broken queries for users migrating from 8.2.4/8.2.5 to 8.3.0. [#42611](https://github.com/grafana/grafana/pull/42611), [@sunker](https://github.com/sunker) +- **CloudWatch:** Make sure MatchExact flag gets the right value. [#42621](https://github.com/grafana/grafana/pull/42621), [@sunker](https://github.com/sunker) +- **Dashboards:** Fix so that empty folders can be deleted from the manage dashboards/folders page. [#42527](https://github.com/grafana/grafana/pull/42527), [@ashharrison90](https://github.com/ashharrison90) +- **InfluxDB:** Improve handling of metadata query errors in InfluxQL. [#42500](https://github.com/grafana/grafana/pull/42500), [@gabor](https://github.com/gabor) +- **Loki:** Fix adding of ad hoc filters for queries with parser and line_format expressions. [#42590](https://github.com/grafana/grafana/pull/42590), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Fix running of exemplar queries for non-histogram metrics. [#42749](https://github.com/grafana/grafana/pull/42749), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Interpolate template variables in interval. [#42637](https://github.com/grafana/grafana/pull/42637), [@ivanahuckova](https://github.com/ivanahuckova) +- **StateTimeline:** Fix toolitp not showing when for frames with multiple fields. [#42741](https://github.com/grafana/grafana/pull/42741), [@dprokop](https://github.com/dprokop) +- **TraceView:** Fix virtualized scrolling when trace view is opened in right pane in Explore. [#42480](https://github.com/grafana/grafana/pull/42480), [@autoric](https://github.com/autoric) +- **Variables:** Fix repeating panels for on time range changed variables. [#42828](https://github.com/grafana/grafana/pull/42828), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables:** Fix so queryparam option works for scoped variables. [#42742](https://github.com/grafana/grafana/pull/42742), [@hugohaggmark](https://github.com/hugohaggmark) + + + + +# 8.3.2 (2021-12-10) + +- **Security**: Fixes CVE-2021-43813 and CVE-2021-43815. For more information, see our [blog](https://grafana.com/blog/2021/12/10/grafana-8.3.2-and-7.5.12-released-with-moderate-severity-security-fix/ + + + + + +# 8.3.1 (2021-12-07) + +- **Security**: Fixes CVE-2021-43798. For more information, see our [blog](https://grafana.com/blog/2021/12/07/grafana-8.3.1-8.2.7-8.1.8-and-8.0.7-released-with-high-severity-security-fix/) + + + + + +# 8.3.0 (2021-11-30) + +### Features and enhancements + +- **Alerting:** Prevent folders from being deleted when they contain alerts. [#42307](https://github.com/grafana/grafana/pull/42307), [@peterholmberg](https://github.com/peterholmberg) +- **Alerting:** Show full preview value in tooltip. [#42445](https://github.com/grafana/grafana/pull/42445), [@peterholmberg](https://github.com/peterholmberg) +- **BarGauge:** Limit title width when name is really long. [#42346](https://github.com/grafana/grafana/pull/42346), [@torkelo](https://github.com/torkelo) +- **CloudMonitoring:** Avoid to escape regexps in filters. [#41961](https://github.com/grafana/grafana/pull/41961), [@andresmgot](https://github.com/andresmgot) +- **CloudWatch:** Add support for AWS Metric Insights. [#42487](https://github.com/grafana/grafana/pull/42487), [@sunker](https://github.com/sunker) +- **TooltipPlugin:** Remove other panels' shared tooltip in edit panel. [#42187](https://github.com/grafana/grafana/pull/42187), [@mdvictor](https://github.com/mdvictor) +- **Visualizations:** Limit y label width to 40% of visualization width. [#42350](https://github.com/grafana/grafana/pull/42350), [@torkelo](https://github.com/torkelo) + +### Bug fixes + +- **Alerting:** Clear alerting rule evaluation errors after intermittent failures. [#42386](https://github.com/grafana/grafana/pull/42386), [@gotjosh](https://github.com/gotjosh) +- **Alerting:** Fix refresh on legacy Alert List panel. [#42322](https://github.com/grafana/grafana/pull/42322), [@peterholmberg](https://github.com/peterholmberg) +- **Dashboard:** Fix queries for panels with non-integer widths. [#42420](https://github.com/grafana/grafana/pull/42420), [@gabor](https://github.com/gabor) +- **Explore:** Fix url update inconsistency. [#42288](https://github.com/grafana/grafana/pull/42288), [@gabor](https://github.com/gabor) +- **Prometheus:** Fix range variables interpolation for time ranges smaller than 1 second. [#42242](https://github.com/grafana/grafana/pull/42242), [@ivanahuckova](https://github.com/ivanahuckova) +- **ValueMappings:** Fixes issue with regex value mapping that only sets color. [#42311](https://github.com/grafana/grafana/pull/42311), [@torkelo](https://github.com/torkelo) + + + + +# 8.3.0-beta2 (2021-11-25) + +### Features and enhancements + +- **Alerting:** Create DatasourceError alert if evaluation returns error. [#41869](https://github.com/grafana/grafana/pull/41869), [@gerobinson](https://github.com/gerobinson) +- **Alerting:** Make Unified Alerting enabled by default for those who do not use legacy alerting. [#42200](https://github.com/grafana/grafana/pull/42200), [@armandgrillet](https://github.com/armandgrillet) +- **Alerting:** Support mute timings configuration through the api for the embedded alert manager. [#41533](https://github.com/grafana/grafana/pull/41533), [@JohnnyQQQQ](https://github.com/JohnnyQQQQ) +- **CloudWatch:** Add missing AWS/Events metrics. [#42164](https://github.com/grafana/grafana/pull/42164), [@n2N8Z](https://github.com/n2N8Z) +- **Docs:** Add easier to find deprecation notices to certain data sources and to the changelog. [#41938](https://github.com/grafana/grafana/pull/41938), [@gabor](https://github.com/gabor) +- **Plugins Catalog:** Enable install controls based on the pluginAdminEnabled flag. [#41686](https://github.com/grafana/grafana/pull/41686), [@leventebalogh](https://github.com/leventebalogh) +- **Query caching:** Increase max_value_mb default to 10. (Enterprise) +- **Table:** Add space between values for the DefaultCell. [#42246](https://github.com/grafana/grafana/pull/42246), [@kirederik](https://github.com/kirederik) +- **Table:** Add space between values on JSONViewCell. [#42156](https://github.com/grafana/grafana/pull/42156), [@kirederik](https://github.com/kirederik) +- **Tracing:** Make query editors available in dashboard for Tempo and Zipkin. [#41974](https://github.com/grafana/grafana/pull/41974), [@ivanahuckova](https://github.com/ivanahuckova) + +### Bug fixes + +- **AccessControl:** Renamed `orgs` roles, removed `fixed:orgs:reader` introduced in beta1. [#42049](https://github.com/grafana/grafana/pull/42049), [@gamab](https://github.com/gamab) +- **Azure Monitor:** Add trap focus for modals in grafana/ui and other small a11y fixes for Azure Monitor. [#41449](https://github.com/grafana/grafana/pull/41449), [@sarahzinger](https://github.com/sarahzinger) +- **CodeEditor:** Prevent suggestions from being clipped. [#42120](https://github.com/grafana/grafana/pull/42120), [@kaydelaney](https://github.com/kaydelaney) +- **Dashboard:** Fix cache timeout persistence. [#42204](https://github.com/grafana/grafana/pull/42204), [@hugohaggmark](https://github.com/hugohaggmark) +- **Datasource:** Fix stable sort order of query responses. [#41868](https://github.com/grafana/grafana/pull/41868), [@marefr](https://github.com/marefr) +- **Explore:** Fix error in query history when removing last item. [#42179](https://github.com/grafana/grafana/pull/42179), [@gabor](https://github.com/gabor) +- **Logs:** Fix requesting of older logs when flipped order. [#41966](https://github.com/grafana/grafana/pull/41966), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Fix running of health check query based on access mode. [#42189](https://github.com/grafana/grafana/pull/42189), [@ivanahuckova](https://github.com/ivanahuckova) +- **TextPanel:** Fix suggestions for existing panels. [#42195](https://github.com/grafana/grafana/pull/42195), [@hugohaggmark](https://github.com/hugohaggmark) +- **Tracing:** Fix incorrect indentations due to reoccurring spanIDs. [#41919](https://github.com/grafana/grafana/pull/41919), [@ivanahuckova](https://github.com/ivanahuckova) +- **Tracing:** Show start time of trace with milliseconds precision. [#42132](https://github.com/grafana/grafana/pull/42132), [@ivanahuckova](https://github.com/ivanahuckova) +- **Variables:** Make renamed or missing variable section expandable. [#41964](https://github.com/grafana/grafana/pull/41964), [@hugohaggmark](https://github.com/hugohaggmark) + +### Breaking changes + +### Grafana 8 Alerting enabled by default for installations that do not use legacy alerting + +Starting with Grafana v8.3.0, if you have **not** explicitly disabled unified alerting and **do not** have legacy alerts set up you are automatically "migrated" to Grafana 8 Alerting. + +A migration **from legacy to Grafana 8 Alerting** will never incur a data loss, as the previous data is kept around for rollback purposes. However, going from **Grafana 8 Alerting to legacy alerting** will delete all the data created for Grafana 8 Alerting. It is recommended that you **backup your database** before attempting a migration between systems. + +If unclear, please verify the table below: + +| `[alerting][enabled]` | `[unified_alerting][enabled]` | With Existing Legacy Alerts | Result | +| --------------------- | ----------------------------- | --------------------------- | ------------------ | +| `true` | `true` | N/A | Error | +| `true` | `false` | N/A | Legacy Alerting | +| `true` | not set | Yes | Legacy Alerting | +| `true` | not set | No | Grafana 8 Alerting | +| not set | `true` | N/A | Grafana 8 Alerting | +| not set | `false` | N/A | Legacy Alerting | +| not set | not set | Yes | Legacy Alerting | +| not set | not set | No | Grafana 8 Alerting | +| `false` | `true` | N/A | Grafana 8 Alerting | +| `false` | `false` | N/A | Alerting disabled | +| `false` | not set | N/A | Grafana 8 Alerting | + +N/A in the "With Existing Legacy Alerts" column means that it does not matter if you have legacy alerts or not. +Issue [#42200](https://github.com/grafana/grafana/issues/42200) + +### Keep Last State for "If execution error or timeout" when upgrading to Grafana 8 alerting + +In Grafana 8.3.0-beta2 we changed how alert rules that use `Keep Last State` for `If execution error or timeout` are upgraded from Legacy Alerting to Grafana 8 alerting. In 8.3.0-beta1 and earlier, alert rules with `Keep Last State` for `If execution error or timeout` were changed to `Alerting` when upgrading from Legacy Alerting to Grafana 8 alerting. However, in 8.3.0-beta2 these alert rules are now upgraded to a new option called `Error`. With this option, on encountering an error evaluating an alert rule, Grafana creates a special alert called `DatasourceError` with the `rule_uid` and `ref_id` as labels and an annotation called `Error` with the error message. Issue [#41869](https://github.com/grafana/grafana/issues/41869) + +### Deprecations + +The access mode "browser" is deprecated in the following data sources and will be removed in a later release: + +- Prometheus +- InfluxDB +- Elasticsearch Issue [#41938](https://github.com/grafana/grafana/issues/41938) + +### Plugin development fixes & changes + +- **Select:** Select menus now properly scroll during keyboard navigation. [#41917](https://github.com/grafana/grafana/pull/41917), [@ashharrison90](https://github.com/ashharrison90) + + + + +# 8.3.0-beta1 (2021-11-18) + +### Features and enhancements + +- **AccessControl:** Apply fine-grained access control to licensing. (Enterprise) +- **Alerting:** Add UI for contact point testing with custom annotations and labels. [#40491](https://github.com/grafana/grafana/pull/40491), [@nathanrodman](https://github.com/nathanrodman) +- **Alerting:** Make alert state indicator in panel header work with Grafana 8 alerts. [#38713](https://github.com/grafana/grafana/pull/38713), [@domasx2](https://github.com/domasx2) +- **Alerting:** Option for Discord notifier to use webhook name. [#40463](https://github.com/grafana/grafana/pull/40463), [@Skyebold](https://github.com/Skyebold) +- **Annotations:** Deprecate AnnotationsSrv. [#39631](https://github.com/grafana/grafana/pull/39631), [@hugohaggmark](https://github.com/hugohaggmark) +- **Auditing:** Add audit logs for unified alerting endpoints. (Enterprise) +- **Auditing:** Add endpoints (plugins, datasources, library elements). (Enterprise) +- **Auth:** Omit all base64 paddings in JWT tokens for the JWT auth. [#35602](https://github.com/grafana/grafana/pull/35602), [@gillg](https://github.com/gillg) +- **Azure Monitor:** Clean up fields when editing Metrics. [#41762](https://github.com/grafana/grafana/pull/41762), [@andresmgot](https://github.com/andresmgot) +- **AzureMonitor:** Add new starter dashboards. [#39876](https://github.com/grafana/grafana/pull/39876), [@jcolladokuri](https://github.com/jcolladokuri) +- **AzureMonitor:** Add starter dashboard for app monitoring with Application Insights. [#40725](https://github.com/grafana/grafana/pull/40725), [@jcolladokuri](https://github.com/jcolladokuri) +- **Barchart/Time series:** Allow x axis label. [#41142](https://github.com/grafana/grafana/pull/41142), [@oscarkilhed](https://github.com/oscarkilhed) +- **CLI:** Improve error handling for installing plugins. [#41257](https://github.com/grafana/grafana/pull/41257), [@marefr](https://github.com/marefr) +- **CloudMonitoring:** Migrate to use backend plugin SDK contracts. [#38650](https://github.com/grafana/grafana/pull/38650), [@idafurjes](https://github.com/idafurjes) +- **CloudWatch Logs:** Add retry strategy for hitting max concurrent queries. [#39290](https://github.com/grafana/grafana/pull/39290), [@aocenas](https://github.com/aocenas) +- **CloudWatch:** Add AWS RoboMaker metrics and dimension. [#41450](https://github.com/grafana/grafana/pull/41450), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch:** Add AWS Transfer metrics and dimension. [#41168](https://github.com/grafana/grafana/pull/41168), [@ilyastoli](https://github.com/ilyastoli) +- **Dashboard:** replace datasource name with a reference object. [#33817](https://github.com/grafana/grafana/pull/33817), [@ryantxu](https://github.com/ryantxu) +- **Dashboards:** Show logs on time series when hovering. [#40110](https://github.com/grafana/grafana/pull/40110), [@ryantxu](https://github.com/ryantxu) +- **Elasticsearch:** Add support for Elasticsearch 8.0 (Beta). [#41729](https://github.com/grafana/grafana/pull/41729), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch:** Add time zone setting to Date Histogram aggregation. [#40882](https://github.com/grafana/grafana/pull/40882), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch:** Enable full range log volume histogram. [#41202](https://github.com/grafana/grafana/pull/41202), [@ifrost](https://github.com/ifrost) +- **Elasticsearch:** Full range logs volume. [#40700](https://github.com/grafana/grafana/pull/40700), [@ifrost](https://github.com/ifrost) +- **Explore:** Allow changing the graph type. [#40522](https://github.com/grafana/grafana/pull/40522), [@gabor](https://github.com/gabor) +- **Explore:** Show ANSI colors when highlighting matched words in the logs panel. [#40971](https://github.com/grafana/grafana/pull/40971), [@oliverfrye](https://github.com/oliverfrye) +- **Graph(old) panel:** Listen to events from Time series panel. [#41033](https://github.com/grafana/grafana/pull/41033), [@zoltanbedi](https://github.com/zoltanbedi) +- **Import:** Load gcom dashboards from URL. [#41799](https://github.com/grafana/grafana/pull/41799), [@ashharrison90](https://github.com/ashharrison90) +- **LibraryPanels:** Improves export and import of library panels between orgs. [#39214](https://github.com/grafana/grafana/pull/39214), [@hugohaggmark](https://github.com/hugohaggmark) +- **OAuth:** Support PKCE. [#39948](https://github.com/grafana/grafana/pull/39948), [@sakjur](https://github.com/sakjur) +- **Panel edit:** Overrides now highlight correctly when searching. [#41684](https://github.com/grafana/grafana/pull/41684), [@ashharrison90](https://github.com/ashharrison90) +- **PanelEdit:** Display drag indicators on draggable sections. [#41711](https://github.com/grafana/grafana/pull/41711), [@ashharrison90](https://github.com/ashharrison90) +- **Plugins:** Refactor Plugin Management. [#40477](https://github.com/grafana/grafana/pull/40477), [@wbrowne](https://github.com/wbrowne) +- **Prometheus:** Add custom query parameters when creating PromLink url. [#41213](https://github.com/grafana/grafana/pull/41213), [@Ian-Yy](https://github.com/Ian-Yy) +- **Prometheus:** Remove limits on metrics, labels, and values in Metrics Browser. [#40660](https://github.com/grafana/grafana/pull/40660), [@autoric](https://github.com/autoric) +- **StateTimeline:** Share cursor with rest of the panels. [#41038](https://github.com/grafana/grafana/pull/41038), [@zoltanbedi](https://github.com/zoltanbedi) +- **Tempo:** Add error details when json upload fails. [#41803](https://github.com/grafana/grafana/pull/41803), [@aocenas](https://github.com/aocenas) +- **Tempo:** Add filtering for service graph query. [#41162](https://github.com/grafana/grafana/pull/41162), [@aocenas](https://github.com/aocenas) +- **Tempo:** Add links to nodes in Service Graph pointing to Prometheus metrics. [#41135](https://github.com/grafana/grafana/pull/41135), [@aocenas](https://github.com/aocenas) +- **Time series/Bar chart panel:** Add ability to sort series via legend. [#40226](https://github.com/grafana/grafana/pull/40226), [@zoltanbedi](https://github.com/zoltanbedi) +- **TimeSeries:** Allow multiple axes for the same unit. [#41635](https://github.com/grafana/grafana/pull/41635), [@dprokop](https://github.com/dprokop) +- **TraceView:** Allow span links defined on dataFrame. [#40563](https://github.com/grafana/grafana/pull/40563), [@aocenas](https://github.com/aocenas) +- **Transformations:** Support a rows mode in labels to fields. [#41020](https://github.com/grafana/grafana/pull/41020), [@ryantxu](https://github.com/ryantxu) +- **ValueMappings:** Don't apply field config defaults to time fields. [#41132](https://github.com/grafana/grafana/pull/41132), [@torkelo](https://github.com/torkelo) +- **Variables:** Only update panels that are impacted by variable change. [#39420](https://github.com/grafana/grafana/pull/39420), [@hugohaggmark](https://github.com/hugohaggmark) + +### Bug fixes + +- **API:** Fix dashboard quota limit for imports. [#41495](https://github.com/grafana/grafana/pull/41495), [@yangkb09](https://github.com/yangkb09) +- **Alerting:** Fix rule editor issues with Azure Monitor data source. [#41317](https://github.com/grafana/grafana/pull/41317), [@domasx2](https://github.com/domasx2) +- **Azure monitor:** Make sure alert rule editor is not enabled when template variables are being used. [#41335](https://github.com/grafana/grafana/pull/41335), [@sunker](https://github.com/sunker) +- **CloudMonitoring:** Fix annotation queries. [#41529](https://github.com/grafana/grafana/pull/41529), [@sunker](https://github.com/sunker) +- **CodeEditor:** Trigger the latest getSuggestions() passed to CodeEditor. [#40544](https://github.com/grafana/grafana/pull/40544), [@DukeManh](https://github.com/DukeManh) +- **Dashboard:** Remove the current panel from the list of options in the Dashboard datasource. [#41826](https://github.com/grafana/grafana/pull/41826), [@ashharrison90](https://github.com/ashharrison90) +- **Encryption:** Fix decrypting secrets in alerting migration. [#41061](https://github.com/grafana/grafana/pull/41061), [@undef1nd](https://github.com/undef1nd) +- **InfluxDB:** Fix corner case where index is too large in ALIAS field. [#41562](https://github.com/grafana/grafana/pull/41562), [@gabor](https://github.com/gabor) +- **NavBar:** Order App plugins alphabetically. [#40078](https://github.com/grafana/grafana/pull/40078), [@ashharrison90](https://github.com/ashharrison90) +- **NodeGraph:** Fix zooming sensitivity on touchpads. [#40718](https://github.com/grafana/grafana/pull/40718), [@aocenas](https://github.com/aocenas) +- **Plugins:** Add OAuth pass-through logic to api/ds/query endpoint. [#41352](https://github.com/grafana/grafana/pull/41352), [@wbrowne](https://github.com/wbrowne) +- **Snapshots:** Fix panel inspector for snapshot data. [#41530](https://github.com/grafana/grafana/pull/41530), [@joshhunt](https://github.com/joshhunt) +- **Tempo:** Fix basic auth password reset on adding tag. [#41808](https://github.com/grafana/grafana/pull/41808), [@aocenas](https://github.com/aocenas) +- **ValueMapping:** Fixes issue with regex mappings. [#41515](https://github.com/grafana/grafana/pull/41515), [@mcdee](https://github.com/mcdee) + +### Plugin development fixes & changes + +- **grafana/ui:** Enable slider marks display. [#41275](https://github.com/grafana/grafana/pull/41275), [@dprokop](https://github.com/dprokop) + + + +# 8.2.7 (2021-12-07) + +- **Security**: Fixes CVE-2021-43798. For more information, see our [blog](https://grafana.com/blog/2021/12/07/grafana-8.3.1-8.2.7-8.1.8-and-8.0.7-released-with-high-severity-security-fix/) + + + + + +# 8.2.6 (2021-12-02) + +### Features and enhancements + +- **Security:** Upgrade Docker base image to Alpine 3.14.3. [#42061](https://github.com/grafana/grafana/pull/42061), [@dsotirakis](https://github.com/dsotirakis) +- **Security:** Upgrade Go to 1.17.2. [#42427](https://github.com/grafana/grafana/pull/42427), [@idafurjes](https://github.com/idafurjes) + +### Bug fixes + +- **TimeSeries:** Fix fillBelowTo wrongly affecting fills of unrelated series. [#41998](https://github.com/grafana/grafana/pull/41998), [@leeoniya](https://github.com/leeoniya) + + + + + +# 8.2.5 (2021-11-18) + +### Bug fixes + +- **Alerting:** Fix a bug where the metric in the evaluation string was not correctly populated. [#41731](https://github.com/grafana/grafana/pull/41731), [@JohnnyQQQQ](https://github.com/JohnnyQQQQ) +- **Alerting:** Fix no data behaviour in Legacy Alerting for alert rules using the AND operator. [#41305](https://github.com/grafana/grafana/pull/41305), [@gerobinson](https://github.com/gerobinson) +- **CloudMonitoring:** Ignore min and max aggregation in MQL queries. [#41302](https://github.com/grafana/grafana/pull/41302), [@sunker](https://github.com/sunker) +- **Dashboards:** 'Copy' is no longer added to new dashboard titles. [#41344](https://github.com/grafana/grafana/pull/41344), [@joshhunt](https://github.com/joshhunt) +- **DataProxy:** Fix overriding response body when response is a WebSocket upgrade. [#41364](https://github.com/grafana/grafana/pull/41364), [@marefr](https://github.com/marefr) +- **Elasticsearch:** Use field configured in query editor as field for date_histogram aggregations. [#41258](https://github.com/grafana/grafana/pull/41258), [@Elfo404](https://github.com/Elfo404) +- **Explore:** Fix running queries without a datasource property set. [#40805](https://github.com/grafana/grafana/pull/40805), [@Elfo404](https://github.com/Elfo404) +- **InfluxDB:** Fix numeric aliases in queries. [#41531](https://github.com/grafana/grafana/pull/41531), [@gabor](https://github.com/gabor) +- **Plugins:** Ensure consistent plugin settings list response. [#41346](https://github.com/grafana/grafana/pull/41346), [@wbrowne](https://github.com/wbrowne) +- **Tempo:** Fix validation of float durations. [#41400](https://github.com/grafana/grafana/pull/41400), [@ivanahuckova](https://github.com/ivanahuckova) +- **Tracing:** Correct tags for each span are shown. [#41473](https://github.com/grafana/grafana/pull/41473), [@ivanahuckova](https://github.com/ivanahuckova) + +### Breaking changes + +### Fix No Data behaviour in Legacy Alerting + +In Grafana 8.2.5 and later, this change fixes a bug in the evaluation of alert rules when using the AND operator to compare two or more conditions. In Grafana 8.2.4 and earlier such alert rules would evaluate to `OK` if at least one, but not all, conditions returned no data. This change fixes that bug such that in Grafana 8.2.5 these alert rules now evaluate to `No Data`. + +If an alert should evaluate to `OK` when one or all conditions return `No Data` then this can be done via changing `If no data or all values are null` to `OK`. However, this will not preserve the old behaviour in 8.2.4 where an alert will be `OK` if at least one, but not all, conditions return no data and then `No Data` if all conditions return `No Data`. Issue [#41305](https://github.com/grafana/grafana/issues/41305) + + + + +# 8.2.4 (2021-11-15) + +- **Security**: Fixes CVE-2021-41244. For more information, see our [blog](https://grafana.com/blog/2021/11/15/grafana-8.2.4-released-with-security-fixes/) + + + + + +# 8.2.3 (2021-11-03) + +- **Security**: Fixes CVE-2021-41174. For more information, see our [blog](https://grafana.com/blog/2021/11/03/grafana-8.2.3-released-with-medium-severity-security-fix-cve-2021-41174-grafana-xss/) + + + + + +# 8.2.2 (2021-10-21) + +### Features and enhancements + +- **Annotations:** We have improved tag search performance. [#40567](https://github.com/grafana/grafana/pull/40567), [@ashharrison90](https://github.com/ashharrison90) +- **Application:** You can now configure an error-template title. [#40310](https://github.com/grafana/grafana/pull/40310), [@benrubson](https://github.com/benrubson) +- **AzureMonitor:** We removed a restriction from the resource filter query. [#40690](https://github.com/grafana/grafana/pull/40690), [@andresmgot](https://github.com/andresmgot) +- **Caching:** Make cache size metric collection optional. (Enterprise) +- **Packaging:** We removed the ProcSubset option in systemd. This option prevented Grafana from starting in LXC environments. [#40339](https://github.com/grafana/grafana/pull/40339), [@kminehart](https://github.com/kminehart) +- **Prometheus:** We removed the autocomplete limit for metrics. [#39363](https://github.com/grafana/grafana/pull/39363), [@ivanahuckova](https://github.com/ivanahuckova) +- **Request interceptor:** Allow MSSQL's named instances. (Enterprise) +- **Table:** We improved the styling of the type icons to make them more distinct from column / field name. [#40596](https://github.com/grafana/grafana/pull/40596), [@torkelo](https://github.com/torkelo) +- **ValueMappings:** You can now use value mapping in stat, gauge, bar gauge, and pie chart visualizations. [#40612](https://github.com/grafana/grafana/pull/40612), [@torkelo](https://github.com/torkelo) + +### Bug fixes + +- **Alerting:** Fix panic when Slack's API sends unexpected response. [#40721](https://github.com/grafana/grafana/pull/40721), [@santihernandezc](https://github.com/santihernandezc) +- **Alerting:** The Create Alert button now appears on the dashboard panel when you are working with a default datasource. [#40334](https://github.com/grafana/grafana/pull/40334), [@domasx2](https://github.com/domasx2) +- **Explore:** We fixed the problem where the Explore log panel disappears when an Elasticsearch logs query returns no results. [#40217](https://github.com/grafana/grafana/pull/40217), [@Elfo404](https://github.com/Elfo404) +- **Graph:** You can now see annotation descriptions on hover. [#40581](https://github.com/grafana/grafana/pull/40581), [@axelavargas](https://github.com/axelavargas) +- **Logs:** The system now uses the JSON parser only if the line is parsed to an object. [#40507](https://github.com/grafana/grafana/pull/40507), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** We fixed the issue where the system did not reuse TCP connections when querying from Grafana alerting. [#40349](https://github.com/grafana/grafana/pull/40349), [@kminehart](https://github.com/kminehart) +- **Prometheus:** We fixed the problem that resulted in an error when a user created a query with a $\_\_interval min step. [#40525](https://github.com/grafana/grafana/pull/40525), [@ivanahuckova](https://github.com/ivanahuckova) +- **RowsToFields:** We fixed the issue where the system was not properly interpreting number values. [#40580](https://github.com/grafana/grafana/pull/40580), [@torkelo](https://github.com/torkelo) +- **Scale:** We fixed how the system handles NaN percent when data min = data max. [#40622](https://github.com/grafana/grafana/pull/40622), [@torkelo](https://github.com/torkelo) +- **Table panel:** You can now create a filter that includes special characters. [#40458](https://github.com/grafana/grafana/pull/40458), [@dprokop](https://github.com/dprokop) + + + + +# 8.2.1 (2021-10-11) + +### Bug fixes + +- **Dashboard:** Fix rendering of repeating panels. [#39991](https://github.com/grafana/grafana/pull/39991), [@hugohaggmark](https://github.com/hugohaggmark) +- **Datasources:** Fix deletion of data source if plugin is not found. [#40095](https://github.com/grafana/grafana/pull/40095), [@jackw](https://github.com/jackw) +- **Packaging:** Remove systemcallfilters sections from systemd unit files. [#40176](https://github.com/grafana/grafana/pull/40176), [@kminehart](https://github.com/kminehart) +- **Prometheus:** Add Headers to HTTP client options. [#40214](https://github.com/grafana/grafana/pull/40214), [@dsotirakis](https://github.com/dsotirakis) + + + + +# 8.2.0 (2021-10-07) + +### Features and enhancements + +- **AWS:** Updated AWS authentication documentation. [#39236](https://github.com/grafana/grafana/pull/39236), [@sunker](https://github.com/sunker) +- **Alerting:** Added support Alertmanager data source for upstream Prometheus AM implementation. [#39775](https://github.com/grafana/grafana/pull/39775), [@domasx2](https://github.com/domasx2) +- **Alerting:** Allows more characters in label names so notifications are sent. [#38629](https://github.com/grafana/grafana/pull/38629), [@gotjosh](https://github.com/gotjosh) +- **Alerting:** Get alert rules for a dashboard or a panel using /api/v1/rules endpoints. [#39476](https://github.com/grafana/grafana/pull/39476), [@gerobinson](https://github.com/gerobinson) +- **Annotations:** Improved rendering performance of event markers. [#39984](https://github.com/grafana/grafana/pull/39984), [@torkelo](https://github.com/torkelo) +- **CloudWatch Logs:** Skip caching for log queries. [#39860](https://github.com/grafana/grafana/pull/39860), [@aocenas](https://github.com/aocenas) +- **Explore:** Added an opt-in configuration for Node Graph in Jaeger, Zipkin, and Tempo. [#39958](https://github.com/grafana/grafana/pull/39958), [@connorlindsey](https://github.com/connorlindsey) +- **Packaging:** Add stricter systemd unit options. [#38109](https://github.com/grafana/grafana/pull/38109), [@erdnaxe](https://github.com/erdnaxe) +- **Prometheus:** Metrics browser can now handle label values with special characters. [#39713](https://github.com/grafana/grafana/pull/39713), [@gabor](https://github.com/gabor) + +### Bug fixes + +- **CodeEditor:** Ensure that we trigger the latest onSave callback provided to the component. [#39835](https://github.com/grafana/grafana/pull/39835), [@mckn](https://github.com/mckn) +- **DashboardList/AlertList:** Fix for missing All folder value. [#39772](https://github.com/grafana/grafana/pull/39772), [@hugohaggmark](https://github.com/hugohaggmark) + +### Breaking changes + +#### Potential failure to start in Ubuntu 18.04 / Debian 9 / CentOS + +- In Grafana v8.2.0, this change can prevent the `grafana-server` service from starting on older versions of systemd, present on Ubuntu 18.04 and slightly older versions of Debian. If running one of those versions, please wait until v8.2.1 is released before upgrading. If you still want to upgrade or have already ugpraded, a simple fix is available here: https://github.com/grafana/grafana/issues/40162#issuecomment-938060240 Issue [#38109](https://github.com/grafana/grafana/issues/38109) + +### Plugin development fixes & changes + +- **Plugins:** Create a mock icon component to prevent console errors. [#39901](https://github.com/grafana/grafana/pull/39901), [@jackw](https://github.com/jackw) + + + + +# 8.2.0-beta2 (2021-09-30) + +### Features and enhancements + +- **AccessControl:** Document new permissions restricting data source access. [#39091](https://github.com/grafana/grafana/pull/39091), [@gamab](https://github.com/gamab) +- **TimePicker:** Add fiscal years and search to time picker. [#39073](https://github.com/grafana/grafana/pull/39073), [@oscarkilhed](https://github.com/oscarkilhed) +- **Alerting:** Added support for Unified Alerting with Grafana HA. [#37920](https://github.com/grafana/grafana/pull/37920), [@gotjosh](https://github.com/gotjosh) +- **Alerting:** Added support for tune rule evaluation using configuration options. [#35623](https://github.com/grafana/grafana/pull/35623), [@papagian](https://github.com/papagian) +- **Alerting:** Cleanups alertmanager namespace from key-value store when disabling Grafana 8 alerts. [#39554](https://github.com/grafana/grafana/pull/39554), [@papagian](https://github.com/papagian) +- **Alerting:** Remove `ngalert` feature toggle and introduce two new settings for enabling Grafana 8 alerts and disabling them for specific organisations. [#38746](https://github.com/grafana/grafana/pull/38746), [@papagian](https://github.com/papagian) +- **CloudWatch:** Introduced new math expression where it is necessary to specify the period field. [#39458](https://github.com/grafana/grafana/pull/39458), [@sunker](https://github.com/sunker) +- **InfluxDB:** Added support for $\_\_interval and $\_\_interval_ms in Flux queries for alerting. [#38889](https://github.com/grafana/grafana/pull/38889), [@gabor](https://github.com/gabor) +- **InfluxDB:** Flux queries can use more precise start and end timestamps with nanosecond-precision. [#39415](https://github.com/grafana/grafana/pull/39415), [@gabor](https://github.com/gabor) +- **Plugins Catalog:** Make the catalog the default way to interact with plugins. [#39779](https://github.com/grafana/grafana/pull/39779), [@leventebalogh](https://github.com/leventebalogh) +- **Prometheus:** Removed autocomplete limit for metrics. [#39363](https://github.com/grafana/grafana/pull/39363), [@ivanahuckova](https://github.com/ivanahuckova) + +### Bug fixes + +- **Alerting:** Fixed an issue where the edit page crashes if you tried to preview an alert without a condition set. [#39659](https://github.com/grafana/grafana/pull/39659), [@peterholmberg](https://github.com/peterholmberg) +- **Alerting:** Fixed rules migration to keep existing Grafana 8 alert rules. [#39541](https://github.com/grafana/grafana/pull/39541), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Alerting:** Fixed the silence file content generated during migration. [#39557](https://github.com/grafana/grafana/pull/39557), [@papagian](https://github.com/papagian) +- **Analytics:** Fixed an issue related to interaction event propagation in Azure Application Insights. [#39752](https://github.com/grafana/grafana/pull/39752), [@sunker](https://github.com/sunker) +- **BarGauge:** Fixed an issue where the cell color was lit even though there was no data. [#39574](https://github.com/grafana/grafana/pull/39574), [@ashharrison90](https://github.com/ashharrison90) +- **BarGauge:** Improved handling of streaming data. [#39737](https://github.com/grafana/grafana/pull/39737), [@ashharrison90](https://github.com/ashharrison90) +- **CloudMonitoring:** Fixed INT64 label unmarshal error. [#39441](https://github.com/grafana/grafana/pull/39441), [@bspellmeyer](https://github.com/bspellmeyer) +- **ConfirmModal:** Fixes confirm button focus on modal open. [#39328](https://github.com/grafana/grafana/pull/39328), [@torkelo](https://github.com/torkelo) +- **Dashboard:** Add option to generate short URL for variables with values containing spaces. [#39552](https://github.com/grafana/grafana/pull/39552), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore:** No longer hides errors containing refId property. [#39504](https://github.com/grafana/grafana/pull/39504), [@Elfo404](https://github.com/Elfo404) +- Fixed an issue that produced State timeline panel tooltip error when data was not in sync. [#39438](https://github.com/grafana/grafana/pull/39438), [@zoltanbedi](https://github.com/zoltanbedi) +- **InfluxDB:** InfluxQL query editor is set to always use resultFormat. [#39330](https://github.com/grafana/grafana/pull/39330), [@gabor](https://github.com/gabor) +- **Loki:** Fixed creating context query for logs with parsed labels. [#39648](https://github.com/grafana/grafana/pull/39648), [@ivanahuckova](https://github.com/ivanahuckova) +- **PageToolbar:** Fixed alignment of titles. [#39572](https://github.com/grafana/grafana/pull/39572), [@ashharrison90](https://github.com/ashharrison90) +- **Plugins Catalog:** Update to the list of available panels after an install, update or uninstall. [#39293](https://github.com/grafana/grafana/pull/39293), [@leventebalogh](https://github.com/leventebalogh) +- **TimeSeries:** Fixed an issue where the shared cursor was not showing when hovering over in old Graph panel. [#39738](https://github.com/grafana/grafana/pull/39738), [@zoltanbedi](https://github.com/zoltanbedi) +- **Variables:** Fixed issues related to change of focus or refresh pages when pressing enter in a text box variable input. [#39666](https://github.com/grafana/grafana/pull/39666), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables:** Panel no longer crash when using the adhoc variable in data links. [#39546](https://github.com/grafana/grafana/pull/39546), [@hugohaggmark](https://github.com/hugohaggmark) + +### Breaking changes + +Grafana v8.2.0-beta1 caused data loss for users having enabled `ngalert` in 8.0.x - 8.1.x and created alerts using the new alerting system. This issue is now fixed except if the deployment has multiple organizations and the feature flag was enabled in the previous version (8.0.x - 8.1.x). + +In this scenario (upgrade from 8.0.x - 8.1.x with multiple organizations and `ngalert` enabled to 8.2.0-beta2), the migration will assign existing notification policies and contact points to the first organization and then apply the default alertmanager configuration to all organizations. This will effectively reset notification policies for _all_ organizations. Issue [#39541](https://github.com/grafana/grafana/issues/39541) + +### Deprecations + +`ngalert` feature toggle it has been deprecated it will be removed in a future release. To enable Grafana 8 alerts, modify your configuration and: + +- in the `unified_alerting` section set the `enabled` property to `true` +- in the `alerting` section set the `enabled` property to `false` Issue [#38746](https://github.com/grafana/grafana/issues/38746) + + + + +# 8.2.0-beta1 (2021-09-16) + +### Features and enhancements + +- **AccessControl:** Introduce new permissions to restrict access for reloading provisioning configuration. [#38906](https://github.com/grafana/grafana/pull/38906), [@vtorosyan](https://github.com/vtorosyan) +- **Admin:** Update license page UI. (Enterprise) +- **Alerting:** Add UI to edit Cortex/Loki namespace, group names, and group evaluation interval. [#38543](https://github.com/grafana/grafana/pull/38543), [@domasx2](https://github.com/domasx2) +- **Alerting:** Add a Test button to test contact point. [#37475](https://github.com/grafana/grafana/pull/37475), [@domasx2](https://github.com/domasx2) +- **Alerting:** Allow creating/editing recording rules for Loki and Cortex. [#38064](https://github.com/grafana/grafana/pull/38064), [@domasx2](https://github.com/domasx2) +- **Alerting:** Metrics should have the label `org` instead of `user`. [#39353](https://github.com/grafana/grafana/pull/39353), [@gotjosh](https://github.com/gotjosh) +- **Alerting:** Sort notification channels by name to make them easier to locate. [#37426](https://github.com/grafana/grafana/pull/37426), [@jstangroome](https://github.com/jstangroome) +- **Alerting:** Support org level isolation of notification configuration. [#37414](https://github.com/grafana/grafana/pull/37414), [@papagian](https://github.com/papagian) +- **AzureMonitor:** Add data links to deep link to Azure Portal Azure Resource Graph. [#35591](https://github.com/grafana/grafana/pull/35591), [@shuotli](https://github.com/shuotli) +- **AzureMonitor:** Add support for annotations from Azure Monitor Metrics and Azure Resource Graph services. [#37633](https://github.com/grafana/grafana/pull/37633), [@joshhunt](https://github.com/joshhunt) +- **AzureMonitor:** Show error message when subscriptions request fails in ConfigEditor. [#37837](https://github.com/grafana/grafana/pull/37837), [@joshhunt](https://github.com/joshhunt) +- **Chore:** Update to Golang 1.16.7. [#38604](https://github.com/grafana/grafana/pull/38604), [@dsotirakis](https://github.com/dsotirakis) +- **CloudWatch Logs:** Add link to X-Ray data source for trace IDs in logs. [#39135](https://github.com/grafana/grafana/pull/39135), [@aocenas](https://github.com/aocenas) +- **CloudWatch Logs:** Disable query path using websockets (Live) feature. [#39231](https://github.com/grafana/grafana/pull/39231), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs:** Don't group dataframes for non time series queries. [#37998](https://github.com/grafana/grafana/pull/37998), [@aocenas](https://github.com/aocenas) +- **Cloudwatch:** Migrate queries that use multiple stats to one query per stat. [#36925](https://github.com/grafana/grafana/pull/36925), [@sunker](https://github.com/sunker) +- **Dashboard:** Keep live timeseries moving left (v2). [#37769](https://github.com/grafana/grafana/pull/37769), [@ryantxu](https://github.com/ryantxu) +- **Datasources:** Introduce `response_limit` for datasource responses. [#38962](https://github.com/grafana/grafana/pull/38962), [@dsotirakis](https://github.com/dsotirakis) +- **Explore:** Add filter by trace or span ID to `trace to logs` feature. [#38943](https://github.com/grafana/grafana/pull/38943), [@connorlindsey](https://github.com/connorlindsey) +- **Explore:** Download traces as JSON in Explore Inspector. [#38614](https://github.com/grafana/grafana/pull/38614), [@connorlindsey](https://github.com/connorlindsey) +- **Explore:** Reuse Dashboard's QueryRows component. [#38942](https://github.com/grafana/grafana/pull/38942), [@Elfo404](https://github.com/Elfo404) +- **Explore:** Support custom display label for derived fields buttons for Loki datasource. [#37273](https://github.com/grafana/grafana/pull/37273), [@connorlindsey](https://github.com/connorlindsey) +- **Grafana UI:** Update monaco-related dependencies. [#39027](https://github.com/grafana/grafana/pull/39027), [@gabor](https://github.com/gabor) +- **Graphite:** Deprecate browser access mode. [#38783](https://github.com/grafana/grafana/pull/38783), [@ifrost](https://github.com/ifrost) +- **InfluxDB:** Improve handling of intervals in alerting. [#37588](https://github.com/grafana/grafana/pull/37588), [@gabor](https://github.com/gabor) +- **InfluxDB:** InfluxQL query editor: Handle unusual characters in tag values better. [#39170](https://github.com/grafana/grafana/pull/39170), [@gabor](https://github.com/gabor) +- Introduce "monitored queries" service. (Enterprise) +- **Jaeger:** Add ability to upload JSON file for trace data. [#37205](https://github.com/grafana/grafana/pull/37205), [@zoltanbedi](https://github.com/zoltanbedi) +- **LibraryElements:** Enable specifying UID for new and existing library elements. [#39019](https://github.com/grafana/grafana/pull/39019), [@hugohaggmark](https://github.com/hugohaggmark) +- **LibraryPanels:** Remove library panel icon from the panel header so you can no longer tell that a panel is a library panel from the dashboard view. [#38749](https://github.com/grafana/grafana/pull/38749), [@hugohaggmark](https://github.com/hugohaggmark) +- **Logs panel:** Scroll to the bottom on page refresh when sorting in ascending order. [#37634](https://github.com/grafana/grafana/pull/37634), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki:** Add fuzzy search to label browser. [#36864](https://github.com/grafana/grafana/pull/36864), [@connorlindsey](https://github.com/connorlindsey) +- **Navigation:** Implement active state for items in the Sidemenu. [#39030](https://github.com/grafana/grafana/pull/39030), [@ashharrison90](https://github.com/ashharrison90) +- **Packaging:** Add stricter systemd unit options. [#38109](https://github.com/grafana/grafana/pull/38109), [@erdnaxe](https://github.com/erdnaxe) +- **Packaging:** Update PID file location from `/var/run` to `/run`. [#35739](https://github.com/grafana/grafana/pull/35739), [@MichaIng](https://github.com/MichaIng) +- **Plugins:** Add Hide OAuth Forward config option. [#36306](https://github.com/grafana/grafana/pull/36306), [@wbrowne](https://github.com/wbrowne) +- **Postgres/MySQL/MSSQL:** Add setting to limit the maximum number of rows processed. [#38986](https://github.com/grafana/grafana/pull/38986), [@marefr](https://github.com/marefr) +- **Prometheus:** Add browser access mode deprecation warning. [#37578](https://github.com/grafana/grafana/pull/37578), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Add interpolation for built-in-time variables to backend. [#39051](https://github.com/grafana/grafana/pull/39051), [@ivanahuckova](https://github.com/ivanahuckova) +- **Recorded Queries:** Finish rest API endpoints. (Enterprise) +- **Reporting:** enable creating reports from dashboard. (Enterprise) +- **Tempo:** Add ability to upload trace data in JSON format. [#37407](https://github.com/grafana/grafana/pull/37407), [@zoltanbedi](https://github.com/zoltanbedi) +- **TimeSeries/XYChart:** Allow grid lines visibility control in XYChart and TimeSeries panels. [#38502](https://github.com/grafana/grafana/pull/38502), [@dprokop](https://github.com/dprokop) +- **Transformations:** Convert field types to time string number or boolean. [#38517](https://github.com/grafana/grafana/pull/38517), [@nikki-kiga](https://github.com/nikki-kiga) +- **Usage Insights:** Support writing events to Grafana's log. (Enterprise) +- **Value mappings:** Add regular-expression based value mapping. [#38931](https://github.com/grafana/grafana/pull/38931), [@mcdee](https://github.com/mcdee) +- **Zipkin:** Add ability to upload trace JSON. [#37483](https://github.com/grafana/grafana/pull/37483), [@zoltanbedi](https://github.com/zoltanbedi) + +### Bug fixes + +- **Admin:** Prevent user from deleting user's current/active organization. [#38056](https://github.com/grafana/grafana/pull/38056), [@idafurjes](https://github.com/idafurjes) +- **LibraryPanels:** Fix library panel getting saved in the dashboard's folder. [#38978](https://github.com/grafana/grafana/pull/38978), [@hugohaggmark](https://github.com/hugohaggmark) +- **OAuth:** Make generic teams URL and JMES path configurable. [#37233](https://github.com/grafana/grafana/pull/37233), [@djairhogeuens](https://github.com/djairhogeuens) +- **QueryEditor:** Fix broken copy-paste for mouse middle-click (#39117). [#39117](https://github.com/grafana/grafana/pull/39117), [@glintik](https://github.com/glintik) +- **Thresholds:** Fix undefined color in "Add threshold". [#39113](https://github.com/grafana/grafana/pull/39113), [@glintik](https://github.com/glintik) +- **Timeseries:** Add wide-to-long, and fix multi-frame output. [#38670](https://github.com/grafana/grafana/pull/38670), [@ryantxu](https://github.com/ryantxu) +- **TooltipPlugin:** Fix behavior of Shared Crosshair when Tooltip is set to All. [#37285](https://github.com/grafana/grafana/pull/37285), [@nikki-kiga](https://github.com/nikki-kiga) + +### Breaking changes + +The `monaco-editor` dependency in `grafana-ui` has been updated to a newer version (`0.27.0`), which is not completely backward compatible with the old version (`0.21.2`). The backward incompatible changes are fairly small, but they do exist, so if your code accesses the raw monaco-objects through the `grafana-ui` package, please check the [monaco-editor changelog](https://github.com/microsoft/monaco-editor/blob/main/CHANGELOG.md) and apply any necessary changes. Issue [#39027](https://github.com/grafana/grafana/issues/39027) + +The mandatory `css` prop in `grafana/ui` components has been removed. + +Previous versions of `grafana/ui` components were typed incorrectly due to a dependency mismatch between emotion 10 and 11 causing a `css` prop to be added to components that extended react types. +Issue [#38078](https://github.com/grafana/grafana/issues/38078) + +### Unified Alerting (Grafana 8 Alerting) data loss + +Grafana v8.2 fixed an issue with org isolation for notification configuration but to fix this Grafana will now re-run the migration from old alerting and this will cause complete removal of all new alert rules and notification configurations. This data loss is not something we find acceptable and are working on ways to mitigate it. So in the meantime, if you are an early adopter of unified alerting please wait with trying v8.2 beta. +Issue [#37414](https://github.com/grafana/grafana/issues/37414) + +Panel queries and/or annotation queries that used more than one statistic will be converted into one query/annotation per statistic. In case an alerting rule was based on a query row that had more than one statistic, it would now be based only on the first statistic for that query row. New alerting rules will not be created for migrated queries. Please note that in most cases it would not make sense to have an alerting rule that is based on multiple statistics anyway. Issue [#36925](https://github.com/grafana/grafana/issues/36925) + +### Deprecations + +`getHighlighterExpressions` in datasource APIs ( used to highlight logs while editing queries) has been deprecated and will be removed in a future release. + +# Deprecation notice + +`ExploreQueryFieldProps` interface for query editors has been deprecated and will be removed in a future release. Use `QueryEditorProps` instead. Issue [#38942](https://github.com/grafana/grafana/issues/38942) + +### Plugin development fixes & changes + +- **Grafana UI:** Fix TS error property `css` is missing in type. [#38078](https://github.com/grafana/grafana/pull/38078), [@jackw](https://github.com/jackw) + + + + + +# 8.1.8 (2021-12-07) + +- **Security**: Fixes CVE-2021-43798. For more information, see our [blog](https://grafana.com/blog/2021/12/07/grafana-8.3.1-8.2.7-8.1.8-and-8.0.7-released-with-high-severity-security-fix/) + + + + + +# 8.1.7 (2021-10-06) + +### Bug fixes + +- **Alerting:** Fix alerts with evaluation interval more than 30 seconds resolving before notification. [#39513](https://github.com/grafana/grafana/pull/39513), [@gerobinson](https://github.com/gerobinson) +- **Elasticsearch/Prometheus:** Fix usage of proper SigV4 service namespace. [#39439](https://github.com/grafana/grafana/pull/39439), [@marefr](https://github.com/marefr) + + + + + +# 8.1.6 (2021-10-05) + +- **Security**: Fixes CVE-2021-39226. For more information, see our [blog](https://grafana.com/blog/2021/10/05/grafana-7.5.11-and-8.1.6-released-with-critical-security-fix/) + + + + + +# 8.1.5 (2021-09-21) + +### Bug fixes + +- **BarChart:** Fixes panel error that happens on second refresh. [#39304](https://github.com/grafana/grafana/pull/39304), [@DanCech](https://github.com/DanCech) + + + + + +# 8.1.4 (2021-09-16) + +### Features and enhancements + +- **Explore:** Ensure logs volume bar colors match legend colors. [#39072](https://github.com/grafana/grafana/pull/39072), [@ifrost](https://github.com/ifrost) +- **LDAP:** Search all DNs for users. [#38891](https://github.com/grafana/grafana/pull/38891), [@sakjur](https://github.com/sakjur) + +### Bug fixes + +- **Alerting:** Fix notification channel migration. [#38983](https://github.com/grafana/grafana/pull/38983), [@papagian](https://github.com/papagian) +- **Annotations:** Fix blank panels for queries with unknown data sources. [#39017](https://github.com/grafana/grafana/pull/39017), [@hugohaggmark](https://github.com/hugohaggmark) +- **BarChart:** Fix stale values and x axis labels. [#39188](https://github.com/grafana/grafana/pull/39188), [@leeoniya](https://github.com/leeoniya) +- **Graph:** Make old graph panel thresholds work even if ngalert is enabled. [#38918](https://github.com/grafana/grafana/pull/38918), [@domasx2](https://github.com/domasx2) +- **InfluxDB:** Fix regex to identify `/` as separator. [#39185](https://github.com/grafana/grafana/pull/39185), [@dsotirakis](https://github.com/dsotirakis) +- **LibraryPanels:** Fix update issues related to library panels in rows. [#38963](https://github.com/grafana/grafana/pull/38963), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables:** Fix variables not updating inside a Panel when the preceding Row uses "Repeat For". [#38935](https://github.com/grafana/grafana/pull/38935), [@axelavargas](https://github.com/axelavargas) + + + + +# 8.1.3 (2021-09-08) + +### Bug fixes + +- **Alerting:** Fix alert flapping in the internal alertmanager. [#38648](https://github.com/grafana/grafana/pull/38648), [@gotjosh](https://github.com/gotjosh) +- **Alerting:** Fix request handler failed to convert dataframe "results" to plugins.DataTimeSeriesSlice: input frame is not recognized as a time series. [#38587](https://github.com/grafana/grafana/pull/38587), [@idafurjes](https://github.com/idafurjes) +- **Dashboard:** Fix UIDs are not preserved when importing/creating dashboards thru importing .json file. [#38659](https://github.com/grafana/grafana/pull/38659), [@axelavargas](https://github.com/axelavargas) +- **Dashboard:** Forces panel re-render when exiting panel edit. [#38913](https://github.com/grafana/grafana/pull/38913), [@hugohaggmark](https://github.com/hugohaggmark) +- **Dashboard:** Prevent folder from changing when navigating to general settings. [#38103](https://github.com/grafana/grafana/pull/38103), [@hugohaggmark](https://github.com/hugohaggmark) +- **Docker:** Force use of libcrypto1.1 and libssl1.1 versions to fix CVE-2021-3711. [#38585](https://github.com/grafana/grafana/pull/38585), [@dsotirakis](https://github.com/dsotirakis) +- **Elasticsearch:** Fix metric names for alert queries. [#38546](https://github.com/grafana/grafana/pull/38546), [@dsotirakis](https://github.com/dsotirakis) +- **Elasticsearch:** Limit Histogram field parameter to numeric values. [#38631](https://github.com/grafana/grafana/pull/38631), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch:** Prevent pipeline aggregations to show up in terms order by options. [#38448](https://github.com/grafana/grafana/pull/38448), [@Elfo404](https://github.com/Elfo404) +- **LibraryPanels:** Prevent duplicate repeated panels from being created. [#38804](https://github.com/grafana/grafana/pull/38804), [@hugohaggmark](https://github.com/hugohaggmark) +- **Loki:** Fix ad-hoc filter in dashboard when used with parser. [#38542](https://github.com/grafana/grafana/pull/38542), [@ivanahuckova](https://github.com/ivanahuckova) +- **Plugins:** Track signed files + add warn log for plugin assets which are not signed. [#38938](https://github.com/grafana/grafana/pull/38938), [@wbrowne](https://github.com/wbrowne) +- **Postgres/MySQL/MSSQL:** Fix region annotations not displayed correctly. [#38936](https://github.com/grafana/grafana/pull/38936), [@marefr](https://github.com/marefr) +- **Prometheus:** Fix validate selector in metrics browser. [#38921](https://github.com/grafana/grafana/pull/38921), [@ivanahuckova](https://github.com/ivanahuckova) +- **Security:** Fix stylesheet injection vulnerability [#38432](https://github.com/grafana/grafana/pull/38432), [@idafurjes](https://github.com/idafurjes). Big thanks to Tobias Hamann and Lauritz Holtmann of usd AG for reporting this issue. +- **Security:** Fix short URL vulnerability [#38436](https://github.com/grafana/grafana/pull/38436), [@idafurjes](https://github.com/idafurjes). Big thanks to Tobias Hamann and Lauritz Holtmann of usd AG for reporting this issue. + + + + +# 8.1.2 (2021-08-19) + +### Features and enhancements + +- **AzureMonitor:** Add support for PostgreSQL and MySQL Flexible Servers. [#38075](https://github.com/grafana/grafana/pull/38075), [@joshhunt](https://github.com/joshhunt) +- **Datasource:** Change HTTP status code for failed datasource health check to 400. [#37895](https://github.com/grafana/grafana/pull/37895), [@stephaniehingtgen](https://github.com/stephaniehingtgen) +- **Explore:** Add span duration to left panel in trace viewer. [#37806](https://github.com/grafana/grafana/pull/37806), [@connorlindsey](https://github.com/connorlindsey) +- **Plugins:** Use file extension allowlist when serving plugin assets instead of checking for UNIX executable. [#37688](https://github.com/grafana/grafana/pull/37688), [@wbrowne](https://github.com/wbrowne) +- **Profiling:** Add support for binding pprof server to custom network interfaces. [#36580](https://github.com/grafana/grafana/pull/36580), [@cinaglia](https://github.com/cinaglia) +- **Search:** Make search icon keyboard navigable. [#37865](https://github.com/grafana/grafana/pull/37865), [@tskarhed](https://github.com/tskarhed) +- **Template variables:** Keyboard navigation improvements. [#38001](https://github.com/grafana/grafana/pull/38001), [@tskarhed](https://github.com/tskarhed) +- **Tooltip:** Display ms within minute time range. [#37569](https://github.com/grafana/grafana/pull/37569), [@nikki-kiga](https://github.com/nikki-kiga) + +### Bug fixes + +- **Alerting:** Fix saving LINE contact point. [#37744](https://github.com/grafana/grafana/pull/37744), [@xy-man](https://github.com/xy-man) +- **Alerting:** Fix saving LINE contact point. [#37718](https://github.com/grafana/grafana/pull/37718), [@xy-man](https://github.com/xy-man) +- **Annotations:** Fix alerting annotation coloring. [#37412](https://github.com/grafana/grafana/pull/37412), [@kylebrandt](https://github.com/kylebrandt) +- **Annotations:** Alert annotations are now visible in the correct Panel. [#37959](https://github.com/grafana/grafana/pull/37959), [@hugohaggmark](https://github.com/hugohaggmark) +- **Auth:** Hide SigV4 config UI and disable middleware when its config flag is disabled. [#37293](https://github.com/grafana/grafana/pull/37293), [@wbrowne](https://github.com/wbrowne) +- **Dashboard:** Prevent incorrect panel layout by comparing window width against theme breakpoints. [#37868](https://github.com/grafana/grafana/pull/37868), [@ashharrison90](https://github.com/ashharrison90) +- **Elasticsearch:** Fix metric names for alert queries. [#37871](https://github.com/grafana/grafana/pull/37871), [@dsotirakis](https://github.com/dsotirakis) +- **Explore:** Fix showing of full log context. [#37442](https://github.com/grafana/grafana/pull/37442), [@ivanahuckova](https://github.com/ivanahuckova) +- **PanelEdit:** Fix 'Actual' size by passing the correct panel size to Das…. [#37885](https://github.com/grafana/grafana/pull/37885), [@ashharrison90](https://github.com/ashharrison90) +- **Plugins:** Fix TLS datasource settings. [#37797](https://github.com/grafana/grafana/pull/37797), [@wbrowne](https://github.com/wbrowne) +- **Variables:** Fix issue with empty drop downs on navigation. [#37776](https://github.com/grafana/grafana/pull/37776), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables:** Fix URL util converting `false` into `true`. [#37402](https://github.com/grafana/grafana/pull/37402), [@simPod](https://github.com/simPod) + +### Plugin development fixes & changes + +- **Toolkit:** Fix matchMedia not found error. [#37643](https://github.com/grafana/grafana/pull/37643), [@zoltanbedi](https://github.com/zoltanbedi) + + + + +# 8.1.1 (2021-08-09) + +### Bug fixes + +- **CloudWatch Logs:** Fix crash when no region is selected. [#37639](https://github.com/grafana/grafana/pull/37639), [@aocenas](https://github.com/aocenas) +- **Reporting:** Fix timezone parsing for scheduler. (Enterprise) + + + + +# 8.1.0 (2021-08-05) + +### Features and enhancements + +- **Alerting:** Deduplicate receivers during migration. [#36812](https://github.com/grafana/grafana/pull/36812), [@codesome](https://github.com/codesome) +- **ColorPicker:** Display colors as RGBA. [#37231](https://github.com/grafana/grafana/pull/37231), [@nikki-kiga](https://github.com/nikki-kiga) +- **Encryption:** Add support for multiple encryption algorithms (aes-gcm). (Enterprise) +- **Select:** Make portalling the menu opt-in, but opt-in _everywhere_. [#37501](https://github.com/grafana/grafana/pull/37501), [@ashharrison90](https://github.com/ashharrison90) +- **TeamSync:** Batch team synchronization. (Enterprise) +- **TimeRangePicker:** Improve accessibility. [#36912](https://github.com/grafana/grafana/pull/36912), [@tskarhed](https://github.com/tskarhed) + +### Bug fixes + +- **Annotations:** Correct annotations that are displayed upon page refresh. [#37496](https://github.com/grafana/grafana/pull/37496), [@axelavargas](https://github.com/axelavargas) +- **Annotations:** Fix **Enabled** button that disappeared from Grafana v8.0.6. [#37454](https://github.com/grafana/grafana/pull/37454), [@axelavargas](https://github.com/axelavargas) +- **Annotations:** Fix data source template variable that was not available for annotations. [#37506](https://github.com/grafana/grafana/pull/37506), [@axelavargas](https://github.com/axelavargas) +- **AzureMonitor:** Fix annotations query editor that does not load. [#37476](https://github.com/grafana/grafana/pull/37476), [@torkelo](https://github.com/torkelo) +- **Geomap:** Fix scale calculations. [#37375](https://github.com/grafana/grafana/pull/37375), [@ryantxu](https://github.com/ryantxu) +- **GraphNG:** Fix y-axis autosizing. [#37464](https://github.com/grafana/grafana/pull/37464), [@leeoniya](https://github.com/leeoniya) +- **Live:** Display stream rate and fix duplicate channels in list response. [#37365](https://github.com/grafana/grafana/pull/37365), [@FZambia](https://github.com/FZambia) +- **Loki:** Update labels in log browser when time range changes. [#37520](https://github.com/grafana/grafana/pull/37520), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki:** Update labels in log browser when time range changes in dashboard. [#37541](https://github.com/grafana/grafana/pull/37541), [@ivanahuckova](https://github.com/ivanahuckova) +- **NGAlert:** Send resolve signal to alertmanager on alerting -> Normal. [#37363](https://github.com/grafana/grafana/pull/37363), [@kylebrandt](https://github.com/kylebrandt) +- **PasswordField:** Prevent a password from being displayed when you click the Enter button. [#37444](https://github.com/grafana/grafana/pull/37444), [@tskarhed](https://github.com/tskarhed) +- **Renderer:** Remove debug.log file when Grafana is stopped. [#37367](https://github.com/grafana/grafana/pull/37367), [@AgnesToulet](https://github.com/AgnesToulet) +- **Security:** Update dependencies to fix CVE-2021-36222. [#37546](https://github.com/grafana/grafana/pull/37546), [@ying-jeanne](https://github.com/ying-jeanne) + + + + + +# 8.1.0-beta3 (2021-07-29) + +### Features and enhancements + +- **Alerting:** Support label matcher syntax in alert rule list filter. [#36408](https://github.com/grafana/grafana/pull/36408), [@nathanrodman](https://github.com/nathanrodman) +- **IconButton:** Put tooltip text as aria-label. [#36760](https://github.com/grafana/grafana/pull/36760), [@tskarhed](https://github.com/tskarhed) +- **Live:** Experimental HA with Redis. [#36787](https://github.com/grafana/grafana/pull/36787), [@FZambia](https://github.com/FZambia) +- **UI:** FileDropzone component. [#36646](https://github.com/grafana/grafana/pull/36646), [@zoltanbedi](https://github.com/zoltanbedi) +- **[v8.1.x] CloudWatch:** Add AWS LookoutMetrics. [#37329](https://github.com/grafana/grafana/pull/37329), [@ilyastoli](https://github.com/ilyastoli) + +### Bug fixes + +- **Docker:** Fix builds by delaying go mod verify until all required files are copied over. [#37246](https://github.com/grafana/grafana/pull/37246), [@wbrowne](https://github.com/wbrowne) +- **Exemplars:** Fix disable exemplars only on the query that failed. [#37296](https://github.com/grafana/grafana/pull/37296), [@zoltanbedi](https://github.com/zoltanbedi) +- **SQL:** Fix SQL dataframe resampling (fill mode + time intervals). [#36937](https://github.com/grafana/grafana/pull/36937), [@idafurjes](https://github.com/idafurjes) + + + + + +# 8.1.0-beta2 (2021-07-23) + +### Features and enhancements + +- **Alerting:** Expand the value string in alert annotations and labels. [#37051](https://github.com/grafana/grafana/pull/37051), [@gerobinson](https://github.com/gerobinson) +- **Auth:** Add Azure HTTP authentication middleware. [#36932](https://github.com/grafana/grafana/pull/36932), [@kostrse](https://github.com/kostrse) +- **Auth:** Auth: Pass user role when using the authentication proxy. [#36729](https://github.com/grafana/grafana/pull/36729), [@yuwaMSFT2](https://github.com/yuwaMSFT2) +- **Gazetteer:** Update countries.json file to allow for linking to 3-letter country codes. [#37129](https://github.com/grafana/grafana/pull/37129), [@bryanuribe](https://github.com/bryanuribe) + +### Bug fixes + +- **Config:** Fix Docker builds by correcting formatting in sample.ini. [#37106](https://github.com/grafana/grafana/pull/37106), [@FZambia](https://github.com/FZambia) +- **Explore:** Fix encoding of internal URLs. [#36919](https://github.com/grafana/grafana/pull/36919), [@aocenas](https://github.com/aocenas) + + + + + +# 8.1.0-beta1 (2021-07-22) + +### Features and enhancements + +- **Alerting:** Add Alertmanager notifications tab. [#35759](https://github.com/grafana/grafana/pull/35759), [@nathanrodman](https://github.com/nathanrodman) +- **Alerting:** Add button to deactivate current Alertmanager configuration. [#36951](https://github.com/grafana/grafana/pull/36951), [@domasx2](https://github.com/domasx2) +- **Alerting:** Add toggle in Loki/Prometheus data source configuration to opt out of alerting UI. [#36552](https://github.com/grafana/grafana/pull/36552), [@domasx2](https://github.com/domasx2) +- **Alerting:** Allow any "evaluate for" value >=0 in the alert rule form. [#35807](https://github.com/grafana/grafana/pull/35807), [@domasx2](https://github.com/domasx2) +- **Alerting:** Load default configuration from status endpoint, if Cortex Alertmanager returns empty user configuration. [#35769](https://github.com/grafana/grafana/pull/35769), [@domasx2](https://github.com/domasx2) +- **Alerting:** view to display alert rule and its underlying data. [#35546](https://github.com/grafana/grafana/pull/35546), [@mckn](https://github.com/mckn) +- **Annotation panel:** Release the annotation panel. [#36959](https://github.com/grafana/grafana/pull/36959), [@ryantxu](https://github.com/ryantxu) +- **Annotations:** Add typeahead support for tags in built-in annotations. [#36377](https://github.com/grafana/grafana/pull/36377), [@ashharrison90](https://github.com/ashharrison90) +- **AzureMonitor:** Add curated dashboards for Azure services. [#35356](https://github.com/grafana/grafana/pull/35356), [@avidhanju](https://github.com/avidhanju) +- **AzureMonitor:** Add support for deep links to Microsoft Azure portal for Metrics. [#32273](https://github.com/grafana/grafana/pull/32273), [@shuotli](https://github.com/shuotli) +- **AzureMonitor:** Remove support for different credentials for Azure Monitor Logs. [#35121](https://github.com/grafana/grafana/pull/35121), [@andresmgot](https://github.com/andresmgot) +- **AzureMonitor:** Support querying any Resource for Logs queries. [#33879](https://github.com/grafana/grafana/pull/33879), [@joshhunt](https://github.com/joshhunt) +- **Elasticsearch:** Add frozen indices search support. [#36018](https://github.com/grafana/grafana/pull/36018), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch:** Name fields after template variables values instead of their name. [#36035](https://github.com/grafana/grafana/pull/36035), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch:** add rate aggregation. [#33311](https://github.com/grafana/grafana/pull/33311), [@estermv](https://github.com/estermv) +- **Email:** Allow configuration of content types for email notifications. [#34530](https://github.com/grafana/grafana/pull/34530), [@djairhogeuens](https://github.com/djairhogeuens) +- **Explore:** Add more meta information when line limit is hit. [#33069](https://github.com/grafana/grafana/pull/33069), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore:** UI improvements to trace view. [#34276](https://github.com/grafana/grafana/pull/34276), [@aocenas](https://github.com/aocenas) +- **FieldOverrides:** Added support to change display name in an override field and have it be matched by a later rule. [#35893](https://github.com/grafana/grafana/pull/35893), [@torkelo](https://github.com/torkelo) +- **HTTP Client:** Introduce `dataproxy_max_idle_connections` config variable. [#35864](https://github.com/grafana/grafana/pull/35864), [@dsotirakis](https://github.com/dsotirakis) +- **InfluxDB:** InfluxQL: adds tags to timeseries data. [#36702](https://github.com/grafana/grafana/pull/36702), [@gabor](https://github.com/gabor) +- **InfluxDB:** InfluxQL: make measurement search case insensitive. [#34563](https://github.com/grafana/grafana/pull/34563), [@gabor](https://github.com/gabor) +- **Legacy Alerting:** Replace simplejson with a struct in webhook notification channel. [#34952](https://github.com/grafana/grafana/pull/34952), [@KEVISONG](https://github.com/KEVISONG) +- **Legend:** Updates display name for Last (not null) to just Last\*. [#35633](https://github.com/grafana/grafana/pull/35633), [@torkelo](https://github.com/torkelo) +- **Logs panel:** Add option to show common labels. [#36166](https://github.com/grafana/grafana/pull/36166), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki:** Add $\_\_range variable. [#36175](https://github.com/grafana/grafana/pull/36175), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki:** Add support for "label_values(log stream selector, label)" in templating. [#35488](https://github.com/grafana/grafana/pull/35488), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki:** Add support for ad-hoc filtering in dashboard. [#36393](https://github.com/grafana/grafana/pull/36393), [@ivanahuckova](https://github.com/ivanahuckova) +- **MySQL Datasource:** Add timezone parameter. [#27535](https://github.com/grafana/grafana/pull/27535), [@andipabst](https://github.com/andipabst) +- **NodeGraph:** Show gradient fields in legend. [#34078](https://github.com/grafana/grafana/pull/34078), [@aocenas](https://github.com/aocenas) +- **PanelOptions:** Don't mutate panel options/field config object when updating. [#36441](https://github.com/grafana/grafana/pull/36441), [@dprokop](https://github.com/dprokop) +- **PieChart:** Make pie gradient more subtle to match other charts. [#36961](https://github.com/grafana/grafana/pull/36961), [@nikki-kiga](https://github.com/nikki-kiga) +- **Prometheus:** Update PromQL typeahead and highlighting. [#36730](https://github.com/grafana/grafana/pull/36730), [@ekpdt](https://github.com/ekpdt) +- **Prometheus:** interpolate variable for step field. [#36437](https://github.com/grafana/grafana/pull/36437), [@zoltanbedi](https://github.com/zoltanbedi) +- **Provisioning:** Improve validation by validating across all dashboard providers. [#26742](https://github.com/grafana/grafana/pull/26742), [@nabokihms](https://github.com/nabokihms) +- **Query cache:** Adding an encryption option for caching. (Enterprise) +- **Reporting:** Use start and end dates for scheduling. (Enterprise) +- **SQL Datasources:** Allow multiple string/labels columns with time series. [#36485](https://github.com/grafana/grafana/pull/36485), [@kylebrandt](https://github.com/kylebrandt) +- **Select:** Portal select menu to document.body. [#36398](https://github.com/grafana/grafana/pull/36398), [@ashharrison90](https://github.com/ashharrison90) +- **Team Sync:** Add group mapping to support team sync in the Generic OAuth provider. [#36307](https://github.com/grafana/grafana/pull/36307), [@wardbekker](https://github.com/wardbekker) +- **Tooltip:** Make active series more noticeable. [#36824](https://github.com/grafana/grafana/pull/36824), [@nikki-kiga](https://github.com/nikki-kiga) +- **Tracing:** Add support to configure trace to logs start and end time. [#34995](https://github.com/grafana/grafana/pull/34995), [@zoltanbedi](https://github.com/zoltanbedi) +- **Transformations:** Skip merge when there is only a single data frame. [#36407](https://github.com/grafana/grafana/pull/36407), [@edgarpoce](https://github.com/edgarpoce) +- **ValueMapping:** Added support for mapping text to color, boolean values, NaN and Null. Improved UI for value mapping. [#33820](https://github.com/grafana/grafana/pull/33820), [@torkelo](https://github.com/torkelo) +- **Visualizations:** Dynamically set any config (min, max, unit, color, thresholds) from query results. [#36548](https://github.com/grafana/grafana/pull/36548), [@torkelo](https://github.com/torkelo) +- **live:** Add support to handle origin without a value for the port when matching with root_url. [#36834](https://github.com/grafana/grafana/pull/36834), [@FZambia](https://github.com/FZambia) + +### Bug fixes + +- **Alerting:** Handle marshaling Inf values. [#36947](https://github.com/grafana/grafana/pull/36947), [@kylebrandt](https://github.com/kylebrandt) +- **AzureMonitor:** Fix macro resolution for template variables. [#36944](https://github.com/grafana/grafana/pull/36944), [@andresmgot](https://github.com/andresmgot) +- **AzureMonitor:** Fix queries with Microsoft.NetApp/../../volumes resources. [#32661](https://github.com/grafana/grafana/pull/32661), [@pckls](https://github.com/pckls) +- **AzureMonitor:** Request and concat subsequent resource pages. [#36958](https://github.com/grafana/grafana/pull/36958), [@andresmgot](https://github.com/andresmgot) +- **Bug:** Fix parse duration for day. [#36942](https://github.com/grafana/grafana/pull/36942), [@idafurjes](https://github.com/idafurjes) +- **Datasources:** Improve error handling for error messages. [#35120](https://github.com/grafana/grafana/pull/35120), [@ifrost](https://github.com/ifrost) +- **Explore:** Correct the functionality of shift-enter shortcut across all uses. [#36600](https://github.com/grafana/grafana/pull/36600), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore:** Show all dataFrames in data tab in Inspector. [#32161](https://github.com/grafana/grafana/pull/32161), [@ivanahuckova](https://github.com/ivanahuckova) +- **GraphNG:** Fix Tooltip mode 'All' for XYChart. [#31260](https://github.com/grafana/grafana/pull/31260), [@Posnet](https://github.com/Posnet) +- **Loki:** Fix highlight of logs when using filter expressions with backticks. [#36024](https://github.com/grafana/grafana/pull/36024), [@ivanahuckova](https://github.com/ivanahuckova) +- **Modal:** Force modal content to overflow with scroll. [#36754](https://github.com/grafana/grafana/pull/36754), [@ashharrison90](https://github.com/ashharrison90) +- **Plugins:** Ignore symlinked folders when verifying plugin signature. [#34434](https://github.com/grafana/grafana/pull/34434), [@wbrowne](https://github.com/wbrowne) + +### Breaking changes + +When parsing Elasticsearch query responses using template variables, each field gets named after the variable value instead of the name. +For example, executing a `terms` aggregation on a variable named `$groupBy` that has `@hostname` as a value, the resulting column in the table response will be `@hostname` instead of `$groupBy` Issue [#36035](https://github.com/grafana/grafana/issues/36035) + +Azure Monitor data source no longer supports different credentials for Metrics and Logs in existing data sources. To use different credentials for Azure Monitor Logs, create another data source. Issue [#35121](https://github.com/grafana/grafana/issues/35121) + +Existing Azure Metrics Logs queries for Log Analytics Workspaces should be backward compatible with this change and should not get impacted. Panels will be migrated to use the new resource-centric backend when you first edit and save them. + +Application Insights and Insights Analytics queries are now read-only and cannot be modified. To update Application Insights queries, users can manually recreate them as Metrics queries, and Insights Analytics are recreated with Logs. + +Issue [#33879](https://github.com/grafana/grafana/issues/33879) + +### Plugin development fixes & changes + +- **Toolkit:** Improve error messages when tasks fail. [#36381](https://github.com/grafana/grafana/pull/36381), [@joshhunt](https://github.com/joshhunt) + + + + + +# 8.0.7 (2021-12-07) + +- **Security**: Fixes CVE-2021-43798. For more information, see our [blog](https://grafana.com/blog/2021/12/07/grafana-8.3.1-8.2.7-8.1.8-and-8.0.7-released-with-high-severity-security-fix/) + + + + + +# 8.0.6 (2021-07-14) + +### Features and enhancements + +- **Alerting:** Add annotation upon alert state change. [#36535](https://github.com/grafana/grafana/pull/36535), [@davidmparrott](https://github.com/davidmparrott) +- **Alerting:** Allow space in label and annotation names. [#36549](https://github.com/grafana/grafana/pull/36549), [@codesome](https://github.com/codesome) +- **InfluxDB:** Improve legend labels for InfluxDB query results. [#36603](https://github.com/grafana/grafana/pull/36603), [@gabor](https://github.com/gabor) + +### Bug fixes + +- **Alerting:** Fix improper alert by changing the handling of empty labels. [#36679](https://github.com/grafana/grafana/pull/36679), [@davidmparrott](https://github.com/davidmparrott) +- **CloudWatch/Logs:** Reestablish Cloud Watch alert behavior. [#36558](https://github.com/grafana/grafana/pull/36558), [@aocenas](https://github.com/aocenas) +- **Dashboard:** Avoid migration breaking on fieldConfig without defaults field in folded panel. [#36666](https://github.com/grafana/grafana/pull/36666), [@glindstedt](https://github.com/glindstedt) +- **DashboardList:** Fix issue not re-fetching dashboard list after variable change. [#36591](https://github.com/grafana/grafana/pull/36591), [@torkelo](https://github.com/torkelo) +- **Database:** Fix incorrect format of isolation level configuration parameter for MySQL. [#36565](https://github.com/grafana/grafana/pull/36565), [@marefr](https://github.com/marefr) +- **InfluxDB:** Correct tag filtering on InfluxDB data. [#36570](https://github.com/grafana/grafana/pull/36570), [@gabor](https://github.com/gabor) +- **Links:** Fix links that caused a full page reload. [#36631](https://github.com/grafana/grafana/pull/36631), [@torkelo](https://github.com/torkelo) +- **Live:** Fix HTTP error when InfluxDB metrics have an incomplete or asymmetrical field set. [#36664](https://github.com/grafana/grafana/pull/36664), [@FZambia](https://github.com/FZambia) +- **Postgres/MySQL/MSSQL:** Change time field to "Time" for time series queries. [#36720](https://github.com/grafana/grafana/pull/36720), [@marefr](https://github.com/marefr) +- **Postgres:** Fix the handling of a null return value in query results. [#36648](https://github.com/grafana/grafana/pull/36648), [@idafurjes](https://github.com/idafurjes) +- **Tempo:** Show hex strings instead of uints for IDs. [#36471](https://github.com/grafana/grafana/pull/36471), [@zoltanbedi](https://github.com/zoltanbedi) +- **TimeSeries:** Improve tooltip positioning when tooltip overflows. [#36440](https://github.com/grafana/grafana/pull/36440), [@ashharrison90](https://github.com/ashharrison90) +- **Transformations:** Add 'prepare time series' transformer. [#36737](https://github.com/grafana/grafana/pull/36737), [@ryantxu](https://github.com/ryantxu) + + + + + +# 8.0.5 (2021-07-08) + +### Features and enhancements + +- **Cloudwatch Logs:** Send error down to client. [#36277](https://github.com/grafana/grafana/pull/36277), [@zoltanbedi](https://github.com/zoltanbedi) +- **Folders:** Return 409 Conflict status when folder already exists. [#36429](https://github.com/grafana/grafana/pull/36429), [@dsotirakis](https://github.com/dsotirakis) +- **TimeSeries:** Do not show series in tooltip if it's hidden in the viz. [#36353](https://github.com/grafana/grafana/pull/36353), [@dprokop](https://github.com/dprokop) + +### Bug fixes + +- **AzureMonitor:** Fix issue where resource group name is missing on the resource picker button. [#36400](https://github.com/grafana/grafana/pull/36400), [@joshhunt](https://github.com/joshhunt) +- **Chore:** Fix AWS auth assuming role with workspace IAM. [#36430](https://github.com/grafana/grafana/pull/36430), [@wbrowne](https://github.com/wbrowne) +- **DashboardQueryRunner:** Fixes unrestrained subscriptions being created. [#36371](https://github.com/grafana/grafana/pull/36371), [@hugohaggmark](https://github.com/hugohaggmark) +- **DateFormats:** Fix reading correct setting key for use_browser_locale. [#36428](https://github.com/grafana/grafana/pull/36428), [@torkelo](https://github.com/torkelo) +- **Links:** Fix links to other apps outside Grafana when under sub path. [#36498](https://github.com/grafana/grafana/pull/36498), [@torkelo](https://github.com/torkelo) +- **Snapshots:** Fix snapshot absolute time range issue. [#36350](https://github.com/grafana/grafana/pull/36350), [@torkelo](https://github.com/torkelo) +- **Table:** Fix data link color. [#36446](https://github.com/grafana/grafana/pull/36446), [@tharun208](https://github.com/tharun208) +- **Time Series:** Fix X-axis time format when tick increment is larger than a year. [#36335](https://github.com/grafana/grafana/pull/36335), [@torkelo](https://github.com/torkelo) +- **Tooltip Plugin:** Prevent tooltip render if field is undefined. [#36260](https://github.com/grafana/grafana/pull/36260), [@ashharrison90](https://github.com/ashharrison90) + + + + + +# 8.0.4 (2021-07-01) + +### Features and enhancements + +- **Live:** Rely on app url for origin check. [#35983](https://github.com/grafana/grafana/pull/35983), [@FZambia](https://github.com/FZambia) +- **PieChart:** Sort legend descending, update placeholder to show default …. [#36062](https://github.com/grafana/grafana/pull/36062), [@ashharrison90](https://github.com/ashharrison90) +- **TimeSeries panel:** Do not reinitialize plot when thresholds mode change. [#35952](https://github.com/grafana/grafana/pull/35952), [@dprokop](https://github.com/dprokop) + +### Bug fixes + +- **Elasticsearch:** Allow case sensitive custom options in date_histogram interval. [#36168](https://github.com/grafana/grafana/pull/36168), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch:** Restore previous field naming strategy when using variables. [#35624](https://github.com/grafana/grafana/pull/35624), [@Elfo404](https://github.com/Elfo404) +- **Explore:** Fix import of queries between SQL data sources. [#36210](https://github.com/grafana/grafana/pull/36210), [@ivanahuckova](https://github.com/ivanahuckova) +- **InfluxDB:** InfluxQL query editor: fix retention policy handling. [#36022](https://github.com/grafana/grafana/pull/36022), [@gabor](https://github.com/gabor) +- **Loki:** Send correct time range in template variable queries. [#36268](https://github.com/grafana/grafana/pull/36268), [@ivanahuckova](https://github.com/ivanahuckova) +- **TimeSeries:** Preserve RegExp series overrides when migrating from old graph panel. [#36134](https://github.com/grafana/grafana/pull/36134), [@ashharrison90](https://github.com/ashharrison90) + + + + + +# 8.0.3 (2021-06-18) + +### Features and enhancements + +- **Alerting:** Increase alertmanager_conf column if MySQL. [#35657](https://github.com/grafana/grafana/pull/35657), [@kylebrandt](https://github.com/kylebrandt) +- **Time series/Bar chart panel:** Handle infinite numbers as nulls when converting to plot array. [#35638](https://github.com/grafana/grafana/pull/35638), [@dprokop](https://github.com/dprokop) +- **TimeSeries:** Ensure series overrides that contain color are migrated, and migrate the previous `fieldConfig` when changing the panel type. [#35676](https://github.com/grafana/grafana/pull/35676), [@ashharrison90](https://github.com/ashharrison90) +- **ValueMappings:** Improve singlestat value mappings migration. [#35578](https://github.com/grafana/grafana/pull/35578), [@dprokop](https://github.com/dprokop) + +### Bug fixes + +- **Annotations:** Fix annotation line and marker colors. [#35608](https://github.com/grafana/grafana/pull/35608), [@torkelo](https://github.com/torkelo) +- **AzureMonitor:** Fix KQL template variable queries without default workspace. [#35836](https://github.com/grafana/grafana/pull/35836), [@joshhunt](https://github.com/joshhunt) +- **CloudWatch/Logs:** Fix missing response data for log queries. [#35724](https://github.com/grafana/grafana/pull/35724), [@aocenas](https://github.com/aocenas) +- **Elasticsearch:** Restore previous field naming strategy when using variables. [#35624](https://github.com/grafana/grafana/pull/35624), [@Elfo404](https://github.com/Elfo404) +- **LibraryPanels:** Fix crash in library panels list when panel plugin is not found. [#35907](https://github.com/grafana/grafana/pull/35907), [@torkelo](https://github.com/torkelo) +- **LogsPanel:** Fix performance drop when moving logs panel in dashboard. [#35379](https://github.com/grafana/grafana/pull/35379), [@aocenas](https://github.com/aocenas) +- **Loki:** Parse log levels when ANSI coloring is enabled. [#35607](https://github.com/grafana/grafana/pull/35607), [@olbo98](https://github.com/olbo98) +- **MSSQL:** Fix issue with hidden queries still being executed. [#35787](https://github.com/grafana/grafana/pull/35787), [@torkelo](https://github.com/torkelo) +- **PanelEdit:** Display the VisualizationPicker that was not displayed if a panel has an unknown panel plugin. [#35831](https://github.com/grafana/grafana/pull/35831), [@jackw](https://github.com/jackw) +- **Plugins:** Fix loading symbolically linked plugins. [#35635](https://github.com/grafana/grafana/pull/35635), [@domasx2](https://github.com/domasx2) +- **Prometheus:** Fix issue where legend name was replaced with name Value in stat and gauge panels. [#35863](https://github.com/grafana/grafana/pull/35863), [@torkelo](https://github.com/torkelo) +- **State Timeline:** Fix crash when hovering over panel. [#35692](https://github.com/grafana/grafana/pull/35692), [@hugohaggmark](https://github.com/hugohaggmark) + + + + + +# 8.0.2 (2021-06-14) + +### Features and enhancements + +- **Datasource:** Add support for max_conns_per_host in dataproxy settings. [#35520](https://github.com/grafana/grafana/pull/35520), [@jvrplmlmn](https://github.com/jvrplmlmn) + +### Bug fixes + +- **Configuration:** Fix changing org preferences in FireFox. [#35549](https://github.com/grafana/grafana/pull/35549), [@hugohaggmark](https://github.com/hugohaggmark) +- **PieChart:** Fix legend dimension limits. [#35563](https://github.com/grafana/grafana/pull/35563), [@torkelo](https://github.com/torkelo) +- **Postgres/MySQL/MSSQL:** Fix panic in concurrent map writes. [#35510](https://github.com/grafana/grafana/pull/35510), [@marefr](https://github.com/marefr) +- **Variables:** Hide default data source if missing from regex. [#35561](https://github.com/grafana/grafana/pull/35561), [@hugohaggmark](https://github.com/hugohaggmark) + + + + + +# 8.0.1 (2021-06-10) + +### Bug fixes + +- **Alerting/SSE:** Fix "count_non_null" reducer validation. [#35451](https://github.com/grafana/grafana/pull/35451), [@kylebrandt](https://github.com/kylebrandt) +- **Cloudwatch:** Fix duplicated time series. [#35433](https://github.com/grafana/grafana/pull/35433), [@sunker](https://github.com/sunker) +- **Cloudwatch:** Fix missing defaultRegion. [#35436](https://github.com/grafana/grafana/pull/35436), [@andresmgot](https://github.com/andresmgot) +- **Dashboard:** Fix Dashboard init failed error on dashboards with old singlestat panels in collapsed rows. [#35425](https://github.com/grafana/grafana/pull/35425), [@torkelo](https://github.com/torkelo) +- **Datasource:** Fix storing timeout option as numeric. [#35441](https://github.com/grafana/grafana/pull/35441), [@marefr](https://github.com/marefr) +- **Postgres/MySQL/MSSQL:** Fix annotation parsing for empty responses. [#35367](https://github.com/grafana/grafana/pull/35367), [@marcbachmann](https://github.com/marcbachmann) +- **Postgres/MySQL/MSSQL:** Numeric/non-string values are now returned from query variables. [#35411](https://github.com/grafana/grafana/pull/35411), [@marefr](https://github.com/marefr) +- **Postgres:** Fix an error that was thrown when the annotation query did not return any results. [#35382](https://github.com/grafana/grafana/pull/35382), [@dprokop](https://github.com/dprokop) +- **StatPanel:** Fix an issue with the appearance of the graph when switching color mode. [#35460](https://github.com/grafana/grafana/pull/35460), [@torkelo](https://github.com/torkelo) +- **Visualizations:** Fix an issue in the Stat/BarGauge/Gauge/PieChart panels where all values mode were showing the same name if they had the same value. [#35368](https://github.com/grafana/grafana/pull/35368), [@torkelo](https://github.com/torkelo) + +### Plugin development fixes & changes + +- **Toolkit:** Resolve external fonts when Grafana is served from a sub path. [#35352](https://github.com/grafana/grafana/pull/35352), [@jackw](https://github.com/jackw) + + + + + +# 8.0.0 (2021-06-08) + +### Features and enhancements + +- **AzureMonitor:** Require default subscription for workspaces() template variable query. [#35181](https://github.com/grafana/grafana/pull/35181), [@joshhunt](https://github.com/joshhunt) +- **AzureMonitor:** Use resource type display names in the UI. [#35060](https://github.com/grafana/grafana/pull/35060), [@joshhunt](https://github.com/joshhunt) +- **Dashboard:** Remove support for loading and deleting dashboard by slug. [#35104](https://github.com/grafana/grafana/pull/35104), [@dsotirakis](https://github.com/dsotirakis) +- **InfluxDB:** Deprecate direct browser access in data source. [#35105](https://github.com/grafana/grafana/pull/35105), [@gabor](https://github.com/gabor) +- **VizLegend:** Add a read-only property. [#35096](https://github.com/grafana/grafana/pull/35096), [@dprokop](https://github.com/dprokop) + +### Bug fixes + +- **AzureMonitor:** Fix Azure Resource Graph queries in Azure China. [#35235](https://github.com/grafana/grafana/pull/35235), [@kostrse](https://github.com/kostrse) +- **Checkbox:** Fix vertical layout issue with checkboxes due to fixed height. [#35022](https://github.com/grafana/grafana/pull/35022), [@torkelo](https://github.com/torkelo) +- **Dashboard:** Fix Table view when editing causes the panel data to not update. [#34998](https://github.com/grafana/grafana/pull/34998), [@axelavargas](https://github.com/axelavargas) +- **Dashboard:** Fix issues where unsaved-changes warning is not displayed. [#34989](https://github.com/grafana/grafana/pull/34989), [@torkelo](https://github.com/torkelo) +- **Login:** Fixes Unauthorized message showing when on login page or snapshot page. [#35311](https://github.com/grafana/grafana/pull/35311), [@torkelo](https://github.com/torkelo) +- **NodeGraph:** Fix sorting markers in grid view. [#35200](https://github.com/grafana/grafana/pull/35200), [@aocenas](https://github.com/aocenas) +- **Short URL:** Include orgId in generated short URLs. [#34696](https://github.com/grafana/grafana/pull/34696), [@farodin91](https://github.com/farodin91) +- **Variables:** Support raw values of boolean type. [#34727](https://github.com/grafana/grafana/pull/34727), [@simPod](https://github.com/simPod) + +### Breaking changes + +The following endpoints were deprecated for Grafana v5.0 and support for them has now been removed: + +- GET `/dashboards/db/:slug` +- GET `/dashboard-solo/db/:slug` +- GET `/api/dashboard/db/:slug` +- DELETE `/api/dashboards/db/:slug` Issue [#35104](https://github.com/grafana/grafana/issues/35104) + + + + + +# 8.0.0-beta3 (2021-06-01) + +### Features and enhancements + +- **API:** Support folder UID in dashboards API. [#33991](https://github.com/grafana/grafana/pull/33991), [@zserge](https://github.com/zserge) +- **Alerting:** Add support for configuring avatar URL for the Discord notifier. [#33355](https://github.com/grafana/grafana/pull/33355), [@ChipWolf](https://github.com/ChipWolf) +- **Alerting:** Clarify that Threema Gateway Alerts support only Basic IDs. [#34828](https://github.com/grafana/grafana/pull/34828), [@dbrgn](https://github.com/dbrgn) +- **Azure:** Expose Azure settings to external plugins. [#34484](https://github.com/grafana/grafana/pull/34484), [@sunker](https://github.com/sunker) +- **AzureMonitor:** Deprecate using separate credentials for Azure Monitor Logs. [#34758](https://github.com/grafana/grafana/pull/34758), [@andresmgot](https://github.com/andresmgot) +- **AzureMonitor:** Display variables in resource picker for Azure Monitor Logs. [#34648](https://github.com/grafana/grafana/pull/34648), [@joshhunt](https://github.com/joshhunt) +- **AzureMonitor:** Hide application insights for data sources not using it. [#34725](https://github.com/grafana/grafana/pull/34725), [@joshhunt](https://github.com/joshhunt) +- **AzureMonitor:** Support querying subscriptions and resource groups in Azure Monitor Logs. [#34766](https://github.com/grafana/grafana/pull/34766), [@joshhunt](https://github.com/joshhunt) +- **AzureMonitor:** remove requirement for default subscription. [#34787](https://github.com/grafana/grafana/pull/34787), [@kostrse](https://github.com/kostrse) +- **CloudWatch:** Add Lambda@Edge Amazon CloudFront metrics. [#34561](https://github.com/grafana/grafana/pull/34561), [@razor-x](https://github.com/razor-x) +- **CloudWatch:** Add missing AWS AppSync metrics. [#34691](https://github.com/grafana/grafana/pull/34691), [@razor-x](https://github.com/razor-x) +- **ConfirmModal:** Auto focus delete button. [#34917](https://github.com/grafana/grafana/pull/34917), [@torkelo](https://github.com/torkelo) +- **Explore:** Add caching for queries that are run from logs navigation. [#34297](https://github.com/grafana/grafana/pull/34297), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki:** Add formatting for annotations. [#34774](https://github.com/grafana/grafana/pull/34774), [@fredr](https://github.com/fredr) +- **Loki:** Bring back processed bytes as meta information. [#34092](https://github.com/grafana/grafana/pull/34092), [@mmenbawy](https://github.com/mmenbawy) +- **NodeGraph:** Display node graph collapsed by default with trace view. [#34491](https://github.com/grafana/grafana/pull/34491), [@aocenas](https://github.com/aocenas) +- **Overrides:** Include a manual override option to hide something from visualization. [#34783](https://github.com/grafana/grafana/pull/34783), [@torkelo](https://github.com/torkelo) +- **PieChart:** Support row data in pie charts. [#34755](https://github.com/grafana/grafana/pull/34755), [@torkelo](https://github.com/torkelo) +- **Prometheus:** Update default HTTP method to POST for existing data sources. [#34599](https://github.com/grafana/grafana/pull/34599), [@ivanahuckova](https://github.com/ivanahuckova) +- **Reporting:** Enable generating PDF for anonymous users. (Enterprise) +- **SAML:** Make private key and certificate optional. (Enterprise) +- **Time series panel:** Position tooltip correctly when window is scrolled or resized. [#34782](https://github.com/grafana/grafana/pull/34782), [@dprokop](https://github.com/dprokop) + +### Bug fixes + +- **Admin:** Fix infinite loading edit on the profile page. [#34627](https://github.com/grafana/grafana/pull/34627), [@hugohaggmark](https://github.com/hugohaggmark) +- **Color:** Fix issues with random colors in string and date fields. [#34913](https://github.com/grafana/grafana/pull/34913), [@torkelo](https://github.com/torkelo) +- **Dashboard:** Fix issue with title or folder change has no effect after exiting settings view. [#34677](https://github.com/grafana/grafana/pull/34677), [@torkelo](https://github.com/torkelo) +- **DataLinks:** Fix an issue \_\_series.name is not working in data link. [#34932](https://github.com/grafana/grafana/pull/34932), [@torkelo](https://github.com/torkelo) +- **Datasource:** Fix dataproxy timeout should always be applied for outgoing data source HTTP requests. [#34597](https://github.com/grafana/grafana/pull/34597), [@dsotirakis](https://github.com/dsotirakis) +- **Elasticsearch:** Fix NewClient not passing httpClientProvider to client impl. [#34539](https://github.com/grafana/grafana/pull/34539), [@KiVirgil](https://github.com/KiVirgil) +- **Explore:** Fix Browser title not updated on Navigation to Explore. [#34651](https://github.com/grafana/grafana/pull/34651), [@axelavargas](https://github.com/axelavargas) +- **GraphNG:** Remove fieldName and hideInLegend properties from UPlotSeriesBuilder. [#34901](https://github.com/grafana/grafana/pull/34901), [@dprokop](https://github.com/dprokop) +- **OAuth:** Fix fallback to auto_assign_org_role setting for Azure AD OAuth when no role claims exists. [#34838](https://github.com/grafana/grafana/pull/34838), [@idafurjes](https://github.com/idafurjes) +- **PanelChrome:** Fix issue with empty panel after adding a non data panel and coming back from panel edit. [#34765](https://github.com/grafana/grafana/pull/34765), [@torkelo](https://github.com/torkelo) +- **StatPanel:** Fix data link tooltip not showing for single value. [#34934](https://github.com/grafana/grafana/pull/34934), [@torkelo](https://github.com/torkelo) +- **Table:** Fix sorting for number fields. [#34722](https://github.com/grafana/grafana/pull/34722), [@hugohaggmark](https://github.com/hugohaggmark) +- **Table:** Have text underline for datalink, and add support for image datalink. [#34635](https://github.com/grafana/grafana/pull/34635), [@thisisobate](https://github.com/thisisobate) +- **Time series panel:** Position tooltip correctly when window is scrolled or resized. [#34584](https://github.com/grafana/grafana/pull/34584), [@dprokop](https://github.com/dprokop) +- **Transformations:** Prevent FilterByValue transform from crashing panel edit. [#34747](https://github.com/grafana/grafana/pull/34747), [@jackw](https://github.com/jackw) + +### Breaking changes + +The default HTTP method for Prometheus data source is now POST. Previously, it was GET. The POST APIs have been available since January 2018 (Prometheus 2.1.0) and they have fewer limitations than the GET APIs. For example, when dealing with high cardinality labels, GET hits the URL size limit. + +If you have a Prometheus instance with version < 2.1.0, which uses the default HTTP method, update your HTTP method to GET. Issue [#34599](https://github.com/grafana/grafana/issues/34599) + + + + + +# 8.0.0-beta2 (2021-05-20) + +### Features and enhancements + +- **AppPlugins:** Expose react-router to apps. [#33775](https://github.com/grafana/grafana/pull/33775), [@dprokop](https://github.com/dprokop) +- **AzureMonitor:** Add Azure Resource Graph. [#33293](https://github.com/grafana/grafana/pull/33293), [@shuotli](https://github.com/shuotli) +- **AzureMonitor:** Managed Identity configuration UI. [#34170](https://github.com/grafana/grafana/pull/34170), [@kostrse](https://github.com/kostrse) +- **AzureMonitor:** Token provider with support for Managed Identities. [#33807](https://github.com/grafana/grafana/pull/33807), [@kostrse](https://github.com/kostrse) +- **AzureMonitor:** Update Logs workspace() template variable query to return resource URIs. [#34445](https://github.com/grafana/grafana/pull/34445), [@joshhunt](https://github.com/joshhunt) +- **BarChart:** Value label sizing. [#34229](https://github.com/grafana/grafana/pull/34229), [@dprokop](https://github.com/dprokop) +- **CloudMonitoring:** Add support for preprocessing. [#33011](https://github.com/grafana/grafana/pull/33011), [@sunker](https://github.com/sunker) +- **CloudWatch:** Add AWS/EFS StorageBytes metric. [#33426](https://github.com/grafana/grafana/pull/33426), [@freshleafmedia](https://github.com/freshleafmedia) +- **CloudWatch:** Allow use of missing AWS namespaces using custom metrics. [#30961](https://github.com/grafana/grafana/pull/30961), [@mmcoltman](https://github.com/mmcoltman) +- **Datasource:** Shared HTTP client provider for core backend data sources and any data source using the data source proxy. [#33439](https://github.com/grafana/grafana/pull/33439), [@marefr](https://github.com/marefr) +- **InfluxDB:** InfluxQL: allow empty tag values in the query editor. [#34311](https://github.com/grafana/grafana/pull/34311), [@gabor](https://github.com/gabor) +- **Instrumentation:** Instrument incoming HTTP request with histograms by default. [#33921](https://github.com/grafana/grafana/pull/33921), [@bergquist](https://github.com/bergquist) +- **Library Panels:** Add name endpoint & unique name validation to AddLibraryPanelModal. [#33987](https://github.com/grafana/grafana/pull/33987), [@kaydelaney](https://github.com/kaydelaney) +- **Logs panel:** Support details view. [#34125](https://github.com/grafana/grafana/pull/34125), [@ivanahuckova](https://github.com/ivanahuckova) +- **PieChart:** Always show the calculation options dropdown in the editor. [#34267](https://github.com/grafana/grafana/pull/34267), [@oscarkilhed](https://github.com/oscarkilhed) +- **PieChart:** Remove beta flag. [#34098](https://github.com/grafana/grafana/pull/34098), [@oscarkilhed](https://github.com/oscarkilhed) +- **Plugins:** Enforce signing for all plugins. [#34364](https://github.com/grafana/grafana/pull/34364), [@wbrowne](https://github.com/wbrowne) +- **Plugins:** Remove support for deprecated backend plugin protocol version. [#34127](https://github.com/grafana/grafana/pull/34127), [@idafurjes](https://github.com/idafurjes) +- **Tempo/Jaeger:** Add better display name to legend. [#34063](https://github.com/grafana/grafana/pull/34063), [@aocenas](https://github.com/aocenas) +- **Timeline:** Add time range zoom. [#34079](https://github.com/grafana/grafana/pull/34079), [@torkelo](https://github.com/torkelo) +- **Timeline:** Adds opacity & line width option. [#34118](https://github.com/grafana/grafana/pull/34118), [@torkelo](https://github.com/torkelo) +- **Timeline:** Value text alignment option. [#34087](https://github.com/grafana/grafana/pull/34087), [@torkelo](https://github.com/torkelo) +- **ValueMappings:** Add duplicate action, and disable dismiss on backdrop click. [#34100](https://github.com/grafana/grafana/pull/34100), [@torkelo](https://github.com/torkelo) +- **Zipkin:** Add node graph view to trace response. [#34414](https://github.com/grafana/grafana/pull/34414), [@aocenas](https://github.com/aocenas) + +### Bug fixes + +- **Annotations panel:** Remove subpath from dashboard links. [#34134](https://github.com/grafana/grafana/pull/34134), [@jackw](https://github.com/jackw) +- **Content Security Policy:** Allow all image sources by default. [#34265](https://github.com/grafana/grafana/pull/34265), [@aknuds1](https://github.com/aknuds1) +- **Content Security Policy:** Relax default template wrt. loading of scripts, due to nonces not working. [#34363](https://github.com/grafana/grafana/pull/34363), [@aknuds1](https://github.com/aknuds1) +- **Datasource:** Fix tracing propagation for alert execution by introducing HTTP client outgoing tracing middleware. [#34466](https://github.com/grafana/grafana/pull/34466), [@marefr](https://github.com/marefr) +- **InfluxDB:** InfluxQL always apply time interval end. [#34308](https://github.com/grafana/grafana/pull/34308), [@gabor](https://github.com/gabor) +- **Library Panels:** Fixes "error while loading library panels". [#34278](https://github.com/grafana/grafana/pull/34278), [@hugohaggmark](https://github.com/hugohaggmark) +- **NewsPanel:** Fixes rendering issue in Safari. [#34067](https://github.com/grafana/grafana/pull/34067), [@kaydelaney](https://github.com/kaydelaney) +- **PanelChrome:** Fix queries being issued again when scrolling in and out of view. [#34061](https://github.com/grafana/grafana/pull/34061), [@torkelo](https://github.com/torkelo) +- **Plugins:** Fix Azure token provider cache panic and auth param nil value. [#34252](https://github.com/grafana/grafana/pull/34252), [@kostrse](https://github.com/kostrse) +- **Snapshots:** Fix key and deleteKey being ignored when creating an external snapshot. [#33686](https://github.com/grafana/grafana/pull/33686), [@wengelbrecht-grafana](https://github.com/wengelbrecht-grafana) +- **Table:** Fix issue with cell border not showing with colored background cells. [#34231](https://github.com/grafana/grafana/pull/34231), [@torkelo](https://github.com/torkelo) +- **Table:** Makes tooltip scrollable for long JSON values. [#34120](https://github.com/grafana/grafana/pull/34120), [@hugohaggmark](https://github.com/hugohaggmark) +- **TimeSeries:** Fix for Connected null values threshold toggle during panel editing. [#34452](https://github.com/grafana/grafana/pull/34452), [@leeoniya](https://github.com/leeoniya) +- **Variables:** Fixes inconsistent `selected` states on dashboard load. [#34197](https://github.com/grafana/grafana/pull/34197), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables:** Refreshes all panels even if panel is full screen. [#34097](https://github.com/grafana/grafana/pull/34097), [@hugohaggmark](https://github.com/hugohaggmark) + +### Breaking changes + +The `workspaces()` template variable, mainly for use with Azure Monitor Logs, has been changed to return resource URIs instead of Log Analytics Workspaces GUIDs. This should not impact Azure Monitor Logs queries, but if the variables are being used in other data sources which expect a Workspace GUID may no longer be compatible. + +Custom template variables used in the workspace or resource field in Azure Monitor Logs queries should resolve to an Azure Resource URI in the format `/subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}` +Issue [#34445](https://github.com/grafana/grafana/issues/34445) + +Removes support for deprecated backend plugin protocol (v1) including usage of github.com/grafana/grafana-plugin-model. + +Issue [#34127](https://github.com/grafana/grafana/issues/34127) + +### Plugin development fixes & changes + +- **QueryField:** Remove carriage return character from pasted text. [#34076](https://github.com/grafana/grafana/pull/34076), [@ivanahuckova](https://github.com/ivanahuckova) + + + + + +# 8.0.0-beta1 (2021-05-13) + +### Features and enhancements + +- **API**: Add org users with pagination. [#33788](https://github.com/grafana/grafana/pull/33788), [@idafurjes](https://github.com/idafurjes) +- **API**: Return 404 when deleting nonexistent API key. [#33346](https://github.com/grafana/grafana/pull/33346), [@chaudum](https://github.com/chaudum) +- **API**: Return query results as JSON rather than base64 encoded Arrow. [#32303](https://github.com/grafana/grafana/pull/32303), [@ryantxu](https://github.com/ryantxu) +- **Alerting**: Allow sending notification tags to Opsgenie as extra properties. [#30332](https://github.com/grafana/grafana/pull/30332), [@DewaldV](https://github.com/DewaldV) +- **Alerts**: Replaces all uses of InfoBox & FeatureInfoBox with Alert. [#33352](https://github.com/grafana/grafana/pull/33352), [@torkelo](https://github.com/torkelo) +- **Auth**: Add support for JWT Authentication. [#29995](https://github.com/grafana/grafana/pull/29995), [@marshall-lee](https://github.com/marshall-lee) +- **AzureMonitor**: Add support for Microsoft.SignalRService/SignalR metrics. [#33246](https://github.com/grafana/grafana/pull/33246), [@M0ns1gn0r](https://github.com/M0ns1gn0r) +- **AzureMonitor**: Azure settings in Grafana server config. [#33728](https://github.com/grafana/grafana/pull/33728), [@kostrse](https://github.com/kostrse) +- **AzureMonitor**: Migrate Metrics query editor to React. [#30783](https://github.com/grafana/grafana/pull/30783), [@joshhunt](https://github.com/joshhunt) +- **BarChart panel**: enable series toggling via legend. [#33955](https://github.com/grafana/grafana/pull/33955), [@dprokop](https://github.com/dprokop) +- **BarChart panel**: Adds support for Tooltip in BarChartPanel. [#33938](https://github.com/grafana/grafana/pull/33938), [@dprokop](https://github.com/dprokop) +- **PieChart panel**: Change look of highlighted pie slices. [#33841](https://github.com/grafana/grafana/pull/33841), [@oscarkilhed](https://github.com/oscarkilhed) +- **CloudMonitoring**: Migrate config editor from angular to react. [#33645](https://github.com/grafana/grafana/pull/33645), [@sunker](https://github.com/sunker) +- **CloudWatch**: Add Amplify Console metrics and dimensions. [#33171](https://github.com/grafana/grafana/pull/33171), [@rodrigorfk](https://github.com/rodrigorfk) +- **CloudWatch**: Add missing Redshift metrics to CloudWatch data source. [#32121](https://github.com/grafana/grafana/pull/32121), [@tomdaly](https://github.com/tomdaly) +- **CloudWatch**: Add metrics for managed RabbitMQ service. [#31838](https://github.com/grafana/grafana/pull/31838), [@nirojan](https://github.com/nirojan) +- **DashboardList**: Enable templating on search tag input. [#31460](https://github.com/grafana/grafana/pull/31460), [@delta50](https://github.com/delta50) +- **Datasource config**: correctly remove single custom http header. [#32445](https://github.com/grafana/grafana/pull/32445), [@gabor](https://github.com/gabor) +- **Elasticsearch**: Add generic support for template variables. [#32762](https://github.com/grafana/grafana/pull/32762), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Allow omitting field when metric supports inline script. [#32839](https://github.com/grafana/grafana/pull/32839), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Allow setting a custom limit for log queries. [#32422](https://github.com/grafana/grafana/pull/32422), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Guess field type from first non-empty value. [#32290](https://github.com/grafana/grafana/pull/32290), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Use application/x-ndjson content type for multisearch requests. [#32282](https://github.com/grafana/grafana/pull/32282), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Use semver strings to identify ES version. [#33646](https://github.com/grafana/grafana/pull/33646), [@Elfo404](https://github.com/Elfo404) +- **Explore**: Add logs navigation to request more logs. [#33259](https://github.com/grafana/grafana/pull/33259), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Map Graphite queries to Loki. [#33405](https://github.com/grafana/grafana/pull/33405), [@ifrost](https://github.com/ifrost) +- **Explore**: Scroll split panes in Explore independently. [#32978](https://github.com/grafana/grafana/pull/32978), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Wrap each panel in separate error boundary. [#33868](https://github.com/grafana/grafana/pull/33868), [@aocenas](https://github.com/aocenas) +- **FieldDisplay**: Smarter naming of stat values when visualising row values (all values) in stat panels. [#31704](https://github.com/grafana/grafana/pull/31704), [@torkelo](https://github.com/torkelo) +- **Graphite**: Expand metric names for variables. [#33694](https://github.com/grafana/grafana/pull/33694), [@ifrost](https://github.com/ifrost) +- **Graphite**: Handle unknown Graphite functions without breaking the visual editor. [#32635](https://github.com/grafana/grafana/pull/32635), [@ifrost](https://github.com/ifrost) +- **Graphite**: Show graphite functions descriptions. [#32305](https://github.com/grafana/grafana/pull/32305), [@ifrost](https://github.com/ifrost) +- **Graphite**: Support request cancellation properly (Uses new backendSrv.fetch Observable request API). [#31928](https://github.com/grafana/grafana/pull/31928), [@mckn](https://github.com/mckn) +- **InfluxDB**: Flux: Improve handling of complex response-structures. [#33823](https://github.com/grafana/grafana/pull/33823), [@gabor](https://github.com/gabor) +- **InfluxDB**: Support region annotations. [#31526](https://github.com/grafana/grafana/pull/31526), [@Komalis](https://github.com/Komalis) +- **Inspector**: Download logs for manual processing. [#32764](https://github.com/grafana/grafana/pull/32764), [@ivanahuckova](https://github.com/ivanahuckova) +- **Jaeger**: Add node graph view for trace. [#31521](https://github.com/grafana/grafana/pull/31521), [@aocenas](https://github.com/aocenas) +- **Jaeger**: Search traces. [#32805](https://github.com/grafana/grafana/pull/32805), [@zoltanbedi](https://github.com/zoltanbedi) +- **Loki**: Use data source settings for alerting queries. [#33942](https://github.com/grafana/grafana/pull/33942), [@ivanahuckova](https://github.com/ivanahuckova) +- **NodeGraph**: Exploration mode. [#33623](https://github.com/grafana/grafana/pull/33623), [@aocenas](https://github.com/aocenas) +- **OAuth**: Add support for empty scopes. [#32129](https://github.com/grafana/grafana/pull/32129), [@jvoeller](https://github.com/jvoeller) +- **PanelChrome**: New logic-less emotion based component with no dependency on PanelModel or DashboardModel. [#29456](https://github.com/grafana/grafana/pull/29456), [@torkelo](https://github.com/torkelo) +- **PanelEdit**: Adds a table view toggle to quickly view data in table form. [#33753](https://github.com/grafana/grafana/pull/33753), [@torkelo](https://github.com/torkelo) +- **PanelEdit**: Highlight matched words when searching options. [#33717](https://github.com/grafana/grafana/pull/33717), [@torkelo](https://github.com/torkelo) +- **PanelEdit**: UX improvements. [#32124](https://github.com/grafana/grafana/pull/32124), [@torkelo](https://github.com/torkelo) +- **Plugins**: PanelRenderer and simplified QueryRunner to be used from plugins. [#31901](https://github.com/grafana/grafana/pull/31901), [@torkelo](https://github.com/torkelo) +- **Plugins**: AuthType in route configuration and params interpolation. [#33674](https://github.com/grafana/grafana/pull/33674), [@kostrse](https://github.com/kostrse) +- **Plugins**: Enable plugin runtime install/uninstall capabilities. [#33836](https://github.com/grafana/grafana/pull/33836), [@wbrowne](https://github.com/wbrowne) +- **Plugins**: Support set body content in plugin routes. [#32551](https://github.com/grafana/grafana/pull/32551), [@marefr](https://github.com/marefr) +- **Plugins**: Introduce marketplace app. [#33869](https://github.com/grafana/grafana/pull/33869), [@jackw](https://github.com/jackw) +- **Plugins**: Moving the DataSourcePicker to grafana/runtime so it can be reused in plugins. [#31628](https://github.com/grafana/grafana/pull/31628), [@mckn](https://github.com/mckn) +- **Prometheus**: Add custom query params for alert and exemplars queries. [#32440](https://github.com/grafana/grafana/pull/32440), [@aocenas](https://github.com/aocenas) +- **Prometheus**: Use fuzzy string matching to autocomplete metric names and label. [#32207](https://github.com/grafana/grafana/pull/32207), [@ifrost](https://github.com/ifrost) +- **Routing**: Replace Angular routing with react-router. [#31463](https://github.com/grafana/grafana/pull/31463), [@dprokop](https://github.com/dprokop) +- **Slack**: Use chat.postMessage API by default. [#32511](https://github.com/grafana/grafana/pull/32511), [@aknuds1](https://github.com/aknuds1) +- **Tempo**: Search for Traces by querying Loki directly from Tempo. [#33308](https://github.com/grafana/grafana/pull/33308), [@davkal](https://github.com/davkal) +- **Tempo**: Show graph view of the trace. [#33635](https://github.com/grafana/grafana/pull/33635), [@aocenas](https://github.com/aocenas) +- **Themes**: Switch theme without reload using global shortcut. [#32180](https://github.com/grafana/grafana/pull/32180), [@torkelo](https://github.com/torkelo) +- **TimeSeries panel**: Add support for shared cursor. [#33433](https://github.com/grafana/grafana/pull/33433), [@dprokop](https://github.com/dprokop) +- **TimeSeries panel**: Do not crash the panel if there is no time series data in the response. [#33993](https://github.com/grafana/grafana/pull/33993), [@dprokop](https://github.com/dprokop) +- **Variables**: Do not save repeated panels, rows and scopedVars. [#32436](https://github.com/grafana/grafana/pull/32436), [@torkelo](https://github.com/torkelo) +- **Variables**: Removes experimental Tags feature. [#33361](https://github.com/grafana/grafana/pull/33361), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Removes the never refresh option. [#33533](https://github.com/grafana/grafana/pull/33533), [@hugohaggmark](https://github.com/hugohaggmark) +- **Visualizations**: Unify tooltip options across visualizations. [#33892](https://github.com/grafana/grafana/pull/33892), [@dprokop](https://github.com/dprokop) +- **Visualizations**: Refactor and unify option creation between new visualizations. [#33867](https://github.com/grafana/grafana/pull/33867), [@oscarkilhed](https://github.com/oscarkilhed) +- **Visualizations**: Remove singlestat panel. [#31904](https://github.com/grafana/grafana/pull/31904), [@dprokop](https://github.com/dprokop) + +### Bug fixes + +- **APIKeys**: Fixes issue with adding first api key. [#32201](https://github.com/grafana/grafana/pull/32201), [@torkelo](https://github.com/torkelo) +- **Alerting**: Add checks for non supported units - disable defaulting to seconds. [#32477](https://github.com/grafana/grafana/pull/32477), [@dsotirakis](https://github.com/dsotirakis) +- **Alerting**: Fix issue where Slack notifications won't link to user IDs. [#32861](https://github.com/grafana/grafana/pull/32861), [@n-wbrown](https://github.com/n-wbrown) +- **Alerting**: Omit empty message in PagerDuty notifier. [#31359](https://github.com/grafana/grafana/pull/31359), [@pkoenig10](https://github.com/pkoenig10) +- **AzureMonitor**: Fix migration error from older versions of App Insights queries. [#32372](https://github.com/grafana/grafana/pull/32372), [@joshhunt](https://github.com/joshhunt) +- **CloudWatch**: Fix AWS/Connect dimensions. [#33736](https://github.com/grafana/grafana/pull/33736), [@sunker](https://github.com/sunker) +- **CloudWatch**: Fix broken AWS/MediaTailor dimension name. [#33271](https://github.com/grafana/grafana/pull/33271), [@sunker](https://github.com/sunker) +- **Dashboards**: Allow string manipulation as advanced variable format option. [#29754](https://github.com/grafana/grafana/pull/29754), [@rscot231](https://github.com/rscot231) +- **DataLinks**: Includes harmless extended characters like Cyrillic characters. [#33551](https://github.com/grafana/grafana/pull/33551), [@hugohaggmark](https://github.com/hugohaggmark) +- **Drawer**: Fixes title overflowing its container. [#33857](https://github.com/grafana/grafana/pull/33857), [@thisisobate](https://github.com/thisisobate) +- **Explore**: Fix issue when some query errors were not shown. [#32212](https://github.com/grafana/grafana/pull/32212), [@aocenas](https://github.com/aocenas) +- **Generic OAuth**: Prevent adding duplicated users. [#32286](https://github.com/grafana/grafana/pull/32286), [@dsotirakis](https://github.com/dsotirakis) +- **Graphite**: Handle invalid annotations. [#32437](https://github.com/grafana/grafana/pull/32437), [@ifrost](https://github.com/ifrost) +- **Graphite**: Fix autocomplete when tags are not available. [#31680](https://github.com/grafana/grafana/pull/31680), [@ifrost](https://github.com/ifrost) +- **InfluxDB**: Fix Cannot read property 'length' of undefined in when parsing response. [#32504](https://github.com/grafana/grafana/pull/32504), [@ivanahuckova](https://github.com/ivanahuckova) +- **Instrumentation**: Enable tracing when Jaeger host and port are set. [#33682](https://github.com/grafana/grafana/pull/33682), [@zserge](https://github.com/zserge) +- **Instrumentation**: Prefix metrics with `grafana`. [#33925](https://github.com/grafana/grafana/pull/33925), [@bergquist](https://github.com/bergquist) +- **MSSQL**: By default let driver choose port. [#32417](https://github.com/grafana/grafana/pull/32417), [@aknuds1](https://github.com/aknuds1) +- **OAuth**: Add optional strict parsing of role_attribute_path. [#28021](https://github.com/grafana/grafana/pull/28021), [@klausenbusk](https://github.com/klausenbusk) +- **Panel**: Fixes description markdown with inline code being rendered on newlines and full width. [#32405](https://github.com/grafana/grafana/pull/32405), [@dprokop](https://github.com/dprokop) +- **PanelChrome**: Ignore data updates & errors for non data panels. [#33477](https://github.com/grafana/grafana/pull/33477), [@torkelo](https://github.com/torkelo) +- **Permissions**: Fix inherited folder permissions can prevent new permissions being added to a dashboard. [#33329](https://github.com/grafana/grafana/pull/33329), [@marefr](https://github.com/marefr) +- **Plugins**: Remove pre-existing plugin installs when installing with grafana-cli. [#31515](https://github.com/grafana/grafana/pull/31515), [@wbrowne](https://github.com/wbrowne) +- **Plugins**: Support installing to folders with whitespace and fix pluginUrl trailing and leading whitespace failures. [#32506](https://github.com/grafana/grafana/pull/32506), [@wbrowne](https://github.com/wbrowne) +- **Postgres/MySQL/MSSQL**: Don't return connection failure details to the client. [#32408](https://github.com/grafana/grafana/pull/32408), [@marefr](https://github.com/marefr) +- **Postgres**: Fix ms precision of interval in time group macro when TimescaleDB is enabled. [#33853](https://github.com/grafana/grafana/pull/33853), [@ying-jeanne](https://github.com/ying-jeanne) +- **Provisioning**: Use dashboard checksum field as change indicator. [#29797](https://github.com/grafana/grafana/pull/29797), [@cristi-](https://github.com/cristi-) +- **SQL**: Fix so that all captured errors are returned from sql engine. [#32353](https://github.com/grafana/grafana/pull/32353), [@marefr](https://github.com/marefr) +- **Shortcuts**: Fixes panel shortcuts so they always work. [#32385](https://github.com/grafana/grafana/pull/32385), [@torkelo](https://github.com/torkelo) +- **Table**: Fixes so border is visible for cells with links. [#33160](https://github.com/grafana/grafana/pull/33160), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Clear query when data source type changes. [#33924](https://github.com/grafana/grafana/pull/33924), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Filters out builtin variables from unknown list. [#33933](https://github.com/grafana/grafana/pull/33933), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Refreshes all panels even if panel is full screen. [#33201](https://github.com/grafana/grafana/pull/33201), [@hugohaggmark](https://github.com/hugohaggmark) + +### Breaking changes + +Removes the `never` refresh option for Query variables. Existing variables will be migrated and any stored options will be removed. Issue [#33533](https://github.com/grafana/grafana/issues/33533) + +Removes the experimental Tags feature for Variables. Issue [#33361](https://github.com/grafana/grafana/issues/33361) + +### Deprecations + +The InfoBox & FeatureInfoBox are now deprecated please use the Alert component instead with severity info. +Issue [#33352](https://github.com/grafana/grafana/issues/33352) + +### Plugin development fixes & changes + +- **Button**: Introduce buttonStyle prop. [#33384](https://github.com/grafana/grafana/pull/33384), [@jackw](https://github.com/jackw) +- **DataQueryRequest**: Remove deprecated props showingGraph and showingTabel and exploreMode. [#31876](https://github.com/grafana/grafana/pull/31876), [@torkelo](https://github.com/torkelo) +- **grafana/ui**: Update React Hook Form to v7. [#33328](https://github.com/grafana/grafana/pull/33328), [@Clarity-89](https://github.com/Clarity-89) +- **IconButton**: Introduce variant for red and blue icon buttons. [#33479](https://github.com/grafana/grafana/pull/33479), [@jackw](https://github.com/jackw) +- **Plugins**: Expose the `getTimeZone` function to be able to get the current selected timeZone. [#31900](https://github.com/grafana/grafana/pull/31900), [@mckn](https://github.com/mckn) +- **TagsInput**: Add className to TagsInput. [#33944](https://github.com/grafana/grafana/pull/33944), [@Clarity-89](https://github.com/Clarity-89) +- **VizLegend**: Move onSeriesColorChanged to PanelContext (breaking change). [#33611](https://github.com/grafana/grafana/pull/33611), [@ryantxu](https://github.com/ryantxu) + +### License update + +- **AGPL License:** Update license from Apache 2.0 to the GNU Affero General Public License (AGPL). [#33184](https://github.com/grafana/grafana/pull/33184) + + + + + +# 7.5.11 (2021-10-05) + +- **Security**: Fixes CVE-2021-39226. For more information, see our [blog](https://grafana.com/blog/2021/10/05/grafana-7.5.11-and-8.1.6-released-with-critical-security-fix/) + + + + + +# 7.5.10 (2021-07-15) + +### Bug fixes + +- **[v7.5.x] Transformations:** add 'prepare time series' transformer. [#36749](https://github.com/grafana/grafana/pull/36749), [@mckn](https://github.com/mckn) + + + + + +# 7.5.9 (2021-06-23) + +### Bug fixes + +- **Login:** Fix Unauthorized message that is displayed on sign-in or snapshot page. [#35880](https://github.com/grafana/grafana/pull/35880), [@torkelo](https://github.com/torkelo) + + + + + +# 7.5.8 (2021-06-16) + +### Features and enhancements + +- **Datasource:** Add support for max_conns_per_host in dataproxy settings. [#35519](https://github.com/grafana/grafana/pull/35519), [@jvrplmlmn](https://github.com/jvrplmlmn) +- **Datasource:** Add support for max_idle_connections_per_host in dataproxy settings. [#35365](https://github.com/grafana/grafana/pull/35365), [@dsotirakis](https://github.com/dsotirakis) +- **Instrumentation:** Add metrics for outbound HTTP connections. [#35321](https://github.com/grafana/grafana/pull/35321), [@dsotirakis](https://github.com/dsotirakis) +- **Snapshots:** Remove dashboard links from dashboard snapshots. [#35567](https://github.com/grafana/grafana/pull/35567), [@torkelo](https://github.com/torkelo) + + + + + +# 7.5.7 (2021-05-19) + +### Bug fixes + +- **Dockerfile:** Fixes missing --no-cache. [#33906](https://github.com/grafana/grafana/pull/33906), [@030](https://github.com/030) +- **Annotations:** Prevent orphaned annotation tags cleanup when no annotations were cleaned. [#33957](https://github.com/grafana/grafana/pull/33957), [@afayngelerindbx](https://github.com/afayngelerindbx) +- **Quota:** Do not count folders towards dashboard quota. [#32519](https://github.com/grafana/grafana/pull/32519), [@conorevans](https://github.com/conorevans) + + + + + +# 7.5.6 (2021-05-11) + +### Features and enhancements + +- **Database**: Add isolation level configuration parameter for MySQL. [#33830](https://github.com/grafana/grafana/pull/33830), [@zserge](https://github.com/zserge) +- **InfluxDB**: Improve measurement-autocomplete behavior. [#33494](https://github.com/grafana/grafana/pull/33494), [@gabor](https://github.com/gabor) +- **Instrumentation**: Don't consider invalid email address a failed email. [#33671](https://github.com/grafana/grafana/pull/33671), [@bergquist](https://github.com/bergquist) + +### Bug fixes + +- **Loki**: fix label browser crashing when + typed. [#33900](https://github.com/grafana/grafana/pull/33900), [@zoltanbedi](https://github.com/zoltanbedi) +- **Prometheus**: Sanitize PromLink button. [#33874](https://github.com/grafana/grafana/pull/33874), [@ivanahuckova](https://github.com/ivanahuckova) + + + + + +# 7.5.5 (2021-04-28) + +### Features and enhancements + +- **Explore:** Load default data source in Explore when the provided source does not exist. [#32992](https://github.com/grafana/grafana/pull/32992), [@ifrost](https://github.com/ifrost) +- **Instrumentation:** Add success rate metrics for email notifications. [#33359](https://github.com/grafana/grafana/pull/33359), [@bergquist](https://github.com/bergquist) + +### Bug fixes + +- **Alerting:** Remove field limitation from Slack notifications. [#33113](https://github.com/grafana/grafana/pull/33113), [@dsotirakis](https://github.com/dsotirakis) +- **Auth:** Do not clear auth token cookie when token lookup fails. [#32999](https://github.com/grafana/grafana/pull/32999), [@marefr](https://github.com/marefr) +- **Bug:** Add git command to Dockerfile.ubuntu file. [#33247](https://github.com/grafana/grafana/pull/33247), [@dsotirakis](https://github.com/dsotirakis) +- **Explore:** Adjust time to the selected timezone. [#33315](https://github.com/grafana/grafana/pull/33315), [@ifrost](https://github.com/ifrost) +- **GraphNG:** Fix exemplars window position. [#33427](https://github.com/grafana/grafana/pull/33427), [@zoltanbedi](https://github.com/zoltanbedi) +- **Loki:** Pass Skip TLS Verify setting to alert queries. [#33025](https://github.com/grafana/grafana/pull/33025), [@ivanahuckova](https://github.com/ivanahuckova) +- **Postgres:** Fix time group macro when TimescaleDB is enabled and interval is less than a second. [#33153](https://github.com/grafana/grafana/pull/33153), [@marefr](https://github.com/marefr) + + + + + +# 7.5.4 (2021-04-14) + +### Features and enhancements + +- **Auditing:** Use nanosecond resolution for audit log timestamps. (Enterprise) +- **AzureMonitor:** Add support for Microsoft.AppConfiguration/configurationStores namespace. [#32123](https://github.com/grafana/grafana/pull/32123), [@deesejohn](https://github.com/deesejohn) +- **TablePanel:** Make sorting case-insensitive. [#32435](https://github.com/grafana/grafana/pull/32435), [@kaydelaney](https://github.com/kaydelaney) + +### Bug fixes + +- **AzureMonitor:** Add support for Virtual WAN namespaces. [#32935](https://github.com/grafana/grafana/pull/32935), [@joshhunt](https://github.com/joshhunt) +- **Bugfix:** Add proper padding when scrolling is added to bar gauge. [#32411](https://github.com/grafana/grafana/pull/32411), [@mckn](https://github.com/mckn) +- **Datasource:** Prevent default data source named "default" from causing infinite loop. [#32949](https://github.com/grafana/grafana/pull/32949), [@jackw](https://github.com/jackw) +- **Prometheus:** Allow exemplars endpoint in data source proxy. [#32802](https://github.com/grafana/grafana/pull/32802), [@zoltanbedi](https://github.com/zoltanbedi) +- **Table:** Fix table data links so they refer to correct row after sorting. [#32571](https://github.com/grafana/grafana/pull/32571), [@torkelo](https://github.com/torkelo) + + + + + +# 7.5.3 (2021-04-07) + +### Features and enhancements + +- **Dashboard**: Do not include default datasource when externally exporting dashboard with row. [#32494](https://github.com/grafana/grafana/pull/32494), [@kaydelaney](https://github.com/kaydelaney) +- **Loki**: Remove empty annotations tags. [#32359](https://github.com/grafana/grafana/pull/32359), [@conorevans](https://github.com/conorevans) + +### Bug fixes + +- **AdHocVariable**: Add default data source to picker. [#32470](https://github.com/grafana/grafana/pull/32470), [@hugohaggmark](https://github.com/hugohaggmark) +- **Configuration**: Prevent browser hanging / crashing with large number of org users. [#32546](https://github.com/grafana/grafana/pull/32546), [@jackw](https://github.com/jackw) +- **Elasticsearch**: Fix bucket script variable duplication in UI. [#32705](https://github.com/grafana/grafana/pull/32705), [@Elfo404](https://github.com/Elfo404) +- **Explore**: Fix bug where navigating to explore would result in wrong query and datasource to be shown. [#32558](https://github.com/grafana/grafana/pull/32558), [@aocenas](https://github.com/aocenas) +- **FolderPicker**: Prevent dropdown menu from disappearing off screen. [#32603](https://github.com/grafana/grafana/pull/32603), [@jackw](https://github.com/jackw) +- **SingleStat**: Fix issue with panel links. [#32721](https://github.com/grafana/grafana/pull/32721), [@gjulianm](https://github.com/gjulianm) +- **Variables**: Confirm selection before opening new picker. [#32586](https://github.com/grafana/grafana/pull/32586), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Confirm selection before opening new picker. [#32503](https://github.com/grafana/grafana/pull/32503), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fix unsupported data format error for null values. [#32480](https://github.com/grafana/grafana/pull/32480), [@hugohaggmark](https://github.com/hugohaggmark) + + + + + +# 7.5.2 (2021-03-30) + +### Features and enhancements + +- **Explore**: Set Explore's GraphNG to use default value for connected null values setting. [#32471](https://github.com/grafana/grafana/pull/32471), [@ivanahuckova](https://github.com/ivanahuckova) + +### Bug fixes + +- **DashboardDataSource**: Fix query not being executed after selecting source panel. [#32383](https://github.com/grafana/grafana/pull/32383), [@torkelo](https://github.com/torkelo) +- **Graph**: Fix setting right y-axis when standard option unit is configured. [#32426](https://github.com/grafana/grafana/pull/32426), [@torkelo](https://github.com/torkelo) +- **Table**: Fix links for image cells. [#32370](https://github.com/grafana/grafana/pull/32370), [@kaydelaney](https://github.com/kaydelaney) +- **Variables**: Fix data source variable when default data source is selected. [#32384](https://github.com/grafana/grafana/pull/32384), [@torkelo](https://github.com/torkelo) +- **Variables**: Fix manually entering non-matching custom value in variable input/picker error. [#32390](https://github.com/grafana/grafana/pull/32390), [@torkelo](https://github.com/torkelo) + + + + + +# 7.5.1 (2021-03-26) + +### Bug fixes + +- **MSSQL**: Fix panic not implemented by upgrading go-mssqldb dependency. [#32347](https://github.com/grafana/grafana/pull/32347), [@aknuds1](https://github.com/aknuds1) + + + + + +# 7.5.0 (2021-03-25) + +### Features and enhancements + +- **Alerting**: Add ability to include aliases with hyphen in InfluxDB. [#32262](https://github.com/grafana/grafana/pull/32262), [@grafanabot](https://github.com/grafanabot) +- **CloudWatch**: Use latest version of aws sdk. [#32217](https://github.com/grafana/grafana/pull/32217), [@sunker](https://github.com/sunker) + +### Bug fixes + +- **Alerting**: Add ability to include aliases with hyphen in InfluxDB. [#32224](https://github.com/grafana/grafana/pull/32224), [@dsotirakis](https://github.com/dsotirakis) +- **DashboardSettings**: Fixes issue with tags list not updating changes are made. [#32241](https://github.com/grafana/grafana/pull/32241), [@huynhsamha](https://github.com/huynhsamha) +- **DashboardSettings**: Fixes issue with tags list not updating changes are made. [#32189](https://github.com/grafana/grafana/pull/32189), [@huynhsamha](https://github.com/huynhsamha) +- **Loki**: Fix text search in Label browser. [#32293](https://github.com/grafana/grafana/pull/32293), [@ivanahuckova](https://github.com/ivanahuckova) + + + + + +# 7.5.0-beta2 (2021-03-19) + +### Features and enhancements + +- **CloudWatch**: Add support for EC2 IAM role. [#31804](https://github.com/grafana/grafana/pull/31804), [@sunker](https://github.com/sunker) +- **CloudWatch**: Consume the grafana/aws-sdk. [#31807](https://github.com/grafana/grafana/pull/31807), [@sunker](https://github.com/sunker) +- **CloudWatch**: Restrict auth provider and assume role usage according to Grafana configuration. [#31805](https://github.com/grafana/grafana/pull/31805), [@sunker](https://github.com/sunker) +- **Cloudwatch**: ListMetrics API page limit. [#31788](https://github.com/grafana/grafana/pull/31788), [@sunker](https://github.com/sunker) +- **Cloudwatch**: Use shared library for aws auth. [#29550](https://github.com/grafana/grafana/pull/29550), [@ryantxu](https://github.com/ryantxu) +- **DataLinks**: Bring back single click links for Stat, Gauge and BarGauge panel. [#31692](https://github.com/grafana/grafana/pull/31692), [@dprokop](https://github.com/dprokop) +- **Docker**: Support pre-installed plugins from other sources in custom Dockerfiles. [#31234](https://github.com/grafana/grafana/pull/31234), [@sgnsys3](https://github.com/sgnsys3) +- **Elasticseach**: Add support for histogram fields. [#29079](https://github.com/grafana/grafana/pull/29079), [@simianhacker](https://github.com/simianhacker) +- **Exemplars**: Always query exemplars. [#31673](https://github.com/grafana/grafana/pull/31673), [@zoltanbedi](https://github.com/zoltanbedi) +- **Explore**: Support full inspect drawer. [#32005](https://github.com/grafana/grafana/pull/32005), [@ivanahuckova](https://github.com/ivanahuckova) +- **HttpServer**: Make read timeout configurable but disabled by default. [#31575](https://github.com/grafana/grafana/pull/31575), [@bergquist](https://github.com/bergquist) +- **SQLStore**: Close session in withDbSession. [#31775](https://github.com/grafana/grafana/pull/31775), [@aknuds1](https://github.com/aknuds1) +- **Templating**: Use dashboard timerange when variables are set to refresh 'On Dashboard Load'. [#31721](https://github.com/grafana/grafana/pull/31721), [@Elfo404](https://github.com/Elfo404) +- **Tempo**: Convert to backend data source. [#31618](https://github.com/grafana/grafana/pull/31618), [@zoltanbedi](https://github.com/zoltanbedi) + +### Bug fixes + +- **Admin**: Keeps expired api keys visible in table after delete. [#31636](https://github.com/grafana/grafana/pull/31636), [@hugohaggmark](https://github.com/hugohaggmark) +- **Data proxy**: Fix encoded characters in URL path should be proxied as encoded. [#30597](https://github.com/grafana/grafana/pull/30597), [@marefr](https://github.com/marefr) +- **Explore/Logs**: Fix escaping in ANSI logs. [#31731](https://github.com/grafana/grafana/pull/31731), [@ivanahuckova](https://github.com/ivanahuckova) +- **GraphNG**: Fix tooltip series color for multi data frame scenario. [#32098](https://github.com/grafana/grafana/pull/32098), [@dprokop](https://github.com/dprokop) +- **GraphNG**: Make sure data set and config are in sync when initializing and re-initializing uPlot. [#32106](https://github.com/grafana/grafana/pull/32106), [@dprokop](https://github.com/dprokop) +- **Loki**: Fix autocomplete when re-editing Loki label values. [#31828](https://github.com/grafana/grafana/pull/31828), [@ivanahuckova](https://github.com/ivanahuckova) +- **MixedDataSource**: Name is updated when data source variables change. [#32090](https://github.com/grafana/grafana/pull/32090), [@hugohaggmark](https://github.com/hugohaggmark) +- **PanelInspect**: Interpolates variables in CSV file name. [#31936](https://github.com/grafana/grafana/pull/31936), [@hugohaggmark](https://github.com/hugohaggmark) +- **ReduceTransform**: Include series with numeric string names. [#31763](https://github.com/grafana/grafana/pull/31763), [@hugohaggmark](https://github.com/hugohaggmark) +- **Snapshots**: Fix usage of sign in link from the snapshot page. [#31986](https://github.com/grafana/grafana/pull/31986), [@marefr](https://github.com/marefr) +- **TimePicker**: Fixes hidden time picker shown in kiosk TV mode. [#32062](https://github.com/grafana/grafana/pull/32062), [@torkelo](https://github.com/torkelo) +- **ValueMappings**: Fixes value 0 not being mapped. [#31924](https://github.com/grafana/grafana/pull/31924), [@Willena](https://github.com/Willena) +- **Variables**: Fixes filtering in picker with null items. [#31979](https://github.com/grafana/grafana/pull/31979), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Improves inspection performance and unknown filtering. [#31811](https://github.com/grafana/grafana/pull/31811), [@hugohaggmark](https://github.com/hugohaggmark) + +### Plugin development fixes & changes + +- **Auth**: Allow soft token revocation. [#31601](https://github.com/grafana/grafana/pull/31601), [@joanlopez](https://github.com/joanlopez) + + + + + +# 7.5.0-beta1 (2021-03-04) + +### Features and enhancements + +- **Alerting**: Customise OK notification priorities for Pushover notifier. [#30169](https://github.com/grafana/grafana/pull/30169), [@acaire](https://github.com/acaire) +- **Alerting**: Improve default message for SensuGo notifier. [#31428](https://github.com/grafana/grafana/pull/31428), [@M4teo](https://github.com/M4teo) +- **Alerting**: PagerDuty: adding current state to the payload. [#29270](https://github.com/grafana/grafana/pull/29270), [@Eraac](https://github.com/Eraac) +- **AzureMonitor**: Add deprecation message for App Insights/Insights Analytics. [#30633](https://github.com/grafana/grafana/pull/30633), [@joshhunt](https://github.com/joshhunt) +- **CloudMonitoring**: Allow free text input for GCP project on dashboard variable query. [#28048](https://github.com/grafana/grafana/issues/28048) +- **CloudMonitoring**: Increase service api page size. [#30892](https://github.com/grafana/grafana/pull/30892), [@sunker](https://github.com/sunker) +- **CloudMonitoring**: Show service and SLO display name in SLO Query editor. [#30900](https://github.com/grafana/grafana/pull/30900), [@sunker](https://github.com/sunker) +- **CloudWatch**: Add AWS Ground Station metrics and dimensions. [#31362](https://github.com/grafana/grafana/pull/31362), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Add AWS Network Firewall metrics and dimensions. [#31498](https://github.com/grafana/grafana/pull/31498), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Add AWS Timestream Metrics and Dimensions. [#31624](https://github.com/grafana/grafana/pull/31624), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Add RDS Proxy metrics. [#31595](https://github.com/grafana/grafana/pull/31595), [@sunker](https://github.com/sunker) +- **CloudWatch**: Add eu-south-1 Cloudwatch region. [#31198](https://github.com/grafana/grafana/pull/31198), [@rubycut](https://github.com/rubycut) +- **CloudWatch**: Make it possible to specify custom api endpoint. [#31402](https://github.com/grafana/grafana/pull/31402), [@sunker](https://github.com/sunker) +- **Cloudwatch**: Add AWS/DDoSProtection metrics and dimensions. [#31297](https://github.com/grafana/grafana/pull/31297), [@relvira](https://github.com/relvira) +- **Dashboard**: Remove template variables option from ShareModal. [#30395](https://github.com/grafana/grafana/pull/30395), [@oscarkilhed](https://github.com/oscarkilhed) +- **Docs**: Define TLS/SSL terminology. [#30533](https://github.com/grafana/grafana/pull/30533), [@aknuds1](https://github.com/aknuds1) +- **Elasticsearch**: Add word highlighting to search results. [#30293](https://github.com/grafana/grafana/pull/30293), [@simianhacker](https://github.com/simianhacker) +- **Folders**: Editors should be able to edit name and delete folders. [#31242](https://github.com/grafana/grafana/pull/31242), [@torkelo](https://github.com/torkelo) +- **Graphite/SSE**: update graphite to work with server side expressions. [#31455](https://github.com/grafana/grafana/pull/31455), [@kylebrandt](https://github.com/kylebrandt) +- **InfluxDB**: Improve maxDataPoints error-message in Flux-mode, raise limits. [#31259](https://github.com/grafana/grafana/pull/31259), [@gabor](https://github.com/gabor) +- **InfluxDB**: In flux query editor, do not run query when disabled. [#31324](https://github.com/grafana/grafana/pull/31324), [@gabor](https://github.com/gabor) +- **LogsPanel**: Add deduplication option for logs. [#31019](https://github.com/grafana/grafana/pull/31019), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Add line limit for annotations. [#31183](https://github.com/grafana/grafana/pull/31183), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Add support for alerting. [#31424](https://github.com/grafana/grafana/pull/31424), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Label browser. [#30351](https://github.com/grafana/grafana/pull/30351), [@davkal](https://github.com/davkal) +- **PieChart**: Add color changing options to pie chart. [#31588](https://github.com/grafana/grafana/pull/31588), [@oscarkilhed](https://github.com/oscarkilhed) +- **PostgreSQL**: Allow providing TLS/SSL certificates as text in addition to file paths. [#30353](https://github.com/grafana/grafana/pull/30353), [@ying-jeanne](https://github.com/ying-jeanne) +- **Postgres**: SSL certification. [#30352](https://github.com/grafana/grafana/pull/30352), [@ying-jeanne](https://github.com/ying-jeanne) +- **Profile**: Prevent OAuth users from changing user details or password. [#27886](https://github.com/grafana/grafana/pull/27886), [@dupondje](https://github.com/dupondje) +- **Prometheus**: Change default httpMethod for new instances to POST. [#31292](https://github.com/grafana/grafana/pull/31292), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Min step defaults to seconds when no unit is set. [#30966](https://github.com/grafana/grafana/pull/30966), [@nutmos](https://github.com/nutmos) +- **Stats**: Exclude folders from total dashboard count. [#31320](https://github.com/grafana/grafana/pull/31320), [@bergquist](https://github.com/bergquist) +- **Tracing**: Specify type of data frame that is expected for TraceView. [#31465](https://github.com/grafana/grafana/pull/31465), [@aocenas](https://github.com/aocenas) +- **Transformers**: Add search to transform selection. [#30854](https://github.com/grafana/grafana/pull/30854), [@ryantxu](https://github.com/ryantxu) + +### Bug fixes + +- **Alerting**: Ensure Discord notification is sent when metric name is absent. [#31257](https://github.com/grafana/grafana/pull/31257), [@LeviHarrison](https://github.com/LeviHarrison) +- **Alerting**: Fix case when Alertmanager notifier fails if a URL is not working. [#31079](https://github.com/grafana/grafana/pull/31079), [@kurokochin](https://github.com/kurokochin) +- **CloudMonitoring**: Prevent resource type variable function from crashing. [#30901](https://github.com/grafana/grafana/pull/30901), [@sunker](https://github.com/sunker) +- **Color**: Fix issue where colors are reset to gray when switching panels. [#31611](https://github.com/grafana/grafana/pull/31611), [@torkelo](https://github.com/torkelo) +- **Explore**: Show ANSI colored logs in logs context. [#31510](https://github.com/grafana/grafana/pull/31510), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: keep enabled/disabled state in angular based QueryEditors correctly. [#31558](https://github.com/grafana/grafana/pull/31558), [@gabor](https://github.com/gabor) +- **Graph**: Fix tooltip not being displayed when close to edge of viewport. [#31493](https://github.com/grafana/grafana/pull/31493), [@msober](https://github.com/msober) +- **Heatmap**: Fix missing value in legend. [#31430](https://github.com/grafana/grafana/pull/31430), [@kurokochin](https://github.com/kurokochin) +- **InfluxDB**: Handle columns named "table". [#30985](https://github.com/grafana/grafana/pull/30985), [@gabor](https://github.com/gabor) +- **Prometheus**: Use configured HTTP method for /series and /labels endpoints. [#31401](https://github.com/grafana/grafana/pull/31401), [@ivanahuckova](https://github.com/ivanahuckova) +- **RefreshPicker**: Make valid intervals in url visible in RefreshPicker. [#30474](https://github.com/grafana/grafana/pull/30474), [@hugohaggmark](https://github.com/hugohaggmark) +- **TimeSeriesPanel**: Fix overlapping time axis ticks. [#31332](https://github.com/grafana/grafana/pull/31332), [@torkelo](https://github.com/torkelo) +- **TraceViewer**: Fix show log marker in spanbar. [#30742](https://github.com/grafana/grafana/pull/30742), [@zoltanbedi](https://github.com/zoltanbedi) + +### Plugin development fixes & changes + +- **Plugins**: Add autoEnabled plugin JSON field to auto enable App plugins and add configuration link to menu by default. [#31354](https://github.com/grafana/grafana/pull/31354), [@torkelo](https://github.com/torkelo) +- **Pagination**: Improve pagination for large number of pages. [#30151](https://github.com/grafana/grafana/pull/30151), [@nathanrodman](https://github.com/nathanrodman) + + + + + +# 7.4.5 (2021-03-18) + +### Bug fixes + +- **Security**: Fix API permissions issues related to team-sync CVE-2021-28146, CVE-2021-28147. (Enterprise) +- **Security**: Usage insights requires signed in users CVE-2021-28148. (Enterprise) +- **Security**: Do not allow editors to incorrectly bypass permissions on the default data source. CVE-2021-27962. (Enterprise) + + + + + +# 7.4.3 (2021-02-24) + +### Bug fixes + +- **AdHocVariables**: Fixes crash when values are stored as numbers. [#31382](https://github.com/grafana/grafana/pull/31382), [@hugohaggmark](https://github.com/hugohaggmark) +- **DashboardLinks**: Fix an issue where the dashboard links were causing a full page reload. [#31334](https://github.com/grafana/grafana/pull/31334), [@torkelo](https://github.com/torkelo) +- **Elasticsearch**: Fix query initialization logic & query transformation from Prometheus/Loki. [#31322](https://github.com/grafana/grafana/pull/31322), [@Elfo404](https://github.com/Elfo404) +- **QueryEditor**: Fix disabling queries in dashboards. [#31336](https://github.com/grafana/grafana/pull/31336), [@gabor](https://github.com/gabor) +- **Streaming**: Fix an issue with the time series panel and streaming data source when scrolling back from being out of view. [#31431](https://github.com/grafana/grafana/pull/31431), [@torkelo](https://github.com/torkelo) +- **Table**: Fix an issue regarding the fixed min and auto max values in bar gauge cell. [#31316](https://github.com/grafana/grafana/pull/31316), [@torkelo](https://github.com/torkelo) + + + + + +# 7.4.2 (2021-02-17) + +### Features and enhancements + +- **Explore**: Do not show non queryable data sources in data source picker. [#31144](https://github.com/grafana/grafana/pull/31144), [@torkelo](https://github.com/torkelo) +- **Security**: Do not allow an anonymous user to create snapshots. CVE-2021-27358. [#31263](https://github.com/grafana/grafana/pull/31263), [@marefr](https://github.com/marefr) + +### Bug fixes + +- **CloudWatch**: Ensure empty query row errors are not passed to the panel. [#31172](https://github.com/grafana/grafana/pull/31172), [@sunker](https://github.com/sunker) +- **DashboardLinks**: Fix the links that always cause a full page to reload. [#31178](https://github.com/grafana/grafana/pull/31178), [@torkelo](https://github.com/torkelo) +- **DashboardListPanel**: Fix issue with folder picker always showing All and using old form styles. [#31160](https://github.com/grafana/grafana/pull/31160), [@torkelo](https://github.com/torkelo) +- **IPv6**: Support host address configured with enclosing square brackets. [#31226](https://github.com/grafana/grafana/pull/31226), [@aknuds1](https://github.com/aknuds1) +- **Permissions**: Fix team and role permissions on folders/dashboards not displayed for non Grafana Admin users. [#31132](https://github.com/grafana/grafana/pull/31132), [@AgnesToulet](https://github.com/AgnesToulet) +- **Postgres**: Fix timeGroup macro converts long intervals to invalid numbers when TimescaleDB is enabled. [#31179](https://github.com/grafana/grafana/pull/31179), [@kurokochin](https://github.com/kurokochin) +- **Prometheus**: Fix enabling of disabled queries when editing in dashboard. [#31055](https://github.com/grafana/grafana/pull/31055), [@ivanahuckova](https://github.com/ivanahuckova) +- **QueryEditors**: Fix an issue that happens after moving queries then editing would update other queries. [#31193](https://github.com/grafana/grafana/pull/31193), [@torkelo](https://github.com/torkelo) +- **SqlDataSources**: Fix the Show Generated SQL button in query editors. [#31236](https://github.com/grafana/grafana/pull/31236), [@torkelo](https://github.com/torkelo) +- **StatPanels**: Fix an issue where the palette color scheme is not cleared when loading panel. [#31126](https://github.com/grafana/grafana/pull/31126), [@torkelo](https://github.com/torkelo) +- **Variables**: Add the default option back for the data source variable. [#31208](https://github.com/grafana/grafana/pull/31208), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fix missing empty elements from regex filters. [#31156](https://github.com/grafana/grafana/pull/31156), [@hugohaggmark](https://github.com/hugohaggmark) + + + + + + + + + +# 7.4.1 (2021-02-11) + +### Features and enhancements + +- **Influx**: Make max series limit configurable and show the limiting message if applied. [#31025](https://github.com/grafana/grafana/pull/31025), [@aocenas](https://github.com/aocenas) +- **Make value mappings correctly interpret numeric-like strings**. [#30893](https://github.com/grafana/grafana/pull/30893), [@dprokop](https://github.com/dprokop) +- **Variables**: Adds queryparam formatting option. [#30858](https://github.com/grafana/grafana/pull/30858), [@hugohaggmark](https://github.com/hugohaggmark) + +### Bug fixes + +- **Alerting**: Fixes so notification channels are properly deleted. [#31040](https://github.com/grafana/grafana/pull/31040), [@hugohaggmark](https://github.com/hugohaggmark) +- **BarGauge**: Improvements to value sizing and table inner width calculations. [#30990](https://github.com/grafana/grafana/pull/30990), [@torkelo](https://github.com/torkelo) +- **DashboardLinks**: Fixes crash when link has no title. [#31008](https://github.com/grafana/grafana/pull/31008), [@hugohaggmark](https://github.com/hugohaggmark) +- **Elasticsearch**: Fix alias field value not being shown in query editor. [#30992](https://github.com/grafana/grafana/pull/30992), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Fix log row context errors. [#31088](https://github.com/grafana/grafana/pull/31088), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Show Size setting for raw_data metric. [#30980](https://github.com/grafana/grafana/pull/30980), [@Elfo404](https://github.com/Elfo404) +- **Graph**: Fixes so graph is shown for non numeric time values. [#30972](https://github.com/grafana/grafana/pull/30972), [@hugohaggmark](https://github.com/hugohaggmark) +- **Logging**: Ignore 'file already closed' error when closing file. [#31119](https://github.com/grafana/grafana/pull/31119), [@aknuds1](https://github.com/aknuds1) +- **Plugins**: Fix plugin signature validation for manifest v2 on Windows. [#31045](https://github.com/grafana/grafana/pull/31045), [@wbrowne](https://github.com/wbrowne) +- **TextPanel**: Fixes so panel title is updated when variables change. [#30884](https://github.com/grafana/grafana/pull/30884), [@hugohaggmark](https://github.com/hugohaggmark) +- **Transforms**: Fixes Outer join issue with duplicate field names not getting the same unique field names as before. [#31121](https://github.com/grafana/grafana/pull/31121), [@torkelo](https://github.com/torkelo) + + + + + +# 7.4.0 (2021-02-04) + +### Features and enhancements + +- **CDN**: Adds support for serving assets over a CDN. [#30691](https://github.com/grafana/grafana/pull/30691), [@torkelo](https://github.com/torkelo) +- **DashboardLinks**: Support variable expression in to tooltip - Issue #30409. [#30569](https://github.com/grafana/grafana/pull/30569), [@huynhsamha](https://github.com/huynhsamha) +- **Explore**: Set Explore's GraphNG to be connected. [#30707](https://github.com/grafana/grafana/pull/30707), [@ivanahuckova](https://github.com/ivanahuckova) +- **InfluxDB**: Add http configuration when selecting InfluxDB v2 flavor. [#30827](https://github.com/grafana/grafana/pull/30827), [@aocenas](https://github.com/aocenas) +- **InfluxDB**: Show all datapoints for dynamically windowed flux query. [#30688](https://github.com/grafana/grafana/pull/30688), [@davkal](https://github.com/davkal) +- **Loki**: Improve live tailing errors. [#30517](https://github.com/grafana/grafana/pull/30517), [@ivanahuckova](https://github.com/ivanahuckova) + +### Bug fixes + +- **Admin**: Fixes so form values are filled in from backend. [#30544](https://github.com/grafana/grafana/pull/30544), [@hugohaggmark](https://github.com/hugohaggmark) +- **Admin**: Fixes so whole org drop down is visible when adding users to org. [#30481](https://github.com/grafana/grafana/pull/30481), [@hugohaggmark](https://github.com/hugohaggmark) +- **Alerting**: Hides threshold handle for percentual thresholds. [#30431](https://github.com/grafana/grafana/pull/30431), [@hugohaggmark](https://github.com/hugohaggmark) +- **CloudWatch**: Prevent field config from being overwritten. [#30437](https://github.com/grafana/grafana/pull/30437), [@sunker](https://github.com/sunker) +- **Decimals**: Big Improvements to auto decimals and fixes to auto decimals bug found in 7.4-beta1. [#30519](https://github.com/grafana/grafana/pull/30519), [@torkelo](https://github.com/torkelo) +- **Explore**: Fix jumpy live tailing. [#30650](https://github.com/grafana/grafana/pull/30650), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Fix loading visualisation on the top of the new time series panel. [#30553](https://github.com/grafana/grafana/pull/30553), [@ivanahuckova](https://github.com/ivanahuckova) +- **Footer**: Fixes layout issue in footer. [#30443](https://github.com/grafana/grafana/pull/30443), [@torkelo](https://github.com/torkelo) +- **Graph**: Fixes so only users with correct permissions can add annotations. [#30419](https://github.com/grafana/grafana/pull/30419), [@hugohaggmark](https://github.com/hugohaggmark) +- **Mobile**: Fixes issue scrolling on mobile in chrome. [#30746](https://github.com/grafana/grafana/pull/30746), [@torkelo](https://github.com/torkelo) +- **PanelEdit**: Trigger refresh when changing data source. [#30744](https://github.com/grafana/grafana/pull/30744), [@torkelo](https://github.com/torkelo) +- **Panels**: Fixes so panels are refreshed when scrolling past them fast. [#30784](https://github.com/grafana/grafana/pull/30784), [@hugohaggmark](https://github.com/hugohaggmark) +- **Prometheus**: Fix show query instead of Value if no **name** and metric. [#30511](https://github.com/grafana/grafana/pull/30511), [@zoltanbedi](https://github.com/zoltanbedi) +- **TimeSeriesPanel**: Fixes default value for Gradient mode. [#30484](https://github.com/grafana/grafana/pull/30484), [@torkelo](https://github.com/torkelo) +- **Variables**: Clears drop down state when leaving dashboard. [#30810](https://github.com/grafana/grafana/pull/30810), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fixes display value when using capture groups in regex. [#30636](https://github.com/grafana/grafana/pull/30636), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fixes so queries work for numbers values too. [#30602](https://github.com/grafana/grafana/pull/30602), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fixes so text format will show All instead of custom all value. [#30730](https://github.com/grafana/grafana/pull/30730), [@hugohaggmark](https://github.com/hugohaggmark) + +### Plugin development fixes & changes + +- **Plugins**: Fix failing plugin builds because of wrong internal import. [#30439](https://github.com/grafana/grafana/pull/30439), [@aocenas](https://github.com/aocenas) + + + + + +# 7.4.0-beta1 (2021-01-20) + +### Features and enhancements + +- **API**: Add ID to snapshot API responses. [#29600](https://github.com/grafana/grafana/pull/29600), [@AgnesToulet](https://github.com/AgnesToulet) +- **AlertListPanel**: Add options to sort by Time(asc) and Time(desc). [#29764](https://github.com/grafana/grafana/pull/29764), [@dboslee](https://github.com/dboslee) +- **AlertListPanel**: Changed alert url to to go the panel view instead of panel edit. [#29060](https://github.com/grafana/grafana/pull/29060), [@zakiharis](https://github.com/zakiharis) +- **Alerting**: Add support for Sensu Go notification channel. [#28012](https://github.com/grafana/grafana/pull/28012), [@nixwiz](https://github.com/nixwiz) +- **Alerting**: Add support for alert notification query label interpolation. [#29908](https://github.com/grafana/grafana/pull/29908), [@wbrowne](https://github.com/wbrowne) +- **Annotations**: Remove annotation_tag entries as part of annotations cleanup. [#29534](https://github.com/grafana/grafana/pull/29534), [@dafydd-t](https://github.com/dafydd-t) +- **Azure Monitor**: Add Microsoft.Network/natGateways. [#29479](https://github.com/grafana/grafana/pull/29479), [@JoeyLemur](https://github.com/JoeyLemur) +- **Backend plugins**: Support Forward OAuth Identity for backend data source plugins. [#27055](https://github.com/grafana/grafana/pull/27055), [@billoley](https://github.com/billoley) +- **Cloud Monitoring**: MQL support. [#26551](https://github.com/grafana/grafana/pull/26551), [@mtanda](https://github.com/mtanda) +- **CloudWatch**: Add 'EventBusName' dimension to CloudWatch 'AWS/Events' namespace. [#28402](https://github.com/grafana/grafana/pull/28402), [@tomdaly](https://github.com/tomdaly) +- **CloudWatch**: Add support for AWS DirectConnect ConnectionErrorCount metric. [#29583](https://github.com/grafana/grafana/pull/29583), [@haeringer](https://github.com/haeringer) +- **CloudWatch**: Add support for AWS/ClientVPN metrics and dimensions. [#29055](https://github.com/grafana/grafana/pull/29055), [@marefr](https://github.com/marefr) +- **CloudWatch**: Added HTTP API Gateway specific metrics and dimensions. [#28780](https://github.com/grafana/grafana/pull/28780), [@karlatkinson](https://github.com/karlatkinson) +- **Configuration**: Add an option to hide certain users in the UI. [#28942](https://github.com/grafana/grafana/pull/28942), [@AgnesToulet](https://github.com/AgnesToulet) +- **Currency**: Adds Indonesian IDR currency. [#28363](https://github.com/grafana/grafana/pull/28363), [@hiddenrebel](https://github.com/hiddenrebel) +- **Dashboards**: Delete related data (permissions, stars, tags, versions, annotations) when deleting a dashboard or a folder. [#28826](https://github.com/grafana/grafana/pull/28826), [@AgnesToulet](https://github.com/AgnesToulet) +- **Dependencies**: Update angularjs to 1.8.2. [#28736](https://github.com/grafana/grafana/pull/28736), [@torkelo](https://github.com/torkelo) +- **Docker**: Use root group in the custom Dockerfile. [#28639](https://github.com/grafana/grafana/pull/28639), [@chugunov](https://github.com/chugunov) +- **Elasticsearch**: Add Moving Function Pipeline Aggregation. [#28131](https://github.com/grafana/grafana/pull/28131), [@simianhacker](https://github.com/simianhacker) +- **Elasticsearch**: Add Support for Serial Differencing Pipeline Aggregation. [#28618](https://github.com/grafana/grafana/pull/28618), [@simianhacker](https://github.com/simianhacker) +- **Elasticsearch**: Deprecate browser access mode. [#29649](https://github.com/grafana/grafana/pull/29649), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Interpolate variables in Filters Bucket Aggregation. [#28969](https://github.com/grafana/grafana/pull/28969), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Support extended stats and percentiles in terms order by. [#28910](https://github.com/grafana/grafana/pull/28910), [@simianhacker](https://github.com/simianhacker) +- **Elasticsearch**: View in context feature for logs. [#28764](https://github.com/grafana/grafana/pull/28764), [@simianhacker](https://github.com/simianhacker) +- **Explore/Logs**: Alphabetically sort unique labels, labels and parsed fields. [#29030](https://github.com/grafana/grafana/pull/29030), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore/Logs**: Update Parsed fields to Detected fields. [#28881](https://github.com/grafana/grafana/pull/28881), [@ivanahuckova](https://github.com/ivanahuckova) +- **Field overrides**: Added matcher to match all fields returned by a specific query. [#28872](https://github.com/grafana/grafana/pull/28872), [@mckn](https://github.com/mckn) +- **Graph**: Add support for spline interpolation (smoothing) added in new time series panel. [#4303](https://github.com/grafana/grafana/issues/4303) +- **Instrumentation**: Add histograms for database queries. [#29662](https://github.com/grafana/grafana/pull/29662), [@dafydd-t](https://github.com/dafydd-t) +- **Jaeger**: Remove browser access mode. [#30349](https://github.com/grafana/grafana/pull/30349), [@zoltanbedi](https://github.com/zoltanbedi) +- **LogsPanel**: Don't show scroll bars when not needed. [#28972](https://github.com/grafana/grafana/pull/28972), [@aocenas](https://github.com/aocenas) +- **Loki**: Add query type and line limit to query editor in dashboard. [#29356](https://github.com/grafana/grafana/pull/29356), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Add query type selector to query editor in Explore. [#28817](https://github.com/grafana/grafana/pull/28817), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Retry web socket connection when connection is closed abnormally. [#29438](https://github.com/grafana/grafana/pull/29438), [@ivanahuckova](https://github.com/ivanahuckova) +- **MS SQL**: Integrated security. [#30369](https://github.com/grafana/grafana/pull/30369), [@daniellee](https://github.com/daniellee) +- **Middleware**: Add CSP support. [#29740](https://github.com/grafana/grafana/pull/29740), [@aknuds1](https://github.com/aknuds1) +- **OAuth**: Configurable user name attribute. [#28286](https://github.com/grafana/grafana/pull/28286), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **PanelEditor**: Render panel field config categories as separate option group sections. [#30301](https://github.com/grafana/grafana/pull/30301), [@dprokop](https://github.com/dprokop) +- **Postgres**: SSL certification. [#30352](https://github.com/grafana/grafana/pull/30352), [@ying-jeanne](https://github.com/ying-jeanne) +- **Prometheus**: Add support for Exemplars. [#28057](https://github.com/grafana/grafana/pull/28057), [@zoltanbedi](https://github.com/zoltanbedi) +- **Prometheus**: Improve autocomplete performance and remove disabling of dynamic label lookup. [#30199](https://github.com/grafana/grafana/pull/30199), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Update default query type option to "Both" in Explore query editor. [#28935](https://github.com/grafana/grafana/pull/28935), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Use customQueryParameters for all queries. [#28949](https://github.com/grafana/grafana/pull/28949), [@alexbumbacea](https://github.com/alexbumbacea) +- **Security**: Prefer server cipher suites for http2. [#29379](https://github.com/grafana/grafana/pull/29379), [@bergquist](https://github.com/bergquist) +- **Security**: Remove insecure cipher suit as default option. [#29378](https://github.com/grafana/grafana/pull/29378), [@bergquist](https://github.com/bergquist) +- **StatPanels**: Add new calculation option for percentage difference. [#26369](https://github.com/grafana/grafana/pull/26369), [@jedstar](https://github.com/jedstar) +- **StatPanels**: Change default stats option to "Last (not null)". [#28617](https://github.com/grafana/grafana/pull/28617), [@ryantxu](https://github.com/ryantxu) +- **Table**: migrate old-table config to new table config. [#30142](https://github.com/grafana/grafana/pull/30142), [@jackw](https://github.com/jackw) +- **Templating**: Custom variable edit UI, change options input into textarea. [#28322](https://github.com/grafana/grafana/pull/28322), [@darrylsepeda](https://github.com/darrylsepeda) +- **TimeSeriesPanel**: The new graph panel now supports y-axis value mapping. [#30272](https://github.com/grafana/grafana/pull/30272), [@torkelo](https://github.com/torkelo) +- **Tracing**: Tag spans with user login and datasource name instead of id. [#29183](https://github.com/grafana/grafana/pull/29183), [@bergquist](https://github.com/bergquist) +- **Transformations**: Add "Rename By Regex" transformer. [#29281](https://github.com/grafana/grafana/pull/29281), [@simianhacker](https://github.com/simianhacker) +- **Transformations**: Added new transform for excluding and including rows based on their values. [#26884](https://github.com/grafana/grafana/pull/26884), [@Totalus](https://github.com/Totalus) +- **Transforms**: Add sort by transformer. [#30370](https://github.com/grafana/grafana/pull/30370), [@ryantxu](https://github.com/ryantxu) +- **Variables**: Add deprecation warning for value group tags. [#30160](https://github.com/grafana/grafana/pull/30160), [@torkelo](https://github.com/torkelo) +- **Variables**: Added \_\_user.email to global variable. [#28853](https://github.com/grafana/grafana/pull/28853), [@mckn](https://github.com/mckn) +- **Variables**: Adds description field. [#29332](https://github.com/grafana/grafana/pull/29332), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Adds variables inspection. [#25214](https://github.com/grafana/grafana/pull/25214), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: New Variables are stored immediately. [#29178](https://github.com/grafana/grafana/pull/29178), [@hugohaggmark](https://github.com/hugohaggmark) +- **Zipkin**: Remove browser access mode. [#30360](https://github.com/grafana/grafana/pull/30360), [@zoltanbedi](https://github.com/zoltanbedi) + +### Bug fixes + +- **API**: Query database from /api/health endpoint. [#28349](https://github.com/grafana/grafana/pull/28349), [@ceh](https://github.com/ceh) +- **Alerting**: Return proper status code when trying to create alert notification channel with duplicate name or uid. [#28043](https://github.com/grafana/grafana/pull/28043), [@jgulick48](https://github.com/jgulick48) +- **Auth**: Fix default maximum lifetime an authenticated user can be logged in. [#30030](https://github.com/grafana/grafana/pull/30030), [@papagian](https://github.com/papagian) +- **Backend**: Fix IPv6 address parsing erroneous. [#28585](https://github.com/grafana/grafana/pull/28585), [@taciomcosta](https://github.com/taciomcosta) +- **CloudWatch**: Make sure stats grow horizontally and not vertically in the Query Editor. [#30106](https://github.com/grafana/grafana/pull/30106), [@sunker](https://github.com/sunker) +- **Cloudwatch**: Fix issue with field calculation transform not working properly with Cloudwatch data. [#28761](https://github.com/grafana/grafana/pull/28761), [@torkelo](https://github.com/torkelo) +- **Dashboards**: Hide playlist edit functionality from viewers and snapshots link from unauthenticated users. [#28992](https://github.com/grafana/grafana/pull/28992), [@jackw](https://github.com/jackw) +- **Data source proxy**: Convert 401 HTTP status code from data source to 400. [#28962](https://github.com/grafana/grafana/pull/28962), [@aknuds1](https://github.com/aknuds1) +- **Decimals**: Improving auto decimals logic for high numbers and scaled units. [#30262](https://github.com/grafana/grafana/pull/30262), [@torkelo](https://github.com/torkelo) +- **Elasticsearch**: Fix date histogram auto interval handling for alert queries. [#30049](https://github.com/grafana/grafana/pull/30049), [@simianhacker](https://github.com/simianhacker) +- **Elasticsearch**: Fix index pattern not working with multiple base sections. [#28348](https://github.com/grafana/grafana/pull/28348), [@tomdaly](https://github.com/tomdaly) +- **Explore**: Clear errors after running a new query. [#30367](https://github.com/grafana/grafana/pull/30367), [@ivanahuckova](https://github.com/ivanahuckova) +- **Graph**: Fixes stacking issues like floating bars when data is not aligned. [#29051](https://github.com/grafana/grafana/pull/29051), [@torkelo](https://github.com/torkelo) +- **Graph**: Staircase and null value=null calculates auto Y-Min incorrectly (fixed in new Time series panel). [#12995](https://github.com/grafana/grafana/issues/12995) +- **Graph**: Staircase mode, do now draw line segment from zero when drawing null values as null (Fixed in new Time series panel). [#17838](https://github.com/grafana/grafana/issues/17838) +- **Image uploader**: Fix uploading of images to GCS. [#26493](https://github.com/grafana/grafana/pull/26493), [@gastonqiu](https://github.com/gastonqiu) +- **Influx**: Fixes issue with many queries being issued as you type in the variable query field. [#29968](https://github.com/grafana/grafana/pull/29968), [@dprokop](https://github.com/dprokop) +- **Logs Panel**: Fix inconsistent highlighting. [#28971](https://github.com/grafana/grafana/pull/28971), [@ivanahuckova](https://github.com/ivanahuckova) +- **Logs Panel**: Fixes problem dragging scrollbar inside logs panel. [#28974](https://github.com/grafana/grafana/pull/28974), [@aocenas](https://github.com/aocenas) +- **Loki**: Fix hiding of series in table if labels have number values. [#30185](https://github.com/grafana/grafana/pull/30185), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Lower min step to 1ms. [#30135](https://github.com/grafana/grafana/pull/30135), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Remove showing of unique labels with the empty string value. [#30363](https://github.com/grafana/grafana/pull/30363), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Timeseries should not produce 0-values for missing data. [#30116](https://github.com/grafana/grafana/pull/30116), [@davkal](https://github.com/davkal) +- **Plugins**: Fix panic when using complex dynamic URLs in app plugin routes. [#27977](https://github.com/grafana/grafana/pull/27977), [@cinaglia](https://github.com/cinaglia) +- **Prometheus**: Fix link to Prometheus graph in dashboard. [#29543](https://github.com/grafana/grafana/pull/29543), [@ivanahuckova](https://github.com/ivanahuckova) +- **Provisioning**: Build paths in an os independent way. [#29143](https://github.com/grafana/grafana/pull/29143), [@amattheisen](https://github.com/amattheisen) +- **Provisioning**: Fixed problem with getting started panel being added to custom home dashboard. [#28750](https://github.com/grafana/grafana/pull/28750), [@torkelo](https://github.com/torkelo) +- **SAML**: Fixes bug in processing SAML response with empty element by updating saml library (Enterprise). [#29991](https://github.com/grafana/grafana/pull/29991), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **SQL**: Define primary key for tables without it. [#22255](https://github.com/grafana/grafana/pull/22255), [@azhiltsov](https://github.com/azhiltsov) +- **Tracing**: Fix issue showing more than 300 spans. [#29377](https://github.com/grafana/grafana/pull/29377), [@zoltanbedi](https://github.com/zoltanbedi) +- **Units**: Changes FLOP/s to FLOPS and some other rates per second units get /s suffix. [#28825](https://github.com/grafana/grafana/pull/28825), [@Berbe](https://github.com/Berbe) +- **Variables**: Fixes Constant variable persistence confusion. [#29407](https://github.com/grafana/grafana/pull/29407), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fixes Textbox current value persistence. [#29481](https://github.com/grafana/grafana/pull/29481), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fixes loading with a custom all value in url. [#28958](https://github.com/grafana/grafana/pull/28958), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fixes so clicking on Selected in drop down will exclude All value from selection. [#29844](https://github.com/grafana/grafana/pull/29844), [@hugohaggmark](https://github.com/hugohaggmark) + +### Breaking changes + +#### Constant variables + +In order to minimize the confusion with Constant variable usage, we've removed the ability to make Constant variables visible. This change will also migrate **`all`** existing **`visible`** Constant variables to Textbox variables because which we think this is a more appropriate type of variable for this use case. +Issue [#29407](https://github.com/grafana/grafana/issues/29407) + +#### Plugin compatibility + +We have upgraded AngularJS from version 1.6.6 to 1.8.2. Due to this upgrade some old angular plugins might stop working and will require a small update. This is due to the deprecation and removal of pre-assigned bindings. So if your custom angular controllers expect component bindings in the controller constructor you need to move this code to an `$onInit` function. For more details on how to migrate AngularJS code open the [migration guide](https://docs.angularjs.org/guide/migration) and search for **pre-assigning bindings**. + +In order not to break all angular panel plugins and data sources we have some custom [angular inject behavior](https://github.com/grafana/grafana/blob/master/public/app/core/injectorMonkeyPatch.ts) that makes sure that bindings for these controllers are still set before constructor is called so many old angular panels and data source plugins will still work. Issue [#28736](https://github.com/grafana/grafana/issues/28736) + +### Deprecations + +#### Query variable value group tags + +This option to group query variable values into groups by tags has been an experimental feature since it was introduced. It was introduced to work around the lack of tags support in time series databases at the time. Now that tags (ie. labels) are the norm there is no longer any great need for this feature. This feature will be removed in Grafana v8 later this year. Issue [#30160](https://github.com/grafana/grafana/issues/30160) + +### Plugin development fixes & changes + +- **AngularPlugins**: Angular controller events emitter is now a separate emitter and not the same as PanelModel events emitter. [#30379](https://github.com/grafana/grafana/pull/30379), [@torkelo](https://github.com/torkelo) +- **FieldConfig API**: Add ability to hide field option or disable it from the overrides. [#29879](https://github.com/grafana/grafana/pull/29879), [@dprokop](https://github.com/dprokop) +- **Select**: Changes default menu placement for Select from auto to bottom. [#29837](https://github.com/grafana/grafana/pull/29837), [@hugohaggmark](https://github.com/hugohaggmark) +- **Collapse**: Allow component children to use height: 100% styling. [#29776](https://github.com/grafana/grafana/pull/29776), [@aocenas](https://github.com/aocenas) +- **DataSourceWithBackend**: Throw error if health check fails in DataSourceWithBackend. [#29743](https://github.com/grafana/grafana/pull/29743), [@aocenas](https://github.com/aocenas) +- **NodeGraph**: Add node graph visualization. [#29706](https://github.com/grafana/grafana/pull/29706), [@aocenas](https://github.com/aocenas) +- **FieldColor**: Handling color changes when switching panel types. [#28875](https://github.com/grafana/grafana/pull/28875), [@dprokop](https://github.com/dprokop) +- **CodeEditor**: Added support for javascript language. [#28818](https://github.com/grafana/grafana/pull/28818), [@ae3e](https://github.com/ae3e) +- **grafana/toolkit**: Allow builds with lint warnings. [#28810](https://github.com/grafana/grafana/pull/28810), [@dprokop](https://github.com/dprokop) +- **grafana/toolkit**: Drop console and debugger statements by default when building plugin. [#28776](https://github.com/grafana/grafana/pull/28776), [@dprokop](https://github.com/dprokop) +- **Card**: Add new Card component. [#28216](https://github.com/grafana/grafana/pull/28216), [@Clarity-89](https://github.com/Clarity-89) +- **FieldConfig**: Implementation slider editor (#27592). [#28007](https://github.com/grafana/grafana/pull/28007), [@isaozlerfm](https://github.com/isaozlerfm) +- **MutableDataFrame**: Remove unique field name constraint and values field index and unused/seldom used stuff. [#27573](https://github.com/grafana/grafana/pull/27573), [@torkelo](https://github.com/torkelo) + + + + + +# 7.3.10 (2021-03-18) + +### Bug fixes + +- **Security**: Fix API permissions issues related to team-sync CVE-2021-28146, CVE-2021-28147. (Enterprise) +- **Security**: Usage insights requires signed in users CVE-2021-28148. (Enterprise) + + + + + +# 7.3.7 (2021-01-14) + +### Bug fixes + +- **Auth**: Add missing request headers to SigV4 middleware allowlist. [#30115](https://github.com/grafana/grafana/pull/30115), [@wbrowne](https://github.com/wbrowne) +- **Elasticsearch**: Sort results by index order as well as @timestamp. [#29761](https://github.com/grafana/grafana/pull/29761), [@STEELBADGE](https://github.com/STEELBADGE) +- **SAML**: Fixes bug in processing SAML response with empty element by updating saml library (Enterprise). [#30179](https://github.com/grafana/grafana/pull/30179), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **SeriesToRows**: Fixes issue in transform so that value field is always named Value. [#30054](https://github.com/grafana/grafana/pull/30054), [@torkelo](https://github.com/torkelo) + + + + + +# 7.3.6 (2020-12-17) + +### Security + +- **SAML**: Fixes encoding/xml SAML vulnerability in Grafana Enterprise. [#29875](https://github.com/grafana/grafana/issues/29875) + + + + + +# 7.3.5 (2020-12-10) + +### Features and enhancements + +- **Alerting**: Improve Prometheus Alert Rule error message. [#29390](https://github.com/grafana/grafana/pull/29390), [@wbrowne](https://github.com/wbrowne) + +### Bug fixes + +- **Alerting**: Fix alarm message formatting in Dingding. [#29482](https://github.com/grafana/grafana/pull/29482), [@tomowang](https://github.com/tomowang) +- **AzureMonitor**: Fix unit translation for MilliSeconds. [#29399](https://github.com/grafana/grafana/pull/29399), [@secustor](https://github.com/secustor) +- **Instrumentation**: Fix bug with invalid handler label value for HTTP request metrics. [#29529](https://github.com/grafana/grafana/pull/29529), [@bergquist](https://github.com/bergquist) +- **Prometheus**: Fixes problem where changing display name in Field tab had no effect. [#29441](https://github.com/grafana/grafana/pull/29441), [@zoltanbedi](https://github.com/zoltanbedi) +- **Tracing**: Fixed issue showing more than 300 spans. [#29377](https://github.com/grafana/grafana/pull/29377), [@zoltanbedi](https://github.com/zoltanbedi) + + + + + +# 7.3.4 (2020-11-24) + +### Bug fixes + +- **Dashboard**: Fixes kiosk state after being redirected to login page and back. [#29273](https://github.com/grafana/grafana/pull/29273), [@torkelo](https://github.com/torkelo) +- **InfluxDB**: Update flux library to fix support for boolean label values. [#29310](https://github.com/grafana/grafana/pull/29310), [@ryantxu](https://github.com/ryantxu) +- **Security**: Fixes minor security issue with alert notification webhooks that allowed GET & DELETE requests. [#29330](https://github.com/grafana/grafana/pull/29330), [@wbrowne](https://github.com/wbrowne) +- **Table**: Fixes issues with phantom extra 0 for zero values. [#29165](https://github.com/grafana/grafana/pull/29165), [@dprokop](https://github.com/dprokop) + + + + + +# 7.3.3 (2020-11-17) + +### Bug fixes + +- **Cloud monitoring**: Fix for multi-value template variable for project selector. [#29042](https://github.com/grafana/grafana/pull/29042), [@papagian](https://github.com/papagian) +- **LogsPanel**: Fixes problem dragging scrollbar inside logs panel. [#28974](https://github.com/grafana/grafana/pull/28974), [@aocenas](https://github.com/aocenas) +- **Provisioning**: Fixes application not pinned to the sidebar when it's enabled. [#29084](https://github.com/grafana/grafana/pull/29084), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **StatPanel**: Fixes hanging issue when all values are zero. [#29077](https://github.com/grafana/grafana/pull/29077), [@torkelo](https://github.com/torkelo) +- **Thresholds**: Fixes color assigned to null values. [#29010](https://github.com/grafana/grafana/pull/29010), [@torkelo](https://github.com/torkelo) + + + + + +# 7.3.2 (2020-11-11) + +### Features / Enhancements + +- **CloudWatch Logs**: Change how we measure query progress. [#28912](https://github.com/grafana/grafana/pull/28912), [@aocenas](https://github.com/aocenas) +- **Dashboards / Folders**: delete related data (permissions, stars, tags, versions, annotations) when deleting a dashboard or a folder. [#28826](https://github.com/grafana/grafana/pull/28826), [@AgnesToulet](https://github.com/AgnesToulet) +- **Gauge**: Improve font size auto sizing. [#28797](https://github.com/grafana/grafana/pull/28797), [@torkelo](https://github.com/torkelo) +- **Short URL**: Cleanup unvisited/stale short URLs. [#28867](https://github.com/grafana/grafana/pull/28867), [@wbrowne](https://github.com/wbrowne) +- **Templating**: Custom variable edit UI, change options input into textarea. [#28322](https://github.com/grafana/grafana/pull/28322), [@darrylsepeda](https://github.com/darrylsepeda) + +### Bug Fixes + +- **Cloudwatch**: Fix issue with field calculation transform not working properly with Cloudwatch data. [#28761](https://github.com/grafana/grafana/pull/28761), [@torkelo](https://github.com/torkelo) +- **Dashboard**: fix view panel mode for Safari / iOS. [#28702](https://github.com/grafana/grafana/pull/28702), [@jackw](https://github.com/jackw) +- **Elasticsearch**: Exclude pipeline aggregations from order by options. [#28620](https://github.com/grafana/grafana/pull/28620), [@simianhacker](https://github.com/simianhacker) +- **Panel inspect**: Interpolate variables in panel inspect title. [#28779](https://github.com/grafana/grafana/pull/28779), [@dprokop](https://github.com/dprokop) +- **Prometheus**: Fix copy paste behaving as cut and paste. [#28622](https://github.com/grafana/grafana/pull/28622), [@aocenas](https://github.com/aocenas) +- **StatPanels**: Fixes auto min max when latest value is zero. [#28982](https://github.com/grafana/grafana/pull/28982), [@torkelo](https://github.com/torkelo) +- **TableFilters**: Fixes filtering with field overrides. [#28690](https://github.com/grafana/grafana/pull/28690), [@hugohaggmark](https://github.com/hugohaggmark) +- **Templating**: Speeds up certain variable queries for Postgres MySql MSSql. [#28686](https://github.com/grafana/grafana/pull/28686), [@hugohaggmark](https://github.com/hugohaggmark) +- **Units**: added support to handle negative fractional numbers. [#28849](https://github.com/grafana/grafana/pull/28849), [@mckn](https://github.com/mckn) +- **Variables**: Fix backward compatibility in custom variable options that contain colon. [#28896](https://github.com/grafana/grafana/pull/28896), [@mckn](https://github.com/mckn) + + + +# 7.3.1 (2020-10-30) + +### Bug Fixes + +- **Cloudwatch**: Fix duplicate metric data. [#28642](https://github.com/grafana/grafana/pull/28642), [@zoltanbedi](https://github.com/zoltanbedi) +- **Loki**: Fix error when some queries return zero results. [#28645](https://github.com/grafana/grafana/pull/28645), [@ivanahuckova](https://github.com/ivanahuckova) +- **PanelMenu**: Fix panel submenu not being accessible for panels close to the right edge of the screen. [#28666](https://github.com/grafana/grafana/pull/28666), [@torkelo](https://github.com/torkelo) +- **Plugins**: Fix descendent frontend plugin signature validation. [#28638](https://github.com/grafana/grafana/pull/28638), [@wbrowne](https://github.com/wbrowne) +- **StatPanel**: Fix value being under graph and reduced likelihood for white and dark value text mixing. [#28641](https://github.com/grafana/grafana/pull/28641), [@torkelo](https://github.com/torkelo) +- **TextPanel**: Fix problems where text panel would show old content. [#28643](https://github.com/grafana/grafana/pull/28643), [@torkelo](https://github.com/torkelo) + +# 7.3.0 (2020-10-28) + +### Features / Enhancements + +- **AzureMonitor**: Support decimal (as float64) type in analytics/logs. [#28480](https://github.com/grafana/grafana/pull/28480), [@kylebrandt](https://github.com/kylebrandt) +- **Plugins signing**: UI information. [#28469](https://github.com/grafana/grafana/pull/28469), [@dprokop](https://github.com/dprokop) +- **Short URL**: Update last seen at when visiting a short URL. [#28565](https://github.com/grafana/grafana/pull/28565), [@marefr](https://github.com/marefr) + +### Bug Fixes + +- **Alerting**: Log warnings for obsolete notifiers when extracting alerts and remove frequent error log messages. [#28162](https://github.com/grafana/grafana/pull/28162), [@papagian](https://github.com/papagian) +- **Auth**: Fix SigV4 request verification step for Amazon Elasticsearch Service. [#28481](https://github.com/grafana/grafana/pull/28481), [@wbrowne](https://github.com/wbrowne) +- **Auth**: Should redirect to login when anonymous enabled and URL with different org than anonymous specified. [#28158](https://github.com/grafana/grafana/pull/28158), [@marefr](https://github.com/marefr) +- **Elasticsearch**: Fix handling of errors when testing data source. [#28498](https://github.com/grafana/grafana/pull/28498), [@marefr](https://github.com/marefr) +- **Graphite**: Fix default version to be 1.1. [#28471](https://github.com/grafana/grafana/pull/28471), [@ivanahuckova](https://github.com/ivanahuckova) +- **StatPanel**: Fixes BizChart error max: yyy should not be less than min zzz. [#28587](https://github.com/grafana/grafana/pull/28587), [@hugohaggmark](https://github.com/hugohaggmark) + +# 7.3.0-beta2 (2020-10-22) + +### Features / Enhancements + +- **Add monitoring mixing for Grafana**. [#28285](https://github.com/grafana/grafana/pull/28285), [@bergquist](https://github.com/bergquist) +- **CloudWatch**: Missing Namespace AWS/EC2CapacityReservations. [#28309](https://github.com/grafana/grafana/pull/28309), [@nonamef](https://github.com/nonamef) +- **Explore**: Support wide data frames. [#28393](https://github.com/grafana/grafana/pull/28393), [@aocenas](https://github.com/aocenas) +- **Instrumentation**: Add counters and histograms for database queries. [#28236](https://github.com/grafana/grafana/pull/28236), [@bergquist](https://github.com/bergquist) +- **Loki**: Visually distinguish error logs for LogQL2. [#28359](https://github.com/grafana/grafana/pull/28359), [@ivanahuckova](https://github.com/ivanahuckova) + +### Bug Fixes + +- **API**: Fix short URLs. [#28300](https://github.com/grafana/grafana/pull/28300), [@aknuds1](https://github.com/aknuds1) +- **BackendSrv**: Fixes queue countdown when unsubscribe is before response. [#28323](https://github.com/grafana/grafana/pull/28323), [@hugohaggmark](https://github.com/hugohaggmark) +- **CloudWatch/Athena - valid metrics and dimensions.**. [#28436](https://github.com/grafana/grafana/pull/28436), [@kwarunek](https://github.com/kwarunek) +- **Dashboard links**: Places drop down list so it's always visible. [#28330](https://github.com/grafana/grafana/pull/28330), [@maknik](https://github.com/maknik) +- **Graph**: Fix for graph size not taking up full height or width. [#28314](https://github.com/grafana/grafana/pull/28314), [@jackw](https://github.com/jackw) +- **Loki**: Base maxDataPoints limits on query type. [#28298](https://github.com/grafana/grafana/pull/28298), [@aocenas](https://github.com/aocenas) +- **Loki**: Run instant query only when doing metric query. [#28325](https://github.com/grafana/grafana/pull/28325), [@aocenas](https://github.com/aocenas) +- **Plugins**: Don't exit on duplicate plugin. [#28390](https://github.com/grafana/grafana/pull/28390), [@aknuds1](https://github.com/aknuds1) + +# 7.3.0-beta1 (2020-10-15) + +### Breaking changes + +- **CloudWatch**: The AWS CloudWatch data source's authentication scheme has changed. See the [upgrade notes](https://grafana.com/docs/grafana/latest/installation/upgrading/#upgrading-to-v73) for details and how this may affect you. +- **Docker**: The Grafana docker image will run with the root group instead of the Grafana group. This may break builds for users who extend the official Docker images. Refer to the [upgrade notes](https://grafana.com/docs/grafana/latest/installation/upgrading/#upgrading-to-v73) for details. + +### Features / Enhancements + +- **Alerting**: Add labels to name when converting data frame to series. [#28085](https://github.com/grafana/grafana/pull/28085), [@kylebrandt](https://github.com/kylebrandt) +- **Alerting**: Ensuring LINE Notify notifications are sent for all alert states. [#27639](https://github.com/grafana/grafana/pull/27639), [@haraldkubota](https://github.com/haraldkubota) +- **Auth**: Add SigV4 auth option to datasources. [#27552](https://github.com/grafana/grafana/pull/27552), [@wbrowne](https://github.com/wbrowne) +- **AzureMonitor**: Pass through null values instead of setting 0. [#28126](https://github.com/grafana/grafana/pull/28126), [@kylebrandt](https://github.com/kylebrandt) +- **Cloud Monitoring**: Out-of-the-box dashboards. [#27864](https://github.com/grafana/grafana/pull/27864), [@papagian](https://github.com/papagian) +- **CloudWatch**: Add support for AWS DirectConnect virtual interface metrics and add missing dimensions. [#28008](https://github.com/grafana/grafana/pull/28008), [@jgulick48](https://github.com/jgulick48) +- **CloudWatch**: Adding support for Amazon ElastiCache Redis metrics. [#28040](https://github.com/grafana/grafana/pull/28040), [@jgulick48](https://github.com/jgulick48) +- **CloudWatch**: Adding support for additional Amazon CloudFront metrics. [#28069](https://github.com/grafana/grafana/pull/28069), [@darrylsepeda](https://github.com/darrylsepeda) +- **CloudWatch**: Re-implement authentication. [#25548](https://github.com/grafana/grafana/pull/25548), [@aknuds1](https://github.com/aknuds1),[@patstrom](https://github.com/patstrom) +- **Dashboard**: Allow shortlink generation. [#27409](https://github.com/grafana/grafana/pull/27409), [@MisterSquishy](https://github.com/MisterSquishy) +- **Docker**: OpenShift compatibility. [#27813](https://github.com/grafana/grafana/pull/27813), [@xlson](https://github.com/xlson) +- **Elasticsearch**: Support multiple pipeline aggregations for a query. [#27945](https://github.com/grafana/grafana/pull/27945), [@simianhacker](https://github.com/simianhacker) +- **Explore**: Allow shortlink generation. [#28222](https://github.com/grafana/grafana/pull/28222), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Remove collapsing of visualisations. [#27026](https://github.com/grafana/grafana/pull/27026), [@ivanahuckova](https://github.com/ivanahuckova) +- **FieldColor**: Adds new standard color option for color. [#28039](https://github.com/grafana/grafana/pull/28039), [@torkelo](https://github.com/torkelo) +- **Gauge**: Improve text sizing and support non threshold color modes. [#28256](https://github.com/grafana/grafana/pull/28256), [@torkelo](https://github.com/torkelo) +- **NamedColors**: Named colors refactors. [#28235](https://github.com/grafana/grafana/pull/28235), [@torkelo](https://github.com/torkelo) +- **Panel Inspect**: Allow CSV download for Excel. [#27284](https://github.com/grafana/grafana/pull/27284), [@tomdaly](https://github.com/tomdaly) +- **Prometheus**: Add time range parameters to labels API. [#27548](https://github.com/grafana/grafana/pull/27548), [@kakkoyun](https://github.com/kakkoyun) +- **Snapshots**: Store dashboard data encrypted in the database. [#28129](https://github.com/grafana/grafana/pull/28129), [@wbrowne](https://github.com/wbrowne) +- **Table**: New cell hover behavior and image cell display mode. [#27669](https://github.com/grafana/grafana/pull/27669), [@torkelo](https://github.com/torkelo) +- **Timezones**: Include IANA timezone canonical name in TimeZoneInfo. [#27591](https://github.com/grafana/grafana/pull/27591), [@dprokop](https://github.com/dprokop) +- **Tracing**: Add Tempo data source. [#28204](https://github.com/grafana/grafana/pull/28204), [@aocenas](https://github.com/aocenas) +- **Transformations**: Add Concatenate fields transformer. [#28237](https://github.com/grafana/grafana/pull/28237), [@ryantxu](https://github.com/ryantxu) +- **Transformations**: improve the reduce transformer. [#27875](https://github.com/grafana/grafana/pull/27875), [@ryantxu](https://github.com/ryantxu) +- **Users**: Expire old user invites. [#27361](https://github.com/grafana/grafana/pull/27361), [@wbrowne](https://github.com/wbrowne) +- **Variables**: Adds loading state and indicators. [#27917](https://github.com/grafana/grafana/pull/27917), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Adds support for key/value mapping in Custom variable. [#27829](https://github.com/grafana/grafana/pull/27829), [@sartaj10](https://github.com/sartaj10) +- **grafana/toolkit**: expose Jest maxWorkers arg for plugin test & build tasks. [#27724](https://github.com/grafana/grafana/pull/27724), [@domasx2](https://github.com/domasx2) + +### Bug Fixes + +- **Azure Analytics**: FormatAs Time series groups bool columns wrong. [#27713](https://github.com/grafana/grafana/issues/27713) +- **Azure**: Fixes cancellation of requests with different Azure sources. [#28180](https://github.com/grafana/grafana/pull/28180), [@hugohaggmark](https://github.com/hugohaggmark) +- **BackendSrv**: Reloads page instead of redirect on Unauthorized Error. [#28276](https://github.com/grafana/grafana/pull/28276), [@hugohaggmark](https://github.com/hugohaggmark) +- **Dashboard**: Do not allow users without edit permission to a folder to see new dashboard page. [#28249](https://github.com/grafana/grafana/pull/28249), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Fixed issue accessing horizontal table scrollbar when placed at bottom of dashboard. [#28250](https://github.com/grafana/grafana/pull/28250), [@torkelo](https://github.com/torkelo) +- **DataProxy**: Add additional settings for dataproxy to help with network proxy timeouts. [#27841](https://github.com/grafana/grafana/pull/27841), [@kahinton](https://github.com/kahinton) +- **Database**: Adds new indices to alert_notification_state and alert_rule_tag tables. [#28166](https://github.com/grafana/grafana/pull/28166), [@KarineValenca](https://github.com/KarineValenca) +- **Explore**: Fix showing of Prometheus data in Query inspector. [#28128](https://github.com/grafana/grafana/pull/28128), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Show results of Prometheus instant queries in formatted table. [#27767](https://github.com/grafana/grafana/pull/27767), [@ivanahuckova](https://github.com/ivanahuckova) +- **Graph**: Prevent legend from overflowing container. [#28254](https://github.com/grafana/grafana/pull/28254), [@jackw](https://github.com/jackw) +- **OAuth**: Fix token refresh failure when custom SSL settings are configured for OAuth provider. [#27523](https://github.com/grafana/grafana/pull/27523), [@billoley](https://github.com/billoley) +- **Plugins**: Let descendant plugins inherit their root's signature. [#27970](https://github.com/grafana/grafana/pull/27970), [@aknuds1](https://github.com/aknuds1) +- **Runtime**: Fix handling of short-lived background services. [#28025](https://github.com/grafana/grafana/pull/28025), [@ahlaw](https://github.com/ahlaw) +- **TemplateSrv**: Fix interpolating strings with object variables. [#28171](https://github.com/grafana/grafana/pull/28171), [@torkelo](https://github.com/torkelo) +- **Variables**: Fixes so constants set from url get completed state. [#28257](https://github.com/grafana/grafana/pull/28257), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Prevent adhoc filters from crashing when they are not loaded properly. [#28226](https://github.com/grafana/grafana/pull/28226), [@mckn](https://github.com/mckn) + + + +# 7.2.3 (2020-12-17) + +### Security + +- **SAML**: Fixes encoding/xml SAML vulnerability in Grafana Enterprise [#29875](https://github.com/grafana/grafana/issues/29875), [@bergquist](https://github.com/bergquist) + + + +# 7.2.2 (2020-10-21) + +### Features / Enhancements + +**Caution:** Please do not use/enable the `database_metrics` feature flag. It will corrupt MySQL database tables. See [#28440](https://github.com/grafana/grafana/issues/28440) for more information. + +~~**Instrumentation**: Add counters and histograms for database queries. [#28236](https://github.com/grafana/grafana/pull/28236), [@bergquist](https://github.com/bergquist)~~ + +- **Instrumentation**: Add histogram for request duration. [#28364](https://github.com/grafana/grafana/pull/28364), [@bergquist](https://github.com/bergquist) +- **Instrumentation**: Adds environment_info metric. [#28355](https://github.com/grafana/grafana/pull/28355), [@bergquist](https://github.com/bergquist) + +### Bug Fixes + +- **CloudWatch**: Fix custom metrics. [#28391](https://github.com/grafana/grafana/pull/28391), [@aknuds1](https://github.com/aknuds1) + +# 7.2.1 (2020-10-08) + +### Features / Enhancements + +- **Api**: Add /healthz endpoint for health checks. [#27536](https://github.com/grafana/grafana/pull/27536), [@bergquist](https://github.com/bergquist) +- **Api**: Healthchecks should not be rejected due to domain enforcement checks. [#27981](https://github.com/grafana/grafana/pull/27981), [@bergquist](https://github.com/bergquist) +- **Instrumentation**: Removes invalid chars from label names. [#27921](https://github.com/grafana/grafana/pull/27921), [@bergquist](https://github.com/bergquist) +- **Orgs**: Remove organisations deprecation notice from backend. [#27788](https://github.com/grafana/grafana/pull/27788), [@wbrowne](https://github.com/wbrowne) +- **grafana/toolkit**: Add --coverage flag to plugin build command. [#27743](https://github.com/grafana/grafana/pull/27743), [@gassiss](https://github.com/gassiss) + +### Bug Fixes + +- **BarGauge**: Fixed scrollbar showing for bar gauge in Firefox. [#27784](https://github.com/grafana/grafana/pull/27784), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Honour root_url for Explore link. [#27654](https://github.com/grafana/grafana/pull/27654), [@tiagomotasantos](https://github.com/tiagomotasantos) +- **DashboardLinks**: values in links are updated when variables change. [#27926](https://github.com/grafana/grafana/pull/27926), [@hugohaggmark](https://github.com/hugohaggmark) +- **Elasticsearch**: Add query's refId to each series returned by a query. [#27614](https://github.com/grafana/grafana/pull/27614), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Fix ad-hoc filter support for Raw Data query and new table panel. [#28064](https://github.com/grafana/grafana/pull/28064), [@Elfo404](https://github.com/Elfo404) +- **Graph**: Fixed histogram bucket calculations to avoid missing buckets. [#27883](https://github.com/grafana/grafana/pull/27883), [@torkelo](https://github.com/torkelo) +- **Loki**: Run instant query only in Explore. [#27974](https://github.com/grafana/grafana/pull/27974), [@ivanahuckova](https://github.com/ivanahuckova) +- **Units**: bps & Bps default scale remains decimal (backwards-compatibility). [#27838](https://github.com/grafana/grafana/pull/27838), [@Berbe](https://github.com/Berbe) +- **ValueMappings**: Fix issue with value mappings in override applying to all columns. [#27718](https://github.com/grafana/grafana/pull/27718), [@torkelo](https://github.com/torkelo) + +# 7.2.0 (2020-09-23) + +### Features / Enhancements + +- **Alerting**: Ensuring notifications displayed correctly in mobile device with Google Chat. [#27578](https://github.com/grafana/grafana/pull/27578), [@alvarolmedo](https://github.com/alvarolmedo) +- **TraceView**: Show full traceID and better discern multiple stackTraces in span details. [#27710](https://github.com/grafana/grafana/pull/27710), [@aocenas](https://github.com/aocenas) + +### Bug Fixes + +- **DataLinks**: Fixes issue with data links not interpolating values with correct field config. [#27622](https://github.com/grafana/grafana/pull/27622), [@torkelo](https://github.com/torkelo) +- **DataProxy**: Ignore empty URL's in plugin routes. [#27653](https://github.com/grafana/grafana/pull/27653), [@domasx2](https://github.com/domasx2) +- **Field config**: Respect config paths when rendering default value of field config property. [#27652](https://github.com/grafana/grafana/pull/27652), [@dprokop](https://github.com/dprokop) +- **Field config**: Fix mismatch in field config editor types. [#27657](https://github.com/grafana/grafana/pull/27657), [@dprokop](https://github.com/dprokop) +- **Panel editor**: Prevents adding transformations in panels with alerts. [#27706](https://github.com/grafana/grafana/pull/27706), [@hugohaggmark](https://github.com/hugohaggmark) +- **Stat panel**: Fix problem where string values where always green. [#27656](https://github.com/grafana/grafana/pull/27656), [@peterholmberg](https://github.com/peterholmberg) + +# 7.2.0-beta2 (2020-09-17) + +### Features / Enhancements + +- **API**: Enrich add user to org endpoints with user ID in the response. [#27551](https://github.com/grafana/grafana/pull/27551), [@AgnesToulet](https://github.com/AgnesToulet) +- **API**: Enrich responses and improve error handling for alerting API endpoints. [#27550](https://github.com/grafana/grafana/pull/27550), [@AgnesToulet](https://github.com/AgnesToulet) +- **Auth**: Replace maximum inactive/lifetime settings of days to duration. [#27150](https://github.com/grafana/grafana/pull/27150), [@Hansuuuuuuuuuu](https://github.com/Hansuuuuuuuuuu) +- **Dashboard**: Support configuring default timezone via config file. [#27404](https://github.com/grafana/grafana/pull/27404), [@woutersmeenk](https://github.com/woutersmeenk) +- **Elasticsearch**: Add support for date_nanos type. [#27538](https://github.com/grafana/grafana/pull/27538), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Allow fields starting with underscore. [#27520](https://github.com/grafana/grafana/pull/27520), [@Elfo404](https://github.com/Elfo404) +- **Elasticsearch**: Increase maximum geohash aggregation precision to 12. [#27539](https://github.com/grafana/grafana/pull/27539), [@Elfo404](https://github.com/Elfo404) +- **Field config**: Add support for paths in default field config setup. [#27570](https://github.com/grafana/grafana/pull/27570), [@dprokop](https://github.com/dprokop) +- **Postgres**: Support request cancellation properly (Uses new backendSrv.fetch Observable request API). [#27478](https://github.com/grafana/grafana/pull/27478), [@hugohaggmark](https://github.com/hugohaggmark) +- **Provisioning**: Remove provisioned dashboards without parental reader. [#26143](https://github.com/grafana/grafana/pull/26143), [@nabokihms](https://github.com/nabokihms) +- **Variables**: Limit rendering of options in dropdown to improve search performance. [#27525](https://github.com/grafana/grafana/pull/27525), [@guoqn](https://github.com/guoqn) +- **Units**: Binary-prefixed data rates. [#27022](https://github.com/grafana/grafana/pull/27022), [@Berbe](https://github.com/Berbe) + +### Bug Fixes + +- **Admin**: Fixes close('X') button layout issue in API keys page. [#27625](https://github.com/grafana/grafana/pull/27625), [@nikasvan](https://github.com/nikasvan) +- **Alerting**: Fix integration key so it's stored encrypted for Pagerduty notifier. [#27484](https://github.com/grafana/grafana/pull/27484), [@marefr](https://github.com/marefr) +- **Annotations**: Fixes issue with showing error notice for cancelled annotation queries. [#27557](https://github.com/grafana/grafana/pull/27557), [@torkelo](https://github.com/torkelo) +- **Azure/Insights**: Fix handling of legacy dimension values. [#27513](https://github.com/grafana/grafana/pull/27513), [@marefr](https://github.com/marefr) +- **DataLinks**: Respects display name and adds field quoting. [#27616](https://github.com/grafana/grafana/pull/27616), [@hugohaggmark](https://github.com/hugohaggmark) +- **ImageRendering**: Fix rendering panel using shared query in png, PDF reports and embedded scenarios. [#27628](https://github.com/grafana/grafana/pull/27628), [@torkelo](https://github.com/torkelo) +- **InputControl**: Fixed using InputControl in unit tests from plugins. [#27615](https://github.com/grafana/grafana/pull/27615), [@torkelo](https://github.com/torkelo) +- **NewsPanel**: Fixed XSS issue when rendering rss links. [#27612](https://github.com/grafana/grafana/pull/27612), [@torkelo](https://github.com/torkelo) +- **Transforms**: Fix for issue in labels to fields transform where the new option value field name did not work properly. [#27501](https://github.com/grafana/grafana/pull/27501), [@torkelo](https://github.com/torkelo) + +# 7.2.0-beta1 (2020-09-09) + +### Breaking changes + +- **Units**: The date time units `YYYY-MM-DD HH:mm:ss` and `MM/DD/YYYY h:mm:ss a` have been renamed to `Datetime ISO` + and `Datetime US` respectively. This is no breaking change just a visual name change (the unit id is unchanged). The + unit behavior is different however, it no longer hides the date part if the date is today. If you want this old + behavior you need to change unit to `Datetime ISO (No date if today)` or `Datetime US (No date if today)`. + +### Features / Enhancements + +- **API**: Return ID of the deleted resource for dashboard, datasource and folder DELETE endpoints. [#26691](https://github.com/grafana/grafana/pull/26691), [@AgnesToulet](https://github.com/AgnesToulet) +- **API**: Support paging in the admin orgs list API. [#26932](https://github.com/grafana/grafana/pull/26932), [@benjaminjb](https://github.com/benjaminjb) +- **API**: return resource ID for auth key creation, folder permissions update and user invite complete endpoints. [#27419](https://github.com/grafana/grafana/pull/27419), [@AgnesToulet](https://github.com/AgnesToulet) +- **Alerting**: Add toggle to disable alert threshold visibility in graph panel. [#25705](https://github.com/grafana/grafana/pull/25705), [@jpalpant](https://github.com/jpalpant) +- **Alerting**: Adds support for overriding 'dedup_key' via alert tags when using the Pagerduty notifier. [#27356](https://github.com/grafana/grafana/pull/27356), [@alavrovinfb](https://github.com/alavrovinfb) +- **Alerting**: Change alert rule link in alert notifications to open panel in view mode. [#27378](https://github.com/grafana/grafana/pull/27378), [@robertlestak](https://github.com/robertlestak) +- **Alerting**: Support storing sensitive notifier settings securely/encrypted. [#25114](https://github.com/grafana/grafana/pull/25114), [@mtanda](https://github.com/mtanda) +- **Annotation**: Add clean up job for old annotations. [#26156](https://github.com/grafana/grafana/pull/26156), [@bergquist](https://github.com/bergquist) +- **AzureMonitor**: select plugin route from cloudname. [#27273](https://github.com/grafana/grafana/pull/27273), [@kylebrandt](https://github.com/kylebrandt) +- **BackendSrv**: Uses credentials, deprecates withCredentials & defaults to same-origin. [#27385](https://github.com/grafana/grafana/pull/27385), [@hugohaggmark](https://github.com/hugohaggmark) +- **Chore**: Upgrade to Go 1.15.1. [#27326](https://github.com/grafana/grafana/pull/27326), [@aknuds1](https://github.com/aknuds1) +- **CloudWatch**: Update list of AmazonMQ metrics and dimensions. [#27332](https://github.com/grafana/grafana/pull/27332), [@szymonpk](https://github.com/szymonpk) +- **Cloudwatch**: Add Support for external ID in assume role. [#23685](https://github.com/grafana/grafana/pull/23685), [@gdhananjay](https://github.com/gdhananjay) +- **Cloudwatch**: Add af-south-1 region. [#26513](https://github.com/grafana/grafana/pull/26513), [@ruanbekker](https://github.com/ruanbekker) +- **Dashboard**: Add Duplicate dashboard links button to links list. [#26600](https://github.com/grafana/grafana/pull/26600), [@Hmerac](https://github.com/Hmerac) +- **Dashboard**: Adds folder name and link to the dashboard overview on the homepage. [#27214](https://github.com/grafana/grafana/pull/27214), [@michelengelen](https://github.com/michelengelen) +- **Database**: Set 0640 permissions on SQLite database file. [#26339](https://github.com/grafana/grafana/pull/26339), [@aknuds1](https://github.com/aknuds1) +- **DateFormats**: Default ISO & US formats never omit date part even if date is today (breaking change). [#27300](https://github.com/grafana/grafana/pull/27300), [@torkelo](https://github.com/torkelo) +- **Explore/Loki**: POC for toggling parsed fields in the list view. [#26178](https://github.com/grafana/grafana/pull/26178), [@fredr](https://github.com/fredr) +- **Explore**: Sort order of log results. [#26669](https://github.com/grafana/grafana/pull/26669), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Transform prometheus query to elasticsearch query. [#23670](https://github.com/grafana/grafana/pull/23670), [@melchiormoulin](https://github.com/melchiormoulin) +- **Field overrides**: Overrides UI improvements. [#27073](https://github.com/grafana/grafana/pull/27073), [@dprokop](https://github.com/dprokop) +- **Heatmap**: Reduce the aggressiveness of hiding ticks/labels when panel is small. [#27016](https://github.com/grafana/grafana/pull/27016), [@lrstanley](https://github.com/lrstanley) +- **Image Store**: Add support for using signed URLs when uploading images to GCS. [#26840](https://github.com/grafana/grafana/pull/26840), [@marcosrmendezthd](https://github.com/marcosrmendezthd) +- **Image Store**: Fallback to application default credentials when no key file is specified for GCS. [#25948](https://github.com/grafana/grafana/pull/25948), [@Eraac](https://github.com/Eraac) +- **InfluxDB/Flux**: Increase series limit for Flux datasource. [#26746](https://github.com/grafana/grafana/pull/26746), [@sneddrs](https://github.com/sneddrs) +- **InfluxDB**: exclude result and table column from Flux table results. [#27081](https://github.com/grafana/grafana/pull/27081), [@ryantxu](https://github.com/ryantxu) +- **InfluxDB**: return a table rather than an error when timeseries is missing time. [#27320](https://github.com/grafana/grafana/pull/27320), [@ryantxu](https://github.com/ryantxu) +- **Instrumentation**: Adds instrumentation for outgoing datasource requests. [#27427](https://github.com/grafana/grafana/pull/27427), [@bergquist](https://github.com/bergquist) +- **Loki**: Add scopedVars support in legend formatting for repeated variables. [#27046](https://github.com/grafana/grafana/pull/27046), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Re-introduce running of instant queries. [#27213](https://github.com/grafana/grafana/pull/27213), [@ivanahuckova](https://github.com/ivanahuckova) +- **Loki**: Support request cancellation properly (Uses new backendSrv.fetch Observable request API). [#27265](https://github.com/grafana/grafana/pull/27265), [@hugohaggmark](https://github.com/hugohaggmark) +- **MixedDatasource**: Shows retrieved data even if a data source fails. [#27024](https://github.com/grafana/grafana/pull/27024), [@hugohaggmark](https://github.com/hugohaggmark) +- **OAuth**: Handle DEFLATE compressed payloads in JWT for Generic OAuth. [#26969](https://github.com/grafana/grafana/pull/26969), [@billoley](https://github.com/billoley) +- **OAuth**: Increase state cookie max age. [#27258](https://github.com/grafana/grafana/pull/27258), [@bergquist](https://github.com/bergquist) +- **Orgs**: Remove org deprecation notice as we have decided to preserve multi-org support. [#26853](https://github.com/grafana/grafana/pull/26853), [@torkelo](https://github.com/torkelo) +- **PanelInspector**: Adds a Raw display mode but defaults to Formatted display mode. [#27306](https://github.com/grafana/grafana/pull/27306), [@hugohaggmark](https://github.com/hugohaggmark) +- **Postgres**: Support Unix socket for host. [#25778](https://github.com/grafana/grafana/pull/25778), [@aknuds1](https://github.com/aknuds1) +- **Prometheus**: Add scopedVars support in legend formatting for repeated variables. [#27047](https://github.com/grafana/grafana/pull/27047), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Support request cancellation properly (Uses new backendSrv.fetch Observable request API). [#27090](https://github.com/grafana/grafana/pull/27090), [@hugohaggmark](https://github.com/hugohaggmark) +- **Prometheus**: add $\_\_rate_interval variable. [#26937](https://github.com/grafana/grafana/pull/26937), [@zoltanbedi](https://github.com/zoltanbedi) +- **Provisioning**: Validate that datasource access field equals to direct or proxy. [#26440](https://github.com/grafana/grafana/pull/26440), [@nabokihms](https://github.com/nabokihms) +- **RangeUtils**: migrate logic from kbn to grafana/data. [#27347](https://github.com/grafana/grafana/pull/27347), [@ryantxu](https://github.com/ryantxu) +- **Table**: Adds column filtering. [#27225](https://github.com/grafana/grafana/pull/27225), [@hugohaggmark](https://github.com/hugohaggmark) +- **Table**: Support showing numbers in strings with full original value. [#27097](https://github.com/grafana/grafana/pull/27097), [@torkelo](https://github.com/torkelo) +- **TablePanel**: Add support for basic gauge as a cell display mode. [#26595](https://github.com/grafana/grafana/pull/26595), [@jutley](https://github.com/jutley) +- **Transformations**: Group by and aggregate on multiple fields. [#25498](https://github.com/grafana/grafana/pull/25498), [@Totalus](https://github.com/Totalus) +- **Transformations**: enable transformations reorder. [#27197](https://github.com/grafana/grafana/pull/27197), [@dprokop](https://github.com/dprokop) +- **Units**: Allow re-scaling nanoseconds up to days. [#26458](https://github.com/grafana/grafana/pull/26458), [@kaydelaney](https://github.com/kaydelaney) +- **grafana-cli**: Add ability to read password from stdin to reset admin password. [#26016](https://github.com/grafana/grafana/pull/26016), [@nabokihms](https://github.com/nabokihms) +- **Reporting**: add branding options. (Enterprise) +- **Reporting**: allow setting custom timerange. (Enterprise) + +### Bug Fixes + +- **Auth**: Fix signup workflow and UI when verify email is enabled. [#26263](https://github.com/grafana/grafana/pull/26263), [@KamalGalrani](https://github.com/KamalGalrani) +- **AzureMonitor**: Change filterDimensions property to match what is stored. [#27459](https://github.com/grafana/grafana/pull/27459), [@kylebrandt](https://github.com/kylebrandt) +- **Cloud Monitoring**: Fix missing title and text from cloud monitoring annotations. [#27187](https://github.com/grafana/grafana/pull/27187), [@atotto](https://github.com/atotto) +- **CloudWatch**: Fix error message returned from tag:GetResources. [#27205](https://github.com/grafana/grafana/pull/27205), [@kichik](https://github.com/kichik) +- **Cloudwatch**: Update AWS/MediaConnect metrics and dimensions. [#26093](https://github.com/grafana/grafana/pull/26093), [@papagian](https://github.com/papagian) +- **DashboardSettings**: Fixes auto refresh crash with space in interval. [#27438](https://github.com/grafana/grafana/pull/27438), [@hugohaggmark](https://github.com/hugohaggmark) +- **Elasticsearch**: Fix localized dates in index pattern. [#27351](https://github.com/grafana/grafana/pull/27351), [@domasx2](https://github.com/domasx2) +- **Elasticsearch**: Fix using multiple bucket script aggregations when only grouping by terms. [#24064](https://github.com/grafana/grafana/pull/24064), [@MarceloNunesAlves](https://github.com/MarceloNunesAlves) +- **Explore**: Expand template variables when redirecting from dashboard panel. [#27354](https://github.com/grafana/grafana/pull/27354), [@Elfo404](https://github.com/Elfo404) +- **FolderPicker**: Fixes not being able to create new folder. [#27092](https://github.com/grafana/grafana/pull/27092), [@hugohaggmark](https://github.com/hugohaggmark) +- **Graphite**: Show and hide query editor function popup on click. [#26923](https://github.com/grafana/grafana/pull/26923), [@ivanahuckova](https://github.com/ivanahuckova) +- **InfluxDB/Flux**: Fix for Alerts on InfluxDB Flux datasources only use the first series. [#27463](https://github.com/grafana/grafana/pull/27463), [@ryantxu](https://github.com/ryantxu) +- **Loki**: Send current time range when fetching labels and values. [#26622](https://github.com/grafana/grafana/pull/26622), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Add backslash escaping for template variables. [#26205](https://github.com/grafana/grafana/pull/26205), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Correctly format multi values variables in queries. [#26896](https://github.com/grafana/grafana/pull/26896), [@ivanahuckova](https://github.com/ivanahuckova) +- **Provisioning**: Add validation for missing organisations in datasource, dashboard, and notifier configurations. [#26601](https://github.com/grafana/grafana/pull/26601), [@nabokihms](https://github.com/nabokihms) +- **Rendering**: Fixed issue rendering text panel to image via image renderer plugin. [#27083](https://github.com/grafana/grafana/pull/27083), [@torkelo](https://github.com/torkelo) +- **Stats**: Use more efficient SQL and add timeouts. [#27390](https://github.com/grafana/grafana/pull/27390), [@sakjur](https://github.com/sakjur) +- **Table**: Support date unit formats on string values. [#26879](https://github.com/grafana/grafana/pull/26879), [@torkelo](https://github.com/torkelo) +- **Thresholds**: Fixed issue with thresholds in overrides not working after save and reload. [#27297](https://github.com/grafana/grafana/pull/27297), [@torkelo](https://github.com/torkelo) +- **Transformations**: Fixes outer join transformation when frames are missing field to join by. [#27453](https://github.com/grafana/grafana/pull/27453), [@hugohaggmark](https://github.com/hugohaggmark) +- **Transformations**: merge will properly handle empty frames and frames with multiple rows where values are overlapping. [#27362](https://github.com/grafana/grafana/pull/27362), [@mckn](https://github.com/mckn) +- **grafana-cli**: Fix installing of plugins missing directory entries in zip. [#26945](https://github.com/grafana/grafana/pull/26945), [@adrianlzt](https://github.com/adrianlzt) + +# 7.1.5 (2020-08-25) + +### Features / Enhancements + +- **Stats**: Stop counting the same user multiple times. [#26777](https://github.com/grafana/grafana/pull/26777), [@sakjur](https://github.com/sakjur) + +### Bug Fixes + +- **Alerting**: remove LongToWide call in alerting. [#27140](https://github.com/grafana/grafana/pull/27140), [@kylebrandt](https://github.com/kylebrandt) +- **AzureMonitor**: fix panic introduced in 7.1.4 when unit was unspecified and alias was used. [#27113](https://github.com/grafana/grafana/pull/27113), [@kylebrandt](https://github.com/kylebrandt) +- **Variables**: Fixes issue with All variable not being resolved. [#27151](https://github.com/grafana/grafana/pull/27151), [@hugohaggmark](https://github.com/hugohaggmark) + +# 7.1.4 (2020-08-20) + +### Features / Enhancements + +- **Azure App Insights Alert error - tsdb.HandleRequest() failed to convert dataframe "" to tsdb.TimeSeriesSlice**. [#26897](https://github.com/grafana/grafana/issues/26897) +- **AzureMonitor**: map more units. [#26990](https://github.com/grafana/grafana/pull/26990), [@kylebrandt](https://github.com/kylebrandt) +- **Azuremonitor**: do not set unit if literal "Unspecified". [#26839](https://github.com/grafana/grafana/pull/26839), [@kylebrandt](https://github.com/kylebrandt) +- **Dataframe/Alerting**: to tsdb.TimeSeriesSlice - accept "empty" time series. [#26903](https://github.com/grafana/grafana/pull/26903), [@kylebrandt](https://github.com/kylebrandt) +- **Field overrides**: Filter by field name using regex. [#27070](https://github.com/grafana/grafana/pull/27070), [@dprokop](https://github.com/dprokop) +- **Overrides**: expose byType matcher UI. [#27056](https://github.com/grafana/grafana/pull/27056), [@ryantxu](https://github.com/ryantxu) + +### Bug Fixes + +- **CloudWatch**: Add FreeStorageCapacity metric. [#26503](https://github.com/grafana/grafana/pull/26503), [@waqark3389](https://github.com/waqark3389) +- **CloudWatch**: Fix sorting of metrics results. [#26835](https://github.com/grafana/grafana/pull/26835), [@aknuds1](https://github.com/aknuds1) +- **Cloudwatch**: Add FileSystemId as a dimension key for the AWS/FSx namespace. [#26662](https://github.com/grafana/grafana/pull/26662), [@waqark3389](https://github.com/waqark3389) +- **InfluxDB**: Update Flux placeholder URL with respect to latest Go client. [#27086](https://github.com/grafana/grafana/pull/27086), [@aknuds1](https://github.com/aknuds1) +- **InfluxDB**: Upgrade Go client, use data source HTTP client. [#27012](https://github.com/grafana/grafana/pull/27012), [@aknuds1](https://github.com/aknuds1) +- **Proxy**: Fix updating refresh token in OAuth pass-thru. [#26885](https://github.com/grafana/grafana/pull/26885), [@seanlaff](https://github.com/seanlaff) +- **Templating**: Fixes so texts show in picker not the values. [#27002](https://github.com/grafana/grafana/pull/27002), [@hugohaggmark](https://github.com/hugohaggmark) + +# 7.1.3 (2020-08-06) + +### Bug Fixes + +- **Templating**: Templating: Fix undefined result when using raw interpolation format [#26818](https://github.com/grafana/grafana/pull/26818) + +# 7.1.2 (2020-08-05) + +### Features / Enhancements + +- **Explore**: Don't run queries on datasource change. [#26033](https://github.com/grafana/grafana/pull/26033), [@davkal](https://github.com/davkal) +- **TemplateSrv**: Formatting options for ${**from} and ${**to}, unix seconds epoch, ISO 8601/RFC 3339. [#26466](https://github.com/grafana/grafana/pull/26466), [@torkelo](https://github.com/torkelo) +- **Toolkit/Plugin**: throw an Error instead of a string. [#26618](https://github.com/grafana/grafana/pull/26618), [@leventebalogh](https://github.com/leventebalogh) + +### Bug Fixes + +- **Dashbard**: Fix refresh interval settings to allow setting it to equal min_refresh_interval. [#26615](https://github.com/grafana/grafana/pull/26615), [@torkelo](https://github.com/torkelo) +- **Flux**: Ensure connections to InfluxDB are closed. [#26735](https://github.com/grafana/grafana/pull/26735), [@sneddrs](https://github.com/sneddrs) +- **Query history**: Fix search filtering if null value. [#26768](https://github.com/grafana/grafana/pull/26768), [@ivanahuckova](https://github.com/ivanahuckova) +- **QueryOptions**: Fix not being able to change cache timeout setting. [#26614](https://github.com/grafana/grafana/pull/26614), [@torkelo](https://github.com/torkelo) +- **StatPanel**: Fix stat panel display name not showing when explicitly set. [#26616](https://github.com/grafana/grafana/pull/26616), [@torkelo](https://github.com/torkelo) +- **Templating**: Fixed access to system variables like **dashboard, **user & \_\_org during dashboard load & variable queries. [#26637](https://github.com/grafana/grafana/pull/26637), [@torkelo](https://github.com/torkelo) +- **TextPanel**: Fix content overflowing panel boundaries. [#26612](https://github.com/grafana/grafana/pull/26612), [@torkelo](https://github.com/torkelo) +- **TimePicker**: Fix position and responsive behavior. [#26570](https://github.com/grafana/grafana/pull/26570), [@torkelo](https://github.com/torkelo) +- **TimePicker**: Fixes app crash when changing custom range to nothing. [#26775](https://github.com/grafana/grafana/pull/26775), [@hugohaggmark](https://github.com/hugohaggmark) +- **Units**: Remove duplicate SI prefix from mSv and µSv. [#26598](https://github.com/grafana/grafana/pull/26598), [@tofurky](https://github.com/tofurky) + +# 7.1.1 (2020-07-24) + +### Features / Enhancements + +- **Graph**: Support setting field unit & override data source (automatic) unit. [#26529](https://github.com/grafana/grafana/pull/26529), [@ryantxu](https://github.com/ryantxu) +- **Tracing**: Add errorIconColor prop to TraceSpanData. [#26509](https://github.com/grafana/grafana/pull/26509), [@zoltanbedi](https://github.com/zoltanbedi) + +### Bug Fixes + +- **Branding**: Fix login app title. [#26425](https://github.com/grafana/grafana/pull/26425), [@benrubson](https://github.com/benrubson) +- **Bring back scripts evaluation in TextPanel**. [#26413](https://github.com/grafana/grafana/pull/26413), [@dprokop](https://github.com/dprokop) +- **Dashboard**: Fix empty panels after scrolling on Safari/iOS. [#26495](https://github.com/grafana/grafana/pull/26495), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Fix for viewer can enter panel edit mode by modifying url (but cannot not save anything). [#26556](https://github.com/grafana/grafana/pull/26556), [@torkelo](https://github.com/torkelo) +- **Elasticsearch**: Fix displaying of bucket script input. [#26552](https://github.com/grafana/grafana/pull/26552), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: parse queryType from explore url. [#26349](https://github.com/grafana/grafana/pull/26349), [@zoltanbedi](https://github.com/zoltanbedi) +- **Tracing**: upstream fix for hovering on log lines. [#26426](https://github.com/grafana/grafana/pull/26426), [@zoltanbedi](https://github.com/zoltanbedi) + +# 7.1.0 (2020-07-16) + +### Features / Enhancements + +- **Backend**: Use latest go plugin sdk (0.74.0) to sort wide frames. [#26207](https://github.com/grafana/grafana/pull/26207), [@kylebrandt](https://github.com/kylebrandt) +- **Elasticsearch**: Create Raw Doc metric to render raw JSON docs in columns in the new table panel. [#26233](https://github.com/grafana/grafana/pull/26233), [@ivanahuckova](https://github.com/ivanahuckova) +- **PluginsListPage**: More plugins button should open in new window. [#26305](https://github.com/grafana/grafana/pull/26305), [@zoltanbedi](https://github.com/zoltanbedi) + +### Bug Fixes + +- **AdminUsers**: Reset page to zero on query change. [#26293](https://github.com/grafana/grafana/pull/26293), [@hshoff](https://github.com/hshoff) +- **CloudWatch Logs**: Fixes grouping of results by numeric field. [#26298](https://github.com/grafana/grafana/pull/26298), [@kaydelaney](https://github.com/kaydelaney) +- **DashboardLinks**: Do not over-query search endpoint. [#26311](https://github.com/grafana/grafana/pull/26311), [@torkelo](https://github.com/torkelo) +- **Docker**: Make sure to create default plugin provisioning directory. [#26017](https://github.com/grafana/grafana/pull/26017), [@marefr](https://github.com/marefr) +- **Elastic**: Fix error "e.buckets[Symbol.iterator] is not a function" when using filter. [#26217](https://github.com/grafana/grafana/pull/26217), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore/Loki**: Escape \ in labels for show context queries. [#26116](https://github.com/grafana/grafana/pull/26116), [@ivanahuckova](https://github.com/ivanahuckova) +- **Jaeger/Zipkin**: URL-encode service names and trace ids for API calls. [#26115](https://github.com/grafana/grafana/pull/26115), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Fix prom links in mixed mode. [#26244](https://github.com/grafana/grafana/pull/26244), [@zoltanbedi](https://github.com/zoltanbedi) +- **Provisioning**: Fix bug when provision app plugins using Enterprise edition. [#26340](https://github.com/grafana/grafana/pull/26340), [@marefr](https://github.com/marefr) +- **Sign In** Use correct url for the Sign In button. [#26239](https://github.com/grafana/grafana/pull/26239), [@dprokop](https://github.com/dprokop) + +# 7.1.0-beta3 (2020-07-13) + +### Features / Enhancements + +- **Explore**: Unification of logs/metrics/traces user interface. [#25890](https://github.com/grafana/grafana/pull/25890), [@aocenas](https://github.com/aocenas) +- **Graph panel**: Move Stacking and null values before Hover tooltip options (#26035). [#26037](https://github.com/grafana/grafana/pull/26037), [@jsoref](https://github.com/jsoref) +- **LDAP**: Get all groups for all group base search DNs. [#25825](https://github.com/grafana/grafana/pull/25825), [@Annegies](https://github.com/Annegies) +- **Table**: JSON Cell should try to convert strings to JSON. [#26024](https://github.com/grafana/grafana/pull/26024), [@ryantxu](https://github.com/ryantxu) +- **Transform**: adding missing "table"-transform and "series to rows"-transform to Grafana v7-transforms. [#26042](https://github.com/grafana/grafana/pull/26042), [@mckn](https://github.com/mckn) + +### Bug Fixes + +- **AdminUsersTable**: Fix width issues. [#26019](https://github.com/grafana/grafana/pull/26019), [@tskarhed](https://github.com/tskarhed) +- **BarGauge**: Fix space bug in single series mode. [#26176](https://github.com/grafana/grafana/pull/26176), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Allow removing min refresh interval from refresh options (5s or other). [#26150](https://github.com/grafana/grafana/pull/26150), [@torkelo](https://github.com/torkelo) +- **DataLinks**: Fixed interpolation of repeated variables used in Graph data links. [#26147](https://github.com/grafana/grafana/pull/26147), [@torkelo](https://github.com/torkelo) +- **Do not break dashboard settings UI when time intervals end with trailing comma**. [#26126](https://github.com/grafana/grafana/pull/26126), [@dprokop](https://github.com/dprokop) +- **Elastic**: Display correct log message based on selected log field. [#26020](https://github.com/grafana/grafana/pull/26020), [@ivanahuckova](https://github.com/ivanahuckova) +- **InfluxDB**: Fixed new group by dropdown now showing after first use. [#26031](https://github.com/grafana/grafana/pull/26031), [@torkelo](https://github.com/torkelo) +- **StatPanel**: Fixes issue with name showing for single series / field results. [#26070](https://github.com/grafana/grafana/pull/26070), [@torkelo](https://github.com/torkelo) +- **Templating**: Fix recursive loop of template variable queries when changing ad-hoc-variable. [#26191](https://github.com/grafana/grafana/pull/26191), [@torkelo](https://github.com/torkelo) + +# 7.0.6 (2020-07-09) + +### Bug fixes + +- **Templating**: Fixed recursive queries triggered when switching dashboard settings view [#26137](https://github.com/grafana/grafana/pull/26137) +- **Templating**: Fix recursive loop of template variable queries when changing ad-hoc-variable [#26191](https://github.com/grafana/grafana/pull/26191) +- **Auth**: Add support for forcing authentication in anonymous mode and modify SignIn to use it instead of redirect [#25567](https://github.com/grafana/grafana/pull/25567) +- **Auth**: Fix POST request failures with anonymous access [#26049](https://github.com/grafana/grafana/pull/26049) + +# 7.1.0-beta 2 (2020-07-02) + +### Features / Enhancements + +- **Loki**: Allow aliasing Loki queries in dashboard. [#25706](https://github.com/grafana/grafana/pull/25706), [@bastjan](https://github.com/bastjan) + +### Bug Fixes + +- **Explore**: Fix href when jumping from Explore to Add data source. [#25991](https://github.com/grafana/grafana/pull/25991), [@ivanahuckova](https://github.com/ivanahuckova) +- **Fix**: Build-in plugins failed to load in windows. [#25982](https://github.com/grafana/grafana/pull/25982), [@papagian](https://github.com/papagian) + +# 7.1.0-beta 1 (2020-07-01) + +### Features / Enhancements + +- **Alerting**: Adds support for multiple URLs in Alertmanager notifier. [#24196](https://github.com/grafana/grafana/pull/24196), [@alistarle](https://github.com/alistarle) +- **Alerting**: updating the victorops alerter to handle the no_data alert type. [#23761](https://github.com/grafana/grafana/pull/23761), [@rrusso1982](https://github.com/rrusso1982) +- **Azure**: Application Insights metrics to Frame and support multiple query dimensions. [#25849](https://github.com/grafana/grafana/pull/25849), [@kylebrandt](https://github.com/kylebrandt) +- **Azure**: Multiple dimension support for Azure Monitor Service. [#25947](https://github.com/grafana/grafana/pull/25947), [@kylebrandt](https://github.com/kylebrandt) +- **Azure**: Split Insights into two services. [#25410](https://github.com/grafana/grafana/pull/25410), [@kylebrandt](https://github.com/kylebrandt) +- **Backend plugins**: Refactor to allow shared contract between core and external backend plugins. [#25472](https://github.com/grafana/grafana/pull/25472), [@marefr](https://github.com/marefr) +- **Branding**: Use AppTitle as document title. [#25271](https://github.com/grafana/grafana/pull/25271), [@benrubson](https://github.com/benrubson) +- **Chore**: upgrade to typescript 3.9.3. [#25154](https://github.com/grafana/grafana/pull/25154), [@ryantxu](https://github.com/ryantxu) +- **CloudWatch**: Add Route53 DNSQueries metric and dimension. [#25125](https://github.com/grafana/grafana/pull/25125), [@erkolson](https://github.com/erkolson) +- **CloudWatch**: Added AWS DataSync metrics and dimensions. [#25054](https://github.com/grafana/grafana/pull/25054), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Added AWS MediaStore metrics and dimensions. [#25492](https://github.com/grafana/grafana/pull/25492), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Added AWS RoboMaker metrics and dimensions. [#25090](https://github.com/grafana/grafana/pull/25090), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Added AWS SDKMetrics metrics and dimensions. [#25150](https://github.com/grafana/grafana/pull/25150), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Added AWS ServiceCatalog metrics and dimensions. [#25812](https://github.com/grafana/grafana/pull/25812), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Added AWS WAFV2 metrics. [#24048](https://github.com/grafana/grafana/pull/24048), [@mikkokupsu](https://github.com/mikkokupsu) +- **Dashboards**: Make path to default dashboard configurable. [#25595](https://github.com/grafana/grafana/pull/25595), [@bergquist](https://github.com/bergquist) +- **Elastic**: Internal data links. [#25942](https://github.com/grafana/grafana/pull/25942), [@aocenas](https://github.com/aocenas) +- **Elasticsearch**: Add support for template variable in date histogram min_doc_count. [#21064](https://github.com/grafana/grafana/pull/21064), [@faxm0dem](https://github.com/faxm0dem) +- **Elasticsearch**: Adds cumulative sum aggregation support. [#24820](https://github.com/grafana/grafana/pull/24820), [@retzkek](https://github.com/retzkek) +- **Elasticsearch**: Support using a variable for histogram and terms min doc count. [#25392](https://github.com/grafana/grafana/pull/25392), [@marefr](https://github.com/marefr) +- **Explore/Loki**: Show results of instant queries only in table and time series only in graph. [#25845](https://github.com/grafana/grafana/pull/25845), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Remove legend formatting when switching from panel to Explore. [#25848](https://github.com/grafana/grafana/pull/25848), [@ivanahuckova](https://github.com/ivanahuckova) +- **Footer**: Add back footer to login page. [#25656](https://github.com/grafana/grafana/pull/25656), [@torkelo](https://github.com/torkelo) +- **ForgottenPassword**: Move view to login screen. [#25366](https://github.com/grafana/grafana/pull/25366), [@tskarhed](https://github.com/tskarhed) +- **Gauge**: Hide orientation option in panel options. [#25511](https://github.com/grafana/grafana/pull/25511), [@torkelo](https://github.com/torkelo) +- **Grafana-UI**: Add FileUpload. [#25835](https://github.com/grafana/grafana/pull/25835), [@Clarity-89](https://github.com/Clarity-89) +- **GraphPanel**: Make legend values clickable series toggles. [#25581](https://github.com/grafana/grafana/pull/25581), [@hshoff](https://github.com/hshoff) +- **Influx**: Support flux in the influx datasource. [#25308](https://github.com/grafana/grafana/pull/25308), [@ryantxu](https://github.com/ryantxu) +- **Migration**: Select org. [#24739](https://github.com/grafana/grafana/pull/24739), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Settings forms. [#24741](https://github.com/grafana/grafana/pull/24741), [@tskarhed](https://github.com/tskarhed) +- **Panel Inspect**: use Monaco editor for json display. [#25251](https://github.com/grafana/grafana/pull/25251), [@ryantxu](https://github.com/ryantxu) +- **Panel edit**: Clicking twice on a visualization closes the VizPicker. [#25739](https://github.com/grafana/grafana/pull/25739), [@peterholmberg](https://github.com/peterholmberg) +- **PanelInspect**: Update UI for Data display options. [#25478](https://github.com/grafana/grafana/pull/25478), [@tskarhed](https://github.com/tskarhed) +- **Plugins**: move jaeger trace type to grafana data. [#25403](https://github.com/grafana/grafana/pull/25403), [@zoltanbedi](https://github.com/zoltanbedi) +- **Provisioning**: Adds support for enabling app plugins. [#25649](https://github.com/grafana/grafana/pull/25649), [@marefr](https://github.com/marefr) +- **Provisioning**: Use folders structure from the file system to create desired folders in dashboard provisioning. [#23117](https://github.com/grafana/grafana/pull/23117), [@nabokihms](https://github.com/nabokihms) +- **Query history**: Add keyboard shortcut support for commenting. [#24736](https://github.com/grafana/grafana/pull/24736), [@ivanahuckova](https://github.com/ivanahuckova) +- **Query history**: Add search for query history and starred queries. [#25747](https://github.com/grafana/grafana/pull/25747), [@ivanahuckova](https://github.com/ivanahuckova) +- **Rich history**: Updates for default settings and starred queries deletion. [#25732](https://github.com/grafana/grafana/pull/25732), [@ivanahuckova](https://github.com/ivanahuckova) +- **Search**: support URL query params. [#25541](https://github.com/grafana/grafana/pull/25541), [@Clarity-89](https://github.com/Clarity-89) +- **Stackdriver**: Deep linking from Grafana panels to the Metrics Explorer. [#25858](https://github.com/grafana/grafana/pull/25858), [@papagian](https://github.com/papagian) +- **Stackdriver**: Rename Stackdriver to Google Cloud Monitoring. [#25807](https://github.com/grafana/grafana/pull/25807), [@papagian](https://github.com/papagian) +- **StatPanel**: Option showing name instead of value and more. [#25676](https://github.com/grafana/grafana/pull/25676), [@torkelo](https://github.com/torkelo) +- **Switch**: Deprecate checked prop in favor of value. [#25862](https://github.com/grafana/grafana/pull/25862), [@tskarhed](https://github.com/tskarhed) +- **Tab**: Make active tab clickable and add hyperlink functionality. [#25546](https://github.com/grafana/grafana/pull/25546), [@tskarhed](https://github.com/tskarhed) +- **Table**: Adds adhoc filtering. [#25467](https://github.com/grafana/grafana/pull/25467), [@hugohaggmark](https://github.com/hugohaggmark) +- **Teams**: Add index for permission check. [#25736](https://github.com/grafana/grafana/pull/25736), [@sakjur](https://github.com/sakjur) +- **Template variable filters**: Hide overflowing text. [#25801](https://github.com/grafana/grafana/pull/25801), [@tskarhed](https://github.com/tskarhed) +- **Templating**: Add bult in \_\_user {name, id, login, email} variable to templating system. [#23378](https://github.com/grafana/grafana/pull/23378), [@aidanmountford](https://github.com/aidanmountford) +- **Templating**: removes old Angular variable system and featureToggle. [#24779](https://github.com/grafana/grafana/pull/24779), [@hugohaggmark](https://github.com/hugohaggmark) +- **TextPanel**: Adds proper editor for markdown and html. [#25618](https://github.com/grafana/grafana/pull/25618), [@hugohaggmark](https://github.com/hugohaggmark) +- **TextPanel**: Removes Angular Text Panel. [#25504](https://github.com/grafana/grafana/pull/25504), [@hugohaggmark](https://github.com/hugohaggmark) +- **TextPanel**: Removes text mode. [#25589](https://github.com/grafana/grafana/pull/25589), [@hugohaggmark](https://github.com/hugohaggmark) +- **TimeZone**: unify the time zone pickers to one that can rule them all. [#24803](https://github.com/grafana/grafana/pull/24803), [@mckn](https://github.com/mckn) +- **Transform**: added merge transform that will merge multiple series/tables into one table. [#25490](https://github.com/grafana/grafana/pull/25490), [@mckn](https://github.com/mckn) +- **Units**: add base-pascals and rotational speed units. [#22879](https://github.com/grafana/grafana/pull/22879), [@sakjur](https://github.com/sakjur) +- **Units**: add new unit for duration, it is optimized for displaying days, hours, minutes and seconds. [#24175](https://github.com/grafana/grafana/pull/24175), [@pabigot](https://github.com/pabigot) +- **Variables**: enables cancel for slow query variables queries. [#24430](https://github.com/grafana/grafana/pull/24430), [@hugohaggmark](https://github.com/hugohaggmark) +- **switches default value for security settings**. [#25175](https://github.com/grafana/grafana/pull/25175), [@bergquist](https://github.com/bergquist) +- **Reporting:** add monthly schedule option. (Enterprise) + +### Bug Fixes + +- **DatatLinks**: Fix open in new tab state mismatch. [#25826](https://github.com/grafana/grafana/pull/25826), [@tskarhed](https://github.com/tskarhed) +- **Explore/Loki**: Fix field type in table for instant queries. [#25907](https://github.com/grafana/grafana/pull/25907), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore/Loki**: Fix scrolling of context when leaving context window. [#25838](https://github.com/grafana/grafana/pull/25838), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore/SQL data sources**: Show correctly interpolated queries. [#25110](https://github.com/grafana/grafana/pull/25110), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore/Tooltip**: Fix label value in tooltip. [#25940](https://github.com/grafana/grafana/pull/25940), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Fix query editors on mobile. [#25148](https://github.com/grafana/grafana/pull/25148), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: adds an ability to exit log row context with ESC key. [#24205](https://github.com/grafana/grafana/pull/24205), [@Estrax](https://github.com/Estrax) +- **Fix**: Value mappings match against string values. [#25929](https://github.com/grafana/grafana/pull/25929), [@peterholmberg](https://github.com/peterholmberg) +- **GraphPanel**: Fix annotations overflowing panels. [#25606](https://github.com/grafana/grafana/pull/25606), [@hshoff](https://github.com/hshoff) +- **Instrumentation**: Fix setting Jaeger tracing address through Grafana config. [#25768](https://github.com/grafana/grafana/pull/25768), [@marefr](https://github.com/marefr) +- **Prometheus**: Fix performance issue in processing of histogram labels. [#25813](https://github.com/grafana/grafana/pull/25813), [@bsherrod](https://github.com/bsherrod) +- **Provisioning**: Makes file the default dashboard provisioner type. [#24856](https://github.com/grafana/grafana/pull/24856), [@bergquist](https://github.com/bergquist) +- **Templating**: fixes variables not being interpolated after dashboard refresh. [#25698](https://github.com/grafana/grafana/pull/25698), [@hugohaggmark](https://github.com/hugohaggmark) +- **Units**: Custom unit suffix and docs for custom units. [#25710](https://github.com/grafana/grafana/pull/25710), [@torkelo](https://github.com/torkelo) +- **ValueFormats**: Fix byte-format data rates. [#25424](https://github.com/grafana/grafana/pull/25424), [@mueslo](https://github.com/mueslo) +- **Variables**: Fixes maximum call stack bug for empty value. [#25503](https://github.com/grafana/grafana/pull/25503), [@hugohaggmark](https://github.com/hugohaggmark) + +### Security fixes + +- **Graph**: Fix XSS vulnerability with series overrides [#25401](https://github.com/grafana/grafana/pull/25401). Thanks to Rotem Reiss for reporting this. + +# 7.0.5 (2020-06-30) + +### Bug Fixes + +- **Datasource**: Make sure data proxy timeout applies to HTTP client. [#25865](https://github.com/grafana/grafana/pull/25865), [@marefr](https://github.com/marefr) +- **Graphite**: Fix tag value dropdowns not showing in query editor. [#25889](https://github.com/grafana/grafana/pull/25889), [@torkelo](https://github.com/torkelo) + +# 7.0.4 (2020-06-25) + +### Features / Enhancements + +- **Dashboard**: Redirects for old (pre 7.0) edit & view panel urls. [#25653](https://github.com/grafana/grafana/pull/25653), [@torkelo](https://github.com/torkelo) +- **Stackdriver**: Use default project name if project name isn't set on the query. [#25413](https://github.com/grafana/grafana/pull/25413), [@alexashley](https://github.com/alexashley) +- **TablePanel**: Sort numbers correctly. [#25421](https://github.com/grafana/grafana/pull/25421), [@speakyourcode](https://github.com/speakyourcode) +- **Update Bitcoin currency to use proper symbol, add mBTC and μBTC**. [#24182](https://github.com/grafana/grafana/pull/24182), [@overcookedpanda](https://github.com/overcookedpanda) +- **Variables**: Links that update variables on current dashboard does not trigger refresh / update. [#25192](https://github.com/grafana/grafana/pull/25192), [@torkelo](https://github.com/torkelo) + +### Bug Fixes + +- **Azure Monitor**: fixes undefined is not iterable. [#25586](https://github.com/grafana/grafana/pull/25586), [@hugohaggmark](https://github.com/hugohaggmark) +- **Datasources**: Handle URL parsing error. [#25742](https://github.com/grafana/grafana/pull/25742), [@marefr](https://github.com/marefr) +- **InfluxDB**: Fix invalid memory address or nil pointer dereference when schema is missing in URL. [#25565](https://github.com/grafana/grafana/pull/25565), [@marefr](https://github.com/marefr) +- **Security**: Use Header.Set and Header.Del for X-Grafana-User header. [#25495](https://github.com/grafana/grafana/pull/25495), [@beardhatcode](https://github.com/beardhatcode) +- **Stackdriver**: Fix creating Label Values datasource query variable. [#25633](https://github.com/grafana/grafana/pull/25633), [@papagian](https://github.com/papagian) +- **Table**: Support custom date formats via custom unit. [#25195](https://github.com/grafana/grafana/pull/25195), [@torkelo](https://github.com/torkelo) +- **Templating**: Fixes query variable with \${\_\_searchFilter} value selection not causing refresh & url update. [#25770](https://github.com/grafana/grafana/pull/25770), [@torkelo](https://github.com/torkelo) + +# 7.0.3 (2020-06-03) + +### Features / Enhancements + +- **Stats**: include all fields. [#24829](https://github.com/grafana/grafana/pull/24829), [@ryantxu](https://github.com/ryantxu) +- **Variables**: change VariableEditorList row action Icon to IconButton. [#25217](https://github.com/grafana/grafana/pull/25217), [@hshoff](https://github.com/hshoff) + +### Bug Fixes + +- **Cloudwatch**: Fix dimensions of DDoSProtection. [#25317](https://github.com/grafana/grafana/pull/25317), [@papagian](https://github.com/papagian) +- **Configuration**: Fix env var override of sections containing hyphen. [#25178](https://github.com/grafana/grafana/pull/25178), [@marefr](https://github.com/marefr) +- **Dashboard**: Get panels in collapsed rows. [#25079](https://github.com/grafana/grafana/pull/25079), [@peterholmberg](https://github.com/peterholmberg) +- **Do not show alerts tab when alerting is disabled**. [#25285](https://github.com/grafana/grafana/pull/25285), [@dprokop](https://github.com/dprokop) +- **Jaeger**: fixes cascader option label duration value. [#25129](https://github.com/grafana/grafana/pull/25129), [@Estrax](https://github.com/Estrax) +- **Transformations**: Fixed Transform tab crash & no update after adding first transform. [#25152](https://github.com/grafana/grafana/pull/25152), [@torkelo](https://github.com/torkelo) + +# 7.0.2 (2020-06-03) + +- **Security**: Urgent security patch release. Please read more in our [blog](https://grafana.com/blog/2020/06/03/grafana-6.7.4-and-7.0.2-released-with-important-security-fix/) + +# 7.0.1 (2020-05-26) + +### Features / Enhancements + +- **Datasource/CloudWatch**: Makes CloudWatch Logs query history more readable. [#24795](https://github.com/grafana/grafana/pull/24795), [@kaydelaney](https://github.com/kaydelaney) +- **Download CSV**: Add date and time formatting. [#24992](https://github.com/grafana/grafana/pull/24992), [@ryantxu](https://github.com/ryantxu) +- **Table**: Make last cell value visible when right aligned. [#24921](https://github.com/grafana/grafana/pull/24921), [@peterholmberg](https://github.com/peterholmberg) +- **TablePanel**: Adding sort order persistence. [#24705](https://github.com/grafana/grafana/pull/24705), [@torkelo](https://github.com/torkelo) +- **Transformations**: Display correct field name when using reduce transformation. [#25068](https://github.com/grafana/grafana/pull/25068), [@peterholmberg](https://github.com/peterholmberg) +- **Transformations**: Allow custom number input for binary operations. [#24752](https://github.com/grafana/grafana/pull/24752), [@ryantxu](https://github.com/ryantxu) + +### Bug Fixes + +- **Cloudwatch**: Fix AWS WAF and AWS DDoSProtection metrics. [#25071](https://github.com/grafana/grafana/pull/25071), [@papagian](https://github.com/papagian) +- **Dashboard/Links**: Fixes dashboard links by tags not working. [#24773](https://github.com/grafana/grafana/pull/24773), [@KamalGalrani](https://github.com/KamalGalrani) +- **Dashboard/Links**: Fixes open in new window for dashboard link. [#24772](https://github.com/grafana/grafana/pull/24772), [@KamalGalrani](https://github.com/KamalGalrani) +- **Dashboard/Links**: Variables are resolved and limits to 100. [#25076](https://github.com/grafana/grafana/pull/25076), [@hugohaggmark](https://github.com/hugohaggmark) +- **DataLinks**: Bring back variables interpolation in title. [#24970](https://github.com/grafana/grafana/pull/24970), [@dprokop](https://github.com/dprokop) +- **Datasource/CloudWatch**: Field suggestions no longer limited to prefix-only. [#24855](https://github.com/grafana/grafana/pull/24855), [@kaydelaney](https://github.com/kaydelaney) +- **Explore/Table**: Keep existing field types if possible. [#24944](https://github.com/grafana/grafana/pull/24944), [@kaydelaney](https://github.com/kaydelaney) +- **Explore**: Fix wrap lines toggle for results of queries with filter expression. [#24915](https://github.com/grafana/grafana/pull/24915), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: fix undo in query editor. [#24797](https://github.com/grafana/grafana/pull/24797), [@zoltanbedi](https://github.com/zoltanbedi) +- **Explore**: fix word break in type head info. [#25014](https://github.com/grafana/grafana/pull/25014), [@zoltanbedi](https://github.com/zoltanbedi) +- **Graph**: Legend decimals now work as expected. [#24931](https://github.com/grafana/grafana/pull/24931), [@torkelo](https://github.com/torkelo) +- **LoginPage**: Fix hover color for service buttons. [#25009](https://github.com/grafana/grafana/pull/25009), [@tskarhed](https://github.com/tskarhed) +- **LogsPanel**: Fix scrollbar. [#24850](https://github.com/grafana/grafana/pull/24850), [@ivanahuckova](https://github.com/ivanahuckova) +- **MoveDashboard**: Fix for moving dashboard caused all variables to be lost. [#25005](https://github.com/grafana/grafana/pull/25005), [@torkelo](https://github.com/torkelo) +- **Organize transformer**: Use display name in field order comparer. [#24984](https://github.com/grafana/grafana/pull/24984), [@dprokop](https://github.com/dprokop) +- **Panel**: shows correct panel menu items in view mode. [#24912](https://github.com/grafana/grafana/pull/24912), [@hugohaggmark](https://github.com/hugohaggmark) +- **PanelEditor Fix missing labels and description if there is only single option in category**. [#24905](https://github.com/grafana/grafana/pull/24905), [@dprokop](https://github.com/dprokop) +- **PanelEditor**: Overrides name matcher still show all original field names even after Field default display name is specified. [#24933](https://github.com/grafana/grafana/pull/24933), [@torkelo](https://github.com/torkelo) +- **PanelInspector**: Makes sure Data display options are visible. [#24902](https://github.com/grafana/grafana/pull/24902), [@hugohaggmark](https://github.com/hugohaggmark) +- **PanelInspector**: Hides unsupported data display options for Panel type. [#24918](https://github.com/grafana/grafana/pull/24918), [@hugohaggmark](https://github.com/hugohaggmark) +- **PanelMenu**: Make menu disappear on button press. [#25015](https://github.com/grafana/grafana/pull/25015), [@tskarhed](https://github.com/tskarhed) +- **Postgres**: Fix add button. [#25087](https://github.com/grafana/grafana/pull/25087), [@phemmer](https://github.com/phemmer) +- **Prometheus**: Fix recording rules expansion. [#24977](https://github.com/grafana/grafana/pull/24977), [@ivanahuckova](https://github.com/ivanahuckova) +- **Stackdriver**: Fix creating Service Level Objectives (SLO) datasource query variable. [#25023](https://github.com/grafana/grafana/pull/25023), [@papagian](https://github.com/papagian) + +# 7.0.0 (2020-05-18) + +## Breaking changes + +- **Removed PhantomJS**: PhantomJS was deprecated in [Grafana v6.4](https://grafana.com/docs/grafana/latest/guides/whats-new-in-v6-4/#phantomjs-deprecation) and starting from Grafana v7.0.0, all PhantomJS support has been removed. This means that Grafana no longer ships with a built-in image renderer, and we advise you to install the [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer). +- **Dashboard**: A global minimum dashboard refresh interval is now enforced and defaults to 5 seconds. +- **Interval calculation**: There is now a new option `Max data points` that controls the auto interval `$__interval` calculation. Interval was previously calculated by dividing the panel width by the time range. With the new max data points option it is now easy to set `$__interval` to a dynamic value that is time range agnostic. For example if you set `Max data points` to 10 Grafana will dynamically set `$__interval` by dividing the current time range by 10. +- **Datasource/Loki**: Support for [deprecated Loki endpoints](https://github.com/grafana/loki/blob/master/docs/api.md#lokis-http-api) has been removed. +- **Backend plugins**: Grafana now requires backend plugins to be signed, otherwise Grafana will not load/start them. This is an additional security measure to make sure backend plugin binaries and files haven't been tampered with. Refer to [Upgrade Grafana](https://grafana.com/docs/grafana/latest/installation/upgrading/#upgrading-to-v7-0) for more information. +- **Docker**: Our Ubuntu based images have been upgraded to Ubuntu [20.04 LTS](https://releases.ubuntu.com/20.04/). +- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md) +- **@grafana/ui**: Select API change for creating custom values, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md) + +**Deprecation warnings** + +- Scripted dashboards is now deprecated. The feature is not removed but will be in a future release. We hope to address the underlying requirement of dynamic dashboards in a different way. [#24059](https://github.com/grafana/grafana/issues/24059) +- The unofficial first version of backend plugins together with usage of [grafana/grafana-plugin-model](https://github.com/grafana/grafana-plugin-model) is now deprecated and support for that will be removed in a future release. Please refer to [backend plugins documentation](https://grafana.com/docs/grafana/latest/developers/plugins/backend/) for information about the new officially supported backend plugins. + +## 7.0 Feature highlights + +### Data transformations + +Not just visualizing data from anywhere, in Grafana 7 you can transform it too. By chaining a simple set of point and click transformations users will be able join, pivot, filter, re-name and calculate to get the results they need. Perfect for operations across queries or data sources missing essential data transformations. + +Data transformations will provide a common set of data operations that were previously duplicated as custom features in many panels or data sources but are now an integral part of the Grafana data processing pipeline and something all data sources and panels can take advantage of. + +In Grafana 7.0 we have a shared data model for both time series and table data that we call [DataFrame](https://github.com/grafana/grafana/blob/master/docs/sources/plugins/developing/dataframe.md). A DataFrame is like a table with columns but we refer to columns as fields. A time series is simply a DataFrame with two fields (time & value). + +**Transformations shipping in 7.0** + +- **Reduce**: Reduce many rows / data points to a single value +- **Filter by name**: Filter fields by name or regex +- **Filter by refId**: Filter by query letter +- **Organize fields**: Reorder, rename and hide fields. +- **Labels to fields**: Transform time series with labels into a table where labels get's converted to fields and the result is joined by time +- **Join by field**: Join many result sets (series) together using for example the time field. Useful for transforming time series into a table with a shared time column and where each series get it's own column. +- **Add field from calculation**: This is a powerful transformation that allows you perform many different types of math operations and add the result as a new field. Examples: + - Calculate the difference between two series or fields and add the result to a new field + - Multiply one field with another another and add the result to a new field + +### New panel edit experience + +In Grafana 7 we have redesigned the UI for editing panels. The first visible change is that we have separated panel display settings to a right hand side pane that you can collapse or expand depending on what your focus is on. With this change we are also introducing our new unified option model & UI for defining data configuration and display options. This unified data configuration system powers a consistent UI for setting data options across visualizations as well as making all data display settings data driven and overridable. + +This new option architecture and UI will make all panels have a consistent set of options and behaviors for attributes like `unit`, `min`, `max`, `thresholds`, `links`, `decimals`. Not only that but all these options will share a consistent UI for specifying override rules and is extensible for custom panel specific options. + +We have yet to migrate all core panels to this new architecture so in 7.0 there will sadly be some big inconsistencies in the UI between panels. Hopefully this will be fixed soon in future releases as we update all the core panels and help the community update the community panel plugins. + +### New table panel + +Grafana 7.0 comes with a new table panel (and deprecates the old one). This new table panel supports horizontal scrolling and column resize. Paired with the new `Organize fields` transformation detailed above you can reorder, hide & rename columns. This new panel also supports new cell display modes, like showing a bar gauge inside a cell. + +### Panel inspector + +The panel inspector is a feature that every panel will support, including internal as well as external community plugins. In this new panel inspector, you can view the raw data in a table format, apply some pre-defined transformations, and download as CSV. You can find the **Inspect** setting in the panel menu. Use the keyboard shortcut `i` when hovering over a panel to get the panel inspector to appear. + +### Improved time zone support + +Starting in version 7.0, you can override the time zone used to display date and time values in a dashboard. + +With this feature, you can specify the local time zone of the service or system that you are monitoring. This can be helpful when monitoring a system or service that operates across several time zones. + +We have also extended the time zone options so you can select any of the standard [ISO 8601 time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). + +### Features / Enhancements + +- **Azure Monitor**: Deep linking from Log Analytic queries to the Azure Portal. [#24417](https://github.com/grafana/grafana/pull/24417), [@daniellee](https://github.com/daniellee) +- **Backend plugins**: Log deprecation warning when using the unofficial first version of backend plugins. [#24675](https://github.com/grafana/grafana/pull/24675), [@marefr](https://github.com/marefr) +- **CloudWatch/Logs**: Add data links to CloudWatch logs for deep linking to AWS. [#24334](https://github.com/grafana/grafana/pull/24334), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch**: Unify look of query mode select between dashboard and explore. [#24648](https://github.com/grafana/grafana/pull/24648), [@aocenas](https://github.com/aocenas) +- **Docker**: Adds tzdata package to Ubuntu image. [#24422](https://github.com/grafana/grafana/pull/24422), [@xlson](https://github.com/xlson) +- **Editor**: New line on Enter, run query on Shift+Enter. [#24654](https://github.com/grafana/grafana/pull/24654), [@davkal](https://github.com/davkal) +- **Loki**: Allow multiple derived fields with the same name. [#24437](https://github.com/grafana/grafana/pull/24437), [@aocenas](https://github.com/aocenas) +- **Orgs**: Add future deprecation notice. [#24502](https://github.com/grafana/grafana/pull/24502), [@torkelo](https://github.com/torkelo) + +### Bug Fixes + +- **@grafana/toolkit**: Use process.cwd() instead of PWD to get directory. [#24677](https://github.com/grafana/grafana/pull/24677), [@zoltanbedi](https://github.com/zoltanbedi) +- **Admin**: Makes long settings values line break in settings page. [#24559](https://github.com/grafana/grafana/pull/24559), [@hugohaggmark](https://github.com/hugohaggmark) +- **Azure Monitor**: Fix failure when using table join in Log Analytics queries. [#24528](https://github.com/grafana/grafana/pull/24528), [@daniellee](https://github.com/daniellee) +- **CloudWatch/Logs**: Add error message when log groups are not selected. [#24361](https://github.com/grafana/grafana/pull/24361), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Allows a user to search for log groups that aren't there initially. [#24695](https://github.com/grafana/grafana/pull/24695), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch/Logs**: Correctly interpolate variables in logs queries. [#24619](https://github.com/grafana/grafana/pull/24619), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch/Logs**: Fix autocomplete after by keyword. [#24644](https://github.com/grafana/grafana/pull/24644), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Fix field autocomplete suggestions inside function. [#24406](https://github.com/grafana/grafana/pull/24406), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Fix fields not being refetched when log group changed. [#24529](https://github.com/grafana/grafana/pull/24529), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Fix panic on multiple aggregations queries. [#24683](https://github.com/grafana/grafana/pull/24683), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Fix query error when results were sparse. [#24702](https://github.com/grafana/grafana/pull/24702), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Fix suggestion for already inserted field. [#24581](https://github.com/grafana/grafana/pull/24581), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Fix suggestions of fields after comma. [#24520](https://github.com/grafana/grafana/pull/24520), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Fixes various autocomplete issues. [#24583](https://github.com/grafana/grafana/pull/24583), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch/Logs**: Handle errors that are not awserr.Error instances. [#24641](https://github.com/grafana/grafana/pull/24641), [@aknuds1](https://github.com/aknuds1) +- **CloudWatch/Logs**: Handle invalidation of log groups when switching data source. [#24703](https://github.com/grafana/grafana/pull/24703), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch/Logs**: Make stats hint show consistently. [#24392](https://github.com/grafana/grafana/pull/24392), [@aocenas](https://github.com/aocenas) +- **CloudWatch/Logs**: Prevents hidden data frame fields from displaying in tables. [#24580](https://github.com/grafana/grafana/pull/24580), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch/Logs**: Results of stats queries are now grouped. [#24396](https://github.com/grafana/grafana/pull/24396), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch/Logs**: Usability improvements. [#24447](https://github.com/grafana/grafana/pull/24447), [@kaydelaney](https://github.com/kaydelaney) +- **Dashboard**: Allow editing provisioned dashboard JSON and add confirmation when JSON is copied to dashboard. [#24680](https://github.com/grafana/grafana/pull/24680), [@dprokop](https://github.com/dprokop) +- **Dashboard**: Fix for strange "dashboard not found" errors when opening links in dashboard settings. [#24416](https://github.com/grafana/grafana/pull/24416), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Fix so default data source is selected when data source can't be found in panel editor. [#24526](https://github.com/grafana/grafana/pull/24526), [@mckn](https://github.com/mckn) +- **Dashboard**: Fixed issue changing a panel from transparent back to normal in panel editor. [#24483](https://github.com/grafana/grafana/pull/24483), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Make header names reflect the field name when exporting to CSV file from the panel inspector. [#24624](https://github.com/grafana/grafana/pull/24624), [@peterholmberg](https://github.com/peterholmberg) +- **Dashboard**: Make sure side pane is displayed with tabs by default in panel editor. [#24636](https://github.com/grafana/grafana/pull/24636), [@dprokop](https://github.com/dprokop) +- **Data source**: Fix query/annotation help content formatting. [#24687](https://github.com/grafana/grafana/pull/24687), [@AgnesToulet](https://github.com/AgnesToulet) +- **Data source**: Fixes async mount errors. [#24579](https://github.com/grafana/grafana/pull/24579), [@Estrax](https://github.com/Estrax) +- **Data source**: Fixes saving a data source without failure when URL doesn't specify a protocol. [#24497](https://github.com/grafana/grafana/pull/24497), [@aknuds1](https://github.com/aknuds1) +- **Explore/Prometheus**: Show results of instant queries only in table. [#24508](https://github.com/grafana/grafana/pull/24508), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Fix rendering of react query editors. [#24593](https://github.com/grafana/grafana/pull/24593), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Fixes loading more logs in logs context view. [#24135](https://github.com/grafana/grafana/pull/24135), [@Estrax](https://github.com/Estrax) +- **Graphite**: Fix schema and dedupe strategy in rollup indicators for Metrictank queries. [#24685](https://github.com/grafana/grafana/pull/24685), [@torkelo](https://github.com/torkelo) +- **Graphite**: Makes query annotations work again. [#24556](https://github.com/grafana/grafana/pull/24556), [@hugohaggmark](https://github.com/hugohaggmark) +- **Logs**: Clicking "Load more" from context overlay doesn't expand log row. [#24299](https://github.com/grafana/grafana/pull/24299), [@kaydelaney](https://github.com/kaydelaney) +- **Logs**: Fix total bytes process calculation. [#24691](https://github.com/grafana/grafana/pull/24691), [@davkal](https://github.com/davkal) +- **Org/user/team preferences**: Fixes so UI Theme can be set back to Default. [#24628](https://github.com/grafana/grafana/pull/24628), [@AgnesToulet](https://github.com/AgnesToulet) +- **Plugins**: Fix manifest validation. [#24573](https://github.com/grafana/grafana/pull/24573), [@aknuds1](https://github.com/aknuds1) +- **Provisioning**: Use proxy as default access mode in provisioning. [#24669](https://github.com/grafana/grafana/pull/24669), [@bergquist](https://github.com/bergquist) +- **Search**: Fix select item when pressing enter and Grafana is served using a sub path. [#24634](https://github.com/grafana/grafana/pull/24634), [@tskarhed](https://github.com/tskarhed) +- **Search**: Save folder expanded state. [#24496](https://github.com/grafana/grafana/pull/24496), [@Clarity-89](https://github.com/Clarity-89) +- **Security**: Tag value sanitization fix in OpenTSDB data source. [#24539](https://github.com/grafana/grafana/pull/24539), [@rotemreiss](https://github.com/rotemreiss) +- **Table**: Do not include angular options in options when switching from angular panel. [#24684](https://github.com/grafana/grafana/pull/24684), [@torkelo](https://github.com/torkelo) +- **Table**: Fixed persisting column resize for time series fields. [#24505](https://github.com/grafana/grafana/pull/24505), [@torkelo](https://github.com/torkelo) +- **Table**: Fixes Cannot read property subRows of null. [#24578](https://github.com/grafana/grafana/pull/24578), [@hugohaggmark](https://github.com/hugohaggmark) +- **Time picker**: Fixed so you can enter a relative range in the time picker without being converted to absolute range. [#24534](https://github.com/grafana/grafana/pull/24534), [@mckn](https://github.com/mckn) +- **Transformations**: Make transform dropdowns not cropped. [#24615](https://github.com/grafana/grafana/pull/24615), [@dprokop](https://github.com/dprokop) +- **Transformations**: Sort order should be preserved as entered by user when using the reduce transformation. [#24494](https://github.com/grafana/grafana/pull/24494), [@hugohaggmark](https://github.com/hugohaggmark) +- **Units**: Adds scale symbol for currencies with suffixed symbol. [#24678](https://github.com/grafana/grafana/pull/24678), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fixes filtering options with more than 1000 entries. [#24614](https://github.com/grafana/grafana/pull/24614), [@hugohaggmark](https://github.com/hugohaggmark) +- **Variables**: Fixes so Textbox variables read value from url. [#24623](https://github.com/grafana/grafana/pull/24623), [@hugohaggmark](https://github.com/hugohaggmark) +- **Zipkin**: Fix error when span contains remoteEndpoint. [#24524](https://github.com/grafana/grafana/pull/24524), [@aocenas](https://github.com/aocenas) +- **SAML**: Switch from email to login for user login attribute mapping (Enterprise) + +# 7.0.0-beta3 (2020-05-08) + +### Features / Enhancements + +- **Docker**: Upgrade to Alpine 3.11. [#24056](https://github.com/grafana/grafana/pull/24056), [@aknuds1](https://github.com/aknuds1) +- **Forms**: Remove Forms namespace [BREAKING]. Will cause all `Forms` imports to stop working. See migration guide in [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md)[#24378](https://github.com/grafana/grafana/pull/24378), [@tskarhed](https://github.com/tskarhed) + +### Bug Fixes + +- **CloudWatch**: Fix error with expression only query. [#24362](https://github.com/grafana/grafana/pull/24362), [@aocenas](https://github.com/aocenas) +- **Elasticsearch**: Fix building of raw document queries resulting in error Unknown BaseAggregationBuilder error. [#24403](https://github.com/grafana/grafana/pull/24403), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Fix for prometheus legend formats for instant time series queries. [#24407](https://github.com/grafana/grafana/pull/24407), [@torkelo](https://github.com/torkelo) + +# 7.0.0-beta2 (2020-05-07) + +## Breaking changes + +- **Removed PhantomJS**: PhantomJS was deprecated in [Grafana v6.4](https://grafana.com/docs/grafana/latest/guides/whats-new-in-v6-4/#phantomjs-deprecation) and starting from Grafana v7.0.0, all PhantomJS support has been removed. This means that Grafana no longer ships with a built-in image renderer, and we advise you to install the [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer). +- **Docker**: Our Ubuntu based images have been upgraded to Ubuntu [20.04 LTS](https://releases.ubuntu.com/20.04/). +- **Dashboard**: A global minimum dashboard refresh interval is now enforced and defaults to 5 seconds. +- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md) +- **Interval calculation**: There is now a new option `Max data points` that controls the auto interval `$__interval` calculation. Interval was previously calculated by dividing the panel width by the time range. With the new max data points option it is now easy to set `$__interval` to a dynamic value that is time range agnostic. For example if you set `Max data points` to 10 Grafana will dynamically set `$__interval` by dividing the current time range by 10. +- **Datasource/Loki**: Support for [deprecated Loki endpoints](https://github.com/grafana/loki/blob/master/docs/api.md#lokis-http-api) has been removed. + +**Deprecation warnings** + +- Scripted dashboards are now deprecated. The feature is not removed but will be in a future release. We hope to address the underlying requirement of dynamic dashboards in a different way. [#24059](https://github.com/grafana/grafana/issues/24059) + +### Features / Enhancements + +- **CloudWatch**: Adds more examples to CloudWatch Logs cheatsheet. [#24288](https://github.com/grafana/grafana/pull/24288), [@kaydelaney](https://github.com/kaydelaney) +- **Elasticsearch**: Changes terms min_doc_count default from 1 to 0. [#24204](https://github.com/grafana/grafana/pull/24204), [@Estrax](https://github.com/Estrax) +- **Login Page**: New design. [#23892](https://github.com/grafana/grafana/pull/23892), [@torkelo](https://github.com/torkelo) +- **Logs**: Add log level Fatal. [#24185](https://github.com/grafana/grafana/pull/24185), [@davkal](https://github.com/davkal) +- **Loki**: Show loki datasource stats in panel inspector. [#24190](https://github.com/grafana/grafana/pull/24190), [@davkal](https://github.com/davkal) +- **Migration**: Dashboard links. [#23553](https://github.com/grafana/grafana/pull/23553), [@peterholmberg](https://github.com/peterholmberg) +- **Plugins**: Require signing of external back-end plugins. [#24075](https://github.com/grafana/grafana/pull/24075), [@aknuds1](https://github.com/aknuds1) +- **Prometheus**: Add off switch for metric/label name lookup. [#24034](https://github.com/grafana/grafana/pull/24034), [@s-h-a-d-o-w](https://github.com/s-h-a-d-o-w) +- **Search**: Bring back open search by clicking dashboard name. [#24151](https://github.com/grafana/grafana/pull/24151), [@torkelo](https://github.com/torkelo) +- **Tracing**: Header updates. [#24153](https://github.com/grafana/grafana/pull/24153), [@aocenas](https://github.com/aocenas) +- **Transformations**: Improve time series support. [#23978](https://github.com/grafana/grafana/pull/23978), [@ryantxu](https://github.com/ryantxu) + +### Bug Fixes + +- **CloudWatch logs**: Fix default region interpolation and reset log groups on region change. [#24346](https://github.com/grafana/grafana/pull/24346), [@aocenas](https://github.com/aocenas) +- **Dashboard**: Fix for folder picker menu not being visible outside modal when saving dashboard. [#24296](https://github.com/grafana/grafana/pull/24296), [@tskarhed](https://github.com/tskarhed) +- **Dashboard**: Go to explore now works even after discarding dashboard changes. [#24149](https://github.com/grafana/grafana/pull/24149), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Only show cache timeout option in panel edit if enabled in data source plugin json. [#24095](https://github.com/grafana/grafana/pull/24095), [@peterholmberg](https://github.com/peterholmberg) +- **Dashboard**: Propagate unhandled errors when saving dashboard. [#24081](https://github.com/grafana/grafana/pull/24081), [@peterholmberg](https://github.com/peterholmberg) +- **Dashboard**: Variable without a current value in json model causes crash on load. [#24261](https://github.com/grafana/grafana/pull/24261), [@torkelo](https://github.com/torkelo) +- **DashboardManager**: Disable editing if there are no folder permissions. [#24237](https://github.com/grafana/grafana/pull/24237), [@tskarhed](https://github.com/tskarhed) +- **DataLinks**: Do not add empty links. [#24088](https://github.com/grafana/grafana/pull/24088), [@dprokop](https://github.com/dprokop) +- **Explore/Loki**: Removes old query syntax support for regex filter. [#24281](https://github.com/grafana/grafana/pull/24281), [@Estrax](https://github.com/Estrax) +- **Explore**: Fix showing of results of queries in table. [#24018](https://github.com/grafana/grafana/pull/24018), [@ivanahuckova](https://github.com/ivanahuckova) +- **Field options**: show field name when title option config is empty. [#24335](https://github.com/grafana/grafana/pull/24335), [@dprokop](https://github.com/dprokop) +- **Graph**: Fixed graph tooltip getting stuck / not being cleared when leaving dashboard. [#24162](https://github.com/grafana/grafana/pull/24162), [@torkelo](https://github.com/torkelo) +- **Graph**: Fixed issue with x-axis labels showing "MM/DD" after viewing dashboard with pie chart. [#24341](https://github.com/grafana/grafana/pull/24341), [@mckn](https://github.com/mckn) +- **Jaeger**: Fix how label is created in cascader. [#24164](https://github.com/grafana/grafana/pull/24164), [@aocenas](https://github.com/aocenas) +- **Loki**: Fix label matcher for log metrics queries. [#24238](https://github.com/grafana/grafana/pull/24238), [@ivanahuckova](https://github.com/ivanahuckova) +- **Panel inspect**: hides Query tab for plugins without Query ability. [#24216](https://github.com/grafana/grafana/pull/24216), [@hugohaggmark](https://github.com/hugohaggmark) +- **Prometheus**: Refresh query field metrics on data source change. [#24116](https://github.com/grafana/grafana/pull/24116), [@s-h-a-d-o-w](https://github.com/s-h-a-d-o-w) +- **Select**: Fixes so component loses focus on selecting value or pressing outside of input. [#24008](https://github.com/grafana/grafana/pull/24008), [@mckn](https://github.com/mckn) +- **Stat/Gauge/BarGauge**: Shows default cursor when missing links. [#24284](https://github.com/grafana/grafana/pull/24284), [@hugohaggmark](https://github.com/hugohaggmark) +- **Tracing**: Fix view bounds after trace change. [#23994](https://github.com/grafana/grafana/pull/23994), [@aocenas](https://github.com/aocenas) +- **Variables**: Migrates old tags format for consistency. [#24276](https://github.com/grafana/grafana/pull/24276), [@hugohaggmark](https://github.com/hugohaggmark) +- **Reporting**: Update report schedule as soon as a report is updated (Enterprise) +- **White-labeling**: Makes login title and subtitle configurable (Enterprise) + +# 7.0.0-beta1 (2020-04-28) + +## Breaking changes + +- **Removed PhantomJS**: PhantomJS was deprecated in [Grafana v6.4](https://grafana.com/docs/grafana/latest/guides/whats-new-in-v6-4/#phantomjs-deprecation) and starting from Grafana v7.0.0, all PhantomJS support has been removed. This means that Grafana no longer ships with a built-in image renderer, and we advise you to install the [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer). +- **Docker**: Our Ubuntu based images have been upgraded to Ubuntu [20.04 LTS](https://releases.ubuntu.com/20.04/). +- **Dashboard**: A global minimum dashboard refresh interval is now enforced and defaults to 5 seconds. +- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md) +- **@grafana/ui**: Select API change for creating custom values, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md) +- **Interval calculation**: There is now a new option `Max data points` that controls the auto interval `$__interval` calculation. Interval was previously calculated by dividing the panel width by the time range. With the new max data points option it is now easy to set `$__interval` to a dynamic value that is time range agnostic. For example if you set `Max data points` to 10 Grafana will dynamically set `$__interval` by dividing the current time range by 10. +- **Datasource/Loki**: Support for [deprecated Loki endpoints](https://github.com/grafana/loki/blob/master/docs/api.md#lokis-http-api) has been removed. + +### Features / Enhancements + +- **@grafana/ui**: Create Icon component and replace icons. [#23402](https://github.com/grafana/grafana/pull/23402), [@ivanahuckova](https://github.com/ivanahuckova) +- **@grafana/ui**: Create slider component. [#22275](https://github.com/grafana/grafana/pull/22275), [@ivanahuckova](https://github.com/ivanahuckova) +- **@grafana/ui**: Remove ColorPalette component. [#23592](https://github.com/grafana/grafana/pull/23592), [@ivanahuckova](https://github.com/ivanahuckova) +- **AWS IAM**: Support for AWS EKS ServiceAccount roles for CloudWatch and S3 image upload. [#21594](https://github.com/grafana/grafana/pull/21594), [@patstrom](https://github.com/patstrom) +- **Alerting**: Adds support for basic auth in Alertmanager notifier. [#23231](https://github.com/grafana/grafana/pull/23231), [@melchiormoulin](https://github.com/melchiormoulin) +- **Alerting**: Enable Alert rule tags to override PagerDuty Severity setting. [#22736](https://github.com/grafana/grafana/pull/22736), [@AndrewBurian](https://github.com/AndrewBurian) +- **Alerting**: Handle image renderer unavailable when edit notifiers. [#23711](https://github.com/grafana/grafana/pull/23711), [@marefr](https://github.com/marefr) +- **Alerting**: Upload error image when image renderer unavailable. [#23713](https://github.com/grafana/grafana/pull/23713), [@marefr](https://github.com/marefr) +- **Alerting**: support alerting on data.Frame (that can be time series). [#22812](https://github.com/grafana/grafana/pull/22812), [@kylebrandt](https://github.com/kylebrandt) +- **Azure Monitor**: Add alerting support - Port Azure log analytics to the backend. [#23839](https://github.com/grafana/grafana/pull/23839), [@daniellee](https://github.com/daniellee) +- **Backend plugins**: Support alerting in external data source plugins. [#6841](https://github.com/grafana/grafana/issues/6841) +- **Build**: Bundle plugins. [#23787](https://github.com/grafana/grafana/pull/23787), [@aknuds1](https://github.com/aknuds1) +- **Build**: Remove usage of Go vendoring. [#23796](https://github.com/grafana/grafana/pull/23796), [@kylebrandt](https://github.com/kylebrandt) +- **Build**: Upgrade to Go 1.14. [#23371](https://github.com/grafana/grafana/pull/23371), [@aknuds1](https://github.com/aknuds1) +- **CloudWatch**: Added AWS Chatbot metrics and dimensions. [#23516](https://github.com/grafana/grafana/pull/23516), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Added Cassandra namespace. [#23299](https://github.com/grafana/grafana/pull/23299), [@vikkyomkar](https://github.com/vikkyomkar) +- **CloudWatch**: Added missing Cassandra metrics. [#23467](https://github.com/grafana/grafana/pull/23467), [@ilyastoli](https://github.com/ilyastoli) +- **CloudWatch**: Adds support for Cloudwatch Logs. [#23566](https://github.com/grafana/grafana/pull/23566), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch**: Prefer webIdentity over EC2 role. [#23452](https://github.com/grafana/grafana/pull/23452), [@dnascimento](https://github.com/dnascimento) +- **CloudWatch**: Prefer webIdentity over EC2 role also when assuming a role. [#23807](https://github.com/grafana/grafana/pull/23807), [@bruecktech](https://github.com/bruecktech) +- **Components**: IconButton. [#23510](https://github.com/grafana/grafana/pull/23510), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Add failsafe for slug generation. [#23709](https://github.com/grafana/grafana/pull/23709), [@sakjur](https://github.com/sakjur) +- **Dashboard**: Enforce minimum dashboard refresh interval to 5 seconds per default. [#23929](https://github.com/grafana/grafana/pull/23929), [@marefr](https://github.com/marefr) +- **Dashboard**: Handle no renderer available in panel share dialog. [#23856](https://github.com/grafana/grafana/pull/23856), [@marefr](https://github.com/marefr) +- **Dashboard**: Support additional variable format options (singlequote, doublequote, sqlstring). [#21622](https://github.com/grafana/grafana/pull/21622), [@xiaobeiyang](https://github.com/xiaobeiyang) +- **Dashboard**: Support data links via field overrides. [#23590](https://github.com/grafana/grafana/pull/23590), [@dprokop](https://github.com/dprokop) +- **Data source**: Max data points now used in interval calculation for all data sources. [#23915](https://github.com/grafana/grafana/pull/23915), [@torkelo](https://github.com/torkelo) +- **Database**: Order results in UserSearch by username/email. [#23328](https://github.com/grafana/grafana/pull/23328), [@aknuds1](https://github.com/aknuds1) +- **Database**: Update the xorm dependency to v0.8.1. [#22376](https://github.com/grafana/grafana/pull/22376), [@novalagung](https://github.com/novalagung) +- **Docker**: Upgrade to Ubuntu 20.04 in Dockerfiles. [#23852](https://github.com/grafana/grafana/pull/23852), [@aknuds1](https://github.com/aknuds1) +- **Docs**: Adding API reference documentation support for the packages libraries. [#21931](https://github.com/grafana/grafana/pull/21931), [@mckn](https://github.com/mckn) +- **Tracing**: Add trace UI to show traces from tracing datasources and Jaeger datasource. [#23047](https://github.com/grafana/grafana/pull/23047), [@aocenas](https://github.com/aocenas) +- **Frontend**: Adding support to select preferred timezone for presentation of date and time values. [#23586](https://github.com/grafana/grafana/pull/23586), [@mckn](https://github.com/mckn) +- **Grafana Toolkit**: Adds template for backend data source. [#23864](https://github.com/grafana/grafana/pull/23864), [@bergquist](https://github.com/bergquist) +- **Graphite**: Rollup indicator and custom meta data inspector. [#22738](https://github.com/grafana/grafana/pull/22738), [@torkelo](https://github.com/torkelo) +- **HTTP API**: Allow assigning a specific organization when creating a new user. [#21775](https://github.com/grafana/grafana/pull/21775), [@Sytten](https://github.com/Sytten) +- **Image Rendering**: New setting to control render request concurrency. [#23950](https://github.com/grafana/grafana/pull/23950), [@marefr](https://github.com/marefr) +- **Image Rendering**: Remove PhantomJS support. [#23460](https://github.com/grafana/grafana/pull/23460), [@marefr](https://github.com/marefr) +- **Logs**: Derived fields link design. [#23695](https://github.com/grafana/grafana/pull/23695), [@aocenas](https://github.com/aocenas) +- **Metrics**: Add image rendering metrics. [#23827](https://github.com/grafana/grafana/pull/23827), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **Metrics**: Instrument backend plugin requests. [#23346](https://github.com/grafana/grafana/pull/23346), [@bergquist](https://github.com/bergquist) +- **Migration**: Add old Input to legacy namespace. [#23286](https://github.com/grafana/grafana/pull/23286), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Admin org edit page. [#23866](https://github.com/grafana/grafana/pull/23866), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Alerting - notifications list. [#22548](https://github.com/grafana/grafana/pull/22548), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Change password. [#23623](https://github.com/grafana/grafana/pull/23623), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Create org. [#22542](https://github.com/grafana/grafana/pull/22542), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Data/Panel link editor. [#23778](https://github.com/grafana/grafana/pull/23778), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Final components to LegacyForms. [#23707](https://github.com/grafana/grafana/pull/23707), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Layout Selector. [#23790](https://github.com/grafana/grafana/pull/23790), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Migrate admin/users. [#22759](https://github.com/grafana/grafana/pull/22759), [@mckn](https://github.com/mckn) +- **Migration**: Migrates ad hoc variable type to react/redux. [#22784](https://github.com/grafana/grafana/pull/22784), [@mckn](https://github.com/mckn) +- **Migration**: Move Switch from Forms namespace. [#23386](https://github.com/grafana/grafana/pull/23386), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Move last components from Forms namespace. [#23556](https://github.com/grafana/grafana/pull/23556), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Move old Switch to legacy namespace. [#23357](https://github.com/grafana/grafana/pull/23357), [@tskarhed](https://github.com/tskarhed) +- **Migration**: New datasource. [#23221](https://github.com/grafana/grafana/pull/23221), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Org users page. [#23372](https://github.com/grafana/grafana/pull/23372), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Orgs list. [#23821](https://github.com/grafana/grafana/pull/23821), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Remove Button from Forms namespace. [#23105](https://github.com/grafana/grafana/pull/23105), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Teams and alert list. [#23810](https://github.com/grafana/grafana/pull/23810), [@tskarhed](https://github.com/tskarhed) +- **Migration**: TextArea from Forms namespace. [#23436](https://github.com/grafana/grafana/pull/23436), [@tskarhed](https://github.com/tskarhed) +- **Migration**: User edit. [#23110](https://github.com/grafana/grafana/pull/23110), [@tskarhed](https://github.com/tskarhed) +- **OAuth**: Adds Okta provider. [#22972](https://github.com/grafana/grafana/pull/22972), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **OAuth**: Introduce new setting for configuring max age of OAuth state cookie. [#23195](https://github.com/grafana/grafana/pull/23195), [@rtrompier](https://github.com/rtrompier) +- **Plugins**: Add deprecation notice to setEditor method in PanelPlugin. [#23895](https://github.com/grafana/grafana/pull/23895), [@dprokop](https://github.com/dprokop) +- **Plugins**: Adds support for URL params in plugin routes. [#23503](https://github.com/grafana/grafana/pull/23503), [@daniellee](https://github.com/daniellee) +- **Plugins**: Fluent API for custom field config and panel options creation for PanelPlugin. [#23070](https://github.com/grafana/grafana/pull/23070), [@dprokop](https://github.com/dprokop) +- **Plugins**: Hide plugins page from viewers, and limit /api/plugins to only core plugins when called by viewer role. [#21901](https://github.com/grafana/grafana/pull/21901), [@dprokop](https://github.com/dprokop) +- **Postgres**: Add SSL support for datasource. [#21341](https://github.com/grafana/grafana/pull/21341), [@ryankurte](https://github.com/ryankurte) +- **Prometheus**: Render missing labels in legend formats as an empty string. [#22355](https://github.com/grafana/grafana/pull/22355), [@Hixon10](https://github.com/Hixon10) +- **Provisioning**: Allows specifying uid for datasource and use that in derived fields. [#23585](https://github.com/grafana/grafana/pull/23585), [@aocenas](https://github.com/aocenas) +- **Provisioning**: Validate that dashboard providers have unique names. [#22898](https://github.com/grafana/grafana/pull/22898), [@youshy](https://github.com/youshy) +- **Search**: Replace search implementation. [#23855](https://github.com/grafana/grafana/pull/23855), [@sakjur](https://github.com/sakjur) +- **Search**: migrate dashboard search to react. [#23274](https://github.com/grafana/grafana/pull/23274), [@Clarity-89](https://github.com/Clarity-89) +- **Server**: Don't include trailing slash in cookie path when hosting Grafana in a sub path. [#22265](https://github.com/grafana/grafana/pull/22265), [@consideRatio](https://github.com/consideRatio) +- **Stackdriver**: Support for SLO queries. [#22917](https://github.com/grafana/grafana/pull/22917), [@sunker](https://github.com/sunker) +- **Table**: Add support for organizing fields/columns. [#23135](https://github.com/grafana/grafana/pull/23135), [@mckn](https://github.com/mckn) +- **Table**: Improvements to column resizing, style and alignment. [#23663](https://github.com/grafana/grafana/pull/23663), [@torkelo](https://github.com/torkelo) +- **Table**: upgrades react-table to 7.0.0 and typings. [#23247](https://github.com/grafana/grafana/pull/23247), [@hugohaggmark](https://github.com/hugohaggmark) +- **Table**: Handle column overflow and horizontal scrolling in table panel. [#4157](https://github.com/grafana/grafana/issues/4157) +- **Tracing**: Dark theme styling for TraceView. [#23406](https://github.com/grafana/grafana/pull/23406), [@aocenas](https://github.com/aocenas) +- **Tracing**: Zipkin datasource. [#23829](https://github.com/grafana/grafana/pull/23829), [@aocenas](https://github.com/aocenas) +- **Transformations**: Adds labels as fields transformer. [#23703](https://github.com/grafana/grafana/pull/23703), [@hugohaggmark](https://github.com/hugohaggmark) +- **Transformations**: Improve UI and add some love to filter by name. [#23751](https://github.com/grafana/grafana/pull/23751), [@dprokop](https://github.com/dprokop) +- **Transformations**: calculate a new field based on the row values. [#23675](https://github.com/grafana/grafana/pull/23675), [@ryantxu](https://github.com/ryantxu) +- **Units**: add (IEC) and (Metric) to bits and bytes. [#23175](https://github.com/grafana/grafana/pull/23175), [@flopp999](https://github.com/flopp999) +- **Usagestats**: Add usage stats about what type of data source is used in alerting. [#23125](https://github.com/grafana/grafana/pull/23125), [@bergquist](https://github.com/bergquist) +- **delete old dashboard versions in multiple batches**. [#23348](https://github.com/grafana/grafana/pull/23348), [@DanCech](https://github.com/DanCech) +- **grafana/data**: PanelTypeChangedHandler API update to use PanelModel instead of panel options object [BREAKING]. [#22754](https://github.com/grafana/grafana/pull/22754), [@dprokop](https://github.com/dprokop) +- **grafana/ui**: Add basic horizontal and vertical layout components. [#22303](https://github.com/grafana/grafana/pull/22303), [@dprokop](https://github.com/dprokop) +- **Auth** SAML Role and Team Sync (Enterprise) +- **Presence Indicators**: Display the avatars of active users on dashboards (Enterprise) +- **Reporting**: Makes it possible to disable the scheduler (Enterprise) +- **Dashboard**: Dashboard usage view (Enterprise) +- **Reporting** Makes it possible to trigger report emails without scheduler (Enterprise) +- **Search**: Sorting based on dashboard views and errors (Enterprise) +- **Reporting**: Improved landscape mode and panel image quality (Enterprise) +- **Reporting**: Adds config setting for image_scale_factor of panel images (Enterprise) + +### Bug Fixes + +- **@grafana/ui**: Fix time range when only partial datetime is provided. [#23122](https://github.com/grafana/grafana/pull/23122), [@ivanahuckova](https://github.com/ivanahuckova) +- **Alerting**: Only include image in notifier when enabled. [#23194](https://github.com/grafana/grafana/pull/23194), [@marefr](https://github.com/marefr) +- **Alerting**: Basic auth should not be required in the Alertmanager notifier. [#23691](https://github.com/grafana/grafana/pull/23691), [@bergquist](https://github.com/bergquist) +- **Alerting**: Translate notification IDs to UIDs when extracting alert rules. [#19882](https://github.com/grafana/grafana/pull/19882), [@aSapien](https://github.com/aSapien) +- **Azure Monitor**: Fix for application insights Azure China plugin route. [#23877](https://github.com/grafana/grafana/pull/23877), [@daniellee](https://github.com/daniellee) +- **CloudWatch**: Add ServerlessDatabaseCapacity to AWS/RDS metrics. [#23635](https://github.com/grafana/grafana/pull/23635), [@jackstevenson](https://github.com/jackstevenson) +- **Dashboard**: Fix global variable "\_\_org.id". [#23362](https://github.com/grafana/grafana/pull/23362), [@vikkyomkar](https://github.com/vikkyomkar) +- **Dashboard**: Handle min refresh interval when importing dashboard. [#23959](https://github.com/grafana/grafana/pull/23959), [@marefr](https://github.com/marefr) +- **DataSourceProxy**: Handle URL parsing error. [#23731](https://github.com/grafana/grafana/pull/23731), [@aknuds1](https://github.com/aknuds1) +- **Frontend**: Fix sorting of organization popup in alphabetical order. [#22259](https://github.com/grafana/grafana/pull/22259), [@vikkyomkar](https://github.com/vikkyomkar) +- **Image Rendering**: Make it work using serve_from_sub_path configured. [#23706](https://github.com/grafana/grafana/pull/23706), [@marefr](https://github.com/marefr) +- **Image rendering**: Fix missing icon on plugins list. [#23958](https://github.com/grafana/grafana/pull/23958), [@marefr](https://github.com/marefr) +- **Logs**: Fix error when non-string log level supplied. [#23654](https://github.com/grafana/grafana/pull/23654), [@ivanahuckova](https://github.com/ivanahuckova) +- **Rich history**: Fix create url and run query for various datasources. [#23627](https://github.com/grafana/grafana/pull/23627), [@ivanahuckova](https://github.com/ivanahuckova) +- **Security**: Fix XSS vulnerability in table panel. [#23816](https://github.com/grafana/grafana/pull/23816), [@torkelo](https://github.com/torkelo) + + + +# 6.7.6 (2021-03-18) + +### Bug fixes + +- **Security**: Fix API permissions issues related to team-sync CVE-2021-28147. (Enterprise) +- **Security**: Usage insights requires signed in users CVE-2021-28148. (Enterprise) + + + + + +# 6.7.5 (2020-12-17) + +### Security + +- **SAML**: Fixes encoding/xml SAML vulnerability in Grafana Enterprise [#29875](https://github.com/grafana/grafana/issues/29875), [@bergquist](https://github.com/bergquist) + + + +# 6.7.4 (2020-06-03) + +- **Security**: Urgent security patch release. Please read more in our [blog](https://grafana.com/blog/2020/06/03/grafana-6.7.4-and-7.0.2-released-with-important-security-fix/) + +# 6.7.3 (2020-04-23) + +### Bug Fixes + +- **Admin**: Fix Synced via LDAP message for non-LDAP external users. [#23477](https://github.com/grafana/grafana/pull/23477), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **Alerting**: Fixes notifications for alerts with empty message in Google Hangouts notifier. [#23559](https://github.com/grafana/grafana/pull/23559), [@hugohaggmark](https://github.com/hugohaggmark) +- **AuthProxy**: Fixes bug where long username could not be cached.. [#22926](https://github.com/grafana/grafana/pull/22926), [@jcmcken](https://github.com/jcmcken) +- **Dashboard**: Fix saving dashboard when editing raw dashboard JSON model. [#23314](https://github.com/grafana/grafana/pull/23314), [@peterholmberg](https://github.com/peterholmberg) +- **Dashboard**: Try to parse 8 and 15 digit numbers as timestamps if parsing of time range as date fails. [#21694](https://github.com/grafana/grafana/pull/21694), [@jessetan](https://github.com/jessetan) +- **DashboardListPanel**: Fixed problem with empty panel after going into edit mode (General folder filter being automatically added) . [#23426](https://github.com/grafana/grafana/pull/23426), [@torkelo](https://github.com/torkelo) +- **Data source**: Handle datasource withCredentials option properly. [#23380](https://github.com/grafana/grafana/pull/23380), [@hvtuananh](https://github.com/hvtuananh) +- **Security**: Fix annotation popup XSS vulnerability [#23813](https://github.com/grafana/grafana/pull/23813), [@torkelo](https://github.com/torkelo). Big thanks to Juha Laaksonen for reporting this issue. +- **Security**: Fix XSS vulnerability in table panel [#23816](https://github.com/grafana/grafana/pull/23816), [@torkelo](https://github.com/torkelo). Big thanks to Rotem Reiss for reporting this issue. +- **Server**: Exit Grafana with status code 0 if no error. [#23312](https://github.com/grafana/grafana/pull/23312), [@aknuds1](https://github.com/aknuds1) +- **TablePanel**: Fix XSS issue in header column rename (backport). [#23814](https://github.com/grafana/grafana/pull/23814), [@torkelo](https://github.com/torkelo) +- **Variables**: Fixes error when setting adhoc variable values. [#23580](https://github.com/grafana/grafana/pull/23580), [@hugohaggmark](https://github.com/hugohaggmark) + +# 6.7.2 (2020-04-02) + +### Bug Fixes + +- **BackendSrv**: Adds config to response to fix issue for external plugins that used this property . [#23032](https://github.com/grafana/grafana/pull/23032), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Fixed issue with saving new dashboard after changing title . [#23104](https://github.com/grafana/grafana/pull/23104), [@dprokop](https://github.com/dprokop) +- **DataLinks**: make sure we use the correct datapoint when dataset contains null value.. [#22981](https://github.com/grafana/grafana/pull/22981), [@mckn](https://github.com/mckn) +- **Plugins**: Fixed issue for plugins that imported dateMath util . [#23069](https://github.com/grafana/grafana/pull/23069), [@mckn](https://github.com/mckn) +- **Security**: Fix for dashboard snapshot original dashboard link could contain XSS vulnerability in url. [#23254](https://github.com/grafana/grafana/pull/23254), [@torkelo](https://github.com/torkelo). Big thanks to Ahmed A. Sherif for reporting this issue. +- **Variables**: Fixes issue with too many queries being issued for nested template variables after value change. [#23220](https://github.com/grafana/grafana/pull/23220), [@torkelo](https://github.com/torkelo) +- **Plugins**: Expose promiseToDigest. [#23249](https://github.com/grafana/grafana/pull/23249), [@torkelo](https://github.com/torkelo) +- **Reporting**: Fixes issue updating a report created by someone else (Enterprise) + +# 6.7.1 (2020-03-20) + +### Bug Fixes + +- **Azure**: Fixed dropdowns not showing current value. [#22914](https://github.com/grafana/grafana/pull/22914), [@torkelo](https://github.com/torkelo) +- **BackendSrv**: only add content-type on POST, PUT requests. [#22910](https://github.com/grafana/grafana/pull/22910), [@hugohaggmark](https://github.com/hugohaggmark) +- **Panels**: Fixed size issue with panel internal size when exiting panel edit mode. [#22912](https://github.com/grafana/grafana/pull/22912), [@torkelo](https://github.com/torkelo) +- **Reporting**: fixes migrations compatibility with mysql (Enterprise) +- **Reporting**: Reduce default concurrency limit to 4 (Enterprise) + +# 6.7.0 (2020-03-19) + +### Features / Enhancements + +- **AzureMonitor**: support workspaces function for template variables. [#22882](https://github.com/grafana/grafana/pull/22882), [@daniellee](https://github.com/daniellee) +- **SQLStore**: Add migration for adding index on annotation.alert_id. [#22876](https://github.com/grafana/grafana/pull/22876), [@aknuds1](https://github.com/aknuds1) +- **TablePanel**: Enable new units picker . [#22833](https://github.com/grafana/grafana/pull/22833), [@dprokop](https://github.com/dprokop) + +### Bug Fixes + +- **AngularPanels**: Fixed inner height calculation for angular panels . [#22796](https://github.com/grafana/grafana/pull/22796), [@torkelo](https://github.com/torkelo) +- **BackendSrv**: makes sure provided headers are correctly recognized and set. [#22778](https://github.com/grafana/grafana/pull/22778), [@hugohaggmark](https://github.com/hugohaggmark) +- **Forms**: Fix input suffix position (caret-down in Select) . [#22780](https://github.com/grafana/grafana/pull/22780), [@torkelo](https://github.com/torkelo) +- **Graphite**: Fixed issue with query editor and next select metric now showing after selecting metric node . [#22856](https://github.com/grafana/grafana/pull/22856), [@torkelo](https://github.com/torkelo) +- **Rich History**: UX adjustments and fixes. [#22729](https://github.com/grafana/grafana/pull/22729), [@ivanahuckova](https://github.com/ivanahuckova) + +# 6.7.0-beta1 (2020-03-12) + +## Breaking changes + +- **Slack**: Removed _Mention_ setting and instead introduce _Mention Users_, _Mention Groups_, and _Mention Channel_. The first two settings require user and group IDs, respectively. This change was necessary because the way of mentioning via the Slack API [changed](https://api.slack.com/changelog/2017-09-the-one-about-usernames) and mentions in Slack notifications no longer worked. +- **Alerting**: Reverts the behavior of `diff` and `percent_diff` to not always be absolute. Something we introduced by mistake in [6.1.0](https://github.com/grafana/grafana/commit/28eaac3a9c7082e8c496005c1cb66b4b70a4f82f). Alerting now support `diff()`, `diff_abs()`, `percent_diff()` and `percent_diff_abs()`. [#21338](https://github.com/grafana/grafana/pull/21338) + +### Notice about changes in backendSrv for plugin authors + +In our mission to migrate away from AngularJS to React we have removed all AngularJS dependencies in the core data retrieval service `backendSrv`. + +Removing the AngularJS dependencies in `backendSrv` has the unfortunate side effect of AngularJS digest no longer being triggered for any request made with `backendSrv`. Because of this, external plugins using `backendSrv` directly may suffer from strange behaviour in the UI. + +To remedy this issue, as a plugin author you need to trigger the digest after a direct call to `backendSrv`. + +Example: + +```js +backendSrv.get(‘http://your.url/api’).then(result => { + this.result = result; + this.$scope.$digest(); +}); +``` + +Another unfortunate outcome from this work in `backendSrv` is that the response format for `.headers()` changed from a function to an object. + +To make your plugin work on 6.7.x as well as on previous versions you should add something like the following: + +```typescript +let responseHeaders = response.headers; +if (!responseHeaders) { + return null; +} + +// Support pre 6.7 angular HTTP rather than fetch +if (typeof responseHeaders === 'function') { + responseHeaders = responseHeaders(); +} +``` + +You can test your plugin with the `master` branch version of Grafana. + +### Features / Enhancements + +- **API**: Include IP address when logging request error. [#21596](https://github.com/grafana/grafana/pull/21596), [@thedeveloperr](https://github.com/thedeveloperr) +- **Alerting**: Support passing tags to Pagerduty and allow notification on specific event categories . [#21335](https://github.com/grafana/grafana/pull/21335), [@johntdyer](https://github.com/johntdyer) +- **Chore**: Remove angular dependency from backendSrv. [#20999](https://github.com/grafana/grafana/pull/20999), [@kaydelaney](https://github.com/kaydelaney) +- **CloudWatch**: Surround dimension names with double quotes. [#22222](https://github.com/grafana/grafana/pull/22222), [@jeet-parekh](https://github.com/jeet-parekh) +- **CloudWatch**: updated metrics and dimensions for Athena, DocDB, and Route53Resolver. [#22604](https://github.com/grafana/grafana/pull/22604), [@jeet-parekh](https://github.com/jeet-parekh) +- **Cloudwatch**: add Usage Metrics. [#22179](https://github.com/grafana/grafana/pull/22179), [@passing](https://github.com/passing) +- **Dashboard**: Adds support for a global minimum dashboard refresh interval. [#19416](https://github.com/grafana/grafana/pull/19416), [@lfroment0](https://github.com/lfroment0) +- **DatasourceEditor**: Add UI to edit custom HTTP headers. [#17846](https://github.com/grafana/grafana/pull/17846), [@adrien-f](https://github.com/adrien-f) +- **Elastic**: To get fields, start with today's index and go backwards. [#22318](https://github.com/grafana/grafana/pull/22318), [@ChadiEM](https://github.com/ChadiEM) +- **Explore**: Rich history. [#22570](https://github.com/grafana/grafana/pull/22570), [@ivanahuckova](https://github.com/ivanahuckova) +- **Graph**: canvas's Stroke is executed after loop. [#22610](https://github.com/grafana/grafana/pull/22610), [@merturl](https://github.com/merturl) +- **Graphite**: Don't issue empty "select metric" queries. [#22699](https://github.com/grafana/grafana/pull/22699), [@papagian](https://github.com/papagian) +- **Image Rendering**: Store render key in remote cache to enable renderer to callback to public/load balancer URL when running in HA mode. [#22031](https://github.com/grafana/grafana/pull/22031), [@marefr](https://github.com/marefr) +- **LDAP**: Add fallback to search_base_dns if group_search_base_dns is undefined.. [#21263](https://github.com/grafana/grafana/pull/21263), [@bb-Ricardo](https://github.com/bb-Ricardo) +- **OAuth**: Implement Azure AD provide. [#20030](https://github.com/grafana/grafana/pull/20030), [@twendt](https://github.com/twendt) +- **Prometheus**: Implement region annotation. [#22225](https://github.com/grafana/grafana/pull/22225), [@secustor](https://github.com/secustor) +- **Prometheus**: make \$\_\_range more precise. [#21722](https://github.com/grafana/grafana/pull/21722), [@bmerry](https://github.com/bmerry) +- **Prometheus**: Do not show rate hint when increase function is used in query. [#21955](https://github.com/grafana/grafana/pull/21955), [@fredwangwang](https://github.com/fredwangwang) +- **Stackdriver**: Project selector. [#22447](https://github.com/grafana/grafana/pull/22447), [@sunker](https://github.com/sunker) +- **TablePanel**: display multi-line text. [#20210](https://github.com/grafana/grafana/pull/20210), [@michael-az](https://github.com/michael-az) +- **Templating**: Add new global built-in variables. [#21790](https://github.com/grafana/grafana/pull/21790), [@dcastanier](https://github.com/dcastanier) +- **Reporting**: add concurrent render limit to settings (Enterprise) +- **Reporting**: Add rendering timeout in settings (Enterprise) + +### Bug Fixes + +- **API**: Fix redirect issues. [#22285](https://github.com/grafana/grafana/pull/22285), [@papagian](https://github.com/papagian) +- **Alerting**: Don't include image_url field with Slack message if empty. [#22372](https://github.com/grafana/grafana/pull/22372), [@aknuds1](https://github.com/aknuds1) +- **Alerting**: Fixed bad background color for default notifications in alert tab . [#22660](https://github.com/grafana/grafana/pull/22660), [@krvajal](https://github.com/krvajal) +- **Annotations**: In table panel when setting transform to annotation, they will now show up right away without a manual refresh. [#22323](https://github.com/grafana/grafana/pull/22323), [@krvajal](https://github.com/krvajal) +- **Azure Monitor**: Fix app insights source to allow for new **timeFrom and **timeTo. [#21879](https://github.com/grafana/grafana/pull/21879), [@ChadNedzlek](https://github.com/ChadNedzlek) +- **BackendSrv**: Fixes POST body for form data. [#21714](https://github.com/grafana/grafana/pull/21714), [@hugohaggmark](https://github.com/hugohaggmark) +- **CloudWatch**: Credentials cache invalidation fix. [#22473](https://github.com/grafana/grafana/pull/22473), [@sunker](https://github.com/sunker) +- **CloudWatch**: Expand alias variables when query yields no result. [#22695](https://github.com/grafana/grafana/pull/22695), [@sunker](https://github.com/sunker) +- **Dashboard**: Fix bug with NaN in alerting. [#22053](https://github.com/grafana/grafana/pull/22053), [@a-melnyk](https://github.com/a-melnyk) +- **Explore**: Fix display of multiline logs in log panel and explore. [#22057](https://github.com/grafana/grafana/pull/22057), [@thomasdraebing](https://github.com/thomasdraebing) +- **Heatmap**: Legend color range is incorrect when using custom min/max. [#21748](https://github.com/grafana/grafana/pull/21748), [@sv5d](https://github.com/sv5d) +- **Security**: Fixed XSS issue in dashboard history diff . [#22680](https://github.com/grafana/grafana/pull/22680), [@torkelo](https://github.com/torkelo) +- **StatPanel**: Fixes base color is being used for null values . + [#22646](https://github.com/grafana/grafana/pull/22646), [@torkelo](https://github.com/torkelo) + +# 6.6.2 (2020-02-20) + +### Features / Enhancements + +- **Data proxy**: Log proxy errors using Grafana logger. [#22174](https://github.com/grafana/grafana/pull/22174), [@bergquist](https://github.com/bergquist) +- **Metrics**: Add gauge for requests currently in flight. [#22168](https://github.com/grafana/grafana/pull/22168), [@bergquist](https://github.com/bergquist) + +### Bug Fixes + +- **@grafana/ui**: Fix displaying of bars in React Graph. [#21968](https://github.com/grafana/grafana/pull/21968), [@ivanahuckova](https://github.com/ivanahuckova) +- **API**: Fix redirect issue when configured to use a subpath. [#21652](https://github.com/grafana/grafana/pull/21652), [@briangann](https://github.com/briangann) +- **API**: Improve recovery middleware when response already been written. [#22256](https://github.com/grafana/grafana/pull/22256), [@marefr](https://github.com/marefr) +- **Auth**: Don't rotate auth token when requests are cancelled by client. [#22106](https://github.com/grafana/grafana/pull/22106), [@bergquist](https://github.com/bergquist) +- **Docker**: Downgrade to 18.04 LTS base image. [#22313](https://github.com/grafana/grafana/pull/22313), [@aknuds1](https://github.com/aknuds1) +- **Elasticsearch**: Fix auto interval for date histogram in explore logs mode. [#21937](https://github.com/grafana/grafana/pull/21937), [@ivanahuckova](https://github.com/ivanahuckova) +- **Image Rendering**: Fix PhantomJS compatibility with es2016 node dependencies. [#21677](https://github.com/grafana/grafana/pull/21677), [@dprokop](https://github.com/dprokop) +- **Links**: Assure base url when single stat, panel and data links are built. [#21956](https://github.com/grafana/grafana/pull/21956), [@dprokop](https://github.com/dprokop) +- **Loki, Prometheus**: Fix PromQL and LogQL syntax highlighting. [#21944](https://github.com/grafana/grafana/pull/21944), [@ivanahuckova](https://github.com/ivanahuckova) +- **OAuth**: Enforce auto_assign_org_id setting when role mapping enabled using Generic OAuth. [#22268](https://github.com/grafana/grafana/pull/22268), [@aknuds1](https://github.com/aknuds1) +- **Prometheus**: Updates explore query editor to prevent it from throwing error on edit. [#21605](https://github.com/grafana/grafana/pull/21605), [@Estrax](https://github.com/Estrax) +- **Server**: Reorder cipher suites for better security. [#22101](https://github.com/grafana/grafana/pull/22101), [@tofu-rocketry](https://github.com/tofu-rocketry) +- **TimePicker**: fixing weird behavior with calendar when switching between months/years . [#22253](https://github.com/grafana/grafana/pull/22253), [@mckn](https://github.com/mckn) + +# 6.6.1 (2020-02-06) + +### Bug Fixes + +- **Annotations**: Change indices and rewrites annotation find query to improve database query performance. [#21915](https://github.com/grafana/grafana/pull/21915), [@papagian](https://github.com/papagian), [@marefr](https://github.com/marefr), [@kylebrandt](https://github.com/kylebrandt) +- **Azure Monitor**: Fix Application Insights API key field to allow input. [#21738](https://github.com/grafana/grafana/pull/21738), [@shavonn](https://github.com/shavonn) +- **BarGauge**: Fix so we properly display the "no result" value when query returns empty result. [#21791](https://github.com/grafana/grafana/pull/21791), [@mckn](https://github.com/mckn) +- **Datasource**: Show access (Browser/Server) select on the Prometheus datasource. [#21833](https://github.com/grafana/grafana/pull/21833), [@jorgelbg](https://github.com/jorgelbg) +- **DatasourceSettings**: Fixed issue navigating away from data source settings page. [#21841](https://github.com/grafana/grafana/pull/21841), [@torkelo](https://github.com/torkelo) +- **Graph Panel**: Fix typo in thresholds form. [#21903](https://github.com/grafana/grafana/pull/21903), [@orendain](https://github.com/orendain) +- **Graphite**: Fixed issue with functions with multiple required params and no defaults caused params that could not be edited (groupByNodes groupByTags). [#21814](https://github.com/grafana/grafana/pull/21814), [@torkelo](https://github.com/torkelo) +- **Image Rendering**: Fix render of graph panel legend aligned to the right using Grafana image renderer plugin/service. [#21854](https://github.com/grafana/grafana/pull/21854), [@marefr](https://github.com/marefr) +- **Metrics**: Adds back missing summary quantiles. [#21858](https://github.com/grafana/grafana/pull/21858), [@kogent](https://github.com/kogent) +- **OpenTSDB**: Adds back missing ngInject to make it work again. [#21796](https://github.com/grafana/grafana/pull/21796), [@marefr](https://github.com/marefr) +- **Plugins**: Fix routing in app plugin pages. [#21847](https://github.com/grafana/grafana/pull/21847), [@dprokop](https://github.com/dprokop) +- **Prometheus**: Fixes default step value for annotation query. [#21934](https://github.com/grafana/grafana/pull/21934), [@hugohaggmark](https://github.com/hugohaggmark) +- **Quota**: Makes LDAP + Quota work for the first login of a new user. [#21949](https://github.com/grafana/grafana/pull/21949), [@xlson](https://github.com/xlson) +- **StatPanels**: Fixed change from singlestat to Gauge / BarGauge / Stat where default min & max (0, 100) was copied . [#21820](https://github.com/grafana/grafana/pull/21820), [@torkelo](https://github.com/torkelo) +- **TimePicker**: Should display in kiosk mode. [#21816](https://github.com/grafana/grafana/pull/21816), [@evgbibko](https://github.com/evgbibko) +- **grafana/toolkit**: Fix failing linter when there were lint issues. [#21849](https://github.com/grafana/grafana/pull/21849), [@dprokop](https://github.com/dprokop) + +# 6.6.0 (2020-01-27) + +### Features / Enhancements + +- **CloudWatch**: Add DynamoDB Accelerator (DAX) metrics & dimensions. [#21644](https://github.com/grafana/grafana/pull/21644), [@kenju](https://github.com/kenju) +- **CloudWatch**: Auto period snap to next higher period. [#21659](https://github.com/grafana/grafana/pull/21659), [@sunker](https://github.com/sunker) +- **Template variables**: Add error for failed query variable on time range update. [#21731](https://github.com/grafana/grafana/pull/21731), [@tskarhed](https://github.com/tskarhed) +- **XSS**: Sanitize column link. [#21735](https://github.com/grafana/grafana/pull/21735), [@tskarhed](https://github.com/tskarhed) + +### Bug Fixes + +- **Elasticsearch**: Fix adhoc variable filtering for logs query. [#21346](https://github.com/grafana/grafana/pull/21346), [@ceh](https://github.com/ceh) +- **Explore**: Fix colors for log level when level value is capitalised. [#21646](https://github.com/grafana/grafana/pull/21646), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Fix context view in logs, where some rows may have been filtered out.. [#21729](https://github.com/grafana/grafana/pull/21729), [@aocenas](https://github.com/aocenas) +- **Loki**: Fix Loki with repeated panels and interpolation for Explore. [#21685](https://github.com/grafana/grafana/pull/21685), [@ivanahuckova](https://github.com/ivanahuckova) +- **SQLStore**: Fix PostgreSQL failure to create organisation for first time. [#21648](https://github.com/grafana/grafana/pull/21648), [@papagian](https://github.com/papagian) + +# 6.6.0-beta1 (2020-01-20) + +## Breaking changes + +- **PagerDuty**: Change `payload.custom_details` field in PagerDuty notification to be a JSON object instead of a string. +- **Security**: The `[security]` setting `cookie_samesite` configured to `none` now renders cookies with `SameSite=None` attribute compared to before where no `SameSite` attribute was added to cookies. To get the old behavior, use value `disabled` instead of `none`. Refer to [Upgrade Grafana](https://grafana.com/docs/grafana/latest/installation/upgrading/#upgrading-to-v6-6) for more information. + +### Features / Enhancements + +- **Graphite**: Add Metrictank dashboard to Graphite datasource +- **Admin**: Show name of user in users table view. [#18108](https://github.com/grafana/grafana/pull/18108), [@eleijonmarck](https://github.com/eleijonmarck) +- **Alerting**: Add configurable severity support for PagerDuty notifier. [#19425](https://github.com/grafana/grafana/pull/19425), [@yemble](https://github.com/yemble) +- **Alerting**: Add more information to webhook notifications. [#20420](https://github.com/grafana/grafana/pull/20420), [@michael-az](https://github.com/michael-az) +- **Alerting**: Add support for sending tags in OpsGenie notifier. [#20810](https://github.com/grafana/grafana/pull/20810), [@aSapien](https://github.com/aSapien) +- **Alerting**: Added fallbackText to Google Chat notifier. [#21464](https://github.com/grafana/grafana/pull/21464), [@alvarolmedo](https://github.com/alvarolmedo) +- **Alerting**: Adds support for sending a single email to all recipients in email notifier. [#21091](https://github.com/grafana/grafana/pull/21091), [@marefr](https://github.com/marefr) +- **Alerting**: Enable setting of OpsGenie priority via a tag. [#21298](https://github.com/grafana/grafana/pull/21298), [@zabullet](https://github.com/zabullet) +- **Alerting**: Use fully qualified status emoji in Threema notifier. [#21305](https://github.com/grafana/grafana/pull/21305), [@dbrgn](https://github.com/dbrgn) +- **Alerting**: new min_interval_seconds option to enforce a minimum evaluation frequency . [#21188](https://github.com/grafana/grafana/pull/21188), [@papagian](https://github.com/papagian) +- **CloudWatch**: Calculate period based on time range. [#21471](https://github.com/grafana/grafana/pull/21471), [@sunker](https://github.com/sunker) +- **CloudWatch**: Display partial result in graph when max DP/call limit is reached . [#21533](https://github.com/grafana/grafana/pull/21533), [@sunker](https://github.com/sunker) +- **CloudWatch**: ECS/ContainerInsights metrics support. [#21125](https://github.com/grafana/grafana/pull/21125), [@briancurt](https://github.com/briancurt) +- **CloudWatch**: Upgrade aws-sdk-go. [#20510](https://github.com/grafana/grafana/pull/20510), [@mtanda](https://github.com/mtanda) +- **DataLinks**: allow using values from other fields in the same row (cells). [#21478](https://github.com/grafana/grafana/pull/21478), [@ryantxu](https://github.com/ryantxu) +- **Editor**: Ignore closing brace when it was added by editor. [#21172](https://github.com/grafana/grafana/pull/21172), [@davkal](https://github.com/davkal) +- **Explore**: Context tooltip to copy labels and values from graph. [#21405](https://github.com/grafana/grafana/pull/21405), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Log message line wrapping options for logs. [#20360](https://github.com/grafana/grafana/pull/20360), [@ivanahuckova](https://github.com/ivanahuckova) +- **Forms**: introduce RadioButtonGroup. [#20828](https://github.com/grafana/grafana/pull/20828), [@dprokop](https://github.com/dprokop) +- **Frontend**: Changes in Redux location should not strip subpath from location url. [#20161](https://github.com/grafana/grafana/pull/20161), [@wybczu](https://github.com/wybczu) +- **Graph**: Add fill gradient option to series override line fill. [#20941](https://github.com/grafana/grafana/pull/20941), [@hendrikvh](https://github.com/hendrikvh) +- **Graphite**: Add metrictank dashboard to Graphite datasource. [#20776](https://github.com/grafana/grafana/pull/20776), [@Dieterbe](https://github.com/Dieterbe) +- **Graphite**: Do not change query when opening the query editor and there is no data. [#21588](https://github.com/grafana/grafana/pull/21588), [@daniellee](https://github.com/daniellee) +- **Gravatar**: Use HTTPS by default. [#20964](https://github.com/grafana/grafana/pull/20964), [@jiajunhuang](https://github.com/jiajunhuang) +- **Loki**: Support for template variable queries. [#20697](https://github.com/grafana/grafana/pull/20697), [@ivanahuckova](https://github.com/ivanahuckova) +- **NewsPanel**: Add news as a builtin panel. [#21128](https://github.com/grafana/grafana/pull/21128), [@ryantxu](https://github.com/ryantxu) +- **OAuth**: Removes send_client_credentials_via_post setting . [#20044](https://github.com/grafana/grafana/pull/20044), [@LK4D4](https://github.com/LK4D4) +- **OpenTSDB**: Adding lookup limit to OpenTSDB datasource settings. [#20647](https://github.com/grafana/grafana/pull/20647), [@itamarst](https://github.com/itamarst) +- **Postgres/MySQL/MSSQL**: Adds support for region annotations. [#20752](https://github.com/grafana/grafana/pull/20752), [@Bercon](https://github.com/Bercon) +- **Prometheus**: Field to specify step in Explore. [#20195](https://github.com/grafana/grafana/pull/20195), [@Estrax](https://github.com/Estrax) +- **Prometheus**: User metrics metadata to inform query hints. [#21304](https://github.com/grafana/grafana/pull/21304), [@davkal](https://github.com/davkal) +- **Renderer**: Add user-agent to remote rendering service requests. [#20956](https://github.com/grafana/grafana/pull/20956), [@kfdm](https://github.com/kfdm) +- **Security**: Add disabled option for cookie samesite attribute. [#21472](https://github.com/grafana/grafana/pull/21472), [@marefr](https://github.com/marefr) +- **Stackdriver**: Support meta labels. [#21373](https://github.com/grafana/grafana/pull/21373), [@sunker](https://github.com/sunker) +- **TablePanel, GraphPanel**: Exclude hidden columns from CSV. [#19925](https://github.com/grafana/grafana/pull/19925), [@literalplus](https://github.com/literalplus) +- **Templating**: Update variables on location changed. [#21480](https://github.com/grafana/grafana/pull/21480), [@ryantxu](https://github.com/ryantxu) +- **Tracing**: Support configuring Jaeger client from environment. [#21103](https://github.com/grafana/grafana/pull/21103), [@hairyhenderson](https://github.com/hairyhenderson) +- **Units**: Add currency and energy units. [#20428](https://github.com/grafana/grafana/pull/20428), [@anirudh-ramesh](https://github.com/anirudh-ramesh) +- **Units**: Support dynamic count and currency units. [#21279](https://github.com/grafana/grafana/pull/21279), [@ryantxu](https://github.com/ryantxu) +- **grafana/toolkit**: Add option to override webpack config. [#20872](https://github.com/grafana/grafana/pull/20872), [@sebimarkgraf](https://github.com/sebimarkgraf) +- **grafana/ui**: ConfirmModal component. [#20965](https://github.com/grafana/grafana/pull/20965), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **grafana/ui**: Create Tabs component. [#21328](https://github.com/grafana/grafana/pull/21328), [@peterholmberg](https://github.com/peterholmberg) +- **grafana/ui**: New table component. [#20991](https://github.com/grafana/grafana/pull/20991), [@peterholmberg](https://github.com/peterholmberg) +- **grafana/ui**: New updated time picker. [#20931](https://github.com/grafana/grafana/pull/20931), [@mckn](https://github.com/mckn) +- **White-labeling**: Makes it possible to customize the footer and login background (Enterprise) + +### Bug Fixes + +- **API**: Optionally list expired API keys. [#20468](https://github.com/grafana/grafana/pull/20468), [@papagian](https://github.com/papagian) +- **Alerting**: Fix custom_details to be a JSON object instead of a string in PagerDuty notifier. [#21150](https://github.com/grafana/grafana/pull/21150), [@tehGoti](https://github.com/tehGoti) +- **Alerting**: Fix image rendering and uploading timeout preventing to send alert notifications. [#21536](https://github.com/grafana/grafana/pull/21536), [@marefr](https://github.com/marefr) +- **Alerting**: Fix panic in dingding notifier . [#20378](https://github.com/grafana/grafana/pull/20378), [@csyangchen](https://github.com/csyangchen) +- **Alerting**: Fix template query validation logic. [#20721](https://github.com/grafana/grafana/pull/20721), [@okhowang](https://github.com/okhowang) +- **Alerting**: If no permission to clear history, keep the historical data. [#19007](https://github.com/grafana/grafana/pull/19007), [@lzdw](https://github.com/lzdw) +- **Alerting**: Unpausing a non-paused alert rule should not change status to Unknown. [#21375](https://github.com/grafana/grafana/pull/21375), [@vikkyomkar](https://github.com/vikkyomkar) +- **Api**: Fix returned message when enabling, disabling and deleting a non-existing user. [#21391](https://github.com/grafana/grafana/pull/21391), [@dpavlos](https://github.com/dpavlos) +- **Auth**: Rotate auth tokens at the end of requests. [#21347](https://github.com/grafana/grafana/pull/21347), [@woodsaj](https://github.com/woodsaj) +- **Azure Monitor**: Fixes error using azure monitor credentials with log analytics and non-default cloud. [#21032](https://github.com/grafana/grafana/pull/21032), [@shavonn](https://github.com/shavonn) +- **CLI**: Return error and aborts when plugin file extraction fails. [#20849](https://github.com/grafana/grafana/pull/20849), [@marefr](https://github.com/marefr) +- **CloudWatch**: Multi-valued template variable dimension alias fix. [#21541](https://github.com/grafana/grafana/pull/21541), [@sunker](https://github.com/sunker) +- **Dashboard**: Disable draggable panels on small devices. [#20629](https://github.com/grafana/grafana/pull/20629), [@peterholmberg](https://github.com/peterholmberg) +- **DataLinks**: Links with \${\_\_value.time} do not work when clicking on first result . [#20019](https://github.com/grafana/grafana/pull/20019), [@dweineha](https://github.com/dweineha) +- **Explore**: Fix showing of results in selected timezone (UTC/local). [#20812](https://github.com/grafana/grafana/pull/20812), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Fix timepicker when browsing back after switching datasource. [#21454](https://github.com/grafana/grafana/pull/21454), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Sync timepicker and logs after live-tailing stops. [#20979](https://github.com/grafana/grafana/pull/20979), [@ivanahuckova](https://github.com/ivanahuckova) +- **Graph**: Fix when clicking a plot on a touch device we won't display the annotation menu. [#21479](https://github.com/grafana/grafana/pull/21479), [@mckn](https://github.com/mckn) +- **OAuth**: Fix role mapping from id token. [#20300](https://github.com/grafana/grafana/pull/20300), [@seanson](https://github.com/seanson) +- **Plugins**: Add appSubUrl string to config pages. [#21414](https://github.com/grafana/grafana/pull/21414), [@Maddin-619](https://github.com/Maddin-619) +- **Provisioning**: Start provision dashboards after Grafana server have started. [#21564](https://github.com/grafana/grafana/pull/21564), [@marefr](https://github.com/marefr) +- **Render**: Use https as protocol when rendering if HTTP2 enabled. [#21600](https://github.com/grafana/grafana/pull/21600), [@marefr](https://github.com/marefr) +- **Security**: Use same cookie settings for all cookies. [#19787](https://github.com/grafana/grafana/pull/19787), [@jeffdesc](https://github.com/jeffdesc) +- **Singlestat**: Support empty value map texts. [#20952](https://github.com/grafana/grafana/pull/20952), [@hendrikvh](https://github.com/hendrikvh) +- **Units**: Custom suffix and prefix units can now be specified, for example custom currency & SI & time formats. [#20763](https://github.com/grafana/grafana/pull/20763), [@ryantxu](https://github.com/ryantxu) +- **grafana/ui**: Do not build grafana/ui in strict mode as it depends on non-strict libs. [#21319](https://github.com/grafana/grafana/pull/21319), [@dprokop](https://github.com/dprokop) + +# 6.5.3 (2020-01-15) + +### Features / Enhancements + +- **API**: Validate redirect_to cookie has valid (Grafana) url . [#21057](https://github.com/grafana/grafana/pull/21057), [@papagian](https://github.com/papagian), Thanks Habi S Ravi for reporting this issue. + +### Bug Fixes + +- **AdHocFilter**: Shows SubMenu when filtering directly from table. [#21017](https://github.com/grafana/grafana/pull/21017), [@hugohaggmark](https://github.com/hugohaggmark) +- **Cloudwatch**: Fixed crash when switching from cloudwatch data source. [#21376](https://github.com/grafana/grafana/pull/21376), [@torkelo](https://github.com/torkelo) +- **DataLinks**: Sanitize data/panel link URLs. [#21140](https://github.com/grafana/grafana/pull/21140), [@dprokop](https://github.com/dprokop) +- **Elastic**: Fix multiselect variable interpolation for logs. [#20894](https://github.com/grafana/grafana/pull/20894), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus**: Fixes so user can change HTTP Method in config settings. [#21055](https://github.com/grafana/grafana/pull/21055), [@hugohaggmark](https://github.com/hugohaggmark) +- **Prometheus**: Prevents validation of inputs when clicking in them without changing the value. [#21059](https://github.com/grafana/grafana/pull/21059), [@hugohaggmark](https://github.com/hugohaggmark) +- **Rendering**: Fix panel PNG rendering when using sub url & serve_from_sub_path = true. [#21306](https://github.com/grafana/grafana/pull/21306), [@bgranvea](https://github.com/bgranvea) +- **Table**: Matches column names with unescaped regex characters. [#21164](https://github.com/grafana/grafana/pull/21164), [@hugohaggmark](https://github.com/hugohaggmark) + +# 6.5.2 (2019-12-11) + +### Bug Fixes + +- **Alerting**: Improve alert threshold handle dragging behavior. [#20922](https://github.com/grafana/grafana/pull/20922), [@torkelo](https://github.com/torkelo) +- **AngularPanels**: Fixed loading spinner being stuck in some rare cases. [#20878](https://github.com/grafana/grafana/pull/20878), [@torkelo](https://github.com/torkelo) +- **CloudWatch**: Fix query editor does not render in Explore. [#20909](https://github.com/grafana/grafana/pull/20909), [@davkal](https://github.com/davkal) +- **CloudWatch**: Remove illegal character escaping in inferred expressions. [#20915](https://github.com/grafana/grafana/pull/20915), [@sunker](https://github.com/sunker) +- **CloudWatch**: Remove template variable error message. [#20864](https://github.com/grafana/grafana/pull/20864), [@sunker](https://github.com/sunker) +- **CloudWatch**: Use datasource template variable in curated dashboards. [#20917](https://github.com/grafana/grafana/pull/20917), [@sunker](https://github.com/sunker) +- **Elasticsearch**: Set default port to 9200 in ConfigEditor. [#20948](https://github.com/grafana/grafana/pull/20948), [@papagian](https://github.com/papagian) +- **Gauge/BarGauge**: Added support for value mapping of "no data"-state to text/value. [#20842](https://github.com/grafana/grafana/pull/20842), [@mckn](https://github.com/mckn) +- **Graph**: Prevent tooltip from being displayed outside of window. [#20874](https://github.com/grafana/grafana/pull/20874), [@mckn](https://github.com/mckn) +- **Graphite**: Fixes error with annotation metric queries . [#20857](https://github.com/grafana/grafana/pull/20857), [@dprokop](https://github.com/dprokop) +- **Login**: Fix fatal error when navigating from reset password page. [#20747](https://github.com/grafana/grafana/pull/20747), [@peterholmberg](https://github.com/peterholmberg) +- **MixedDatasources**: Do not filter out all mixed data sources in add mixed query dropdown. [#20990](https://github.com/grafana/grafana/pull/20990), [@torkelo](https://github.com/torkelo) +- **Prometheus**: Fix caching for default labels request. [#20718](https://github.com/grafana/grafana/pull/20718), [@aocenas](https://github.com/aocenas) +- **Prometheus**: Run default labels query only once. [#20898](https://github.com/grafana/grafana/pull/20898), [@aocenas](https://github.com/aocenas) +- **Security**: Fix invite link still accessible after completion or revocation. [#20863](https://github.com/grafana/grafana/pull/20863), [@aknuds1](https://github.com/aknuds1) +- **Server**: Fail when unable to create log directory. [#20804](https://github.com/grafana/grafana/pull/20804), [@aknuds1](https://github.com/aknuds1) +- **TeamPicker**: Increase size limit from 10 to 100. [#20882](https://github.com/grafana/grafana/pull/20882), [@hendrikvh](https://github.com/hendrikvh) +- **Units**: Remove SI prefix symbol from new milli/microSievert(/h) units. [#20650](https://github.com/grafana/grafana/pull/20650), [@zegelin](https://github.com/zegelin) + +# 6.5.1 (2019-11-28) + +### Bug Fixes + +- **CloudWatch**: Region template query fix. [#20661](https://github.com/grafana/grafana/pull/20661), [@sunker](https://github.com/sunker) +- **CloudWatch**: Fix annotations query editor loading. [#20687](https://github.com/grafana/grafana/pull/20687), [@sunker](https://github.com/sunker) +- **Panel**: Fixes undefined services/dependencies in plugins without `/**@ngInject*/`. [#20696](https://github.com/grafana/grafana/pull/20696), [@hugohaggmark](https://github.com/hugohaggmark) +- **Server**: Fix failure to start with "bind: address already in use" when using socket as protocol. [#20679](https://github.com/grafana/grafana/pull/20679), [@aknuds1](https://github.com/aknuds1) +- **Stats**: Fix active admins/editors/viewers stats are counted more than once if the user is part of more than one org. [#20711](https://github.com/grafana/grafana/pull/20711), [@papagian](https://github.com/papagian) + +# 6.5.0 (2019-11-25) + +### Features / Enhancements + +- **CloudWatch**: Add curated dashboards for most popular amazon services. [#20486](https://github.com/grafana/grafana/pull/20486), [@sunker](https://github.com/sunker) +- **CloudWatch**: Enable Min time interval. [#20260](https://github.com/grafana/grafana/pull/20260), [@mtanda](https://github.com/mtanda) +- **Explore**: UI improvements for log details. [#20485](https://github.com/grafana/grafana/pull/20485), [@ivanahuckova](https://github.com/ivanahuckova) +- **Server**: Improve grafana-server diagnostics configuration for profiling and tracing. [#20593](https://github.com/grafana/grafana/pull/20593), [@papagian](https://github.com/papagian) + +### Bug Fixes + +- **BarGauge/Gauge**: Add back missing title option field display options. [#20616](https://github.com/grafana/grafana/pull/20616), [@torkelo](https://github.com/torkelo) +- **CloudWatch**: Fix high CPU load. [#20579](https://github.com/grafana/grafana/pull/20579), [@marefr](https://github.com/marefr) +- **CloudWatch**: Fix high resolution mode without expression. [#20459](https://github.com/grafana/grafana/pull/20459), [@mtanda](https://github.com/mtanda) +- **CloudWatch**: Make sure period variable is being interpreted correctly. [#20447](https://github.com/grafana/grafana/pull/20447), [@sunker](https://github.com/sunker) +- **CloudWatch**: Remove HighResolution toggle since it's not being used. [#20440](https://github.com/grafana/grafana/pull/20440), [@sunker](https://github.com/sunker) +- **Cloudwatch**: Fix LaunchTime attribute tag bug. [#20237](https://github.com/grafana/grafana/pull/20237), [@sunker](https://github.com/sunker) +- **Data links**: Fix URL field turns read-only for graph panels. [#20381](https://github.com/grafana/grafana/pull/20381), [@dprokop](https://github.com/dprokop) +- **Explore**: Keep logQL filters when selecting labels in log row details. [#20570](https://github.com/grafana/grafana/pull/20570), [@ivanahuckova](https://github.com/ivanahuckova) +- **MySQL**: Fix TLS auth settings in config page. [#20501](https://github.com/grafana/grafana/pull/20501), [@peterholmberg](https://github.com/peterholmberg) +- **Provisioning**: Fix unmarshaling nested jsonData values. [#20399](https://github.com/grafana/grafana/pull/20399), [@aocenas](https://github.com/aocenas) +- **Server**: Should fail when server is unable to bind port. [#20409](https://github.com/grafana/grafana/pull/20409), [@aknuds1](https://github.com/aknuds1) +- **Templating**: Prevents crash when \$\_\_searchFilter is not a string. [#20526](https://github.com/grafana/grafana/pull/20526), [@hugohaggmark](https://github.com/hugohaggmark) +- **TextPanel**: Fixes issue with template variable value not properly html escaped [#20588](https://github.com/grafana/grafana/pull/20588), [@torkelo](https://github.com/torkelo) +- **TimePicker**: Should update after location change. [#20466](https://github.com/grafana/grafana/pull/20466), [@torkelo](https://github.com/torkelo) + +## Breaking changes + +- **CloudWatch**: Pre Grafana 6.5.0, the CloudWatch datasource used the GetMetricStatistics API for all queries that did not have an ´id´ and did not have an ´expression´ defined in the query editor. The GetMetricStatistics API has a limit of 400 transactions per second. In this release, all queries use the GetMetricData API. The GetMetricData API has a limit of 50 transactions per second and 100 metrics per transaction. For API pricing information, please refer to the CloudWatch pricing page (https://aws.amazon.com/cloudwatch/pricing/). + +- **CloudWatch**: The GetMetricData API does not return metric unit, so unit auto detection in panels is no longer supported. + +- **CloudWatch**: The `HighRes` switch has been removed from the query editor. Read more about this in [upgrading to 6.5](https://grafana.com/docs/installation/upgrading/#upgrading-to-v6-5). + +- **CloudWatch**: In previous versions of Grafana, there was partial support for using multi-valued template variables as dimension values. When a multi-valued template variable is being used for dimension values in Grafana 6.5, a [search expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-search-expressions.html) will be generated. In the GetMetricData API, expressions are limited to 1024 characters, so you might reach this limit if you are using a large number of values. Read our [upgrading to 6.5](https://grafana.com/docs/installation/upgrading/#upgrading-to-v6-5) guide to see how you can use the `*` wildcard for this use case. + +# 6.5.0-beta1 (2019-11-14) + +### Features / Enhancements + +- **API**: Add `createdAt` and `updatedAt` to api/users/lookup. [#19496](https://github.com/grafana/grafana/pull/19496), [@gotjosh](https://github.com/gotjosh) +- **API**: Add createdAt field to /api/users/:id. [#19475](https://github.com/grafana/grafana/pull/19475), [@cored](https://github.com/cored) +- **Admin**: Adds setting to disable creating initial admin user. [#19505](https://github.com/grafana/grafana/pull/19505), [@shavonn](https://github.com/shavonn) +- **Alerting**: Include alert_state in Kafka notifier payload. [#20099](https://github.com/grafana/grafana/pull/20099), [@arnaudlemaignen](https://github.com/arnaudlemaignen) +- **AuthProxy**: Can now login with auth proxy and get a login token. [#20175](https://github.com/grafana/grafana/pull/20175), [@torkelo](https://github.com/torkelo) +- **AuthProxy**: replaces setting ldap_sync_ttl with sync_ttl. [#20191](https://github.com/grafana/grafana/pull/20191), [@jongyllen](https://github.com/jongyllen) +- **AzureMonitor**: Alerting for Azure Application Insights. [#19381](https://github.com/grafana/grafana/pull/19381), [@ChadNedzlek](https://github.com/ChadNedzlek) +- **Build**: Upgrade to Go 1.13. [#19502](https://github.com/grafana/grafana/pull/19502), [@aknuds1](https://github.com/aknuds1) +- **CLI**: Reduce memory usage for plugin installation. [#19639](https://github.com/grafana/grafana/pull/19639), [@olivierlemasle](https://github.com/olivierlemasle) +- **CloudWatch**: Add ap-east-1 to hard-coded region lists. [#19523](https://github.com/grafana/grafana/pull/19523), [@Nessworthy](https://github.com/Nessworthy) +- **CloudWatch**: ContainerInsights metrics support. [#18971](https://github.com/grafana/grafana/pull/18971), [@francopeapea](https://github.com/francopeapea) +- **CloudWatch**: Support dynamic queries using dimension wildcards [#20058](https://github.com/grafana/grafana/issues/20058), [@sunker](https://github.com/sunker) +- **CloudWatch**: Stop using GetMetricStatistics and use GetMetricData for all time series requests [#20057](https://github.com/grafana/grafana/issues/20057), [@sunker](https://github.com/sunker) +- **CloudWatch**: Convert query editor from Angular to React [#19880](https://github.com/grafana/grafana/issues/19880), [@sunker](https://github.com/sunker) +- **CloudWatch**: Convert config editor from Angular to React [#19881](https://github.com/grafana/grafana/issues/19881), [@shavonn](https://github.com/shavonn) +- **CloudWatch**: Improved error handling when throttling occurs [#20348](https://github.com/grafana/grafana/issues/20348), [@sunker](https://github.com/sunker) +- **CloudWatch**: Deep linking from Grafana panel to CloudWatch console [#20279](https://github.com/grafana/grafana/issues/20279), [@sunker](https://github.com/sunker) +- **CloudWatch**: Add Grafana user agent to GMD calls [#20277](https://github.com/grafana/grafana/issues/20277), [@sunker](https://github.com/sunker) +- **Dashboard**: Allows the d-solo route to be used without slug. [#19640](https://github.com/grafana/grafana/pull/19640), [@97amarnathk](https://github.com/97amarnathk) +- **Docker**: Build and publish an additional Ubuntu based docker image. [#20196](https://github.com/grafana/grafana/pull/20196), [@aknuds1](https://github.com/aknuds1) +- **Elasticsearch**: Adds support for region annotations. [#17602](https://github.com/grafana/grafana/pull/17602), [@fangel](https://github.com/fangel) +- **Explore**: Add custom DataLinks on datasource level (like tracing links). [#20060](https://github.com/grafana/grafana/pull/20060), [@aocenas](https://github.com/aocenas) +- **Explore**: Add functionality to show/hide query row results. [#19794](https://github.com/grafana/grafana/pull/19794), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Synchronise time ranges in split mode. [#19274](https://github.com/grafana/grafana/pull/19274), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: UI change for log row details . [#20034](https://github.com/grafana/grafana/pull/20034), [@ivanahuckova](https://github.com/ivanahuckova) +- **Frontend**: Migrate DataSource HTTP Settings to React. [#19452](https://github.com/grafana/grafana/pull/19452), [@dprokop](https://github.com/dprokop) +- **Frontend**: Show browser not supported notification. [#19904](https://github.com/grafana/grafana/pull/19904), [@peterholmberg](https://github.com/peterholmberg) +- **Graph**: Added series override option to have hidden series be persisted on save. [#20124](https://github.com/grafana/grafana/pull/20124), [@Gauravshah](https://github.com/Gauravshah) +- **Graphite**: Add Metrictank option to settings to view Metrictank request processing info in new inspect feature. [#20138](https://github.com/grafana/grafana/pull/20138), [@ryantxu](https://github.com/ryantxu) +- **LDAP**: Enable single user sync. [#19446](https://github.com/grafana/grafana/pull/19446), [@gotjosh](https://github.com/gotjosh) +- **LDAP**: Last org admin can login but wont be removed. [#20326](https://github.com/grafana/grafana/pull/20326), [@xlson](https://github.com/xlson) +- **LDAP**: Support env variable expressions in ldap.toml file. [#20173](https://github.com/grafana/grafana/pull/20173), [@torkelo](https://github.com/torkelo) +- **OAuth**: Generic OAuth role mapping support. [#17149](https://github.com/grafana/grafana/pull/17149), [@hypery2k](https://github.com/hypery2k) +- **Prometheus**: Custom query parameters string for Thanos downsampling. [#19121](https://github.com/grafana/grafana/pull/19121), [@seuf](https://github.com/seuf) +- **Provisioning**: Allow saving of provisioned dashboards. [#19820](https://github.com/grafana/grafana/pull/19820), [@jongyllen](https://github.com/jongyllen) +- **Security**: Minor XSS issue resolved by angularjs upgrade from 1.6.6 -> 1.6.9. [#19849](https://github.com/grafana/grafana/pull/19849), [@peterholmberg](https://github.com/peterholmberg) +- **TablePanel**: Prevents crash when data contains mixed data formats. [#20202](https://github.com/grafana/grafana/pull/20202), [@hugohaggmark](https://github.com/hugohaggmark) +- **Templating**: Introduces \$\_\_searchFilter to Query Variables. [#19858](https://github.com/grafana/grafana/pull/19858), [@hugohaggmark](https://github.com/hugohaggmark) +- **Templating**: Made default template variable query editor field a textarea with automatic height. [#20288](https://github.com/grafana/grafana/pull/20288), [@torkelo](https://github.com/torkelo) +- **Units**: Add milli/microSievert, milli/microSievert/h and pixels. [#20144](https://github.com/grafana/grafana/pull/20144), [@ryantxu](https://github.com/ryantxu) +- **Units**: Added mega ampere and watt-hour per kg. [#19922](https://github.com/grafana/grafana/pull/19922), [@Karan96Kaushik](https://github.com/Karan96Kaushik) +- **Enterprise**: Enterprise without a license behaves like OSS (Enterprise) + +### Bug Fixes + +- **API**: Added dashboardId and slug in response to dashboard import api. [#19692](https://github.com/grafana/grafana/pull/19692), [@jongyllen](https://github.com/jongyllen) +- **API**: Fix logging of dynamic listening port. [#19644](https://github.com/grafana/grafana/pull/19644), [@oleggator](https://github.com/oleggator) +- **BarGauge**: Fix so that default thresholds not keeps resetting. [#20190](https://github.com/grafana/grafana/pull/20190), [@lzdw](https://github.com/lzdw) +- **CloudWatch**: Fix incorrect casing of Redshift dimension entry for service class and stage. [#19897](https://github.com/grafana/grafana/pull/19897), [@nlsdfnbch](https://github.com/nlsdfnbch) +- **CloudWatch**: Fixing AWS Kafka dimension names. [#19986](https://github.com/grafana/grafana/pull/19986), [@skuxy](https://github.com/skuxy) +- **CloudWatch**: Metric math broken when using multi template variables [#18337](https://github.com/grafana/grafana/issues/18337), [@sunker](https://github.com/sunker) +- **CloudWatch**: Graphs with multiple multi-value dimension variables don't work [#17949](https://github.com/grafana/grafana/issues/17949), [@sunker](https://github.com/sunker) +- **CloudWatch**: Variables' values surrounded with braces in request sent to AWS [#14451](https://github.com/grafana/grafana/issues/14451), [@sunker](https://github.com/sunker) +- **CloudWatch**: Cloudwatch Query for a list of instances for which data is available in the selected time interval [#12784](https://github.com/grafana/grafana/issues/12784), [@sunker](https://github.com/sunker) +- **CloudWatch**: Dimension's positioning/order should be stored in the json dashboard [#11062](https://github.com/grafana/grafana/issues/11062), [@sunker](https://github.com/sunker) +- **CloudWatch**: Batch CloudWatch API call support in backend [#7991](https://github.com/grafana/grafana/issues/7991), [@sunker](https://github.com/sunker) +- **ColorPicker**: Fixes issue with ColorPicker disappearing too quickly . [#20289](https://github.com/grafana/grafana/pull/20289), [@dprokop](https://github.com/dprokop) +- **Datasource**: Add custom headers on alerting queries. [#19508](https://github.com/grafana/grafana/pull/19508), [@weeco](https://github.com/weeco) +- **Docker**: Add additional glibc dependencies to support certain backend plugins in alpine. [#20214](https://github.com/grafana/grafana/pull/20214), [@briangann](https://github.com/briangann) +- **Docker**: Build and use musl-based binaries in alpine images to resolve glibc incompatibility issues. [#19798](https://github.com/grafana/grafana/pull/19798), [@aknuds1](https://github.com/aknuds1) +- **Elasticsearch**: Fix template variables interpolation when redirecting to Explore. [#20314](https://github.com/grafana/grafana/pull/20314), [@ivanahuckova](https://github.com/ivanahuckova) +- **Elasticsearch**: Support rendering in logs panel. [#20229](https://github.com/grafana/grafana/pull/20229), [@davkal](https://github.com/davkal) +- **Explore**: Expand template variables when redirecting from dashboard panel. [#19582](https://github.com/grafana/grafana/pull/19582), [@ivanahuckova](https://github.com/ivanahuckova) +- **OAuth**: Make the login button display name of custom OAuth provider. [#20209](https://github.com/grafana/grafana/pull/20209), [@dprokop](https://github.com/dprokop) +- **ReactPanels**: Adds Explore menu item. [#20236](https://github.com/grafana/grafana/pull/20236), [@hugohaggmark](https://github.com/hugohaggmark) +- **Team Sync**: Fix URL encode Group IDs for external team sync. [#20280](https://github.com/grafana/grafana/pull/20280), [@gotjosh](https://github.com/gotjosh) + +## Breaking changes + +- **CloudWatch**: Pre Grafana 6.5.0, the CloudWatch datasource used the GetMetricStatistics API for all queries that did not have an ´id´ and did not have an ´expression´ defined in the query editor. The GetMetricStatistics API has a limit of 400 transactions per second. In this release, all queries use the GetMetricData API. The GetMetricData API has a limit of 50 transactions per second and 100 metrics per transaction. For API pricing information, please refer to the CloudWatch pricing page (https://aws.amazon.com/cloudwatch/pricing/). + +- **CloudWatch**: The GetMetricData API does not return metric unit, so unit auto detection in panels is no longer supported. + +- **CloudWatch**: The `HighRes` switch has been removed from the query editor. Read more about this in [upgrading to 6.5](https://grafana.com/docs/installation/upgrading/#upgrading-to-v6-5). + +- **CloudWatch**: In previous versions of Grafana, there was partial support for using multi-valued template variables as dimension values. When a multi-valued template variable is being used for dimension values in Grafana 6.5, a [search expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-search-expressions.html) will be generated. In the GetMetricData API, expressions are limited to 1024 characters, so you might reach this limit if you are using a large number of values. Read our [upgrading to 6.5](https://grafana.com/docs/installation/upgrading/#upgrading-to-v6-5) guide to see how you can use the `*` wildcard for this use case. + +# 6.4.5 (2019-11-25) + +### Bug Fixes + +- **CloudWatch**: Fix high CPU load [#20579](https://github.com/grafana/grafana/pull/20579) + +# 6.4.4 (2019-11-06) + +### Bug Fixes + +- **MySQL**: Fix encoding in connection string [#20192](https://github.com/grafana/grafana/pull/20192) +- **DataLinks**: Fix blur issues. [#19883](https://github.com/grafana/grafana/pull/19883), [@aocenas](https://github.com/aocenas) +- **Docker**: Makes it possible to parse timezones in the docker image. [#20081](https://github.com/grafana/grafana/pull/20081), [@xlson](https://github.com/xlson) +- **LDAP**: All LDAP servers should be tried even if one of them returns a connection error. [#20077](https://github.com/grafana/grafana/pull/20077), [@jongyllen](https://github.com/jongyllen) +- **LDAP**: No longer shows incorrectly matching groups based on role in debug page. [#20018](https://github.com/grafana/grafana/pull/20018), [@xlson](https://github.com/xlson) +- **Singlestat**: Fix no data / null value mapping . [#19951](https://github.com/grafana/grafana/pull/19951), [@ryantxu](https://github.com/ryantxu) + +#### Security vulnerability + +The MySQL data source connection string fix, [#20192](https://github.com/grafana/grafana/pull/20192), that was part of this release +also fixed a security vulnerability. Thanks Yuriy Dyachenko for discovering and notifying us about this. + +# 6.4.3 (2019-10-16) + +### Bug Fixes + +- **Alerting**: All notification channels should send even if one fails to send. [#19807](https://github.com/grafana/grafana/pull/19807), [@jan25](https://github.com/jan25) +- **AzureMonitor**: Fix slate interference with dropdowns. [#19799](https://github.com/grafana/grafana/pull/19799), [@aocenas](https://github.com/aocenas) +- **ContextMenu**: make ContextMenu positioning aware of the viewport width. [#19699](https://github.com/grafana/grafana/pull/19699), [@krvajal](https://github.com/krvajal) +- **DataLinks**: Fix context menu not showing in singlestat-ish visualisations. [#19809](https://github.com/grafana/grafana/pull/19809), [@dprokop](https://github.com/dprokop) +- **DataLinks**: Fix url field not releasing focus. [#19804](https://github.com/grafana/grafana/pull/19804), [@aocenas](https://github.com/aocenas) +- **Datasource**: Fixes clicking outside of some query editors required 2 clicks. [#19822](https://github.com/grafana/grafana/pull/19822), [@aocenas](https://github.com/aocenas) +- **Panels**: Fixes default tab for visualizations without Queries Tab. [#19803](https://github.com/grafana/grafana/pull/19803), [@hugohaggmark](https://github.com/hugohaggmark) +- **Singlestat**: Fixed issue with mapping null to text. [#19689](https://github.com/grafana/grafana/pull/19689), [@torkelo](https://github.com/torkelo) +- **@grafana/toolkit**: Don't fail plugin creation when git user.name config is not set. [#19821](https://github.com/grafana/grafana/pull/19821), [@dprokop](https://github.com/dprokop) +- **@grafana/toolkit**: TSLint line number off by 1. [#19782](https://github.com/grafana/grafana/pull/19782), [@fredwangwang](https://github.com/fredwangwang) + +# 6.4.2 (2019-10-08) + +### Bug Fixes + +- **CloudWatch**: Changes incorrect dimension wmlid to wlmid . [#19679](https://github.com/grafana/grafana/pull/19679), [@ATTron](https://github.com/ATTron) +- **Grafana Image Renderer**: Fixes plugin page. [#19664](https://github.com/grafana/grafana/pull/19664), [@hugohaggmark](https://github.com/hugohaggmark) +- **Graph**: Fixes auto decimals logic for y axis ticks that results in too many decimals for high values. [#19618](https://github.com/grafana/grafana/pull/19618), [@torkelo](https://github.com/torkelo) +- **Graph**: Switching to series mode should re-render graph. [#19623](https://github.com/grafana/grafana/pull/19623), [@torkelo](https://github.com/torkelo) +- **Loki**: Fix autocomplete on label values. [#19579](https://github.com/grafana/grafana/pull/19579), [@aocenas](https://github.com/aocenas) +- **Loki**: Removes live option for logs panel. [#19533](https://github.com/grafana/grafana/pull/19533), [@davkal](https://github.com/davkal) +- **Profile**: Fix issue with user profile not showing more than sessions sessions in some cases. [#19578](https://github.com/grafana/grafana/pull/19578), [@huynhsamha](https://github.com/huynhsamha) +- **Prometheus**: Fixes so results in Panel always are sorted by query order. [#19597](https://github.com/grafana/grafana/pull/19597), [@hugohaggmark](https://github.com/hugohaggmark) +- **ShareQuery**: Fixed issue when using -- Dashboard -- datasource (to share query result) when dashboard had rows. [#19610](https://github.com/grafana/grafana/pull/19610), [@torkelo](https://github.com/torkelo) +- **Show SAML login button if SAML is enabled**. [#19591](https://github.com/grafana/grafana/pull/19591), [@papagian](https://github.com/papagian) +- **SingleStat**: Fixes \$\_\_name postfix/prefix usage. [#19687](https://github.com/grafana/grafana/pull/19687), [@hugohaggmark](https://github.com/hugohaggmark) +- **Table**: Proper handling of json data with dataframes. [#19596](https://github.com/grafana/grafana/pull/19596), [@marefr](https://github.com/marefr) +- **Units**: Fixed wrong id for Terabits/sec. [#19611](https://github.com/grafana/grafana/pull/19611), [@andreaslangnevyjel](https://github.com/andreaslangnevyjel) + +# 6.4.1 (2019-10-02) + +### Bug Fixes + +- **Provisioning**: Fixed issue where empty nested keys in YAML provisioning caused server crash, [#19547](https://github.com/grafana/grafana/pull/19547) +- **ImageRendering**: Fixed issue with image rendering in enterprise build (Enterprise) +- **Reporting**: Fixed issue with reporting service when STMP disabled (Enterprise). + +# 6.4.0 (2019-10-01) + +### Features / Enhancements + +- **Build**: Upgrade go to 1.12.10. [#19499](https://github.com/grafana/grafana/pull/19499), [@marefr](https://github.com/marefr) +- **DataLinks**: Suggestions menu improvements. [#19396](https://github.com/grafana/grafana/pull/19396), [@dprokop](https://github.com/dprokop) +- **Explore**: Take root_url setting into account when redirecting from dashboard to explore. [#19447](https://github.com/grafana/grafana/pull/19447), [@ivanahuckova](https://github.com/ivanahuckova) +- **Explore**: Update broken link to logql docs. [#19510](https://github.com/grafana/grafana/pull/19510), [@ivanahuckova](https://github.com/ivanahuckova) +- **Logs**: Adds Logs Panel as a visualization. [#19504](https://github.com/grafana/grafana/pull/19504), [@davkal](https://github.com/davkal) +- **Reporting**: Generate and email PDF reports based on Dashboards (Enterprise) + +### Bug Fixes + +- **CLI**: Fix version selection for plugin install. [#19498](https://github.com/grafana/grafana/pull/19498), [@aocenas](https://github.com/aocenas) +- **Graph**: Fixes minor issue with series override color picker and custom color . [#19516](https://github.com/grafana/grafana/pull/19516), [@torkelo](https://github.com/torkelo) + +## Plugins that need updating when upgrading from 6.3 to 6.4 + +- [Splunk](https://grafana.com/grafana/plugins/grafana-splunk-datasource) + +# 6.4.0-beta2 (2019-09-25) + +### Features / Enhancements + +- **Azure Monitor**: Remove support for cross resource queries (#19115)". [#19346](https://github.com/grafana/grafana/pull/19346), [@sunker](https://github.com/sunker) +- **Docker**: Upgrade packages to resolve reported vulnerabilities. [#19188](https://github.com/grafana/grafana/pull/19188), [@marefr](https://github.com/marefr) +- **Graphite**: Time range expansion reduced from 1 minute to 1 second. [#19246](https://github.com/grafana/grafana/pull/19246), [@torkelo](https://github.com/torkelo) +- **grafana/toolkit**: Add plugin creation task. [#19207](https://github.com/grafana/grafana/pull/19207), [@dprokop](https://github.com/dprokop) + +### Bug Fixes + +- **Alerting**: Prevents creating alerts from unsupported queries. [#19250](https://github.com/grafana/grafana/pull/19250), [@hugohaggmark](https://github.com/hugohaggmark) +- **Alerting**: Truncate PagerDuty summary when greater than 1024 characters. [#18730](https://github.com/grafana/grafana/pull/18730), [@nvllsvm](https://github.com/nvllsvm) +- **Cloudwatch**: Fix autocomplete for Gamelift dimensions. [#19146](https://github.com/grafana/grafana/pull/19146), [@kevinpz](https://github.com/kevinpz) +- **Dashboard**: Fix export for sharing when panels use default data source. [#19315](https://github.com/grafana/grafana/pull/19315), [@torkelo](https://github.com/torkelo) +- **Database**: Rewrite system statistics query to perform better. [#19178](https://github.com/grafana/grafana/pull/19178), [@papagian](https://github.com/papagian) +- **Gauge/BarGauge**: Fix issue with [object Object] in titles . [#19217](https://github.com/grafana/grafana/pull/19217), [@ryantxu](https://github.com/ryantxu) +- **MSSQL**: Revert usage of new connectionstring format introduced by #18384. [#19203](https://github.com/grafana/grafana/pull/19203), [@marefr](https://github.com/marefr) +- **Multi-LDAP**: Do not fail-fast on invalid credentials. [#19261](https://github.com/grafana/grafana/pull/19261), [@gotjosh](https://github.com/gotjosh) +- **MySQL, Postgres, MSSQL**: Fix validating query with template variables in alert . [#19237](https://github.com/grafana/grafana/pull/19237), [@marefr](https://github.com/marefr) +- **MySQL, Postgres**: Update raw sql when query builder updates. [#19209](https://github.com/grafana/grafana/pull/19209), [@marefr](https://github.com/marefr) +- **MySQL**: Limit datasource error details returned from the backend. [#19373](https://github.com/grafana/grafana/pull/19373), [@marefr](https://github.com/marefr) + +# 6.4.0-beta1 (2019-09-17) + +### Features / Enhancements + +- **Reporting**: Created scheduled PDF reports for any dashboard (Enterprise). +- **API**: Readonly datasources should not be created via the API. [#19006](https://github.com/grafana/grafana/pull/19006), [@papagian](https://github.com/papagian) +- **Alerting**: Include configured AlertRuleTags in Webhooks notifier. [#18233](https://github.com/grafana/grafana/pull/18233), [@dominic-miglar](https://github.com/dominic-miglar) +- **Annotations**: Add annotations support to Loki. [#18949](https://github.com/grafana/grafana/pull/18949), [@aocenas](https://github.com/aocenas) +- **Annotations**: Use a single row to represent a region. [#17673](https://github.com/grafana/grafana/pull/17673), [@ryantxu](https://github.com/ryantxu) +- **Auth**: Allow inviting existing users when login form is disabled. [#19048](https://github.com/grafana/grafana/pull/19048), [@548017](https://github.com/548017) +- **Azure Monitor**: Add support for cross resource queries. [#19115](https://github.com/grafana/grafana/pull/19115), [@sunker](https://github.com/sunker) +- **CLI**: Allow installing custom binary plugins. [#17551](https://github.com/grafana/grafana/pull/17551), [@aocenas](https://github.com/aocenas) +- **Dashboard**: Adds Logs Panel (alpha) as visualization option for Dashboards. [#18641](https://github.com/grafana/grafana/pull/18641), [@hugohaggmark](https://github.com/hugohaggmark) +- **Dashboard**: Reuse query results between panels . [#16660](https://github.com/grafana/grafana/pull/16660), [@ryantxu](https://github.com/ryantxu) +- **Dashboard**: Set time to to 23:59:59 when setting To time using calendar. [#18595](https://github.com/grafana/grafana/pull/18595), [@simPod](https://github.com/simPod) +- **DataLinks**: Add DataLinks support to Gauge, BarGauge and stat panel. [#18605](https://github.com/grafana/grafana/pull/18605), [@ryantxu](https://github.com/ryantxu) +- **DataLinks**: Enable access to labels & field names. [#18918](https://github.com/grafana/grafana/pull/18918), [@torkelo](https://github.com/torkelo) +- **DataLinks**: Enable multiple data links per panel. [#18434](https://github.com/grafana/grafana/pull/18434), [@dprokop](https://github.com/dprokop) +- **Docker**: switch docker image to alpine base with phantomjs support. [#18468](https://github.com/grafana/grafana/pull/18468), [@DanCech](https://github.com/DanCech) +- **Elasticsearch**: allow templating queries to order by doc_count. [#18870](https://github.com/grafana/grafana/pull/18870), [@hackery](https://github.com/hackery) +- **Explore**: Add throttling when doing live queries. [#19085](https://github.com/grafana/grafana/pull/19085), [@aocenas](https://github.com/aocenas) +- **Explore**: Adds ability to go back to dashboard, optionally with query changes. [#17982](https://github.com/grafana/grafana/pull/17982), [@kaydelaney](https://github.com/kaydelaney) +- **Explore**: Reduce default time range to last hour. [#18212](https://github.com/grafana/grafana/pull/18212), [@davkal](https://github.com/davkal) +- **Gauge/BarGauge**: Support decimals for min/max. [#18368](https://github.com/grafana/grafana/pull/18368), [@ryantxu](https://github.com/ryantxu) +- **Graph**: New series override transform constant that renders a single point as a line across the whole graph. [#19102](https://github.com/grafana/grafana/pull/19102), [@davkal](https://github.com/davkal) +- **Image rendering**: Add deprecation warning when PhantomJS is used for rendering images. [#18933](https://github.com/grafana/grafana/pull/18933), [@papagian](https://github.com/papagian) +- **InfluxDB**: Enable interpolation within ad-hoc filter values. [#18077](https://github.com/grafana/grafana/pull/18077), [@kvc-code](https://github.com/kvc-code) +- **LDAP**: Allow an user to be synchronized against LDAP. [#18976](https://github.com/grafana/grafana/pull/18976), [@gotjosh](https://github.com/gotjosh) +- **Ldap**: Add ldap debug page. [#18759](https://github.com/grafana/grafana/pull/18759), [@peterholmberg](https://github.com/peterholmberg) +- **Loki**: Remove prefetching of default label values. [#18213](https://github.com/grafana/grafana/pull/18213), [@davkal](https://github.com/davkal) +- **Metrics**: Add failed alert notifications metric. [#18089](https://github.com/grafana/grafana/pull/18089), [@koorgoo](https://github.com/koorgoo) +- **OAuth**: Support JMES path lookup when retrieving user email. [#14683](https://github.com/grafana/grafana/pull/14683), [@bobmshannon](https://github.com/bobmshannon) +- **OAuth**: return GitLab groups as a part of user info (enable team sync). [#18388](https://github.com/grafana/grafana/pull/18388), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **Panels**: Add unit for electrical charge - ampere-hour. [#18950](https://github.com/grafana/grafana/pull/18950), [@anirudh-ramesh](https://github.com/anirudh-ramesh) +- **Plugin**: AzureMonitor - Reapply MetricNamespace support. [#17282](https://github.com/grafana/grafana/pull/17282), [@raphaelquati](https://github.com/raphaelquati) +- **Plugins**: better warning when plugins fail to load. [#18671](https://github.com/grafana/grafana/pull/18671), [@ryantxu](https://github.com/ryantxu) +- **Postgres**: Add support for scram sha 256 authentication. [#18397](https://github.com/grafana/grafana/pull/18397), [@nonamef](https://github.com/nonamef) +- **RemoteCache**: Support SSL with Redis. [#18511](https://github.com/grafana/grafana/pull/18511), [@kylebrandt](https://github.com/kylebrandt) +- **SingleStat**: The gauge option in now disabled/hidden (unless it's an old panel with it already enabled) . [#18610](https://github.com/grafana/grafana/pull/18610), [@ryantxu](https://github.com/ryantxu) +- **Stackdriver**: Add extra alignment period options. [#18909](https://github.com/grafana/grafana/pull/18909), [@sunker](https://github.com/sunker) +- **Units**: Add South African Rand (ZAR) to currencies. [#18893](https://github.com/grafana/grafana/pull/18893), [@jeteon](https://github.com/jeteon) +- **Units**: Adding T,P,E,Z,and Y bytes. [#18706](https://github.com/grafana/grafana/pull/18706), [@chiqomar](https://github.com/chiqomar) + +### Bug Fixes + +- **Alerting**: Notification is sent when state changes from no_data to ok. [#18920](https://github.com/grafana/grafana/pull/18920), [@papagian](https://github.com/papagian) +- **Alerting**: fix duplicate alert states when the alert fails to save to the database. [#18216](https://github.com/grafana/grafana/pull/18216), [@kylebrandt](https://github.com/kylebrandt) +- **Alerting**: fix response popover prompt when add notification channels. [#18967](https://github.com/grafana/grafana/pull/18967), [@lzdw](https://github.com/lzdw) +- **CloudWatch**: Fix alerting for queries with Id (using GetMetricData). [#17899](https://github.com/grafana/grafana/pull/17899), [@alex-berger](https://github.com/alex-berger) +- **Explore**: Fix auto completion on label values for Loki. [#18988](https://github.com/grafana/grafana/pull/18988), [@aocenas](https://github.com/aocenas) +- **Explore**: Fixes crash using back button with a zoomed in graph. [#19122](https://github.com/grafana/grafana/pull/19122), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: Fixes so queries in Explore are only run if Graph/Table is shown. [#19000](https://github.com/grafana/grafana/pull/19000), [@hugohaggmark](https://github.com/hugohaggmark) +- **MSSQL**: Change connectionstring to URL format to fix using passwords with semicolon. [#18384](https://github.com/grafana/grafana/pull/18384), [@Russiancold](https://github.com/Russiancold) +- **MSSQL**: Fix memory leak when debug enabled. [#19049](https://github.com/grafana/grafana/pull/19049), [@briangann](https://github.com/briangann) +- **Provisioning**: Allow escaping literal '$' with '$\$' in configs to avoid interpolation. [#18045](https://github.com/grafana/grafana/pull/18045), [@kylebrandt](https://github.com/kylebrandt) +- **TimePicker**: Fixes hiding time picker dropdown in FireFox. [#19154](https://github.com/grafana/grafana/pull/19154), [@hugohaggmark](https://github.com/hugohaggmark) + +## Breaking changes + +### Annotations + +There are some breaking changes in the annotations HTTP API for region annotations. Region annotations are now represented +using a single event instead of two separate events. Check breaking changes in HTTP API [below](#http-api) and [HTTP API documentation](https://grafana.com/docs/http_api/annotations/) for more details. + +### Docker + +Grafana is now using Alpine 3.10 as docker base image. + +### HTTP API + +- `GET /api/alert-notifications` now requires at least editor access. New `/api/alert-notifications/lookup` returns less information than `/api/alert-notifications` and can be access by any authenticated user. +- `GET /api/alert-notifiers` now requires at least editor access +- `GET /api/org/users` now requires org admin role. New `/api/org/users/lookup` returns less information than `/api/org/users` and can be access by users that are org admins, admin in any folder or admin of any team. +- `GET /api/annotations` no longer returns `regionId` property. +- `POST /api/annotations` no longer supports `isRegion` property. +- `PUT /api/annotations/:id` no longer supports `isRegion` property. +- `PATCH /api/annotations/:id` no longer supports `isRegion` property. +- `DELETE /api/annotations/region/:id` has been removed. + +## Deprecation notes + +### PhantomJS + +[PhantomJS](https://phantomjs.org/), which is used for rendering images of dashboards and panels, is deprecated and will be removed in a future Grafana release. A deprecation warning will from now on be logged when Grafana starts up if PhantomJS is in use. + +Please consider migrating from PhantomJS to the [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer). + +# 6.3.7 (2019-11-22) + +### Bug Fixes + +- **CloudWatch**: Fix high CPU load [#20579](https://github.com/grafana/grafana/pull/20579) + +# 6.3.6 (2019-09-23) + +### Features / Enhancements + +- **Metrics**: Adds setting for turning off total stats metrics. [#19142](https://github.com/grafana/grafana/pull/19142), [@marefr](https://github.com/marefr) + +### Bug Fixes + +- **Database**: Rewrite system statistics query to perform better. [#19178](https://github.com/grafana/grafana/pull/19178), [@papagian](https://github.com/papagian) +- **Explore**: Fixes error when switching from prometheus to loki data sources. [#18599](https://github.com/grafana/grafana/pull/18599), [@kaydelaney](https://github.com/kaydelaney) + +# 6.3.5 (2019-09-02) + +### Upgrades + +- **Build**: Upgrade to go 1.12.9. [#18638](https://github.com/grafana/grafana/pull/18638), [@marcusolsson](https://github.com/marcusolsson) + +### Bug Fixes + +- **Dashboard**: Fixes dashboards init failed loading error for dashboards with panel links that had missing properties. [#18786](https://github.com/grafana/grafana/pull/18786), [@torkelo](https://github.com/torkelo) +- **Editor**: Fixes issue where only entire lines were being copied. [#18806](https://github.com/grafana/grafana/pull/18806), [@kaydelaney](https://github.com/kaydelaney) +- **Explore**: Fixes query field layout in splitted view for Safari browsers. [#18654](https://github.com/grafana/grafana/pull/18654), [@hugohaggmark](https://github.com/hugohaggmark) +- **LDAP**: multildap + ldap integration. [#18588](https://github.com/grafana/grafana/pull/18588), [@markelog](https://github.com/markelog) +- **Profile/UserAdmin**: Fix for user agent parser crashes grafana-server on 32-bit builds. [#18788](https://github.com/grafana/grafana/pull/18788), [@marcusolsson](https://github.com/marcusolsson) +- **Prometheus**: Prevents panel editor crash when switching to Prometheus data source. [#18616](https://github.com/grafana/grafana/pull/18616), [@hugohaggmark](https://github.com/hugohaggmark) +- **Prometheus**: Changes brace-insertion behavior to be less annoying. [#18698](https://github.com/grafana/grafana/pull/18698), [@kaydelaney](https://github.com/kaydelaney) + +# 6.3.4 (2019-08-29) + +- **Security**: Urgent security patch release. Please read more in our [blog](https://grafana.com/blog/2019/08/29/grafana-5.4.5-and-6.3.4-released-with-important-security-fix/) + +# 6.3.3 (2019-08-15) + +### Bug Fixes + +- **Annotations**: Fix failing annotation query when time series query is cancelled. [#18532](https://github.com/grafana/grafana/pull/18532), [@dprokop](https://github.com/dprokop) +- **Auth**: Do not set SameSite cookie attribute if cookie_samesite is none. [#18462](https://github.com/grafana/grafana/pull/18462), [@papagian](https://github.com/papagian) +- **DataLinks**: Apply scoped variables to data links correctly. [#18454](https://github.com/grafana/grafana/pull/18454), [@dprokop](https://github.com/dprokop) +- **DataLinks**: Respect timezone when displaying datapoint's timestamp in graph context menu. [#18461](https://github.com/grafana/grafana/pull/18461), [@dprokop](https://github.com/dprokop) +- **DataLinks**: Use datapoint timestamp correctly when interpolating variables. [#18459](https://github.com/grafana/grafana/pull/18459), [@dprokop](https://github.com/dprokop) +- **Explore**: Fix loading error for empty queries. [#18488](https://github.com/grafana/grafana/pull/18488), [@davkal](https://github.com/davkal) +- **Graph**: Fixes legend issue clicking on series line icon and issue with horizontal scrollbar being visible on windows. [#18563](https://github.com/grafana/grafana/pull/18563), [@torkelo](https://github.com/torkelo) +- **Graphite**: Avoid glob of single-value array variables . [#18420](https://github.com/grafana/grafana/pull/18420), [@gotjosh](https://github.com/gotjosh) +- **Prometheus**: Fix queries with label_replace remove the \$1 match when loading query editor. [#18480](https://github.com/grafana/grafana/pull/18480), [@hugohaggmark](https://github.com/hugohaggmark) +- **Prometheus**: More consistently allows for multi-line queries in editor. [#18362](https://github.com/grafana/grafana/pull/18362), [@kaydelaney](https://github.com/kaydelaney) +- **TimeSeries**: Assume values are all numbers. [#18540](https://github.com/grafana/grafana/pull/18540), [@ryantxu](https://github.com/ryantxu) + +# 6.3.2 (2019-08-07) + +### Bug Fixes + +- **Gauge/BarGauge**: Fixes issue with lost thresholds and an issue loading Gauge with avg stat. [#18375](https://github.com/grafana/grafana/pull/18375) + +# 6.3.1 (2019-08-07) + +### Bug Fixes + +- **PanelLinks**: Fixes crash issue with Gauge & Bar Gauge panels with panel links (drill down links). [#18430](https://github.com/grafana/grafana/pull/18430) + +# 6.3.0 (2019-08-06) + +### Features / Enhancements + +- **OAuth**: Do not set SameSite OAuth cookie if cookie_samesite is None. [#18392](https://github.com/grafana/grafana/pull/18392), [@papagian](https://github.com/papagian) + +### Bug Fixes + +- **PanelLinks**: Fix render issue when there is no panel description. [#18408](https://github.com/grafana/grafana/pull/18408), [@dehrax](https://github.com/dehrax) + +# 6.3.0-beta4 (2019-08-02) + +### Features / Enhancements + +- **Auth Proxy**: Include additional headers as part of the cache key. [#18298](https://github.com/grafana/grafana/pull/18298), [@gotjosh](https://github.com/gotjosh) + +# 6.3.0-beta3 (2019-08-02) + +### Bug Fixes + +- **OAuth**: Fix "missing saved state" OAuth login failure due to SameSite cookie policy. [#18332](https://github.com/grafana/grafana/pull/18332), [@papagian](https://github.com/papagian) +- **cli**: fix for recognizing when in dev mode.. [#18334](https://github.com/grafana/grafana/pull/18334), [@xlson](https://github.com/xlson) + +# 6.3.0-beta2 (2019-07-26) + +### Features / Enhancements + +- **Build grafana images consistently**. [#18224](https://github.com/grafana/grafana/pull/18224), [@hassanfarid](https://github.com/hassanfarid) +- **Docs**: SAML. [#18069](https://github.com/grafana/grafana/pull/18069), [@gotjosh](https://github.com/gotjosh) +- **Permissions**: Show plugins in nav for non admin users but hide plugin configuration. [#18234](https://github.com/grafana/grafana/pull/18234), [@aocenas](https://github.com/aocenas) +- **TimePicker**: Increase max height of quick range dropdown. [#18247](https://github.com/grafana/grafana/pull/18247), [@torkelo](https://github.com/torkelo) + +### Bug Fixes + +- **DataLinks**: Fixes incorrect interpolation of \${\_\_series_name} . [#18251](https://github.com/grafana/grafana/pull/18251), [@torkelo](https://github.com/torkelo) +- **Loki**: Display live tailed logs in correct order in Explore. [#18031](https://github.com/grafana/grafana/pull/18031), [@kaydelaney](https://github.com/kaydelaney) +- **PhantomJS**: Fixes rendering on Debian Buster. [#18162](https://github.com/grafana/grafana/pull/18162), [@xlson](https://github.com/xlson) +- **TimePicker**: Fixed style issue for custom range popover. [#18244](https://github.com/grafana/grafana/pull/18244), [@torkelo](https://github.com/torkelo) +- **Timerange**: Fixes a bug where custom time ranges didn't respect UTC. [#18248](https://github.com/grafana/grafana/pull/18248), [@kaydelaney](https://github.com/kaydelaney) +- **remote_cache**: Fix redis connstr parsing. [#18204](https://github.com/grafana/grafana/pull/18204), [@mblaschke](https://github.com/mblaschke) + +# 6.3.0-beta1 (2019-07-10) + +### Features / Enhancements + +- **Alerting**: Add tags to alert rules. [#10989](https://github.com/grafana/grafana/pull/10989), [@Thib17](https://github.com/Thib17) +- **Alerting**: Attempt to send email notifications to all given email addresses. [#16881](https://github.com/grafana/grafana/pull/16881), [@zhulongcheng](https://github.com/zhulongcheng) +- **Alerting**: Improve alert rule testing. [#16286](https://github.com/grafana/grafana/pull/16286), [@marefr](https://github.com/marefr) +- **Alerting**: Support for configuring content field for Discord alert notifier. [#17017](https://github.com/grafana/grafana/pull/17017), [@jan25](https://github.com/jan25) +- **Alertmanager**: Replace illegal chars with underscore in label names. [#17002](https://github.com/grafana/grafana/pull/17002), [@bergquist](https://github.com/bergquist) +- **Auth**: Allow expiration of API keys. [#17678](https://github.com/grafana/grafana/pull/17678), [@papagian](https://github.com/papagian) +- **Auth**: Return device, os and browser when listing user auth tokens in HTTP API. [#17504](https://github.com/grafana/grafana/pull/17504), [@shavonn](https://github.com/shavonn) +- **Auth**: Support list and revoke of user auth tokens in UI. [#17434](https://github.com/grafana/grafana/pull/17434), [@shavonn](https://github.com/shavonn) +- **AzureMonitor**: change clashing built-in Grafana variables/macro names for Azure Logs. [#17140](https://github.com/grafana/grafana/pull/17140), [@shavonn](https://github.com/shavonn) +- **CloudWatch**: Made region visible for AWS Cloudwatch Expressions. [#17243](https://github.com/grafana/grafana/pull/17243), [@utkarshcmu](https://github.com/utkarshcmu) +- **Cloudwatch**: Add AWS DocDB metrics. [#17241](https://github.com/grafana/grafana/pull/17241), [@utkarshcmu](https://github.com/utkarshcmu) +- **Dashboard**: Use timezone dashboard setting when exporting to CSV. [#18002](https://github.com/grafana/grafana/pull/18002), [@dehrax](https://github.com/dehrax) +- **Data links**. [#17267](https://github.com/grafana/grafana/pull/17267), [@torkelo](https://github.com/torkelo) +- **Docker**: Switch base image to ubuntu:latest from debian:stretch to avoid security issues.. [#17066](https://github.com/grafana/grafana/pull/17066), [@bergquist](https://github.com/bergquist) +- **Elasticsearch**: Support for visualizing logs in Explore . [#17605](https://github.com/grafana/grafana/pull/17605), [@marefr](https://github.com/marefr) +- **Explore**: Adds Live option for supported data sources. [#17062](https://github.com/grafana/grafana/pull/17062), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: Adds orgId to URL for sharing purposes. [#17895](https://github.com/grafana/grafana/pull/17895), [@kaydelaney](https://github.com/kaydelaney) +- **Explore**: Adds support for new loki 'start' and 'end' params for labels endpoint. [#17512](https://github.com/grafana/grafana/pull/17512), [@kaydelaney](https://github.com/kaydelaney) +- **Explore**: Adds support for toggling raw query mode in explore. [#17870](https://github.com/grafana/grafana/pull/17870), [@kaydelaney](https://github.com/kaydelaney) +- **Explore**: Allow switching between metrics and logs . [#16959](https://github.com/grafana/grafana/pull/16959), [@marefr](https://github.com/marefr) +- **Explore**: Combines the timestamp and local time columns into one. [#17775](https://github.com/grafana/grafana/pull/17775), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: Display log lines context . [#17097](https://github.com/grafana/grafana/pull/17097), [@dprokop](https://github.com/dprokop) +- **Explore**: Don't parse log levels if provided by field or label. [#17180](https://github.com/grafana/grafana/pull/17180), [@marefr](https://github.com/marefr) +- **Explore**: Improves performance of Logs element by limiting re-rendering. [#17685](https://github.com/grafana/grafana/pull/17685), [@kaydelaney](https://github.com/kaydelaney) +- **Explore**: Support for new LogQL filtering syntax. [#16674](https://github.com/grafana/grafana/pull/16674), [@davkal](https://github.com/davkal) +- **Explore**: Use new TimePicker from Grafana/UI. [#17793](https://github.com/grafana/grafana/pull/17793), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: handle newlines in LogRow Highlighter. [#17425](https://github.com/grafana/grafana/pull/17425), [@rrfeng](https://github.com/rrfeng) +- **Graph**: Added new fill gradient option. [#17528](https://github.com/grafana/grafana/pull/17528), [@torkelo](https://github.com/torkelo) +- **GraphPanel**: Don't sort series when legend table & sort column is not visible . [#17095](https://github.com/grafana/grafana/pull/17095), [@shavonn](https://github.com/shavonn) +- **InfluxDB**: Support for visualizing logs in Explore. [#17450](https://github.com/grafana/grafana/pull/17450), [@hugohaggmark](https://github.com/hugohaggmark) +- **Logging**: Login and Logout actions (#17760). [#17883](https://github.com/grafana/grafana/pull/17883), [@ATTron](https://github.com/ATTron) +- **Logging**: Move log package to pkg/infra. [#17023](https://github.com/grafana/grafana/pull/17023), [@zhulongcheng](https://github.com/zhulongcheng) +- **Metrics**: Expose stats about roles as metrics. [#17469](https://github.com/grafana/grafana/pull/17469), [@bergquist](https://github.com/bergquist) +- **MySQL/Postgres/MSSQL**: Add parsing for day, weeks and year intervals in macros. [#13086](https://github.com/grafana/grafana/pull/13086), [@bernardd](https://github.com/bernardd) +- **MySQL**: Add support for periodically reloading client certs. [#14892](https://github.com/grafana/grafana/pull/14892), [@tpetr](https://github.com/tpetr) +- **Plugins**: replace dataFormats list with skipDataQuery flag in plugin.json. [#16984](https://github.com/grafana/grafana/pull/16984), [@ryantxu](https://github.com/ryantxu) +- **Prometheus**: Take timezone into account for step alignment. [#17477](https://github.com/grafana/grafana/pull/17477), [@fxmiii](https://github.com/fxmiii) +- **Prometheus**: Use overridden panel range for \$\_\_range instead of dashboard range. [#17352](https://github.com/grafana/grafana/pull/17352), [@patrick246](https://github.com/patrick246) +- **Prometheus**: added time range filter to series labels query. [#16851](https://github.com/grafana/grafana/pull/16851), [@FUSAKLA](https://github.com/FUSAKLA) +- **Provisioning**: Support folder that doesn't exist yet in dashboard provisioning. [#17407](https://github.com/grafana/grafana/pull/17407), [@Nexucis](https://github.com/Nexucis) +- **Refresh picker**: Handle empty intervals. [#17585](https://github.com/grafana/grafana/pull/17585), [@dehrax](https://github.com/dehrax) +- **Singlestat**: Add y min/max config to singlestat sparklines. [#17527](https://github.com/grafana/grafana/pull/17527), [@pitr](https://github.com/pitr) +- **Snapshot**: use given key and deleteKey. [#16876](https://github.com/grafana/grafana/pull/16876), [@zhulongcheng](https://github.com/zhulongcheng) +- **Templating**: Correctly display \_\_text in multi-value variable after page reload. [#17840](https://github.com/grafana/grafana/pull/17840), [@EduardSergeev](https://github.com/EduardSergeev) +- **Templating**: Support selecting all filtered values of a multi-value variable. [#16873](https://github.com/grafana/grafana/pull/16873), [@r66ad](https://github.com/r66ad) +- **Tracing**: allow propagation with Zipkin headers. [#17009](https://github.com/grafana/grafana/pull/17009), [@jrockway](https://github.com/jrockway) +- **Users**: Disable users removed from LDAP. [#16820](https://github.com/grafana/grafana/pull/16820), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **SAML**: Add SAML as an authentication option (Enterprise) + +### Bug Fixes + +- **AddPanel**: Fix issue when removing moved add panel widget . [#17659](https://github.com/grafana/grafana/pull/17659), [@dehrax](https://github.com/dehrax) +- **CLI**: Fix encrypt-datasource-passwords fails with sql error. [#18014](https://github.com/grafana/grafana/pull/18014), [@marefr](https://github.com/marefr) +- **Elasticsearch**: Fix default max concurrent shard requests. [#17770](https://github.com/grafana/grafana/pull/17770), [@marefr](https://github.com/marefr) +- **Explore**: Fix browsing back to dashboard panel. [#17061](https://github.com/grafana/grafana/pull/17061), [@jschill](https://github.com/jschill) +- **Explore**: Fix filter by series level in logs graph. [#17798](https://github.com/grafana/grafana/pull/17798), [@marefr](https://github.com/marefr) +- **Explore**: Fix issues when loading and both graph/table are collapsed. [#17113](https://github.com/grafana/grafana/pull/17113), [@marefr](https://github.com/marefr) +- **Explore**: Fix selection/copy of log lines. [#17121](https://github.com/grafana/grafana/pull/17121), [@marefr](https://github.com/marefr) +- **Fix**: Wrap value of multi variable in array when coming from URL. [#16992](https://github.com/grafana/grafana/pull/16992), [@aocenas](https://github.com/aocenas) +- **Frontend**: Fix for Json tree component not working. [#17608](https://github.com/grafana/grafana/pull/17608), [@srid12](https://github.com/srid12) +- **Graphite**: Fix for issue with alias function being moved last. [#17791](https://github.com/grafana/grafana/pull/17791), [@torkelo](https://github.com/torkelo) +- **Graphite**: Fixes issue with seriesByTag & function with variable param. [#17795](https://github.com/grafana/grafana/pull/17795), [@torkelo](https://github.com/torkelo) +- **Graphite**: use POST for /metrics/find requests. [#17814](https://github.com/grafana/grafana/pull/17814), [@papagian](https://github.com/papagian) +- **HTTP Server**: Serve Grafana with a custom URL path prefix. [#17048](https://github.com/grafana/grafana/pull/17048), [@jan25](https://github.com/jan25) +- **InfluxDB**: Fixes single quotes are not escaped in label value filters. [#17398](https://github.com/grafana/grafana/pull/17398), [@Panzki](https://github.com/Panzki) +- **Prometheus**: Correctly escape '|' literals in interpolated PromQL variables. [#16932](https://github.com/grafana/grafana/pull/16932), [@Limess](https://github.com/Limess) +- **Prometheus**: Fix when adding label for metrics which contains colons in Explore. [#16760](https://github.com/grafana/grafana/pull/16760), [@tolwi](https://github.com/tolwi) +- **SinglestatPanel**: Remove background color when value turns null. [#17552](https://github.com/grafana/grafana/pull/17552), [@druggieri](https://github.com/druggieri) + +# 6.2.5 (2019-06-25) + +### Features / Enhancements + +- **Grafana-CLI**: Wrapper for `grafana-cli` within RPM/DEB packages and config/homepath are now global flags. [#17695](https://github.com/grafana/grafana/pull/17695), [@gotjosh](https://github.com/gotjosh) +- **Panel**: Fully escape html in drilldown links (was only sanitized before) . [#17731](https://github.com/grafana/grafana/pull/17731), [@dehrax](https://github.com/dehrax) + +### Bug Fixes + +- **Config**: Fix connectionstring for remote_cache in defaults.ini. [#17675](https://github.com/grafana/grafana/pull/17675), [@kylebrandt](https://github.com/kylebrandt) +- **Elasticsearch**: Fix empty query (via template variable) should be sent as wildcard. [#17488](https://github.com/grafana/grafana/pull/17488), [@davewat](https://github.com/davewat) +- **HTTP-Server**: Fix Strict-Transport-Security header. [#17644](https://github.com/grafana/grafana/pull/17644), [@kylebrandt](https://github.com/kylebrandt) +- **TablePanel**: fix annotations display. [#17646](https://github.com/grafana/grafana/pull/17646), [@ryantxu](https://github.com/ryantxu) + +# 6.2.4 (2019-06-18) + +### Bug Fixes + +- **Grafana-CLI**: Fix receiving flags via command line . [#17617](https://github.com/grafana/grafana/pull/17617), [@gotjosh](https://github.com/gotjosh) +- **HTTPServer**: Fix X-XSS-Protection header formatting. [#17620](https://github.com/grafana/grafana/pull/17620), [@yverry](https://github.com/yverry) + +# 6.2.3 (2019-06-17) + +### Known issues + +- **grafana-cli**: The argument `--pluginsDir` is not working. +- **docker**: Due to above problem with grafana-cli the docker run will fail to start the container if you're installing plugins using the `GF_INSTALL_PLUGINS` environment variable. We have removed 6.2.3 tag from docker hub and latest tag now points to 6.2.2. + +More details in bug report: https://github.com/grafana/grafana/issues/17613 + +### Features / Enhancements + +- **AuthProxy**: Optimistic lock pattern for remote cache Set. [#17485](https://github.com/grafana/grafana/pull/17485), [@papagian](https://github.com/papagian) +- **HTTPServer**: Options for returning new headers X-Content-Type-Options, X-XSS-Protection and Strict-Transport-Security. [#17522](https://github.com/grafana/grafana/pull/17522), [@kylebrandt](https://github.com/kylebrandt) + +### Bug Fixes + +- **Auth Proxy**: Fix non-negative cache TTL. [#17495](https://github.com/grafana/grafana/pull/17495), [@kylebrandt](https://github.com/kylebrandt) +- **Grafana-CLI**: Fix receiving configuration flags from the command line. [#17606](https://github.com/grafana/grafana/pull/17606), [@gotjosh](https://github.com/gotjosh) +- **OAuth**: Fix for wrong user token updated on OAuth refresh in DS proxy. [#17541](https://github.com/grafana/grafana/pull/17541), [@redbaron](https://github.com/redbaron) +- **remote_cache**: Fix redis. [#17483](https://github.com/grafana/grafana/pull/17483), [@kylebrandt](https://github.com/kylebrandt) + +# 6.2.2 (2019-06-05) + +### Features / Enhancements + +- **Security**: Prevent CSV formula injection attack when exporting data. [#17363](https://github.com/grafana/grafana/pull/17363), [@DanCech](https://github.com/DanCech) + +### Bug Fixes + +- **CloudWatch**: Fixes error when hiding/disabling queries . [#17283](https://github.com/grafana/grafana/pull/17283), [@jpiccari](https://github.com/jpiccari) +- **Database**: Fixed slow permission query in folder/dashboard search. [#17427](https://github.com/grafana/grafana/pull/17427), [@aocenas](https://github.com/aocenas) +- **Explore**: Fixed updating time range before running queries. [#17349](https://github.com/grafana/grafana/pull/17349), [@marefr](https://github.com/marefr) +- **Plugins**: Fixed plugin config page navigation when using subpath. [#17364](https://github.com/grafana/grafana/pull/17364), [@torkelo](https://github.com/torkelo) + +# 6.2.1 (2019-05-27) + +### Features / Enhancements + +- **CLI**: Add command to migrate all data sources to use encrypted password fields . [#17118](https://github.com/grafana/grafana/pull/17118), [@aocenas](https://github.com/aocenas) +- **Gauge/BarGauge**: Improvements to auto value font size . [#17292](https://github.com/grafana/grafana/pull/17292), [@torkelo](https://github.com/torkelo) + +### Bug Fixes + +- **Auth Proxy**: Resolve database is locked errors. [#17274](https://github.com/grafana/grafana/pull/17274), [@marefr](https://github.com/marefr) +- **Database**: Retry transaction if sqlite returns database is locked error. [#17276](https://github.com/grafana/grafana/pull/17276), [@marefr](https://github.com/marefr) +- **Explore**: Fixes so clicking in a Prometheus Table the query is filtered by clicked value. [#17083](https://github.com/grafana/grafana/pull/17083), [@hugohaggmark](https://github.com/hugohaggmark) +- **Singlestat**: Fixes issue with value placement and line wraps. [#17249](https://github.com/grafana/grafana/pull/17249), [@torkelo](https://github.com/torkelo) +- **Tech**: Update jQuery to 3.4.1 to fix issue on iOS 10 based browsers as well as Chrome 53.x . [#17290](https://github.com/grafana/grafana/pull/17290), [@timbutler](https://github.com/timbutler) + +# 6.2.0 (2019-05-22) + +### Bug Fixes + +- **BarGauge**: Fix for negative min values. [#17192](https://github.com/grafana/grafana/pull/17192), [@torkelo](https://github.com/torkelo) +- **Gauge/BarGauge**: Fix for issues editing min & max options. [#17174](https://github.com/grafana/grafana/pull/17174) +- **Search**: Make only folder name only open search with current folder filter. [#17226](https://github.com/grafana/grafana/pull/17226) +- **AzureMonitor**: Revert to clearing chained dropdowns. [#17212](https://github.com/grafana/grafana/pull/17212) + +### Breaking Changes + +- **Plugins**: Data source plugins that process hidden queries need to add a "hiddenQueries: true" attribute in plugin.json. [#17124](https://github.com/grafana/grafana/pull/17124), [@ryantxu](https://github.com/ryantxu) + +### Removal of old deprecated package repository + +5 months ago we deprecated our old package cloud repository and [replaced it](https://grafana.com/blog/2019/01/05/moving-to-packages.grafana.com/) with our own. We will remove the old depreciated +repo on July 1st. Make sure you have switched to the new repo by then. The new repository has all our old releases so you are not required to upgrade just to switch package repository. + +# 6.2.0-beta2 (2019-05-15) + +### Features / Enhancements + +- **Plugins**: Support templated urls in plugin routes. [#16599](https://github.com/grafana/grafana/pull/16599), [@briangann](https://github.com/briangann) +- **Packaging**: New MSI windows installer package\*\*. [#17073](https://github.com/grafana/grafana/pull/17073), [@briangann](https://github.com/briangann) + +### Bug Fixes + +- **Dashboard**: Fixes blank dashboard after window resize with panel without title. [#16942](https://github.com/grafana/grafana/pull/16942), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Fixes lazy loading & expanding collapsed rows on mobile. [#17055](https://github.com/grafana/grafana/pull/17055), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Fixes scrolling issues for Edge browser. [#17033](https://github.com/grafana/grafana/pull/17033), [@jschill](https://github.com/jschill) +- **Dashboard**: Show refresh button in first kiosk(tv) mode. [#17032](https://github.com/grafana/grafana/pull/17032), [@torkelo](https://github.com/torkelo) +- **Explore**: Fix empty result from data source should render logs container. [#16999](https://github.com/grafana/grafana/pull/16999), [@marefr](https://github.com/marefr) +- **Explore**: Fixes so clicking in a Prometheus Table the query is filtered by clicked value. [#17083](https://github.com/grafana/grafana/pull/17083), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: Makes it possible to zoom in Explore/Loki/Graph without exception. [#16991](https://github.com/grafana/grafana/pull/16991), [@hugohaggmark](https://github.com/hugohaggmark) +- **Gauge**: Fixes orientation issue after switching from BarGauge to Gauge. [#17064](https://github.com/grafana/grafana/pull/17064), [@torkelo](https://github.com/torkelo) +- **GettingStarted**: Fixes layout issues in getting started panel. [#16941](https://github.com/grafana/grafana/pull/16941), [@torkelo](https://github.com/torkelo) +- **InfluxDB**: Fix HTTP method should default to GET. [#16949](https://github.com/grafana/grafana/pull/16949), [@StephenSorriaux](https://github.com/StephenSorriaux) +- **Panels**: Fixed alert icon position in panel header. [#17070](https://github.com/grafana/grafana/pull/17070), [@torkelo](https://github.com/torkelo) +- **Panels**: Fixes panel error tooltip not showing. [#16993](https://github.com/grafana/grafana/pull/16993), [@torkelo](https://github.com/torkelo) +- **Plugins**: Fix how datemath utils are exposed to plugins. [#16976](https://github.com/grafana/grafana/pull/16976), [@marefr](https://github.com/marefr) +- **Singlestat**: fixed centering issue for very small panels. [#16944](https://github.com/grafana/grafana/pull/16944), [@torkelo](https://github.com/torkelo) +- **Search**: Scroll issue in dashboard search in latest Chrome. [#17054](https://github.com/grafana/grafana/pull/17054), [@jschill](https://github.com/jschill) +- **Docker**: Prevent a permission denied error when writing files to the default provisioning directory. [#16831](https://github.com/grafana/grafana/pull/16831), [@wmedlar](https://github.com/wmedlar) +- **Gauge**: Adds background shade to gauge track and improves height usage. [#17019](https://github.com/grafana/grafana/pull/17019), [@torkelo](https://github.com/torkelo) +- **RemoteCache**: Avoid race condition in Set causing error on insert. . [#17082](https://github.com/grafana/grafana/pull/17082), [@bergquist](https://github.com/bergquist) + +# 6.2.0-beta1 (2019-05-07) + +### Features / Enhancements + +- **Admin**: Add more stats about roles. [#16667](https://github.com/grafana/grafana/pull/16667), [@bergquist](https://github.com/bergquist) +- **Alert list panel**: Support variables in filters. [#16892](https://github.com/grafana/grafana/pull/16892), [@psschand](https://github.com/psschand) +- **Alerting**: Adjust label for send on all alerts to default . [#16554](https://github.com/grafana/grafana/pull/16554), [@simPod](https://github.com/simPod) +- **Alerting**: Makes timeouts and retries configurable. [#16259](https://github.com/grafana/grafana/pull/16259), [@kobehaha](https://github.com/kobehaha) +- **Alerting**: No notification when going from no data to pending. [#16905](https://github.com/grafana/grafana/pull/16905), [@bergquist](https://github.com/bergquist) +- **Alerting**: Pushover alert, support for different sound for OK. [#16525](https://github.com/grafana/grafana/pull/16525), [@Hofls](https://github.com/Hofls) +- **Auth**: Enable retries and transaction for some db calls for auth tokens . [#16785](https://github.com/grafana/grafana/pull/16785), [@bergquist](https://github.com/bergquist) +- **AzureMonitor**: Adds support for multiple subscriptions per data source. [#16922](https://github.com/grafana/grafana/pull/16922), [@daniellee](https://github.com/daniellee) +- **Bar Gauge**: New multi series enabled gauge like panel with horizontal and vertical layouts and 3 display modes. [#16918](https://github.com/grafana/grafana/pull/16918), [@torkelo](https://github.com/torkelo) +- **Build**: Upgrades to golang 1.12.4. [#16545](https://github.com/grafana/grafana/pull/16545), [@bergquist](https://github.com/bergquist) +- **CloudWatch**: Update AWS/IoT metric and dimensions. [#16337](https://github.com/grafana/grafana/pull/16337), [@nonamef](https://github.com/nonamef) +- **Config**: Show user-friendly error message instead of stack trace. [#16564](https://github.com/grafana/grafana/pull/16564), [@Hofls](https://github.com/Hofls) +- **Dashboard**: Enable filtering dashboards in search by current folder. [#16790](https://github.com/grafana/grafana/pull/16790), [@dprokop](https://github.com/dprokop) +- **Dashboard**: Lazy load out of view panels . [#15554](https://github.com/grafana/grafana/pull/15554), [@ryantxu](https://github.com/ryantxu) +- **DataProxy**: Restore Set-Cookie header after proxy request. [#16838](https://github.com/grafana/grafana/pull/16838), [@marefr](https://github.com/marefr) +- **Data Sources**: Add pattern validation for time input on data source config pages. [#16837](https://github.com/grafana/grafana/pull/16837), [@aocenas](https://github.com/aocenas) +- **Elasticsearch**: Add 7.x version support. [#16646](https://github.com/grafana/grafana/pull/16646), [@alcidesv](https://github.com/alcidesv) +- **Explore**: Adds reconnect for failing data source. [#16226](https://github.com/grafana/grafana/pull/16226), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: Support user timezone. [#16469](https://github.com/grafana/grafana/pull/16469), [@marefr](https://github.com/marefr) +- **InfluxDB**: Add support for POST HTTP verb. [#16690](https://github.com/grafana/grafana/pull/16690), [@StephenSorriaux](https://github.com/StephenSorriaux) +- **Loki**: Search is now case insensitive. [#15948](https://github.com/grafana/grafana/pull/15948), [@steven-sheehy](https://github.com/steven-sheehy) +- **OAuth**: Update jwt regexp to include `=`. [#16521](https://github.com/grafana/grafana/pull/16521), [@DanCech](https://github.com/DanCech) +- **Panels**: No title will no longer make panel header take up space. [#16884](https://github.com/grafana/grafana/pull/16884), [@torkelo](https://github.com/torkelo) +- **Prometheus**: Adds tracing headers for Prometheus datasource. [#16724](https://github.com/grafana/grafana/pull/16724), [@svagner](https://github.com/svagner) +- **Provisioning**: Add API endpoint to reload provisioning configs. [#16579](https://github.com/grafana/grafana/pull/16579), [@aocenas](https://github.com/aocenas) +- **Provisioning**: Do not allow deletion of provisioned dashboards. [#16211](https://github.com/grafana/grafana/pull/16211), [@aocenas](https://github.com/aocenas) +- **Provisioning**: Interpolate env vars in provisioning files. [#16499](https://github.com/grafana/grafana/pull/16499), [@aocenas](https://github.com/aocenas) +- **Provisioning**: Support FolderUid in Dashboard Provisioning Config. [#16559](https://github.com/grafana/grafana/pull/16559), [@swtch1](https://github.com/swtch1) +- **Security**: Add new setting allow_embedding. [#16853](https://github.com/grafana/grafana/pull/16853), [@marefr](https://github.com/marefr) +- **Security**: Store data source passwords encrypted in secureJsonData. [#16175](https://github.com/grafana/grafana/pull/16175), [@aocenas](https://github.com/aocenas) +- **UX**: Improve Grafana usage for smaller screens. [#16783](https://github.com/grafana/grafana/pull/16783), [@torkelo](https://github.com/torkelo) +- **Units**: Add angle units, Arc Minutes and Seconds. [#16271](https://github.com/grafana/grafana/pull/16271), [@Dripoul](https://github.com/Dripoul) + +### Bug Fixes + +- **Build**: Fix bug where grafana didn't start after mysql on rpm packages. [#16917](https://github.com/grafana/grafana/pull/16917), [@bergquist](https://github.com/bergquist) +- **CloudWatch**: Fixes query order not affecting series ordering & color. [#16408](https://github.com/grafana/grafana/pull/16408), [@mtanda](https://github.com/mtanda) +- **CloudWatch**: Use default alias if there is no alias for metrics. [#16732](https://github.com/grafana/grafana/pull/16732), [@utkarshcmu](https://github.com/utkarshcmu) +- **Config**: Fixes bug where timeouts for alerting was not parsed correctly. [#16784](https://github.com/grafana/grafana/pull/16784), [@aocenas](https://github.com/aocenas) +- **Elasticsearch**: Fix view percentiles metric in table without date histogram. [#15686](https://github.com/grafana/grafana/pull/15686), [@Igor-Ratsuk](https://github.com/Igor-Ratsuk) +- **Explore**: Prevents histogram loading from killing Prometheus instance. [#16768](https://github.com/grafana/grafana/pull/16768), [@hugohaggmark](https://github.com/hugohaggmark) +- **Graph**: Allow override decimals to fully override. [#16414](https://github.com/grafana/grafana/pull/16414), [@torkelo](https://github.com/torkelo) +- **Mixed Data Source**: Fix error when one query is disabled. [#16409](https://github.com/grafana/grafana/pull/16409), [@marefr](https://github.com/marefr) +- **Search**: Fixes search limits and adds a page parameter. [#16458](https://github.com/grafana/grafana/pull/16458), [@torkelo](https://github.com/torkelo) +- **Security**: Responses from backend should not be cached. [#16848](https://github.com/grafana/grafana/pull/16848), [@marefr](https://github.com/marefr) + +### Breaking changes + +- **Gauge Panel**: The suffix / prefix options have been removed from the new Gauge Panel (introduced in v6.0). [#16870](https://github.com/grafana/grafana/issues/16870). + +# 6.1.6 (2019-04-29) + +### Features / Enhancements + +- **Security**: Bump jQuery to 3.4.0 . [#16761](https://github.com/grafana/grafana/pull/16761), [@dprokop](https://github.com/dprokop) + +### Bug Fixes + +- **Playlist**: Fix loading dashboards by tag. [#16727](https://github.com/grafana/grafana/pull/16727), [@marefr](https://github.com/marefr) + +# 6.1.5 (2019-04-29) + +- **Security**: Urgent security patch release. Please read more in our [blog](https://grafana.com/blog/2019/04/29/grafana-5.4.4-and-6.1.6-released-with-important-security-fix/) + +# 6.1.4 (2019-04-16) + +### Bug Fixes + +- **DataPanel**: Added missing built-in interval variables to scopedVars. [#16556](https://github.com/grafana/grafana/pull/16556), [@torkelo](https://github.com/torkelo) +- **Explore**: Adds maxDataPoints to data source query options . [#16513](https://github.com/grafana/grafana/pull/16513), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: Fixes so intervals are recalculated on run query. [#16510](https://github.com/grafana/grafana/pull/16510), [@hugohaggmark](https://github.com/hugohaggmark) +- **Heatmap**: Fix for empty graph when panel is too narrow (#16378). [#16460](https://github.com/grafana/grafana/pull/16460), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **Heatmap**: Fixed auto decimals when bucket name is not number. [#16609](https://github.com/grafana/grafana/pull/16609), [@torkelo](https://github.com/torkelo) +- **QueryInspector**: Now shows error responses again. [#16514](https://github.com/grafana/grafana/pull/16514), [@torkelo](https://github.com/torkelo) + +# 6.1.3 (2019-04-09) + +### Bug Fixes + +- **Graph**: Fixed auto decimals in legend values for some units like `ms` and `s`. [#16455](https://github.com/grafana/grafana/pull/16455), [@torkelo](https://github.com/torkelo) +- **Graph**: Fixed png rendering with legend to the right. [#16463](https://github.com/grafana/grafana/pull/16463), [@torkelo](https://github.com/torkelo) +- **Singlestat**: Use decimals when manually specified. [#16451](https://github.com/grafana/grafana/pull/16451), [@torkelo](https://github.com/torkelo) +- **UI Switch**: Fix broken UI switches. Fixes Default Data Source switch, Explore Logs switches, Gauge option switches. [#16303](https://github.com/grafana/grafana/pull/16303), [@dprokop](https://github.com/dprokop) + +# 6.1.2 (2019-04-08) + +### Bug Fixes + +- **Graph**: Fixed series legend color for hidden series. [#16438](https://github.com/grafana/grafana/pull/16438), [@Ijin08](https://github.com/Ijin08) +- **Graph**: Fixed tooltip highlight on white theme. [#16429](https://github.com/grafana/grafana/pull/16429), [@torkelo](https://github.com/torkelo) +- **Styles**: Fixed menu hover highlight border. [#16431](https://github.com/grafana/grafana/pull/16431), [@torkelo](https://github.com/torkelo) +- **Singlestat Panel**: Correctly use the override decimals. [#16413](https://github.com/grafana/grafana/pull/16413), [@torkelo](https://github.com/torkelo) + +# 6.1.1 (2019-04-05) + +### Bug Fixes + +- **Alerting**: Notification channel http api fixes. [#16379](https://github.com/grafana/grafana/pull/16379), [@marefr](https://github.com/marefr) +- **Graphite**: Editing graphite query function now works again. [#16390](https://github.com/grafana/grafana/pull/16390), [@torkelo](https://github.com/torkelo) +- **Playlist**: Kiosk & auto fit panels modes are working normally again . [#16403](https://github.com/grafana/grafana/pull/16403), [@torkelo](https://github.com/torkelo) +- **QueryEditors**: Toggle edit mode now always work on slower computers. [#16394](https://github.com/grafana/grafana/pull/16394), [@seanlaff](https://github.com/seanlaff) + +# 6.1.0 (2019-04-03) + +### Bug Fixes + +- **CloudWatch**: Fix for dimension value list when changing dimension key. [#16356](https://github.com/grafana/grafana/pull/16356), [@mtanda](https://github.com/mtanda) +- **Graphite**: Editing function arguments now works again. [#16297](https://github.com/grafana/grafana/pull/16297), [@torkelo](https://github.com/torkelo) +- **InfluxDB**: Fix tag names with periods in alert evaluation. [#16255](https://github.com/grafana/grafana/pull/16255), [@floyd-may](https://github.com/floyd-may) +- **PngRendering**: Fix for panel height & title centering . [#16351](https://github.com/grafana/grafana/pull/16351), [@torkelo](https://github.com/torkelo) +- **Templating**: Fix for editing query variables. [#16299](https://github.com/grafana/grafana/pull/16299), [@torkelo](https://github.com/torkelo) + +# 6.1.0-beta1 (2019-03-27) + +### New Features + +- **Prometheus**: adhoc filter support [#8253](https://github.com/grafana/grafana/issues/8253), thx [@mtanda](https://github.com/mtanda) +- **Permissions**: Editors can become admin for dashboards, folders and teams they create. [#15977](https://github.com/grafana/grafana/pull/15977), [@xlson](https://github.com/xlson) + +### Minor + +- **Auth**: Support listing and revoking auth tokens via API [#15836](https://github.com/grafana/grafana/issues/15836) +- **Alerting**: DingDing notification channel now includes alert values. [#13825](https://github.com/grafana/grafana/pull/13825), [@athurg](https://github.com/athurg) +- **Alerting**: Notification channel http api enhancements. [#16219](https://github.com/grafana/grafana/pull/16219), [@marefr](https://github.com/marefr) +- **CloudWatch**: Update metrics/dimensions list. [#16137](https://github.com/grafana/grafana/pull/16137), [@mtanda](https://github.com/mtanda) +- **Cloudwatch**: Add AWS RDS MaximumUsedTransactionIDs metric [#15077](https://github.com/grafana/grafana/pull/15077), thx [@activeshadow](https://github.com/activeshadow) +- **Cache**: Adds support for using out of proc caching in the backend [#10816](https://github.com/grafana/grafana/issues/10816) +- **Dashboard**: New keyboard shortcut `d l` toggles all Graph legends in a dashboard. [#15770](https://github.com/grafana/grafana/pull/15770), [@jsferrei](https://github.com/jsferrei) +- **Data Source**: Only log connection string in dev environment [#16001](https://github.com/grafana/grafana/issues/16001) +- **DataProxy**: Add custom header (X-Grafana-User) to data source requests with the current username. [#15998](https://github.com/grafana/grafana/pull/15998), [@aocenas](https://github.com/aocenas) +- **DataProxy**: Make it possible to add user details to requests sent to the dataproxy [#6359](https://github.com/grafana/grafana/issues/6359) and [#15931](https://github.com/grafana/grafana/issues/15931) +- **DataProxy**: Adds oauth pass-through option for data sources. [#15205](https://github.com/grafana/grafana/pull/15205), [@seanlaff](https://github.com/seanlaff) +- **Explore**: Hide empty duplicates column in logs viewer. [#15982](https://github.com/grafana/grafana/pull/15982), [@steven-sheehy](https://github.com/steven-sheehy) +- **Explore**: Make it possible to close left pane of split view. [#16155](https://github.com/grafana/grafana/pull/16155), [@dprokop](https://github.com/dprokop) +- **Explore**: Move back / forward with browser buttons now works. [#16150](https://github.com/grafana/grafana/pull/16150), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: Update Loki labels when label selector is opened. [#16131](https://github.com/grafana/grafana/pull/16131), [@dprokop](https://github.com/dprokop) +- **Graph Panel**: New options for X-axis Min & Max (for histograms). [#14877](https://github.com/grafana/grafana/pull/14877), [@papagian](https://github.com/papagian) +- **Heatmap**: You can now choose to hide buckets with zero value. [#15934](https://github.com/grafana/grafana/pull/15934), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **Heatmap**: `Middle` bucket bound option [#15683](https://github.com/grafana/grafana/issues/15683) +- **Heatmap**: `Reverse order` option for changing order of buckets [#15683](https://github.com/grafana/grafana/issues/15683) +- **Prometheus**: Change alignment of range queries to end before now and not in future. [#16110](https://github.com/grafana/grafana/pull/16110), [@davkal](https://github.com/davkal) +- **Prometheus**: Dedup annotations events with same timestamp . [#16152](https://github.com/grafana/grafana/pull/16152), [@torkelo](https://github.com/torkelo) +- **SQL**: Use default min interval of 1m for all SQL data sources. [#15799](https://github.com/grafana/grafana/pull/15799), [@marefr](https://github.com/marefr) +- **TablePanel**: Column color style now works even after removing columns. [#16227](https://github.com/grafana/grafana/pull/16227), [@torkelo](https://github.com/torkelo) +- **Templating**: Custom variable value now escapes all backslashes properly. [#15980](https://github.com/grafana/grafana/pull/15980), [@srid12](https://github.com/srid12) +- **Templating**: Data source variable now supports multi-value for uses cases that involve repeating panels & rows. [#15914](https://github.com/grafana/grafana/pull/15914), [@torkelo](https://github.com/torkelo) +- **VictorOps**: Adds more information to the victor ops notifiers [#15744](https://github.com/grafana/grafana/issues/15744), thx [@zhulongcheng](https://github.com/zhulongcheng) + +### Bug Fixes + +- **Alerting**: Don't include non-existing image in MS Teams notifications. [#16116](https://github.com/grafana/grafana/pull/16116), [@SGI495](https://github.com/SGI495) +- **Api**: Invalid org invite code [#10506](https://github.com/grafana/grafana/issues/10506) +- **Annotations**: Fix for native annotations filtered by template variable with pipe. [#15515](https://github.com/grafana/grafana/pull/15515), [@marefr](https://github.com/marefr) +- **Dashboard**: Fix for time regions spanning across midnight. [#16201](https://github.com/grafana/grafana/pull/16201), [@marefr](https://github.com/marefr) +- **Data Source**: Handles nil jsondata field gracefully [#14239](https://github.com/grafana/grafana/issues/14239) +- **Data Source**: Empty user/password was not updated when updating data sources [#15608](https://github.com/grafana/grafana/pull/15608), thx [@Maddin-619](https://github.com/Maddin-619) +- **Elasticsearch**: Fixes using template variables in the alias field. [#16229](https://github.com/grafana/grafana/pull/16229), [@daniellee](https://github.com/daniellee) +- **Elasticsearch**: Fix incorrect index pattern padding in alerting queries. [#15892](https://github.com/grafana/grafana/pull/15892), [@sandlis](https://github.com/sandlis) +- **Explore**: Fix for Prometheus autocomplete not working in Firefox. [#16192](https://github.com/grafana/grafana/pull/16192), [@hugohaggmark](https://github.com/hugohaggmark) +- **Explore**: Fix for url does not keep query after browser refresh. [#16189](https://github.com/grafana/grafana/pull/16189), [@hugohaggmark](https://github.com/hugohaggmark) +- **Gauge**: Interpolate scoped variables in repeated gauges [#15739](https://github.com/grafana/grafana/issues/15739) +- **Graphite**: Fixed issue with using series ref and series by tag. [#16111](https://github.com/grafana/grafana/pull/16111), [@torkelo](https://github.com/torkelo) +- **Graphite**: Fixed variable quoting when variable value is numeric. [#16149](https://github.com/grafana/grafana/pull/16149), [@torkelo](https://github.com/torkelo) +- **Heatmap**: Fixes Y-axis tick labels being in wrong order for some Prometheus queries. [#15932](https://github.com/grafana/grafana/pull/15932), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **Heatmap**: Negative values are now displayed correctly in graph & legend. [#15953](https://github.com/grafana/grafana/pull/15953), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **Heatmap**: legend shows wrong colors for small values [#14019](https://github.com/grafana/grafana/issues/14019) +- **InfluxDB**: Always close request body even for error status codes. [#16207](https://github.com/grafana/grafana/pull/16207), [@ramongtx](https://github.com/ramongtx) +- **ManageDashboards**: Fix for checkboxes not appearing properly Firefox . [#15981](https://github.com/grafana/grafana/pull/15981), [@srid12](https://github.com/srid12) +- **Playlist**: Leaving playlist now always stops playlist . [#15791](https://github.com/grafana/grafana/pull/15791), [@peterholmberg](https://github.com/peterholmberg) +- **Prometheus**: fixes regex ad-hoc filters variables with wildcards. [#16234](https://github.com/grafana/grafana/pull/16234), [@daniellee](https://github.com/daniellee) +- **TablePanel**: Column color style now works even after removing columns. [#16227](https://github.com/grafana/grafana/pull/16227), [@torkelo](https://github.com/torkelo) +- **TablePanel**: Fix for white text on white background when value is null. [#16199](https://github.com/grafana/grafana/pull/16199), [@peterholmberg](https://github.com/peterholmberg) + +# 6.0.2 (2019-03-19) + +### Bug Fixes + +- **Alerting**: Fixed issue with AlertList panel links resulting in panel not found errors. [#15975](https://github.com/grafana/grafana/pull/15975), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Improved error handling when rendering dashboard panels. [#15970](https://github.com/grafana/grafana/pull/15970), [@torkelo](https://github.com/torkelo) +- **LDAP**: Fix allow anonymous server bind for ldap search. [#15872](https://github.com/grafana/grafana/pull/15872), [@marefr](https://github.com/marefr) +- **Discord**: Fix discord notifier so it doesn't crash when there are no image generated. [#15833](https://github.com/grafana/grafana/pull/15833), [@marefr](https://github.com/marefr) +- **Panel Edit**: Prevent search in VizPicker from stealing focus. [#15802](https://github.com/grafana/grafana/pull/15802), [@peterholmberg](https://github.com/peterholmberg) +- **Data Source admin**: Fixed url of back button in data source edit page, when root_url configured. [#15759](https://github.com/grafana/grafana/pull/15759), [@dprokop](https://github.com/dprokop) + +# 6.0.1 (2019-03-06) + +### Bug Fixes + +- **Metrics**: Fixes broken usagestats metrics for /metrics [#15651](https://github.com/grafana/grafana/issues/15651) +- **Dashboard**: Fixes kiosk mode should have &kiosk appended to the url [#15765](https://github.com/grafana/grafana/issues/15765) +- **Dashboard**: Fixes kiosk=tv mode with autofitpanels should respect header [#15650](https://github.com/grafana/grafana/issues/15650) +- **Image rendering**: Fixed image rendering issue for dashboards with auto refresh, . [#15818](https://github.com/grafana/grafana/pull/15818), [@torkelo](https://github.com/torkelo) +- **Dashboard**: Fix only users that can edit a dashboard should be able to update panel json. [#15805](https://github.com/grafana/grafana/pull/15805), [@marefr](https://github.com/marefr) +- **LDAP**: fix allow anonymous initial bind for ldap search. [#15803](https://github.com/grafana/grafana/pull/15803), [@marefr](https://github.com/marefr) +- **UX**: Fixed scrollbar not visible initially (only after manual scroll). [#15798](https://github.com/grafana/grafana/pull/15798), [@torkelo](https://github.com/torkelo) +- **Data Source admin** TestData [#15793](https://github.com/grafana/grafana/pull/15793), [@hugohaggmark](https://github.com/hugohaggmark) +- **Dashboard**: Fixed scrolling issue that caused scroll to be locked to bottom. [#15792](https://github.com/grafana/grafana/pull/15792), [@torkelo](https://github.com/torkelo) +- **Explore**: Viewers with viewers_can_edit should be able to access /explore. [#15787](https://github.com/grafana/grafana/pull/15787), [@jschill](https://github.com/jschill) +- **Security** fix: limit access to org admin and alerting pages. [#15761](https://github.com/grafana/grafana/pull/15761), [@marefr](https://github.com/marefr) +- **Panel Edit** minInterval changes did not persist [#15757](https://github.com/grafana/grafana/pull/15757), [@hugohaggmark](https://github.com/hugohaggmark) +- **Teams**: Fixed bug when getting teams for user. [#15595](https://github.com/grafana/grafana/pull/15595), [@hugohaggmark](https://github.com/hugohaggmark) +- **Stackdriver**: fix for float64 bounds for distribution metrics [#14509](https://github.com/grafana/grafana/issues/14509) +- **Stackdriver**: no reducers available for distribution type [#15179](https://github.com/grafana/grafana/issues/15179) + +# 6.0.0 stable (2019-02-25) + +### Bug Fixes + +- **Dashboard**: fixes click after scroll in series override menu [#15621](https://github.com/grafana/grafana/issues/15621) +- **MySQL**: fix mysql query using \_interval_ms variable throws error [#14507](https://github.com/grafana/grafana/issues/14507) + +# 6.0.0-beta3 (2019-02-19) + +### Minor + +- **CLI**: Grafana CLI should preserve permissions for backend binaries for Linux and Darwin [#15500](https://github.com/grafana/grafana/issues/15500) +- **Alerting**: Allow image rendering 90 percent of alertTimeout [#15395](https://github.com/grafana/grafana/pull/15395) + +### Bug fixes + +- **Influxdb**: Add support for alerting on InfluxDB queries that use the non_negative_difference function [#15415](https://github.com/grafana/grafana/issues/15415), thx [@kiran3394](https://github.com/kiran3394) +- **Alerting**: Fix percent_diff calculation when points are nulls [#15443](https://github.com/grafana/grafana/issues/15443), thx [@max-neverov](https://github.com/max-neverov) +- **Alerting**: Fixed handling of alert urls with true flags [#15454](https://github.com/grafana/grafana/issues/15454) + +# 6.0.0-beta2 (2019-02-11) + +### New Features + +- **AzureMonitor**: Enable alerting by converting Azure Monitor API to Go [#14623](https://github.com/grafana/grafana/issues/14623) + +### Minor + +- **Alerting**: Adds support for images in pushover notifier [#10780](https://github.com/grafana/grafana/issues/10780), thx [@jpenalbae](https://github.com/jpenalbae) +- **Graphite/InfluxDB/OpenTSDB**: Fix always take dashboard timezone into consideration when handle custom time ranges [#15284](https://github.com/grafana/grafana/issues/15284) +- **Stackdriver**: Template variables in filters using globbing format [#15182](https://github.com/grafana/grafana/issues/15182) +- **Cloudwatch**: Add `resource_arns` template variable query function [#8207](https://github.com/grafana/grafana/issues/8207), thx [@jeroenvollenbrock](https://github.com/jeroenvollenbrock) +- **Cloudwatch**: Add AWS/Neptune metrics [#14231](https://github.com/grafana/grafana/issues/14231), thx [@tcpatterson](https://github.com/tcpatterson) +- **Cloudwatch**: Add AWS/EC2/API metrics [#14233](https://github.com/grafana/grafana/issues/14233), thx [@tcpatterson](https://github.com/tcpatterson) +- **Cloudwatch**: Add AWS RDS ServerlessDatabaseCapacity metric [#15265](https://github.com/grafana/grafana/pull/15265), thx [@larsjoergensen](https://github.com/larsjoergensen) +- **MySQL**: Adds data source SSL CA/client certificates support [#8570](https://github.com/grafana/grafana/issues/8570), thx [@bugficks](https://github.com/bugficks) +- **MSSQL**: Timerange are now passed for template variable queries [#13324](https://github.com/grafana/grafana/issues/13324), thx [@thatsparesh](https://github.com/thatsparesh) +- **Annotations**: Support PATCH verb in annotations http api [#12546](https://github.com/grafana/grafana/issues/12546), thx [@SamuelToh](https://github.com/SamuelToh) +- **Templating**: Add json formatting to variable interpolation [#15291](https://github.com/grafana/grafana/issues/15291), thx [@mtanda](https://github.com/mtanda) +- **Login**: Anonymous usage stats for token auth [#15288](https://github.com/grafana/grafana/issues/15288) +- **AzureMonitor**: improve autocomplete for Log Analytics and App Insights editor [#15131](https://github.com/grafana/grafana/issues/15131) +- **LDAP**: Fix IPA/FreeIPA v4.6.4 does not allow LDAP searches with empty attributes [#14432](https://github.com/grafana/grafana/issues/14432) +- **Provisioning**: Allow testing data sources that were added by config [#12164](https://github.com/grafana/grafana/issues/12164) +- **Security**: Fix CSRF Token validation for POSTs [#1441](https://github.com/grafana/grafana/issues/1441) + +### Breaking changes + +- **Internal Metrics** Edition has been added to the build_info metric. This will break any Graphite queries using this metric. Edition will be a new label for the Prometheus metric. [#15363](https://github.com/grafana/grafana/pull/15363) + +### Bug fixes + +- **Gauge**: Fix issue with gauge requests being cancelled [#15366](https://github.com/grafana/grafana/issues/15366) +- **Gauge**: Accept decimal inputs for thresholds [#15372](https://github.com/grafana/grafana/issues/15372) +- **UI**: Fix error caused by named colors that are not part of named colors palette [#15373](https://github.com/grafana/grafana/issues/15373) +- **Search**: Bug pressing special regexp chars in input fields [#12972](https://github.com/grafana/grafana/issues/12972) +- **Permissions**: No need to have edit permissions to be able to "Save as" [#13066](https://github.com/grafana/grafana/issues/13066) + +# 6.0.0-beta1 (2019-01-30) + +### New Features + +- **Alerting**: Adds support for Google Hangouts Chat notifications [#11221](https://github.com/grafana/grafana/issues/11221), thx [@PatrickSchuster](https://github.com/PatrickSchuster) +- **Elasticsearch**: Support bucket script pipeline aggregations [#5968](https://github.com/grafana/grafana/issues/5968) +- **Influxdb**: Add support for time zone (`tz`) clause [#10322](https://github.com/grafana/grafana/issues/10322), thx [@cykl](https://github.com/cykl) +- **Snapshots**: Enable deletion of public snapshot [#14109](https://github.com/grafana/grafana/issues/14109) +- **Provisioning**: Provisioning support for alert notifiers [#10487](https://github.com/grafana/grafana/issues/10487), thx [@pbakulev](https://github.com/pbakulev) +- **Explore**: A whole new way to do ad-hoc metric queries and exploration. Split view in half and compare metrics & logs and much much more. [Read more here](http://docs.grafana.org/features/explore/) +- **Auth**: Replace remember me cookie solution for Grafana's builtin, LDAP and OAuth authentication with a solution based on short-lived tokens [#15303](https://github.com/grafana/grafana/issues/15303) + +### Minor + +- **Templating**: Built in time range variables `$__from` and `$__to`, [#1909](https://github.com/grafana/grafana/issues/1909) +- **Alerting**: Use separate timeouts for alert evals and notifications [#14701](https://github.com/grafana/grafana/issues/14701), thx [@sharkpc0813](https://github.com/sharkpc0813) +- **Elasticsearch**: Add support for offset in date histogram aggregation [#12653](https://github.com/grafana/grafana/issues/12653), thx [@mattiarossi](https://github.com/mattiarossi) +- **Elasticsearch**: Add support for moving average and derivative using doc count (metric count) [#8843](https://github.com/grafana/grafana/issues/8843) [#11175](https://github.com/grafana/grafana/issues/11175) +- **Elasticsearch**: Add support for template variable interpolation in alias field [#4075](https://github.com/grafana/grafana/issues/4075), thx [@SamuelToh](https://github.com/SamuelToh) +- **Influxdb**: Fix autocomplete of measurements does not escape search string properly [#11503](https://github.com/grafana/grafana/issues/11503), thx [@SamuelToh](https://github.com/SamuelToh) +- **Stackdriver**: Aggregating series returns more than one series [#14581](https://github.com/grafana/grafana/issues/14581) and [#13914](https://github.com/grafana/grafana/issues/13914), thx [@kinok](https://github.com/kinok) +- **Cloudwatch**: Fix Assume Role Arn [#14722](https://github.com/grafana/grafana/issues/14722), thx [@jaken551](https://github.com/jaken551) +- **Postgres/MySQL/MSSQL**: Nanosecond timestamp support (`$__unixEpochNanoFilter`, `$__unixEpochNanoFrom`, `$__unixEpochNanoTo`) [#14711](https://github.com/grafana/grafana/pull/14711), thx [@ander26](https://github.com/ander26) +- **Provisioning**: Fixes bug causing infinite growth in dashboard_version table. [#12864](https://github.com/grafana/grafana/issues/12864) +- **Auth**: Prevent password reset when login form is disabled or either LDAP or Auth Proxy is enabled [#14246](https://github.com/grafana/grafana/issues/14246), thx [@SilverFire](https://github.com/SilverFire) +- **Admin**: Fix prevent removing last grafana admin permissions [#11067](https://github.com/grafana/grafana/issues/11067), thx [@danielbh](https://github.com/danielbh) +- **Admin**: When multiple user invitations, all links are the same as the first user who was invited [#14483](https://github.com/grafana/grafana/issues/14483) +- **LDAP**: Upgrade go-ldap to v3 [#14548](https://github.com/grafana/grafana/issues/14548) +- **OAuth**: Support OAuth providers that are not RFC6749 compliant [#14562](https://github.com/grafana/grafana/issues/14562), thx [@tdabasinskas](https://github.com/tdabasinskas) +- **Proxy whitelist**: Add CIDR capability to auth_proxy whitelist [#14546](https://github.com/grafana/grafana/issues/14546), thx [@jacobrichard](https://github.com/jacobrichard) +- **Dashboard**: `Min width` changed to `Max per row` for repeating panels. This lets you specify the maximum number of panels to show per row and by that repeated panels will always take up full width of row [#12991](https://github.com/grafana/grafana/pull/12991), thx [@pgiraud](https://github.com/pgiraud) +- **Dashboard**: Retain decimal precision when exporting CSV [#13929](https://github.com/grafana/grafana/issues/13929), thx [@cinaglia](https://github.com/cinaglia) +- **Templating**: Escaping "Custom" template variables [#13754](https://github.com/grafana/grafana/issues/13754), thx [@IntegersOfK](https://github.com/IntegersOfK) +- **Templating**: Add percentencode formatting to variable interpolation to be used mainly for url escaping [#12764](https://github.com/grafana/grafana/issues/12764), thx [@cxcv](https://github.com/cxcv) +- **Units**: Add blood glucose level units mg/dL and mmol/L [#14519](https://github.com/grafana/grafana/issues/14519), thx [@kjedamzik](https://github.com/kjedamzik) +- **Units**: Add Floating Point Operations per Second units [#14558](https://github.com/grafana/grafana/pull/14558), thx [@hahnjo](https://github.com/hahnjo) +- **Table**: Renders epoch string as date if date column style [#14484](https://github.com/grafana/grafana/issues/14484) +- **Dataproxy**: Override incoming Authorization header [#13815](https://github.com/grafana/grafana/issues/13815), thx [@kornholi](https://github.com/kornholi) +- **Dataproxy**: Add global data source proxy timeout setting [#5699](https://github.com/grafana/grafana/issues/5699), thx [@RangerRick](https://github.com/RangerRick) +- **Database**: Support specifying database host using IPV6 for backend database and sql data sources [#13711](https://github.com/grafana/grafana/issues/13711), thx [@ellisvlad](https://github.com/ellisvlad) +- **Database**: Support defining additional database connection string args when using `url` property in database settings [#14709](https://github.com/grafana/grafana/pull/14709), thx [@tpetr](https://github.com/tpetr) +- **Stackdriver**: crossSeriesAggregation not being sent with the query [#15129](https://github.com/grafana/grafana/issues/15129), thx [@Legogris](https://github.com/Legogris) + +### Bug fixes + +- **Search**: Fix for issue with scrolling the "tags filter" dropdown, fixes [#14486](https://github.com/grafana/grafana/issues/14486) +- **Prometheus**: Query for annotation always uses 60s step regardless of dashboard range, fixes [#14795](https://github.com/grafana/grafana/issues/14795) +- **Annotations**: Fix creating annotation when graph panel has no data points position the popup outside viewport [#13765](https://github.com/grafana/grafana/issues/13765), thx [@banjeremy](https://github.com/banjeremy) +- **Piechart/Flot**: Fixes multiple piechart instances with donut bug [#15062](https://github.com/grafana/grafana/pull/15062) +- **Postgres**: Fix default port not added when port not configured [#15189](https://github.com/grafana/grafana/issues/15189) +- **Alerting**: Fixes crash bug when alert notifier folders are missing [#15295](https://github.com/grafana/grafana/issues/15295) +- **Dashboard**: Fix save provisioned dashboard modal [#15219](https://github.com/grafana/grafana/pull/15219) +- **Dashboard**: Fix having a long query in prometheus dashboard query editor blocks 30% of the query field when on OSX and having native scrollbars [#15122](https://github.com/grafana/grafana/issues/15122) +- **Explore**: Fix issue with wrapping on long queries [#15222](https://github.com/grafana/grafana/issues/15222) +- **Explore**: Fix cut & paste adds newline before and after selection [#15223](https://github.com/grafana/grafana/issues/15223) +- **Dataproxy**: Fix global data source proxy timeout not added to correct http client [#15258](https://github.com/grafana/grafana/issues/15258) [#5699](https://github.com/grafana/grafana/issues/5699) + +### Breaking changes + +- **Text Panel**: The text panel does no longer by default allow unsanitized HTML. [#4117](https://github.com/grafana/grafana/issues/4117). This means that if you have text panels with scripts tags they will no longer work as before. To enable unsafe javascript execution in text panels enable the settings `disable_sanitize_html` under the section `[panels]` in your Grafana ini file, or set env variable `GF_PANELS_DISABLE_SANITIZE_HTML=true`. +- **Dashboard**: Panel property `minSpan` replaced by `maxPerRow`. Dashboard migration will automatically migrate all dashboard panels using the `minSpan` property to the new `maxPerRow` property [#12991](https://github.com/grafana/grafana/pull/12991) + +For older release notes, refer to the [CHANGELOG_ARCHIVE.md](https://github.com/grafana/grafana/blob/master/CHANGELOG_ARCHIVE.md) diff --git a/CHANGELOG_ARCHIVE.md b/CHANGELOG_ARCHIVE.md new file mode 100644 index 00000000..6cc22ffe --- /dev/null +++ b/CHANGELOG_ARCHIVE.md @@ -0,0 +1,2256 @@ +# 5.4.5 (2019-08-29) + +- **Security**: Urgent security patch release. Please read more in our [blog](https://grafana.com/blog/2019/08/29/grafana-5.4.5-and-6.3.4-released-with-important-security-fix/) + +# 5.4.4 (2019-04-29) + +- **Security**: Urgent security patch release. Please read more in our [blog](https://grafana.com/blog/2019/04/29/grafana-5.4.4-and-6.1.6-released-with-important-security-fix/) + +# 5.4.3 (2019-01-14) + +### Tech + +- **Docker**: Build and publish docker images for armv7 and arm64 [#14617](https://github.com/grafana/grafana/pull/14617), thx [@johanneswuerbach](https://github.com/johanneswuerbach) +- **Backend**: Upgrade to golang 1.11.4 [#14580](https://github.com/grafana/grafana/issues/14580) +- **MySQL** only update session in mysql database when required [#14540](https://github.com/grafana/grafana/pull/14540) + +### Bug fixes + +- **Alerting** Invalid frequency causes division by zero in alert scheduler [#14810](https://github.com/grafana/grafana/issues/14810) +- **Dashboard** Dashboard links do not update when time range changes [#14493](https://github.com/grafana/grafana/issues/14493) +- **Limits** Support more than 1000 data sources per org [#13883](https://github.com/grafana/grafana/issues/13883) +- **Backend** fix signed in user for orgId=0 result should return active org id [#14574](https://github.com/grafana/grafana/pull/14574) +- **Provisioning** Adds orgId to user dto for provisioned dashboards [#14678](https://github.com/grafana/grafana/pull/14678) + +# 5.4.2 (2018-12-13) + +- **Data Source admin**: Fix for issue creating new data source when same name exists [#14467](https://github.com/grafana/grafana/issues/14467) +- **OAuth**: Fix for oauth auto login setting, can now be set using env variable [#14435](https://github.com/grafana/grafana/issues/14435) +- **Dashboard search**: Fix for searching tags in tags filter dropdown. + +# 5.4.1 (2018-12-10) + +- **Stackdriver**: Fixes issue with data proxy and Authorization header [#14262](https://github.com/grafana/grafana/issues/14262) +- **Units**: fixedUnit for Flow:l/min and mL/min [#14294](https://github.com/grafana/grafana/issues/14294), thx [@flopp999](https://github.com/flopp999). +- **Logging**: Fix for issue where data proxy logged a secret when debug logging was enabled, now redacted. [#14319](https://github.com/grafana/grafana/issues/14319) +- TSDB**: Fix always take dashboard timezone into consideration when handle custom time ranges**: Add support for alerting on InfluxDB queries that use the cumulative_sum function. [#14314](https://github.com/grafana/grafana/pull/14314), thx [@nitti](https://github.com/nitti) +- **Plugins**: Panel plugins should no receive the panel-initialized event again as usual. +- **Embedded Graphs**: Iframe graph panels should now work as usual. [#14284](https://github.com/grafana/grafana/issues/14284) +- **Postgres**: Improve PostgreSQL Query Editor if using different Schemas, [#14313](https://github.com/grafana/grafana/pull/14313) +- **Quotas**: Fixed for updating org & user quotas. [#14347](https://github.com/grafana/grafana/pull/14347), thx [#moznion](https://github.com/moznion) +- **Cloudwatch**: Add the AWS/SES Cloudwatch metrics of BounceRate and ComplaintRate to auto complete list. [#14401](https://github.com/grafana/grafana/pull/14401), thx [@sglajchEG](https://github.com/sglajchEG) +- **Dashboard Search**: Fixed filtering by tag issues. +- **Graph**: Fixed time region issues, [#14425](https://github.com/grafana/grafana/issues/14425), [#14280](https://github.com/grafana/grafana/issues/14280) +- **Graph**: Fixed issue with series color picker popover being placed outside window. + +# 5.4.0 (2018-12-03) + +- **Cloudwatch**: Fix invalid time range causes segmentation fault [#14150](https://github.com/grafana/grafana/issues/14150) +- **Cloudwatch**: AWS/CodeBuild metrics and dimensions [#14167](https://github.com/grafana/grafana/issues/14167), thx [@mmcoltman](https://github.com/mmcoltman) +- **MySQL**: Fix `$__timeFrom()` and `$__timeTo()` should respect local time zone [#14228](https://github.com/grafana/grafana/issues/14228) + +### 5.4.0-beta1 fixes + +- **Graph**: Fix legend always visible even if configured to be hidden [#14144](https://github.com/grafana/grafana/issues/14144) +- **Elasticsearch**: Fix regression when using data source version 6.0+ and alerting [#14175](https://github.com/grafana/grafana/pull/14175) + +# 5.4.0-beta1 (2018-11-20) + +### New Features + +- **Alerting**: Introduce alert debouncing with the `FOR` setting. [#7886](https://github.com/grafana/grafana/issues/7886) & [#6202](https://github.com/grafana/grafana/issues/6202) +- **Alerting**: Option to disable OK alert notifications [#12330](https://github.com/grafana/grafana/issues/12330) & [#6696](https://github.com/grafana/grafana/issues/6696), thx [@davewat](https://github.com/davewat) +- **Postgres/MySQL/MSSQL**: Adds support for configuration of max open/idle connections and connection max lifetime. Also, panels with multiple SQL queries will now be executed concurrently [#11711](https://github.com/grafana/grafana/issues/11711), thx [@connection-reset](https://github.com/connection-reset) +- **MySQL**: Graphical query builder [#13762](https://github.com/grafana/grafana/issues/13762), thx [svenklemm](https://github.com/svenklemm) +- **MySQL**: Support connecting thru Unix socket for MySQL data source [#12342](https://github.com/grafana/grafana/issues/12342), thx [@Yukinoshita-Yukino](https://github.com/Yukinoshita-Yukino) +- **MSSQL**: Add encrypt setting to allow configuration of how data sent between client and server are encrypted [#13629](https://github.com/grafana/grafana/issues/13629), thx [@ramiro](https://github.com/ramiro) +- **Stackdriver**: Not possible to authenticate using GCE metadata server [#13669](https://github.com/grafana/grafana/issues/13669) +- **Teams**: Team preferences (theme, home dashboard, timezone) support [#12550](https://github.com/grafana/grafana/issues/12550) +- **Graph**: Time regions support enabling highlight of weekdays and/or certain timespans [#5930](https://github.com/grafana/grafana/issues/5930) +- **OAuth**: Automatic redirect to sign-in with OAuth [#11893](https://github.com/grafana/grafana/issues/11893), thx [@Nick-Triller](https://github.com/Nick-Triller) +- **Stackdriver**: Template query editor [#13561](https://github.com/grafana/grafana/issues/13561) + +### Minor + +- **Security**: Upgrade macaron session package to fix security issue. [#14043](https://github.com/grafana/grafana/pull/14043) +- **Cloudwatch**: Show all available CloudWatch regions [#12308](https://github.com/grafana/grafana/issues/12308), thx [@mtanda](https://github.com/mtanda) +- **Cloudwatch**: AWS/Connect metrics and dimensions [#13970](https://github.com/grafana/grafana/pull/13970), thx [@zcoffy](https://github.com/zcoffy) +- **Cloudwatch**: CloudHSM metrics and dimensions [#14129](https://github.com/grafana/grafana/pull/14129), thx [@daktari](https://github.com/daktari) +- **Cloudwatch**: Enable using variables in the stats field [#13810](https://github.com/grafana/grafana/issues/13810), thx [@mtanda](https://github.com/mtanda) +- **Postgres**: Add delta window function to postgres query builder [#13925](https://github.com/grafana/grafana/issues/13925), thx [svenklemm](https://github.com/svenklemm) +- **Elasticsearch**: Fix switching to/from es raw document metric query [#6367](https://github.com/grafana/grafana/issues/6367) +- **Elasticsearch**: Fix deprecation warning about terms aggregation order key in Elasticsearch 6.x [#11977](https://github.com/grafana/grafana/issues/11977) +- **Graph**: Render dots when no connecting line can be made [#13605](https://github.com/grafana/grafana/issues/13605), thx [@jsferrei](https://github.com/jsferrei) +- **Table**: Fix CSS alpha background-color applied twice in table cell with link [#13606](https://github.com/grafana/grafana/issues/13606), thx [@grisme](https://github.com/grisme) +- **Singlestat**: Fix XSS in prefix/postfix [#13946](https://github.com/grafana/grafana/issues/13946), thx [@cinaglia](https://github.com/cinaglia) +- **Units**: New clock time format, to format ms or second values as for example `01h:59m`, [#13635](https://github.com/grafana/grafana/issues/13635), thx [@franciscocpg](https://github.com/franciscocpg) +- **Alerting**: Increase default duration for queries [#13945](https://github.com/grafana/grafana/pull/13945) +- **Alerting**: More options for the Slack Alert notifier [#13993](https://github.com/grafana/grafana/issues/13993), thx [@andreykaipov](https://github.com/andreykaipov) +- **Alerting**: Can't receive DingDing alert when alert is triggered [#13723](https://github.com/grafana/grafana/issues/13723), thx [@Yukinoshita-Yukino](https://github.com/Yukinoshita-Yukino) +- **Alerting**: Increase Telegram captions length limit [#13876](https://github.com/grafana/grafana/pull/13876), thx [@skgsergio](https://github.com/skgsergio) +- **Internal metrics**: Renamed `grafana_info` to `grafana_build_info` and added branch, goversion and revision [#13876](https://github.com/grafana/grafana/pull/13876) +- **Data Source Proxy**: Keep trailing slash for data source proxy requests [#13326](https://github.com/grafana/grafana/pull/13326), thx [@ryantxu](https://github.com/ryantxu) +- **OAuth**: Fix Google OAuth relies on email, not google account id [#13924](https://github.com/grafana/grafana/issues/13924), thx [@vinicyusmacedo](https://github.com/vinicyusmacedo) +- **Dashboard**: Toggle legend using keyboard shortcut [#13655](https://github.com/grafana/grafana/issues/13655), thx [@davewat](https://github.com/davewat) +- **Dashboard**: Fix render dashboard row drag handle only in edit mode [#13555](https://github.com/grafana/grafana/issues/13555), thx [@praveensastry](https://github.com/praveensastry) +- **Teams**: Fix cannot select team if not included in initial search [#13425](https://github.com/grafana/grafana/issues/13425) +- **Render**: Support full height screenshots using phantomjs render script [#13352](https://github.com/grafana/grafana/pull/13352), thx [@amuraru](https://github.com/amuraru) +- **HTTP API**: Support retrieving teams by user [#14120](https://github.com/grafana/grafana/pull/14120), thx [@supercharlesliu](https://github.com/supercharlesliu) +- **Metrics**: Add basic authentication to metrics endpoint [#13577](https://github.com/grafana/grafana/issues/13577), thx [@bobmshannon](https://github.com/bobmshannon) + +### Breaking changes + +- Postgres/MySQL/MSSQL data sources now per default uses `max open connections` = `unlimited` (earlier 10), `max idle connections` = `2` (earlier 10) and `connection max lifetime` = `4` hours (earlier unlimited). + +# 5.3.4 (2018-11-13) + +- **Alerting**: Delete alerts when parent folder was deleted [#13322](https://github.com/grafana/grafana/issues/13322) +- **MySQL**: Fix `$__timeFilter()` should respect local time zone [#13769](https://github.com/grafana/grafana/issues/13769) +- **Dashboard**: Fix data source selection in panel by enter key [#13932](https://github.com/grafana/grafana/issues/13932) +- **Graph**: Fix table legend height when positioned below graph and using Internet Explorer 11 [#13903](https://github.com/grafana/grafana/issues/13903) +- **Dataproxy**: Drop origin and referer http headers [#13328](https://github.com/grafana/grafana/issues/13328) [#13949](https://github.com/grafana/grafana/issues/13949), thx [@roidelapluie](https://github.com/roidelapluie) + +# 5.3.3 (2018-11-13) + +### File Exfiltration vulnerability Security fix + +See [security announcement](https://community.grafana.com/t/grafana-5-3-3-and-4-6-5-security-update/11961) for details. + +# 5.3.2 (2018-10-24) + +- **InfluxDB/Graphite/Postgres**: Prevent cross site scripting (XSS) in query editor [#13667](https://github.com/grafana/grafana/issues/13667), thx [@svenklemm](https://github.com/svenklemm) +- **Postgres**: Fix template variables error [#13692](https://github.com/grafana/grafana/issues/13692), thx [@svenklemm](https://github.com/svenklemm) +- **Cloudwatch**: Fix service panic because of race conditions [#13674](https://github.com/grafana/grafana/issues/13674), thx [@mtanda](https://github.com/mtanda) +- **Cloudwatch**: Fix check for invalid percentile statistics [#13633](https://github.com/grafana/grafana/issues/13633), thx [@apalaniuk](https://github.com/apalaniuk) +- **Stackdriver/Cloudwatch**: Allow user to change unit in graph panel if cloudwatch/stackdriver data source response doesn't include unit [#13718](https://github.com/grafana/grafana/issues/13718), thx [@mtanda](https://github.com/mtanda) +- **Stackdriver**: stackdriver user-metrics duplicated response when multiple resource types [#13691](https://github.com/grafana/grafana/issues/13691) +- **Variables**: Fix text box template variable doesn't work properly without a default value [#13666](https://github.com/grafana/grafana/issues/13666) +- **Variables**: Fix variable dependency check when using `${var}` format [#13600](https://github.com/grafana/grafana/issues/13600) +- **Dashboard**: Fix kiosk=1 url parameter should put dashboard in kiosk mode [#13764](https://github.com/grafana/grafana/pull/13764) +- **LDAP**: Fix super admins can also be admins of orgs [#13710](https://github.com/grafana/grafana/issues/13710), thx [@adrien-f](https://github.com/adrien-f) +- **Provisioning**: Fix deleting provisioned dashboard folder should cleanup provisioning meta data [#13280](https://github.com/grafana/grafana/issues/13280) + +### Minor + +- **Docker**: adds curl back into the docker image for utility. [#13794](https://github.com/grafana/grafana/pull/13794) + +# 5.3.1 (2018-10-16) + +- **Render**: Fix PhantomJS render of graph panel when legend displayed as table to the right [#13616](https://github.com/grafana/grafana/issues/13616) +- **Stackdriver**: Filter option disappears after removing initial filter [#13607](https://github.com/grafana/grafana/issues/13607) +- **Elasticsearch**: Fix no limit size in terms aggregation for alerting queries [#13172](https://github.com/grafana/grafana/issues/13172), thx [@Yukinoshita-Yukino](https://github.com/Yukinoshita-Yukino) +- **InfluxDB**: Fix for annotation issue that caused text to be shown twice [#13553](https://github.com/grafana/grafana/issues/13553) +- **Variables**: Fix nesting variables leads to exception and missing refresh [#13628](https://github.com/grafana/grafana/issues/13628) +- **Variables**: Prometheus: Single letter labels are not supported [#13641](https://github.com/grafana/grafana/issues/13641), thx [@olshansky](https://github.com/olshansky) +- **Graph**: Fix graph time formatting for Last 24h ranges [#13650](https://github.com/grafana/grafana/issues/13650) +- **Playlist**: Fix cannot add dashboards with long names to playlist [#13464](https://github.com/grafana/grafana/issues/13464), thx [@neufeldtech](https://github.com/neufeldtech) +- **HTTP API**: Fix /api/org/users so that query and limit querystrings works + +# 5.3.0 (2018-10-10) + +- **Stackdriver**: Filter wildcards and regex matching are not yet supported [#13495](https://github.com/grafana/grafana/issues/13495) +- **Stackdriver**: Support the distribution metric type for heatmaps [#13559](https://github.com/grafana/grafana/issues/13559) +- **Cloudwatch**: Automatically set graph yaxis unit [#13575](https://github.com/grafana/grafana/issues/13575), thx [@mtanda](https://github.com/mtanda) + +# 5.3.0-beta3 (2018-10-03) + +- **Stackdriver**: Fix for missing ngInject [#13511](https://github.com/grafana/grafana/pull/13511) +- **Permissions**: Fix for broken permissions selector [#13507](https://github.com/grafana/grafana/issues/13507) +- **Alerting**: Alert reminders deduping not working as expected when running multiple Grafana instances [#13492](https://github.com/grafana/grafana/issues/13492) + +# 5.3.0-beta2 (2018-10-01) + +### New Features + +- **Annotations**: Enable template variables in tagged annotations queries [#9735](https://github.com/grafana/grafana/issues/9735) +- **Stackdriver**: Support for Google Stackdriver data source [#13289](https://github.com/grafana/grafana/pull/13289) + +### Minor + +- **Provisioning**: Dashboard Provisioning now support symlinks that changes target [#12534](https://github.com/grafana/grafana/issues/12534), thx [@auhlig](https://github.com/auhlig) +- **OAuth**: Allow oauth email attribute name to be configurable [#12986](https://github.com/grafana/grafana/issues/12986), thx [@bobmshannon](https://github.com/bobmshannon) +- **Tags**: Default sort order for GetDashboardTags [#11681](https://github.com/grafana/grafana/pull/11681), thx [@Jonnymcc](https://github.com/Jonnymcc) +- **Prometheus**: Label completion queries respect dashboard time range [#12251](https://github.com/grafana/grafana/pull/12251), thx [@mtanda](https://github.com/mtanda) +- **Prometheus**: Allow to display annotations based on Prometheus series value [#10159](https://github.com/grafana/grafana/issues/10159), thx [@mtanda](https://github.com/mtanda) +- **Prometheus**: Adhoc-filtering for Prometheus dashboards [#13212](https://github.com/grafana/grafana/issues/13212) +- **Singlestat**: Fix gauge display accuracy for percents [#13270](https://github.com/grafana/grafana/issues/13270), thx [@tianon](https://github.com/tianon) +- **Dashboard**: Prevent auto refresh from starting when loading dashboard with absolute time range [#12030](https://github.com/grafana/grafana/issues/12030) +- **Templating**: New templating variable type `Text box` that allows free text input [#3173](https://github.com/grafana/grafana/issues/3173) +- **Alerting**: Link to view full size image in Microsoft Teams alert notifier [#13121](https://github.com/grafana/grafana/issues/13121), thx [@holiiveira](https://github.com/holiiveira) +- **Alerting**: Fixes a bug where all alerts would send reminders after upgrade & restart [#13402](https://github.com/grafana/grafana/pull/13402) +- **Alerting**: Concurrent render limit for graphs used in notifications [#13401](https://github.com/grafana/grafana/pull/13401) +- **Postgres/MySQL/MSSQL**: Add support for replacing $\_\_interval and $\_\_interval_ms in alert queries [#11555](https://github.com/grafana/grafana/issues/11555), thx [@svenklemm](https://github.com/svenklemm) + +# 5.3.0-beta1 (2018-09-06) + +### New Major Features + +- **Alerting**: Notification reminders [#7330](https://github.com/grafana/grafana/issues/7330), thx [@jbaublitz](https://github.com/jbaublitz) +- **Dashboard**: TV & Kiosk mode changes, new cycle view mode button in dashboard toolbar [#13025](https://github.com/grafana/grafana/pull/13025) +- **OAuth**: Gitlab OAuth with support for filter by groups [#5623](https://github.com/grafana/grafana/issues/5623), thx [@BenoitKnecht](https://github.com/BenoitKnecht) +- **Postgres**: Graphical query builder [#10095](https://github.com/grafana/grafana/issues/10095), thx [svenklemm](https://github.com/svenklemm) + +### New Features + +- **LDAP**: Define Grafana Admin permission in ldap group mappings [#2469](https://github.com/grafana/grafana/issues/2496), PR [#12622](https://github.com/grafana/grafana/issues/12622) +- **LDAP**: Client certificates support [#12805](https://github.com/grafana/grafana/issues/12805), thx [@nyxi](https://github.com/nyxi) +- **Profile**: List teams that the user is member of in current/active organization [#12476](https://github.com/grafana/grafana/issues/12476) +- **Configuration**: Allow auto-assigning users to specific organization (other than Main. Org) [#1823](https://github.com/grafana/grafana/issues/1823) [#12801](https://github.com/grafana/grafana/issues/12801), thx [@gzzo](https://github.com/gzzo) and [@ofosos](https://github.com/ofosos) +- **Dataproxy**: Pass configured/auth headers to a data source [#10971](https://github.com/grafana/grafana/issues/10971), thx [@mrsiano](https://github.com/mrsiano) +- **CloudWatch**: GetMetricData support [#11487](https://github.com/grafana/grafana/issues/11487), thx [@mtanda](https://github.com/mtanda) +- **Postgres**: TimescaleDB support, e.g. use `time_bucket` for grouping by time when option enabled [#12680](https://github.com/grafana/grafana/pull/12680), thx [svenklemm](https://github.com/svenklemm) +- **Cleanup**: Make temp file time to live configurable [#11607](https://github.com/grafana/grafana/issues/11607), thx [@xapon](https://github.com/xapon) + +### Minor + +- **Alerting**: Its now possible to configure the default value for how to handle errors and no data in alerting. [#10424](https://github.com/grafana/grafana/issues/10424) +- **Alerting**: Fix diff and percent_diff reducers [#11563](https://github.com/grafana/grafana/issues/11563), thx [@jessetane](https://github.com/jessetane) +- **Alerting**: Fix rendering timeout which could cause notifications to not be sent due to rendering timing out [#12151](https://github.com/grafana/grafana/issues/12151) +- **Docker**: Make it possible to set a specific plugin url [#12861](https://github.com/grafana/grafana/pull/12861), thx [ClementGautier](https://github.com/ClementGautier) +- **GrafanaCli**: Fixed issue with grafana-cli install plugin resulting in corrupt http response from source error. Fixes [#13079](https://github.com/grafana/grafana/issues/13079) +- **Provisioning**: Should allow one default data source per organization [#12229](https://github.com/grafana/grafana/issues/12229) +- **GitHub OAuth**: Allow changes of user info at GitHub to be synched to Grafana when signing in [#11818](https://github.com/grafana/grafana/issues/11818), thx [@rwaweber](https://github.com/rwaweber) +- **OAuth**: Fix overriding tls_skip_verify_insecure using environment variable [#12747](https://github.com/grafana/grafana/issues/12747), thx [@jangaraj](https://github.com/jangaraj) +- **Prometheus**: Fix graph panel bar width issue in aligned prometheus queries [#12379](https://github.com/grafana/grafana/issues/12379) +- **Prometheus**: Heatmap - fix unhandled error when some points are missing [#12484](https://github.com/grafana/grafana/issues/12484) +- **Prometheus**: Add $**interval, $**interval_ms, \$**range, $**range_s & $\_\_range_ms support for dashboard and template queries [#12597](https://github.com/grafana/grafana/issues/12597) [#12882](https://github.com/grafana/grafana/issues/12882), thx [@roidelapluie](https://github.com/roidelapluie) +- **Elasticsearch**: For alerting/backend, support having index name to the right of pattern in index pattern [#12731](https://github.com/grafana/grafana/issues/12731) +- **Graphite**: Fix for quoting of int function parameters (when using variables) [#11927](https://github.com/grafana/grafana/pull/11927) +- **InfluxDB**: Support timeFilter in query templating for InfluxDB [#12598](https://github.com/grafana/grafana/pull/12598), thx [kichristensen](https://github.com/kichristensen) +- **Postgres/MySQL/MSSQL**: New $\_\_unixEpochGroup and $\_\_unixEpochGroupAlias macros [#12892](https://github.com/grafana/grafana/issues/12892), thx [@svenklemm](https://github.com/svenklemm) +- **Postgres/MySQL/MSSQL**: Add previous fill mode to \$\_\_timeGroup macro which will fill in previously seen value when point is missing [#12756](https://github.com/grafana/grafana/issues/12756), thx [@svenklemm](https://github.com/svenklemm) +- **Postgres/MySQL/MSSQL**: Use floor rounding in \$\_\_timeGroup macro function [#12460](https://github.com/grafana/grafana/issues/12460), thx [@svenklemm](https://github.com/svenklemm) +- **Postgres/MySQL/MSSQL**: Use metric column as prefix when returning multiple value columns [#12727](https://github.com/grafana/grafana/issues/12727), thx [@svenklemm](https://github.com/svenklemm) +- **Postgres/MySQL/MSSQL**: New $\_\_timeGroupAlias macro. Postgres $\_\_timeGroup no longer automatically adds time column alias [#12749](https://github.com/grafana/grafana/issues/12749), thx [@svenklemm](https://github.com/svenklemm) +- **Postgres/MySQL/MSSQL**: Escape single quotes in variables [#12785](https://github.com/grafana/grafana/issues/12785), thx [@eMerzh](https://github.com/eMerzh) +- **Postgres/MySQL/MSSQL**: Min time interval support [#13157](https://github.com/grafana/grafana/issues/13157), thx [@svenklemm](https://github.com/svenklemm) +- **MySQL/MSSQL**: Use datetime format instead of epoch for $\_\_timeFilter, $**timeFrom and \$**timeTo macros [#11618](https://github.com/grafana/grafana/issues/11618) [#11619](https://github.com/grafana/grafana/issues/11619), thx [@AustinWinstanley](https://github.com/AustinWinstanley) +- **Postgres**: Escape ssl mode parameter in connectionstring [#12644](https://github.com/grafana/grafana/issues/12644), thx [@yogyrahmawan](https://github.com/yogyrahmawan) +- **Cloudwatch**: Improved error handling [#12489](https://github.com/grafana/grafana/issues/12489), thx [@mtanda](https://github.com/mtanda) +- **Cloudwatch**: AppSync metrics and dimensions [#12300](https://github.com/grafana/grafana/issues/12300), thx [@franciscocpg](https://github.com/franciscocpg) +- **Cloudwatch**: Direct Connect metrics and dimensions [#12762](https://github.com/grafana/grafana/pulls/12762), thx [@mindriot88](https://github.com/mindriot88) +- **Cloudwatch**: Added BurstBalance metric to list of AWS RDS metrics [#12561](https://github.com/grafana/grafana/pulls/12561), thx [@activeshadow](https://github.com/activeshadow) +- **Cloudwatch**: Add new Redshift metrics and dimensions [#12063](https://github.com/grafana/grafana/pulls/12063), thx [@A21z](https://github.com/A21z) +- **Dashboard**: Fix selecting current dashboard from search should not reload dashboard [#12248](https://github.com/grafana/grafana/issues/12248) +- **Dashboard**: Use uid when linking to dashboards internally in a dashboard [#10705](https://github.com/grafana/grafana/issues/10705) +- **Graph**: Option to hide series from tooltip [#3341](https://github.com/grafana/grafana/issues/3341), thx [@mtanda](https://github.com/mtanda) +- **Singlestat**: Make colorization of prefix and postfix optional in singlestat [#11892](https://github.com/grafana/grafana/pull/11892), thx [@ApsOps](https://github.com/ApsOps) +- **Table**: Adjust header contrast for the light theme [#12668](https://github.com/grafana/grafana/issues/12668) +- **Table**: Fix link color when using light theme and thresholds in use [#12766](https://github.com/grafana/grafana/issues/12766) +- **Table**: Fix for useless horizontal scrollbar for table panel [#9964](https://github.com/grafana/grafana/issues/9964) +- **Table**: Make table sorting stable when null values exist [#12362](https://github.com/grafana/grafana/pull/12362), thx [@bz2](https://github.com/bz2) +- **Heatmap**: Fix broken tooltip and crosshair on Firefox [#12486](https://github.com/grafana/grafana/issues/12486) +- **Data Source**: Fix UI issue with secret fields after updating data source [#11270](https://github.com/grafana/grafana/issues/11270) +- **Variables**: Skip unneeded extra query request when de-selecting variable values used for repeated panels [#8186](https://github.com/grafana/grafana/issues/8186), thx [@mtanda](https://github.com/mtanda) +- **Variables**: Limit amount of queries executed when updating variable that other variable(s) are dependent on [#11890](https://github.com/grafana/grafana/issues/11890) +- **Variables**: Support query variable refresh when another variable referenced in `Regex` field change its value [#12952](https://github.com/grafana/grafana/issues/12952), thx [@franciscocpg](https://github.com/franciscocpg) +- **Variables**: Support variables in query variable `Custom all value` field [#12965](https://github.com/grafana/grafana/issues/12965), thx [@franciscocpg](https://github.com/franciscocpg) +- **Units**: Change units to include characters for power of 2 and 3 [#12744](https://github.com/grafana/grafana/pull/12744), thx [@Worty](https://github.com/Worty) +- **Units**: Polish złoty currency [#12691](https://github.com/grafana/grafana/pull/12691), thx [@mwegrzynek](https://github.com/mwegrzynek) +- **Units**: Adds bitcoin axes unit. [#13125](https://github.com/grafana/grafana/pull/13125) +- **Api**: Delete nonexistent data source should return 404 [#12313](https://github.com/grafana/grafana/issues/12313), thx [@AustinWinstanley](https://github.com/AustinWinstanley) +- **Logging**: Reopen log files after receiving a SIGHUP signal [#13112](https://github.com/grafana/grafana/pull/13112), thx [@filewalkwithme](https://github.com/filewalkwithme) +- **Login**: Show loading animation while waiting for authentication response on login [#12865](https://github.com/grafana/grafana/issues/12865) +- **UI**: Fix iOS home screen "app" icon and Windows 10 app experience [#12752](https://github.com/grafana/grafana/issues/12752), thx [@andig](https://github.com/andig) +- **Plugins**: Convert URL-like text to links in plugins readme [#12843](https://github.com/grafana/grafana/pull/12843), thx [pgiraud](https://github.com/pgiraud) + +### Breaking changes + +- Postgres data source no longer automatically adds time column alias when using the \$\_\_timeGroup alias. However, there's code in place which should make this change backward compatible and shouldn't create any issues. +- Kiosk mode now also hides submenu (variables) +- ?inactive url parameter no longer supported, replaced with kiosk=tv url parameter + +### New experimental features + +These are new features that's still being worked on and are in an experimental phase. We encourage users to try these out and provide any feedback in related issue. + +- **Dashboard**: Auto fit dashboard panels to optimize space used for current TV / Monitor [#12768](https://github.com/grafana/grafana/issues/12768) + +### Tech + +- **Frontend**: Convert all Frontend Karma tests to Jest tests [#12224](https://github.com/grafana/grafana/issues/12224) +- **Backend**: Upgrade to golang 1.11 [#13030](https://github.com/grafana/grafana/issues/13030) + +# 5.2.4 (2018-09-07) + +- **GrafanaCli**: Fixed issue with grafana-cli install plugin resulting in corrupt http response from source error. Fixes [#13079](https://github.com/grafana/grafana/issues/13079) + +# 5.2.3 (2018-08-29) + +### Important fix for LDAP & OAuth login vulnerability + +See [security announcement](https://community.grafana.com/t/grafana-5-2-3-and-4-6-4-security-update/10050) for details. + +# 5.2.2 (2018-07-25) + +### Minor + +- **Prometheus**: Fix graph panel bar width issue in aligned prometheus queries [#12379](https://github.com/grafana/grafana/issues/12379) +- **Dashboard**: Dashboard links not updated when changing variables [#12506](https://github.com/grafana/grafana/issues/12506) +- **Postgres/MySQL/MSSQL**: Fix connection leak [#12636](https://github.com/grafana/grafana/issues/12636) [#9827](https://github.com/grafana/grafana/issues/9827) +- **Plugins**: Fix loading of external plugins [#12551](https://github.com/grafana/grafana/issues/12551) +- **Dashboard**: Remove unwanted scrollbars in embedded panels [#12589](https://github.com/grafana/grafana/issues/12589) +- **Prometheus**: Prevent error using \$\_\_interval_ms in query [#12533](https://github.com/grafana/grafana/pull/12533), thx [@mtanda](https://github.com/mtanda) + +# 5.2.1 (2018-06-29) + +### Minor + +- **Auth Proxy**: Important security fix for whitelist of IP address feature [#12444](https://github.com/grafana/grafana/pull/12444) +- **UI**: Fix - Grafana footer overlapping page [#12430](https://github.com/grafana/grafana/issues/12430) +- **Logging**: Errors should be reported before crashing [#12438](https://github.com/grafana/grafana/issues/12438) + +# 5.2.0-stable (2018-06-27) + +### Minor + +- **Plugins**: Handle errors correctly when loading data source plugin [#12383](https://github.com/grafana/grafana/pull/12383) thx [@rozetko](https://github.com/rozetko) +- **Render**: Enhance error message if phantomjs executable is not found [#11868](https://github.com/grafana/grafana/issues/11868) +- **Dashboard**: Set correct text in drop down when variable is present in url [#11968](https://github.com/grafana/grafana/issues/11968) + +### 5.2.0-beta3 fixes + +- **LDAP**: Handle "dn" ldap attribute more gracefully [#12385](https://github.com/grafana/grafana/pull/12385), reverts [#10970](https://github.com/grafana/grafana/pull/10970) + +# 5.2.0-beta3 (2018-06-21) + +### Minor + +- **Build**: All rpm packages should be signed [#12359](https://github.com/grafana/grafana/issues/12359) + +# 5.2.0-beta2 (2018-06-20) + +### New Features + +- **Dashboard**: Import dashboard to folder [#10796](https://github.com/grafana/grafana/issues/10796) + +### Minor + +- **Permissions**: Important security fix for API keys with viewer role [#12343](https://github.com/grafana/grafana/issues/12343) +- **Dashboard**: Fix so panel titles doesn't wrap [#11074](https://github.com/grafana/grafana/issues/11074) +- **Dashboard**: Prevent double-click when saving dashboard [#11963](https://github.com/grafana/grafana/issues/11963) +- **Dashboard**: AutoFocus the add-panel search filter [#12189](https://github.com/grafana/grafana/pull/12189) thx [@ryantxu](https://github.com/ryantxu) +- **Units**: W/m2 (energy), l/h (flow) and kPa (pressure) [#11233](https://github.com/grafana/grafana/pull/11233), thx [@flopp999](https://github.com/flopp999) +- **Units**: Liter/min (flow) and milliLiter/min (flow) [#12282](https://github.com/grafana/grafana/pull/12282), thx [@flopp999](https://github.com/flopp999) +- **Alerting**: Fix mobile notifications for Microsoft Teams alert notifier [#11484](https://github.com/grafana/grafana/pull/11484), thx [@manacker](https://github.com/manacker) +- **Influxdb**: Add support for mode function [#12286](https://github.com/grafana/grafana/issues/12286) +- **Cloudwatch**: Fixes panic caused by bad timerange settings [#12199](https://github.com/grafana/grafana/issues/12199) +- **Auth Proxy**: Whitelist proxy IP address instead of client IP address [#10707](https://github.com/grafana/grafana/issues/10707) +- **User Management**: Make sure that a user always has a current org assigned [#11076](https://github.com/grafana/grafana/issues/11076) +- **Snapshots**: Fix: annotations not properly extracted leading to incorrect rendering of annotations [#12278](https://github.com/grafana/grafana/issues/12278) +- **LDAP**: Allow use of DN in group_search_filter_user_attribute and member_of [#3132](https://github.com/grafana/grafana/issues/3132), thx [@mmolnar](https://github.com/mmolnar) +- **Graph**: Fix legend decimals precision calculation [#11792](https://github.com/grafana/grafana/issues/11792) +- **Dashboard**: Make sure to process panels in collapsed rows when exporting dashboard [#12256](https://github.com/grafana/grafana/issues/12256) + +### 5.2.0-beta1 fixes + +- **Dashboard**: Dashboard link doesn't work when "As dropdown" option is checked [#12315](https://github.com/grafana/grafana/issues/12315) +- **Dashboard**: Fix regressions after save modal changes, including adhoc template issues [#12240](https://github.com/grafana/grafana/issues/12240) +- **Docker**: Config keys ending with \_FILE are not respected [#170](https://github.com/grafana/grafana-docker/issues/170) + +# 5.2.0-beta1 (2018-06-05) + +### New Features + +- **Elasticsearch**: Alerting support [#5893](https://github.com/grafana/grafana/issues/5893), thx [@WPH95](https://github.com/WPH95) +- **Build**: Crosscompile and packages Grafana on arm, windows, linux and darwin [#11920](https://github.com/grafana/grafana/pull/11920), thx [@fg2it](https://github.com/fg2it) +- **Login**: Change admin password after first login [#11882](https://github.com/grafana/grafana/issues/11882) +- **Alert list panel**: Updated to support filtering alerts by name, dashboard title, folder, tags [#11500](https://github.com/grafana/grafana/issues/11500), [#8168](https://github.com/grafana/grafana/issues/8168), [#6541](https://github.com/grafana/grafana/issues/6541) + +### Minor + +- **Dashboard**: Modified time range and variables are now not saved by default [#10748](https://github.com/grafana/grafana/issues/10748), [#8805](https://github.com/grafana/grafana/issues/8805) +- **Graph**: Show invisible highest value bucket in histogram [#11498](https://github.com/grafana/grafana/issues/11498) +- **Dashboard**: Enable "Save As..." if user has edit permission [#11625](https://github.com/grafana/grafana/issues/11625) +- **Prometheus**: Query dates are now step-aligned [#10434](https://github.com/grafana/grafana/pull/10434) +- **Prometheus**: Table columns order now changes when rearrange queries [#11690](https://github.com/grafana/grafana/issues/11690), thx [@mtanda](https://github.com/mtanda) +- **Variables**: Fix variable interpolation when using multiple formatting types [#11800](https://github.com/grafana/grafana/issues/11800), thx [@svenklemm](https://github.com/svenklemm) +- **Dashboard**: Fix date selector styling for dark/light theme in time picker control [#11616](https://github.com/grafana/grafana/issues/11616) +- **Discord**: Alert notification channel type for Discord, [#7964](https://github.com/grafana/grafana/issues/7964) thx [@jereksel](https://github.com/jereksel), +- **InfluxDB**: Support SELECT queries in templating query, [#5013](https://github.com/grafana/grafana/issues/5013) +- **InfluxDB**: Support count distinct aggregation [#11645](https://github.com/grafana/grafana/issues/11645), thx [@kichristensen](https://github.com/kichristensen) +- **Dashboard**: JSON Model under dashboard settings can now be updated & changes saved, [#1429](https://github.com/grafana/grafana/issues/1429), thx [@jereksel](https://github.com/jereksel) +- **Security**: Fix XSS vulnerabilities in dashboard links [#11813](https://github.com/grafana/grafana/pull/11813) +- **Singlestat**: Fix "time of last point" shows local time when dashboard timezone set to UTC [#10338](https://github.com/grafana/grafana/issues/10338) +- **Prometheus**: Add support for passing timeout parameter to Prometheus [#11788](https://github.com/grafana/grafana/pull/11788), thx [@mtanda](https://github.com/mtanda) +- **Login**: Add optional option sign out url for generic oauth [#9847](https://github.com/grafana/grafana/issues/9847), thx [@roidelapluie](https://github.com/roidelapluie) +- **Login**: Use proxy server from environment variable if available [#9703](https://github.com/grafana/grafana/issues/9703), thx [@iyeonok](https://github.com/iyeonok) +- **Invite users**: Friendlier error message when smtp is not configured [#12087](https://github.com/grafana/grafana/issues/12087), thx [@thurt](https://github.com/thurt) +- **Graphite**: Don't send distributed tracing headers when using direct/browser access mode [#11494](https://github.com/grafana/grafana/issues/11494) +- **Sidenav**: Show create dashboard link for viewers if at least editor in one folder [#11858](https://github.com/grafana/grafana/issues/11858) +- **SQL**: Second epochs are now correctly converted to ms. [#12085](https://github.com/grafana/grafana/pull/12085) +- **Singlestat**: Fix singlestat threshold tooltip [#11971](https://github.com/grafana/grafana/issues/11971) +- **Dashboard**: Hide grid controls in fullscreen/low-activity views [#11771](https://github.com/grafana/grafana/issues/11771) +- **Dashboard**: Validate uid when importing dashboards [#11515](https://github.com/grafana/grafana/issues/11515) +- **Docker**: Support for env variables ending with \_FILE [grafana-docker #166](https://github.com/grafana/grafana-docker/pull/166), thx [@efrecon](https://github.com/efrecon) +- **Alert list panel**: Show alerts for user with viewer role [#11167](https://github.com/grafana/grafana/issues/11167) +- **Provisioning**: Verify checksum of dashboards before updating to reduce load on database [#11670](https://github.com/grafana/grafana/issues/11670) +- **Provisioning**: Support symlinked files in dashboard provisioning config files [#11958](https://github.com/grafana/grafana/issues/11958) +- **Dashboard list panel**: Search dashboards by folder [#11525](https://github.com/grafana/grafana/issues/11525) +- **Sidenav**: Always show server admin link in sidenav if grafana admin [#11657](https://github.com/grafana/grafana/issues/11657) + +# 5.1.5 (2018-06-27) + +- **Docker**: Config keys ending with \_FILE are not respected [#170](https://github.com/grafana/grafana-docker/issues/170) + +# 5.1.4 (2018-06-19) + +- **Permissions**: Important security fix for API keys with viewer role [#12343](https://github.com/grafana/grafana/issues/12343) + +# 5.1.3 (2018-05-16) + +- **Scroll**: Graph panel / legend texts shifts on the left each time we move scrollbar on firefox [#11830](https://github.com/grafana/grafana/issues/11830) + +# 5.1.2 (2018-05-09) + +- **Database**: Fix MySql migration issue [#11862](https://github.com/grafana/grafana/issues/11862) +- **Google Analytics**: Enable Google Analytics anonymizeIP setting for GDPR [#11656](https://github.com/grafana/grafana/pull/11656) + +# 5.1.1 (2018-05-07) + +- **LDAP**: LDAP login with MariaDB/MySQL database and dn>100 chars not possible [#11754](https://github.com/grafana/grafana/issues/11754) +- **Build**: AppVeyor Windows build missing version and commit info [#11758](https://github.com/grafana/grafana/issues/11758) +- **Scroll**: Scroll can't start in graphs on Chrome mobile [#11710](https://github.com/grafana/grafana/issues/11710) +- **Units**: Revert renaming of unit key ppm [#11743](https://github.com/grafana/grafana/issues/11743) + +# 5.1.0 (2018-04-26) + +- **Folders**: Default permissions on folder are not shown as inherited in its dashboards [#11668](https://github.com/grafana/grafana/issues/11668) +- **Templating**: Allow more than 20 previews when creating a variable [#11508](https://github.com/grafana/grafana/issues/11508) +- **Dashboard**: Row edit icon not shown [#11466](https://github.com/grafana/grafana/issues/11466) +- **SQL**: Unsupported data types for value column using time series query [#11703](https://github.com/grafana/grafana/issues/11703) +- **Prometheus**: Prometheus query inspector expands to be very large on autocomplete queries [#11673](https://github.com/grafana/grafana/issues/11673) + +# 5.1.0-beta1 (2018-04-20) + +- **MSSQL**: New Microsoft SQL Server data source [#10093](https://github.com/grafana/grafana/pull/10093), [#11298](https://github.com/grafana/grafana/pull/11298), thx [@linuxchips](https://github.com/linuxchips) +- **Prometheus**: The heatmap panel now support Prometheus histograms [#10009](https://github.com/grafana/grafana/issues/10009) +- **Postgres/MySQL**: Ability to insert 0s or nulls for missing intervals [#9487](https://github.com/grafana/grafana/issues/9487), thanks [@svenklemm](https://github.com/svenklemm) +- **Postgres/MySQL/MSSQL**: Fix precision for the time column in table mode [#11306](https://github.com/grafana/grafana/issues/11306) +- **Graph**: Align left and right Y-axes to one level [#1271](https://github.com/grafana/grafana/issues/1271) & [#2740](https://github.com/grafana/grafana/issues/2740) thx [@ilgizar](https://github.com/ilgizar) +- **Graph**: Thresholds for Right Y axis [#7107](https://github.com/grafana/grafana/issues/7107), thx [@ilgizar](https://github.com/ilgizar) +- **Graph**: Support multiple series stacking in histogram mode [#8151](https://github.com/grafana/grafana/issues/8151), thx [@mtanda](https://github.com/mtanda) +- **Alerting**: Pausing/un alerts now updates new_state_date [#10942](https://github.com/grafana/grafana/pull/10942) +- **Alerting**: Support Pagerduty notification channel using Pagerduty V2 API [#10531](https://github.com/grafana/grafana/issues/10531), thx [@jbaublitz](https://github.com/jbaublitz) +- **Templating**: Add comma templating format [#10632](https://github.com/grafana/grafana/issues/10632), thx [@mtanda](https://github.com/mtanda) +- **Prometheus**: Show template variable candidate in query editor [#9210](https://github.com/grafana/grafana/issues/9210), thx [@mtanda](https://github.com/mtanda) +- **Prometheus**: Support POST for query and query_range [#9859](https://github.com/grafana/grafana/pull/9859), thx [@mtanda](https://github.com/mtanda) +- **Alerting**: Add support for retries on alert queries [#5855](https://github.com/grafana/grafana/issues/5855), thx [@Thib17](https://github.com/Thib17) +- **Table**: Table plugin value mappings [#7119](https://github.com/grafana/grafana/issues/7119), thx [infernix](https://github.com/infernix) +- **IE11**: IE 11 compatibility [#11165](https://github.com/grafana/grafana/issues/11165) +- **Scrolling**: Better scrolling experience [#11053](https://github.com/grafana/grafana/issues/11053), [#11252](https://github.com/grafana/grafana/issues/11252), [#10836](https://github.com/grafana/grafana/issues/10836), [#11185](https://github.com/grafana/grafana/issues/11185), [#11168](https://github.com/grafana/grafana/issues/11168) +- **Docker**: Improved docker image (breaking changes regarding file ownership) [grafana-docker #141](https://github.com/grafana/grafana-docker/issues/141), thx [@Spindel](https://github.com/Spindel), [@ChristianKniep](https://github.com/ChristianKniep), [@brancz](https://github.com/brancz) and [@jangaraj](https://github.com/jangaraj) +- **Folders**: A folder admin cannot add user/team permissions for folder/its dashboards [#11173](https://github.com/grafana/grafana/issues/11173) +- **Provisioning**: Improved workflow for provisioned dashboards [#10883](https://github.com/grafana/grafana/issues/10883) + +### Minor + +- **OpsGenie**: Add triggered alerts as description [#11046](https://github.com/grafana/grafana/pull/11046), thx [@llamashoes](https://github.com/llamashoes) +- **Cloudwatch**: Support high resolution metrics [#10925](https://github.com/grafana/grafana/pull/10925), thx [@mtanda](https://github.com/mtanda) +- **Cloudwatch**: Add dimension filtering to CloudWatch `dimension_values()` [#10029](https://github.com/grafana/grafana/issues/10029), thx [@willyhutw](https://github.com/willyhutw) +- **Units**: Second to HH:mm:ss formatter [#11107](https://github.com/grafana/grafana/issues/11107), thx [@gladdiologist](https://github.com/gladdiologist) +- **Singlestat**: Add color to prefix and postfix in singlestat panel [#11143](https://github.com/grafana/grafana/pull/11143), thx [@ApsOps](https://github.com/ApsOps) +- **Dashboards**: Version cleanup fails on old databases with many entries [#11278](https://github.com/grafana/grafana/issues/11278) +- **Server**: Adjust permissions of unix socket [#11343](https://github.com/grafana/grafana/pull/11343), thx [@corny](https://github.com/corny) +- **Shortcuts**: Add shortcut for duplicate panel [#11102](https://github.com/grafana/grafana/issues/11102) +- **AuthProxy**: Support IPv6 in Auth proxy white list [#11330](https://github.com/grafana/grafana/pull/11330), thx [@corny](https://github.com/corny) +- **SMTP**: Don't connect to STMP server using TLS unless configured. [#7189](https://github.com/grafana/grafana/issues/7189) +- **Prometheus**: Escape backslash in labels correctly. [#10555](https://github.com/grafana/grafana/issues/10555), thx [@roidelapluie](https://github.com/roidelapluie) +- **Variables**: Case-insensitive sorting for template values [#11128](https://github.com/grafana/grafana/issues/11128) thx [@cross](https://github.com/cross) +- **Annotations (native)**: Change default limit from 10 to 100 when querying api [#11569](https://github.com/grafana/grafana/issues/11569), thx [@flopp999](https://github.com/flopp999) +- **MySQL/Postgres/MSSQL**: PostgreSQL data source generates invalid query with dates before 1970 [#11530](https://github.com/grafana/grafana/issues/11530) thx [@ryantxu](https://github.com/ryantxu) +- **Kiosk**: Adds url parameter for starting a dashboard in inactive mode [#11228](https://github.com/grafana/grafana/issues/11228), thx [@towolf](https://github.com/towolf) +- **Dashboard**: Enable closing timepicker using escape key [#11332](https://github.com/grafana/grafana/issues/11332) +- **Data Sources**: Rename direct access mode in the data source settings [#11391](https://github.com/grafana/grafana/issues/11391) +- **Search**: Display dashboards in folder indented [#11073](https://github.com/grafana/grafana/issues/11073) +- **Units**: Use B/s instead Bps for Bytes per second [#9342](https://github.com/grafana/grafana/pull/9342), thx [@mayli](https://github.com/mayli) +- **Units**: Radiation units [#11001](https://github.com/grafana/grafana/issues/11001), thx [@victorclaessen](https://github.com/victorclaessen) +- **Units**: Timeticks unit [#11183](https://github.com/grafana/grafana/pull/11183), thx [@jtyr](https://github.com/jtyr) +- **Units**: Concentration units and "Normal cubic meter" [#11211](https://github.com/grafana/grafana/issues/11211), thx [@flopp999](https://github.com/flopp999) +- **Units**: New currency - Czech koruna [#11384](https://github.com/grafana/grafana/pull/11384), thx [@Rohlik](https://github.com/Rohlik) +- **Avatar**: Fix DISABLE_GRAVATAR option [#11095](https://github.com/grafana/grafana/issues/11095) +- **Heatmap**: Disable log scale when using time time series buckets [#10792](https://github.com/grafana/grafana/issues/10792) +- **Provisioning**: Remove `id` from json when provisioning dashboards, [#11138](https://github.com/grafana/grafana/issues/11138) +- **Prometheus**: tooltip for legend format not showing properly [#11516](https://github.com/grafana/grafana/issues/11516), thx [@svenklemm](https://github.com/svenklemm) +- **Playlist**: Empty playlists cannot be deleted [#11133](https://github.com/grafana/grafana/issues/11133), thx [@kichristensen](https://github.com/kichristensen) +- **Switch Orgs**: Alphabetic order in Switch Organization modal [#11556](https://github.com/grafana/grafana/issues/11556) +- **Postgres**: improve `$__timeFilter` macro [#11578](https://github.com/grafana/grafana/issues/11578), thx [@svenklemm](https://github.com/svenklemm) +- **Permission list**: Improved ux [#10747](https://github.com/grafana/grafana/issues/10747) +- **Dashboard**: Sizing and positioning of settings menu icons [#11572](https://github.com/grafana/grafana/pull/11572) +- **Dashboard**: Add search filter/tabs to new panel control [#10427](https://github.com/grafana/grafana/issues/10427) +- **Folders**: User with org viewer role should not be able to save/move dashboards in/to general folder [#11553](https://github.com/grafana/grafana/issues/11553) +- **Influxdb**: Don't assume the first column in table response is time. [#11476](https://github.com/grafana/grafana/issues/11476), thx [@hahnjo](https://github.com/hahnjo) + +### Tech + +- Backend code simplification [#11613](https://github.com/grafana/grafana/pull/11613), thx [@knweiss](https://github.com/knweiss) +- Add codespell to CI [#11602](https://github.com/grafana/grafana/pull/11602), thx [@mjtrangoni](https://github.com/mjtrangoni) +- Migrated JavaScript files to TypeScript + +# 5.0.4 (2018-03-28) + +- **Docker** Can't start Grafana on Kubernetes 1.7.14, 1.8.9, or 1.9.4 [#140 in grafana-docker repo](https://github.com/grafana/grafana-docker/issues/140) thx [@suquant](https://github.com/suquant) +- **Dashboard** Fixed bug where collapsed panels could not be directly linked to/renderer [#11114](https://github.com/grafana/grafana/issues/11114) & [#11086](https://github.com/grafana/grafana/issues/11086) & [#11296](https://github.com/grafana/grafana/issues/11296) +- **Dashboard** Provisioning dashboard with alert rules should create alerts [#11247](https://github.com/grafana/grafana/issues/11247) +- **Snapshots** For snapshots, the Graph panel renders the legend incorrectly on right hand side [#11318](https://github.com/grafana/grafana/issues/11318) +- **Alerting** Link back to Grafana returns wrong URL if root_path contains sub-path components [#11403](https://github.com/grafana/grafana/issues/11403) +- **Alerting** Incorrect default value for upload images setting for alert notifiers [#11413](https://github.com/grafana/grafana/pull/11413) + +# 5.0.3 (2018-03-16) + +- **Mysql**: Mysql panic occurring occasionally upon Grafana dashboard access (a bigger patch than the one in 5.0.2) [#11155](https://github.com/grafana/grafana/issues/11155) + +# 5.0.2 (2018-03-14) + +- **Mysql**: Mysql panic occurring occasionally upon Grafana dashboard access [#11155](https://github.com/grafana/grafana/issues/11155) +- **Dashboards**: Should be possible to browse dashboard using only uid [#11231](https://github.com/grafana/grafana/issues/11231) +- **Alerting**: Fixes bug where alerts from hidden panels where deleted [#11222](https://github.com/grafana/grafana/issues/11222) +- **Import**: Fixes bug where dashboards with alerts couldn't be imported [#11227](https://github.com/grafana/grafana/issues/11227) +- **Teams**: Remove quota restrictions from teams [#11220](https://github.com/grafana/grafana/issues/11220) +- **Render**: Fixes bug with legacy url redirection for panel rendering [#11180](https://github.com/grafana/grafana/issues/11180) + +# 5.0.1 (2018-03-08) + +- **Postgres**: PostgreSQL error when using ipv6 address as hostname in connection string [#11055](https://github.com/grafana/grafana/issues/11055), thanks [@svenklemm](https://github.com/svenklemm) +- **Dashboards**: Changing templated value from dropdown is causing unsaved changes [#11063](https://github.com/grafana/grafana/issues/11063) +- **Prometheus**: Fixes bundled Prometheus 2.0 dashboard [#11016](https://github.com/grafana/grafana/issues/11016), thx [@roidelapluie](https://github.com/roidelapluie) +- **Sidemenu**: Profile menu "invisible" when gravatar is disabled [#11097](https://github.com/grafana/grafana/issues/11097) +- **Dashboard**: Fixes a bug with resizable handles for panels [#11103](https://github.com/grafana/grafana/issues/11103) +- **Alerting**: Telegram inline image mode fails when caption too long [#10975](https://github.com/grafana/grafana/issues/10975) +- **Alerting**: Fixes silent failing validation [#11145](https://github.com/grafana/grafana/pull/11145) +- **OAuth**: Only use jwt token if it contains an email address [#11127](https://github.com/grafana/grafana/pull/11127) + +# 5.0.0-stable (2018-03-01) + +### Fixes + +- **oauth** Fix GitHub OAuth not working with private Organizations [#11028](https://github.com/grafana/grafana/pull/11028) [@lostick](https://github.com/lostick) +- **kiosk** white area over bottom panels in kiosk mode [#11010](https://github.com/grafana/grafana/issues/11010) +- **alerting** Fix OK state doesn't show up in Microsoft Teams [#11032](https://github.com/grafana/grafana/pull/11032), thx [@manacker](https://github.com/manacker) + +# 5.0.0-beta5 (2018-02-26) + +### Fixes + +- **Orgs** Unable to switch org when too many orgs listed [#10774](https://github.com/grafana/grafana/issues/10774) +- **Folders** Make it easier/explicit to access/modify folders using the API [#10630](https://github.com/grafana/grafana/issues/10630) +- **Dashboard** Scrollbar works incorrectly in Grafana 5.0 Beta4 in some cases [#10982](https://github.com/grafana/grafana/issues/10982) +- **ElasticSearch** Custom aggregation sizes no longer allowed for Elasticsearch [#10124](https://github.com/grafana/grafana/issues/10124) +- **oauth** GitHub OAuth with allowed organizations fails to login [#10964](https://github.com/grafana/grafana/issues/10964) +- **heatmap** Heatmap panel has partially hidden legend [#10793](https://github.com/grafana/grafana/issues/10793) +- **snapshots** Expired snapshots not being cleaned up [#10996](https://github.com/grafana/grafana/pull/10996) + +# 5.0.0-beta4 (2018-02-19) + +### Fixes + +- **Dashboard** Fixed dashboard overwrite permission issue [#10814](https://github.com/grafana/grafana/issues/10814) +- **Keyboard shortcuts** Fixed Esc key when in panel edit/view mode [#10945](https://github.com/grafana/grafana/issues/10945) +- **Save dashboard** Fixed issue with time range & variable reset after saving [#10946](https://github.com/grafana/grafana/issues/10946) + +# 5.0.0-beta3 (2018-02-16) + +### Fixes + +- **MySQL** Fixed new migration issue with index length [#10931](https://github.com/grafana/grafana/issues/10931) +- **Modal** Escape key no closes modals everywhere, fixes [#10887](https://github.com/grafana/grafana/issues/10887) +- **Row repeats** Fix for repeating rows issue, fixes [#10932](https://github.com/grafana/grafana/issues/10932) +- **Docs** Team api documented, fixes [#10832](https://github.com/grafana/grafana/issues/10832) +- **Plugins** Plugin info page broken, fixes [#10943](https://github.com/grafana/grafana/issues/10943) + +# 5.0.0-beta2 (2018-02-15) + +### Fixes + +- **Permissions** Fixed search permissions issues [#10822](https://github.com/grafana/grafana/issues/10822) +- **Permissions** Fixed problem issues displaying permissions lists [#10864](https://github.com/grafana/grafana/issues/10864) +- **PNG-Rendering** Fixed problem rendering legend to the right [#10526](https://github.com/grafana/grafana/issues/10526) +- **Reset password** Fixed problem with reset password form [#10870](https://github.com/grafana/grafana/issues/10870) +- **Light theme** Fixed problem with light theme in safari, [#10869](https://github.com/grafana/grafana/issues/10869) +- **Provisioning** Now handles deletes when dashboard json files removed from disk [#10865](https://github.com/grafana/grafana/issues/10865) +- **MySQL** Fixed issue with schema migration on old mysql (index too long) [#10779](https://github.com/grafana/grafana/issues/10779) +- **GitHub OAuth** Fixed fetching github orgs from private github org [#10823](https://github.com/grafana/grafana/issues/10823) +- **Embedding** Fixed issues embedding panel [#10787](https://github.com/grafana/grafana/issues/10787) + +# 5.0.0-beta1 (2018-02-05) + +Grafana v5.0 is going to be the biggest and most foundational release Grafana has ever had, coming with a ton of UX improvements, a new dashboard grid engine, dashboard folders, user teams and permissions. Checkout out this [video preview](https://www.youtube.com/watch?v=Izr0IBgoTZQ) of Grafana v5. + +### New Major Features + +- **Dashboards** Dashboard folders, [#1611](https://github.com/grafana/grafana/issues/1611) +- **Teams** User groups (teams) implemented. Can be used in folder & dashboard permission list. +- **Dashboard grid**: Panels are now laid out in a two dimensional grid (with x, y, w, h). [#9093](https://github.com/grafana/grafana/issues/9093). +- **Templating**: Vertical repeat direction for panel repeats. +- **UX**: Major update to page header and navigation +- **Dashboard settings**: Combine dashboard settings views into one with side menu, [#9750](https://github.com/grafana/grafana/issues/9750) +- **Persistent dashboard url's**: New url's for dashboards that allows renaming dashboards without breaking links. [#7883](https://github.com/grafana/grafana/issues/7883) + +## Breaking changes + +- **[dashboard.json]** have been replaced with [dashboard provisioning](http://docs.grafana.org/administration/provisioning/). + Config files for provisioning data sources as configuration have changed from `/conf/datasources` to `/conf/provisioning/datasources`. + From `/etc/grafana/datasources` to `/etc/grafana/provisioning/datasources` when installed with deb/rpm packages. + +- **Pagerduty** The notifier now defaults to not auto resolve incidents. More details at [#10222](https://github.com/grafana/grafana/issues/10222) + +- **HTTP API** + - `GET /api/alerts` property dashboardUri renamed to url and is now the full url (that is including app sub url). + +## New Dashboard Grid + +The new grid engine is a major upgrade for how you can position and move panels. It enables new layouts and a much easier dashboard building experience. The change is backward compatible. So you can upgrade your current version to 5.0 without breaking dashboards, but you cannot downgrade from 5.0 to previous versions. Grafana will automatically upgrade your dashboards to the new schema and position panels to match your existing layout. There might be minor differences in panel height. If you upgrade to 5.0 and for some reason want to rollback to the previous version you can restore dashboards to previous versions using dashboard history. But that should only be seen as an emergency solution. + +Dashboard panels and rows are positioned using a gridPos object `{x: 0, y: 0, w: 24, h: 5}`. Units are in grid dimensions (24 columns, 1 height unit 30px). Rows and Panels objects exist (together) in a flat array directly on the dashboard root object. Rows are not needed for layouts anymore and are mainly there for backward compatibility. Some panel plugins that do not respect their panel height might require an update. + +## New Features + +- **Alerting**: Add support for internal image store [#6922](https://github.com/grafana/grafana/issues/6922), thx [@FunkyM](https://github.com/FunkyM) +- **Data Source Proxy**: Add support for whitelisting specified cookies that will be passed through to the data source when proxying data source requests [#5457](https://github.com/grafana/grafana/issues/5457), thanks [@robingustafsson](https://github.com/robingustafsson) +- **Postgres/MySQL**: add \_\_timeGroup macro for mysql [#9596](https://github.com/grafana/grafana/pull/9596), thanks [@svenklemm](https://github.com/svenklemm) +- **Text**: Text panel are now edited in the ace editor. [#9698](https://github.com/grafana/grafana/pull/9698), thx [@mtanda](https://github.com/mtanda) +- **Teams**: Add Microsoft Teams notifier as [#8523](https://github.com/grafana/grafana/issues/8523), thx [@anthu](https://github.com/anthu) +- **Data Sources**: Its now possible to configure data sources with config files [#1789](https://github.com/grafana/grafana/issues/1789) +- **Graphite**: Query editor updated to support new query by tag features [#9230](https://github.com/grafana/grafana/issues/9230) +- **Dashboard history**: New config file option versions_to_keep sets how many versions per dashboard to store, [#9671](https://github.com/grafana/grafana/issues/9671) +- **Dashboard as cfg**: Load dashboards from file into Grafana on startup/change [#9654](https://github.com/grafana/grafana/issues/9654) [#5269](https://github.com/grafana/grafana/issues/5269) +- **Prometheus**: Grafana can now send alerts to Prometheus Alertmanager while firing [#7481](https://github.com/grafana/grafana/issues/7481), thx [@Thib17](https://github.com/Thib17) and [@mtanda](https://github.com/mtanda) +- **Table**: Support multiple table formatted queries in table panel [#9170](https://github.com/grafana/grafana/issues/9170), thx [@davkal](https://github.com/davkal) +- **Security**: Protect against brute force (frequent) login attempts [#7616](https://github.com/grafana/grafana/issues/7616) + +## Minor + +- **Graph**: Don't hide graph display options (Lines/Points) when draw mode is unchecked [#9770](https://github.com/grafana/grafana/issues/9770), thx [@Jonnymcc](https://github.com/Jonnymcc) +- **Prometheus**: Show label name in paren after by/without/on/ignoring/group_left/group_right [#9664](https://github.com/grafana/grafana/pull/9664), thx [@mtanda](https://github.com/mtanda) +- **Alert panel**: Adds placeholder text when no alerts are within the time range [#9624](https://github.com/grafana/grafana/issues/9624), thx [@straend](https://github.com/straend) +- **Mysql**: MySQL enable MaxOpenCon and MaxIdleCon regards how constring is configured. [#9784](https://github.com/grafana/grafana/issues/9784), thx [@dfredell](https://github.com/dfredell) +- **Cloudwatch**: Fixes broken query inspector for cloudwatch [#9661](https://github.com/grafana/grafana/issues/9661), thx [@mtanda](https://github.com/mtanda) +- **Dashboard**: Make it possible to start dashboards from search and dashboard list panel [#1871](https://github.com/grafana/grafana/issues/1871) +- **Annotations**: Posting annotations now return the id of the annotation [#9798](https://github.com/grafana/grafana/issues/9798) +- **Systemd**: Use systemd notification ready flag [#10024](https://github.com/grafana/grafana/issues/10024), thx [@jgrassler](https://github.com/jgrassler) +- **GitHub**: Use organizations_url provided from github to verify user belongs in org. [#10111](https://github.com/grafana/grafana/issues/10111), thx + [@adiletmaratov](https://github.com/adiletmaratov) +- **Backend**: Fixed bug where Grafana exited before all sub routines where finished [#10131](https://github.com/grafana/grafana/issues/10131) +- **Azure**: Adds support for Azure blob storage as external image stor [#8955](https://github.com/grafana/grafana/issues/8955), thx [@saada](https://github.com/saada) +- **Telegram**: Add support for inline image uploads to telegram notifier plugin [#9967](https://github.com/grafana/grafana/pull/9967), thx [@rburchell](https://github.com/rburchell) + +## Fixes + +- **Sensu**: Send alert message to sensu output [#9551](https://github.com/grafana/grafana/issues/9551), thx [@cjchand](https://github.com/cjchand) +- **Singlestat**: suppress error when result contains no datapoints [#9636](https://github.com/grafana/grafana/issues/9636), thx [@utkarshcmu](https://github.com/utkarshcmu) +- **Postgres/MySQL**: Control quoting in SQL-queries when using template variables [#9030](https://github.com/grafana/grafana/issues/9030), thanks [@svenklemm](https://github.com/svenklemm) +- **Pagerduty**: Pagerduty don't auto resolve incidents by default anymore. [#10222](https://github.com/grafana/grafana/issues/10222) +- **Cloudwatch**: Fix for multi-valued templated queries. [#9903](https://github.com/grafana/grafana/issues/9903) + +## Tech + +- **RabbitMq**: Remove support for publishing events to RabbitMQ [#9645](https://github.com/grafana/grafana/issues/9645) + +## Deprecation notes + +### HTTP API + +The following operations have been deprecated and will be removed in a future release: + +- `GET /api/dashboards/db/:slug` -> Use `GET /api/dashboards/uid/:uid` instead +- `DELETE /api/dashboards/db/:slug` -> Use `DELETE /api/dashboards/uid/:uid` instead + +The following properties have been deprecated and will be removed in a future release: + +- `uri` property in `GET /api/search` -> Use new `url` or `uid` property instead +- `meta.slug` property in `GET /api/dashboards/uid/:uid` and `GET /api/dashboards/db/:slug` -> Use new `meta.url` or `dashboard.uid` property instead + +# 4.6.4 (2018-08-29) + +### Important fix for LDAP & OAuth login vulnerability + +See [security announcement](https://community.grafana.com/t/grafana-5-2-3-and-4-6-4-security-update/10050) for details. + +# 4.6.3 (2017-12-14) + +## Fixes + +- **Gzip**: Fixes bug gravatar images when gzip was enabled [#5952](https://github.com/grafana/grafana/issues/5952) +- **Alert list**: Now shows alert state changes even after adding manual annotations on dashboard [#9951](https://github.com/grafana/grafana/issues/9951) +- **Alerting**: Fixes bug where rules evaluated as firing when all conditions was false and using OR operator. [#9318](https://github.com/grafana/grafana/issues/9318) +- **Cloudwatch**: CloudWatch no longer display metrics' default alias [#10151](https://github.com/grafana/grafana/issues/10151), thx [@mtanda](https://github.com/mtanda) + +# 4.6.2 (2017-11-16) + +## Important + +- **Prometheus**: Fixes bug with new prometheus alerts in Grafana. Make sure to download this version if you're using Prometheus for alerting. More details in the issue. [#9777](https://github.com/grafana/grafana/issues/9777) + +## Fixes + +- **Color picker**: Bug after using textbox input field to change/paste color string [#9769](https://github.com/grafana/grafana/issues/9769) +- **Cloudwatch**: Fix for cloudwatch templating query `ec2_instance_attribute` [#9667](https://github.com/grafana/grafana/issues/9667), thanks [@mtanda](https://github.com/mtanda) +- **Heatmap**: Fixed tooltip for "time series buckets" mode [#9332](https://github.com/grafana/grafana/issues/9332) +- **InfluxDB**: Fixed query editor issue when using `>` or `<` operators in WHERE clause [#9871](https://github.com/grafana/grafana/issues/9871) + +# 4.6.1 (2017-11-01) + +- **Singlestat**: Lost thresholds when using save dashboard as [#9681](https://github.com/grafana/grafana/issues/9681) +- **Graph**: Fix for series override color picker [#9715](https://github.com/grafana/grafana/issues/9715) +- **Go**: build using golang 1.9.2 [#9713](https://github.com/grafana/grafana/issues/9713) +- **Plugins**: Fixed problem with loading plugin js files behind auth proxy [#9509](https://github.com/grafana/grafana/issues/9509) +- **Graphite**: Annotation tooltip should render empty string when undefined [#9707](https://github.com/grafana/grafana/issues/9707) + +# 4.6.0 (2017-10-26) + +## Fixes + +- **Alerting**: Viewer can no longer pause alert rules [#9640](https://github.com/grafana/grafana/issues/9640) +- **Playlist**: Bug where playlist controls was missing [#9639](https://github.com/grafana/grafana/issues/9639) +- **Firefox**: Creating region annotations now work in firefox [#9638](https://github.com/grafana/grafana/issues/9638) + +# 4.6.0-beta3 (2017-10-23) + +## Fixes + +- **Prometheus**: Fix for browser crash for short time ranges. [#9575](https://github.com/grafana/grafana/issues/9575) +- **Heatmap**: Fix for y-axis not showing. [#9576](https://github.com/grafana/grafana/issues/9576) +- **Save to file**: Fix for save to file in export modal. [#9586](https://github.com/grafana/grafana/issues/9586) +- **Postgres**: modify group by time macro so it can be used in select clause [#9527](https://github.com/grafana/grafana/pull/9527), thanks [@svenklemm](https://github.com/svenklemm) + +# 4.6.0-beta2 (2017-10-17) + +## Fixes + +- **ColorPicker**: Fix for color picker not showing [#9549](https://github.com/grafana/grafana/issues/9549) +- **Alerting**: Fix for broken test rule button in alert tab [#9539](https://github.com/grafana/grafana/issues/9539) +- **Cloudwatch**: Provide error message when failing to add cloudwatch data source [#9534](https://github.com/grafana/grafana/pull/9534), thx [@mtanda](https://github.com/mtanda) +- **Cloudwatch**: Fix unused period parameter [#9536](https://github.com/grafana/grafana/pull/9536), thx [@mtanda](https://github.com/mtanda) +- **CSV Export**: Fix for broken CSV export [#9525](https://github.com/grafana/grafana/issues/9525) +- **Text panel**: Fix for issue with break lines in Firefox [#9491](https://github.com/grafana/grafana/issues/9491) +- **Annotations**: Fix for issue saving annotation event in MySQL DB [#9550](https://github.com/grafana/grafana/issues/9550), thanks [@krise3k](https://github.com/krise3k) + +# 4.6.0-beta1 (2017-10-13) + +## New Features + +- **Annotations**: Add support for creating annotations from graph panel [#8197](https://github.com/grafana/grafana/pull/8197) +- **GCS**: Adds support for Google Cloud Storage [#8370](https://github.com/grafana/grafana/issues/8370) thx [@chuhlomin](https://github.com/chuhlomin) +- **Prometheus**: Adds /metrics endpoint for exposing Grafana metrics. [#9187](https://github.com/grafana/grafana/pull/9187) +- **Graph**: Add support for local formatting in axis. [#1395](https://github.com/grafana/grafana/issues/1395), thx [@m0nhawk](https://github.com/m0nhawk) +- **Jaeger**: Add support for open tracing using jaeger in Grafana. [#9213](https://github.com/grafana/grafana/pull/9213) +- **Unit types**: New date & time unit types added, useful in singlestat to show dates & times. [#3678](https://github.com/grafana/grafana/issues/3678), [#6710](https://github.com/grafana/grafana/issues/6710), [#2764](https://github.com/grafana/grafana/issues/2764) +- **CLI**: Make it possible to install plugins from any url [#5873](https://github.com/grafana/grafana/issues/5873) +- **Prometheus**: Add support for instant queries [#5765](https://github.com/grafana/grafana/issues/5765), thx [@mtanda](https://github.com/mtanda) +- **Cloudwatch**: Add support for alerting using the cloudwatch data source [#8050](https://github.com/grafana/grafana/pull/8050), thx [@mtanda](https://github.com/mtanda) +- **Pagerduty**: Include triggering series in pagerduty notification [#8479](https://github.com/grafana/grafana/issues/8479), thx [@rickymoorhouse](https://github.com/rickymoorhouse) +- **Timezone**: Time ranges like Today & Yesterday now work correctly when timezone setting is set to UTC [#8916](https://github.com/grafana/grafana/issues/8916), thx [@ctide](https://github.com/ctide) +- **Prometheus**: Align \$\_\_interval with the step parameters. [#9226](https://github.com/grafana/grafana/pull/9226), thx [@alin-amana](https://github.com/alin-amana) +- **Prometheus**: Autocomplete for label name and label value [#9208](https://github.com/grafana/grafana/pull/9208), thx [@mtanda](https://github.com/mtanda) +- **Postgres**: New Postgres data source [#9209](https://github.com/grafana/grafana/pull/9209), thx [@svenklemm](https://github.com/svenklemm) +- **Data sources**: Make data source HTTP requests verify TLS by default. closes [#9371](https://github.com/grafana/grafana/issues/9371), [#5334](https://github.com/grafana/grafana/issues/5334), [#8812](https://github.com/grafana/grafana/issues/8812), thx [@mattbostock](https://github.com/mattbostock) +- **OAuth**: Verify TLS during OAuth callback [#9373](https://github.com/grafana/grafana/issues/9373), thx [@mattbostock](https://github.com/mattbostock) + +## Minor + +- **SMTP**: Make it possible to set specific HELO for smtp client. [#9319](https://github.com/grafana/grafana/issues/9319) +- **Dataproxy**: Allow grafana to renegotiate tls connection [#9250](https://github.com/grafana/grafana/issues/9250) +- **HTTP**: set net.Dialer.DualStack to true for all http clients [#9367](https://github.com/grafana/grafana/pull/9367) +- **Alerting**: Add diff and percent diff as series reducers [#9386](https://github.com/grafana/grafana/pull/9386), thx [@shanhuhai5739](https://github.com/shanhuhai5739) +- **Slack**: Allow images to be uploaded to slack when Token is present [#7175](https://github.com/grafana/grafana/issues/7175), thx [@xginn8](https://github.com/xginn8) +- **Opsgenie**: Use their latest API instead of old version [#9399](https://github.com/grafana/grafana/pull/9399), thx [@cglrkn](https://github.com/cglrkn) +- **Table**: Add support for displaying the timestamp with milliseconds [#9429](https://github.com/grafana/grafana/pull/9429), thx [@s1061123](https://github.com/s1061123) +- **Hipchat**: Add metrics, message and image to hipchat notifications [#9110](https://github.com/grafana/grafana/issues/9110), thx [@eloo](https://github.com/eloo) +- **Kafka**: Add support for sending alert notifications to kafka [#7104](https://github.com/grafana/grafana/issues/7104), thx [@utkarshcmu](https://github.com/utkarshcmu) +- **Alerting**: add count_non_null as series reducer [#9516](https://github.com/grafana/grafana/issues/9516) + +## Tech + +- **Go**: Grafana is now built using golang 1.9 +- **Webpack**: Changed from systemjs to webpack (see readme or building from source guide for new build instructions). Systemjs is still used to load plugins but now plugins can only import a limited set of dependencies. See [PLUGIN_DEV.md](https://github.com/grafana/grafana/blob/master/PLUGIN_DEV.md) for more details on how this can effect some plugins. + +# 4.5.2 (2017-09-22) + +## Fixes + +- **Graphite**: Fix for issues with jsonData & graphiteVersion null errors [#9258](https://github.com/grafana/grafana/issues/9258) +- **Graphite**: Fix for Grafana internal metrics to Graphite sending NaN values [#9279](https://github.com/grafana/grafana/issues/9279) +- **HTTP API**: Fix for HEAD method requests [#9307](https://github.com/grafana/grafana/issues/9307) +- **Templating**: Fix for duplicate template variable queries when refresh is set to time range change [#9185](https://github.com/grafana/grafana/issues/9185) +- **Metrics**: don't write NaN values to graphite [#9279](https://github.com/grafana/grafana/issues/9279) + +# 4.5.1 (2017-09-15) + +## Fixes + +- **MySQL**: Fixed issue with query editor not showing [#9247](https://github.com/grafana/grafana/issues/9247) + +## Breaking changes + +- **Metrics**: The metric structure for internal metrics about Grafana published to graphite has changed. This might break dashboards for internal metrics. + +# 4.5.0 (2017-09-14) + +## Fixes & Enhancements since beta1 + +- **Security**: Security fix for api vulnerability (in multiple org setups). +- **Shortcuts**: Adds shortcut for creating new dashboard [#8876](https://github.com/grafana/grafana/pull/8876) thx [@mtanda](https://github.com/mtanda) +- **Graph**: Right Y-Axis label position fixed [#9172](https://github.com/grafana/grafana/pull/9172) +- **General**: Improve rounding of time intervals [#9197](https://github.com/grafana/grafana/pull/9197), thx [@alin-amana](https://github.com/alin-amana) + +# 4.5.0-beta1 (2017-09-05) + +## New Features + +- **Table panel**: Render cell values as links that can have an url template that uses variables from current table row. [#3754](https://github.com/grafana/grafana/issues/3754) +- **Elasticsearch**: Add ad hoc filters directly by clicking values in table panel [#8052](https://github.com/grafana/grafana/issues/8052). +- **MySQL**: New rich query editor with syntax highlighting +- **Prometheus**: New rich query editor with syntax highlighting, metric & range auto complete and integrated function docs. [#5117](https://github.com/grafana/grafana/issues/5117) + +## Enhancements + +- **GitHub OAuth**: Support for GitHub organizations with 100+ teams. [#8846](https://github.com/grafana/grafana/issues/8846), thx [@skwashd](https://github.com/skwashd) +- **Graphite**: Calls to Graphite api /metrics/find now include panel or dashboard time range (from & until) in most cases, [#8055](https://github.com/grafana/grafana/issues/8055) +- **Graphite**: Added new graphite 1.0 functions, available if you set version to 1.0.x in data source settings. New Functions: mapSeries, reduceSeries, isNonNull, groupByNodes, offsetToZero, grep, weightedAverage, removeEmptySeries, aggregateLine, averageOutsidePercentile, delay, exponentialMovingAverage, fallbackSeries, integralByInterval, interpolate, invert, linearRegression, movingMin, movingMax, movingSum, multiplySeriesWithWildcards, pow, powSeries, removeBetweenPercentile, squareRoot, timeSlice, closes [#8261](https://github.com/grafana/grafana/issues/8261) + +- **Elasticsearch**: Ad-hoc filters now use query phrase match filters instead of term filters, works on non keyword/raw fields [#9095](https://github.com/grafana/grafana/issues/9095). + +### Breaking change + +- **InfluxDB/Elasticsearch**: The panel & data source option named "Group by time interval" is now named "Min time interval" and does now always define a lower limit for the auto group by time. Without having to use `>` prefix (that prefix still works). This should in theory have close to zero actual impact on existing dashboards. It does mean that if you used this setting to define a hard group by time interval of, say "1d", if you zoomed to a time range wide enough the time range could increase above the "1d" range as the setting is now always considered a lower limit. +- **Elasticsearch**: Elasticsearch metric queries without date histogram now return table formatted data making table panel much easier to use for this use case. Should not break/change existing dashboards with stock panels but external panel plugins can be affected. + +## Changes + +- **InfluxDB**: Change time range filter for absolute time ranges to be inclusive instead of exclusive [#8319](https://github.com/grafana/grafana/issues/8319), thx [@Oxydros](https://github.com/Oxydros) +- **InfluxDB**: Added parenthesis around tag filters in queries [#9131](https://github.com/grafana/grafana/pull/9131) + +## Bug Fixes + +- **Modals**: Maintain scroll position after opening/leaving modal [#8800](https://github.com/grafana/grafana/issues/8800) +- **Templating**: You cannot select data source variables as data source for other template variables [#7510](https://github.com/grafana/grafana/issues/7510) +- **MySQL/Postgres**: Fix for max_idle_conn option default which was wrongly set to zero which does not mean unlimited but means zero, which in practice kind of disables connection pooling, which is not good. Fixes [#8513](https://github.com/grafana/grafana/issues/8513) + +# 4.4.3 (2017-08-07) + +## Bug Fixes + +- **Search**: Fix for issue that caused search view to hide when you clicked starred or tags filters, fixes [#8981](https://github.com/grafana/grafana/issues/8981) +- **Modals**: ESC key now closes modal again, fixes [#8981](https://github.com/grafana/grafana/issues/8988), thx [@j-white](https://github.com/j-white) + +# 4.4.2 (2017-08-01) + +## Bug Fixes + +- **GrafanaDB(mysql)**: Fix for dashboard_version.data column type, now changed to MEDIUMTEXT, fixes [#8813](https://github.com/grafana/grafana/issues/8813) +- **Dashboard(settings)**: Closing setting views using ESC key did not update url correctly, fixes [#8869](https://github.com/grafana/grafana/issues/8869) +- **InfluxDB**: Wrong username/password parameter name when using direct access, fixes [#8789](https://github.com/grafana/grafana/issues/8789) +- **Forms(TextArea)**: Bug fix for no scroll in text areas [#8797](https://github.com/grafana/grafana/issues/8797) +- **Png Render API**: Bug fix for timeout url parameter. It now works as it should. Default value was also increased from 30 to 60 seconds [#8710](https://github.com/grafana/grafana/issues/8710) +- **Search**: Fix for not being able to close search by clicking on right side of search result container, [8848](https://github.com/grafana/grafana/issues/8848) +- **Cloudwatch**: Fix for using variables in templating metrics() query, [8965](https://github.com/grafana/grafana/issues/8965) + +## Changes + +- **Settings(defaults)**: allow_sign_up default changed from true to false [#8743](https://github.com/grafana/grafana/issues/8743) +- **Settings(defaults)**: allow_org_create default changed from true to false + +# 4.4.1 (2017-07-05) + +## Bug Fixes + +- **Migrations**: migration fails where dashboard.created_by is null [#8783](https://github.com/grafana/grafana/issues/8783) + +# 4.4.0 (2017-07-04) + +## New Features + +**Dashboard History**: View dashboard version history, compare any two versions (summary & json diffs), restore to old version. This big feature +was contributed by **Walmart Labs**. Big thanks to them for this massive contribution! +Initial feature request: [#4638](https://github.com/grafana/grafana/issues/4638) +Pull Request: [#8472](https://github.com/grafana/grafana/pull/8472) + +## Enhancements + +- **Elasticsearch**: Added filter aggregation label [#8420](https://github.com/grafana/grafana/pull/8420), thx [@tianzk](github.com/tianzk) +- **Sensu**: Added option for source and handler [#8405](https://github.com/grafana/grafana/pull/8405), thx [@joemiller](github.com/joemiller) +- **CSV**: Configurable csv export datetime format [#8058](https://github.com/grafana/grafana/issues/8058), thx [@cederigo](github.com/cederigo) +- **Table Panel**: Column style that preserves formatting/indentation (like pre tag) [#6617](https://github.com/grafana/grafana/issues/6617) +- **DingDing**: Add DingDing Alert Notifier [#8473](https://github.com/grafana/grafana/pull/8473) thx [@jiamliang](https://github.com/jiamliang) + +## Minor Enhancements + +- **Elasticsearch**: Add option for result set size in raw_document [#3426](https://github.com/grafana/grafana/issues/3426) [#8527](https://github.com/grafana/grafana/pull/8527), thx [@mk-dhia](github.com/mk-dhia) + +## Bug Fixes + +- **Graph**: Bug fix for negative values in histogram mode [#8628](https://github.com/grafana/grafana/issues/8628) + +# 4.3.2 (2017-05-31) + +## Bug fixes + +- **InfluxDB**: Fixed issue with query editor not showing ALIAS BY input field when in text editor mode [#8459](https://github.com/grafana/grafana/issues/8459) +- **Graph Log Scale**: Fixed issue with log scale going below x-axis [#8244](https://github.com/grafana/grafana/issues/8244) +- **Playlist**: Fixed dashboard play order issue [#7688](https://github.com/grafana/grafana/issues/7688) +- **Elasticsearch**: Fixed table query issue with ES 2.x [#8467](https://github.com/grafana/grafana/issues/8467), thx [@goldeelox](https://github.com/goldeelox) + +## Changes + +- **Lazy Loading Of Panels**: Panels are no longer loaded as they are scrolled into view, this was reverted due to Chrome bug, might be reintroduced when Chrome fixes it's JS blocking behavior on scroll. [#8500](https://github.com/grafana/grafana/issues/8500) + +# 4.3.1 (2017-05-23) + +## Bug fixes + +- **S3 image upload**: Fixed image url issue for us-east-1 (us standard) region. If you were missing slack images for alert notifications this should fix it. [#8444](https://github.com/grafana/grafana/issues/8444) + +# 4.3.0-stable (2017-05-23) + +## Bug fixes + +- **Gzip**: Fixed crash when gzip was enabled [#8380](https://github.com/grafana/grafana/issues/8380) +- **Graphite**: Fixed issue with Toggle edit mode did in query editor [#8377](https://github.com/grafana/grafana/issues/8377) +- **Alerting**: Fixed issue with state history not showing query execution errors [#8412](https://github.com/grafana/grafana/issues/8412) +- **Alerting**: Fixed issue with missing state history events/annotations when using sqlite3 database [#7992](https://github.com/grafana/grafana/issues/7992) +- **Sqlite**: Fixed with database table locked and using sqlite3 database [#7992](https://github.com/grafana/grafana/issues/7992) +- **Alerting**: Fixed issue with annotations showing up in unsaved dashboards, new graph & alert panel. [#8361](https://github.com/grafana/grafana/issues/8361) +- **webdav**: Fixed http proxy env variable support for webdav image upload [#7922](https://github.com/grafana/grafana/issues/79222), thx [@berghauz](https://github.com/berghauz) +- **Prometheus**: Fixed issue with hiding query [#8413](https://github.com/grafana/grafana/issues/8413) + +## Enhancements + +- **VictorOps**: Now supports panel image & auto resolve [#8431](https://github.com/grafana/grafana/pull/8431), thx [@davidmscott](https://github.com/davidmscott) +- **Alerting**: Alert annotations now provide more info [#8421](https://github.com/grafana/grafana/pull/8421) + +# 4.3.0-beta1 (2017-05-12) + +## Enhancements + +- **InfluxDB**: influxdb query builder support for ORDER BY and LIMIT (allows TOPN queries) [#6065](https://github.com/grafana/grafana/issues/6065) Support influxdb's SLIMIT Feature [#7232](https://github.com/grafana/grafana/issues/7232) thx [@thuck](https://github.com/thuck) +- **Panels**: Delay loading & Lazy load panels as they become visible (scrolled into view) [#5216](https://github.com/grafana/grafana/issues/5216) thx [@jifwin](https://github.com/jifwin) +- **Graph**: Support auto grid min/max when using log scale [#3090](https://github.com/grafana/grafana/issues/3090), thx [@bigbenhur](https://github.com/bigbenhur) +- **Graph**: Support for histograms [#600](https://github.com/grafana/grafana/issues/600) +- **Prometheus**: Support table response formats (column per label) [#6140](https://github.com/grafana/grafana/issues/6140), thx [@mtanda](https://github.com/mtanda) +- **Single Stat Panel**: support for non time series data [#6564](https://github.com/grafana/grafana/issues/6564) +- **Server**: Monitoring Grafana (health check endpoint) [#3302](https://github.com/grafana/grafana/issues/3302) +- **Heatmap**: Heatmap Panel [#7934](https://github.com/grafana/grafana/pull/7934) +- **Elasticsearch**: histogram aggregation [#3164](https://github.com/grafana/grafana/issues/3164) + +## Minor Enhancements + +- **InfluxDB**: Small fix for the "glow" when focus the field for LIMIT and SLIMIT [#7799](https://github.com/grafana/grafana/pull/7799) thx [@thuck](https://github.com/thuck) +- **Prometheus**: Make Prometheus query field a textarea [#7663](https://github.com/grafana/grafana/issues/7663), thx [@hagen1778](https://github.com/hagen1778) +- **Prometheus**: Step parameter changed semantics to min step to reduce the load on Prometheus and rendering in browser [#8073](https://github.com/grafana/grafana/pull/8073), thx [@bobrik](https://github.com/bobrik) +- **Templating**: Should not be possible to create self-referencing (recursive) template variable definitions [#7614](https://github.com/grafana/grafana/issues/7614) thx [@thuck](https://github.com/thuck) +- **Cloudwatch**: Correctly obtain IAM roles within ECS container tasks [#7892](https://github.com/grafana/grafana/issues/7892) thx [@gomlgs](https://github.com/gomlgs) +- **Units**: New number format: Scientific notation [#7781](https://github.com/grafana/grafana/issues/7781) thx [@cadnce](https://github.com/cadnce) +- **Oauth**: Add common type for oauth authorization errors [#6428](https://github.com/grafana/grafana/issues/6428) thx [@amenzhinsky](https://github.com/amenzhinsky) +- **Templating**: Data source variable now supports multi value and panel repeats [#7030](https://github.com/grafana/grafana/issues/7030) thx [@mtanda](https://github.com/mtanda) +- **Telegram**: Telegram alert is not sending metric and legend. [#8110](https://github.com/grafana/grafana/issues/8110), thx [@bashgeek](https://github.com/bashgeek) +- **Graph**: Support dashed lines [#514](https://github.com/grafana/grafana/issues/514), thx [@smalik03](https://github.com/smalik03) +- **Table**: Support to change column header text [#3551](https://github.com/grafana/grafana/issues/3551) +- **Alerting**: Better error when SMTP is not configured [#8093](https://github.com/grafana/grafana/issues/8093) +- **Pushover**: Add an option to attach graph image link in Pushover notification [#8043](https://github.com/grafana/grafana/issues/8043) thx [@devkid](https://github.com/devkid) +- **WebDAV**: Allow to set different ImageBaseUrl for WebDAV upload and image link [#7914](https://github.com/grafana/grafana/issues/7914) +- **Panels**: type-ahead mixed data source selection [#7697](https://github.com/grafana/grafana/issues/7697) thx [@mtanda](https://github.com/mtanda) +- **Security**:User enumeration problem [#7619](https://github.com/grafana/grafana/issues/7619) +- **InfluxDB**: Register new queries available in InfluxDB - Holt Winters [#5619](https://github.com/grafana/grafana/issues/5619) thx [@rikkuness](https://github.com/rikkuness) +- **Server**: Support listening on a UNIX socket [#4030](https://github.com/grafana/grafana/issues/4030), thx [@mitjaziv](https://github.com/mitjaziv) +- **Graph**: Support log scaling for values smaller 1 [#5278](https://github.com/grafana/grafana/issues/5278) +- **InfluxDB**: Slow 'select measurement' rendering for InfluxDB [#2524](https://github.com/grafana/grafana/issues/2524), thx [@sbhenderson](https://github.com/sbhenderson) +- **Config**: Configurable signout menu activation [#7968](https://github.com/grafana/grafana/pull/7968), thx [@seuf](https://github.com/seuf) + +## Fixes + +- **Table Panel**: Fixed annotation display in table panel, [#8023](https://github.com/grafana/grafana/issues/8023) +- **Dashboard**: If refresh is blocked due to tab not visible, then refresh when it becomes visible [#8076](https://github.com/grafana/grafana/issues/8076) thanks [@SimenB](https://github.com/SimenB) +- **Snapshots**: Fixed problem with annotations & snapshots [#7659](https://github.com/grafana/grafana/issues/7659) +- **Graph**: MetricSegment loses type when value is an asterisk [#8277](https://github.com/grafana/grafana/issues/8277), thx [@Gordiychuk](https://github.com/Gordiychuk) +- **Alerting**: Alert notifications do not show charts when using a non public S3 bucket [#8250](https://github.com/grafana/grafana/issues/8250) thx [@rogerswingle](https://github.com/rogerswingle) +- **Graph**: 100% client CPU usage on red alert glow animation [#8222](https://github.com/grafana/grafana/issues/8222) +- **InfluxDB**: Templating: "All" query does match too much [#8165](https://github.com/grafana/grafana/issues/8165) +- **Dashboard**: Description tooltip is not fully displayed [#7970](https://github.com/grafana/grafana/issues/7970) +- **Proxy**: Redirect after switching Org does not obey sub path in root_url (using reverse proxy) [#8089](https://github.com/grafana/grafana/issues/8089) +- **Templating**: Restoration of ad-hoc variable from URL does not work correctly [#8056](https://github.com/grafana/grafana/issues/8056) thx [@tamayika](https://github.com/tamayika) +- **InfluxDB**: timeFilter cannot be used twice in alerts [#7969](https://github.com/grafana/grafana/issues/7969) +- **MySQL**: 4-byte UTF8 not supported when using MySQL database (allows Emojis) [#7958](https://github.com/grafana/grafana/issues/7958) +- **Alerting**: api/alerts and api/alert/:id hold previous data for "message" and "Message" field when field value is changed from "some string" to empty string. [#7927](https://github.com/grafana/grafana/issues/7927) +- **Graph**: Cannot add fill below to series override [#7916](https://github.com/grafana/grafana/issues/7916) +- **InfluxDB**: Influxb Data source test passes even if the Database doesn't exist [#7864](https://github.com/grafana/grafana/issues/7864) +- **Prometheus**: Displaying Prometheus annotations is incredibly slow [#7750](https://github.com/grafana/grafana/issues/7750), thx [@mtanda](https://github.com/mtanda) +- **Graphite**: grafana generates empty find query to graphite -> 422 Unprocessable Entity [#7740](https://github.com/grafana/grafana/issues/7740) +- **Admin**: make organization filter case insensitive [#8194](https://github.com/grafana/grafana/issues/8194), thx [@Alexander-N](https://github.com/Alexander-N) + +## Changes + +- **Elasticsearch**: Changed elasticsearch Terms aggregation to default to Min Doc Count to 1, and sort order to Top [#8321](https://github.com/grafana/grafana/issues/8321) + +## Tech + +- **Library Upgrade**: inconshreveable/log15 outdated - no support for solaris [#8262](https://github.com/grafana/grafana/issues/8262) +- **Library Upgrade**: Upgrade Macaron [#7600](https://github.com/grafana/grafana/issues/7600) + +# 4.2.0 (2017-03-22) + +## Minor Enhancements + +- **Templates**: Prevent use of the prefix `__` for templates in web UI [#7678](https://github.com/grafana/grafana/issues/7678) +- **Threema**: Add emoji to Threema alert notifications [#7676](https://github.com/grafana/grafana/pull/7676) thx [@dbrgn](https://github.com/dbrgn) +- **Panels**: Support dm3 unit [#7695](https://github.com/grafana/grafana/issues/7695) thx [@mitjaziv](https://github.com/mitjaziv) +- **Docs**: Added some details about Sessions in Postgres [#7694](https://github.com/grafana/grafana/pull/7694) thx [@rickard-von-essen](https://github.com/rickard-von-essen) +- **Influxdb**: Allow commas in template variables [#7681](https://github.com/grafana/grafana/issues/7681) thx [@thuck](https://github.com/thuck) +- **Cloudwatch**: stop using deprecated session.New() [#7736](https://github.com/grafana/grafana/issues/7736) thx [@mtanda](https://github.com/mtanda) + \*TSDB**: Fix always take dashboard timezone into consideration when handle custom time ranges**: Pass dropcounter rate option if no max counter and no reset value or reset value as 0 is specified [#7743](https://github.com/grafana/grafana/pull/7743) thx [@r4um](https://github.com/r4um) +- **Templating**: support full resolution for \$interval variable [#7696](https://github.com/grafana/grafana/pull/7696) thx [@mtanda](https://github.com/mtanda) +- **Elasticsearch**: Unique Count on string fields in ElasticSearch [#3536](https://github.com/grafana/grafana/issues/3536), thx [@pyro2927](https://github.com/pyro2927) +- **Templating**: Data source template variable that refers to other variable in regex filter [#6365](https://github.com/grafana/grafana/issues/6365) thx [@rlodge](https://github.com/rlodge) +- **Admin**: Global User List: add search and pagination [#7469](https://github.com/grafana/grafana/issues/7469) +- **User Management**: Invite UI is now disabled when login form is disabled [#7875](https://github.com/grafana/grafana/issues/7875) + +## Bugfixes + +- **Webhook**: Use proxy settings from environment variables [#7710](https://github.com/grafana/grafana/issues/7710) +- **Panels**: Deleting a dashboard with unsaved changes raises an error message [#7591](https://github.com/grafana/grafana/issues/7591) thx [@thuck](https://github.com/thuck) +- **Influxdb**: Query builder detects regex to easily for measurement [#7276](https://github.com/grafana/grafana/issues/7276) thx [@thuck](https://github.com/thuck) +- **Docs**: router_logging not documented [#7723](https://github.com/grafana/grafana/issues/7723) +- **Alerting**: Spelling mistake [#7739](https://github.com/grafana/grafana/pull/7739) thx [@woutersmit](https://github.com/woutersmit) +- **Alerting**: Graph legend scrolls to top when an alias is toggled/clicked [#7680](https://github.com/grafana/grafana/issues/7680) thx [@p4ddy1](https://github.com/p4ddy1) +- **Panels**: Fixed panel tooltip description after scrolling down [#7708](https://github.com/grafana/grafana/issues/7708) thx [@askomorokhov](https://github.com/askomorokhov) + +# 4.2.0-beta1 (2017-02-27) + +## Enhancements + +- **Telegram**: Added Telegram alert notifier [#7098](https://github.com/grafana/grafana/pull/7098), thx [@leonoff](https://github.com/leonoff) +- **Templating**: Make $\_\_interval and $\_\_interval_ms global built in variables that can be used in by any data source (in panel queries), closes [#7190](https://github.com/grafana/grafana/issues/7190), closes [#6582](https://github.com/grafana/grafana/issues/6582) +- **S3 Image Store**: External s3 image store (used in alert notifications) now support AWS IAM Roles, closes [#6985](https://github.com/grafana/grafana/issues/6985), [#7058](https://github.com/grafana/grafana/issues/7058) thx [@mtanda](https://github.com/mtanda) +- **SingleStat**: Implements diff aggregation method for singlestat [#7234](https://github.com/grafana/grafana/issues/7234), thx [@oliverpool](https://github.com/oliverpool) +- **Dataproxy**: Added setting to enable more verbose logging in dataproxy [#7209](https://github.com/grafana/grafana/pull/7209), thx [@Ricky-N](https://github.com/Ricky-N) +- **Alerting**: Better information about why an alert triggered [#7035](https://github.com/grafana/grafana/issues/7035) +- **LINE**: Add LINE as alerting notification channel [#7301](https://github.com/grafana/grafana/pull/7301), thx [@huydx](https://github.com/huydx) +- **LINE**: Adds image to notification message [#7417](https://github.com/grafana/grafana/pull/7417), thx [@Erliz](https://github.com/Erliz) +- **Hipchat**: Adds support for sending alert notifications to hipchat [#6451](https://github.com/grafana/grafana/issues/6451), thx [@jregovic](https://github.com/jregovic) +- **Alerting**: Uploading images for alert notifications is now optional [#7419](https://github.com/grafana/grafana/issues/7419) +- **Dashboard**: Adds shortcut for collapsing/expanding all rows [#552](https://github.com/grafana/grafana/issues/552), thx [@mtanda](https://github.com/mtanda) +- **Alerting**: Adds de duping of alert notifications [#7632](https://github.com/grafana/grafana/pull/7632) +- **Orgs**: Sharing dashboards using Grafana share feature will now redirect to correct org. [#1613](https://github.com/grafana/grafana/issues/1613) +- **Pushover**: Add Pushover alert notifications [#7526](https://github.com/grafana/grafana/pull/7526) thx [@devkid](https://github.com/devkid) +- **Threema**: Add Threema Gateway alert notification integration [#7482](https://github.com/grafana/grafana/pull/7482) thx [@dbrgn](https://github.com/dbrgn) + +## Minor Enhancements + +- **Optimization**: Never issue refresh event when Grafana tab is not visible [#7218](https://github.com/grafana/grafana/issues/7218), thx [@mtanda](https://github.com/mtanda) +- **Browser History**: Browser back/forward now works time ranges / zoom, [#7259](https://github.com/grafana/grafana/issues/7259) +- **Elasticsearch**: Support for Min Doc Count options in Terms aggregation [#7324](https://github.com/grafana/grafana/pull/7324), thx [@lpic10](https://github.com/lpic10) +- **Elasticsearch**: Term aggregation limit can now be changed in template queries [#7112](https://github.com/grafana/grafana/issues/7112), thx [@FFalcon](https://github.com/FFalcon) +- **Elasticsearch**: Ad-hoc filters now support all operators [#7612](https://github.com/grafana/grafana/issues/7612), thx [@tamayika](https://github.com/tamayika) +- **Graph**: Add full series name as title for legends. [#7493](https://github.com/grafana/grafana/pull/7493), thx [@kolobaev](https://github.com/kolobaev) +- **Table**: Add a message when queries returns no data. [#6109](https://github.com/grafana/grafana/issues/6109), thx [@xginn8](https://github.com/xginn8) +- **Graph**: Set max width for series names in legend tables. [#2385](https://github.com/grafana/grafana/issues/2385), thx [@kolobaev](https://github.com/kolobaev) +- **Database**: Allow max db connection pool configuration [#7427](https://github.com/grafana/grafana/issues/7427), thx [@huydx](https://github.com/huydx) +- **Data Sources** Delete datsource by name [#7476](https://github.com/grafana/grafana/issues/7476), thx [@huydx](https://github.com/huydx) +- **Dataproxy**: Only allow get that begins with api/ to access Prometheus [#7459](https://github.com/grafana/grafana/pull/7459), thx [@mtanda](https://github.com/mtanda) +- **Snapshot**: Make timeout for snapshot creation configurable [#7449](https://github.com/grafana/grafana/pull/7449) thx [@ryu1-sakai](https://github.com/ryu1-sakai) +- **Panels**: Add more physics units [#7554](https://github.com/grafana/grafana/pull/7554) thx [@ryantxu](https://github.com/ryantxu) +- **Email**: Add sender's name on email [#2131](https://github.com/grafana/grafana/issues/2131) thx [@jacobbednarz](https://github.com/jacobbednarz) +- **HTTPS**: Set tls 1.2 as lowest tls version. [#7347](https://github.com/grafana/grafana/pull/7347) thx [@roman-vynar](https://github.com/roman-vynar) +- **Table**: Added suppressing of empty results to table plugin. [#7602](https://github.com/grafana/grafana/pull/7602) thx [@LLIyRiK](https://github.com/LLIyRiK) + +## Tech + +- **Library Upgrade**: Upgraded angularjs from 1.5.8 to 1.6.1 [#7274](https://github.com/grafana/grafana/issues/7274) +- **Backend**: Grafana is now built using golang 1.8 + +## Bugfixes + +- **Alerting**: Fixes missing support for no_data and execution error when testing alerts [#7149](https://github.com/grafana/grafana/issues/7149) +- **Dashboard**: Avoid duplicate data in dashboard json for panels with alerts [#7256](https://github.com/grafana/grafana/pull/7256) +- **Alertlist**: Only show scrollbar when required [#7269](https://github.com/grafana/grafana/issues/7269) +- **SMTP**: Set LocalName to hostname [#7223](https://github.com/grafana/grafana/issues/7223) +- **Sidemenu**: Disable sign out in sidemenu for AuthProxyEnabled [#7377](https://github.com/grafana/grafana/pull/7377), thx [@solugebefola](https://github.com/solugebefola) +- **Prometheus**: Add support for basic auth in Prometheus tsdb package [#6799](https://github.com/grafana/grafana/issues/6799), thx [@hagen1778](https://github.com/hagen1778) +- **OAuth**: Redirect to original page when logging in with OAuth [#7513](https://github.com/grafana/grafana/issues/7513) +- **Annotations**: Wrap text in annotations tooltip [#7542](https://github.com/grafana/grafana/pull/7542), thx [@xginn8](https://github.com/xginn8) +- **Templating**: Fixes error when using numeric sort on empty strings [#7382](https://github.com/grafana/grafana/issues/7382) +- **Templating**: Fixed issue detecting template variable dependency [#7354](https://github.com/grafana/grafana/issues/7354) + +# 4.1.2 (2017-02-13) + +### Bugfixes + +- **Table**: Fixes broken annotation rendering mode in the table panel [#7268](https://github.com/grafana/grafana/issues/7268) +- **Data Sources**: Sorting for lists of data sources in UI is now case insensitive [#7491](https://github.com/grafana/grafana/issues/7491) +- **Admin**: Support more then 1000 users in global users list [#7469](https://github.com/grafana/grafana/issues/7469) + +# 4.1.1 (2017-01-11) + +### Bugfixes + +- **Graph Panel**: Fixed issue with legend height in table mode [#7221](https://github.com/grafana/grafana/issues/7221) + +# 4.1.0 (2017-01-11) + +### Bugfixes + +- **Server side PNG rendering**: Fixed issue with y-axis label rotation in phantomjs rendered images [#6924](https://github.com/grafana/grafana/issues/6924) +- **Graph**: Fixed centering of y-axis label [#7099](https://github.com/grafana/grafana/issues/7099) +- **Graph**: Fixed graph legend table mode and always visible scrollbar [#6828](https://github.com/grafana/grafana/issues/6828) +- **Templating**: Fixed template variable value groups/tags feature [#6752](https://github.com/grafana/grafana/issues/6752) +- **Webhook**: Fixed webhook username mismatch [#7195](https://github.com/grafana/grafana/pull/7195), thx [@theisenmark](https://github.com/theisenmark) +- **Influxdb**: Handles time(auto) the same way as time(\$interval) [#6997](https://github.com/grafana/grafana/issues/6997) + +## Enhancements + +- **Elasticsearch**: Added support for all moving average options [#7154](https://github.com/grafana/grafana/pull/7154), thx [@vaibhavinbayarea](https://github.com/vaibhavinbayarea) + +# 4.1-beta1 (2016-12-21) + +### Enhancements + +- **Postgres**: Add support for Certs for Postgres database [#6655](https://github.com/grafana/grafana/issues/6655) +- **Victorops**: Add VictorOps notification integration [#6411](https://github.com/grafana/grafana/issues/6411), thx [@ichekrygin](https://github.com/ichekrygin) +- **Opsgenie**: Add OpsGenie notification integration [#6687](https://github.com/grafana/grafana/issues/6687), thx [@kylemcc](https://github.com/kylemcc) +- **Singlestat**: New aggregation on singlestat panel [#6740](https://github.com/grafana/grafana/pull/6740), thx [@dirk-leroux](https://github.com/dirk-leroux) +- **Cloudwatch**: Make it possible to specify access and secret key on the data source config page [#6697](https://github.com/grafana/grafana/issues/6697) +- **Table**: Added Hidden Column Style for Table Panel [#5677](https://github.com/grafana/grafana/pull/5677), thx [@bmundt](https://github.com/bmundt) +- **Graph**: Shared crosshair option renamed to shared tooltip, shows tooltip on all graphs as you hover over one graph. [#1578](https://github.com/grafana/grafana/pull/1578), [#6274](https://github.com/grafana/grafana/pull/6274) +- **Elasticsearch**: Added support for Missing option (bucket) for terms aggregation [#4244](https://github.com/grafana/grafana/pull/4244), thx [@shanielh](https://github.com/shanielh) +- **Elasticsearch**: Added support for Elasticsearch 5.x [#5740](https://github.com/grafana/grafana/issues/5740), thx [@lpic10](https://github.com/lpic10) +- **CLI**: Make it possible to reset the admin password using the grafana-cli. [#5479](https://github.com/grafana/grafana/issues/5479) +- **Influxdb**: Support multiple tags in InfluxDB annotations. [#4550](https://github.com/grafana/grafana/pull/4550), thx [@adrianlzt](https://github.com/adrianlzt) +- **LDAP**: Basic Auth now supports LDAP username and password, [#6940](https://github.com/grafana/grafana/pull/6940), thx [@utkarshcmu](https://github.com/utkarshcmu) +- **LDAP**: Now works with Auth Proxy, role and organization mapping & sync will regularly be performed. [#6895](https://github.com/grafana/grafana/pull/6895), thx [@Seuf](https://github.com/seuf) +- **Alerting**: Adds OK as no data option. [#6866](https://github.com/grafana/grafana/issues/6866) +- **Alert list**: Order alerts based on state. [#6676](https://github.com/grafana/grafana/issues/6676) +- **Alerting**: Add api endpoint for pausing all alerts. [#6589](https://github.com/grafana/grafana/issues/6589) +- **Panel**: Added help text for panels. [#4079](https://github.com/grafana/grafana/issues/4079), thx [@utkarshcmu](https://github.com/utkarshcmu) + +### Bugfixes + +- **API**: HTTP API for deleting org returning incorrect message for a non-existing org [#6679](https://github.com/grafana/grafana/issues/6679) +- **Dashboard**: Posting empty dashboard result in corrupted dashboard [#5443](https://github.com/grafana/grafana/issues/5443) +- **Logging**: Fixed logging level config issue [#6978](https://github.com/grafana/grafana/issues/6978) +- **Notifications**: Remove html escaping the email subject. [#6905](https://github.com/grafana/grafana/issues/6905) +- **Influxdb**: Fixes broken field dropdown when using template vars as measurement. [#6473](https://github.com/grafana/grafana/issues/6473) + +# 4.0.2 (2016-12-08) + +### Enhancements + +- **Playlist**: Add support for kiosk mode [#6727](https://github.com/grafana/grafana/issues/6727) + +### Bugfixes + +- **Alerting**: Add alert message to webhook notifications [#6807](https://github.com/grafana/grafana/issues/6807) +- **Alerting**: Fixes a bug where avg() reducer treated null as zero. [#6879](https://github.com/grafana/grafana/issues/6879) +- **PNG Rendering**: Fix for server side rendering when using non default http addr bind and domain setting [#6813](https://github.com/grafana/grafana/issues/6813) +- **PNG Rendering**: Fix for server side rendering when setting enforce_domain to true [#6769](https://github.com/grafana/grafana/issues/6769) +- **Webhooks**: Add content type json to outgoing webhooks [#6822](https://github.com/grafana/grafana/issues/6822) +- **Keyboard shortcut**: Fixed zoom out shortcut [#6837](https://github.com/grafana/grafana/issues/6837) +- **Webdav**: Adds basic auth headers to webdav uploader [#6779](https://github.com/grafana/grafana/issues/6779) + +# 4.0.1 (2016-12-02) + +> **Notice** +> 4.0.0 had serious connection pooling issue when using a data source in proxy access. This bug caused lots of resource issues +> due to too many connections/file handles on the data source backend. This problem is fixed in this release. + +### Bugfixes + +- **Metrics**: Fixes nil pointer dereference on my arm build [#6749](https://github.com/grafana/grafana/issues/6749) +- **Data proxy**: Fixes a tcp pooling issue in the data source reverse proxy [#6759](https://github.com/grafana/grafana/issues/6759) + +# 4.0-stable (2016-11-29) + +### Bugfixes + +- **Server-side rendering**: Fixed address used when rendering panel via phantomjs and using non default http_addr config [#6660](https://github.com/grafana/grafana/issues/6660) +- **Graph panel**: Fixed graph panel tooltip sort order issue [#6648](https://github.com/grafana/grafana/issues/6648) +- **Unsaved changes**: You now navigate to the intended page after saving in the unsaved changes dialog [#6675](https://github.com/grafana/grafana/issues/6675) +- **TLS Client Auth**: Support for TLS client authentication for data source proxies [#2316](https://github.com/grafana/grafana/issues/2316) +- **Alerts out of sync**: Saving dashboards with broken alerts causes sync problem[#6576](https://github.com/grafana/grafana/issues/6576) +- **Alerting**: Saving an alert with condition "HAS NO DATA" throws an error[#6701](https://github.com/grafana/grafana/issues/6701) +- **Config**: Improve error message when parsing broken config file [#6731](https://github.com/grafana/grafana/issues/6731) +- **Table**: Render empty dates as - instead of current date [#6728](https://github.com/grafana/grafana/issues/6728) + +# 4.0-beta2 (2016-11-21) + +### Bugfixes + +- **Graph Panel**: Log base scale on right Y-axis had no effect, max value calc was not applied, [#6534](https://github.com/grafana/grafana/issues/6534) +- **Graph Panel**: Bar width if bars was only used in series override, [#6528](https://github.com/grafana/grafana/issues/6528) +- **UI/Browser**: Fixed issue with page/view header gradient border not showing in Safari, [#6530](https://github.com/grafana/grafana/issues/6530) +- **Cloudwatch**: Fixed cloudwatch data source requesting to many datapoints, [#6544](https://github.com/grafana/grafana/issues/6544) +- **UX**: Panel Drop zone visible after duplicating panel, and when entering fullscreen/edit view, [#6598](https://github.com/grafana/grafana/issues/6598) +- **Templating**: Newly added variable was not visible directly only after dashboard reload, [#6622](https://github.com/grafana/grafana/issues/6622) + +### Enhancements + +- **Singlestat**: Support repeated template variables in prefix/postfix [#6595](https://github.com/grafana/grafana/issues/6595) +- **Templating**: Don't persist variable options with refresh option [#6586](https://github.com/grafana/grafana/issues/6586) +- **Alerting**: Add ability to have OR conditions (and mixing AND & OR) [#6579](https://github.com/grafana/grafana/issues/6579) +- **InfluxDB**: Fix for Ad-Hoc Filters variable & changing dashboards [#6821](https://github.com/grafana/grafana/issues/6821) + +# 4.0-beta1 (2016-11-09) + +### Enhancements + +- **Login**: Adds option to disable username/password logins, closes [#4674](https://github.com/grafana/grafana/issues/4674) +- **SingleStat**: Add seriesName as option in singlestat panel, closes [#4740](https://github.com/grafana/grafana/issues/4740) +- **Localization**: Week start day now dependent on browser locale setting, closes [#3003](https://github.com/grafana/grafana/issues/3003) +- **Templating**: Update panel repeats for variables that change on time refresh, closes [#5021](https://github.com/grafana/grafana/issues/5021) +- **Templating**: Add support for numeric and alphabetical sorting of variable values, closes [#2839](https://github.com/grafana/grafana/issues/2839) +- **Elasticsearch**: Support to set Precision Threshold for Unique Count metric, closes [#4689](https://github.com/grafana/grafana/issues/4689) +- **Navigation**: Add search to org switcher, closes [#2609](https://github.com/grafana/grafana/issues/2609) +- **Database**: Allow database config using one property, closes [#5456](https://github.com/grafana/grafana/pull/5456) +- **Graphite**: Add support for groupByNodes, closes [#5613](https://github.com/grafana/grafana/pull/5613) +- **Influxdb**: Add support for elapsed(), closes [#5827](https://github.com/grafana/grafana/pull/5827) +- **OpenTSDB**: Add support for explicitTags for OpenTSDB>=2.3, closes [#6360](https://github.com/grafana/grafana/pull/6361) +- **OAuth**: Add support for generic oauth, closes [#4718](https://github.com/grafana/grafana/pull/4718) +- **Cloudwatch**: Add support to expand multi select template variable, closes [#5003](https://github.com/grafana/grafana/pull/5003) +- **Background Tasks**: Now support automatic purging of old snapshots, closes [#4087](https://github.com/grafana/grafana/issues/4087) +- **Background Tasks**: Now support automatic purging of old rendered images, closes [#2172](https://github.com/grafana/grafana/issues/2172) +- **Dashboard**: After inactivity hide nav/row actions, fade to nice clean view, can be toggled with `d v`, also added kiosk mode, toggled via `d k` [#6476](https://github.com/grafana/grafana/issues/6476) +- **Dashboard**: Improved dashboard row menu & add panel UX [#6442](https://github.com/grafana/grafana/issues/6442) +- **Graph Panel**: Support for stacking null values [#2912](https://github.com/grafana/grafana/issues/2912), [#6287](https://github.com/grafana/grafana/issues/6287), thanks @benrubson! + +### Breaking changes + +- **SystemD**: Change systemd description, closes [#5971](https://github.com/grafana/grafana/pull/5971) +- **lodash upgrade**: Upgraded lodash from 2.4.2 to 4.15.0, this contains a number of breaking changes that could effect plugins. closes [#6021](https://github.com/grafana/grafana/pull/6021) + +### Bug fixes + +- **Table Panel**: Fixed problem when switching to Mixed data source in metrics tab, fixes [#5999](https://github.com/grafana/grafana/pull/5999) +- **Playlist**: Fixed problem with play order not matching order defined in playlist, fixes [#5467](https://github.com/grafana/grafana/pull/5467) +- **Graph panel**: Fixed problem with auto decimals on y axis when datamin=datamax, fixes [#6070](https://github.com/grafana/grafana/pull/6070) +- **Snapshot**: Can view embedded panels/png rendered panels in snapshots without login, fixes [#3769](https://github.com/grafana/grafana/pull/3769) +- **Elasticsearch**: Fix for query template variable when looking up terms without query, no longer relies on elasticsearch default field, fixes [#3887](https://github.com/grafana/grafana/pull/3887) +- **Elasticsearch**: Fix for displaying IP address used in terms aggregations, fixes [#4393](https://github.com/grafana/grafana/pull/4393) +- **PNG Rendering**: Fix for server side rendering when using auth proxy, fixes [#5906](https://github.com/grafana/grafana/pull/5906) +- **OpenTSDB**: Fixed multi-value nested templating for opentsdb, fixes [#6455](https://github.com/grafana/grafana/pull/6455) +- **Playlist**: Remove playlist items when dashboard is removed, fixes [#6292](https://github.com/grafana/grafana/issues/6292) + +# 3.1.2 (unreleased) + +- **Templating**: Fixed issue when combining row & panel repeats, fixes [#5790](https://github.com/grafana/grafana/issues/5790) +- **Drag&Drop**: Fixed issue with drag and drop in latest Chrome(51+), fixes [#5767](https://github.com/grafana/grafana/issues/5767) +- **Internal Metrics**: Fixed issue with dots in instance_name when sending internal metrics to Graphite, fixes [#5739](https://github.com/grafana/grafana/issues/5739) +- **Grafana-CLI**: Add default plugin path for MAC OS, fixes [#5806](https://github.com/grafana/grafana/issues/5806) +- **Grafana-CLI**: Improve error message for upgrade-all command, fixes [#5885](https://github.com/grafana/grafana/issues/5885) + +# 3.1.1 (2016-08-01) + +- **IFrame embedding**: Fixed issue of using full iframe height, fixes [#5605](https://github.com/grafana/grafana/issues/5606) +- **Panel PNG rendering**: Fixed issue detecting render completion, fixes [#5605](https://github.com/grafana/grafana/issues/5606) +- **Elasticsearch**: Fixed issue with templating query and json parse error, fixes [#5615](https://github.com/grafana/grafana/issues/5615) +- **Tech**: Upgraded JQuery to 2.2.4 to fix Security vulnerabilities in 2.1.4, fixes [#5627](https://github.com/grafana/grafana/issues/5627) +- **Graphite**: Fixed issue with mixed data sources and Graphite, fixes [#5617](https://github.com/grafana/grafana/issues/5617) +- **Templating**: Fixed issue with template variable query was issued multiple times during dashboard load, fixes [#5637](https://github.com/grafana/grafana/issues/5637) +- **Zoom**: Fixed issues with zoom in and out on embedded (iframed) panel, fixes [#4489](https://github.com/grafana/grafana/issues/4489), [#5666](https://github.com/grafana/grafana/issues/5666) + +# 3.1.0 stable (2016-07-12) + +### Bugfixes & Enhancements, + +- **User Alert Notices**: Backend error alert popups did not show properly, fixes [#5435](https://github.com/grafana/grafana/issues/5435) +- **Table**: Added sanitize HTML option to allow links in table cells, fixes [#4596](https://github.com/grafana/grafana/issues/4596) +- **Apps**: App dashboards are automatically synced to DB at startup after plugin update, fixes [#5529](https://github.com/grafana/grafana/issues/5529) + +# 3.1.0-beta1 (2016-06-23) + +### Enhancements + +- **Dashboard Export/Import**: Dashboard export now templatize data sources and constant variables, users pick these on import, closes [#5084](https://github.com/grafana/grafana/issues/5084) +- **Dashboard Url**: Time range changes updates url, closes [#458](https://github.com/grafana/grafana/issues/458) +- **Dashboard Url**: Template variable change updates url, closes [#5002](https://github.com/grafana/grafana/issues/5002) +- **Singlestat**: Add support for range to text mappings, closes [#1319](https://github.com/grafana/grafana/issues/1319) +- **Graph**: Adds sort order options for graph tooltip, closes [#1189](https://github.com/grafana/grafana/issues/1189) +- **Theme**: Add default theme to config file [#5011](https://github.com/grafana/grafana/pull/5011) +- **Page Footer**: Added page footer with links to docs, shows Grafana version and info if new version is available, closes [#4889](https://github.com/grafana/grafana/pull/4889) +- **InfluxDB**: Add spread function, closes [#5211](https://github.com/grafana/grafana/issues/5211) +- **Scripts**: Use restart instead of start for deb package script, closes [#5282](https://github.com/grafana/grafana/pull/5282) +- **Logging**: Moved to structured logging lib, and moved to component specific level filters via config file, closes [#4590](https://github.com/grafana/grafana/issues/4590) +- **OpenTSDB**: Support nested template variables in tag_values function, closes [#4398](https://github.com/grafana/grafana/issues/4398) +- **Data Source**: Pending data source requests are canceled before new ones are issues (Graphite & Prometheus), closes [#5321](https://github.com/grafana/grafana/issues/5321) + +### Breaking changes + +- **Logging** : Changed default logging output format (now structured into message, and key value pairs, with logger key acting as component). You can also no change in config to json log output. +- **Graphite** : The Graph panel no longer have a Graphite PNG option. closes [#5367](https://github.com/grafana/grafana/issues/5367) + +### Bug fixes + +- **PNG rendering**: Fixed phantomjs rendering and y-axis label rotation. fixes [#5220](https://github.com/grafana/grafana/issues/5220) +- **CLI**: The cli tool now supports reading plugin.json from dist/plugin.json. fixes [#5410](https://github.com/grafana/grafana/issues/5410) + +# 3.0.4 Patch release (2016-05-25) + +- **Panel**: Fixed blank dashboard issue when switching to other dashboard while in fullscreen edit mode, fixes [#5163](https://github.com/grafana/grafana/pull/5163) +- **Templating**: Fixed issue with nested multi select variables and cascading and updating child variable selection state, fixes [#4861](https://github.com/grafana/grafana/pull/4861) +- **Templating**: Fixed issue with using templated data source in another template variable query, fixes [#5165](https://github.com/grafana/grafana/pull/5165) +- **Singlestat gauge**: Fixed issue with gauge render position, fixes [#5143](https://github.com/grafana/grafana/pull/5143) +- **Home dashboard**: Fixes broken home dashboard api, fixes [#5167](https://github.com/grafana/grafana/issues/5167) + +# 3.0.3 Patch release (2016-05-23) + +- **Annotations**: Annotations can now use a template variable as data source, closes [#5054](https://github.com/grafana/grafana/issues/5054) +- **Time picker**: Fixed issue timepicker and UTC when reading time from URL, fixes [#5078](https://github.com/grafana/grafana/issues/5078) +- **CloudWatch**: Support for Multiple Account by AssumeRole, closes [#3522](https://github.com/grafana/grafana/issues/3522) +- **Singlestat**: Fixed alignment and minimum height issue, fixes [#5113](https://github.com/grafana/grafana/issues/5113), fixes [#4679](https://github.com/grafana/grafana/issues/4679) +- **Share modal**: Fixed link when using grafana under dashboard sub url, fixes [#5109](https://github.com/grafana/grafana/issues/5109) +- **Prometheus**: Fixed bug in query editor that caused it not to load when reloading page, fixes [#5107](https://github.com/grafana/grafana/issues/5107) +- **Elasticsearch**: Fixed bug when template variable query returns numeric values, fixes [#5097](https://github.com/grafana/grafana/issues/5097), fixes [#5088](https://github.com/grafana/grafana/issues/5088) +- **Logging**: Fixed issue with reading logging level value, fixes [#5079](https://github.com/grafana/grafana/issues/5079) +- **Timepicker**: Fixed issue with timepicker and UTC when reading time from URL, fixes [#5078](https://github.com/grafana/grafana/issues/5078) +- **Docs**: Added docs for org & user preferences HTTP API, closes [#5069](https://github.com/grafana/grafana/issues/5069) +- **Plugin list panel**: Now shows correct enable state for apps when not enabled, fixes [#5068](https://github.com/grafana/grafana/issues/5068) +- **Elasticsearch**: Templating & Annotation queries that use template variables are now formatted correctly, fixes [#5135](https://github.com/grafana/grafana/issues/5135) + +# 3.0.2 Patch release (2016-05-16) + +- **Templating**: Fixed issue mixing row repeat and panel repeats, fixes [#4988](https://github.com/grafana/grafana/issues/4988) +- **Templating**: Fixed issue detecting dependencies in nested variables, fixes [#4987](https://github.com/grafana/grafana/issues/4987), fixes [#4986](https://github.com/grafana/grafana/issues/4986) +- **Graph**: Fixed broken PNG rendering in graph panel, fixes [#5025](https://github.com/grafana/grafana/issues/5025) +- **Graph**: Fixed broken xaxis on graph panel, fixes [#5024](https://github.com/grafana/grafana/issues/5024) + +- **Influxdb**: Fixes crash when hiding middle series, fixes [#5005](https://github.com/grafana/grafana/issues/5005) + +# 3.0.1 Stable (2016-05-11) + +### Bug fixes + +- **Templating**: Fixed issue with new data source variable not persisting current selected value, fixes [#4934](https://github.com/grafana/grafana/issues/4934) + +# 3.0.0-beta7 (2016-05-02) + +### Bug fixes + +- **Dashboard title**: Fixed max dashboard title width (media query) for large screens, fixes [#4859](https://github.com/grafana/grafana/issues/4859) +- **Annotations**: Fixed issue with entering annotation edit view, fixes [#4857](https://github.com/grafana/grafana/issues/4857) +- **Remove query**: Fixed issue with removing query for data sources without collapsible query editors, fixes [#4856](https://github.com/grafana/grafana/issues/4856) +- **Graphite PNG**: Fixed issue graphite png rendering option, fixes [#4864](https://github.com/grafana/grafana/issues/4864) +- **InfluxDB**: Fixed issue missing plus group by iconn, fixes [#4862](https://github.com/grafana/grafana/issues/4862) +- **Graph**: Fixes missing line mode for thresholds, fixes [#4902](https://github.com/grafana/grafana/pull/4902) + +### Enhancements + +- **InfluxDB**: Added new functions moving_average and difference to query editor, closes [#4698](https://github.com/grafana/grafana/issues/4698) + +# 3.0.0-beta6 (2016-04-29) + +### Enhancements + +- **Singlestat**: Support for gauges in singlestat panel. closes [#3688](https://github.com/grafana/grafana/pull/3688) +- **Templating**: Support for data source as variable, closes [#816](https://github.com/grafana/grafana/pull/816) + +### Bug fixes + +- **InfluxDB 0.12**: Fixed issue templating and `show tag values` query only returning tags for first measurement, fixes [#4726](https://github.com/grafana/grafana/issues/4726) +- **Templating**: Fixed issue with regex formatting when matching multiple values, fixes [#4755](https://github.com/grafana/grafana/issues/4755) +- **Templating**: Fixed issue with custom all value and escaping, fixes [#4736](https://github.com/grafana/grafana/issues/4736) +- **Dashlist**: Fixed issue dashboard list panel and caching tags, fixes [#4768](https://github.com/grafana/grafana/issues/4768) +- **Graph**: Fixed issue with unneeded scrollbar in legend for Firefox, fixes [#4760](https://github.com/grafana/grafana/issues/4760) +- **Table panel**: Fixed issue table panel formatting string array properties, fixes [#4791](https://github.com/grafana/grafana/issues/4791) +- **grafana-cli**: Improve error message when failing to install plugins due to corrupt response, fixes [#4651](https://github.com/grafana/grafana/issues/4651) +- **Singlestat**: Fixes prefix an postfix for gauges, fixes [#4812](https://github.com/grafana/grafana/issues/4812) +- **Singlestat**: Fixes auto-refresh on change for some options, fixes [#4809](https://github.com/grafana/grafana/issues/4809) + +### Breaking changes + +**Data Source Query Editors**: Issue [#3900](https://github.com/grafana/grafana/issues/3900) + +Query editors have been updated to use the new form styles. External data source plugins needs to be +updated to work. Sorry to introduce breaking change this late in beta phase. We wanted to get this change +in before 3.0 stable is released so we don't have to break data sources in next release (3.1). If you are +a data source plugin author and want help for how the new form styles work please ask for help in +slack channel (link to slack channel in readme). + +# 3.0.0-beta5 (2016-04-15) + +### Bug fixes + +- **grafana-cli**: Fixed issue grafana-cli tool, did not detect the right plugin dir, fixes [#4723](https://github.com/grafana/grafana/issues/4723) +- **Graph**: Fixed issue with light theme text color issue in tooltip, fixes [#4702](https://github.com/grafana/grafana/issues/4702) +- **Snapshot**: Fixed issue with empty snapshots, fixes [#4706](https://github.com/grafana/grafana/issues/4706) + +# 3.0.0-beta4 (2016-04-13) + +### Bug fixes + +- **Home dashboard**: Fixed issue with permission denied error on home dashboard, fixes [#4686](https://github.com/grafana/grafana/issues/4686) +- **Templating**: Fixed issue templating variables that use regex extraction, fixes [#4672](https://github.com/grafana/grafana/issues/4672) + +# 3.0.0-beta3 (2016-04-12) + +### Enhancements + +- **InfluxDB**: Changed multi query encoding to work with InfluxDB 0.11 & 0.12, closes [#4533](https://github.com/grafana/grafana/issues/4533) +- **Timepicker**: Add arrows and shortcuts for moving back and forth in current dashboard, closes [#119](https://github.com/grafana/grafana/issues/119) + +### Bug fixes + +- **Postgres**: Fixed page render crash when using postgres, fixes [#4558](https://github.com/grafana/grafana/issues/4558) +- **Table panel**: Fixed table panel bug when trying to show annotations in table panel, fixes [#4563](https://github.com/grafana/grafana/issues/4563) +- **App Config**: Fixed app config issue showing content of other app config, fixes [#4575](https://github.com/grafana/grafana/issues/4575) +- **Graph Panel**: Fixed legend option max not updating, fixes [#4601](https://github.com/grafana/grafana/issues/4601) +- **Graph Panel**: Fixed issue where newly added graph panels shared same axes config, fixes [#4582](https://github.com/grafana/grafana/issues/4582) +- **Graph Panel**: Fixed issue with axis labels overlapping Y-axis, fixes [#4626](https://github.com/grafana/grafana/issues/4626) +- **InfluxDB**: Fixed issue with templating query containing template variable, fixes [#4602](https://github.com/grafana/grafana/issues/4602) +- **Graph Panel**: Fixed issue with hiding series and stacking, fixes [#4557](https://github.com/grafana/grafana/issues/4557) +- **Graph Panel**: Fixed issue with legend height in table mode with few series, affected iframe embedding as well, fixes [#4640](https://github.com/grafana/grafana/issues/4640) + +# 3.0.0-beta2 (2016-04-04) + +### New Features (introduces since 3.0-beta1) + +- **Preferences**: Set home dashboard on user and org level, closes [#1678](https://github.com/grafana/grafana/issues/1678) +- **Preferences**: Set timezone on user and org level, closes [#3214](https://github.com/grafana/grafana/issues/3214), [#1200](https://github.com/grafana/grafana/issues/1200) +- **Preferences**: Set theme on user and org level, closes [#3214](https://github.com/grafana/grafana/issues/3214), [#1917](https://github.com/grafana/grafana/issues/1917) + +### Bug fixes + +- **Dashboard**: Fixed dashboard panel layout for mobile devices, fixes [#4529](https://github.com/grafana/grafana/issues/4529) +- **Table Panel**: Fixed issue with table panel sort, fixes [#4532](https://github.com/grafana/grafana/issues/4532) +- **Page Load Crash**: A data source with null jsonData would make Grafana fail to load page, fixes [#4536](https://github.com/grafana/grafana/issues/4536) +- **Metrics tab**: Fix for missing data source name in data source selector, fixes [#4541](https://github.com/grafana/grafana/issues/4540) +- **Graph**: Fix legend in table mode with series on right-y axis, fixes [#4551](https://github.com/grafana/grafana/issues/4551), [#1145](https://github.com/grafana/grafana/issues/1145) + +# 3.0.0-beta1 (2016-03-31) + +### New Features + +- **Playlists**: Playlists can now be persisted and started from urls, closes [#3655](https://github.com/grafana/grafana/issues/3655) +- **Metadata**: Settings panel now shows dashboard metadata, closes [#3304](https://github.com/grafana/grafana/issues/3304) +- **InfluxDB**: Support for policy selection in query editor, closes [#2018](https://github.com/grafana/grafana/issues/2018) +- **Snapshots UI**: Dashboard snapshots list can be managed through UI, closes[#1984](https://github.com/grafana/grafana/issues/1984) +- **Prometheus**: Prometheus annotation support, closes[#2883](https://github.com/grafana/grafana/pull/2883) +- **Cli**: New cli tool for downloading and updating plugins +- **Annotations**: Annotations can now contain links that can be clicked (you can navigate on to annotation popovers), closes [#1588](https://github.com/grafana/grafana/issues/1588) +- **Opentsdb**: Opentsdb 2.2 filters support, closes[#3077](https://github.com/grafana/grafana/issues/3077) + +### Breaking changes + +- **Plugin API**: Both data source and panel plugin api (and plugin.json schema) have been updated, requiring an update to plugins. See [plugin api](https://github.com/grafana/grafana/blob/master/public/app/plugins/plugin_api.md) for more info. +- **InfluxDB 0.8.x** The data source for the old version of influxdb (0.8.x) is no longer included in default builds, but can easily be installed via improved plugin system, closes [#3523](https://github.com/grafana/grafana/issues/3523) +- **KairosDB** The data source is no longer included in default builds, but can easily be installed via improved plugin system, closes [#3524](https://github.com/grafana/grafana/issues/3524) +- **Templating**: Templating value formats (glob/regex/pipe etc) are now handled automatically and not specified by the user, this makes variable values possible to reuse in many contexts. It can in some edge cases break existing dashboards that have template variables that do not reload on dashboard load. To fix any issue just go into template variable options and update the variable (so it's values are reloaded.). + +### Enhancements + +- **LDAP**: Support for nested LDAP Groups, closes [#4401](https://github.com/grafana/grafana/issues/4401), [#3808](https://github.com/grafana/grafana/issues/3808) +- **Sessions**: Support for memcached as session storage, closes [#3458](https://github.com/grafana/grafana/issues/3458) +- **mysql**: Grafana now supports ssl for mysql, closes [#3584](https://github.com/grafana/grafana/issues/3584) +- **snapshot**: Annotations are now included in snapshots, closes [#3635](https://github.com/grafana/grafana/issues/3635) +- **Admin**: Admin can now have global overview of Grafana setup, closes [#3812](https://github.com/grafana/grafana/issues/3812) +- **graph**: Right side legend height is now fixed at row height, closes [#1277](https://github.com/grafana/grafana/issues/1277) +- **Table**: All content in table panel is now html escaped, closes [#3673](https://github.com/grafana/grafana/issues/3673) +- **graph**: Template variables can now be used in TimeShift and TimeFrom, closes[#1960](https://github.com/grafana/grafana/issues/1960) +- **Tooltip**: Optionally add milliseconds to timestamp in tool tip, closes[#2248](https://github.com/grafana/grafana/issues/2248) +- **Opentsdb**: Support milliseconds when using openTSDB data source, closes [#2865](https://github.com/grafana/grafana/issues/2865) +- **Opentsdb**: Add support for annotations, closes[#664](https://github.com/grafana/grafana/issues/664) + +### Bug fixes + +- **Playlist**: Fix for memory leak when running a playlist, closes [#3794](https://github.com/grafana/grafana/pull/3794) +- **InfluxDB**: Fix for InfluxDB and table panel when using Format As Table and having group by time, fixes [#3928](https://github.com/grafana/grafana/issues/3928) +- **Panel Time shift**: Fix for panel time range and using dashboard times like `Today` and `This Week`, fixes [#3941](https://github.com/grafana/grafana/issues/3941) +- **Row repeat**: Repeated rows will now appear next to each other and not by the bottom of the dashboard, fixes [#3942](https://github.com/grafana/grafana/issues/3942) +- **Png renderer**: Fix for phantomjs path on windows, fixes [#3657](https://github.com/grafana/grafana/issues/3657) + +# 2.6.1 (unreleased, 2.6.x branch) + +### New Features + +- **Elasticsearch**: Support for derivative unit option, closes [#3512](https://github.com/grafana/grafana/issues/3512) + +### Bug fixes + +- **Graph Panel**: Fixed typehead when adding series style override, closes [#3554](https://github.com/grafana/grafana/issues/3554) + +# 2.6.0 (2015-12-14) + +### New Features + +- **Elasticsearch**: Support for pipeline aggregations Moving average and derivative, closes [#2715](https://github.com/grafana/grafana/issues/2715) +- **Elasticsearch**: Support for inline script and missing options for metrics, closes [#3500](https://github.com/grafana/grafana/issues/3500) +- **Syslog**: Support for syslog logging, closes [#3161](https://github.com/grafana/grafana/pull/3161) +- **Timepicker**: Always show refresh button even with refresh rate, closes [#3498](https://github.com/grafana/grafana/pull/3498) +- **Login**: Make it possible to change the login hint on the login page, closes [#2571](https://github.com/grafana/grafana/pull/2571) + +### Bug Fixes + +- **metric editors**: Fix for clicking typeahead auto dropdown option, fixes [#3428](https://github.com/grafana/grafana/issues/3428) +- **influxdb**: Fixed issue showing Group By label only on first query, fixes [#3453](https://github.com/grafana/grafana/issues/3453) +- **logging**: Add more verbose info logging for http requests, closes [#3405](https://github.com/grafana/grafana/pull/3405) + +# 2.6.0-Beta1 (2015-12-04) + +### New Table Panel + +- **table**: New powerful and flexible table panel, closes [#215](https://github.com/grafana/grafana/issues/215) + +### Enhancements + +- **CloudWatch**: Support for multiple AWS Credentials, closes [#3053](https://github.com/grafana/grafana/issues/3053), [#3080](https://github.com/grafana/grafana/issues/3080) +- **Elasticsearch**: Support for dynamic daily indices for annotations, closes [#3061](https://github.com/grafana/grafana/issues/3061) +- **Elasticsearch**: Support for setting min_doc_count for date histogram, closes [#3416](https://github.com/grafana/grafana/issues/3416) +- **Graph Panel**: Option to hide series with all zeroes from legend and tooltip, closes [#1381](https://github.com/grafana/grafana/issues/1381), [#3336](https://github.com/grafana/grafana/issues/3336) + +### Bug Fixes + +- **cloudwatch**: fix for handling of period for long time ranges, fixes [#3086](https://github.com/grafana/grafana/issues/3086) +- **dashboard**: fix for collapse row by clicking on row title, fixes [#3065](https://github.com/grafana/grafana/issues/3065) +- **influxdb**: fix for relative time ranges `last x months` and `last x years`, fixes [#3067](https://github.com/grafana/grafana/issues/3067) +- **graph**: layout fix for color picker when right side legend was enabled, fixes [#3093](https://github.com/grafana/grafana/issues/3093) +- **elasticsearch**: disabling elastic query (via eye) caused error, fixes [#3300](https://github.com/grafana/grafana/issues/3300) + +### Breaking changes + +- **elasticsearch**: Manual json edited queries are not supported any more (They very barely worked in 2.5) + +# 2.5 (2015-10-28) + +**New Feature: Mix data sources** + +- A built in data source is now available named `-- Mixed --`, When picked in the metrics tab, + it allows you to add queries of different data source types & instances to the same graph/panel! + [Issue #436](https://github.com/grafana/grafana/issues/436) + +**New Feature: Elasticsearch Metrics Query Editor and Viz Support** + +- Feature rich query editor and processing features enables you to issues all kind of metric queries to Elasticsearch +- See [Issue #1034](https://github.com/grafana/grafana/issues/1034) for more info. + +**New Feature: New and much improved time picker** + +- Support for quick ranges like `Today`, `This day last week`, `This week`, `The day so far`, etc. +- Improved UI and improved support for UTC, [Issue #2761](https://github.com/grafana/grafana/issues/2761) for more info. + +**User Onboarding** + +- Org admin can now send email invites (or invite links) to people who are not yet Grafana users +- Sign up flow now supports email verification (if enabled) +- See [Issue #2353](https://github.com/grafana/grafana/issues/2353) for more info. + +**Other new Features && Enhancements** + +- [Pull #2720](https://github.com/grafana/grafana/pull/2720). Admin: Initial basic quota support (per Org) +- [Issue #2577](https://github.com/grafana/grafana/issues/2577). Panel: Resize handles in panel bottom right corners for easy width and height change +- [Issue #2457](https://github.com/grafana/grafana/issues/2457). Admin: admin page for all grafana organizations (list / edit view) +- [Issue #1186](https://github.com/grafana/grafana/issues/1186). Time Picker: New option `today`, will set time range from midnight to now +- [Issue #2647](https://github.com/grafana/grafana/issues/2647). InfluxDB: You can now set group by time interval on each query +- [Issue #2599](https://github.com/grafana/grafana/issues/2599). InfluxDB: Improved alias support, you can now use the `AS` clause for each select statement +- [Issue #2708](https://github.com/grafana/grafana/issues/2708). InfluxDB: You can now set math expression for select clauses. +- [Issue #1575](https://github.com/grafana/grafana/issues/1575). Drilldown link: now you can click on the external link icon in the panel header to access drilldown links! +- [Issue #1646](https://github.com/grafana/grafana/issues/1646). OpenTSDB: Fetch list of aggregators from OpenTSDB +- [Issue #2955](https://github.com/grafana/grafana/issues/2955). Graph: More axis units (Length, Volume, Temperature, Pressure, etc), thanks @greglook +- [Issue #2928](https://github.com/grafana/grafana/issues/2928). LDAP: Support for searching for groups memberships, i.e. POSIX (no memberOf) schemas, also multiple ldap servers, and root ca cert, thanks @abligh + +**Fixes** + +- [Issue #2413](https://github.com/grafana/grafana/issues/2413). InfluxDB 0.9: Fix for handling empty series object in response from influxdb +- [Issue #2574](https://github.com/grafana/grafana/issues/2574). Snapshot: Fix for snapshot with expire 7 days option, 7 days option not correct, was 7 hours +- [Issue #2568](https://github.com/grafana/grafana/issues/2568). AuthProxy: Fix for server side rendering of panel when using auth proxy +- [Issue #2490](https://github.com/grafana/grafana/issues/2490). Graphite: Dashboard import was broken in 2.1 and 2.1.1, working now +- [Issue #2565](https://github.com/grafana/grafana/issues/2565). TimePicker: Fix for when you applied custom time range it did not refresh dashboard +- [Issue #2563](https://github.com/grafana/grafana/issues/2563). Annotations: Fixed issue when html sanitizer fails for title to annotation body, now fallbacks to html escaping title and text +- [Issue #2564](https://github.com/grafana/grafana/issues/2564). Templating: Another attempt at fixing #2534 (Init multi value template var used in repeat panel from url) +- [Issue #2620](https://github.com/grafana/grafana/issues/2620). Graph: multi series tooltip did no highlight correct point when stacking was enabled and series were of different resolution +- [Issue #2636](https://github.com/grafana/grafana/issues/2636). InfluxDB: Do no show template vars in dropdown for tag keys and group by keys +- [Issue #2604](https://github.com/grafana/grafana/issues/2604). InfluxDB: More alias options, can now use `$[0-9]` syntax to reference part of a measurement name (separated by dots) + +**Breaking Changes** + +- Notice to makers/users of custom data sources, there is a minor breaking change in 2.2 that + require an update to custom data sources for them to work in 2.2. [Read this doc](https://github.com/grafana/grafana/tree/master/docs/sources/datasources/plugin_api.md) for more on the + data source api change. +- Data source api changes, [PLUGIN_CHANGES.md](https://github.com/grafana/grafana/blob/master/public/app/plugins/PLUGIN_CHANGES.md) +- The duplicate query function used in data source editors is changed, and moveMetricQuery function was renamed + +**Tech (Note for devs)** +Started using Typescript (transpiled to ES5), uncompiled typescript files and less files are in public folder (in source tree) +This folder is never modified by build steps. Compiled css and javascript files are put in public_gen, all other files +that do not undergo transformation are just copied from public to public_gen, it is public_gen that is used by grafana-server +if it is found. + +Grunt & Watch tasks: + +- `grunt` : default task, will remove public_gen, copy over all files from public, do less & typescript compilation +- `grunt watch`: will watch for changes to less, and typescript files and compile them to public_gen, and for other files it will just copy them to public_gen + +# 2.1.3 (2015-08-24) + +**Fixes** + +- [Issue #2580](https://github.com/grafana/grafana/issues/2580). Packaging: ldap.toml was not marked as config file and could be overwritten in upgrade +- [Issue #2564](https://github.com/grafana/grafana/issues/2564). Templating: Another attempt at fixing #2534 (Init multi value template var used in repeat panel from url) + +# 2.1.2 (2015-08-20) + +**Fixes** + +- [Issue #2558](https://github.com/grafana/grafana/issues/2558). DragDrop: Fix for broken drag drop behavior +- [Issue #2534](https://github.com/grafana/grafana/issues/2534). Templating: fix for setting template variable value via url and having repeated panels or rows + +# 2.1.1 (2015-08-11) + +**Fixes** + +- [Issue #2443](https://github.com/grafana/grafana/issues/2443). Templating: Fix for buggy repeat row behavior when combined with with repeat panel due to recent change before 2.1 release +- [Issue #2442](https://github.com/grafana/grafana/issues/2442). Templating: Fix text panel when using template variables in text in in repeated panel +- [Issue #2446](https://github.com/grafana/grafana/issues/2446). InfluxDB: Fix for using template vars inside alias field (InfluxDB 0.9) +- [Issue #2460](https://github.com/grafana/grafana/issues/2460). SinglestatPanel: Fix to handle series with no data points +- [Issue #2461](https://github.com/grafana/grafana/issues/2461). LDAP: Fix for ldap users with empty email address +- [Issue #2484](https://github.com/grafana/grafana/issues/2484). Graphite: Fix bug when using series ref (#A-Z) and referenced series is hidden in query editor. +- [Issue #1896](https://github.com/grafana/grafana/issues/1896). Postgres: Dashboard search is now case insensitive when using Postgres + +**Enhancements** + +- [Issue #2477](https://github.com/grafana/grafana/issues/2477). InfluxDB(0.9): Added more condition operators (`<`, `>`, `<>`, `!~`), thx @thuck +- [Issue #2483](https://github.com/grafana/grafana/issues/2484). InfluxDB(0.9): Use \$col as option in alias patterns, thx @thuck + +# 2.1.0 (2015-08-04) + +**Data sources** + +- [Issue #1525](https://github.com/grafana/grafana/issues/1525). InfluxDB: Full support for InfluxDB 0.9 with new adapted query editor +- [Issue #2191](https://github.com/grafana/grafana/issues/2191). KariosDB: Grafana now ships with a KariosDB data source plugin, thx @masaori335 +- [Issue #1177](https://github.com/grafana/grafana/issues/1177). OpenTSDB: Limit tags by metric, OpenTSDB config option tsd.core.meta.enable_realtime_ts must enabled for OpenTSDB lookup api +- [Issue #1250](https://github.com/grafana/grafana/issues/1250). OpenTSDB: Support for template variable values lookup queries + +**New dashboard features** + +- [Issue #1144](https://github.com/grafana/grafana/issues/1144). Templating: You can now select multiple template variables values at the same time. +- [Issue #1922](https://github.com/grafana/grafana/issues/1922). Templating: Specify multiple variable values via URL params. +- [Issue #1888](https://github.com/grafana/grafana/issues/1144). Templating: Repeat panel or row for each selected template variable value +- [Issue #1888](https://github.com/grafana/grafana/issues/1944). Dashboard: Custom Navigation links & dynamic links to related dashboards +- [Issue #590](https://github.com/grafana/grafana/issues/590). Graph: Define series color using regex rule +- [Issue #2162](https://github.com/grafana/grafana/issues/2162). Graph: New series style override, negative-y transform and stack groups +- [Issue #2096](https://github.com/grafana/grafana/issues/2096). Dashboard list panel: Now supports search by multiple tags +- [Issue #2203](https://github.com/grafana/grafana/issues/2203). Singlestat: Now support string values + +**User or Organization admin** + +- [Issue #1899](https://github.com/grafana/grafana/issues/1899). Organization: You can now update the organization user role directly (without removing and readding the organization user). +- [Issue #2088](https://github.com/grafana/grafana/issues/2088). Roles: New user role `Read Only Editor` that replaces the old `Viewer` role behavior + +**Backend** + +- [Issue #2218](https://github.com/grafana/grafana/issues/2218). Auth: You can now authenticate against api with username / password using basic auth +- [Issue #2095](https://github.com/grafana/grafana/issues/2095). Search: Search now supports filtering by multiple dashboard tags +- [Issue #1905](https://github.com/grafana/grafana/issues/1905). GitHub OAuth: You can now configure a GitHub team membership requirement, thx @dewski +- [Issue #2052](https://github.com/grafana/grafana/issues/2052). GitHub OAuth: You can now configure a GitHub organization requirement, thx @indrekj +- [Issue #1891](https://github.com/grafana/grafana/issues/1891). Security: New config option to disable the use of gravatar for profile images +- [Issue #1921](https://github.com/grafana/grafana/issues/1921). Auth: Support for user authentication via reverse proxy header (like X-Authenticated-User, or X-WEBAUTH-USER) +- [Issue #960](https://github.com/grafana/grafana/issues/960). Search: Backend can now index a folder with json files, will be available in search (saving back to folder is not supported, this feature is meant for static generated json dashboards) + +**Breaking changes** + +- [Issue #1826](https://github.com/grafana/grafana/issues/1826). User role 'Viewer' are now prohibited from entering edit mode (and doing other transient dashboard edits). A new role `Read Only Editor` will replace the old Viewer behavior +- [Issue #1928](https://github.com/grafana/grafana/issues/1928). HTTP API: GET /api/dashboards/db/:slug response changed property `model` to `dashboard` to match the POST request naming +- Backend render URL changed from `/render/dashboard/solo` `render/dashboard-solo/` (in order to have consistent dashboard url `/dashboard/:type/:slug`) +- Search HTTP API response has changed (simplified), tags list moved to separate HTTP resource URI +- Data source HTTP api breaking change, ADD data source is now POST /api/datasources/, update is now PUT /api/datasources/:id + +**Fixes** + +- [Issue #2185](https://github.com/grafana/grafana/issues/2185). Graph: fixed PNG rendering of panels with legend table to the right +- [Issue #2163](https://github.com/grafana/grafana/issues/2163). Backend: Load dashboards with capital letters in the dashboard url slug (url id) + +# 2.0.3 (unreleased - 2.0.x branch) + +**Fixes** + +- [Issue #1872](https://github.com/grafana/grafana/issues/1872). Firefox/IE issue, invisible text in dashboard search fixed +- [Issue #1857](https://github.com/grafana/grafana/issues/1857). /api/login/ping Fix for issue when behind reverse proxy and subpath +- [Issue #1863](https://github.com/grafana/grafana/issues/1863). MySQL: Dashboard.data column type changed to mediumtext (sql migration added) + +# 2.0.2 (2015-04-22) + +**Fixes** + +- [Issue #1832](https://github.com/grafana/grafana/issues/1832). Graph Panel + Legend Table mode: Many series caused zero height graph, now legend will never reduce the height of the graph below 50% of row height. +- [Issue #1846](https://github.com/grafana/grafana/issues/1846). Snapshots: Fixed issue with snapshotting dashboards with an interval template variable +- [Issue #1848](https://github.com/grafana/grafana/issues/1848). Panel timeshift: You can now use panel timeshift without a relative time override + +# 2.0.1 (2015-04-20) + +**Fixes** + +- [Issue #1784](https://github.com/grafana/grafana/issues/1784). Data source proxy: Fixed issue with using data source proxy when grafana is behind nginx suburl +- [Issue #1749](https://github.com/grafana/grafana/issues/1749). Graph Panel: Table legends are now visible when rendered to PNG +- [Issue #1786](https://github.com/grafana/grafana/issues/1786). Graph Panel: Legend in table mode now aligns, graph area is reduced depending on how many series +- [Issue #1734](https://github.com/grafana/grafana/issues/1734). Support for unicode / international characters in dashboard title (improved slugify) +- [Issue #1782](https://github.com/grafana/grafana/issues/1782). GitHub OAuth: Now works with GitHub for Enterprise, thanks @williamjoy +- [Issue #1780](https://github.com/grafana/grafana/issues/1780). Dashboard snapshot: Should not require login to view snapshot, Fixes #1780 + +# 2.0.0-Beta3 (2015-04-12) + +**RPM / DEB Package changes (to follow HFS)** + +- binary name changed to grafana-server +- does not install to `/opt/grafana` any more, installs to `/usr/share/grafana` +- binary to `/usr/sbin/grafana-server` +- init.d script improvements, renamed to `/etc/init.d/grafana-server` +- added default file with environment variables, + + - `/etc/default/grafana-server` (deb/ubuntu) + - `/etc/sysconfig/grafana-server` (centos/redhat) + +- added systemd service file, tested on debian jessie and centos7 +- config file in same location `/etc/grafana/grafana.ini` (now complete config file but with every setting commented out) +- data directory (where sqlite3) file is stored is now by default `/var/lib/grafana` +- no symlinking current to versions anymore +- For more info see [Issue #1758](https://github.com/grafana/grafana/issues/1758). + +**Config breaking change (setting rename)** + +- `[log] root_path` has changed to `[paths] logs` + +# 2.0.0-Beta2 (...) + +**Enhancements** + +- [Issue #1701](https://github.com/grafana/grafana/issues/1701). Share modal: Override UI theme via URL param for Share link, rendered panel, or embedded panel +- [Issue #1660](https://github.com/grafana/grafana/issues/1660). OAuth: Specify allowed email address domains for google or and github oauth logins + +**Fixes** + +- [Issue #1649](https://github.com/grafana/grafana/issues/1649). HTTP API: grafana /render calls nows with api keys +- [Issue #1667](https://github.com/grafana/grafana/issues/1667). Data source proxy & session timeout fix (caused 401 Unauthorized error after a while) +- [Issue #1707](https://github.com/grafana/grafana/issues/1707). Unsaved changes: Do not show for snapshots, scripted and file based dashboards +- [Issue #1703](https://github.com/grafana/grafana/issues/1703). Unsaved changes: Do not show for users with role `Viewer` +- [Issue #1675](https://github.com/grafana/grafana/issues/1675). Data source proxy: Fixed issue with Gzip enabled and data source proxy +- [Issue #1681](https://github.com/grafana/grafana/issues/1681). MySQL session: fixed problem using mysql as session store +- [Issue #1671](https://github.com/grafana/grafana/issues/1671). Data sources: Fixed issue with changing default data source (should not require full page load to take effect, now fixed) +- [Issue #1685](https://github.com/grafana/grafana/issues/1685). Search: Dashboard results should be sorted alphabetically +- [Issue #1673](https://github.com/grafana/grafana/issues/1673). Basic auth: Fixed issue when using basic auth proxy infront of Grafana + +# 2.0.0-Beta1 (2015-03-30) + +**Important Note** + +Grafana 2.x is fundamentally different from 1.x; it now ships with an integrated backend server. Please read the [Documentation](http://docs.grafana.org) for more detailed about this SIGNIFICANT change to Grafana + +**New features** + +- [Issue #1623](https://github.com/grafana/grafana/issues/1623). Share Dashboard: Dashboard snapshot sharing (dash and data snapshot), save to local or save to public snapshot dashboard snapshots.raintank.io site +- [Issue #1622](https://github.com/grafana/grafana/issues/1622). Share Panel: The share modal now has an embed option, gives you an iframe that you can use to embed a single graph on another web site +- [Issue #718](https://github.com/grafana/grafana/issues/718). Dashboard: When saving a dashboard and another user has made changes in between the user is prompted with a warning if he really wants to overwrite the other's changes +- [Issue #1331](https://github.com/grafana/grafana/issues/1331). Graph & Singlestat: New axis/unit format selector and more units (kbytes, Joule, Watt, eV), and new design for graph axis & grid tab and single stat options tab views +- [Issue #1241](https://github.com/grafana/grafana/issues/1242). Timepicker: New option in timepicker (under dashboard settings), to change `now` to be for example `now-1m`, useful when you want to ignore last minute because it contains incomplete data +- [Issue #171](https://github.com/grafana/grafana/issues/171). Panel: Different time periods, panels can override dashboard relative time and/or add a time shift +- [Issue #1488](https://github.com/grafana/grafana/issues/1488). Dashboard: Clone dashboard / Save as +- [Issue #1458](https://github.com/grafana/grafana/issues/1458). User: persisted user option for dark or light theme (no longer an option on a dashboard) +- [Issue #452](https://github.com/grafana/grafana/issues/452). Graph: Adds logarithmic scale option for base 10, base 16 and base 1024 + +**Enhancements** + +- [Issue #1366](https://github.com/grafana/grafana/issues/1366). Graph & Singlestat: Support for additional units, Fahrenheit (°F) and Celsius (°C), Humidity (%H), kW, watt-hour (Wh), kilowatt-hour (kWh), velocities (m/s, km/h, mpg, knot) +- [Issue #978](https://github.com/grafana/grafana/issues/978). Graph: Shared tooltip improvement, can now support metrics of different resolution/intervals +- [Issue #1297](https://github.com/grafana/grafana/issues/1297). Graphite: Added cumulative and minimumBelow graphite functions +- [Issue #1296](https://github.com/grafana/grafana/issues/1296). InfluxDB: Auto escape column names with special characters. Thanks @steven-aerts +- [Issue #1321](https://github.com/grafana/grafana/issues/1321). SingleStatPanel: You can now use template variables in pre & postfix +- [Issue #599](https://github.com/grafana/grafana/issues/599). Graph: Added right y axis label setting and graph support +- [Issue #1253](https://github.com/grafana/grafana/issues/1253). Graph & Singlestat: Users can now set decimal precision for legend and tooltips (override auto precision) +- [Issue #1255](https://github.com/grafana/grafana/issues/1255). Templating: Dashboard will now wait to load until all template variables that have refresh on load set or are initialized via url to be fully loaded and so all variables are in valid state before panels start issuing metric requests. +- [Issue #1344](https://github.com/grafana/grafana/issues/1344). OpenTSDB: Alias patterns (reference tag values), syntax is: \$tag_tagname or [[tag_tagname]] + +**Fixes** + +- [Issue #1298](https://github.com/grafana/grafana/issues/1298). InfluxDB: Fix handling of empty array in templating variable query +- [Issue #1309](https://github.com/grafana/grafana/issues/1309). Graph: Fixed issue when using zero as a grid threshold +- [Issue #1345](https://github.com/grafana/grafana/issues/1345). UI: Fixed position of confirm modal when scrolled down +- [Issue #1372](https://github.com/grafana/grafana/issues/1372). Graphite: Fix for nested complex queries, where a query references a query that references another query (ie the #[A-Z] syntax) +- [Issue #1363](https://github.com/grafana/grafana/issues/1363). Templating: Fix to allow custom template variables to contain white space, now only splits on ',' +- [Issue #1359](https://github.com/grafana/grafana/issues/1359). Graph: Fix for all series tooltip showing series with all null values when `Hide Empty` option is enabled +- [Issue #1497](https://github.com/grafana/grafana/issues/1497). Dashboard: Fixed memory leak when switching dashboards + +**Changes** + +- Dashboard title change & save will no longer create a new dashboard, it will just change the title. + +**OpenTSDB breaking change** + +- [Issue #1438](https://github.com/grafana/grafana/issues/1438). OpenTSDB: Automatic downsample interval passed to OpenTSDB (depends on timespan and graph width) +- NOTICE, Downsampling is now enabled by default, so if you have not picked a downsample aggregator in your metric query do so or your graphs will be misleading +- This will make Grafana a lot quicker for OpenTSDB users when viewing large time spans without having to change the downsample interval manually. + +**Tech** + +- [Issue #1311](https://github.com/grafana/grafana/issues/1311). Tech: Updated Font-Awesome from 3.2 to 4.2 + +# 1.9.1 (2014-12-29) + +**Enhancements** + +- [Issue #1028](https://github.com/grafana/grafana/issues/1028). Graph: New legend option `hideEmpty` to hide series with only null values from legend +- [Issue #1242](https://github.com/grafana/grafana/issues/1242). OpenTSDB: Downsample query field now supports interval template variable +- [Issue #1126](https://github.com/grafana/grafana/issues/1126). InfluxDB: Support more than 10 series name segments when using alias `$number` patterns + +**Fixes** + +- [Issue #1251](https://github.com/grafana/grafana/issues/1251). Graph: Fix for y axis and scaled units (GiB etc) caused rounding, for example 400 GiB instead of 378 GiB +- [Issue #1199](https://github.com/grafana/grafana/issues/1199). Graph: fix for series tooltip when one series is hidden/disabled +- [Issue #1207](https://github.com/grafana/grafana/issues/1207). Graphite: movingAverage / movingMedian parameter type improvement, now handles int and interval parameter + +# 1.9.0 (2014-12-02) + +**Enhancements** + +- [Issue #1130](https://github.com/grafana/grafana/issues/1130). SinglestatPanel: Added null point handling, and value to text mapping + +**Fixes** + +- [Issue #1087](https://github.com/grafana/grafana/issues/1087). Panel: Fixed IE9 crash due to angular drag drop +- [Issue #1093](https://github.com/grafana/grafana/issues/1093). SingleStatPanel: Fixed position for drilldown link tooltip when dashboard requires scrolling +- [Issue #1095](https://github.com/grafana/grafana/issues/1095). DrilldownLink: template variables in params property was not interpolated +- [Issue #1114](https://github.com/grafana/grafana/issues/1114). Graphite: Lexer fix, allow equal sign (=) in metric paths +- [Issue #1136](https://github.com/grafana/grafana/issues/1136). Graph: Fix to legend value Max and negative values +- [Issue #1150](https://github.com/grafana/grafana/issues/1150). SinglestatPanel: Fixed absolute drilldown link issue +- [Issue #1123](https://github.com/grafana/grafana/issues/1123). Firefox: Workaround for Firefox bug, caused input text fields to not be selectable and not have placeable cursor +- [Issue #1108](https://github.com/grafana/grafana/issues/1108). Graph: Fix for tooltip series order when series draw order was changed with zindex property + +# 1.9.0-rc1 (2014-11-17) + +**UI Improvements** + +- [Issue #770](https://github.com/grafana/grafana/issues/770). UI: Panel dropdown menu replaced with a new panel menu + +**Graph** + +- [Issue #877](https://github.com/grafana/grafana/issues/877). Graph: Smart auto decimal precision when using scaled unit formats +- [Issue #850](https://github.com/grafana/grafana/issues/850). Graph: Shared tooltip that shows multiple series & crosshair line, thx @toni-moreno +- [Issue #940](https://github.com/grafana/grafana/issues/940). Graph: New series style override option "Fill below to", useful to visualize max & min as a shadow for the mean +- [Issue #1030](https://github.com/grafana/grafana/issues/1030). Graph: Legend table display/look changed, now includes column headers for min/max/avg, and full width (unless on right side) +- [Issue #861](https://github.com/grafana/grafana/issues/861). Graph: Export graph time series data as csv file + +**New Panels** + +- [Issue #951](https://github.com/grafana/grafana/issues/951). SingleStat: New singlestat panel + +**Misc** + +- [Issue #864](https://github.com/grafana/grafana/issues/846). Panel: Share panel feature, get a link to panel with the current time range +- [Issue #938](https://github.com/grafana/grafana/issues/938). Panel: Plugin panels now reside outside of app/panels directory +- [Issue #952](https://github.com/grafana/grafana/issues/952). Help: Shortcut "?" to open help modal with list of all shortcuts +- [Issue #991](https://github.com/grafana/grafana/issues/991). ScriptedDashboard: data source services are now available in scripted dashboards, you can query data source for metric keys, generate dashboards, and even save them in a scripted dashboard (see scripted_gen_and_save.js for example) +- [Issue #1041](https://github.com/grafana/grafana/issues/1041). Panel: All panels can now have links to other dashboards or absolute links, these links are available in the panel menu. + +**Changes** + +- [Issue #1007](https://github.com/grafana/grafana/issues/1007). Graph: Series hide/show toggle changed to be default exclusive, so clicking on a series name will show only that series. (SHIFT or meta)+click will toggle hide/show. + +**OpenTSDB** + +- [Issue #930](https://github.com/grafana/grafana/issues/930). OpenTSDB: Adding counter max and counter reset value to open tsdb query editor, thx @rsimiciuc +- [Issue #917](https://github.com/grafana/grafana/issues/917). OpenTSDB: Templating support for OpenTSDB series name and tags, thx @mchataigner + +**InfluxDB** + +- [Issue #714](https://github.com/grafana/grafana/issues/714). InfluxDB: Support for sub second resolution graphs + +**Fixes** + +- [Issue #925](https://github.com/grafana/grafana/issues/925). Graph: bar width calculation fix for some edge cases (bars would render on top of each other) +- [Issue #505](https://github.com/grafana/grafana/issues/505). Graph: fix for second y axis tick unit labels wrapping on the next line +- [Issue #987](https://github.com/grafana/grafana/issues/987). Dashboard: Collapsed rows became invisible when hide controls was enabled + +======= + +# 1.8.1 (2014-09-30) + +**Fixes** + +- [Issue #855](https://github.com/grafana/grafana/issues/855). Graph: Fix for scroll issue in graph edit mode when dropdown goes below screen +- [Issue #847](https://github.com/grafana/grafana/issues/847). Graph: Fix for series draw order not being the same after hiding/unhiding series +- [Issue #851](https://github.com/grafana/grafana/issues/851). Annotations: Fix for annotations not reloaded when switching between 2 dashboards with annotations +- [Issue #846](https://github.com/grafana/grafana/issues/846). Edit panes: Issue when open row or json editor when scrolled down the page, unable to scroll and you did not see editor +- [Issue #840](https://github.com/grafana/grafana/issues/840). Import: Fixes to import from json file and import from graphite. Issues was lingering state from previous dashboard. +- [Issue #859](https://github.com/grafana/grafana/issues/859). InfluxDB: Fix for bug when saving dashboard where title is the same as slugified url id +- [Issue #852](https://github.com/grafana/grafana/issues/852). White theme: Fixes for hidden series legend text and disabled annotations color + +# 1.8.0 (2014-09-22) + +Read this [blog post](https://grafana.com/blog/2014/09/11/grafana-1.8.0-rc1-released) for an overview of all improvements. + +**Fixes** + +- [Issue #802](https://github.com/grafana/grafana/issues/802). Annotations: Fix when using InfluxDB data source +- [Issue #795](https://github.com/grafana/grafana/issues/795). Chrome: Fix for display issue in chrome beta & chrome canary when entering edit mode +- [Issue #818](https://github.com/grafana/grafana/issues/818). Graph: Added percent y-axis format +- [Issue #828](https://github.com/grafana/grafana/issues/828). Elasticsearch: saving new dashboard with title equal to slugified url would cause it to deleted. +- [Issue #830](https://github.com/grafana/grafana/issues/830). Annotations: Fix for elasticsearch annotations and mapping nested fields + +# 1.8.0-RC1 (2014-09-12) + +**UI polish / changes** + +- [Issue #725](https://github.com/grafana/grafana/issues/725). UI: All modal editors are removed and replaced by an edit pane under menu. The look of editors is also updated and polished. Search dropdown is also shown as pane under menu and has seen some UI polish. + +**Filtering/Templating feature overhaul** + +- Filtering renamed to Templating, and filter items to variables +- Filter editing has gotten its own edit pane with much improved UI and options +- [Issue #296](https://github.com/grafana/grafana/issues/296). Templating: Can now retrieve variable values from a non-default data source +- [Issue #219](https://github.com/grafana/grafana/issues/219). Templating: Template variable value selection is now a typeahead autocomplete dropdown +- [Issue #760](https://github.com/grafana/grafana/issues/760). Templating: Extend template variable syntax to include \$variable syntax replacement +- [Issue #234](https://github.com/grafana/grafana/issues/234). Templating: Interval variable type for time intervals summarize/group by parameter, included "auto" option, and auto step counts option. +- [Issue #262](https://github.com/grafana/grafana/issues/262). Templating: Ability to use template variables for function parameters via custom variable type, can be used as parameter for movingAverage or scaleToSeconds for example +- [Issue #312](https://github.com/grafana/grafana/issues/312). Templating: Can now use template variables in panel titles +- [Issue #613](https://github.com/grafana/grafana/issues/613). Templating: Full support for InfluxDB, filter by part of series names, extract series substrings, nested queries, multiple where clauses! +- Template variables can be initialized from url, with var-my_varname=value, breaking change, before it was just my_varname. +- Templating and url state sync has some issues that are not solved for this release, see [Issue #772](https://github.com/grafana/grafana/issues/772) for more details. + +**InfluxDB Breaking changes** + +- To better support templating, fill(0) and group by time low limit some changes has been made to the editor and query model schema +- Currently some of these changes are breaking +- If you used custom condition filter you need to open the graph in edit mode, the editor will update the schema, and the queries should work again +- If you used a raw query you need to remove the time filter and replace it with \$timeFilter (this is done automatically when you switch from query editor to raw query, but old raw queries needs to updated) +- If you used group by and later removed the group by the graph could break, open in editor and should correct it +- InfluxDB annotation queries that used [[timeFilter]] should be updated to use \$timeFilter syntax instead +- Might write an upgrade tool to update dashboards automatically, but right now master (1.8) includes the above breaking changes + +**InfluxDB query editor enhancements** + +- [Issue #756](https://github.com/grafana/grafana/issues/756). InfluxDB: Add option for fill(0) and fill(null), integrated help in editor for why this option is important when stacking series +- [Issue #743](https://github.com/grafana/grafana/issues/743). InfluxDB: A group by time option for all queries in graph panel that supports a low limit for auto group by time, very important for stacking and fill(0) +- The above to enhancements solves the problems associated with stacked bars and lines when points are missing, these issues are solved: +- [Issue #673](https://github.com/grafana/grafana/issues/673). InfluxDB: stacked bars missing intermediate data points, unless lines also enabled +- [Issue #674](https://github.com/grafana/grafana/issues/674). InfluxDB: stacked chart ignoring series without latest values +- [Issue #534](https://github.com/grafana/grafana/issues/534). InfluxDB: No order in stacked bars mode + +**New features and improvements** + +- [Issue #117](https://github.com/grafana/grafana/issues/117). Graphite: Graphite query builder can now handle functions that multiple series as arguments! +- [Issue #281](https://github.com/grafana/grafana/issues/281). Graphite: Metric node/segment selection is now a textbox with autocomplete dropdown, allow for custom glob expression for single node segment without entering text editor mode. +- [Issue #304](https://github.com/grafana/grafana/issues/304). Dashboard: View dashboard json, edit/update any panel using json editor, makes it possible to quickly copy a graph from one dashboard to another. +- [Issue #578](https://github.com/grafana/grafana/issues/578). Dashboard: Row option to display row title even when the row is visible +- [Issue #672](https://github.com/grafana/grafana/issues/672). Dashboard: panel fullscreen & edit state is present in url, can now link to graph in edit & fullscreen mode. +- [Issue #709](https://github.com/grafana/grafana/issues/709). Dashboard: Small UI look polish to search results, made dashboard title link are larger +- [Issue #425](https://github.com/grafana/grafana/issues/425). Graph: New section in 'Display Styles' tab to override any display setting on per series bases (mix and match lines, bars, points, fill, stack, line width etc) +- [Issue #634](https://github.com/grafana/grafana/issues/634). Dashboard: Dashboard tags now in different colors (from fixed palette) determined by tag name. +- [Issue #685](https://github.com/grafana/grafana/issues/685). Dashboard: New config.js option to change/remove window title prefix. +- [Issue #781](https://github.com/grafana/grafana/issues/781). Dashboard: Title URL is now slugified for greater URL readability, works with both ES & InfluxDB storage, is backward compatible +- [Issue #785](https://github.com/grafana/grafana/issues/785). Elasticsearch: Support for full elasticsearch lucene search grammar when searching for dashboards, better async search +- [Issue #787](https://github.com/grafana/grafana/issues/787). Dashboard: time range can now be read from URL parameters, will override dashboard saved time range + +**Fixes** + +- [Issue #696](https://github.com/grafana/grafana/issues/696). Graph: Fix for y-axis format 'none' when values are in scientific notation (ex 2.3e-13) +- [Issue #733](https://github.com/grafana/grafana/issues/733). Graph: Fix for tooltip current value decimal precision when 'none' axis format was selected +- [Issue #697](https://github.com/grafana/grafana/issues/697). Graphite: Fix for Glob syntax in graphite queries ([1-9] and ?) that made the query editor / parser bail and fallback to a text box. +- [Issue #702](https://github.com/grafana/grafana/issues/702). Graphite: Fix for nonNegativeDerivative function, now possible to not include optional first parameter maxValue +- [Issue #277](https://github.com/grafana/grafana/issues/277). Dashboard: Fix for timepicker date & tooltip when UTC timezone selected. +- [Issue #699](https://github.com/grafana/grafana/issues/699). Dashboard: Fix for bug when adding rows from dashboard settings dialog. +- [Issue #723](https://github.com/grafana/grafana/issues/723). Dashboard: Fix for hide controls setting not used/initialized on dashboard load +- [Issue #724](https://github.com/grafana/grafana/issues/724). Dashboard: Fix for zoom out causing right hand "to" range to be set in the future. + +**Tech** + +- Upgraded from angularjs 1.1.5 to 1.3 beta 17; +- Switch from underscore to lodash +- helpers to easily unit test angularjs controllers and services +- Test coverage through coveralls +- Upgrade from jquery 1.8.0 to 2.1.1 (**Removes support for IE7 & IE8**) + +# 1.7.1 (unreleased) + +**Fixes** + +- [Issue #691](https://github.com/grafana/grafana/issues/691). Dashboard: Tooltip fixes, sometimes they would not show, and sometimes they would get stuck. +- [Issue #695](https://github.com/grafana/grafana/issues/695). Dashboard: Tooltip on goto home menu icon would get stuck after clicking on it + +# 1.7.0 (2014-08-11) + +**Fixes** + +- [Issue #652](https://github.com/grafana/grafana/issues/652). Timepicker: Entering custom date range impossible when refresh is low (now is constantly reset) +- [Issue #450](https://github.com/grafana/grafana/issues/450). Graph: Tooltip does not disappear sometimes and would get stuck +- [Issue #655](https://github.com/grafana/grafana/issues/655). General: Auto refresh not initiated / started after dashboard loading +- [Issue #657](https://github.com/grafana/grafana/issues/657). General: Fix for refresh icon in IE browsers +- [Issue #661](https://github.com/grafana/grafana/issues/661). Annotations: Elasticsearch querystring with filter template replacements was not interpolated +- [Issue #660](https://github.com/grafana/grafana/issues/660). OpenTSDB: fix opentsdb queries that returned more than one series + +**Change** + +- [Issue #681](https://github.com/grafana/grafana/issues/681). Dashboard: The panel error bar has been replaced with a small error indicator, this indicator does not change panel height and is a lot less intrusive. Hover over it for short details, click on it for more details. + +# 1.7.0-rc1 (2014-08-05) + +**New features or improvements** + +- [Issue #581](https://github.com/grafana/grafana/issues/581). InfluxDB: Add continuous query in series results (series typeahead). +- [Issue #584](https://github.com/grafana/grafana/issues/584). InfluxDB: Support for alias & alias patterns when using raw query mode +- [Issue #394](https://github.com/grafana/grafana/issues/394). InfluxDB: Annotation support +- [Issue #633](https://github.com/grafana/grafana/issues/633). InfluxDB: InfluxDB can now act as a datastore for dashboards +- [Issue #610](https://github.com/grafana/grafana/issues/610). InfluxDB: Support for InfluxdB v0.8 list series response schema (series typeahead) +- [Issue #525](https://github.com/grafana/grafana/issues/525). InfluxDB: Enhanced series aliasing (legend names) with pattern replacements +- [Issue #266](https://github.com/grafana/grafana/issues/266). Graphite: New option cacheTimeout to override graphite default memcache timeout +- [Issue #606](https://github.com/grafana/grafana/issues/606). General: New global option in config.js to specify admin password (useful to hinder users from accidentally make changes) +- [Issue #201](https://github.com/grafana/grafana/issues/201). Annotations: Elasticsearch data source support for events +- [Issue #344](https://github.com/grafana/grafana/issues/344). Annotations: Annotations can now be fetched from non default data sources +- [Issue #631](https://github.com/grafana/grafana/issues/631). Search: max_results config.js option & scroll in search results (To show more or all dashboards) +- [Issue #511](https://github.com/grafana/grafana/issues/511). Text panel: Allow [[..]] filter notation in all text panels (markdown/html/text) +- [Issue #136](https://github.com/grafana/grafana/issues/136). Graph: New legend display option "Align as table" +- [Issue #556](https://github.com/grafana/grafana/issues/556). Graph: New legend display option "Right side", will show legend to the right of the graph +- [Issue #604](https://github.com/grafana/grafana/issues/604). Graph: New axis format, 'bps' (SI unit in steps of 1000) useful for network gear metrics +- [Issue #626](https://github.com/grafana/grafana/issues/626). Graph: Downscale y axis to more precise unit, value of 0.1 for seconds format will be formatted as 100 ms. Thanks @kamaradclimber +- [Issue #618](https://github.com/grafana/grafana/issues/618). OpenTSDB: Series alias option to override metric name returned from opentsdb. Thanks @heldr + +**Documentation** + +- [Issue #635](https://github.com/grafana/grafana/issues/635). Docs for features and changes in v1.7, new troubleshooting guide, new Getting started guide, improved install & config guide. + +**Changes** + +- [Issue #536](https://github.com/grafana/grafana/issues/536). Graphite: Use unix epoch for Graphite from/to for absolute time ranges +- [Issue #641](https://github.com/grafana/grafana/issues/536). General: Dashboard save temp copy feature settings moved from dashboard to config.js, default is enabled, and ttl to 30 days +- [Issue #532](https://github.com/grafana/grafana/issues/532). Schema: Dashboard schema changes, "Unsaved changes" should not appear for schema changes. All changes are backward compatible with old schema. + +**Fixes** + +- [Issue #545](https://github.com/grafana/grafana/issues/545). Graph: Fix formatting negative values (axis formats, legend values) +- [Issue #460](https://github.com/grafana/grafana/issues/460). Graph: fix for max legend value when max value is zero +- [Issue #628](https://github.com/grafana/grafana/issues/628). Filtering: Fix for nested filters, changing a child filter could result in infinite recursion in some cases +- [Issue #528](https://github.com/grafana/grafana/issues/528). Graphite: Fix for graphite expressions parser failure when metric expressions starts with curly brace segment + +# 1.6.1 (2014-06-24) + +**New features or improvements** + +- [Issue #360](https://github.com/grafana/grafana/issues/360). Ability to set y min/max for right y-axis (RR #519) + +**Fixes** + +- [Issue #500](https://github.com/grafana/grafana/issues/360). Fixes regex InfluxDB queries introduced in 1.6.0 +- [Issue #506](https://github.com/grafana/grafana/issues/506). Bug in when using % sign in legends (aliases), fixed by removing url decoding of metric names +- [Issue #522](https://github.com/grafana/grafana/issues/522). Series names and column name typeahead cache fix +- [Issue #504](https://github.com/grafana/grafana/issues/504). Fixed influxdb issue with raw query that caused wrong value column detection +- [Issue #526](https://github.com/grafana/grafana/issues/526). Default property that marks which data source is default in config.js is now optional +- [Issue #342](https://github.com/grafana/grafana/issues/342). Auto-refresh caused 2 refreshes (and hence multiple queries) each time (at least in firefox) + +# 1.6.0 (2014-06-16) + +#### New features or improvements + +- [Issue #427](https://github.com/grafana/grafana/issues/427). New Y-axis formater for metric values that represent seconds, Thanks @jippi +- [Issue #390](https://github.com/grafana/grafana/issues/390). Allow special characters in series names (influxdb data source), Thanks @majst01 +- [Issue #428](https://github.com/grafana/grafana/issues/428). Refactoring of filterSrv, Thanks @Tetha +- [Issue #445](https://github.com/grafana/grafana/issues/445). New config for playlist feature. Set playlist_timespan to set default playlist interval, Thanks @rmca +- [Issue #461](https://github.com/grafana/grafana/issues/461). New graphite function definition added isNonNull, Thanks @tmonk42 +- [Issue #455](https://github.com/grafana/grafana/issues/455). New InfluxDB function difference add to function dropdown +- [Issue #459](https://github.com/grafana/grafana/issues/459). Added parameter to keepLastValue graphite function definition (default 100) + [Issue #418](https://github.com/grafana/grafana/issues/418). to the browser cache when upgrading grafana and improve load performance +- [Issue #327](https://github.com/grafana/grafana/issues/327). Partial support for url encoded metrics when using Graphite data source. Thanks @axe-felix +- [Issue #473](https://github.com/grafana/grafana/issues/473). Improvement to InfluxDB query editor and function/value column selection +- [Issue #375](https://github.com/grafana/grafana/issues/375). Initial support for filtering (templated queries) for InfluxDB. Thanks @mavimo +- [Issue #475](https://github.com/grafana/grafana/issues/475). Row editing and adding new panel is now a lot quicker and easier with the new row menu +- [Issue #211](https://github.com/grafana/grafana/issues/211). New data source! Initial support for OpenTSDB, Thanks @mpage +- [Issue #492](https://github.com/grafana/grafana/issues/492). Improvement and polish to the OpenTSDB query editor +- [Issue #441](https://github.com/grafana/grafana/issues/441). Influxdb group by support, Thanks @piis3 +- improved asset (css/js) build pipeline, added revision to css and js. Will remove issues related + +#### Changes + +- [Issue #475](https://github.com/grafana/grafana/issues/475). Add panel icon and Row edit button is replaced by the Row edit menu +- New graphs now have a default empty query +- Add Row button now creates a row with default height of 250px (no longer opens dashboard settings modal) +- Clean up of config.sample.js, graphiteUrl removed (still works, but deprecated, removed in future) + Use data sources config instead. panel_names removed from config.js. Use plugins.panels to add custom panels +- Graphite panel is now renamed graph (Existing dashboards will still work) + +#### Fixes + +- [Issue #126](https://github.com/grafana/grafana/issues/126). Graphite query lexer change, can now handle regex parameters for aliasSub function +- [Issue #447](https://github.com/grafana/grafana/issues/447). Filter option loading when having multiple nested filters now works better. Options are now reloaded correctly and there are no multiple renders/refresh in between. +- [Issue #412](https://github.com/grafana/grafana/issues/412). After a filter option is changed and a nested template param is reloaded, if the current value exists after the options are reloaded the current selected value is kept. +- [Issue #460](https://github.com/grafana/grafana/issues/460). Legend Current value did not display when value was zero +- [Issue #328](https://github.com/grafana/grafana/issues/328). Fix to series toggling bug that caused annotations to be hidden when toggling/hiding series. +- [Issue #293](https://github.com/grafana/grafana/issues/293). Fix for graphite function selection menu that some times draws outside screen. It now displays upward +- [Issue #350](https://github.com/grafana/grafana/issues/350). Fix for exclusive series toggling (hold down CTRL, SHIFT or META key) and left click a series for exclusive toggling +- [Issue #472](https://github.com/grafana/grafana/issues/472). CTRL does not work on MAC OSX but SHIFT or META should (depending on browser) + +# 1.5.4 (2014-05-13) + +### New features and improvements + +- InfluxDB enhancement: support for multiple hosts (with retries) and raw queries ([Issue #318](https://github.com/grafana/grafana/issues/318), thx @toddboom) +- Added rounding for graphites from and to time range filters + for very short absolute ranges ([Issue #320](https://github.com/grafana/grafana/issues/320)) +- Increased resolution for graphite datapoints (maxDataPoints), now equal to panel pixel width. ([Issue #5](https://github.com/grafana/grafana/issues/5)) +- Improvement to influxdb query editor, can now add where clause and alias ([Issue #331](https://github.com/grafana/grafana/issues/331), thanks @mavimo) +- New config setting for graphite data source to control if json render request is POST or GET ([Issue #345](https://github.com/grafana/grafana/issues/345)) +- Unsaved changes warning feature ([Issue #324](https://github.com/grafana/grafana/issues/324)) +- Improvement to series toggling, CTRL+MouseClick on series name will now hide all others ([Issue #350](https://github.com/grafana/grafana/issues/350)) + +### Changes + +- Graph default setting for Y-Min changed from zero to auto scaling (will not effect existing dashboards). ([Issue #386](https://github.com/grafana/grafana/issues/386)) - thx @kamaradclimber + +### Fixes + +- Fixes to filters and "All" option. It now never uses "\*" as value, but all options in a {node1, node2, node3} expression ([Issue #228](https://github.com/grafana/grafana/issues/228), #359) +- Fix for InfluxDB query generation with columns containing dots or dashes ([Issue #369](https://github.com/grafana/grafana/issues/369), #348) - Thanks to @jbripley + +# 1.5.3 (2014-04-17) + +- Add support for async scripted dashboards ([Issue #274](https://github.com/grafana/grafana/issues/274)) +- Text panel now accepts html (for links to other dashboards, etc) ([Issue #236](https://github.com/grafana/grafana/issues/236)) +- Fix for Text panel, now changes take effect directly ([Issue #251](https://github.com/grafana/grafana/issues/251)) +- Fix when adding functions without params that did not cause graph to update ([Issue #267](https://github.com/grafana/grafana/issues/267)) +- Graphite errors are now much easier to see and troubleshoot with the new inspector ([Issue #265](https://github.com/grafana/grafana/issues/265)) +- Use influxdb aliases to distinguish between multiple columns ([Issue #283](https://github.com/grafana/grafana/issues/283)) +- Correction to ms axis formater, now formats days correctly. ([Issue #189](https://github.com/grafana/grafana/issues/189)) +- Css fix for Firefox and using top menu dropdowns in panel fullscreen / edit mode ([Issue #106](https://github.com/grafana/grafana/issues/106)) +- Browser page title is now Grafana - {{dashboard title}} ([Issue #294](https://github.com/grafana/grafana/issues/294)) +- Disable auto refresh zooming in (every time you change to an absolute time range), refresh will be restored when you change time range back to relative ([Issue #282](https://github.com/grafana/grafana/issues/282)) +- More graphite functions + +# 1.5.2 (2014-03-24) + +### New Features and improvements + +- Support for second optional params for functions like aliasByNode ([Issue #167](https://github.com/grafana/grafana/issues/167)). Read the wiki on the [Function Editor](https://github.com/torkelo/grafana/wiki/Graphite-Function-Editor) for more info. +- More functions added to InfluxDB query editor ([Issue #218](https://github.com/grafana/grafana/issues/218)) +- Filters can now be used inside other filters (templated segments) ([Issue #128](https://github.com/grafana/grafana/issues/128)) +- More graphite functions added + +### Fixes + +- Float arguments now work for functions like scale ([Issue #223](https://github.com/grafana/grafana/issues/223)) +- Fix for graphite function editor, the graph & target was not updated after adding a function and leaving default params as is #191 + +The zip files now contains a sub folder with project name and version prefix. ([Issue #209](https://github.com/grafana/grafana/issues/209)) + +# 1.5.1 (2014-03-10) + +### Fixes + +- maxDataPoints must be an integer #184 (thanks @frejsoya for fixing this) + +For people who are find Grafana slow for large time spans or high resolution metrics. This is most likely due to graphite returning a large number of datapoints. The maxDataPoints parameter solves this issue. For maxDataPoints to work you need to run the latest graphite-web (some builds of 0.9.12 does not include this feature). + +Read this for more info: +[Performance for large time spans](https://github.com/torkelo/grafana/wiki/Performance-for-large-time-spans) + +# 1.5.0 (2014-03-09) + +### New Features and improvements + +- New function editor [video demo](http://youtu.be/I90WHRwE1ZM) ([Issue #178](https://github.com/grafana/grafana/issues/178)) +- Links to function documentation from function editor ([Issue #3](https://github.com/grafana/grafana/issues/3)) +- Reorder functions ([Issue #130](https://github.com/grafana/grafana/issues/130)) +- [Initial support for InfluxDB](https://github.com/torkelo/grafana/wiki/InfluxDB) as metric data source (#103), need feedback! +- [Dashboard playlist](https://github.com/torkelo/grafana/wiki/Dashboard-playlist) ([Issue #36](https://github.com/grafana/grafana/issues/36)) +- When adding aliasByNode smartly set node number ([Issue #175](https://github.com/grafana/grafana/issues/175)) +- Support graphite identifiers with embedded colons ([Issue #173](https://github.com/grafana/grafana/issues/173)) +- Typeahead & autocomplete when adding new function ([Issue #164](https://github.com/grafana/grafana/issues/164)) +- More graphite function definitions +- Make "ms" axis format include hour, day, weeks, month and year ([Issue #149](https://github.com/grafana/grafana/issues/149)) +- Microsecond axis format ([Issue #146](https://github.com/grafana/grafana/issues/146)) +- Specify template parameters in URL ([Issue #123](https://github.com/grafana/grafana/issues/123)) + +### Fixes + +- Basic Auth fix ([Issue #152](https://github.com/grafana/grafana/issues/152)) +- Fix to annotations with graphite source & null values ([Issue #138](https://github.com/grafana/grafana/issues/138)) + +# 1.4.0 (2014-02-21) + +### New Features + +- #44 Annotations! Required a lot of work to get right. Read wiki article for more info. Supported annotations data sources are graphite metrics and graphite events. Support for more will be added in the future! +- #35 Support for multiple graphite servers! (Read wiki article for more) +- #116 Back to dashboard link in top menu to easily exist full screen / edit mode. +- #114, #97 Legend values now use the same y axes formatter +- #77 Improvements and polish to the light theme + +### Changes + +- #98 Stack is no longer by default turned on in graph display settings. +- Hide controls (Ctrl+h) now hides the sub menu row (where filtering, and annotations are). So if you had filtering enabled and hide controls enabled you will not see the filtering sub menu. + +### Fixes: + +- #94 Fix for bug that caused dashboard settings to sometimes not contain timepicker tab. +- #110 Graph with many many metrics caused legend to push down graph editor below screen. You can now scroll in edit mode & full screen mode for graphs with lots of series & legends. +- #104 Improvement to graphite target editor, select wildcard now gives you a "select metric" link for the next node. +- #105 Added zero as a possible node value in groupByAlias function + +# 1.3.0 (2014-02-13) + +### New features or improvements + +- #86 Dashboard tags and search (see wiki article for details) +- #54 Enhancement to filter / template. "Include All" improvement +- #82 Dashboard search result sorted in alphabetical order + +### Fixes + +- #91 Custom date selector is one day behind +- #89 Filter / template does not work after switching dashboard +- #88 Closed / Minimized row css bug +- #85 Added all parameters to summarize function +- #83 Stack as percent should now work a lot better! + +# 1.2.0 (2014-02-10) + +### New features + +- #70 Grid Thresholds (warning and error regions or lines in graph) +- #72 Added an example of a scripted dashboard and a short wiki article documenting scripted dashboards. + +### Fixes + +- #81 Grid min/max values are ignored bug +- #80 "stacked as percent" graphs should always use "max" value of 100 bug +- #73 Left Y format change did not work +- #42 Fixes to grid min/max auto scaling +- #69 Fixes to lexer/parser for metrics segments like "10-20". +- #67 Allow decimal input for scale function +- #68 Bug when trying to open dashboard while in edit mode + +# 1.1.0 (2014-02-06) + +### New features: + +- #22 Support for native graphite png renderer, does not support click and select zoom yet +- #60 Support for legend values (cactiStyle, min, max, current, total, avg). The options for these are found in the new "Axes & Grid" tab for now. +- #62 There is now a "New" button in the search/open dashboard view to quickly open a clean empty dashboard. +- #55 Basic auth is now supported for elastic search as well +- some new function definitions added (will focus more on this for next release). + +### Fixes + +- #45 zero values from graphite was handled as null. +- #63 Kibana / Grafana on same host would use same localStorage keys, now fixed +- #46 Impossible to edit graph without a name fixed. +- #24 fix for dashboard search when elastic search is configured to disable \_all field. +- #38 Improvement to lexer / parser to support pure numeric literals in metric segments + +Thanks to everyone who contributed fixes and provided feedback :+1: + +# 1.0.4 (2014-01-24) + +- [Issue #28](https://github.com/grafana/grafana/issues/28) - Relative time range caused 500 graphite error in some cases (thx rsommer for the fix) + +# 1.0.3 (2014-01-23) + +- #9 Add Y-axis format for milliseconds +- #16 Add support for Basic Auth (use http://username:password@yourgraphitedomain.com) +- #13 Relative time ranges now uses relative time ranges when issuing graphite query + +# 1.0.2 (2014-01-21) + +- [Issue #12](https://github.com/grafana/grafana/issues/12), should now work ok without ElasticSearch + +# 1.0.1 (2014-01-21) + +- Resize fix +- Improvements to drag & drop +- Added a few graphite function definitions +- Fixed duplicate panel bug +- Updated default dashboard with welcome message and randomWalk graph + +# 1.0.0 (2014-01-19) + +First public release diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..3d4caa4f --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at conduct@grafana.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..ea19d699 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,85 @@ +# Contributing to Grafana + +Thank you for your interest in contributing to Grafana! We welcome all people who want to contribute in a healthy and constructive manner within our community. To help us create a safe and positive community experience for all, we require all participants to adhere to the [Code of Conduct](CODE_OF_CONDUCT.md). + +This document is a guide to help you through the process of contributing to Grafana. + +## Become a contributor + +You can contribute to Grafana in several ways. Here are some examples: + +- Contribute to the Grafana codebase. +- Report and triage bugs. +- Develop community plugins and dashboards. +- Write technical documentation and blog posts, for users and contributors. +- Organize meetups and user groups in your local area. +- Help others by answering questions about Grafana. + +For more ways to contribute, check out the [Open Source Guides](https://opensource.guide/how-to-contribute/). + +### Report bugs + +Before submitting a new issue, try to make sure someone hasn't already reported the problem. Look through the [existing issues](https://github.com/grafana/grafana/issues) for similar issues. + +Report a bug by submitting a [bug report](https://github.com/grafana/grafana/issues/new?labels=type%3A+bug&template=1-bug_report.md). Make sure that you provide as much information as possible on how to reproduce the bug. + +Follow the issue template and add additional information that will help us replicate the problem. + +For data visualization issues: + +- Query results from the inspect drawer (data tab & query inspector) +- Panel settings can be extracted in the panel inspect drawer JSON tab + +For a dashboard related issues: + +- Dashboard JSON can be found in the dashboard settings JSON model view + +For authentication and alerting Grafana server logs are useful. + +#### Security issues + +If you believe you've found a security vulnerability, please read our [security policy](https://github.com/grafana/grafana/security/policy) for more details. + +### Suggest enhancements + +If you have an idea of how to improve Grafana, submit an [enhancement request](https://github.com/grafana/grafana/discussions/new). + +We want to make Grafana accessible to even more people. Submit an [accessibility issue](https://github.com/grafana/grafana/issues/new?labels=type%3A+accessibility&template=3-accessibility.md) to help us understand what we can improve. + +### Write documentation + +To edit or write technical content, refer to [Contribute to our documentation](/contribute/documentation/README.md). We welcome your expertise and input as our body of technical content grows. + +### Triage issues + +If you don't have the knowledge or time to code, consider helping with _issue triage_. The community will thank you for saving them time by spending some of yours. + +Read more about the ways you can [Triage issues](/contribute/triage-issues.md). + +### Answering questions + +If you have a question and you can't find the answer in the [documentation](https://grafana.com/docs/), the next step is to ask it on the [community site](https://community.grafana.com/). + +It's important to us to help these users, and we'd love your help. Sign up to our [community site](https://community.grafana.com/), and start helping other Grafana users by answering their questions. + +### Your first contribution + +Unsure where to begin contributing to Grafana? Start by browsing issues labeled `beginner friendly` or `help wanted`. + +- [Beginner-friendly](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22) issues are generally straightforward to complete. +- [Help wanted](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issues are problems we would like the community to help us with regardless of complexity. + +If you're looking to make a code change, see how to set up your environment for [local development](contribute/developer-guide.md). + +When you're ready to contribute, it's time to [Create a pull request](/contribute/create-pull-request.md). + +#### Contributor License Agreement (CLA) + +Before we can accept your pull request, you need to [sign our CLA](https://grafana.com/docs/grafana/latest/developers/cla/). If you haven't, our CLA assistant prompts you to when you create your pull request. + +## Where do I go from here? + +- Set up your [development environment](contribute/developer-guide.md). +- Learn how to [contribute documentation](contribute/documentation.md). +- Get started [developing plugins](https://grafana.com/docs/grafana/latest/developers/plugins/) for Grafana. +- Look through the resources in the [contribute](https://github.com/grafana/grafana/tree/main/contribute) folder. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..e3768bfc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,95 @@ +FROM node:16-alpine3.14 as js-builder + +ENV NODE_OPTIONS=--max_old_space_size=8000 + +WORKDIR /grafana + +COPY package.json yarn.lock .yarnrc.yml ./ +COPY .yarn .yarn +COPY packages packages +COPY plugins-bundled plugins-bundled + +RUN yarn install + +COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js babel.config.json ./ +COPY public public +COPY tools tools +COPY scripts scripts +COPY emails emails + +ENV NODE_ENV production +RUN yarn build + +FROM golang:1.17.3-alpine3.14 as go-builder + +RUN apk add --no-cache gcc g++ make + +WORKDIR /grafana + +COPY go.mod go.sum embed.go Makefile build.go package.json ./ +COPY cue cue +COPY packages/grafana-schema packages/grafana-schema +COPY public/app/plugins public/app/plugins +COPY pkg pkg +COPY scripts scripts +COPY cue.mod cue.mod +COPY .bingo .bingo + +RUN go mod verify +RUN make build-go + +# Final stage +FROM alpine:3.14.3 + +LABEL maintainer="Grafana team " + +ARG GF_UID="472" +ARG GF_GID="0" + +ENV PATH="/usr/share/grafana/bin:$PATH" \ + GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \ + GF_PATHS_DATA="/var/lib/grafana" \ + GF_PATHS_HOME="/usr/share/grafana" \ + GF_PATHS_LOGS="/var/log/grafana" \ + GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \ + GF_PATHS_PROVISIONING="/etc/grafana/provisioning" + +WORKDIR $GF_PATHS_HOME + +RUN apk add --no-cache ca-certificates bash tzdata musl-utils +RUN apk add --no-cache openssl ncurses-libs ncurses-terminfo-base --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main +RUN apk upgrade ncurses-libs ncurses-terminfo-base --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main +RUN apk info -vv | sort + +COPY conf ./conf + +RUN if [ ! $(getent group "$GF_GID") ]; then \ + addgroup -S -g $GF_GID grafana; \ + fi + +RUN export GF_GID_NAME=$(getent group $GF_GID | cut -d':' -f1) && \ + mkdir -p "$GF_PATHS_HOME/.aws" && \ + adduser -S -u $GF_UID -G "$GF_GID_NAME" grafana && \ + mkdir -p "$GF_PATHS_PROVISIONING/datasources" \ + "$GF_PATHS_PROVISIONING/dashboards" \ + "$GF_PATHS_PROVISIONING/notifiers" \ + "$GF_PATHS_PROVISIONING/plugins" \ + "$GF_PATHS_PROVISIONING/access-control" \ + "$GF_PATHS_LOGS" \ + "$GF_PATHS_PLUGINS" \ + "$GF_PATHS_DATA" && \ + cp "$GF_PATHS_HOME/conf/sample.ini" "$GF_PATHS_CONFIG" && \ + cp "$GF_PATHS_HOME/conf/ldap.toml" /etc/grafana/ldap.toml && \ + chown -R "grafana:$GF_GID_NAME" "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \ + chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" + +COPY --from=go-builder /grafana/bin/*/grafana-server /grafana/bin/*/grafana-cli ./bin/ +COPY --from=js-builder /grafana/public ./public +COPY --from=js-builder /grafana/tools ./tools + +EXPOSE 3000 + +COPY ./packaging/docker/run.sh /run.sh + +USER grafana +ENTRYPOINT [ "/run.sh" ] diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu new file mode 100644 index 00000000..b486d7ae --- /dev/null +++ b/Dockerfile.ubuntu @@ -0,0 +1,86 @@ +FROM node:16-alpine3.14 as js-builder + +ENV NODE_OPTIONS=--max_old_space_size=8000 + +WORKDIR /usr/src/app/ + +COPY package.json yarn.lock ./ +COPY packages packages +COPY .yarnrc.yml ./ +COPY .yarn .yarn +COPY plugins-bundled plugins-bundled + +RUN yarn install + +COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js babel.config.json ./ +COPY public public +COPY tools tools +COPY scripts scripts +COPY emails emails + +ENV NODE_ENV production +RUN yarn build + +FROM golang:1.17.3 AS go-builder + +WORKDIR /src/grafana + +COPY go.mod go.sum embed.go ./ +COPY Makefile build.go package.json ./ +COPY .bingo .bingo +COPY pkg pkg/ +COPY cue cue/ +COPY cue.mod cue.mod/ +COPY packages/grafana-schema packages/grafana-schema/ +COPY public/app/plugins public/app/plugins/ + +RUN go mod verify +RUN make build-go + +FROM ubuntu:20.04 + +LABEL maintainer="Grafana team " +EXPOSE 3000 + +ARG GF_UID="472" +ARG GF_GID="472" + +ENV PATH="/usr/share/grafana/bin:$PATH" \ + GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \ + GF_PATHS_DATA="/var/lib/grafana" \ + GF_PATHS_HOME="/usr/share/grafana" \ + GF_PATHS_LOGS="/var/log/grafana" \ + GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \ + GF_PATHS_PROVISIONING="/etc/grafana/provisioning" + +WORKDIR $GF_PATHS_HOME + +COPY conf conf + +# curl should be part of the image +RUN apt-get update && apt-get install -y ca-certificates curl + +RUN mkdir -p "$GF_PATHS_HOME/.aws" && \ + addgroup --system --gid $GF_GID grafana && \ + adduser --uid $GF_UID --system --ingroup grafana grafana && \ + mkdir -p "$GF_PATHS_PROVISIONING/datasources" \ + "$GF_PATHS_PROVISIONING/dashboards" \ + "$GF_PATHS_PROVISIONING/notifiers" \ + "$GF_PATHS_PROVISIONING/plugins" \ + "$GF_PATHS_PROVISIONING/access-control" \ + "$GF_PATHS_LOGS" \ + "$GF_PATHS_PLUGINS" \ + "$GF_PATHS_DATA" && \ + cp conf/sample.ini "$GF_PATHS_CONFIG" && \ + cp conf/ldap.toml /etc/grafana/ldap.toml && \ + chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \ + chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" + +COPY --from=go-builder /src/grafana/bin/*/grafana-server /src/grafana/bin/*/grafana-cli bin/ +COPY --from=js-builder /usr/src/app/public public +COPY --from=js-builder /usr/src/app/tools tools + +COPY packaging/docker/run.sh / + +USER grafana +ENTRYPOINT [ "/run.sh" ] diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 00000000..d85c66e0 --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,208 @@ +# Governance + +This document describes the rules and governance of the project. It is meant to be followed by all the developers of the project and the Grafana community. Common terminology used in this governance document are listed below: + +- **Team members**: Any members of the private [grafana-team][team] Google group. + +- **Maintainers**: Maintainers lead an individual project or parts thereof ([`MAINTAINERS.md`][maintainers]). + +- **Projects**: A single repository in the Grafana GitHub organization and listed below is referred to as a project: + + - clock-panel + - devtools + - gel-app + - grafana + - grafana-github-datasource + - grafana-image-renderer + - grafana-kiosk + - grafana-plugin-sdk-go + - grafana-polystat-panel + - grafonnet-lib + - kairosdb-datasource + - piechart-panel + - simple-angular-panel + - simple-app-plugin + - simple-datasource + - simple-datasource-backend + - simple-json-backend-datasource + - simple-json-datasource + - simple-react-panel + - strava-datasource + - tutorials + - worldmap-panel + +- **The Grafana project**: The sum of all activities performed under this governance, concerning one or more repositories or the community. + +## Values + +The Grafana developers and community are expected to follow the values defined in the Grafana Code of Conduct. Furthermore, the Grafana community strives for kindness, giving feedback effectively, and building a welcoming environment. The Grafana developers generally decide by consensus and only resort to conflict resolution by a majority vote if consensus cannot be reached. + +## Projects + +Each project must have a [`MAINTAINERS.md`][maintainers] file with at least one maintainer. Where a project has a release process, access and documentation should be such that more than one person can perform a release. Releases should be announced on the Grafana Labs blog. Any new projects should be first proposed on the [team mailing list][team] following the voting procedures listed below. + +## Decision making + +### Team members + +Team member status may be given to those who have made ongoing contributions to the Grafana project for at least 3 months. This is usually in the form of code improvements and/or notable work on documentation, but organizing events or user support could also be taken into account. + +New members may be proposed by any existing member by email to [grafana-team][team]. It is highly desirable to reach consensus about acceptance of a new member. However, the proposal is ultimately voted on by a formal [supermajority vote](#supermajority-vote). + +If the new member proposal is accepted, the proposed team member should be contacted privately via email to confirm or deny their acceptance of team membership. This email will also be CC'd to [grafana-team][team] for record-keeping purposes. + +If they choose to accept, the [onboarding](#onboarding) procedure is followed. + +Team members may retire at any time by emailing [the team][team]. + +Team members can be removed by [supermajority vote](#supermajority-vote) on [the team mailing list][team]. +For this vote, the member in question is not eligible to vote and does not count towards the quorum. +Any removal vote can cover only one single person. + +Upon death of a member, they leave the team automatically. + +In case a member leaves, the [offboarding](#offboarding) procedure is applied. + +The current team members are: + +- Alexander Zobnin ([Grafana Labs](https://grafana.com/)) +- Alex Khomenko ([Grafana Labs](https://grafana.com/)) +- Andrej Ocenas ([Grafana Labs](https://grafana.com/)) +- Arve Knudsen ([Grafana Labs](https://grafana.com/)) +- Brian Gann ([Grafana Labs](https://grafana.com/)) +- Carl Bergquist ([Grafana Labs](https://grafana.com/)) +- Chris Trott ([Grafana Labs](https://grafana.com/)) +- Daniel Lee ([Grafana Labs](https://grafana.com/)) +- David Kaltschmidt ([Grafana Labs](https://grafana.com/)) +- Diana Payton ([Grafana Labs](https://grafana.com/)) +- Diana Sarlinska ([Grafana Labs](https://grafana.com/)) +- Dominik Prokop ([Grafana Labs](https://grafana.com/)) +- Emil Tullstedt ([Grafana Labs](https://grafana.com/)) +- Erik Sundell ([Grafana Labs](https://grafana.com/)) +- Fredrik Enestad ([Soundtrack Your Brand](https://www.soundtrackyourbrand.com/)) +- Hugo Häggmark ([Grafana Labs](https://grafana.com/)) +- Ivana Huckova ([Grafana Labs](https://grafana.com/)) +- Jeroen Op 't Eynde ([Grafana Labs](https://grafana.com/)) +- Jessica Müller ([Grafana Labs](https://grafana.com/)) +- Julien Pivotto ([Inuits](https://inuits.eu/)) +- Kay Delaney ([Grafana Labs](https://grafana.com/)) +- Kyle Brandt ([Grafana Labs](https://grafana.com/)) +- Leonard Gram ([Grafana Labs](https://grafana.com/)) +- Lukas Siatka ([Grafana Labs](https://grafana.com/)) +- Malcolm Holmes ([Grafana Labs](https://grafana.com/)) +- Marcus Andersson ([Grafana Labs](https://grafana.com/)) +- Marcus Efraimsson ([Grafana Labs](https://grafana.com/)) +- Marcus Olsson ([Grafana Labs](https://grafana.com/)) +- Mitsuhiro Tanda ([GREE](https://corp.gree.net/jp/en/)) +- Patrick O’Carroll ([Grafana Labs](https://grafana.com/)) +- Peter Holmberg ([Grafana Labs](https://grafana.com/)) +- Richard Hartmann ([Grafana Labs](https://grafana.com/)) +- Ryan McKinley ([Grafana Labs](https://grafana.com/)) +- Sofia Papagiannaki ([Grafana Labs](https://grafana.com/)) +- Stephanie Closson ([Grafana Labs](https://grafana.com/)) +- Tobias Skarhed ([Grafana Labs](https://grafana.com/)) +- Torkel Ödegaard ([Grafana Labs](https://grafana.com/)) +- Utkarsh Bhatnagar ([Tinder](https://www.tinder.com/)) +- Will Browne ([Grafana Labs](https://grafana.com/)) +- Zoltán Bedi ([Grafana Labs](https://grafana.com/)) + +### Maintainers + +Maintainers lead one or more project(s) or parts thereof and serve as a point of conflict resolution amongst the contributors to this project. Ideally, maintainers are also team members, but exceptions are possible for suitable maintainers that, for whatever reason, are not yet team members. + +Changes in maintainership have to be announced on the [developers mailing list][devs]. They are decided by [rough consensus](#consensus) and formalized by changing the [`MAINTAINERS.md`][maintainers] file of the respective repository. + +Maintainers are granted commit rights to all projects covered by this governance. + +A maintainer or committer may resign by notifying the [team mailing list][team]. A maintainer with no project activity for a year is considered to have resigned. Maintainers that wish to resign are encouraged to propose another team member to take over the project. + +A project may have multiple maintainers, as long as the responsibilities are clearly agreed upon between them. This includes coordinating who handles which issues and pull requests. + +### Technical decisions + +Technical decisions that only affect a single project are made informally by the maintainer of this project, and [rough consensus](#consensus) is assumed. Technical decisions that span multiple parts of the Grafana project should be discussed and made on the [Grafana developer mailing list][devs]. + +Decisions are usually made by [rough consensus](#consensus). If no consensus can be reached, the matter may be resolved by [majority vote](#majority-vote). + +### Governance changes + +Changes to this document are made by Grafana Labs. + +### Other matters + +Any matter that needs a decision may be called to a vote by any member if they deem it necessary. For private or personnel matters, discussion and voting takes place on the [team mailing list][team], otherwise on the [developer mailing list][devs]. + +## Voting + +The Grafana project usually runs by informal consensus, however sometimes a formal decision must be made. + +Depending on the subject matter, as laid out [above](#decision-making), different methods of voting are used. + +For all votes, voting must be open for at least one week. The end date should be clearly stated in the call to vote. A vote may be called and closed early if enough votes have come in one way so that further votes cannot change the final decision. + +In all cases, all and only [team members](#team-members) are eligible to vote, with the sole exception of the forced removal of a team member, in which said member is not eligible to vote. + +Discussion and votes on personnel matters (including but not limited to team membership and maintainership) are held in private on the [team mailing list][team]. All other discussion and votes are held in public on the [developer mailing list][devs]. + +For public discussions, anyone interested is encouraged to participate. Formal power to object or vote is limited to [team members](#team-members). + +### Consensus + +The default decision making mechanism for the Grafana project is [rough][rough] consensus. This means that any decision on technical issues is considered supported by the [team][team] as long as nobody objects or the objection has been considered but not necessarily accommodated. + +Silence on any consensus decision is implicit agreement and equivalent to explicit agreement. Explicit agreement may be stated at will. Decisions may, but do not need to be called out and put up for decision on the [developers mailing list][devs] at any time and by anyone. + +Consensus decisions can never override or go against the spirit of an earlier explicit vote. + +If any [team member](#team-members) raises objections, the team members work together towards a solution that all involved can accept. This solution is again subject to rough consensus. + +In case no consensus can be found, but a decision one way or the other must be made, any [team member](#team-members) may call a formal [majority vote](#majority-vote). + +### Majority vote + +Majority votes must be called explicitly in a separate thread on the appropriate mailing list. The subject must be prefixed with `[VOTE]`. In the body, the call to vote must state the proposal being voted on. It should reference any discussion leading up to this point. + +Votes may take the form of a single proposal, with the option to vote yes or no, or the form of multiple alternatives. + +A vote on a single proposal is considered successful if more vote in favor than against. + +If there are multiple alternatives, members may vote for one or more alternatives, or vote “no” to object to all alternatives. It is not possible to cast an “abstain” vote. A vote on multiple alternatives is considered decided in favor of one alternative if it has received the most votes in favor, and a vote from more than half of those voting. Should no alternative reach this quorum, another vote on a reduced number of options may be called separately. + +### Supermajority vote + +Supermajority votes must be called explicitly in a separate thread on the appropriate mailing list. The subject must be prefixed with `[VOTE]`. In the body, the call to vote must state the proposal being voted on. It should reference any discussion leading up to this point. + +Votes may take the form of a single proposal, with the option to vote yes or no, or the form of multiple alternatives. + +A vote on a single proposal is considered successful if at least two thirds of those eligible to vote vote in favor. + +If there are multiple alternatives, members may vote for one or more alternatives, or vote “no” to object to all alternatives. A vote on multiple alternatives is considered decided in favor of one alternative if it has received the most votes in favor, and a vote from at least two thirds of those eligible to vote. Should no alternative reach this quorum, another vote on a reduced number of options may be called separately. + +## On- / Offboarding + +### Onboarding + +The new member is + +- added to the list of [team members](#team-members). Ideally by sending a PR of their own, at least approving said PR. +- announced on the [developers mailing list][devs] by an existing team member. Ideally, the new member replies in this thread, acknowledging team membership. +- added to the projects with commit rights. +- added to the [team mailing list][team]. + +### Offboarding + +The ex-member is + +- removed from the list of [team members](#team-members). Ideally by sending a PR of their own, at least approving said PR. In case of forced removal, no approval is needed. +- removed from the projects. Optionally, they can retain maintainership of one or more repositories if the [team](#team-members) agrees. +- removed from the team mailing list and demoted to a normal member of the other mailing lists. +- not allowed to call themselves an active team member any more, nor allowed to imply this to be the case. +- added to a list of previous members if they so choose. + +If needed, we reserve the right to publicly announce removal. + +[coc]: https://github.com/grafana/grafana/blob/main/CODE_OF_CONDUCT.md +[devs]: https://groups.google.com/forum/#!forum/grafana-developers +[maintainers]: https://github.com/grafana/grafana/blob/main/MAINTAINERS.md +[rough]: https://tools.ietf.org/html/rfc7282 +[team]: https://groups.google.com/forum/#!forum/grafana-team diff --git a/ISSUE_TRIAGE.md b/ISSUE_TRIAGE.md new file mode 100644 index 00000000..22d9409f --- /dev/null +++ b/ISSUE_TRIAGE.md @@ -0,0 +1,355 @@ +# Triage issues + +The main goal of issue triage is to categorize all incoming Grafana issues and make sure each issue has all basic information needed for anyone else to understand and be able to start working on it. + +> **Note:** This information is for Grafana project Maintainers, Owners, and Admins. If you are a Contributor, then you will not be able to perform most of the tasks in this topic. + +The core maintainers of the Grafana project are responsible for categorizing all incoming issues and delegating any critical or important issue to other maintainers. Currently one maintainer each week is responsible. Besides that part, triage provides an important way to contribute to an open source project. + +Triage helps ensure issues resolve quickly by: + +- Ensuring the issue's intent and purpose is conveyed precisely. This is necessary because it can be difficult for an issue to explain how an end user experiences a problem and what actions they took. +- Giving a contributor the information they need before they commit to resolving an issue. +- Lowering the issue count by preventing duplicate issues. +- Streamlining the development process by preventing duplicate discussions. + +If you don't have the knowledge or time to code, consider helping with triage. The community will thank you for saving them time by spending some of yours. + +## Simplified flowchart diagram of the issue triage process + + + +``` + +--------------------------+ + +----------------+ New issue opened/ | + | | more information added | + | +-------------+------------+ + | Ask for more | + | information +-------------+------------+ + | | All information needed | + | +--------+ to categorize the issue? +--------+ + | | | | | + | | NO +--------------------------+ YES | + | | | ++------+-------+-------------+ +------------+---------+ +----------------------------+ +| | | | | | +| label: needs more info | | Needs investigation? +--YES---+ label: needs investigation | +| | | | | | ++----------------------------+ +----------------+-----+ +--------------+-------------+ + NO | | + | Investigate | + +-----------+----------+ | + | label: type/* | | + | label: area/* +------------------+ + | label: datasource/* | + +-----|----------+-----+ + | | + | | + | +--+--------------------+ +--------------------+ + | | | | label: priority/* | + | | Needs priority? +--YES---+| milestone? | + | | | | | + | +--------------------+--+ +----+---------------+ + | NO | | + | | | + +----+-------------+ +---+----------+ | + | | | | | + | Close issue +----------+ Done +------+ + | | | | + +------------------+ +--------------+ +``` + +## 1. Find uncategorized issues + +To get started with issue triage and finding issues that haven't been triaged you have two alternatives. + +### Browse unlabeled issues + +The easiest and straight forward way of getting started and finding issues that haven't been triaged is to browse [unlabeled issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+no%3Alabel) and starting from the bottom and working yourself to the top. + +### Subscribe to all notifications + +The more advanced, but recommended way is to subscribe to all notifications from this repository which means that all new issues, pull requests, comments and important status changes are sent to your configured email address. Read this [guide](https://help.github.com/en/articles/watching-and-unwatching-repositories#watching-a-single-repository) for help with setting this up. + +It's highly recommended that you setup filters to automatically remove emails from the inbox and label/categorize them accordingly to make it easy for you to understand when you need to act upon a notification or where to look for finding issues that haven't been triaged etc. + +Instructions for setting up filters in Gmail can be found [here](#setting-up-gmail-filters). Another alternative is to use [Trailer](https://github.com/ptsochantaris/trailer) or similar software. + +## 2. Ensure the issue contains basic information + +Before triaging an issue very far, make sure that the issue's author provided the standard issue information. This will help you make an educated recommendation on how to categorize the issue. The Grafana project utilizes [GitHub issue templates](https://help.github.com/en/articles/creating-issue-templates-for-your-repository) to guide contributors to provide standard information that must be included for each type of template or type of issue. + +### Standard issue information that must be included + +Given a certain [issue template](<[template](https://github.com/grafana/grafana/issues/new/choose)>) have been used by the issue author or depending how the issue is perceived by the issue triage responsible, the following should help you understand what standard issue information that must be included. + +#### Bug reports + +Should explain what happened, what was expected and how to reproduce it together with any additional information that may help giving a complete picture of what happened such as screenshots, [query inspector](https://community.grafana.com/t/using-grafanas-query-inspector-to-troubleshoot-issues/2630) output and any environment related information that's applicable and/or maybe related to the reported problem: + +- Grafana version +- Data source type & version +- Platform & OS Grafana is installed on +- User OS & Browser + versions +- Using docker + what environment +- Which plugins +- Configuration database in use (sqlite, mysql, postgres) +- Reverse proxy in front of Grafana, what version and configuration +- Non-default configuration settings +- Development environment like Go and Node versions, if applicable + +#### Enhancement requests + +Should explain what enhancement or feature that the author wants to be added and why that is needed. + +#### Accessibility issues + +This is a mix between a bug report and enhancement request but focused on accessibility issues to help make Grafana improve keyboard navigation, screen-reader support and being accessible to everyone. The report should include relevant WCAG criteria, if applicable. + +#### Support requests + +In general, if the issue description and title is perceived as a question no more information is needed. + +### Good practices + +To make it easier for everyone to understand and find issues they're searching for it's suggested as a general rule of thumbs to: + +- Make sure that issue titles are named to explain the subject of the issue, has a correct spelling and doesn't include irrelevant information and/or sensitive information. +- Make sure that issue descriptions doesn't include irrelevant information, information from template that haven't been filled out and/or sensitive information. +- Do your best effort to change title and description or request suggested changes by adding a comment. + +> **Note:** Above rules is applicable to both new and existing issues of the Grafana project. + +### Do you have all the information needed to categorize an issue? + +Depending on the issue, you might not feel all this information is needed. Use your best judgement. If you cannot triage an issue using what its author provided, explain kindly to the author that they must provide the above information to clarify the problem. Label issue with `needs more detail` and add any related `area/*` or `datasource/*` labels. + +If the author provides the standard information but you are still unable to triage the issue, request additional information. Do this kindly and politely because you are asking for more of the author's time. + +If the author does not respond to the requested information within the timespan of a week, close the issue with a kind note stating that the author can request for the issue to be reopened when the necessary information is provided. + +When you feel you have all the information needed you're ready to [categorizing the issue](#3-categorizing-an-issue). + +If you receive a notification with additional information provided but you are not anymore on issue triage and you feel you do not have time to handle it, you should delegate it to the current person on issue triage. + +## 3. Categorizing an issue + +An issue can have multiple of the following labels. Typically, a properly categorized issue should at least have: + +- One label identifying its type (`type/*`). +- One or multiple labels identifying the functional areas of interest or component (`area/*`) and/or data source (`datasource/*`), if applicable. + +| Label | Description | +| ------------------------ | ------------------------------------------------------------------------- | +| `type/bug` | A feature isn't working as expected given design or documentation. | +| `type/feature-request` | Request for a new feature or enhancement. | +| `type/docs` | Documentation problem or enhancement. | +| `type/accessibility` | Accessibility problem or enhancement. | +| `type/question` | Issue is a question or is perceived as such. | +| `type/duplicate` | An existing issue of the same subject/request have already been reported. | +| `type/works-as-intended` | A reported bug works as intended/by design. | +| `type/build-packaging` | Build or packaging problem or enhancement. | +| `area/*` | Subject is related to a functional area of interest or component. | +| `datasource/*` | Subject is related to a core data source plugin. | + +### Duplicate issues + +Make sure it's not a duplicate by searching existing issues using related terms from the issue title and description. If you think you know there is an existing issue, but can't find it, please reach out to one of the maintainers and ask for help. If you identify that the issue is a duplicate of an existing issue: + +1. Add a comment `/duplicate of #`. GitHub will recognize this and add some additional context to the issue activity. +2. The Grafana bot will do the rest, adding the correct label and closing comment +3. Optionally add any related `area/*` or `datasource/*` labels. + +### Bug reports + +If it's not perfectly clear that it's an actual bug, quickly try to reproduce it. + +**It's a bug/it can be reproduced:** + +1. Add a comment describing detailed steps for how to reproduce it, if applicable. +2. Label the issue `type/bug` and at least one `area/*` or `datasource/*` label. +3. If you know that maintainers wont be able to put any resources into it for some time then label the issue with `help wanted` and optionally `beginner friendly` together with pointers on which code to update to fix the bug. This should signal to the community that we would appreciate any help we can get to resolve this. +4. Move on to [prioritizing the issue](#4-prioritization-of-issues). + +**It can't be reproduced:** + +1. Either [ask for more information](#2-ensure-the-issue-contains-basic-information) needed to investigate it more thoroughly. +2. Either [delegate further investigations](#investigation-of-issues) to someone else. + +**It works as intended/by design:** + +1. Kindly and politely add a comment explaining briefly why we think it works as intended and close the issue. +2. Label the issue `type/works-as-intended`. + +### Enhancement/feature? + +1. Label the issue `type/feature-request` and at least one `area/*` or `datasource/*` label. +2. Move on to [prioritizing the issue](#4-prioritization-of-issues). + +### Documentation issue? + +First, evaluate if the documentation makes sense to be included in the Grafana project: + +- Is this something we want/can maintain as a project? +- Is this referring to usage of some specific integration/tool and in that case is that a popular use case in combination with Grafana? +- If unsure, kindly and politely add a comment explaining that we would need [upvotes](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments) to identify that lots of other users want/need this. + +Second, label the issue `type/docs` and at least one `area/*` or `datasource/*` label. + +**Minor typo/error/lack of information:** + +There's a minor typo/error/lack of information that adds a lot of confusion for users and given the amount of work is a big win to make sure fixing it: + +1. Either update the documentation yourself and open a pull request. +2. Either delegate the work to someone else by assigning that person to the issue and add the issue to next major/minor milestone. + +**Major error/lack of information:** + +1. Label the issue with `help wanted` and `beginner friendly`, if applicable, to signal that we find this important to fix and we would appreciate any help we can get from the community. +2. Move on to [prioritizing the issue](#4-prioritization-of-issues). + +### Accessibility issues + +1. Label the issue `type/accessibility` and at least one `area/*` or `datasource/*` label. + +### Support requests + +1. Kindly and politely direct the issue author to the [community site](https://community.grafana.com/) and explain that GitHub is mainly used for tracking bugs and feature requests. If possible, it's usually a good idea to add some pointers to the issue author's question. +2. Close the issue and label it with `type/question`. + +## 4. Prioritization of issues + +In general bugs and enhancement issues should be labeled with a priority. + +This is the most difficult thing with triaging issues since it requires a lot of knowledge, context and experience before being able to think of and start feel comfortable adding a certain priority label. + +The key here is asking for help and discuss issues to understand how more experienced project members think and reason. By doing that you learn more and eventually be more and more comfortable with prioritizing issues. + +In case there is an uncertainty around the prioritization of an issue, please ask the maintainers for help. + +| Label | Description | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| `priority/critical` | Highest priority. Must be actively worked on as someone's top priority right now. | +| `priority/support-subscription` | This is important for one or several customers having a paid Grafana support subscription. | +| `priority/important-soon` | Must be staffed and worked on either currently, or very soon, ideally in time for the next release. | +| `priority/important-longterm` | Important over the long term, but may not be staffed and/or may need multiple releases to complete. | +| `priority/nice-to-have` | It's a good idea, but not scheduled for any release. | +| `priority/awaiting-more-evidence` | Lowest priority. Possibly useful, but not yet enough interest in it. | +| `priority/unscheduled` | Something to look into before and to be discussed during the planning of the next (upcoming) major/minor stable release. | + +**Critical bugs** + +1. If a bug has been categorized and any of the following criteria apply, the bug should be labeled as critical and must be actively worked on as someone's top priority right now. + + - Results in any data loss + - Critical security or performance issues + - Problem that makes a feature unusable + - Multiple users experience a severe problem affecting their business, users etc. + +2. Label the issue `priority/critical`. +3. If applicable, label the issue `priority/support-subscription`. +4. Add the issue to the next upcoming patch release milestone. Create a new milestone if there are none. +5. Escalate the problem to the maintainers. +6. Assign or ask a maintainer for help assigning someone to make this issue their top priority right now. + +**Important short-term** + +1. Label the issue `priority/important-soon`. +2. If applicable, label the issue `priority/support-subscription`. +3. Add the issue to the next upcoming patch or major/minor stable release milestone. Ask maintainers for help if unsure if it's a patch or not. Create a new milestone if there are none. +4. Make sure to add the issue to a suitable backlog of a GitHub project and prioritize it or assign someone to work on it now or very soon. +5. Consider requesting [help from the community](#5-requesting-help-from-the-community), even though it may be problematic given a short amount of time until it should be released. + +**Important long-term** + +1. Label the issue `priority/important-longterm`. +2. Consider requesting [help from the community](#5-requesting-help-from-the-community). + +**Nice to have** + +1. Label the issue `priority/nice-to-have`. +2. Consider requesting [help from the community](#5-requesting-help-from-the-community). + +**Not critical, but unsure?** + +1. Label the issue `priority/unscheduled`. +2. Consider requesting [help from the community](#5-requesting-help-from-the-community). + +## 5. Requesting help from the community + +Depending on the issue and/or priority, it's always a good idea to consider signalling to the community that help from community is appreciated and needed in case an issue is not prioritized to be worked on by maintainers. Use your best judgement. In general, requesting help from the community means that a contribution has a good chance of getting accepted and merged. + +In many cases the issue author or community as a whole is more suitable to contribute changes since they're experts in their domain. It's also quite common that someone has tried to get something to work using the documentation without success and made an effort to get it to work and/or reached out to the [community site](https://community.grafana.com/) to get the missing information. Particularly in these areas it's more likely that there exist experts in their own domain and it is usually a good idea to request help from contributors: + +- Database setups +- Authentication like OAuth providers and LDAP setups +- Platform specific things +- Reverse proxy setups +- Alert notifiers + +1. Kindly and politely add a comment to signal to users subscribed to updates of the issue. + - Explain that the issue would be nice to get resolved, but it isn't prioritized to work on by maintainers for an unforeseen future. + - If possible or applicable, try to help contributors getting starting by adding pointers and references to what code/files need to be changed and/or ideas of a good way to solve/implement the issue. +2. Label the issue with `help wanted`. +3. If applicable, label the issue with `beginner friendly` to denote that the issue is suitable for a beginner to work on. +4. If possible, try to estimate the amount of work by adding `effort/small`, `effort/medium` or `effort/large`. + +## Investigation of issues + +When an issue has all basic information provided, but the triage responsible haven't been able to reproduce the reported problem at a first glance, the issue is labeled [Needs investigation](https://github.com/grafana/grafana/labels/needs%20investigation). Depending on the perceived severity and/or number of [upvotes](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments), the investigation will either be delegated to another maintainer for further investigation or put on hold until someone else (maintainer or contributor) picks it up and eventually starts investigating it. + +Investigating issues can be a very time consuming task, especially for the maintainers, given the huge number of combinations of plugins, data sources, platforms, databases, browsers, tools, hardware, integrations, versions and cloud services, etc that are being used with Grafana. There is a certain number of combinations that are more common than others, and these are in general easier for maintainers to investigate. + +For some other combinations it may not be possible at all for a maintainer to setup a proper test environment to investigate the issue. In these cases we really appreciate any help we can get from the community. Otherwise the issue is highly likely to be closed. + +Even if you don't have the time or knowledge to investigate an issue we highly recommend that you [upvote](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments) the issue if you happen to have the same problem. If you have further details that may help investigating the issue please provide as much information as possible. + +## Automation + +We have some automation that triggers on comments or labels being added to issues. Many of these automated behaviors are defined in [commands.json](https://github.com/grafana/grafana/blob/main/.github/commands.json). Or in other [GitHub Actions](https://github.com/grafana/grafana/tree/main/.github/workflows) + +- Add /duplicate `#` to have Grafana label & close issue with an appropriate message. +- Add `bot/question` and the bot will close it with an appropriate message. + +[Read more on bot actions](https://github.com/grafana/grafana/blob/main/.github/bot.md) + +## External PRs + +Part of issue triage should also be triaging of external PRs. Main goal should be to make sure PRs from external contributors have an owner/reviewer and are not forgotten. + +1. Check new external PRs which do not have a reviewer. +1. Check if there is a link to an existing issue. +1. If not and you know which issue it is solving, add the link yourself, otherwise ask the author to link the issue or create one. +1. Assign a reviewer based on who was handling the linked issue or what code or feature does the PR touches (look at who was the last to make changes there if all else fails). + +## Appendix + +### Setting up Gmail filters + +If you're using Gmail it's highly recommended that you setup filters to automatically remove email from the inbox and label them accordingly to make it easy for you to understand when you need to act upon a notification or process all incoming issues that haven't been triaged. + +This may be setup by personal preference, but here's a working configuration for reference. + +1. Follow instructions in [gist](https://gist.github.com/marefr/9167c2e31466f6316c1cba118874e74f) +2. In Gmail, go to Settings -> Filters and Blocked Addresses +3. Import filters -> select xml file -> Open file +4. Review filters +5. Optional, Check Apply new filters to existing email +6. Create filters + +This will give you a structure of labels in the sidebar similar to the following: + +``` + - Inbox + ... + - GitHub (mine) + - activity + - assigned + - mentions + - GitHub (other) + - Grafana +``` + +- All notifications you’ll need to read/take action on show up as unread in GitHub (mine) and its sub-labels. +- All other notifications you don’t need to take action on show up as unread in GitHub (other) and its sub-labels + - This is convenient for issue triage and to follow the activity in the Grafana project. diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..be3f7b28 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/LICENSING.md b/LICENSING.md new file mode 100644 index 00000000..5c5d7d8f --- /dev/null +++ b/LICENSING.md @@ -0,0 +1,28 @@ +# Licensing + +License names used in this document are as per [SPDX License List](https://spdx.org/licenses/). + +The default license for this project is [AGPL-3.0-only](LICENSE). + +## Apache-2.0 + +The following directories and their subdirectories are licensed under Apache-2.0: + +``` +packages/grafana-data/ +packages/grafana-e2e/ +packages/grafana-e2e-selectors/ +packages/grafana-runtime/ +packages/grafana-toolkit/ +packages/grafana-ui/ +packages/jaeger-ui-components/ +packaging/ +grafana-mixin/ +cue/ +``` + +The following directories and their subdirectories are the original upstream licenses: + +``` +public/vendor/ +``` diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 00000000..beb4c277 --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,8 @@ +@torkelo is the main/default maintainer, some parts of the codebase have other maintainers: + +- Backend: + - @bergquist +- Plugins: + - @ryantxu +- UX/UI: + - @davkal diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..45544ca5 --- /dev/null +++ b/Makefile @@ -0,0 +1,158 @@ +## This is a self-documented Makefile. For usage information, run `make help`: +## +## For more information, refer to https://suva.sh/posts/well-documented-makefiles/ + +WIRE_TAGS = "oss" + +-include local/Makefile +include .bingo/Variables.mk + +.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-full lint-go golangci-lint test-go test-js gen-ts test run run-frontend clean devenv devenv-down protobuf drone help + +GO = go +GO_FILES ?= ./pkg/... +SH_FILES ?= $(shell find ./scripts -name *.sh) + +all: deps build + +##@ Dependencies + +deps-go: ## Install backend dependencies. + $(GO) run build.go setup + +deps-js: node_modules ## Install frontend dependencies. + +deps: deps-js ## Install all dependencies. + +node_modules: package.json yarn.lock ## Install node modules. + @echo "install frontend dependencies" + YARN_ENABLE_PROGRESS_BARS=false yarn install --immutable + +##@ Building + +gen-go: $(WIRE) + @echo "generate go files" + $(WIRE) gen -tags $(WIRE_TAGS) ./pkg/server ./pkg/cmd/grafana-cli/runner + +build-go: gen-go ## Build all Go binaries. + @echo "build go files" + $(GO) run build.go build + +build-server: ## Build Grafana server. + @echo "build server" + $(GO) run build.go build-server + +build-cli: ## Build Grafana CLI application. + @echo "build grafana-cli" + $(GO) run build.go build-cli + +build-js: ## Build frontend assets. + @echo "build frontend" + yarn run build + yarn run plugins:build-bundled + +build: build-go build-js ## Build backend and frontend. + +scripts/go/bin/bra: scripts/go/go.mod + @cd scripts/go; \ + $(GO) build -o ./bin/bra github.com/unknwon/bra + +run: scripts/go/bin/bra ## Build and run web server on filesystem changes. + @scripts/go/bin/bra run + +run-frontend: deps-js ## Fetch js dependencies and watch frontend for rebuild + yarn start + +##@ Testing + +test-go: ## Run tests for backend. + @echo "test backend" + $(GO) test -v ./pkg/... + +test-js: ## Run tests for frontend. + @echo "test frontend" + yarn test + +test: test-go test-js ## Run all tests. + +##@ Linting +scripts/go/bin/golangci-lint: scripts/go/go.mod + @cd scripts/go; \ + $(GO) build -o ./bin/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint + +golangci-lint: scripts/go/bin/golangci-lint + @echo "lint via golangci-lint" + @scripts/go/bin/golangci-lint run \ + --config ./scripts/go/configs/.golangci.toml \ + $(GO_FILES) + +lint-go: golangci-lint ## Run all code checks for backend. You can use GO_FILES to specify exact files to check + +# with disabled SC1071 we are ignored some TCL,Expect `/usr/bin/env expect` scripts +shellcheck: $(SH_FILES) ## Run checks for shell scripts. + @docker run --rm -v "$$PWD:/mnt" koalaman/shellcheck:stable \ + $(SH_FILES) -e SC1071 -e SC2162 + +##@ Docker + +build-docker-full: ## Build Docker image for development. + @echo "build docker container" + docker build --tag grafana/grafana:dev . + +##@ Services + +# create docker-compose file with provided sources and start them +# example: make devenv sources=postgres,openldap +ifeq ($(sources),) +devenv: + @printf 'You have to define sources for this command \nexample: make devenv sources=postgres,openldap\n' +else +devenv: devenv-down ## Start optional services, e.g. postgres, prometheus, and elasticsearch. + $(eval targets := $(shell echo '$(sources)' | tr "," " ")) + + @cd devenv; \ + ./create_docker_compose.sh $(targets) || \ + (rm -rf {docker-compose.yaml,conf.tmp,.env}; exit 1) + + @cd devenv; \ + docker-compose up -d --build +endif + +devenv-down: ## Stop optional services. + @cd devenv; \ + test -f docker-compose.yaml && \ + docker-compose down || exit 0; + +##@ Helpers + +# We separate the protobuf generation because most development tasks on +# Grafana do not involve changing protobuf files and protoc is not a +# go-gettable dependency and so getting it installed can be inconvenient. +# +# If you are working on changes to protobuf interfaces you may either use +# this target or run the individual scripts below directly. +protobuf: ## Compile protobuf definitions + bash scripts/protobuf-check.sh + bash pkg/plugins/backendplugin/pluginextensionv2/generate.sh + +clean: ## Clean up intermediate build artifacts. + @echo "cleaning" + rm -rf node_modules + rm -rf public/build + +gen-ts: + @echo "generating TypeScript definitions" + go get github.com/tkrajina/typescriptify-golang-structs/typescriptify@v0.1.7 + tscriptify -interface -package=github.com/grafana/grafana/pkg/services/live/pipeline -import="import { FieldConfig } from '@grafana/data'" -target=public/app/features/live/pipeline/models.gen.ts pkg/services/live/pipeline/config.go + go mod tidy + +# This repository's configuration is protected (https://readme.drone.io/signature/). +# Use this make target to regenerate the configuration YAML files when +# you modify starlark files. +drone: $(DRONE) + $(DRONE) starlark --format + $(DRONE) lint .drone.yml --trusted + $(DRONE) --server https://drone.grafana.net sign --save grafana/grafana + +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 00000000..15bc6c61 --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,4 @@ +Copyright 2014-2021 Grafana Labs + +This software is based on Kibana: +Copyright 2012-2013 Elasticsearch BV diff --git a/PLUGIN_DEV.md b/PLUGIN_DEV.md new file mode 100644 index 00000000..fbb2b79c --- /dev/null +++ b/PLUGIN_DEV.md @@ -0,0 +1,33 @@ +# Plugin development + +This document is not meant as a complete guide for developing plugins but more as a changelog for changes in +Grafana that can impact plugin development. Whenever you as a plugin author encounter an issue with your plugin after +upgrading Grafana please check here before creating an issue. + +## Plugin development resources + +- [Grafana plugin developer guide](https://grafana.com/docs/grafana/latest/developers/plugins/) +- [Webpack Grafana plugin template project](https://github.com/CorpGlory/grafana-plugin-template-webpack) +- [Simple JSON datasource plugin](https://github.com/grafana/simple-json-datasource) + +## Changes in Grafana v4.6 + +This version of Grafana has big changes that will impact a limited set of plugins. We moved from systemjs to webpack +for built-in plugins and everything internal. External plugins still use systemjs but now with a limited +set of Grafana components they can import. Plugins can depend on libs like lodash & moment and internal components +like before using the same import paths. However since everything in Grafana is no longer accessible, a few plugins could encounter issues when importing a Grafana dependency. + +[List of exposed components plugins can import/require](https://github.com/grafana/grafana/blob/main/public/app/features/plugins/plugin_loader.ts#L48) + +If you think we missed exposing a crucial lib or Grafana component let us know by opening an issue. + +### Deprecated components + +The angular directive `` is now deprecated (will still work for a version more) but we recommend plugin authors +upgrade to new `` + +## Changes in Grafana v6.0 + +### DashboardSrv.ts + +If you utilize [DashboardSrv](https://github.com/grafana/grafana/commit/8574dca081002f36e482b572517d8f05fd44453f#diff-1ab99561f9f6a10e1fafcddc39bc1d65) in your plugin code, `dash` was renamed to `dashboard`. diff --git a/README.md b/README.md new file mode 100644 index 00000000..f4873c5b --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +![Grafana](docs/logo-horizontal.png) + +The open-source platform for monitoring and observability. + +[![License](https://img.shields.io/github/license/grafana/grafana)](LICENSE) +[![Drone](https://drone.grafana.net/api/badges/grafana/grafana/status.svg)](https://drone.grafana.net/grafana/grafana) +[![Go Report Card](https://goreportcard.com/badge/github.com/grafana/grafana)](https://goreportcard.com/report/github.com/grafana/grafana) + +Grafana allows you to query, visualize, alert on and understand your metrics no matter where they are stored. Create, explore, and share dashboards with your team and foster a data driven culture: + +- **Visualize:** Fast and flexible client side graphs with a multitude of options. Panel plugins offer many different ways to visualize metrics and logs. +- **Dynamic Dashboards:** Create dynamic & reusable dashboards with template variables that appear as dropdowns at the top of the dashboard. +- **Explore Metrics:** Explore your data through ad-hoc queries and dynamic drilldown. Split view and compare different time ranges, queries and data sources side by side. +- **Explore Logs:** Experience the magic of switching from metrics to logs with preserved label filters. Quickly search through all your logs or streaming them live. +- **Alerting:** Visually define alert rules for your most important metrics. Grafana will continuously evaluate and send notifications to systems like Slack, PagerDuty, VictorOps, OpsGenie. +- **Mixed Data Sources:** Mix different data sources in the same graph! You can specify a data source on a per-query basis. This works for even custom datasources. + +## Get started + +- [Get Grafana](https://grafana.com/get) +- [Installation guides](http://docs.grafana.org/installation/) + +Unsure if Grafana is for you? Watch Grafana in action on [play.grafana.org](https://play.grafana.org/)! + +## Documentation + +The Grafana documentation is available at [grafana.com/docs](https://grafana.com/docs/). + +## Contributing + +If you're interested in contributing to the Grafana project: + +- Start by reading the [Contributing guide](https://github.com/grafana/grafana/blob/HEAD/CONTRIBUTING.md). +- Learn how to set up your local environment, in our [Developer guide](https://github.com/grafana/grafana/blob/HEAD/contribute/developer-guide.md). +- Explore our [beginner-friendly issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22). +- Look through our [style guide and Storybook](https://developers.grafana.com/ui/latest/index.html). + +## Get involved + +- Follow [@grafana on Twitter](https://twitter.com/grafana/). +- Read and subscribe to the [Grafana blog](https://grafana.com/blog/). +- If you have a specific question, check out our [discussion forums](https://community.grafana.com/). +- For general discussions, join us on the [official Slack](https://slack.grafana.com) team. + +## License + +Grafana is distributed under [AGPL-3.0-only](LICENSE). For Apache-2.0 exceptions, see [LICENSING.md](https://github.com/grafana/grafana/blob/HEAD/LICENSING.md). diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 00000000..7daf6465 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,5 @@ +# Roadmap + +The roadmap is a tentative plan for the core development team. Things change constantly as pull requests come in and priorities change, but it will give you an idea of our current vision and plan. + +To view the Roadmap, go to the Issues tab on GitHub. There you will find three roadmap issues pinned at the top. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..b8697c16 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Reporting security issues + +If you think you have found a security vulnerability, please send a report to [security@grafana.com](mailto:security@grafana.com). This address can be used for all of Grafana Labs's open source and commercial products (including but not limited to Grafana, Grafana Cloud, Grafana Enterprise, and grafana.com). We can accept only vulnerability reports at this address. + +Please encrypt your message to us; please use our PGP key. The key fingerprint is: + +F988 7BEA 027A 049F AE8E 5CAA D125 8932 BE24 C5CA + +The key is available from [keyserver.ubuntu.com](https://keyserver.ubuntu.com/pks/lookup?search=0xF9887BEA027A049FAE8E5CAAD1258932BE24C5CA&fingerprint=on&op=index). + +Grafana Labs will send you a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. + +**Important:** We ask you to not disclose the vulnerability before it have been fixed and announced, unless you received a response from the Grafana Labs security team that you can do so. + +## Security announcements + +We maintain a category on the community site called [Security Announcements](https://community.grafana.com/c/support/security-announcements), +where we will post a summary, remediation, and mitigation details for any patch containing security fixes. + +You can also subscribe to email updates to this category if you have a grafana.com account and sign on to the community site or track updates via an [RSS feed](https://community.grafana.com/c/support/security-announcements.rss). diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 00000000..a8aae994 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,13 @@ +# Get Grafana help + +--- + +First, check the official [Grafana documentation](https://grafana.com/docs/). + +If you require further help or support then ask a question in the [Grafana community site](https://community.grafana.com/) or [Grafana Slack](http://slack.raintank.io/). You can also search the community site for previously answered questions, in case someone already had your problem and got help. + +**Please note:** + +- The Grafana project uses GitHub mainly for tracking bugs and feature requests. +- Do not open an issue just to ask a question. The issue will be closed immediately. +- Only submit issues for bug reports, feature requests, or enhancements. diff --git a/UPGRADING_DEPENDENCIES.md b/UPGRADING_DEPENDENCIES.md new file mode 100644 index 00000000..06e0146f --- /dev/null +++ b/UPGRADING_DEPENDENCIES.md @@ -0,0 +1,109 @@ +# Guide to upgrading dependencies + +Upgrading Go or Node.js requires making changes in many different files. See below for a list and explanation for each. + +## Go + +- Drone +- `grafana/build-container` +- Appveyor +- Dockerfile + +## Node.js + +- Drone +- `grafana/build-container` +- Appveyor +- Dockerfile + +## Go dependencies + +The Grafana project uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages. This requires a working Go environment with version 1.11 or greater installed. + +To add or update a new dependency, use the `go get` command: + +```bash +go get example.com/some/module/pkg + +# Pick a specific version. +go get example.com/some/module/pkg@vX.Y.Z +``` + +Tidy up the `go.mod` and `go.sum` files: + +```bash +go mod tidy +``` + +You have to commit the changes to `go.mod` and `go.sum` before submitting the pull request. + +To understand what the actual dependencies of `grafana-server` are, one could run it with `-vv` flag. This might produce an output, different from `go.mod` contents and `-vv` option is the source of truth here. It lists the modules _compiled_ into the executable, while `go.mod` lists also test and weak transitive dependencies (modules, used in some package, which is not in use by itself). If you are interested in reporting a vulnerability in a dependency module - please consult `-vv` output, maybe the "dependency" is not a dependency as such. + +### Upgrading dependencies + +If you need to upgrade a direct or indirect dependency, you can do it like so, $MODULE being the dependency in question: `go get -u $MODULE`. The corresponding entry in go.mod should then have the version you specified; if it's an indirect dependency, the entry should have the `// indirect` comment. Follow this by executing `go mod tidy`, to ensure that go.mod and go.sum are up to date. If the indirect dependency turns out to not be used (transitively) by any of our packages, `go mod tidy` will actually strip it from go.mod. In that case, you can just ignore it since it isn't used in the end. + +## Node.js dependencies + +Updated using `yarn`. + +- `package.json` + +## Where to make changes + +### Drone + +Our CI builds run on Drone. + +#### Files + +- `.circleci/config.yml`. + +#### Dependencies + +- nodejs +- golang +- grafana/build-container (our custom docker build container) + +### grafana/build-container + +The main build steps (in Drone) happen using a custom Docker image that comes pre-baked with some of the necessary dependencies. + +Link: [grafana/build-container](https://github.com/grafana/grafana/tree/main/scripts/build/ci-build) + +#### Dependencies + +- fpm +- nodejs +- golang +- crosscompiling (several compilers) + +### Appveyor + +Main and release builds trigger test runs on Appveyors build environment so that tests will run on Windows. + +#### Files: + +- `appveyor.yml` + +#### Dependencies + +- nodejs +- golang + +### Dockerfile + +There is a Docker build for Grafana in the root of the project that allows anyone to build Grafana just using Docker. + +#### Files + +- `Dockerfile` + +#### Dependencies + +- nodejs +- golang + +### Local developer environments + +Please send out a notice in the grafana-dev slack channel when updating Go or Node.js to make it easier for everyone to update their local developer environments. diff --git a/WORKFLOW.md b/WORKFLOW.md new file mode 100644 index 00000000..633a996c --- /dev/null +++ b/WORKFLOW.md @@ -0,0 +1,83 @@ +# Grafana workflow + +This document is based on [GOVERNANCE.md](GOVERNANCE.md). We assume good faith and intend to keep all processes as lightweight as possible but as specific as required. In case of disagreements about anything in this document, GOVERNANCE.md applies. + +The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC2119](http://tools.ietf.org/html/rfc2119). + +Git and [GitHub terminology](https://help.github.com/en/github/getting-started-with-github/github-glossary) are used throughout this document. + +Team members and their access to repositories is maintained through [GitHub teams](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/about-teams). Team maintainers add and remove team members as outlined in GOVERNANCE.md. + +# Code changes + +## Proposing changes + +Examples of proposed changes are overarching architecture, component design, and specific code or graphical elements. Proposed changes SHOULD cover the big picture and intention, but individual parts SHOULD be split into the smallest possible changes. Changes SHOULD be based on and target the main branch. Depending on size of the proposed change, each change SHOULD be discussed, in increasing order of change size and complexity: + +- Directly in a RR (Pull Request) - this MAY be done, but SHOULD not be the common case. +- Issue +- Developer mailing list +- Design document, shared via Google Docs, accessible to at least all team members. + +Significant changes MUST be discussed and agreed upon with the relevant subsystem maintainers. + +## Merging PRs (Pull Requests) + +Depending on the size and complexity of a PR, different requirements MUST be applied. Any team member contributing substantially to a PR MUST NOT count against review requirements. +Commits MUST be merged into main using PRs. They MUST NOT be merged into main directly. + +- Every merge MUST be approved by at least one team member. +- Non-trivial changes MUST be approved by at least + - two team members, or + - one subsystem maintainer. +- Significant changes MUST be approved by at least + - two team members, AND + - the relevant subsystem maintainer. + +PRs MUST be [reviewed](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/reviewing-changes-in-pull-requests) and [approved](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews) via GitHub’s review system. + +- Reviewers MAY write comments if approving +- Reviewers MUST write comments if rejecting a PR or if requesting changes. + +Once a PR is approved as per above, any team member MAY merge the PR. + +## Backporting a PR + +PRs intended for inclusion in the next PATCH release they must be backported to the release branch. The bot can do this automatically. [Read more on backport PRs](https://github.com/grafana/grafana/blob/main/.github/bot.md). Both the source PR and the backport PR should be assigned to the patch release milestone, unless you are backporting to many releases then it can differ. + +Backport PRs are also needed during the beta period to get fixes into the stable release. + +# Release workflow + +## Branch structure + +Grafana uses trunk-based development. + +In particular, we found that the following principles match how we work: + +- Main and release branches MUST always build without failure. +- Branches SHOULD be merged often. Larger changes SHOULD be activated with feature flags until they are ready. Long-lived development branches SHOULD be avoided. +- Changes MAY be enabled by default once they are in a complete state +- Changes which span multiple PRs MUST be described in an overarching issue or Google Doc. + +## Releases + +Releases MUST follow [Semantic Versioning](https://semver.org/) in naming and SHOULD follow Semantic Versioning as closely as reasonably possible for non-library software. + +Release branches MUST be split from the following branches. + +- MAJOR release branches MUST be based on main. +- MINOR release branches MUST be based on main. +- PATCH release branches MUST be split from the relevant MINOR release branch’s most current PATCH + +Security releases follow the same process but MUST be prepared in secret. Security releases MUST NOT include changes which are not related to the security fix. Normal release processes MUST accommodate the security release process. SECURITY.md MUST be followed. + +Releases follow the following cadence + +- MAJOR: Yearly +- MINOR: Every 4-6 weeks +- PATCH: As needed + +Releases SHOULD NOT be delayed by pending changes. + +Releases MUST be coordinated with the relevant subsystem maintainers. diff --git a/api-extractor.json b/api-extractor.json new file mode 100644 index 00000000..b73e800b --- /dev/null +++ b/api-extractor.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "mainEntryPointFilePath": "/dist/index.d.ts", + "bundledPackages": [], + "compiler": {}, + "apiReport": { + "enabled": false + }, + "docModel": { + "enabled": true, + "apiJsonFilePath": "/../../reports/docs/.api.json" + }, + "dtsRollup": { + "enabled": false + }, + "tsdocMetadata": {}, + "messages": { + "compilerMessageReporting": { + "default": { + "logLevel": "warning" + } + }, + "extractorMessageReporting": { + "default": { + "logLevel": "warning" + }, + "ae-internal-missing-underscore": { + "logLevel": "none", + "addToApiReportFile": false + } + }, + "tsdocMessageReporting": { + "default": { + "logLevel": "warning" + } + } + } +} diff --git a/babel.config.json b/babel.config.json new file mode 100644 index 00000000..4de74eb5 --- /dev/null +++ b/babel.config.json @@ -0,0 +1,59 @@ +{ + "babelrc": false, + // Note: order is bottom-to-top and/or right-to-left + "presets": [ + [ + "@babel/preset-env", + { + "bugfixes": true, + "browserslistEnv": "dev", + "useBuiltIns": "entry", + "corejs": "3.10" + } + ], + [ + "@babel/preset-typescript", + { + "allowNamespaces": true, + "allowDeclareFields": true + } + ], + [ + "@babel/preset-react", + { + "runtime": "automatic" + } + ] + ], + "plugins": [ + [ + "@babel/plugin-transform-typescript", + { + "allowNamespaces": true, + "allowDeclareFields": true + } + ], + ["@babel/plugin-proposal-object-rest-spread", { "loose": true }], + "@babel/plugin-transform-react-constant-elements", + "@babel/plugin-proposal-nullish-coalescing-operator", + "@babel/plugin-proposal-optional-chaining", + "@babel/plugin-syntax-dynamic-import", // needed for `() => import()` in routes.ts + "angularjs-annotate", + "macros" + ], + "env": { + "production": { + "presets": [ + [ + "@babel/preset-env", + { + "browserslistEnv": "production" + } + ] + ] + }, + "hot": { + "plugins": ["react-refresh/babel"] + } + } +} diff --git a/build.go b/build.go new file mode 100644 index 00000000..50b8e4e2 --- /dev/null +++ b/build.go @@ -0,0 +1,16 @@ +// +build ignore + +package main + +import ( + "log" + "os" + + "github.com/grafana/grafana/pkg/build" +) + +func main() { + log.SetOutput(os.Stdout) + log.SetFlags(0) + os.Exit(build.RunCmd()) +} diff --git a/conf/defaults.ini b/conf/defaults.ini new file mode 100644 index 00000000..43196b6a --- /dev/null +++ b/conf/defaults.ini @@ -0,0 +1,1119 @@ +##################### Grafana Configuration Defaults ##################### +# +# Do not modify this file in grafana installs +# + +# possible values : production, development +app_mode = production + +# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty +instance_name = ${HOSTNAME} + +#################################### Paths ############################### +[paths] +# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) +data = data + +# Temporary files in `data` directory older than given duration will be removed +temp_data_lifetime = 24h + +# Directory where grafana can store logs +logs = data/log + +# Directory where grafana will automatically scan and look for plugins +plugins = data/plugins + +# folder that contains provisioning config files that grafana will apply on startup and while running. +provisioning = conf/provisioning + +#################################### Server ############################## +[server] +# Protocol (http, https, h2, socket) +protocol = http + +# The ip address to bind to, empty will bind to all interfaces +http_addr = + +# The http port to use +http_port = 3000 + +# The public facing domain name used to access grafana from a browser +domain = localhost + +# Redirect to correct domain if host header does not match domain +# Prevents DNS rebinding attacks +enforce_domain = false + +# The full public facing url +root_url = %(protocol)s://%(domain)s:%(http_port)s/ + +# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons. +serve_from_sub_path = false + +# Log web requests +router_logging = false + +# the path relative working path +static_root_path = public + +# enable gzip +enable_gzip = false + +# https certs & key file +cert_file = +cert_key = + +# Unix socket path +socket = /tmp/grafana.sock + +# CDN Url +cdn_url = + +# Sets the maximum time in minutes before timing out read of an incoming request and closing idle connections. +# `0` means there is no timeout for reading the request. +read_timeout = 0 + +#################################### Database ############################ +[database] +# You can configure the database connection by specifying type, host, name, user and password +# as separate properties or as on string using the url property. + +# Either "mysql", "postgres" or "sqlite3", it's your choice +type = sqlite3 +host = 127.0.0.1:3306 +name = grafana +user = root +# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" +password = +# Use either URL or the previous fields to configure the database +# Example: mysql://user:secret@host:port/database +url = + +# Max idle conn setting default is 2 +max_idle_conn = 2 + +# Max conn setting default is 0 (mean not set) +max_open_conn = + +# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours) +conn_max_lifetime = 14400 + +# Set to true to log the sql calls and execution times. +log_queries = + +# For "postgres", use either "disable", "require" or "verify-full" +# For "mysql", use either "true", "false", or "skip-verify". +ssl_mode = disable + +# Database drivers may support different transaction isolation levels. +# Currently, only "mysql" driver supports isolation levels. +# If the value is empty - driver's default isolation level is applied. +# For "mysql" use "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ" or "SERIALIZABLE". +isolation_level = + +ca_cert_path = +client_key_path = +client_cert_path = +server_cert_name = + +# For "sqlite3" only, path relative to data_path setting +path = grafana.db + +# For "sqlite3" only. cache mode setting used for connecting to the database +cache_mode = private + +#################################### Cache server ############################# +[remote_cache] +# Either "redis", "memcached" or "database" default is "database" +type = database + +# cache connectionstring options +# database: will use Grafana primary database. +# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'. +# memcache: 127.0.0.1:11211 +connstr = + +#################################### Data proxy ########################### +[dataproxy] + +# This enables data proxy logging, default is false +logging = false + +# How long the data proxy waits to read the headers of the response before timing out, default is 30 seconds. +# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set. +timeout = 30 + +# How long the data proxy waits to establish a TCP connection before timing out, default is 10 seconds. +dialTimeout = 10 + +# How many seconds the data proxy waits before sending a keepalive request. +keep_alive_seconds = 30 + +# How many seconds the data proxy waits for a successful TLS Handshake before timing out. +tls_handshake_timeout_seconds = 10 + +# How many seconds the data proxy will wait for a server's first response headers after +# fully writing the request headers if the request has an "Expect: 100-continue" +# header. A value of 0 will result in the body being sent immediately, without +# waiting for the server to approve. +expect_continue_timeout_seconds = 1 + +# Optionally limits the total number of connections per host, including connections in the dialing, +# active, and idle states. On limit violation, dials will block. +# A value of zero (0) means no limit. +max_conns_per_host = 0 + +# The maximum number of idle connections that Grafana will keep alive. +max_idle_connections = 100 + +# How many seconds the data proxy keeps an idle connection open before timing out. +idle_conn_timeout_seconds = 90 + +# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request. +send_user_header = false + +# Limit the amount of bytes that will be read/accepted from responses of outgoing HTTP requests. +response_limit = 0 + +# Limits the number of rows that Grafana will process from SQL data sources. +row_limit = 1000000 + +#################################### Analytics ########################### +[analytics] +# Server reporting, sends usage counters to stats.grafana.org every 24 hours. +# No ip addresses are being tracked, only simple counters to track +# running instances, dashboard and error counts. It is very helpful to us. +# Change this option to false to disable reporting. +reporting_enabled = true + +# The name of the distributor of the Grafana instance. Ex hosted-grafana, grafana-labs +reporting_distributor = grafana-labs + +# Set to false to disable all checks to https://grafana.com +# for new versions (grafana itself and plugins), check is used +# in some UI views to notify that grafana or plugin update exists +# This option does not cause any auto updates, nor send any information +# only a GET request to https://grafana.com to get latest versions +check_for_updates = true + +# Google Analytics universal tracking code, only enabled if you specify an id here +google_analytics_ua_id = + +# Google Tag Manager ID, only enabled if you specify an id here +google_tag_manager_id = + +# Rudderstack write key, enabled only if rudderstack_data_plane_url is also set +rudderstack_write_key = + +# Rudderstack data plane url, enabled only if rudderstack_write_key is also set +rudderstack_data_plane_url = + +# Rudderstack SDK url, optional, only valid if rudderstack_write_key and rudderstack_data_plane_url is also set +rudderstack_sdk_url = + +# Rudderstack Config url, optional, used by Rudderstack SDK to fetch source config +rudderstack_config_url = + +# Application Insights connection string. Specify an URL string to enable this feature. +application_insights_connection_string = + +# Optional. Specifies an Application Insights endpoint URL where the endpoint string is wrapped in backticks ``. +application_insights_endpoint_url = + +#################################### Security ############################ +[security] +# disable creation of admin user on first start of grafana +disable_initial_admin_creation = false + +# default admin user, created on startup +admin_user = admin + +# default admin password, can be changed before first start of grafana, or in profile settings +admin_password = admin + +# used for signing +secret_key = SW2YcwTIb9zpOOhoPsMm + +# current key provider used for envelope encryption, default to static value specified by secret_key +encryption_provider = secretKey + +# list of configured key providers, space separated (Enterprise only): e.g., awskms.v1 azurekv.v1 +available_encryption_providers = + +# disable gravatar profile images +disable_gravatar = false + +# data source proxy whitelist (ip_or_domain:port separated by spaces) +data_source_proxy_whitelist = + +# disable protection against brute force login attempts +disable_brute_force_login_protection = false + +# set to true if you host Grafana behind HTTPS. default is false. +cookie_secure = false + +# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled" +cookie_samesite = lax + +# set to true if you want to allow browsers to render Grafana in a , +``` + +The result is an interactive Grafana graph embedded in an iframe: + + + +## Library panel + +To create a library panel from the Share Panel dialog: + +1. Click **Library panel**. + {{< figure src="/static/img/docs/library-panels/create-lib-panel-8-0.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the create library panel dialog" >}} +1. In **Library panel name**, enter the name. +1. In **Save in folder**, select the folder to save the library panel. By default, the General folder is selected. +1. Click **Create library panel** to save your changes. +1. Save the dashboard. diff --git a/docs/sources/troubleshooting/_index.md b/docs/sources/troubleshooting/_index.md new file mode 100644 index 00000000..ef8c9f72 --- /dev/null +++ b/docs/sources/troubleshooting/_index.md @@ -0,0 +1,41 @@ ++++ +title = "Troubleshooting" +description = "Guide to troubleshooting Grafana problems" +keywords = ["grafana", "troubleshooting", "documentation", "guide"] +weight = 180 ++++ + +# Troubleshooting + +This page lists some tools and advice to help troubleshoot common Grafana issues. + +## Troubleshoot with logs + +If you encounter an error or problem, then you can check the Grafana server log. Usually located at `/var/log/grafana/grafana.log` on Unix systems or in `/data/log` on other platforms and manual installations. + +You can enable more logging by changing log level in the Grafana configuration file. + +For more information, refer to [Enable debug logging in Grafana CLI]({{< relref "../administration/cli.md#enable-debug-logging" >}}) and the [log section in Configuration]({{< relref "../administration/configuration.md#log" >}}). + +## Troubleshoot transformations + +Order of transformations matters. If the final data output from multiple transformations looks wrong, try changing the transformation order. Each transformation transforms data returned by the previous transformation, not the original raw data. + +For more information, refer to [Debug transformations]({{< relref "../panels/transformations/apply-transformations.md" >}}). + +## Text missing with server-side image rendering (RPM-based Linux) + +Server-side image (png) rendering is a feature that is optional but very useful when sharing visualizations, for example in alert notifications. + +If the image is missing text, then make sure you have font packages installed. + +```bash +sudo yum install fontconfig +sudo yum install freetype* +sudo yum install urw-fonts +``` + +## FAQs + +Check out the [FAQ section](https://community.grafana.com/c/howto/faq) on the Grafana Community page for answers to frequently +asked questions. diff --git a/docs/sources/troubleshooting/diagnostics.md b/docs/sources/troubleshooting/diagnostics.md new file mode 100644 index 00000000..65cac5ab --- /dev/null +++ b/docs/sources/troubleshooting/diagnostics.md @@ -0,0 +1,56 @@ ++++ +title = "Enable diagnostics" +weight = 200 ++++ + +# Enable diagnostics + +You can set up the `grafana-server` process to enable certain diagnostics when it starts. This can be helpful +when investigating certain performance problems. It's _not_ recommended to have these enabled by default. + +## Turn on profiling + +The `grafana-server` can be started with the arguments `-profile` to enable profiling, `-profile-addr` to override the default HTTP address (`localhost`), and +`-profile-port` to override the default HTTP port (`6060`) where the `pprof` debugging endpoints are available. For example: + +```bash +./grafana-server -profile -profile-addr=0.0.0.0 -profile-port=8080 +``` + +Note that `pprof` debugging endpoints are served on a different port than the Grafana HTTP server. + +You can configure or override profiling settings using environment variables: + +```bash +export GF_DIAGNOSTICS_PROFILING_ENABLED=true +export GF_DIAGNOSTICS_PROFILING_ADDR=0.0.0.0 +export GF_DIAGNOSTICS_PROFILING_PORT=8080 +``` + +Refer to [Go command pprof](https://golang.org/cmd/pprof/) for more information about how to collect and analyze profiling data. + +## Use tracing + +The `grafana-server` can be started with the arguments `-tracing` to enable tracing and `-tracing-file` to override the default trace file (`trace.out`) where trace result is written to. For example: + +```bash +./grafana-server -tracing -tracing-file=/tmp/trace.out +``` + +You can configure or override profiling settings using environment variables: + +```bash +export GF_DIAGNOSTICS_TRACING_ENABLED=true +export GF_DIAGNOSTICS_TRACING_FILE=/tmp/trace.out +``` + +View the trace in a web browser (Go required to be installed): + +```bash +go tool trace +2019/11/24 22:20:42 Parsing trace... +2019/11/24 22:20:42 Splitting trace... +2019/11/24 22:20:42 Opening browser. Trace viewer is listening on http://127.0.0.1:39735 +``` + +For more information about how to analyze trace files, refer to [Go command trace](https://golang.org/cmd/trace/). diff --git a/docs/sources/troubleshooting/troubleshoot-dashboards.md b/docs/sources/troubleshooting/troubleshoot-dashboards.md new file mode 100644 index 00000000..a9dbb8db --- /dev/null +++ b/docs/sources/troubleshooting/troubleshoot-dashboards.md @@ -0,0 +1,43 @@ ++++ +title = "Troubleshoot dashboards" +description = "Guide to troubleshooting Grafana dashboards" +keywords = ["grafana", "troubleshooting", "documentation", "dashboards"] +weight = 100 ++++ + +# Troubleshoot dashboards + +This page provides information to solve common dashboard problems. + +## Dashboard is slow + +- Are you trying to render dozens (or hundreds or thousands) of time-series on a graph? This can cause the browser to lag and feel sluggish. Try using functions like `highestMax` (in Graphite) to reduce the returned series. +- Sometimes the series names can be very large. This causes larger response sizes. Try using `alias` to reduce the size of the returned series names. +- Are you querying many time-series or for a long range of time? Both of these can cause Grafana or your data source to pull in a lot of data, which may slow it down. +- It could be high load on your network infrastructure. If the slowness isn't consistent, this may be the problem. + +## Dashboard refresh rate issues + +By default, Grafana queries your data source every 30 seconds. Setting a low refresh rate on your dashboards puts unnecessary stress on the backend. In many cases, querying this frequently makes no sense, because the data isn't being sent to the system such that changes would be seen. + +We recommend the following: + +- Do not enable auto-refreshing on dashboards, panels, or variables unless you need it. Users can refresh their browser manually, or you can set the refresh rate for a time period that makes sense (every ten minutes, every hour, and so on). +- If it is required, then set the refresh rate to once a minute. Again, users can always refresh the dashboard manually. +- If your dashboard has a longer time period (such as a week), then you really don't need automated refreshing. + +### Handling or rendering null data is wrong/confusing/weird + +Some applications publish data intermittently; for example, they only post a metric when an event occurs. By +default, Grafana graphs connect lines between the data points. This can be very deceiving. + +In the picture below we have enabled: + +- Points and 3-point radius to highlight where data points are actually present. +- **Null value** is set to **connected**. + +{{< figure src="/static/img/docs/troubleshooting/grafana_null_connected.png" max-width="1200px" >}} + +In this graph, we set graph to show bars instead of lines and set the **Null value** to graph **null as zero**. There is a very big different in the visuals. + +{{< figure src="/static/img/docs/troubleshooting/grafana_null_zero.png" max-width="1200px" >}} diff --git a/docs/sources/troubleshooting/troubleshoot-queries.md b/docs/sources/troubleshooting/troubleshoot-queries.md new file mode 100644 index 00000000..2283bdb7 --- /dev/null +++ b/docs/sources/troubleshooting/troubleshoot-queries.md @@ -0,0 +1,30 @@ ++++ +title = "Troubleshoot queries" +description = "Guide to troubleshooting Grafana queries" +keywords = ["grafana", "troubleshooting", "documentation", "guide", "queries"] +weight = 400 ++++ + +# Troubleshoot queries + +This page provides information to solve common dashboard problems. + +## I get different results when I rearrange my functions + +Function order is very important. Just like in math, the order that you place your functions can affect the result. + +## Inspect your query request and response + +The most common problems are related to the query and response from your data source. Even if it looks +like a bug or visualization issue in Grafana, it is almost always a problem with the data source query or +the data source response. Start by inspecting your panel query and response. + +For more information, refer to [Inspect a panel]({{< relref "../panels/inspect-panel.md" >}}). + +## My query is slow + +How many data points is your query returning? A query that returns lots of data points will be slow. Try this: + +- In **Query options**, limit the **Max data points** returned. +- In **Query options**, increase the **Min interval** time. +- In your query, use a `group by` function. diff --git a/docs/sources/variables/_index.md b/docs/sources/variables/_index.md new file mode 100644 index 00000000..9beb52fd --- /dev/null +++ b/docs/sources/variables/_index.md @@ -0,0 +1,45 @@ ++++ +title = "Templates and variables" +weight = 130 ++++ + +# Templates and variables + +A variable is a placeholder for a value. You can use variables in metric queries and in panel titles. So when you change +the value, using the dropdown at the top of the dashboard, your panel's metric queries will change to reflect the new value. + +Variables allow you to create more interactive and dynamic dashboards. Instead of hard-coding things like server, application, +and sensor names in your metric queries, you can use variables in their place. Variables are displayed as dropdown lists at the top of +the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard. +{{< figure src="/static/img/docs/v50/variables_dashboard.png" >}} + +These can be especially useful for administrators who want to allow Grafana viewers to quickly adjust visualizations but do not want to give them full editing permissions. Grafana Viewers can use variables. + +Variables and templates also allow you to single-source dashboards. If you have multiple identical data sources or servers, you can make one dashboard and use variables to change what you are viewing. This simplifies maintenance and upkeep enormously. + +## Templates + +A _template_ is any query that contains a variable. + +For example, if you were administering a dashboard to monitor several servers, you _could_ make a dashboard for each server. Or you could create one dashboard and use panels with template queries like this one: + +``` +wmi_system_threads{instance=~"$server"} +``` + +Variable values are always synced to the URL using the syntax `var-=value`. + +## Examples of templates and variables + +To see variable and template examples, go to any of the dashboards listed in [Variable examples]({{< relref "variable-examples.md" >}}). + +Variables are listed in drop-down lists across the top of the screen. Select different variables to see how the visualizations change. + +To see variable settings, navigate to **Dashboard Settings > Variables**. Click a variable in the list to see its settings. + +Variables can be used in titles, descriptions, text panels, and queries. Queries with text that starts with `$` are templates. Not all panels will have template queries. + +## Variable best practices + +- Variable drop-down lists are displayed in the order they are listed in the variable list in Dashboard settings. +- Put the variables that you will change often at the top, so they will be shown first (far left on the dashboard). diff --git a/docs/sources/variables/advanced-variable-format-options.md b/docs/sources/variables/advanced-variable-format-options.md new file mode 100644 index 00000000..0650e78e --- /dev/null +++ b/docs/sources/variables/advanced-variable-format-options.md @@ -0,0 +1,161 @@ ++++ +title = "Advanced variable format options" +keywords = ["grafana", "templating", "documentation", "guide", "template", "variable"] +weight = 600 ++++ + +# Advanced variable format options + +The formatting of the variable interpolation depends on the data source, but there are some situations where you might want to change the default formatting. + +For example, the default for the MySql data source is to join multiple values as comma-separated with quotes: `'server01','server02'`. In some cases, you might want to have a comma-separated string without quotes: `server01,server02`. You can make that happen with advanced variable formatting options listed below. + +## General syntax + +Syntax: `${var_name:option}` + +Test the formatting options on the [Grafana Play site](https://play.grafana.org/d/cJtIfcWiz/template-variable-formatting-options?orgId=1). + +If any invalid formatting option is specified, then `glob` is the default/fallback option. + +An alternative syntax (that might be deprecated in the future) is `[[var_name:option]]`. + +## CSV + +Formats variables with multiple values as a comma-separated string. + +```bash +servers = ['test1', 'test2'] +String to interpolate: '${servers:csv}' +Interpolation result: 'test1,test2' +``` + +## Distributed - OpenTSDB + +Formats variables with multiple values in custom format for OpenTSDB. + +```bash +servers = ['test1', 'test2'] +String to interpolate: '${servers:distributed}' +Interpolation result: 'test1,servers=test2' +``` + +## Doublequote + +Formats single- and multi-valued variables into a comma-separated string, escapes `"` in each value by `\"` and quotes each value with `"`. + +```bash +servers = ['test1', 'test2'] +String to interpolate: '${servers:doublequote}' +Interpolation result: '"test1","test2"' +``` + +## Glob - Graphite + +Formats variables with multiple values into a glob (for Graphite queries). + +```bash +servers = ['test1', 'test2'] +String to interpolate: '${servers:glob}' +Interpolation result: '{test1,test2}' +``` + +## JSON + +Formats variables with multiple values as a comma-separated string. + +```bash +servers = ['test1', 'test2'] +String to interpolate: '${servers:json}' +Interpolation result: '["test1", "test2"]' +``` + +## Lucene - Elasticsearch + +Formats variables with multiple values in Lucene format for Elasticsearch. + +```bash +servers = ['test1', 'test2'] +String to interpolate: '${servers:lucene}' +Interpolation result: '("test1" OR "test2")' +``` + +## Percentencode + +Formats single and multi valued variables for use in URL parameters. + +```bash +servers = ['foo()bar BAZ', 'test2'] +String to interpolate: '${servers:percentencode}' +Interpolation result: 'foo%28%29bar%20BAZ%2Ctest2' +``` + +## Pipe + +Formats variables with multiple values into a pipe-separated string. + +```bash +servers = ['test1.', 'test2'] +String to interpolate: '${servers:pipe}' +Interpolation result: 'test1.|test2' +``` + +## Raw + +Turns off data source-specific formatting, such as single quotes in an SQL query. + +```bash +servers = ['test.1', 'test2'] +String to interpolate: '${var_name:raw}' +Interpolation result: 'test.1,test2' +``` + +## Regex + +Formats variables with multiple values into a regex string. + +```bash +servers = ['test1.', 'test2'] +String to interpolate: '${servers:regex}' +Interpolation result: '(test1\.|test2)' +``` + +## Singlequote + +Formats single- and multi-valued variables into a comma-separated string, escapes `'` in each value by `\'` and quotes each value with `'`. + +```bash +servers = ['test1', 'test2'] +String to interpolate: '${servers:singlequote}' +Interpolation result: "'test1','test2'" +``` + +## Sqlstring + +Formats single- and multi-valued variables into a comma-separated string, escapes `'` in each value by `''` and quotes each value with `'`. + +```bash +servers = ["test'1", "test2"] +String to interpolate: '${servers:sqlstring}' +Interpolation result: "'test''1','test2'" +``` + +## Text + +Formats single- and multi-valued variables into their text representation. For a single variable it will just return the text representation. For multi-valued variables it will return the text representation combined with `+`. + +```bash +servers = ["test1", "test2"] +String to interpolate: '${servers:text}' +Interpolation result: "test1 + test2" +``` + +## Query parameters + +Formats single- and multi-valued variables into their query parameter representation. Example: `var-foo=value1&var-foo=value2` + +```bash +servers = ["test1", "test2"] +String to interpolate: '${servers:queryparam}' +Interpolation result: "var-servers=test1&var-servers=test2" +``` diff --git a/docs/sources/variables/filter-variables-with-regex.md b/docs/sources/variables/filter-variables-with-regex.md new file mode 100644 index 00000000..299b1d58 --- /dev/null +++ b/docs/sources/variables/filter-variables-with-regex.md @@ -0,0 +1,110 @@ ++++ +title = "Filter variables with regex" +keywords = ["grafana", "templating", "documentation", "guide", "template", "variable"] +weight = 700 ++++ + +# Filter variables with regex + +Using the Regex Query option, you filter the list of options returned by the variable query or modify the options returned. + +This page shows how to use regex to filter/modify values in the variable dropdown. + +Using the Regex Query Option, you filter the list of options returned by the Variable query or modify the options returned. For more information, refer to the Mozilla guide on [Regular expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions). + +Examples of filtering on the following list of options: + +```text +backend_01 +backend_02 +backend_03 +backend_04 +``` + +## Filter so that only the options that end with `01` or `02` are returned: + +Regex: + +```regex +/.*[01|02]/ +``` + +Result: + +```text +backend_01 +backend_02 +``` + +## Filter and modify the options using a regex capture group to return part of the text: + +Regex: + +```regex +/.*(01|02)/ +``` + +Result: + +```text +01 +02 +``` + +## Filter and modify - Prometheus Example + +List of options: + +```text +up{instance="demo.robustperception.io:9090",job="prometheus"} 1 1521630638000 +up{instance="demo.robustperception.io:9093",job="alertmanager"} 1 1521630638000 +up{instance="demo.robustperception.io:9100",job="node"} 1 1521630638000 +``` + +Regex: + +```regex +/.*instance="([^"]*).*/ +``` + +Result: + +```text +demo.robustperception.io:9090 +demo.robustperception.io:9093 +demo.robustperception.io:9100 +``` + +## Filter and modify using named text and value capture groups + +> **Note:** This feature is available in Grafana 7.4+. + +Using named capture groups, you can capture separate 'text' and 'value' parts from the options returned by the variable query. This allows the variable drop-down list to contain a friendly name for each value that can be selected. + +For example, when querying the `node_hwmon_chip_names` Prometheus metric, the `chip_name` is a lot friendlier that the `chip` value. So the following variable query result: + +```text +node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_0",chip_name="enp216s0f0np0"} 1 +node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_1",chip_name="enp216s0f0np1"} 1 +node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_2",chip_name="enp216s0f0np2"} 1 +node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_3",chip_name="enp216s0f0np3"} 1 +``` + +Passed through the following Regex: + +```regex +/chip_name="(?[^"]+)|chip="(?[^"]+)/g +``` + +Would produce the following drop-down list: + +```text +Display Name Value +------------ ------------------------- +enp216s0f0np0 0000:d7:00_0_0000:d8:00_0 +enp216s0f0np1 0000:d7:00_0_0000:d8:00_1 +enp216s0f0np2 0000:d7:00_0_0000:d8:00_2 +enp216s0f0np3 0000:d7:00_0_0000:d8:00_3 +``` + +**Note:** Only `text` and `value` capture group names are supported. diff --git a/docs/sources/variables/formatting-multi-value-variables.md b/docs/sources/variables/formatting-multi-value-variables.md new file mode 100644 index 00000000..b8a9b1ee --- /dev/null +++ b/docs/sources/variables/formatting-multi-value-variables.md @@ -0,0 +1,31 @@ ++++ +title = "Multi-value variables" +weight = 600 ++++ + +# Multi-value variables + +Interpolating a variable with multiple values selected is tricky as it is not straight forward how to format the multiple values into a string that is valid in the given context where the variable is used. Grafana tries to solve this by allowing each data source plugin to inform the templating interpolation engine what format to use for multiple values. + +> **Note:** The **Custom all value** option on the variable must be blank for Grafana to format all values into a single string. If leave it blank, then the Grafana concatenates (adds together) all the values in the query. Something like `value1,value2,value3`. If a custom `all` value is used, then instead the value will be something like `*` or `all`. + +## Multi-value variables with a Graphite data source + +Graphite uses glob expressions. A variable with multiple values would, in this case, be interpolated as `{host1,host2,host3}` if the current variable value was _host1_, _host2_, and _host3_. + +## Multi-value variables with a Prometheus or InfluxDB data source + +InfluxDB and Prometheus use regex expressions, so the same variable would be interpolated as `(host1|host2|host3)`. Every value would also be regex escaped. If not, a value with a regex control character would break the regex expression. + +## Multi-value variables with an Elastic data source + +Elasticsearch uses lucene query syntax, so the same variable would be formatted as `("host1" OR "host2" OR "host3")`. In this case, every value must be escaped so that the value only contains lucene control words and quotation marks. + +## Troubleshoot multi-value variables + +Automatic escaping and formatting can cause problems and it can be tricky to grasp the logic behind it. Especially for InfluxDB and Prometheus where the use of regex syntax requires that the variable is used in regex operator context. + +If you do not want Grafana to do this automatic regex escaping and formatting, then you must do one of the following: + +- Turn off the **Multi-value** or **Include All option** options. +- Use the [raw variable format]({{< relref "advanced-variable-format-options.md#raw" >}}). diff --git a/docs/sources/variables/inspect-variable.md b/docs/sources/variables/inspect-variable.md new file mode 100644 index 00000000..f9502ca3 --- /dev/null +++ b/docs/sources/variables/inspect-variable.md @@ -0,0 +1,22 @@ ++++ +title = "Inspect variables" +keywords = ["grafana", "templating", "documentation", "guide", "template", "variable"] +aliases = ["/docs/grafana/latest/reference/templating"] +weight = 125 ++++ + +# Inspect variables and their dependencies + +The variables page lets you easily identify whether a variable is being referenced (or used) in other variables or dashboard. In addition, you can also [add]({{< relref "variable-types/_index.md" >}}) variables and [manage]({{< relref "manage-variable.md" >}}) existing variables from this page. + +> **Note:** This feature is available in Grafana 7.4 and later versions. + +![Variables list](/static/img/docs/variables-templates/variables-list-7-4.png) + +Any variable that is referenced or used has a green check mark next to it, while unreferenced variables have a orange caution icon next to them. + +![Variables list](/static/img/docs/variables-templates/variable-not-referenced-7-4.png) + +In addition, all referenced variables have a dependency icon next to the green check mark. You can click on the icon to view the dependency map. The dependency map can be moved. You can zoom in out with mouse wheel or track pad equivalent. + +![Variables list](/static/img/docs/variables-templates/dependancy-map-7-4.png) diff --git a/docs/sources/variables/manage-variable.md b/docs/sources/variables/manage-variable.md new file mode 100644 index 00000000..e3d6be88 --- /dev/null +++ b/docs/sources/variables/manage-variable.md @@ -0,0 +1,22 @@ ++++ +title = "Manage variables" +keywords = ["grafana", "templating", "documentation", "guide", "template", "variable"] +aliases = ["/docs/grafana/latest/reference/templating"] +weight = 120 ++++ + +# Manage variables + +The variables page lets you [add]({{< relref "variable-types/_index.md" >}}) variables and manage existing variables. It also allows you to [inspect]({{< relref "inspect-variable.md" >}}) variables and identify whether a variable is being referenced (or used) in other variables or dashboard. + +## Move + +You can move a variable up or down the list using drag and drop. + +## Clone + +To clone a variable, click the clone icon from the set of icons on the right. This creates a copy of the variable with the name of the original variable prefixed with `copy_of_`. + +## Delete + +To delete a variable, click the trash icon from the set of icons on the right. diff --git a/docs/sources/variables/syntax.md b/docs/sources/variables/syntax.md new file mode 100644 index 00000000..f1ffcf80 --- /dev/null +++ b/docs/sources/variables/syntax.md @@ -0,0 +1,24 @@ ++++ +title = "Variable syntax" +keywords = ["grafana", "templating", "documentation", "guide", "template", "variable"] +aliases = ["/docs/grafana/latest/reference/templating"] +weight = 100 ++++ + +# Variable syntax + +Panel titles and metric queries can refer to variables using two different syntaxes: + +- `$varname` + This syntax is easy to read, but it does not allow you to use a variable in the middle of a word. + **Example:** apps.frontend.$server.requests.count +- `${var_name}` Use this syntax when you want to interpolate a variable in the middle of an expression. +- `${var_name:}` This format gives you more control over how Grafana interpolates values. Refer to [Advanced variable format options]({{< relref "advanced-variable-format-options.md" >}}) for more detail on all the formatting types. +- `[[varname]]` Do not use. Deprecated old syntax, will be removed in a future release. + +Before queries are sent to your data source the query is _interpolated_, meaning the variable is replaced with its current value. During +interpolation, the variable value might be _escaped_ in order to conform to the syntax of the query language and where it is used. +For example, a variable used in a regex expression in an InfluxDB or Prometheus query will be regex escaped. Read the data source specific +documentation topic for details on value escaping during interpolation. + +For advanced syntax to override data source default formatting, refer to [Advanced variable format options]({{< relref "advanced-variable-format-options.md" >}}). diff --git a/docs/sources/variables/variable-examples.md b/docs/sources/variables/variable-examples.md new file mode 100644 index 00000000..2ef61665 --- /dev/null +++ b/docs/sources/variables/variable-examples.md @@ -0,0 +1,20 @@ ++++ +title = "Variable examples" +keywords = ["grafana", "templating", "documentation", "guide", "template", "variable"] +weight = 200 ++++ + +# Variable examples + +This page contains links to dashboards in Grafana Play with examples of template variables. + +- [Elasticsearch Metrics](https://play.grafana.org/d/000000014/elasticsearch-metrics?orgId=1) - Uses ad hoc filters, global variables, and a custom variable. +- [Graphite Templated Nested](https://play.grafana.org/d/000000056/graphite-templated-nested?orgId=1) - Uses query variables, chained query variables, an interval variable, and a repeated panel. +- [Influx DB Group By Variable](https://play.grafana.org/d/000000137/influxdb-group-by-variable?orgId=1) - Query variable, panel uses the variable results to group the metric data. +- [InfluxDB Raw Query Template Var](https://play.grafana.org/d/000000083/influxdb-raw-query-template-var?orgId=1) - Uses query variables, chained query variables, and an interval variable. +- [InfluxDB Server Monitoring](https://play.grafana.org/d/AAy9r_bmk/influxdb-server-monitoring?orgId=1) - Uses query variables, chained query variables, an interval variable, and an ad hoc filter. +- [Prometheus templating](https://play.grafana.org/d/000000063/prometheus-templating?orgId=1) - Uses chained query variables. +- [Template Redux](https://play.grafana.org/d/p-k6QtkGz/template-redux?orgId=1) - Uses query variables, chained query variables, ad hoc filters, an interval variable, a text box variable, a custom variable, and a data source variable. +- [Templating, repeated panels](https://play.grafana.org/d/000000025/templating-repeated-panels?orgId=1) - Two sets of repeated panels use query variables. +- [Templating showcase](https://play.grafana.org/d/000000091/templating-showcase?orgId=1) - Uses custom, query, chained query, and data source variables. +- [Templating value groups](https://play.grafana.org/d/000000024/templating-value-groups?orgId=1) - Uses query variable with value groups. diff --git a/docs/sources/variables/variable-selection-options.md b/docs/sources/variables/variable-selection-options.md new file mode 100644 index 00000000..24ce424d --- /dev/null +++ b/docs/sources/variables/variable-selection-options.md @@ -0,0 +1,26 @@ ++++ +title = "Variable selection options" +weight = 400 ++++ + +# Configure variable selection options + +**Selection Options** are a feature you can use to manage variable option selections. All selection options are optional, and they are off by default. + +## Multi-value + +If you turn this on, then the variable dropdown list allows users to select multiple options at the same time. For more information, refer to [Formatting multi-value variables]({{< relref "formatting-multi-value-variables.md" >}}). + +## Include All option + +Grafana adds an `All` option to the variable dropdown list. If a user selects this option, then all variable options are selected. + +## Custom all value + +This option is only visible if the **Include All option** is selected. + +Enter regex, globs, or lucene syntax in the **Custom all value** field to define the value of the `All` option. + +By default the `All` value includes all options in combined expression. This can become very long and can have performance problems. Sometimes it can be better to specify a custom all value, like a wildcard regex. + +In order to have custom regex, globs, or lucene syntax in the **Custom all value** option, it is never escaped so you will have to think about what is a valid value for your data source. diff --git a/docs/sources/variables/variable-types/_index.md b/docs/sources/variables/variable-types/_index.md new file mode 100644 index 00000000..c1089495 --- /dev/null +++ b/docs/sources/variables/variable-types/_index.md @@ -0,0 +1,20 @@ ++++ +title = "Add variables" +weight = 140 ++++ + +# Variables types + +Grafana uses several types of variables. + +| Variable type | Description | +| :---------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Query | Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on. [Add a query variable]({{< relref "add-query-variable.md" >}}). | +| Custom | Define the variable options manually using a comma-separated list. [Add a custom variable]({{< relref "add-custom-variable.md" >}}). | +| Text box | Display a free text input field with an optional default value. [Add a text box variable]({{< relref "add-text-box-variable.md" >}}). | +| Constant | Define a hidden constant. [Add a constant variable]({{< relref "add-constant-variable.md" >}}). | +| Data source | Quickly change the data source for an entire dashboard. [Add a data source variable]({{< relref "add-data-source-variable.md" >}}). | +| Interval | Interval variables represent time spans. [Add an interval variable]({{< relref "add-interval-variable.md" >}}). | +| Ad hoc filters | Key/value filters that are automatically added to all metric queries for a data source (InfluxDB, Prometheus, and Elasticsearch only). [Add ad hoc filters]({{< relref "add-ad-hoc-filters.md" >}}). | +| Global variables | Built-in variables that can be used in expressions in the query editor. Refer to [Global variables]({{< relref "global-variables" >}}). | +| Chained variables | Variable queries can contain other variables. Refer to [Chained variables]({{< relref "chained-variables.md" >}}). | diff --git a/docs/sources/variables/variable-types/add-ad-hoc-filters.md b/docs/sources/variables/variable-types/add-ad-hoc-filters.md new file mode 100644 index 00000000..4b3f9255 --- /dev/null +++ b/docs/sources/variables/variable-types/add-ad-hoc-filters.md @@ -0,0 +1,32 @@ ++++ +title = "Add ad hoc filters" +aliases = ["/docs/grafana/latest/variables/add-ad-hoc-filters.md"] +weight = 700 ++++ + +# Add ad hoc filters + +_Ad hoc filters_ allow you to add key/value filters that are automatically added to all metric queries that use the specified data source. Unlike other variables, you do not use ad hoc filters in queries. Instead, you use ad hoc filters to write filters for existing queries. + +> **Note:** Ad hoc filter variables only work with Prometheus, Loki, InfluxDB, and Elasticsearch data sources. + +## Enter General options + +1. Navigate to the dashboard you want to make a variable for and then click the **Dashboard settings** (gear) icon at the top of the page. +1. On the Variables tab, click **New**. +1. Enter a **Name** for your variable. +1. In the **Type** list, select **Ad hoc filters**. +1. (optional) In **Label**, enter the display name of the variable dropdown. If you don't enter a display name, then the dropdown label will be the variable name. +1. Choose a **Hide** option: + - **No selection (blank) -** The variable dropdown displays the variable **Name** or **Label** value. This is the default. + - **Label -** The variable dropdown only displays the selected variable value and a down arrow. + - **Variable -** No variable dropdown is displayed on the dashboard. + +## Enter Options + +1. In the **Data source** list, select the target data source. For more information about data sources, refer to [Add a data source]({{< relref "../../datasources/add-a-data-source.md" >}}). +1. Click **Add** to add the variable to the dashboard. + +## Create ad hoc filters + +Ad hoc filters are one of the most complex and flexible variable options available. Instead of a regular list of variable options, this variable allows you to build a dashboard-wide ad hoc query. Filters you apply in this manner are applied to all panels on the dashboard. diff --git a/docs/sources/variables/variable-types/add-constant-variable.md b/docs/sources/variables/variable-types/add-constant-variable.md new file mode 100644 index 00000000..68c68157 --- /dev/null +++ b/docs/sources/variables/variable-types/add-constant-variable.md @@ -0,0 +1,31 @@ ++++ +title = "Add a constant variable" +aliases = ["/docs/grafana/latest/variables/add-constant-variable.md"] +weight = 400 ++++ + +# Add a constant variable + +_Constant_ variables allow you to define a hidden constant. This is useful for metric path prefixes for dashboards you want to share. When you export a dashboard, constant variables are converted to import options. + +Constant variables are _not_ flexible. Each constant variable only holds one value, and it cannot be updated unless you update the variable settings. + +Constant variables are useful when you have complex values that you need to include in queries but don't want to retype in every single query. For example, if you had a server path called `i-0b6a61efe2ab843gg`, then you could replace it with a variable called `$path_gg`. + +## Enter General options + +1. Navigate to the dashboard you want to make a variable for and then click the **Dashboard settings** (gear) icon at the top of the page. +1. On the Variables tab, click **New**. +1. Enter a **Name** for your variable. +1. In the **Type** list, select **Constant**. +1. (optional) In **Label**, enter the display name of the variable dropdown. If you don't enter a display name, then the dropdown label will be the variable name. +1. Choose a **Hide** option: + - **Variable -** No variable dropdown is displayed on the dashboard. This is the default. + - **No selection (blank) -** The variable dropdown displays the variable **Name** or **Label** value. + - **Label -** The variable dropdown only displays the selected variable value and a down arrow. + +## Enter Constant options + +1. In the **Value** field, enter the variable value. You can enter letters, numbers, and symbols. You can even use wildcards if you use [raw format]({{< relref "../advanced-variable-format-options.md#raw" >}}). +1. In **Preview of values**, Grafana displays the current variable value. Review it to ensure it matches what you expect. +1. Click **Add** to add the variable to the dashboard. diff --git a/docs/sources/variables/variable-types/add-custom-variable.md b/docs/sources/variables/variable-types/add-custom-variable.md new file mode 100644 index 00000000..846e6269 --- /dev/null +++ b/docs/sources/variables/variable-types/add-custom-variable.md @@ -0,0 +1,30 @@ ++++ +title = "Add a custom variable" +aliases = ["/docs/grafana/latest/variables/add-custom-variable.md"] +weight = 200 ++++ + +# Add a custom variable + +Use a _custom_ variable for a value that does not change, such as a number or a string. + +For example, if you have server names or region names that never change, then you might want to create them as custom variables rather than query variables. Because they do not change, you might use them in [chained variables]({{< relref "chained-variables.md" >}}) rather than other query variables. That would reduce the number of queries Grafana must send when chained variables are updated. + +## Enter General options + +1. Navigate to the dashboard you want to make a variable for and then click the **Dashboard settings** (gear) icon at the top of the page. +1. On the Variables tab, click **New**. +1. Enter a **Name** for your variable. +1. In the **Type** list, select **Custom**. +1. (optional) In **Label**, enter the display name of the variable dropdown. If you don't enter a display name, then the dropdown label will be the variable name. +1. Choose a **Hide** option: + - **No selection (blank) -** The variable dropdown displays the variable **Name** or **Label** value. This is the default. + - **Label -** The variable dropdown only displays the selected variable value and a down arrow. + - **Variable -** No variable dropdown is displayed on the dashboard. + +## Enter Custom Options + +1. In the **Values separated by comma** list, enter the values for this variable in a comma-separated list. You can include numbers, strings, or key/value pairs separated by a space and a colon. For example, `key1 : value1,key2 : value2`. +1. (optional) Enter [Selection Options]({{< relref "../variable-selection-options.md" >}}). +1. In **Preview of values**, Grafana displays a list of the current variable values. Review them to ensure they match what you expect. +1. Click **Add** to add the variable to the dashboard. diff --git a/docs/sources/variables/variable-types/add-data-source-variable.md b/docs/sources/variables/variable-types/add-data-source-variable.md new file mode 100644 index 00000000..941999ea --- /dev/null +++ b/docs/sources/variables/variable-types/add-data-source-variable.md @@ -0,0 +1,29 @@ ++++ +title = "Add a data source variable" +aliases = ["/docs/grafana/latest/variables/add-data-source-variable.md"] +weight = 500 ++++ + +# Add a data source variable + +_Data source_ variables allow you to quickly change the data source for an entire dashboard. They are useful if you have multiple instances of a data source, perhaps in different environments. + +## Enter General options + +1. Navigate to the dashboard you want to make a variable for and then click the **Dashboard settings** (gear) icon at the top of the page. +1. On the Variables tab, click **New**. +1. Enter a **Name** for your variable. +1. In the **Type** list, select **Datasource**. +1. (optional) In **Label**, enter the display name of the variable dropdown. If you don't enter a display name, then the dropdown label will be the variable name. +1. Choose a **Hide** option: + - **No selection (blank) -** The variable dropdown displays the variable **Name** or **Label** value. This is the default. + - **Label -** The variable dropdown only displays the selected variable value and a down arrow. + - **Variable -** No variable dropdown is displayed on the dashboard. + +## Enter Data source options + +1. In the **Type** list, select the target data source for the variable. For more information about data sources, refer to [Add a data source]({{< relref "../../datasources/add-a-data-source.md" >}}). +1. (optional) In **Instance name filter**, enter a regex filter for which data source instances to choose from in the variable value drop-down list. Leave this field empty to display all instances. +1. (optional) Enter [Selection Options]({{< relref "../variable-selection-options.md" >}}). +1. In **Preview of values**, Grafana displays a list of the current variable values. Review them to ensure they match what you expect. +1. Click **Add** to add the variable to the dashboard. diff --git a/docs/sources/variables/variable-types/add-interval-variable.md b/docs/sources/variables/variable-types/add-interval-variable.md new file mode 100644 index 00000000..d23ca3c6 --- /dev/null +++ b/docs/sources/variables/variable-types/add-interval-variable.md @@ -0,0 +1,46 @@ ++++ +title = "Add an interval variable" +aliases = ["/docs/grafana/latest/variables/add-interval-variable.md"] +weight = 600 ++++ + +# Add an interval variable + +Use an _interval_ variable to represents time spans such as `1m`,`1h`, `1d`. You can think of them as a dashboard-wide "group by time" command. Interval variables change how the data is grouped in the visualization. You can also use the Auto Option to return a set number of data points per time span. + +You can use an interval variable as a parameter to group by time (for InfluxDB), date histogram interval (for Elasticsearch), or as a summarize function parameter (for Graphite). + +## Enter General options + +1. Navigate to the dashboard you want to make a variable for and then click the **Dashboard settings** (gear) icon at the top of the page. +1. On the Variables tab, click **New**. +1. Enter a **Name** for your variable. +1. In the **Type** list, select **Interval**. +1. (optional) In **Label**, enter the display name of the variable dropdown. If you don't enter a display name, then the dropdown label will be the variable name. +1. Choose a **Hide** option: + - **No selection (blank) -** The variable dropdown displays the variable **Name** or **Label** value. This is the default. + - **Label -** The variable dropdown only displays the selected variable value and a down arrow. + - **Variable -** No variable dropdown is displayed on the dashboard. + +## Enter Interval Options + +1. In the **Values** field, enter the time range intervals that you want to appear in the variable drop-down list. The following time units are supported: `s (seconds)`, `m (minutes)`, `h (hours)`, `d (days)`, `w (weeks)`, `M (months)`, and `y (years)`. You can also accept or edit the default values: `1m,10m,30m,1h,6h,12h,1d,7d,14d,30d`. +1. (optional) Turn on the **Auto Option** if you want to add the `auto` option to the list. This option allows you to specify how many times the current time range should be divided to calculate the current `auto` time span. If you turn it on, then two more options appear: + - **Step count -** Select the number of times the current time range will be divided to calculate the value, similar to the **Max data points** query option. For example, if the current visible time range is 30 minutes, then the `auto` interval groups the data into 30 one-minute increments. The default value is 30 steps. + - **Min Interval -** The minimum threshold below which the step count intervals will not divide the time. To continue the 30 minute example, if the minimum interval is set to 2m, then Grafana would group the data into 15 two-minute increments. +1. In **Preview of values**, Grafana displays a list of the current variable values. Review them to ensure they match what you expect. +1. Click **Add** to add the variable to the dashboard. + +## Interval variable examples + +Example using the template variable `myinterval` in a Graphite function: + +``` +summarize($myinterval, sum, false) +``` + +A more complex Graphite example, from the [Graphite Template Nested Requests panel](https://play.grafana.org/d/000000056/graphite-templated-nested?editPanel=2&orgId=1): + +``` +groupByNode(summarize(movingAverage(apps.$app.$server.counters.requests.count, 5), '$interval', 'sum', false), 2, 'sum') +``` diff --git a/docs/sources/variables/variable-types/add-query-variable.md b/docs/sources/variables/variable-types/add-query-variable.md new file mode 100644 index 00000000..947b0ba0 --- /dev/null +++ b/docs/sources/variables/variable-types/add-query-variable.md @@ -0,0 +1,44 @@ ++++ +title = "Add a query variable" +aliases = ["/docs/grafana/latest/variables/add-query-variable.md"] +weight = 100 ++++ + +# Add a query variable + +Query variables allow you to write a data source query that can return a list of metric names, tag values, or keys. For example, a query variable might return a list of server names, sensor IDs, or data centers. The variable values change as they dynamically fetch options with a data source query. + +Query variables are generally only supported for strings. If your query return numbers or any other data type, you may need to convert them to strings in order to use them as variables. For the Azure data source, for example, you can use the [tostring](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/tostringfunction) function for this purpose. + +Query expressions can contain references to other variables and in effect create linked variables. Grafana detects this and automatically refreshes a variable when one of its linked variables change. + +## Query expressions + +Query expressions are different for each data source. For more information, refer to the documentation for your [data source]({{< relref "../../datasources/_index.md" >}}). + +## Enter General options + +1. Navigate to the dashboard you want to make a variable for and then click the **Dashboard settings** (gear) icon at the top of the page. +1. On the Variables tab, click **New**. +1. Enter a **Name** for your variable. +1. In the **Type** list, select **Query**. +1. (optional) In **Label**, enter the display name of the variable dropdown. If you don't enter a display name, then the dropdown label will be the variable name. +1. Choose a **Hide** option: + - **No selection (blank) -** The variable dropdown displays the variable **Name** or **Label** value. This is the default. + - **Label -** The variable dropdown only displays the selected variable value and a down arrow. + - **Variable -** No variable dropdown is displayed on the dashboard. + +## Enter Query Options + +1. In the **Data source** list, select the target data source for the query. For more information about data sources, refer to [Add a data source]({{< relref "../../datasources/add-a-data-source.md" >}}). +1. In the **Refresh** list, select when the variable should update options. + - **On Dashboard Load -** Queries the data source every time the dashboard loads. This slows down dashboard loading, because the variable query needs to be completed before dashboard can be initialized. + - **On Time Range Change -** Queries the data source when the dashboard time range changes. Only use this option if your variable options query contains a time range filter or is dependent on the dashboard time range. +1. In the **Query** field, enter a query. + - The query field varies according to your data source. Some data sources have custom query editors. + - If you need more room in a single input field query editor, then hover your cursor over the lines in the lower right corner of the field and drag downward to expand. +1. (optional) In the **Regex** field, type a regex expression to filter or capture specific parts of the names returned by your data source query. To see examples, refer to [Filter variables with regex]({{< relref "../filter-variables-with-regex.md" >}}). +1. In the **Sort** list, select the sort order for values to be displayed in the dropdown list. The default option, **Disabled**, means that the order of options returned by your data source query will be used. +1. (optional) Enter [Selection Options]({{< relref "../variable-selection-options.md" >}}). +1. In **Preview of values**, Grafana displays a list of the current variable values. Review them to ensure they match what you expect. +1. Click **Add** to add the variable to the dashboard. diff --git a/docs/sources/variables/variable-types/add-text-box-variable.md b/docs/sources/variables/variable-types/add-text-box-variable.md new file mode 100644 index 00000000..ad35046d --- /dev/null +++ b/docs/sources/variables/variable-types/add-text-box-variable.md @@ -0,0 +1,27 @@ ++++ +title = "Add a text box variable" +aliases = ["/docs/grafana/latest/variables/add-text-box-variable.md"] +weight = 300 ++++ + +# Add a text box variable + +_Text box_ variables display a free text input field with an optional default value. This is the most flexible variable, because you can enter any value. Use this type of variable if you have metrics with high cardinality or if you want to update multiple panels in a dashboard at the same time. + +## Enter General options + +1. Navigate to the dashboard you want to make a variable for and then click the **Dashboard settings** (gear) icon at the top of the page. +1. On the Variables tab, click **New**. +1. Enter a **Name** for your variable. +1. In the **Type** list, select **Text box**. +1. (optional) In **Label**, enter the display name of the variable dropdown. If you don't enter a display name, then the dropdown label will be the variable name. +1. Choose a **Hide** option: + - **No selection (blank) -** The variable dropdown displays the variable **Name** or **Label** value. This is the default. + - **Label -** The variable dropdown only displays the selected variable value and a down arrow. + - **Variable -** No variable dropdown is displayed on the dashboard. + +## Enter Text options + +1. (optional) In the **Default value** field, select the default value for the variable. If you do not enter anything in this field, then Grafana displays an empty text box for users to type text into. +1. In **Preview of values**, Grafana displays a list of the current variable values. Review them to ensure they match what you expect. +1. Click **Add** to add the variable to the dashboard. diff --git a/docs/sources/variables/variable-types/chained-variables.md b/docs/sources/variables/variable-types/chained-variables.md new file mode 100644 index 00000000..e94091d6 --- /dev/null +++ b/docs/sources/variables/variable-types/chained-variables.md @@ -0,0 +1,173 @@ ++++ +title = "Chained variables" +keywords = ["grafana", "templating", "variable", "nested", "chained", "linked"] +aliases = ["/docs/grafana/latest/variables/chained-variables.md"] +weight = 800 ++++ + +# Chained variables + +_Chained variables_, also called _linked variables_ or _nested variables_, are query variables with one or more other variables in their variable query. This page explains how chained variables work and provides links to example dashboards that use chained variables. + +Chained variable queries are different for every data source, but the premise is the same for all. You can use chained variable queries in any data source that allows them. + +Extremely complex linked templated dashboards are possible, 5 or 10 levels deep. Technically, there is no limit to how deep or complex you can go, but the more links you have, the greater the query load. + +## Grafana Play dashboard examples + +The following Grafana Play dashboards contain fairly simple chained variables, only two layers deep. To view the variables and their settings, click **Dashboard settings** (gear icon) and then click **Variables**. Both examples are expanded in the following section. + +- [Graphite Templated Nested](https://play.grafana.org/d/000000056/graphite-templated-nested?orgId=1&var-app=country&var-server=All&var-interval=1h) +- [InfluxDB Templated](https://play.grafana.org/d/000000002/influxdb-templated?orgId=1) + +## Examples explained + +Variables are useful to reuse dashboards, dynamically change what is shown in dashboards. Chained variables are especially useful to filter what you see. + +Create parent/child relationship in variable, sort of a tree structure where you can select different levels of filters. + +The following sections explain the linked examples in the dashboards above in depth and builds on them. While the examples are data source-specific, the concepts can be applied broadly. + +### Graphite example + +In this example, you have several applications. Each application has a different subset of servers. It is based on the [Graphite Templated Nested](https://play.grafana.org/d/000000056/graphite-templated-nested?orgId=1&var-app=country&var-server=All&var-interval=1h). + +Now, you could make separate variables for each metric source, but then you have to know which server goes with which app. A better solution is to use one variable to filter another. In this example, when the user changes the value of the `app` variable, it changes the dropdown options returned by the `server` variable. Both variables use the **Multi-value** option and **Include all option**, allowing users to select some or all options presented at any time. + +#### app variable + +The query for this variable basically says, "Give me all the applications that exist." + +``` +apps.* +``` + +The values returned are `backend`, `country`, `fakesite`, and `All`. + +#### server variable + +The query for this variable basically says, "Give me all servers for the currently chosen application." + +``` +apps.$app.* +``` + +If the user selects `backend`, then the query changes to: + +``` +apps.backend.* +``` + +The query returns all servers associated with `backend`, including `backend_01`, `backend_02`, and so on. + +If the user selects `fakesite`, then the query changes to: + +``` +apps.fakesite.* +``` + +The query returns all servers associated with `fakesite`, including `web_server_01`, `web_server_02`, and so on. + +#### More variables + +> **Note:** This example is theoretical. The Graphite server used in the example does not contain CPU metrics. + +The dashboard stops at two levels, but you could keep going. For example, if you wanted to get CPU metrics for selected servers, you could copy the `server` variable and extend the query so that it reads: + +``` +apps.$app.$server.cpu.* +``` + +This query basically says, "Show me the CPU metrics for the selected server." + +Depending on what variable options the user selects, you could get queries like: + +``` +apps.backend.backend_01.cpu.* +apps.{backend.backend_02,backend_03}.cpu.* +apps.fakesite.web_server_01.cpu.* +``` + +### InfluxDB example + +In this example, you have several data centers. Each data center has a different subset of hosts. It is based on the [InfluxDB Templated](https://play.grafana.org/d/000000002/influxdb-templated?orgId=1). + +In this example, when the user changes the value of the `datacenter` variable, it changes the dropdown options returned by the `host` variable. The `host` variable uses the **Multi-value** option and **Include all option**, allowing users to select some or all options presented at any time. The `datacenter` does not use either option, so you can only select one data center at a time. + +#### datacenter variable + +The query for this variable basically says, "Give me all the data centers that exist." + +``` +SHOW TAG VALUES WITH KEY = "datacenter" +``` + +The values returned are `America`, `Africa`, `Asia`, and `Europe`. + +#### host variable + +The query for this variable basically says, "Give me all hosts for the currently chosen data center." + +``` +SHOW TAG VALUES WITH KEY = "hostname" WHERE "datacenter" =~ /^$datacenter$/ +``` + +If the user selects `America`, then the query changes to: + +``` +SHOW TAG VALUES WITH KEY = "hostname" WHERE "datacenter" =~ /^America/ +``` + +The query returns all servers associated with `America`, including `server1`, `server2`, and so on. + +If the user selects `Europe`, then the query changes to: + +``` +SHOW TAG VALUES WITH KEY = "hostname" WHERE "datacenter" =~ /^Europe/ +``` + +The query returns all servers associated with `Europe`, including `server3`, `server4`, and so on. + +#### More variables + +> **Note:** This example is theoretical. The InfluxDB server used in the example does not contain CPU metrics. + +The dashboard stops at two levels, but you could keep going. For example, if you wanted to get CPU metrics for selected hosts, you could copy the `host` variable and extend the query so that it reads: + +``` +SHOW TAG VALUES WITH KEY = "cpu" WHERE "datacenter" =~ /^$datacenter$/ AND "host" =~ /^$host$/ +``` + +This query basically says, "Show me the CPU metrics for the selected host." + +Depending on what variable options the user selects, you could get queries like: + +```bash +SHOW TAG VALUES WITH KEY = "cpu" WHERE "datacenter" =~ /^America/ AND "host" =~ /^server2/ +SHOW TAG VALUES WITH KEY = "cpu" WHERE "datacenter" =~ /^Africa/ AND "host" =~ /^server/7/ +SHOW TAG VALUES WITH KEY = "cpu" WHERE "datacenter" =~ /^Europe/ AND "host" =~ /^server3+server4/ +``` + +## Best practices and tips + +The following practices will make your dashboards and variables easier to use. + +### Creating new linked variables + +- Chaining variables create parent/child dependencies. You can envision them as a ladder or a tree. +- The easiest way to create a new chained variable is to copy the variable that you want to base the new one on. In the variable list, click the **Duplicate variable** icon to the right of the variable entry to create a copy. You can then add on to the query for the parent variable. +- New variables created this way appear at the bottom of the list. You might need to drag it to a different position in the list to get it into a logical order. + +### Variable order + +You can change the orders of variables in the dashboard variable list by clicking the up and down arrows on the right side of each entry. Grafana lists variable dropdowns left to right according to this list, with the variable at the top on the far left. + +- List variables that do not have dependencies at the top, before their child variables. +- Each variable should follow the one it is dependent on. +- Remember there is no indication in the UI of which variables have dependency relationships. List the variables in a logical order to make it easy on other users (and yourself). + +### Complexity consideration + +The more layers of dependency you have in variables, the longer it will take to update dashboards after you change variables. + +For example, if you have a series of four linked variables (country, region, server, metric) and you change a root variable value (country), then Grafana must run queries for all the dependent variables before it updates the visualizations in the dashboard. diff --git a/docs/sources/variables/variable-types/global-variables.md b/docs/sources/variables/variable-types/global-variables.md new file mode 100644 index 00000000..ab02f3ae --- /dev/null +++ b/docs/sources/variables/variable-types/global-variables.md @@ -0,0 +1,88 @@ ++++ +title = "Global variables" +keywords = ["grafana", "templating", "documentation", "guide", "template", "variable", "global", "standard"] +aliases = ["/docs/grafana/latest/variables/global-variables.md"] +weight = 900 ++++ + +# Global variables + +Grafana has global built-in variables that can be used in expressions in the query editor. This topic lists them in alphabetical order and defines them. These variables are useful in queries, dashboard links, panel links, and data links. + +## $\_\_dashboard + +> Only available in Grafana v6.7+. In Grafana 7.1, the variable changed from showing the UID of the current dashboard to the name of the current dashboard. + +This variable is the name of the current dashboard. + +## $\_\_from and $\_\_to + +Grafana has two built in time range variables: `$__from` and `$__to`. They are currently always interpolated as epoch milliseconds by default but you can control date formatting. + +> This special formatting syntax is only available in Grafana 7.1.2+ + +| Syntax | Example result | Description | +| ------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------- | +| `${__from}` | 1594671549254 | Unix millisecond epoch | +| `${__from:date}` | 2020-07-13T20:19:09.254Z | No args, defaults to ISO 8601/RFC 3339 | +| `${__from:date:iso}` | 2020-07-13T20:19:09.254Z | ISO 8601/RFC 3339 | +| `${__from:date:seconds}` | 1594671549 | Unix seconds epoch | +| `${__from:date:YYYY-MM}` | 2020-07 | Any custom [date format](https://momentjs.com/docs/#/displaying/) that does not include the `:` character | + +The above syntax works with `${__to}` as well. + +You can use this variable in URLs as well. For example, send a user to a dashboard that shows a time range from six hours ago until now: https://play.grafana.org/d/000000012/grafana-play-home?viewPanel=2&orgId=1?from=now-6h&to=now + +## $\_\_interval + +You can use the `$__interval` variable as a parameter to group by time (for InfluxDB, MySQL, Postgres, MSSQL), Date histogram interval (for Elasticsearch), or as a _summarize_ function parameter (for Graphite). + +Grafana automatically calculates an interval that can be used to group by time in queries. When there are more data points than can be shown on a graph then queries can be made more efficient by grouping by a larger interval. It is more efficient to group by 1 day than by 10s when looking at 3 months of data and the graph will look the same and the query will be faster. The `$__interval` is calculated using the time range and the width of the graph (the number of pixels). + +Approximate Calculation: `(to - from) / resolution` + +For example, when the time range is 1 hour and the graph is full screen, then the interval might be calculated to `2m` - points are grouped in 2 minute intervals. If the time range is 6 months and the graph is full screen, then the interval might be `1d` (1 day) - points are grouped by day. + +In the InfluxDB data source, the legacy variable `$interval` is the same variable. `$__interval` should be used instead. + +The InfluxDB and Elasticsearch data sources have `Group by time interval` fields that are used to hard code the interval or to set the minimum limit for the `$__interval` variable (by using the `>` syntax -> `>10m`). + +## $\_\_interval_ms + +This variable is the `$__interval` variable in milliseconds, not a time interval formatted string. For example, if the `$__interval` is `20m` then the `$__interval_ms` is `1200000`. + +## $\_\_name + +This variable is only available in the Singlestat panel and can be used in the prefix or suffix fields on the Options tab. The variable will be replaced with the series name or alias. + +## $\_\_org + +This variable is the ID of the current organization. +`${__org.name}` is the name of the current organization. + +## $\_\_user + +> Only available in Grafana v7.1+ + +`${__user.id}` is the ID of the current user. +`${__user.login}` is the login handle of the current user. +`${__user.email}` is the email for the current user. + +## $\_\_range + +Currently only supported for Prometheus and Loki data sources. This variable represents the range for the current dashboard. It is calculated by `to - from`. It has a millisecond and a second representation called `$__range_ms` and `$__range_s`. + +## $\_\_rate_interval + +Currently only supported for Prometheus data sources. The `$__rate_interval` variable is meant to be used in the rate function. Refer to [Prometheus query variables]({{< relref "../../datasources/prometheus.md">}}) for details. + +## $timeFilter or $\_\_timeFilter + +The `$timeFilter` variable returns the currently selected time range as an expression. For example, the time range interval `Last 7 days` expression is `time > now() - 7d`. + +This is used in several places, including: + +- The WHERE clause for the InfluxDB data source. Grafana adds it automatically to InfluxDB queries when in Query Editor mode. You can add it manually in Text Editor mode: `WHERE $timeFilter`. +- Log Analytics queries in the Azure Monitor data source. +- SQL queries in MySQL, Postgres, and MSSQL. +- The `$__timeFilter` variable is used in the MySQL data source. diff --git a/docs/sources/visualizations/_index.md b/docs/sources/visualizations/_index.md new file mode 100644 index 00000000..d9b8bc0d --- /dev/null +++ b/docs/sources/visualizations/_index.md @@ -0,0 +1,92 @@ ++++ +title = "Visualizations" +weight = 75 +aliases = ["/docs/grafana/latest/panels/visualizations/"] ++++ + +# Visualization panels + +Grafana offers a variety of visualizations to support different use cases. This section of the documentation highlights the built-in panels, their options and typical usage. + +> **Note:** If you are unsure which visualization to pick, Grafana can provide visualization suggestions based on the panel query. When you select a visualization, Grafana will show a preview with that visualization applied. For more information, see the [add a panel]({{< relref "../panels/add-a-panel.md" >}}) documentation. + +- Graphs & charts + - [Time series]({{< relref "./time-series/_index.md" >}}) is the default and main Graph visualization. + - [State timeline]({{< relref "./state-timeline.md" >}}) for state changes over time. + - [Status history]({{< relref "./status-history.md" >}}) for periodic state over time. + - [Bar chart]({{< relref "./bar-chart.md" >}}) shows any categorical data. + - [Histogram]({{< relref "./histogram.md" >}}) calculates and shows value distribution in a bar chart. + - [Heatmap]({{< relref "./heatmap.md" >}}) visualizes data in two dimensions, used typically for the magnitude of a phenomenon. + - [Pie chart]({{< relref "./pie-chart-panel.md" >}}) is typically used where proportionality is important. + - [Candlestick]({{< relref "./candlestick.md" >}}) is typically for financial data where the focus is price/data movement. +- Stats & numbers + - [Stat]({{< relref "./stat-panel.md" >}}) for big stats and optional sparkline. + - [Gauge]({{< relref "./gauge-panel.md" >}}) is a normal radial gauge. + - [Bar gauge]({{< relref "./bar-gauge-panel.md" >}}) is a horizontal or vertical bar gauge. +- Misc + - [Table]({{< relref "./table/_index.md" >}}) is the main and only table visualization. + - [Logs]({{< relref "./logs-panel.md" >}}) is the main visualization for logs. + - [Node Graph]({{< relref "./node-graph.md" >}}) for directed graphs or networks. +- Widgets + - [Dashboard list]({{< relref "./dashboard-list-panel.md" >}}) can list dashboards. + - [Alert list]({{< relref "./alert-list-panel.md" >}}) can list alerts. + - [Text panel]({{< relref "./text-panel.md" >}}) can show markdown and html. + - [News panel]({{< relref "./news-panel.md" >}}) can show RSS feeds. + +## Get more + +You can add more visualization types by installing panel [panel plugins](https://grafana.com/grafana/plugins/?type=panel). + +## Examples + +Below you can find some good examples for how all the visualizations in Grafana can be configured. You can also explore [play.grafana.org](https://play.grafana.org) which has a large set of demo dashboards that showcase all the different visualizations. + +### Graphs + +For time based line, area and bar charts we recommend the default [Time series]({{< relref "./time-series/_index.md" >}}) visualization. [This public demo dashboard](https://play.grafana.org/d/000000016/1-time-series-graphs?orgId=1) contains many different examples for how this visualization can be configured and styled. + +{{< figure src="/static/img/docs/time-series-panel/time_series_small_example.png" max-width="700px" caption="Time series" >}} + +For categorical data use the [Bar chart]({{< relref "./bar-chart.md" >}}) visualization. + +{{< figure src="/static/img/docs/bar-chart-panel/barchart_small_example.png" max-width="700px" caption="Bar chart" >}} + +### Big numbers & stats + +The [Stat](stat-panel/) visualization shows one large stat value with an optional graph sparkline. You can control the background or value color using thresholds or color scales. + +{{< figure src="/static/img/docs/v66/stat_panel_dark3.png" max-width="1025px" caption="Stat panel" >}} + +### Gauge + +If you want to present a value as it relates to a min and max value you have two options. First a standard [Radial Gauge]({{< relref "./gauge-panel.md" >}}) shown below. + +{{< figure src="/static/img/docs/v66/gauge_panel_cover.png" max-width="700px" >}} + +Secondly Grafana also has a horizontal or vertical [Bar gauge]({{< relref "./bar-gauge-panel.md" >}}) with three different distinct display modes. + +{{< figure src="/static/img/docs/v66/bar_gauge_lcd.png" max-width="700px" >}} + +### Table + +To show data in a table layout, use the [Table]({{< relref "./table/_index.md" >}}) visualization. + +{{< figure src="/static/img/docs/tables/table_visualization.png" max-width="700px" lightbox="true" caption="Table visualization" >}} + +### Pie chart + +Grafana now ships with an included [Pie chart]({{< relref "./pie-chart-panel.md" >}}) visualization. + +{{< figure src="/static/img/docs/pie-chart-panel/pie-chart-example.png" max-width="700px" lightbox="true" caption="Pie chart visualization" >}} + +### Heatmaps + +To show value distribution over, time use the [heatmap]({{< relref "./heatmap.md" >}}) visualization. + +{{< figure src="/static/img/docs/v43/heatmap_panel_cover.jpg" max-width="1000px" lightbox="true" caption="Heatmap" >}} + +### State timeline + +The state timeline panel visualization shows discrete state changes over time. When used with time series, the thresholds are used to turn the numerical values into discrete state regions. + +{{< figure src="/static/img/docs/v8/state_timeline_strings.png" max-width="700px" caption="state timeline with string states" >}} diff --git a/docs/sources/visualizations/alert-list-panel.md b/docs/sources/visualizations/alert-list-panel.md new file mode 100644 index 00000000..b667181a --- /dev/null +++ b/docs/sources/visualizations/alert-list-panel.md @@ -0,0 +1,49 @@ ++++ +title = "Alert list" +keywords = ["grafana", "alert list", "documentation", "panel", "alertlist"] +aliases = ["/docs/grafana/latest/reference/alertlist/", "/docs/grafana/latest/features/panels/alertlist/", "/docs/grafana/latest/panels/visualizations/alert-list-panel/"] +weight = 100 ++++ + +# Alert list + +The Alert list allows you to display your dashboards alerts. You can configure the list to show current state or recent state changes. You can read more about alerts in [Alerts overview]({{< relref "../alerting/_index.md" >}}). + +{{< figure src="/static/img/docs/v45/alert-list-panel.png" max-width="850px" >}} + +Use these settings to refine your visualization. + +## Options + +- **Show -** Choose whether the panel should display the current alert state or recent alert state changes. +- **Max Items -** Sets the maximum number of alerts to list. +- **Sort order -** Select how to order the alerts displayed: + - **Alphabetical (asc) -** Alphabetical order. + - **Alphabetical (desc) -** Reverse alphabetical order. + - **Importance -** By importance according to the following values, with 1 being the highest: + - alerting: 1 + - no_data: 2 + - pending: 3 + - ok: 4 + - paused: 5 +- **Alerts from this dashboard -** Shows alerts only from the dashboard the alert list is in. + +## Filter + +These options allow you to limit alerts shown to only those that match the query, folder, or tags you choose. + +- **Alert name -** Enter an alert name query. +- **Dashboard title -** Enter a dashboard title query. +- **Folder -** Select a folder. Only alerts from dashboards in the folder selected will be displayed. +- **Dashboard tags -** Select one or more tags. Only alerts from dashboards with one or more of the tags will be displayed. + +## State filter + +Choose which alert states to display in this panel. + +- Ok +- Paused +- No data +- Execution error +- Alerting +- Pending diff --git a/docs/sources/visualizations/annotations.md b/docs/sources/visualizations/annotations.md new file mode 100644 index 00000000..660a884a --- /dev/null +++ b/docs/sources/visualizations/annotations.md @@ -0,0 +1,72 @@ ++++ +title = "Annotations" +description = "Annotations visualization documentation" +keywords = ["grafana", "Annotations", "panel", "documentation"] +aliases = ["/docs/grafana/latest/features/panels/anotations/", "/docs/grafana/latest/panels/visualizations/annotations/"] +weight = 105 ++++ + +# Annotations + +The Annotations panel shows a list of available annotations you can use to view annotated data. Various options are available to filter the list based on tags and on the current dashboard. + +## Annotation query + +The following options control the source query for the list of annotations. + +### Query Filter + +Use the query filter to create a list of annotations from all dashboards in your organization or the current dashboard in which this panel is located. It has the following options: + +- All dashboards - List annotations from all dashboards in the current organization. +- This dashboard - Limit the list to the annotations on the current dashboard. + +### Time Range + +Use the time range option to specify whether the list should be limited to the current time range. It has the following options: + +- None - no time range limit for the annotations query. +- This dashboard - Limit the list to the time range of the dashboard where the annotation list panel is available. + +### Tags + +Use the tags option to filter the annotations by tags. You can add multiple tags in order to refine the list. + +> **Note:** Optionally, leave the tag list empty and filter on the fly by selecting tags that are listed as part of the results on the panel itself. + +### Limit + +Use the limit option to limit the number of results returned. + +## Display + +These options control additional meta-data included in the annotations panel display. + +### Show user + +Use this option to show or hide which user created the annotation. + +### Show time + +Use this option to show or hide the time the annotation creation time. + +### Show Tags + +Use this option to show or hide the tags associated with an annotation. _NB_: You can use the tags to live-filter the annotation list on the panel itself. + +## Link behavior + +### Link target + +Use this option to chose how to view the annotated data. It has the following options. + +- Panel - This option will take you directly to a full-screen view of the panel with the corresponding annotation +- Dashboard - This option will focus the annotation in the context of a complete dashboard + +### Time before + +Use this option to set the time range before the annotation. Use duration string values like "1h" = 1 hour, "10m" = 10 minutes, etc. + +### Time after + +Use this option to set the time range after the annotation. diff --git a/docs/sources/visualizations/bar-chart.md b/docs/sources/visualizations/bar-chart.md new file mode 100644 index 00000000..c918ab65 --- /dev/null +++ b/docs/sources/visualizations/bar-chart.md @@ -0,0 +1,151 @@ ++++ +title = "Bar chart" +description = "Bar chart visualization" +keywords = ["grafana", "docs", "bar chart", "panel", "barchart"] +weight = 170 +aliases = ["/docs/grafana/latest/panels/visualizations/bar-chart/"] ++++ + +# Bar chart + +This panel visualization allows you to graph categorical data. + +{{< figure src="/static/img/docs/bar-chart-panel/barchart_small_example.png" max-width="1000px" caption="Bar chart" >}} + +## Supported data formats + +Only one data frame is supported and it needs to have at least one string field that will be used as the category for an X or Y axis and one or more numerical fields. + +Example: + +| Browser | Market share | +| ------- | ------------ | +| Chrome | 50 | +| IE | 17.5 | + +If you have more than one numerical field the panel will show grouped bars. + +### Visualizing time series or multiple result sets + +If you have multiple time series or tables you first need to join them using a join or reduce transform. For example if you +have multiple time series and you want to compare their last and max value add the **Reduce** transform and specify **Max** and **Last** as options under **Calculations**. + +{{< figure src="/static/img/docs/bar-chart-panel/bar-chart-time-series-v8-0.png" max-width="1025px" caption="Bar chart time series example" >}} + +## Bar chart options + +Use these options to refine your visualization. + +### Orientation + +- **Auto** - Grafana decides the bar orientation based on what the panel dimensions. +- **Horizontal** - Will make the X axis the category axis. +- **Vertical** - Will make the Y axis the category axis. + +### Rotate bar labels + +When the graph is in vertical orientation you can use this setting to rotate the labels under the bars. Useful if the labels are long and overlap. + +### Bar label max length + +Sets the max length of the bar label. Labels longer than the max length will be truncated and `...` will be appended to the end. + +### Show values + +This controls whether values are shown on top or to the left of bars. + +- **Auto** Values will be shown if there is space +- **Always** Always show values. +- **Never** Never show values. + +### Group width + +Controls the width of groups. 1 = max with, 0 = min width. + +### Bar width + +Controls the width of bars. 1 = Max width, 0 = Min width. + +### Line width + +Controls line width of the bars. + +### Fill opacity + +Controls the fill opacity bars. + +### Gradient mode + +Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard [color scheme]({{< relref "../panels/standard-options.md#color-scheme" >}}) field option. + +Gradient appearance is influenced by the **Fill opacity** setting. + +#### None + +No gradient fill. This is the default setting. + +#### Opacity + +Transparency of the gradient is calculated based on the values on the y-axis. Opacity of the fill is increasing with the values on the Y-axis. + +#### Hue + +Gradient color is generated based on the hue of the line color. + +{{< docs/shared "visualizations/tooltip-mode.md" >}} + +{{< docs/shared "visualizations/legend-mode.md" >}} + +### Legend calculations + +Choose which of the [standard calculations]({{< relref "../panels/calculations-list.md">}}) to show in the legend. You can have more than one. + +## Text size + +Enter a **Value** to change the size of the text on your bar chart. + +## Axis + +Use the following field settings to refine how your axes display. + +Some field options will not affect the visualization until you click outside of the field option box you are editing or press Enter. + +### Placement + +Select the placement of the Y-axis. + +#### Auto + +Grafana automatically assigns Y-axis to the series. When there are two or more series with different units, then Grafana assigns the left axis to the first unit and right to the following units. + +#### Left + +Display all Y-axes on the left side. + +#### Right + +Display all Y-axes on the right side. + +#### Hidden + +Hide the Y-axes. + +### Label + +Set a Y-axis text label. + +If you have more than one Y-axis, then you can give assign different labels with an override. + +### Width + +Set a fixed width of the axis. By default, Grafana dynamically calculates the width of an axis. + +By setting the width of the axis, data whose axes types are different can share the same display proportions. This makes it easier to compare more than one graph’s worth of data because the axes are not shifted or stretched within visual proximity of each other. + +### Soft min and soft max + +Set a **Soft min** or **soft max** option for better control of Y-axis limits. By default, Grafana sets the range for the Y-axis automatically based on the dataset. + +**Soft min** and **soft max** settings can prevent blips from turning into mountains when the data is mostly flat, and hard min or max derived from standard min and max field options can prevent intermittent spikes from flattening useful detail by clipping the spikes past a defined point. + +You can set standard min/max options to define hard limits of the Y-axis. For more information, refer to [Standard field options]({{< relref "../panels/standard-options.md#max" >}}). diff --git a/docs/sources/visualizations/bar-gauge-panel.md b/docs/sources/visualizations/bar-gauge-panel.md new file mode 100644 index 00000000..d8101db0 --- /dev/null +++ b/docs/sources/visualizations/bar-gauge-panel.md @@ -0,0 +1,61 @@ ++++ +title = "Bar gauge" +description = "Bar gauge panel options" +keywords = ["grafana", "bar", "bar gauge"] +aliases = ["/docs/grafana/latest/features/panels/bar_gauge/", "/docs/grafana/latest/panels/visualizations/bar-gauge-panel/"] +weight = 200 ++++ + +# Bar gauge + +The bar gauge simplifies your data by reducing every field to a single value. You choose how Grafana calculates the reduction. + +This panel can show one or more bar gauges depending on how many series, rows, or columns your query returns. + +{{< figure src="/static/img/docs/v66/bar_gauge_cover.png" max-width="1025px" caption="Stat panel" >}} + +## Value options + +Use the following options to refine how your visualization displays the value: + +### Show + +Choose how Grafana displays your data. + +#### Calculate + +Show a calculated value based on all rows. + +- **Calculation -** Select a reducer function that Grafana will use to reduce many fields to a single value. For a list of available calculations, refer to [List of calculations]({{< relref "../panels/calculations-list.md" >}}). +- **Fields -** Select the fields display in the panel. + +#### All values + +Show a separate stat for every row. If you select this option, then you can also limit the number of rows to display. + +- **Limit -** The maximum number of rows to display. Default is 5,000. +- **Fields -** Select the fields display in the panel. + +## Bar gauge options + +Adjust how the bar gauge is displayed. + +### Orientation + +Choose a stacking direction. + +- **Auto -** Grafana selects what it thinks is the best orientation. +- **Horizontal -** Bars stretch horizontally, left to right. +- **Vertical -** Bars stretch vertically, bottom to top. + +### Display mode + +Choose a display mode. + +- **Gradient -** Threshold levels define a gradient. +- **Retro LCD -** The gauge is split into small cells that are lit or unlit. +- **Basic -** Single color based on the matching threshold. + +### Show unfilled area + +Select this if you want to render the unfilled region of the bars as dark gray. Not applicable to Retro LCD display mode. diff --git a/docs/sources/visualizations/candlestick.md b/docs/sources/visualizations/candlestick.md new file mode 100644 index 00000000..632dfb13 --- /dev/null +++ b/docs/sources/visualizations/candlestick.md @@ -0,0 +1,51 @@ ++++ +title = "Candlestick" +description = "Candlestick visualization documentation" +keywords = ["grafana", "Candlestick", "OHLC", "panel", "documentation"] +aliases = ["/docs/grafana/latest/features/panels/candlestick/", "/docs/grafana/latest/panels/visualizations/candlestick/"] +weight = 600 ++++ + +# Candlestick + +The Candlestick panel allows you to visualize data that includes a number of consistent dimensions focused on price movement. The Candlestick panel includes an Open-High-Low-Close (OHLC) mode, as well as support for additional dimensions based on time series data. + +{{< figure src="/static/img/docs/candlestick-panel/candlestick-panel-8-3.png" max-width="1200px" caption="Candlestick panel" >}} + +The Candlestick panel builds upon the foundation of the [time series]({{< relref "./time-series/_index.md" >}}) panel and includes many common configuration settings. + +## Mode + +The mode options allow you to toggle which dimensions are used for the visualization. + +- **Candles** limits the panel dimensions to the open, high, low, and close dimensions used by candlestick visualizations. +- **Volume** limits the panel dimension to the volume dimension. +- **Both** is the default behavior for the candlestick panel. It includes both candlestick and volume visualizations. + +## Candle style + +- **Candles** is the default display style and creates candle-style visualizations between the open and close dimensions. +- **OHLC Bars** displays the four core dimensions open, high, low, and close values. + +## Color strategy + +- **Since Open** is the default behavior. This mode will utilize the _Up_ color (below) if the intra-period price movement is positive. In other words, if the value on close is greater or equal to the value on open, the _Up_ color is used. +- **Since Prior Close** is an alternative display method based where the color of the candle is based on the inter-period price movement or change in value. In other words, if the value on open is greater than the previous value on close, the _Up_ color is used. If the value on open is lower than the previous value on close, the _Down_ color is used. _This option also triggers the hollow candlestick visualization mode_. Hollow candlesticks indicate that the intra-period movement is positive (value is higher on close than on open), filled candlesticks indicate the intra-period change is negative (value is lower on close than on open). To learn more, see the [explanation of the differences](https://thetradingbible.com/how-to-read-hollow-candlesticks). + +## Up & Down Colors + +The **Up color** and **Down color** options select which colors are used when the price movement is up or down. Please note that the _Color strategy_ above will determine if intra-period or inter-period price movement is used to select the candle or OHLC bar color. + +## Open, High, Low, Close + +The candlestick panel will attempt to map fields to the appropriate dimension. The **Open**, **High**, **Low**, and **Close** options allow you to map your data to these dimensions if the panel is unable to do so. + +- **Open** corresponds to the starting value of the given period. +- **High** corresponds to the highest value of the given period. +- **Low** corresponds to the lowest value of the given period. +- **Close** corresponds to the final (end) value of the given period. +- **Volume** corresponds to the sample count in the given period. (e.g. number of trades) + +## Additional fields + +The candlestick panel is based on the time series panel. It can visualization additional data dimensions beyond open, high, low, close, and volume The **Include** and **Ignore** options allow the panel to visualize other included data such as simple moving averages, Bollinger bands and more, using the same styles and configurations available in the [time series]({{< relref "./time-series/_index.md" >}}) panel. diff --git a/docs/sources/visualizations/dashboard-list-panel.md b/docs/sources/visualizations/dashboard-list-panel.md new file mode 100644 index 00000000..a77d4329 --- /dev/null +++ b/docs/sources/visualizations/dashboard-list-panel.md @@ -0,0 +1,34 @@ ++++ +title = "Dashboard list" +keywords = ["grafana", "dashboard list", "documentation", "panel", "dashlist"] +aliases = ["/docs/grafana/latest/reference/dashlist/", "/docs/grafana/latest/features/panels/dashlist/", "/docs/grafana/latest/panels/visualizations/dashboard-list-panel/"] +weight = 300 ++++ + +# Dashboard list + +The dashboard list visualization allows you to display dynamic links to other dashboards. The list can be configured to use starred dashboards, recently viewed dashboards, a search query, and dashboard tags. + +{{< figure src="/static/img/docs/v45/dashboard-list-panels.png" max-width="850px">}} + +On each dashboard load, this panel queries the dashboard list, always providing the most up-to-date results. + +## Options + +Use these options to refine your visualization. + +- **Starred -** Display starred dashboards in alphabetical order. +- **Recently viewed -** Display recently viewed dashboards in alphabetical order. +- **Search -** Display dashboards by search query or tags. You must enter at least one value in **Query** or **Tags**. For the **Query** and **Tags** fields. Variable interpolation is supported, for example,`$my_var` or `${my_var}`. +- **Show headings -** The chosen list selection (Starred, Recently viewed, Search) is shown as a heading. +- **Max items -** Sets the maximum number of items to list per section. For example, if you left this at the default value of 10 and displayed Starred and Recently viewed dashboards, then the panel would display up to 20 total dashboards, ten in each section. + +## Search + +These options only apply if the **Search** option is selected. + +- **Query -** Enter the query you want to search by. Queries are case-insensitive, and partial values are accepted. +- **Folder -** Select the dashboard folders that you want to display. +- **Tags -** Here is where you enter your tags you want to search by. Note that existing tags will not appear as you type, and they _are_ case sensitive. + +> **Note:** When multiple tags and strings appear, the dashboard list displays those matching _all_ conditions. diff --git a/docs/sources/visualizations/gauge-panel.md b/docs/sources/visualizations/gauge-panel.md new file mode 100644 index 00000000..8aa8f14a --- /dev/null +++ b/docs/sources/visualizations/gauge-panel.md @@ -0,0 +1,49 @@ ++++ +title = "Gauge" +description = "Gauge panel docs" +keywords = ["grafana", "gauge", "gauge panel"] +aliases = ["/docs/grafana/latest/features/panels/gauge/", "/docs/grafana/latest/panels/visualizations/gauge-panel/"] +weight = 400 ++++ + +# Gauge + +Gauge is a single-value visualization that can repeat a gauge for every series, column or row. + +{{< figure src="/static/img/docs/v66/gauge_panel_cover.png" max-width="1025px" >}} + +## Value options + +Use the following options to refine how your visualization displays the value: + +### Show + +Choose how Grafana displays your data. + +#### Calculate + +Show a calculated value based on all rows. + +- **Calculation -** Select a reducer function that Grafana will use to reduce many fields to a single value. For a list of available calculations, refer to [List of calculations]({{< relref "../panels/calculations-list.md" >}}). +- **Fields -** Select the fields display in the panel. + +#### All values + +Show a separate stat for every row. If you select this option, then you can also limit the number of rows to display. + +- **Limit -** The maximum number of rows to display. Default is 5,000. +- **Fields -** Select the fields display in the panel. + +## Gauge + +Adjust how the gauge is displayed. + +- **Show threshold labels -** Controls if threshold values are shown. +- **Show threshold markers -** Controls if a threshold band is shown outside the inner gauge value band. + +## Text size + +Adjust the sizes of the gauge text. + +- **Title -** Enter a numeric value for the gauge title size. +- **Value -** Enter a numeric value for the gauge value size. diff --git a/docs/sources/visualizations/geomap.md b/docs/sources/visualizations/geomap.md new file mode 100644 index 00000000..4124d468 --- /dev/null +++ b/docs/sources/visualizations/geomap.md @@ -0,0 +1,176 @@ ++++ +title = "Geomap" +description = "Geomap visualization documentation" +keywords = ["grafana", "Geomap", "panel", "documentation"] +aliases = ["/docs/grafana/latest/features/panels/geomap/", "/docs/grafana/latest/panels/visualizations/geomap/"] +weight = 600 ++++ + +# Geomap + +The Geomap panel visualization allows you to view and customize the world map using geospatial data. You can configure various overlay styles and map view settings to easily focus on the important location-based characteristics of the data. + +{{< figure src="/static/img/docs/geomap-panel/geomap-example-8-1-0.png" max-width="1200px" caption="Geomap panel" >}} + +## Map View + +The map view controls the initial view of the map when the dashboard loads. + +### Initial View + +The initial view configures how the GeoMap panel renders when the panel is first loaded. + +- **View** sets the center for the map when the panel first loads. +- **Latitude** (available when the **View** mode is _Coordinates_) +- **Longitude** (available when the **View** mode is _Coordinates_) +- **Zoom** sets the initial zoom level for the GeoMap panel. + +## Data layer + +The Geomap visualization supports multiple Data Layers. Each data layer determines how you visualize geospatial data on top of the base map. + +### Layer Types + +There are four-layer types to choose from in the Geomap visualization. + +- **Marker** renders a marker at each data point. +- **Heatmap** visualizes a heatmap of the data. +- **GeoJSON** renders static data from a geojson file. + +### Layer Controls + +The layer controls allow you to create layers, change their name, reorder and delete layers. + +- **Add layer** creates an additional, configurable data layer for the Geomap visualization. When you add a layer, you are prompted to select a layer type. You can change the layer type at any point during panel configuration. See the **Layer Types** section above for details on each layer type. +- The layer controls allow you to rename, delete, and reorder the layers of the panel. + - **Edit layer name (pencil icon)** renames the layer. + - **Trash Bin** deletes the layer. + - **Reorder (six dots/grab handle)** allows you to change the layer order. Data on higher layers will appear above data on lower layers. The panel will update the layer order as you drag and drop to help simplify choosing a layer order. + +You can add multiple layers of data to a single Geomap panel in order to create rich, detailed visualizations. + +### Location + +The Geomap panel needs a source of geographical data. This data comes from a database query, and there are four mapping options for your data. + +- **Auto** automatically searches for location data. Use this option when your query is based on one of the following names for data fields. + - geohash: “geohash” + - latitude: “latitude”, “lat” + - longitude: “longitude”, “lng”, “lon” + - lookup: “lookup” +- **Coords** specifies that your query holds coordinate data. You will get prompted to select numeric data fields for latitude and longitude from your database query. +- **Geohash** specifies that your query holds geohash data. You will get prompted to select a string data field for the geohash from your database query. +- **Lookup** specifies that your query holds location name data that needs to be mapped to a value. You will get prompted to select the lookup field from your database query and a gazetteer. The gazetteer is the directory that is used to map your queried data to a geographical point. + +### Markers layer + +The markers layer allows you to display data points as different marker shapes such as circles, squares, triangles, stars, and more. + +![Markers Layer](/static/img/docs/geomap-panel/geomap-markers-8-1-0.png) + +![Markers Layer Options](/static/img/docs/geomap-panel/geomap-markers-options-8-1-0.png) + +- **Marker Color** configures the color of the marker. The default `Fixed size` keeps all points a single color. There is an alternate option to have multiple colors depending on the data point values and the threshold set at the `Thresholds` section. +- **Marker Size** configures the size of the marker. Default is `Fixed size`, making all marker size the same regardless of the data points. However, there is also an option to scale the circles to the corresponding data points. `Min` and `Max` marker size has to be set such that the Marker layer can scale within this range. +- **Marker Shape** allows you to choose the shape, icon, or graphic to aid in providing additional visual context to your data. Choose from assets that are included with Grafana such as simple shapes or the Unicon library. You can also specify a URL containing an image asset. The image must be a scalable vector graphic (SVG). +- **Fill opacity** configures the transparency of each marker. + +### Heatmap layer + +The heatmap layer clusters various data points to visualize locations with different densities. +To add a heatmap layer: + +Click on the drop-down menu under Data Layer and choose `Heatmap`. + +Similar to `Markers`, you are prompted with various options to determine which data points to visualize and how. + +![Heatmap Layer](/static/img/docs/geomap-panel/geomap-heatmap-8-1-0.png) + +![Heatmap Layer Options](/static/img/docs/geomap-panel/geomap-heatmap-options-8-1-0.png) + +- **Weight values** configure the intensity of the heatmap clusters. `Fixed value` keeps a constant weight value throughout all data points. This value should be in the range of 0~1. Similar to Markers, there is an alternate option in the drop-down to automatically scale the weight values depending on data values. +- **Radius** configures the size of the heatmap clusters. +- **Blur** configures the amount of blur on each cluster. + +### GeoJSON layer + +The GeoJSON layer allows you to select and load a static GeoJSON file from the filesystem. + +- **GeoJSON URL** provides a choice of GeoJSON files that ship with Grafana. +- **Default Style** controls which styles to apply when no rules above match. + - **Color** configures the color of the default style + - **Opacity** configures the default opacity +- **Style Rules** apply styles based on feature properties + - **Rule** allows you to select a _feature_, _condition_, and _value_ from the GeoJSON file in order to define a rule. The trash bin icon can be used to delete the current rule. + - **Color** configures the color of the style for the current rule + - **Opacity** configures the transparency level for the current rule +- **Add style rule** creates additional style rules. + +## Base layer + +The base layer loads in a blank world map from the tile server to the Grafana panel. Several base layer options are available each with specific configuration options to style the base map. The default base layer is CartoDB base map. Custom default base layers can be defined in the `.ini` configuration file. + +![Base layer options](/static/img/docs/geomap-panel/geomap-baselayer-8-1-0.png) + +### Configure the default base layer with provisioning + +You can configure the default base map using config files with Grafana’s provisioning system. For more information on all the settings, refer to the [provisioning docs page]({{< relref "../administration/provisioning.md" >}}). + +Use the JSON configuration option `default_baselayer_config` to define the default base map. There are currently four base map options to choose from: `carto`, `esri-xyz`, `osm-standard`, `xyz`. Here are some provisioning examples for each base map option. + +- **carto** loads the CartoDB tile server. You can choose from `auto`, `dark`, and `light` theme for the base map and can be set as shown below. The `showLabels` tag determines whether or not Grafana shows the Country details on top of the map. Here is an example: + +```ini +geomap_default_baselayer = `{ + "type": "carto", + "config": { + "theme": "auto", + "showLabels": true + } +}` +``` + +- **esri-xyz** loads the ESRI tile server. There are already multiple server instances implemented to show the various map styles: `world-imagery`, `world-physical`, `topo`, `usa-topo`, and `ocean`. The `custom` server option allows you to configure your own ArcGIS map server. Here are some examples: + +```ini +geomap_default_baselayer = `{ + "type": "esri-xyz", + "config": { + "server": "world-imagery" + } +}` +``` + +```ini +geomap_default_baselayer = `{ + "type": "esri-xyz", + "config": { + "server": "custom", + "url": "[tile server url]", + "attribution": "[tile server attribution]" + } +}` +``` + +- **osm-standard** loads the OpenStreetMap tile server. There are no additional configurations needed and the `config` fields can be left blank. Here is an example: + +```ini +default_baselayer_config = `{ + "type": "osm-standard", + "config": {} +}` +``` + +- **xyz** loads a custom tile server defined by the user. Set a valid tile server `url`, with {z}/{x}/{y} for this option in order to properly load a default base map. Here is an example: + +```ini +default_baselayer_config = `{ + "type": "xyz", + "config": { + "attribution": "Open street map", + "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png" + } +}` +``` + +`enable_custom_baselayers` allows you to enable or disable custom open source base maps that are already implemented. The default is `true`. diff --git a/docs/sources/visualizations/graph-panel.md b/docs/sources/visualizations/graph-panel.md new file mode 100644 index 00000000..ac1bde7c --- /dev/null +++ b/docs/sources/visualizations/graph-panel.md @@ -0,0 +1,169 @@ ++++ +title = "Graph (old)" +keywords = ["grafana", "graph panel", "documentation", "guide", "graph"] +aliases = ["/docs/grafana/latest/reference/graph/", "/docs/grafana/latest/features/panels/graph/", "/docs/grafana/latest/panels/visualizations/graph-panel/"] +weight = 500 ++++ + +# Graph panel (old) + +> **Note:** [Time series panel]({{< relref "./time-series/_index.md" >}}) visualization is going to replace the Graph panel visualization in a future release. + +The graph panel can render metrics as a line, a path of dots, or a series of bars. This type of graph is versatile enough to display almost any time-series data. + +## Data and field options + +Graph visualizations allow you to apply: + +- [Alerts]({{< relref "../alerting/_index.md" >}}) - This is the only type of visualization that allows you to set alerts. +- [Data transformations]({{< relref "../panels/transformations/_index.md" >}}) +- [Field overrides]({{< relref "../panels/field-overrides.md" >}}) +- [Thresholds]({{< relref "../panels/thresholds.md" >}}) + +## Display options + +Use these settings to refine your visualization. + +- **Bars -** Display values as a bar chart. +- **Lines -** Display values as a line graph. +- **Line width -** The width of the line for a series. (default 1). +- **Staircase -** Draws adjacent points as staircase. +- **Area fill -** Amount of color fill for a series. (default 1, 0 is none) +- **Fill gradient -** Degree of gradient on the area fill. (0 is no gradient, 10 is a steep gradient. Default is 0.) +- **Points -** Display points for values. +- **Point radius -** Controls how large the points are. +- **Alert thresholds -** Display alert thresholds and regions on the panel. + +### Stacking and null value + +- **Stack -** Each series is stacked on top of another. +- **Percent -** Available when **Stack** is selected. Each series is drawn as a percentage of the total of all series. +- **Null value -** How null values are displayed. _This is a very important setting._ See note below. + - **connected -** If there is a gap in the series, meaning a null value or values, then the line will skip the gap and connect to the next non-null value. + - **null -** (default) If there is a gap in the series, meaning a null value, then the line in the graph will be broken and show the gap. + - **null as zero -** If there is a gap in the series, meaning a null value, then it will be displayed as a zero value in the graph panel. + +> **Note:** If you are monitoring a server's CPU load and the load reaches 100%, then the server will lock up and the agent sending statistics will not be able to collect the load statistic. This leads to a gap in the metrics and having the default as _null_ means Grafana will show the gaps and indicate that something is wrong. If this is set to _connected_, then it would be easy to miss this signal. + +### Hover tooltip + +Use these settings to change the appearance of the tooltip that appears when you hover your cursor over the graph visualization. + +- **Mode** + - **All series -** The hover tooltip shows all series in the graph. Grafana highlights the series that you are hovering over in bold in the series list in the tooltip. + - **Single -** The hover tooltip shows only a single series, the one that you are hovering over on the graph. +- **Sort order -** Sorts the order of series in the hover tooltip if you have selected **All series** mode. When you hover your cursor on a graph, Grafana displays the values associated with the lines. Generally users are most interested in the highest or lowest values. Sorting these values can make it much easier to find the data of interest. + - **None -** The order of the series in the tooltip is determined by the sort order in your query. For example, they could be alphabetically sorted by series name. + - **Increasing -** The series in the hover tooltip are sorted by value and in increasing order, with the lowest value at the top of the list. + - **Decreasing -** The series in the hover tooltip are sorted by value and in decreasing order, with the highest value at the top of the list. + +## Series overrides + +Series overrides allow a series in a graph panel to be rendered differently from the others. You can customize display options on a per-series bases or by using regex rules. For example, one series can have a thicker line width to make it stand out or be moved to the right Y-axis. + +You can add multiple series overrides. + +**Add a series override** + +1. Click **Add series override**. +1. In **Alias or regex** Type or select a series. Click in the field to see a list of available series. + + **Example:** `/Network.*/` would match two series named `Network out` and `Network in`. + +1. Click **+** and then select a style to apply to the series. You can add multiple styles to each entry. + +- **Bars -** Show series as a bar graph. +- **Lines -** Show series as line graph. +- **Line fill -** Show line graph with area fill. +- **Fill gradient -** Area fill gradient amount. +- **Line width -** Set line width. +- **Null point mode -** Option to ignore null values or replace with zero. Important if you want to ignore gaps in your data. +- **Fill below to -** Fill area between two series. +- **Staircase line -** Show series as a staircase line. +- **Dashes -** Show line with dashes. +- **Hidden Series -** Hide the series. +- **Dash Length -** Dashed line length. +- **Dash Space -** Dashed line spacing. +- **Points -** Show series as separate points. +- **Point Radius -** Radius for point rendering. +- **Stack -** Set stack group for series. +- **Color -** Set series color. +- **Y-axis -** Set series y-axis. +- **Z-index -** Set series z-index (rendering order). Important when overlaying different styles (bar charts, area charts). +- **Transform -** Transform value to negative to render below the y-axis. +- **Legend -** Control if a series is shown in legend. +- **Hide in tooltip -** Control if a series is shown in graph tooltip. + +## Axes + +Use these options to control the display of axes in the visualization. + +### Left Y/Right Y + +Options are identical for both Y-axes. + +- **Show -** Click to show or hide the axis. +- **Unit -** The display unit for the Y value. +- **Scale -** The scale to use for the Y value, linear, or logarithmic. (default linear) +- **Y-Min -** The minimum Y value. (default auto) +- **Y-Max -** The maximum Y value. (default auto) +- **Decimals -** Defines how many decimals are displayed for Y value. (default auto) +- **Label -** The Y axis label. (default “") + +### Y-Axes + +- **Align -** Select to align left and right Y-axes by value. (default unchecked/false) +- **Level -** Available when **Align** is selected. Value to use for alignment of left and right Y-axes, starting from Y=0. (default 0) + +### X-Axis + +- **Show -** Click to show or hide the axis. +- **Mode -** The display mode completely changes the visualization of the graph panel. It's like three panels in one. The main mode is the time series mode with time on the X-axis. The other two modes are a basic bar chart mode with series on the X-axis instead of time and a histogram mode. + + - **Time -** (default) The X-axis represents time and that the data is grouped by time (for example, by hour, or by minute). + - **Series -** The data is grouped by series and not by time. The Y-axis still represents the value. + - **Value -** The aggregation type to use for the values. The default is total (summing the values together). + - **Histogram -** Converts the graph into a histogram. A histogram is a kind of bar chart that groups numbers into ranges, often called buckets or bins. Taller bars show that more data falls in that range. + + For more information about histograms, refer to [Introduction to histograms and heatmaps]({{< relref "../basics/intro-histograms.md" >}}). + + - **Buckets -** The number of buckets to group the values by. If left empty, then Grafana tries to calculate a suitable number of buckets. + - **X-Min -** Filters out values from the histogram that are under this minimum limit. + - **X-Max -** Filters out values that are greater than this maximum limit. + +## Legend + +Use these settings to refine how the legend appears in your visualization. + +### Options + +- **Show -** Uncheck to hide the legend. (default checked/true) +- **As Table -** Check to display legend in table. (default checked/true) +- **To the right -** Check to display legend to the right. +- **Width -** Available when **To the right** is selected. Enter the minimum width for the legend in pixels. + +### Values + +Additional values can be shown along-side the legend names: + +- **Min -** Minimum of all values returned from the metric query. +- **Max -** Maximum of all values returned from the metric query. +- **Avg -** Average of all values returned from the metric query. +- **Current** - Last value returned from the metric query. +- **Total -** Sum of all values returned from the metric query. +- **Decimals -** Controls how many decimals are displayed for legend values and graph hover tooltips. + +The legend values are calculated on the client side by Grafana and depend on what type of aggregation or point consolidation your metric query is using. All the above legend values cannot be correct at the same time. + +For example, if you plot a rate like requests/second, this is probably using average as an aggregator, then the Total in the legend will not represent the total number of requests. It is just the sum of all data points received by Grafana. + +### Hide series + +Hide series when all values of a series from a metric query are of a specific value. + +- **With only nulls -** Value=null (default unchecked) +- **With only zeroes -** Value=zero (default unchecked) + +### Time regions + +Time regions allow you to highlight certain time regions of the graph to make it easier to see for example weekends, business hours and/or off work hours. All configured time regions refer to UTC time. diff --git a/docs/sources/visualizations/heatmap.md b/docs/sources/visualizations/heatmap.md new file mode 100644 index 00000000..6939f31d --- /dev/null +++ b/docs/sources/visualizations/heatmap.md @@ -0,0 +1,98 @@ ++++ +title = "Heatmap" +description = "Heatmap visualization documentation" +keywords = ["grafana", "heatmap", "panel", "documentation"] +aliases =["/docs/grafana/latest/features/panels/heatmap/"] +weight = 600 ++++ + +# Heatmap + +The Heatmap panel visualization allows you to view histograms over time. For more information about histograms, refer to [Introduction to histograms and heatmaps]({{< relref "../basics/intro-histograms.md" >}}). + +![](/static/img/docs/v43/heatmap_panel_cover.jpg) + +## Axes options + +Use these settings to adjust how axes are displayed in your visualization. + +### Y Axis + +- **Unit -** The display unit for the Y axis value +- **Scale -** The scale to use for the Y axis value. + - **linear -** Linear scale. + - **log (base 2) -** Logarithmic scale with base 2. + - **log (base 10) -** Logarithmic scale with base 10. + - **log (base 32) -** Logarithmic scale with base 32. + - **log (base 1024) -** Logarithmic scale with base 1024. +- **Y-Min -** The minimum Y value (default auto). +- **Y-Max -** The maximum Y value (default auto). +- **Decimals -** Number of decimals to render Y axis values with (default auto). + +### Buckets + +> **Note:** If the data format is **Time series buckets**, then this section will not be available. + +- **Y Axis Buckets -** Number of buckets Y axis will be split into. +- **Size -** (Only visible if **Scale** is _linear_). Size of each Y axis bucket. This option has priority over **Y Axis Buckets**. +- **Split Factor -** (Only visible if **Scale** is _log (base 2)_ or greater). By default Grafana splits Y values by log base. This option allows to split each default bucket into specified number of buckets. +- **X Axis Buckets -** Number of buckets X axis will be split into. +- **Size -** Size of each X axis bucket. Number or time interval (10s, 5m, 1h, etc). Supported intervals: ms, s, m, h, d, w, M, y. This option has priority over **X Axis Buckets**. + +#### Bucket bound + +When Data format is Time series buckets data source returns series with names representing bucket bound. But depending on data source, a bound may be upper or lower. This option allows to adjust a bound type. If Auto is set, a bound option will be chosen based on panels’ data source type. + +#### Bucket size + +The Bucket count and size options are used by Grafana to calculate how big each cell in the heatmap is. You can define the bucket size either by count (the first input box) or by specifying a size interval. For the Y-Axis the size interval is just a value but for the X-bucket you can specify a time interval in the Size input, for example, the time range 1h. This will make the cells 1h wide on the X-axis. + +#### Data format + +Choose an option in the **Format** list. + +- **Time series -** Grafana does the bucketing by going through all time series values. The bucket sizes and intervals are set in the Buckets options. +- **Time series buckets -** Each time series already represents a Y-Axis bucket. The time series name (alias) needs to be a numeric value representing the upper or lower interval for the bucket. Grafana does no bucketing, so the bucket size options are hidden. + +## Display options + +Use these settings to refine your visualization. + +### Colors + +The color spectrum controls the mapping between value count (in each bucket) and the color assigned to each bucket. The leftmost color on the spectrum represents the minimum count and the color on the right most side represents the maximum count. Some color schemes are automatically inverted when using the light theme. + +You can also change the color mode to Opacity. In this case, the color will not change but the amount of opacity will change with the bucket count + +- **Mode** + - **opacity -** Bucket value represented by cell opacity. Opaque cell means maximum value. + - **Color -** Cell base color. + - **Scale -** Scale for mapping bucket values to the opacity. + - **linear -** Linear scale. Bucket value maps linearly to the opacity. + - **sqrt -** Power scale. Cell opacity calculated as `value ^ k`, where `k` is a configured **Exponent** value. If exponent is less than `1`, you will get a logarithmic scale. If exponent is greater than `1`, you will get an exponential scale. In case of `1`, scale will be the same as linear. + - **Exponent -** value of the exponent, greater than `0`. + - **spectrum -** Bucket value represented by cell color. + - **Scheme -** If the mode is **spectrum**, then select a color scheme. + +### Color scale + +By default, Grafana calculates cell colors based on minimum and maximum buckets values. With Min and Max you can overwrite those values. Think of a bucket value as a Z-axis and Min and Max as Z-Min and Z-Max respectively. + +- **Min -** Minimum value using for cell color calculation. If the bucket value is less than Min, then it is mapped to the "minimum" color. Default is series min value. +- **Max -** Maximum value using for cell color calculation. If the bucket value is greater than Max, then it is mapped to the "maximum" color. Default is series max value. + +### Legend + +Choose whether to display the heatmap legend on the visualization or not. + +### Buckets + +- **Hide zero -** Do not draw cells with zero values. +- **Space -** Space in pixels between cells. Default is 1 pixel. +- **Round -** Cell roundness in pixels. Default is 0. + +### Tooltip + +- **Show tooltip -** Show heatmap tooltip. +- **Histogram -** Show Y axis histogram on the tooltip. Histogram represents distribution of the bucket values for the specific timestamp. +- **Decimals -** Number of decimals to render bucket value with (default auto). diff --git a/docs/sources/visualizations/histogram.md b/docs/sources/visualizations/histogram.md new file mode 100644 index 00000000..7def217c --- /dev/null +++ b/docs/sources/visualizations/histogram.md @@ -0,0 +1,67 @@ ++++ +title = "Histogram" +description = "Histogram visualization" +keywords = ["grafana", "docs", "bar chart", "panel", "barchart"] +aliases =["/docs/grafana/latest/features/panels/histogram/", "/docs/grafana/latest/panels/visualizations/histogram/"] +weight = 605 ++++ + +# Histogram + +The histogram visualization calculates the distribution of values and presents them as a bar chart. The Y-axis and the height of each bar represent the count of values that fall into each bracket while the X-axis represents the value range. + +{{< figure src="/static/img/docs/histogram-panel/histogram-example-v8-0.png" max-width="625px" caption="Bar chart example" >}} + +## Supported data formats + +Histogram visualization supports time series and any table results with one or more numerical fields. + +## Display options + +Use the following options to refine your visualization. + +### Bucket size + +The size of the buckets. Leave this empty for automatic bucket sizing (~10% of the full range). + +### Bucket offset + +If the first bucket should not start at zero. A non-zero offset has the effect of shifting the aggregation window. For example, 5-sized buckets that are 0-5, 5-10, 10-15 with a default 0 offset would become 2-7, 7-12, 12-17 with an offset of 2; offsets of 0, 5, or 10, in this case, would effectively do nothing. Typically, this option would be used with an explicitly defined bucket size rather than automatic. For this setting to affect, the offset amount should be greater than 0 and less than the bucket size; values outside this range will have the same effect as values within this range. + +### Combine series + +This will merge all series and fields into a combined histogram. + +### Line width + +Controls line width of the bars. + +### Fill opacity + +Controls the fill opacity bars. + +### Gradient mode + +Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard [color scheme]({{< relref "../panels/standard-options.md#color-scheme" >}}) field option. + +Gradient display is influenced by the **Fill opacity** setting. + +#### None + +No gradient fill. This is the default setting. + +#### Opacity + +Transparency of the gradient is calculated based on the values on the Y-axis. The opacity of the fill is increasing with the values on the Y-axis. + +#### Hue + +Gradient color is generated based on the hue of the line color. + +{{< docs/shared "visualizations/tooltip-mode.md" >}} + +{{< docs/shared "visualizations/legend-mode.md" >}} + +### Legend calculations + +Choose a [standard calculations]({{< relref "../panels/calculations-list.md">}}) to show in the legend. You can select more than one. diff --git a/docs/sources/visualizations/logs-panel.md b/docs/sources/visualizations/logs-panel.md new file mode 100644 index 00000000..179a25e8 --- /dev/null +++ b/docs/sources/visualizations/logs-panel.md @@ -0,0 +1,40 @@ ++++ +title = "Logs panel" +keywords = ["grafana", "dashboard", "documentation", "panels", "logs panel"] +aliases = ["/docs/grafana/latest/reference/logs/", "/docs/grafana/latest/features/panels/logs/", "/docs/grafana/latest/panels/visualizations/logs-panel/"] +weight = 700 ++++ + +# Logs panel + +The logs panel visualization shows log lines from data sources that support logs, such as Elastic, Influx, and Loki. Typically you would use this panel next to a graph panel to display the log output of a related process. + + + +The logs panel shows the result of queries that were entered in the Query tab. The results of multiple queries are merged and sorted by time. You can scroll inside the panel if the data source returns more lines than can be displayed at any one time. + +To limit the number of lines rendered, you can use the **Max data points** setting in the **Query options**. If it is not set, then the data source will usually enforce a default limit. + +## Log level + +For logs where a **level** label is specified, we use the value of the label to determine the log level and update color accordingly. If the log doesn't have a level label specified, we parse the log to find out if its content matches any of the supported expressions (see below for more information). The log level is always determined by the first match. In case Grafana is not able to determine a log level, it will be visualized with **unknown** log level. See [supported log levels and mappings of log level abbreviation and expressions]({{< relref "../explore/_index.md#log-level" >}}). + +## Log details + +Each log row has an extendable area with its labels and detected fields, for more robust interaction. Each field or label has a stats icon to display ad-hoc statistics in relation to all displayed logs. + +### Derived fields links + +By using Derived fields, you can turn any part of a log message into an internal or external link. The created link is visible as a button next to the Detected field in the Log details view. + +### Display options + +Use these settings to refine your visualization: + +- **Time -** Show or hide the time column. This is the timestamp associated with the log line as reported from the data source. +- **Unique labels -** Show or hide the unique labels column, which shows only non-common labels. +- **Common labels -** Show or hide the common labels. +- **Wrap lines -** Toggle line wrapping. +- **Prettify JSON -** Set this to `true` to pretty print all JSON logs. This setting does not affect logs in any format other than JSON. +- **Enable log details -** Toggle option to see the log details view for each log row. The default setting is true. +- **Order -** Display results in descending or ascending time order. The default is **Descending**, showing the newest logs first. Set to **Ascending** to show the oldest log lines first. diff --git a/docs/sources/visualizations/news-panel.md b/docs/sources/visualizations/news-panel.md new file mode 100644 index 00000000..020a1ea9 --- /dev/null +++ b/docs/sources/visualizations/news-panel.md @@ -0,0 +1,12 @@ ++++ +title = "News" +keywords = ["grafana", "news", "documentation", "panels", "news panel"] +aliases = ["/docs/grafana/latest/panels/visualizations/news-graph/"] +weight = 800 ++++ + +## News + +This panel visualization displays an RSS feed. By default, it displays articles from the Grafana Labs blog. + +Enter the URL of an RSS in the URL field in the Display section. This panel type does not accept any other queries. diff --git a/docs/sources/visualizations/node-graph.md b/docs/sources/visualizations/node-graph.md new file mode 100644 index 00000000..1f4ba8c4 --- /dev/null +++ b/docs/sources/visualizations/node-graph.md @@ -0,0 +1,116 @@ ++++ +title = "Node graph" +keywords = ["grafana", "dashboard", "documentation", "panels", "node graph", "directed graph"] +aliases = ["/docs/grafana/latest/panels/visualizations/node-graph/"] +weight = 850 ++++ + +# Node graph panel + +> **Note:** This panel is currently in beta. Expect changes in future releases. + +The _Node graph_ can visualize directed graphs or networks. It uses a directed force layout to effectively position the nodes, so it can display complex infrastructure maps, hierarchies, or execution diagrams. + +![Node graph panel](/static/img/docs/node-graph/node-graph-8-0.png 'Node graph') + +## Data requirements + +The Node graph panel requires specific shape of the data to be able to display its nodes and edges. This means not every data source or query can be visualized in this panel. If you want to use this as a data source developer see the section about data API. + +The Node graph visualization consists of _nodes_ and _edges_. + +- A _node_ is displayed as a circle. A node might represent an application, a service, or anything else that is relevant from an application perspective. +- An _edge_ is displayed as a line that connects two nodes. The connection might be a request, an execution, or some other relationship between the two nodes. + +Both nodes and edges can have associated metadata or statistics. The data source defines what information and values is shown, so different data sources can show different type of values or not show some values. + +### Nodes + +> **Note:** Node graph can show only 1,500 nodes. If this limit is crossed a warning will be visible in upper right corner, and some nodes will be hidden. You can expand hidden parts of the graph by clicking on the "Hidden nodes" markers in the graph. + +Usually, nodes show two statistical values inside the node and two identifiers just below the node, usually name and type. Nodes can also show another set of values as a color circle around the node, with sections of different color represents different values that should add up to 1. + +For example, you can have the percentage of errors represented by a red portion of the circle. Additional details can be displayed in a context menu which is displayed when you click on the node. There also can be additional links in the context menu that can target either other parts of Grafana or any external link. + +![Node graph navigation](/static/img/docs/node-graph/node-graph-navigation-7-4.gif 'Node graph navigation') + +### Edges + +Edges can also show statistics when you hover over the edge. Similar to nodes, you can open a context menu with additional details and links by clicking on the edge. + +The first data source supporting this visualization is X-Ray data source for it's Service map feature. For more information, refer to the [X-Ray plugin documentation](https://grafana.com/grafana/plugins/grafana-x-ray-datasource). + +## Navigating the node graph + +You can pan and zoom in or out the node graph. + +### Pan + +You can pan the view by clicking outside any node or edge and dragging your mouse. + +### Zoom in or out + +Use the buttons in the upper left corner or use the mouse wheel, touchpad scroll, together with either Ctrl or Cmd key to zoom in or out. + +### Explore hidden nodes + +The number of nodes shown at a given time is limited to maintain a reasonable visualization performance. Nodes that are not currently visible are hidden behind clickable markers that show an approximate number of hidden nodes that are connected by a particular edge. You can click on the marker to expand the graph around that node. + +![Node graph exploration](/static/img/docs/node-graph/node-graph-exploration-8-0.png 'Node graph exploration') + +### Grid view + +You can switch to the grid view to have a better overview of the most interesting nodes in the graph. Grid view shows nodes in a grid without edges and can be sorted by stats shown inside the node or by stats represented by the a colored border of the nodes. + +![Node graph grid](/static/img/docs/node-graph/node-graph-grid-8-0.png 'Node graph grid') + +To sort the nodes, click on the stats inside the legend. The marker next to the stat name shows which stat is currently used for sorting and sorting direction. + +![Node graph legend](/static/img/docs/node-graph/node-graph-legend-8-0.png 'Node graph legend') + +Click on the node and select "Show in Graph layout" option to switch back to graph layout and focus on the selected node, to show it in context of the full graph. + +![Node graph grid to default](/static/img/docs/node-graph/node-graph-grid-to-default-8-0.png 'Node graph grid to default') + +## Data API + +This visualization needs a specific shape of the data to be returned from the data source in order to correctly display it. + +Data source needs to return two data frames, one for nodes and one for edges, and you also have to set `frame.meta.preferredVisualisationType = 'nodeGraph'` on both data frames if you want them to be automatically shown in node graph in Explore. + +### Node parameters + +Required fields: + +| Field name | Type | Description | +| ---------- | ------ | --------------------------------------------------------------------------------------------- | +| id | string | Unique identifier of the node. This ID is referenced by edge in it's source and target field. | + +Optional fields: + +| Field name | Type | Description | +| ------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| title | string | Name of the node visible in just under the node. | +| subTitle | string | Additional, name, type or other identifier that will be shown right under the title. | +| mainStat | string/number | First stat shown inside the node itself. Can be either string in which case the value will be shown as it is or it can be a number in which case any unit associated with that field will be also shown. | +| secondaryStat | string/number | Same as mainStat but shown right under it inside the node. | +| arc\_\_\* | number | Any field prefixed with `arc__` will be used to create the color circle around the node. All values in these fields should add up to 1. You can specify color using `config.color.fixedColor`. | +| detail\_\_\* | string/number | Any field prefixed with `detail__` will be shown in the header of context menu when clicked on the node. Use `config.displayName` for more human readable label. | + +### Edge parameters + +Required fields: + +| Field name | Type | Description | +| ---------- | ------ | ------------------------------ | +| id | string | Unique identifier of the edge. | +| source | string | Id of the source node. | +| target | string | Id of the target. | + +Optional fields: + +| Field name | Type | Description | +| ------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| mainStat | string/number | First stat shown in the overlay when hovering over the edge. Can be either string in which case the value will be shown as it is or it can be a number in which case any unit associated with that field will be also shown | +| secondaryStat | string/number | Same as mainStat but shown right under it. | +| detail\_\_\* | string/number | Any field prefixed with `detail__` will be shown in the header of context menu when clicked on the edge. Use `config.displayName` for more human readable label. | diff --git a/docs/sources/visualizations/pie-chart-panel.md b/docs/sources/visualizations/pie-chart-panel.md new file mode 100644 index 00000000..77a38912 --- /dev/null +++ b/docs/sources/visualizations/pie-chart-panel.md @@ -0,0 +1,80 @@ ++++ +title = "Pie chart" +keywords = ["grafana", "pie chart"] +weight = 850 +aliases = ["/docs/grafana/latest/panels/visualizations/pie-chart-pane/"] ++++ + +# Pie chart + +{{< figure src="/static/img/docs/pie-chart-panel/pie-chart-example.png" max-width="1200px" lightbox="true" caption="Pie chart visualization" >}} + +The pie chart displays reduced series, or values in a series, from one or more queries, as they relate to each other, in the form of slices of a pie. The arc length, area and central angle of a slice are all proportional to the slices value, as it relates to the sum of all values. This type of chart is best used when you want a quick comparison of a small set of values in an aesthetically pleasing form. + +## Value options + +Use the following options to refine the value in your visualization. + +### Show + +Choose how much information to show. + +- **Calculate -** Reduces each value to a single value per series. +- **All values -** Displays every value from a single series. + +### Calculation + +Select a calculation to reduce each series when Calculate has been selected. For information about available calculations, refer to the [Calculation list]({{< relref "../panels/calculations-list.md" >}}). + +### Limit + +When displaying every value from a single series, this limits the number of values displayed. + +### Fields + +Select which field or fields to display in the visualization. Each field name is available on the list, or you can select one of the following options: + +- **Numeric fields -** All fields with numerical values. +- **All fields -** All fields that are not removed by transformations. +- **Time -** All fields with time values. + +## Pie chart options + +Use these options to refine how your visualization looks. + +### Pie chart type + +Select the pie chart display style. + +### Pie + +![Pie type chart](/static/img/docs/pie-chart-panel/pie-type-chart-7-5.png) + +### Donut + +![Donut type chart](/static/img/docs/pie-chart-panel/donut-type-chart-7-5.png) + +### Labels + +Select labels to display on the pie chart. You can select more than one. + +- **Name -** The series or field name. +- **Percent -** The percentage of the whole. +- **Value -** The raw numerical value. + +Labels are displayed in white over the body of the chart. You might need to select darker chart colors to make them more visible. Long names or numbers might be clipped. + +The following example shows a pie chart with **Name** and **Percent** labels displayed. + +![Pie chart labels](/static/img/docs/pie-chart-panel/pie-chart-labels-7-5.png) + +{{< docs/shared "visualizations/tooltip-mode.md" >}} + +{{< docs/shared "visualizations/legend-mode.md" >}} + +### Legend values + +Select values to display in the legend. You can select more than one. + +**Percent -** The percentage of the whole. +**Value -** The raw numerical value. diff --git a/docs/sources/visualizations/stat-panel.md b/docs/sources/visualizations/stat-panel.md new file mode 100644 index 00000000..c78d7366 --- /dev/null +++ b/docs/sources/visualizations/stat-panel.md @@ -0,0 +1,102 @@ ++++ +title = "Stat" +description = "Stat panel documentation" +keywords = ["grafana", "docs", "stat panel"] +aliases = ["/docs/grafana/latest/features/panels/stat/", "/docs/grafana/latest/features/panels/singlestat/", "/docs/grafana/latest/reference/singlestat/", "/docs/grafana/latest/panels/visualizations/stat-panel/"] +weight = 900 ++++ + +# Stat + +The Stat panel visualization shows a one large stat value with an optional graph sparkline. You can control the background or value color using thresholds. + +{{< figure src="/static/img/docs/v66/stat_panel_dark3.png" max-width="1025px" caption="Stat panel" >}} + +> **Note:** This panel replaces the Singlestat panel, which was deprecated in Grafana 7.0 and removed in Grafana 8.0. + +By default, the Stat panel displays one of the following: + +- Just the value for a single series or field. +- Both the value and name for multiple series or fields. + +You can use the **Text mode** to control whether the text is displayed or not. + +Example screenshot: + +{{< figure src="/static/img/docs/v71/stat-panel-text-modes.png" max-width="1025px" caption="Stat panel" >}} + +## Automatic layout adjustment + +The panel automatically adjusts the layout depending on available width and height in the dashboard. It automatically hides the graph (sparkline) if the panel becomes too small. + +## Value options + +Use the following options to refine how your visualization displays the value: + +### Show + +Choose how Grafana displays your data. + +#### Calculate + +Show a calculated value based on all rows. + +- **Calculation -** Select a reducer function that Grafana will use to reduce many fields to a single value. For a list of available calculations, refer to [List of calculations]({{< relref "../panels/calculations-list.md" >}}). +- **Fields -** Select the fields display in the panel. + +#### All values + +Show a separate stat for every row. If you select this option, then you can also limit the number of rows to display. + +- **Limit -** The maximum number of rows to display. Default is 5,000. +- **Fields -** Select the fields display in the panel. + +## Stat styles + +Style your visualization. + +### Orientation + +Choose a stacking direction. + +- **Auto -** Grafana selects what it thinks is the best orientation. +- **Horizontal -** Bars stretch horizontally, left to right. +- **Vertical -** Bars stretch vertically, top to bottom. + +### Text mode + +You can use the Text mode option to control what text the panel renders. If the value is not important, only the name and color is, then change the **Text mode** to **Name**. The value will still be used to determine color and is displayed in a tooltip. + +- **Auto -** If the data contains multiple series or fields, show both name and value. +- **Value -** Show only value, never name. Name is displayed in the hover tooltip instead. +- **Value and name -** Always show value and name. +- **Name -** Show name instead of value. Value is displayed in the hover tooltip. +- **None -** Show nothing (empty). Name and value are displayed in the hover tooltip. + +### Color mode + +Select a color mode. + +- **Value -** Colors only the value and graph area. +- **Background -** Colors the background as well. + +### Graph mode + +Select a graph and splarkline mode. + +- **None -** Hides the graph and only shows the value. +- **Area -** Shows the area graph below the value. This requires that your query returns a time column. + +### Text alignment + +Choose an alignment mode. + +- **Auto -** If only a single value is shown (no repeat), then the value is centered. If multiple series or rows are shown, then the value is left-aligned. +- **Center -** Stat value is centered. + +## Text size + +Adjust the sizes of the gauge text. + +- **Title -** Enter a numeric value for the gauge title size. +- **Value -** Enter a numeric value for the gauge value size. diff --git a/docs/sources/visualizations/state-timeline.md b/docs/sources/visualizations/state-timeline.md new file mode 100644 index 00000000..099b8e87 --- /dev/null +++ b/docs/sources/visualizations/state-timeline.md @@ -0,0 +1,59 @@ ++++ +title = "State timeline" +description = "State timeline visualization" +keywords = ["grafana", "docs", "state timeline", "panel"] +aliases = ["/docs/grafana/latest/panels/visualizations/state-timeline/"] +weight = 900 ++++ + +# State timeline + +The state timeline panel visualization shows discrete state changes over time. Each field or series is rendered as its unique horizontal band. State regions can either be rendered with or without values. This panel works well with string or boolean states but can also be used with time series. When used with time series, the thresholds are used to turn the numerical values into discrete state regions. + +{{< figure src="/static/img/docs/v8/state_timeline_strings.png" max-width="1025px" caption="state timeline with string states" >}} + +## State timeline options + +Use these options to refine the visualization. + +### Merge equal consecutive values + +Controls whether Grafana merges identical values if they are next to each other. + +### Show values + +Controls whether values are rendered inside the state regions. Auto will render values if there is sufficient space. + +### Align values + +Controls value alignment inside state regions. + +### Row height + +Controls how much space between rows there are. 1 = no space = 0.5 = 50% space. + +### Line width + +Controls line width of state regions. + +### Fill opacity + +Controls the opacity of state regions. + +## Value mappings + +To assign colors to boolean or string values, use [Value mappings]({{< relref "../panels/value-mappings.md" >}}). + +{{< figure src="/static/img/docs/v8/value_mappings_side_editor.png" max-width="300px" caption="Value mappings side editor" >}} + +## Time series data with thresholds + +The panel can be used with time series data as well. In this case, the thresholds are used to turn the time series into discrete colored state regions. + +{{< figure src="/static/img/docs/v8/state_timeline_time_series.png" max-width="1025px" caption="state timeline with time series" >}} + +## Legend options + +When the legend option is enabled it can show either the value mappings or the threshold brackets. To show the value mappings in the legend, it's important that the `Color scheme` option under [Standard options]({{< relref "../panels/standard-options.md" >}}) is set to `Single color` or `Classic palette`. To see the threshold brackets in the legend set the `Color scheme` to `From thresholds`. + +{{< docs/shared "visualizations/legend-mode.md" >}} diff --git a/docs/sources/visualizations/status-history.md b/docs/sources/visualizations/status-history.md new file mode 100644 index 00000000..6c44fdd3 --- /dev/null +++ b/docs/sources/visualizations/status-history.md @@ -0,0 +1,56 @@ ++++ +title = "Status history" +description = "Status history visualization" +keywords = ["grafana", "docs", "status history", "panel"] +aliases = ["/docs/grafana/latest/panels/visualizations/status-history/"] +weight = 900 ++++ + +# Status history + +The Status history visualization shows periodic states over time. Each field or series is rendered as a horizontal row. Boxes are rendered and centered around each value. + +{{< figure src="/static/img/docs/status-history-panel/status-history-example-v8-0.png" max-width="1025px" caption="Status history example" >}} + +## Supported data + +Status history visualization works with string, boolean and numerical fields or time series. A time field is required. You can use value mappings to color strings or assign text values to numerical ranges. + +## Display options + +Use these options to refine the visualization. + +### Show values + +Controls whether values are rendered inside the value boxes. Auto will render values if there is sufficient space. + +### Column width + +Controls the width of boxes. 1 = maximum space and 0 = minimum space. + +### Line width + +Controls line width of state regions. + +### Fill opacity + +Controls the opacity of state regions. + +## Value mappings + +To assign colors to boolean or string values, use the [Value mappings](< {{ refref "../value-mappings.md"}} >). + +{{< figure src="/static/img/docs/v8/value_mappings_side_editor.png" max-width="300px" caption="Value mappings side editor" >}} + +## Time series data with thresholds + +The panel can be used with time series data as well. In this case, the thresholds are used to color the boxes. You can also +use gradient color schemes to color values. + +{{< figure src="/static/img/docs/v8/state_timeline_time_series.png" max-width="1025px" caption="state timeline with time series" >}} + +## Legend options + +When the legend option is enabled it can show either the value mappings or the threshold brackets. To show the value mappings in the legend, it's important that the `Color scheme` option under [Standard options]({{< relref "../panels/standard-options.md" >}}) is set to `Single color` or `Classic palette`. To see the threshold brackets in the legend set the `Color scheme` to `From thresholds`. + +{{< docs/shared "visualizations/legend-mode.md" >}} diff --git a/docs/sources/visualizations/table/_index.md b/docs/sources/visualizations/table/_index.md new file mode 100644 index 00000000..8a43c64d --- /dev/null +++ b/docs/sources/visualizations/table/_index.md @@ -0,0 +1,101 @@ ++++ +title = "Table" +keywords = ["grafana", "dashboard", "documentation", "panels", "table panel"] +aliases = ["/docs/grafana/latest/reference/table/", "/docs/grafana/latest/features/panels/table_panel/", "/docs/grafana/next/panels/visualizations/table/table-field-options/"] +weight = 1000 ++++ + +# Table + +The table panel visualization is very flexible, supporting multiple modes for time series and for tables, annotation, and raw JSON data. This panel also provides date formatting, value formatting, and coloring options. + +{{< figure src="/static/img/docs/tables/table_visualization.png" max-width="1200px" lightbox="true" caption="Table visualization" >}} + +## Annotation support + +Annotations are not currently supported in the new table panel. This might be added back in a future release. + +## Sort column + +Click a column title to change the sort order from default to descending to ascending. Each time you click, the sort order changes to the next option in the cycle. You can only sort by one column at a time. + +![Sort descending](/static/img/docs/tables/sort-descending.png 'Sort descending') + +## Table options + +> **Note:** If you are using a table visualization created before Grafana 7.0, then you need to migrate to the new table version in order to see these options. To migrate, on the Panel tab, click **Table** visualization. Grafana updates the table version and you can then access all table options. + +### Show header + +Show or hide column names imported from your data source. + +## Column width + +By default, Grafana automatically calculates the column width based on the table size and the minimum column width. This field option can override the setting and define the width for all columns in pixels. + +For example, if you enter `100` in the field, then when you click outside the field, all the columns will be set to 100 pixels wide. + +## Minimum column width + +By default, the minimum width of the table column is 150 pixels. This field option can override that default and will define the new minimum column width for the table panel in pixels. + +For example, if you enter `75` in the field, then when you click outside the field, all the columns will scale to no smaller than 75 pixels wide. + +For small-screen devices, such as smartphones or tablets, reduce the default `150` pixel value to`50` to allow table based panels to render correctly in dashboards. + +## Column alignment + +Choose how Grafana should align cell contents: + +- Auto (default) +- Left +- Center +- Right + +## Cell display mode + +By default, Grafana automatically chooses display settings. You can override the settings by choosing one of the following options to change all fields. + +> **Note:** If you set these in the Field tab, then the display modes will apply to all fields, including the time field. Many options will work best if you set them in the Override tab. + +### Color text + +If thresholds are set, then the field text is displayed in the appropriate threshold color. + +{{< figure src="/static/img/docs/tables/color-text.png" max-width="500px" caption="Color text" class="docs-image--no-shadow" >}} + +### Color background (gradient or solid) + +If thresholds are set, then the field background is displayed in the appropriate threshold color. + +{{< figure src="/static/img/docs/tables/color-background.png" max-width="500px" caption="Color background" class="docs-image--no-shadow" >}} + +### Gradient gauge + +The threshold levels define a gradient. + +{{< figure src="/static/img/docs/tables/gradient-gauge.png" max-width="500px" caption="Gradient gauge" class="docs-image--no-shadow" >}} + +### LCD gauge + +The gauge is split up in small cells that are lit or unlit. + +{{< figure src="/static/img/docs/tables/lcd-gauge.png" max-width="500px" caption="LCD gauge" class="docs-image--no-shadow" >}} + +### JSON view + +Shows value formatted as code. If a value is an object the JSON view allowing browsing the JSON object will appear on hover. + +{{< figure src="/static/img/docs/tables/json-view.png" max-width="500px" caption="JSON view" class="docs-image--no-shadow" >}} + +### Image + +> Only available in Grafana 7.3+ + +If you have a field value that is an image URL or a base64 encoded image you can configure the table to display it as an image. + +{{< figure src="/static/img/docs/v73/table_hover.gif" max-width="900px" caption="Table hover" >}} + +## Column filter + +You can temporarily change how column data is displayed. For example, you can order values from highest to lowest or hide specific values. For more information, refer to [Filter table columns]({{< relref "./filter-table-columns.md" >}}). diff --git a/docs/sources/visualizations/table/filter-table-columns.md b/docs/sources/visualizations/table/filter-table-columns.md new file mode 100644 index 00000000..c92460a9 --- /dev/null +++ b/docs/sources/visualizations/table/filter-table-columns.md @@ -0,0 +1,37 @@ ++++ +title = "Filter table columns" +keywords = ["grafana", "table options", "documentation", "format tables", "table filter", "filter columns"] +aliases = ["/docs/grafana/latest/reference/table/", "/docs/grafana/latest/features/panels/table_panel/", "/docs/grafana/next/panels/visualizations/table/table-field-options/", "/docs/grafana/latest/panels/visualizations/table/filter-table-columns/"] +weight = 600 ++++ + +# Filter table columns + +If you turn on the **Column filter**, then you can filter table options. + +## Turn on column filtering + +1. In Grafana, navigate to the dashboard with the table with the columns that you want to filter. +1. On the table panel you want to filter, [open the panel editor]({{< relref "../../panels/panel-editor.md#open-the-panel-editor" >}}). +1. Click the **Field** tab. +1. In Table options, turn on the **Column filter** option. + +A filter icon appears next to each column title. + +{{< figure src="/static/img/docs/tables/column-filter-with-icon.png" max-width="500px" caption="Column filtering turned on" class="docs-image--no-shadow" >}} + +## Filter column values + +To filter column values, click the filter (funnel) icon next to a column title. Grafana displays the filter options for that column. + +{{< figure src="/static/img/docs/tables/filter-column-values.png" max-width="500px" caption="Filter column values" class="docs-image--no-shadow" >}} + +Click the check box next to the values that you want to display. Enter text in the search field at the top to show those values in the display so that you can select them rather than scroll to find them. + +## Clear column filters + +Columns with filters applied have a blue funnel displayed next to the title. + +{{< figure src="/static/img/docs/tables/filtered-column.png" max-width="500px" caption="Filtered column" class="docs-image--no-shadow" >}} + +To remove the filter, click the blue funnel icon and then click **Clear filter**. diff --git a/docs/sources/visualizations/text-panel.md b/docs/sources/visualizations/text-panel.md new file mode 100644 index 00000000..b3afe3af --- /dev/null +++ b/docs/sources/visualizations/text-panel.md @@ -0,0 +1,12 @@ ++++ +title = "Text" +keywords = ["grafana", "text", "documentation", "panel"] +aliases = ["/docs/grafana/latest/reference/alertlist/", "/docs/grafana/latest/features/panels/text/", "/docs/grafana/latest/panels/visualizations/text-panel/"] +weight = 1100 ++++ + +# Text + +The text panel visualization lets you make information and description panels for your dashboards. + +In **Mode**, select whether you want to use markdown or HTML to style your text, then enter content in the box below. Grafana includes a title and paragraph to help you get started, or you can paste content in from another editor. diff --git a/docs/sources/visualizations/time-series/_index.md b/docs/sources/visualizations/time-series/_index.md new file mode 100644 index 00000000..de68030d --- /dev/null +++ b/docs/sources/visualizations/time-series/_index.md @@ -0,0 +1,40 @@ ++++ +title = "Time series" +keywords = ["grafana", "graph panel", "time series panel", "documentation", "guide", "graph"] +aliases = ["/docs/grafana/latest/panels/visualizations/time-series/"] +weight = 1200 ++++ + +# Time series + +{{< figure src="/static/img/docs/time-series-panel/time_series_small_example.png" max-width="1200px" caption="Time series" >}} + +Time series visualization is the default and primary way to visualize time series data. It can render as a line, a path of dots, or a series of bars. It is versatile enough to display almost any time-series data. [ This public demo dashboard](https://play.grafana.org/d/000000016/1-time-series-graphs?orgId=1) contains many different examples for how this visualization can be configured and styled. + +> **Note:** You can migrate Graph panel visualizations to Time series visualizations. To migrate, open the panel and then select the **Time series** visualization. Grafana transfers all applicable settings. + +## Common time series options + +These options are available whether you are graphing your time series as lines, bars, or points. + +{{< docs/shared "visualizations/tooltip-mode.md" >}} + +{{< docs/shared "visualizations/legend-mode.md" >}} + +### Legend calculations + +Choose which of the [standard calculations]({{< relref "../../panels/calculations-list.md">}}) to show in the legend. You can have more than one. + +## Graph styles + +Use these options to choose how to display your time series data. + +- [Graph time series as lines]({{< relref "./graph-time-series-as-lines.md" >}}) +- [Graph time series as bars]({{< relref "./graph-time-series-as-bars.md" >}}) +- [Graph time series as points]({{< relref "./graph-time-series-as-points.md" >}}) +- [Graph stacked time series]({{< relref "./graph-time-series-stacking.md" >}}) +- [Graph and color schemes]({{< relref "./graph-color-scheme.md" >}}) + +## Axis + +For more information about adjusting your time series axes, refer to [Change axis display]({{< relref "change-axis-display.md" >}}). diff --git a/docs/sources/visualizations/time-series/annotate-time-series.md b/docs/sources/visualizations/time-series/annotate-time-series.md new file mode 100644 index 00000000..cc7059eb --- /dev/null +++ b/docs/sources/visualizations/time-series/annotate-time-series.md @@ -0,0 +1,42 @@ ++++ +title = "Annotate time series" +keywords = ["grafana", "time series panel", "documentation", "guide", "graph", "annotations"] +aliases = ["/docs/grafana/latest/panels/visualizations/time-series/annotate-time-series/"] +weight = 100 ++++ + +# Annotate time series + +This section explains how to create annotations in the Time series panel. To read more about annotations support in Grafana please refer to [Annotations]({{< relref "../../dashboards/annotations.md" >}}). + +## Add annotation + +1. In the dashboard click on the Time series panel. A context menu will appear. +1. In the context menu click on **Add annotation**. + ![Add annotation context menu](/static/img/docs/time-series-panel/time-series-annotations-context-menu.png) +1. Add an annotation description and tags(optional). + ![Add annotation popover](/static/img/docs/time-series-panel/time-series-annotations-add-annotation.png) +1. Click save. + +Alternatively, to add an annotation, Ctrl/Cmd+Click on the Time series panel and the Add annotation popover will appear + +## Add region annotation + +1. In the dashboard Ctrl/Cmd+click and drag on the Time series panel. + ![Add annotation popover](/static/img/docs/time-series-panel/time-series-annotations-add-region-annotation.gif) +1. Add an annotation description and tags(optional). +1. Click save. + +## Edit annotation + +1. In the dashboard hover over an annotation indicator on the Time series panel. + ![Add annotation popover](/static/img/docs/time-series-panel/time-series-annotations-edit-annotation.gif) +1. Click on the pencil icon in the annotation tooltip. +1. Modify the description and/or tags. +1. Click save. + +## Delete annotation + +1. In the dashboard hover over an annotation indicator on the Time series panel. + ![Add annotation popover](/static/img/docs/time-series-panel/time-series-annotations-edit-annotation.gif) +1. Click on the trash icon in the annotation tooltip. diff --git a/docs/sources/visualizations/time-series/change-axis-display.md b/docs/sources/visualizations/time-series/change-axis-display.md new file mode 100644 index 00000000..3c370ad3 --- /dev/null +++ b/docs/sources/visualizations/time-series/change-axis-display.md @@ -0,0 +1,82 @@ ++++ +title = "Change axis display" +keywords = ["grafana", "time series panel", "documentation", "guide", "graph"] +aliases = ["/docs/grafana/latest/panels/visualizations/time-series/change-axis-display/"] +weight = 400 ++++ + +# Change axis display + +> **Note:** This is a beta feature. Time series panel is going to replace the Graph panel in the future releases. + +This section explains how to use Time series field options to control the display of axes in the visualization and illustrates what the axis options do. + +Use the following field settings to refine how your axes display. + +Some field options will not affect the visualization until you click outside of the field option box you are editing or press Enter. + +## Placement + +Select the placement of the Y-axis. + +### Auto + +Grafana automatically assigns Y-axis to the series. When there are two or more series with different units, then Grafana assigns the left axis to the first unit and right to the following units. + +### Left + +Display all Y-axes on the left side. + +![Left Y-axis example](/static/img/docs/time-series-panel/axis-placement-left-7-4.png) + +### Right + +Display all Y-axes on the right side. + +![Right Y-axis example](/static/img/docs/time-series-panel/axis-placement-right-7-4.png) + +### Hidden + +Hide the Y-axes. + +![Hidden Y-axis example](/static/img/docs/time-series-panel/axis-placement-hidden-7-4.png) + +## Label + +Set a Y-axis text label. + +![Label example](/static/img/docs/time-series-panel/label-example-7-4.png) + +If you have more than one Y-axis, then you can give assign different labels in the Override tab. + +## Width + +Set a fixed width of the axis. By default, Grafana dynamically calculates the width of an axis. + +By setting the width of the axis, data whose axes types are different can share the same display proportions. This makes it easier to compare more than one graph’s worth of data because the axes are not shifted or stretched within visual proximity of each other. + +## Soft min and soft max + +Set a **Soft min** or **soft max** option for better control of Y-axis limits. By default, Grafana sets the range for the Y-axis automatically based on the dataset. + +**Soft min** and **soft max** settings can prevent blips from turning into mountains when the data is mostly flat, and hard min or max derived from standard min and max field options can prevent intermittent spikes from flattening useful detail by clipping the spikes past a defined point. + +You can set standard min/max options to define hard limits of the Y-axis. For more information, refer to [Standard field options]({{< relref "../../panels/standard-options.md#max" >}}). + +![Label example](/static/img/docs/time-series-panel/axis-soft-min-max-7-4.png) + +## Scale + +Set the scale to use for the Y-axis values. + +### Linear + +Use scale divided into equal parts. + +### Logarithmic + +Use a logarithmic scale. When this option is chosen, a list appears where you can choose binary (base 2) or common (base 10) logarithmic scale. + +## Axis examples + +For examples, refer to the Grafana Play dashboard [New Features in v7.4](https://play.grafana.org/d/nP8rcffGk/new-features-in-v7-4?orgId=1). diff --git a/docs/sources/visualizations/time-series/graph-color-scheme.md b/docs/sources/visualizations/time-series/graph-color-scheme.md new file mode 100644 index 00000000..f73b30dc --- /dev/null +++ b/docs/sources/visualizations/time-series/graph-color-scheme.md @@ -0,0 +1,50 @@ ++++ +title = "Graph and color schemes " +keywords = ["grafana", "time series panel", "documentation", "guide", "graph"] +aliases = ["/docs/grafana/latest/panels/visualizations/time-series/graph-color-scheme/"] +weight = 400 ++++ + +{{< figure src="/static/img/docs/v73/color_scheme_dropdown.png" max-width="350px" caption="Color scheme" class="pull-right" >}} + +# Graph and color schemes + +Under [Standard options]({{< relref "../../panels/standard-options.md" >}}) you find the [Color scheme]({{< relref "../../panels/standard-options.md#color-scheme" >}}) option. This option controls series are assigned their color. + +## Classic palette + +The most common setup is to use the **Classic palette** for graphs. This scheme will automatically assign a color for each field or series based on it's order. So if the order of a field change in your query the color will also change. You can manually configure a color for a specific field using an override rule. + +## Single color + +Use this mode to set a specific color. You can also click the colored line icon next to each series in the Legend to open the color picker. This will automatically create new override that sets the color scheme to single color and the selected color. + +## By value color schemes + +> **Note:** Starting in v8.1 the Time series panel now supports by value color schemes like **From thresholds** of the gradient color schemes. + +If you select a by value color scheme like **From thresholds (by value)** or **Green-Yellow-Red (by value)** another option named **Color series by** will show up. This option control what value (Last, Min, Max) to use to assign the series its color. + +## Scheme gradient mode + +The **Gradient mode** option located under the **Graph styles** has a mode named **Scheme**. When this mode is enabled the whole line or bar gets a gradient color defined from the selected **Color scheme**. + +### From thresholds + +If the **Color scheme** is set to **From thresholds (by value)** and **Gradient mode** is set to **Scheme** then the line or bar color will change as they cross the thresholds defined. + +{{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_thresholds_line.png" max-width="1200px" caption="Colors scheme: From thresholds" >}} + +If you have enabled bars mode it would look like this: + +{{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_thresholds_bars.png" max-width="1200px" caption="Color scheme: From thresholds" >}} + +### Gradient color schemes + +If you have a selected a **Color scheme** like **Green-Yellow-Red (by value)** then it would look like this: + +{{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_line.png" max-width="1200px" caption="Color scheme: Green-Yellow-Red" >}} + +If you have enabled bars mode it would look like this: + +{{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_bars.png" max-width="1200px" caption="Color scheme: Green-Yellow-Red" >}} diff --git a/docs/sources/visualizations/time-series/graph-time-series-as-bars.md b/docs/sources/visualizations/time-series/graph-time-series-as-bars.md new file mode 100644 index 00000000..a95e2091 --- /dev/null +++ b/docs/sources/visualizations/time-series/graph-time-series-as-bars.md @@ -0,0 +1,146 @@ ++++ +title = "Graph time series as bars" +keywords = ["grafana", "time series panel", "documentation", "guide", "graph"] +aliases = ["/docs/grafana/latest/panels/visualizations/time-series/graph-time-series-as-bars/"] +weight = 200 ++++ + +# Graph time series as bars + +This section explains how to use Time series field options to visualize time series data as bars and illustrates what the options do. + +## Create the panel + +1. [Add a panel]({{< relref "../../panels/add-a-panel.md" >}}). Select the [Time series]({{< relref "_index.md" >}}) visualization. +2. In the [Panel editor]({{< relref "../../panels/panel-editor.md" >}}) side pane, click **Graph styles** to expand it. +3. In Style, click **Bars**. + +## Style the bars + +Use the following field settings to refine your visualization. + +Some field options will not affect the visualization until you click outside of the field option box you are editing or press Enter. + +### Bar alignment + +Set the position of the bar relative to a data point. In the examples below, **Show points** is set to **Always** to make it easier to see the difference this setting makes. The points do not change; the bars change in relationship to the points. + +#### Before + +![Bar alignment before icon](/static/img/docs/time-series-panel/bar-alignment-icon-before-7-4.png) + +The bar is drawn before the point. The point is placed on the trailing corner of the bar. + +![Bar alignment before example](/static/img/docs/time-series-panel/bar-alignment-before-7-4.png) + +#### Center + +![Bar alignment center icon](/static/img/docs/time-series-panel/bar-alignment-icon-center-7-4.png) + +The bar is drawn around the point. The point is placed in the center of the bar. This is the default. + +![Bar alignment center](/static/img/docs/time-series-panel/bar-alignment-center-7-4.png) + +#### After + +![Bar alignment after icon](/static/img/docs/time-series-panel/bar-alignment-icon-after-7-4.png) + +The bar is drawn after the point. The point is placed on the leading corner of the bar. + +![Bar alignment after](/static/img/docs/time-series-panel/bar-alignment-after-7-4.png) + +### Line width + +Set the thickness of the lines bar outlines, from 0 to 10 pixels. **Fill opacity** is set to 10 in the examples below. + +Line thickness set to 1: + +![Line thickness 1 example](/static/img/docs/time-series-panel/bar-graph-thickness-1-7-4.png) + +Line thickness set to 7: + +![Line thickness 7 example](/static/img/docs/time-series-panel/bar-graph-thickness-7-7-4.png) + +### Fill opacity + +Set the opacity of the bar fill, from 0 to 100 percent. In the examples below, the **Line width** is set to 1. + +Fill opacity set to 20: + +![Fill opacity 20 example](/static/img/docs/time-series-panel/bar-graph-opacity-20-7-4.png) + +Fill opacity set to 95: + +![Fill opacity 95 example](/static/img/docs/time-series-panel/bar-graph-opacity-95-7-4.png) + +### Gradient mode + +Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard [color scheme]({{< relref "../../panels/standard-options.md#color-scheme" >}}) field option. + +Gradient appearance is influenced by the **Fill opacity** setting. In the screenshots below, **Fill opacity** is set to 50. + +#### None + +No gradient fill. This is the default setting. + +![Gradient mode none example](/static/img/docs/time-series-panel/bar-graph-gradient-none-7-4.png) + +#### Opacity + +Transparency of the gradient is calculated based on the values on the y-axis. Opacity of the fill is increasing with the values on the Y-axis. + +![Gradient mode opacity example](/static/img/docs/time-series-panel/bar-graph-gradient-opacity-7-4.png) + +#### Hue + +Gradient color is generated based on the hue of the line color. + +![Gradient mode hue example](/static/img/docs/time-series-panel/bar-graph-gradient-hue-7-4.png) + +#### Scheme + +In this mode the whole bar will use a color gradient defined by your [Color scheme]({{< relref "../../panels/standard-options.md#color-scheme" >}}) option. There is more information on this option in [Graph and color scheme]({{< relref "./graph-color-scheme.md" >}}). + +{{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_bars.png" max-width="1200px" caption="Gradient color scheme mode" >}} + +### Show points + +Choose when the points should be shown on the graph + +#### Auto + +Grafana automatically decides whether or not to show the points depending on the density of the data. If the density is low, then points are shown. + +#### Always + +Show the points no matter how dense the data set is. This example uses a **Line width** of 1. If the line width is thicker than the point size, then the line obscures the points. + +##### Point size + +Set the size of the points, from 1 to 40 pixels in diameter. + +Point size set to 6: + +![Show points point size 6 example](/static/img/docs/time-series-panel/bar-graph-show-points-6-7-4.png) + +Point size set to 20: + +![Show points point size 20 example](/static/img/docs/time-series-panel/bar-graph-show-points-20-7-4.png) + +#### Never + +Never show the points. + +![Show points point never example](/static/img/docs/time-series-panel/bar-graph-show-points-never-7-4.png) + +{{< docs/shared "visualizations/stack-series-link.md" >}} + +{{< docs/shared "visualizations/change-axis-link.md" >}} + +## Bar graph examples + +Below are some bar graph examples to give you ideas. + +### Hue gradient + +![Bars with hue gradient example](/static/img/docs/time-series-panel/bars-with-hue-gradient-7-4.png) diff --git a/docs/sources/visualizations/time-series/graph-time-series-as-lines.md b/docs/sources/visualizations/time-series/graph-time-series-as-lines.md new file mode 100644 index 00000000..dbb4760d --- /dev/null +++ b/docs/sources/visualizations/time-series/graph-time-series-as-lines.md @@ -0,0 +1,240 @@ ++++ +title = "Graph time series as lines" +keywords = ["grafana", "time series panel", "documentation", "guide", "graph"] +aliases = ["/docs/grafana/latest/panels/visualizations/time-series/graph-time-series-as-lines/"] +weight = 200 ++++ + +# Graph time series as lines + +This section explains how to use Time series field options to visualize time series data as lines and illustrates what the options do. + +## Create the panel + +1. [Add a panel]({{< relref "../../panels/add-a-panel.md" >}}). Select the [Time series]({{< relref "_index.md" >}}) visualization. +1. In the [Panel editor]({{< relref "../../panels/panel-editor.md" >}}) side pane, click **Graph styles** to expand it. +1. In Style, click **Lines**. + +## Style the lines + +Use the following field settings to refine your visualization. + +Some field options will not affect the visualization until you click outside of the field option box you are editing or press Enter. + +### Line interpolation + +Choose how Grafana interpolates the series line. The screenshots below show the same data displayed with different line interpolations. + +#### Linear + +![Linear interpolation icon](/static/img/docs/time-series-panel/interpolation-icon-linear-7-4.png) + +Points are joined by straight lines. + +![Linear interpolation example](/static/img/docs/time-series-panel/interpolation-linear-7-4.png) + +#### Smooth + +![Smooth interpolation icon](/static/img/docs/time-series-panel/interpolation-icon-smooth-7-4.png) + +Points are joined by curved lines resulting in smooth transitions between points. + +![Smooth interpolation example](/static/img/docs/time-series-panel/interpolation-smooth-7-4.png) + +#### Step before + +![Step before interpolation icon](/static/img/docs/time-series-panel/interpolation-icon-step-before-7-4.png) + +The line is displayed as steps between points. Points are rendered at the end of the step. + +![Step before interpolation example](/static/img/docs/time-series-panel/interpolation-step-before-7-4.png) + +#### Step after + +![Step after interpolation icon](/static/img/docs/time-series-panel/interpolation-icon-step-after-7-4.png) + +Line is displayed as steps between points. Points are rendered at the beginning of the step. + +![Step after interpolation example](/static/img/docs/time-series-panel/interpolation-step-after-7-4.png) + +### Line width + +Set the thickness of the series line, from 0 to 10 pixels. + +Line thickness set to 1: + +![Line thickness 1 example](/static/img/docs/time-series-panel/line-graph-thickness-1-7-4.png) + +Line thickness set to 7: + +![Line thickness 7 example](/static/img/docs/time-series-panel/line-graph-thickness-7-7-4.png) + +### Fill opacity + +Set the opacity of the series fill, from 0 to 100 percent. + +Fill opacity set to 20: + +![Fill opacity 20 example](/static/img/docs/time-series-panel/line-graph-opacity-20-7-4.png) + +Fill opacity set to 95: + +![Fill opacity 95 example](/static/img/docs/time-series-panel/line-graph-opacity-95-7-4.png) + +### Gradient mode + +Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard [color scheme]({{< relref "../../panels/standard-options.md#color-scheme" >}}) field option. + +Gradient appearance is influenced by the **Fill opacity** setting. In the screenshots below, **Fill opacity** is set to 50. + +#### None + +No gradient fill. This is the default setting. + +![Gradient mode none example](/static/img/docs/time-series-panel/line-graph-gradient-none-7-4.png) + +#### Opacity + +Transparency of the gradient is calculated based on the values on the y-axis. Opacity of the fill is increasing with the values on the Y-axis. + +![Gradient mode opacity example](/static/img/docs/time-series-panel/line-graph-gradient-opacity-7-4.png) + +#### Hue + +Gradient color is generated based on the hue of the line color. + +![Gradient mode hue example](/static/img/docs/time-series-panel/line-graph-gradient-hue-7-4.png) + +#### Scheme + +In this mode the whole line will use a color gradient defined by your [Color scheme]({{< relref "../../panels/standard-options.md#color-scheme" >}}) option. There is more information on this option in [Graph and color scheme]({{< relref "./graph-color-scheme.md" >}}). + +{{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_line.png" max-width="1200px" caption="Gradient mode scheme" >}} + +### Line style + +Set the style of the line. To change the color, use the standard [color scheme]({{< relref "../../panels/standard-options.md#color-scheme" >}}) field option. + +Line style appearance is influenced by the **Line width** and **Fill opacity** settings. In the screenshots below, **Line width** is set to 3 and **Fill opacity** is set to 20. + +#### Solid + +Display solid line. This is the default setting. + +![Line style solid example](/static/img/docs/time-series-panel/line-graph-line-style-solid-7-4.png) + +#### Dash + +Display a dashed line. When you choose this option, a list appears so that you can select the length and gap (length, gap) for the line dashes. + +Dash spacing set to 10, 10 (default): + +![Line style dashed 10, 10 example](/static/img/docs/time-series-panel/line-graph-line-style-dashed-10-10-7-4.png) + +Dash spacing set to 10, 30: + +![Line style dashed 10, 30 example](/static/img/docs/time-series-panel/line-graph-line-style-dashed-10-30-7-4.png) + +Dash spacing set to 40, 10: + +![Line style dashed 40, 10 example](/static/img/docs/time-series-panel/line-graph-line-style-dashed-40-10-7-4.png) + +#### Dots + +Display dotted lines. When you choose this option, a list appears so that you can select the gap (length = 0, gap) for the dot spacing. + +Dot spacing set to 0, 10 (default): + +![Line style dots 0, 10 example](/static/img/docs/time-series-panel/line-graph-line-style-dots-0-10-7-4.png) + +Dot spacing set to 0, 30: + +![Line style dots 0, 30 example](/static/img/docs/time-series-panel/line-graph-line-style-dots-0-30-7-4.png) + +### Connect null values + +Choose how null values (gaps in the data) are displayed on the graph. Null values can be connected to form a continuous line or, optionally, set a threshold above which gaps in the data should no longer be connected. + +![Image name](/static/img/docs/time-series-panel/connect-null-values-8-0.png) + +#### Never + +Time series data points with gaps in the the data are never connected. + +#### Always + +Time series data points with gaps in the the data are always connected. + +#### Threshold + +A threshold can be set above which gaps in the data should no longer be connected. This can be useful when the connected gaps in the data are of a known size and/or within a known range and gaps outside this range should no longer be connected. + +![Image name](/static/img/docs/time-series-panel/connect-null-values-8-0.png) + +### Show points + +Choose when the points should be shown on the graph. + +#### Auto + +Grafana automatically decides whether or not to show the points depending on the density of the data. If the density is low, then points are shown. + +#### Always + +Show the points no matter how dense the data set is. This example uses a **Line width** of 1 and 50 data points. If the line width is thicker than the point size, then the line obscures the points. + +##### Point size + +Set the size of the points, from 1 to 40 pixels in diameter. + +Point size set to 4: + +![Show points point size 4 example](/static/img/docs/time-series-panel/line-graph-show-points-4-7-4.png) + +Point size set to 10: + +![Show points point size 10 example](/static/img/docs/time-series-panel/line-graph-show-points-10-7-4.png) + +#### Never + +Never show the points. + +![Show points point never example](/static/img/docs/time-series-panel/line-graph-show-points-never-7-4.png) + +{{< docs/shared "visualizations/stack-series-link.md" >}} + +{{< docs/shared "visualizations/change-axis-link.md" >}} + +## Fill below to + +This option is only available as in the Overrides tab. + +Fill the area between two series. On the Overrides tab: + +1. Select the fields to fill below. +1. In **Add override property**, select **Fill below to**. +1. Select the series that you want the fill to stop at. + +A-series filled below to B-series: + +![Fill below to example](/static/img/docs/time-series-panel/line-graph-fill-below-to-7-4.png) + +## Line graph examples + +Below are some line graph examples to give you ideas. + +### Various line styles + +This is a graph with different line styles and colors applied to each series and zero fill. + +![Various line styles example](/static/img/docs/time-series-panel/various-line-styles-7-4.png) + +### Interpolation modes examples + +![Interpolation modes example](/static/img/docs/time-series-panel/interpolation-modes-examples-7-4.png) + +### Fill below example + +This graph shows three series: Min, Max, and Value. The Min and Max series have **Line width** set to 0. Max has a **Fill below to** override set to Min, which fills the area between Max and Min with the Max line color. + +![Fill below example](/static/img/docs/time-series-panel/fill-below-to-7-4.png) diff --git a/docs/sources/visualizations/time-series/graph-time-series-as-points.md b/docs/sources/visualizations/time-series/graph-time-series-as-points.md new file mode 100644 index 00000000..ac5f0852 --- /dev/null +++ b/docs/sources/visualizations/time-series/graph-time-series-as-points.md @@ -0,0 +1,42 @@ ++++ +title = "Graph time series as points" +keywords = ["grafana", "time series panel", "documentation", "guide", "graph"] +aliases = ["/docs/grafana/latest/panels/visualizations/time-series/graph-time-series-as-points/"] +weight = 300 ++++ + +# Graph time series as points + +This section explains how to use Time series field options to visualize time series data as points and illustrates what the options do. + +## Create the panel + +1. [Add a panel]({{< relref "../../panels/add-a-panel.md" >}}). Select the [Time series]({{< relref "_index.md" >}}) visualization. +1. In the [Panel editor]({{< relref "../../panels/panel-editor.md" >}}) side pane, click **Graph styles** to expand it. +1. In Style, click **Points**. + +## Style the points + +Use the following field settings to refine your visualization. + +Some field options will not affect the visualization until you click outside of the field option box you are editing or press Enter. + +### Point size + +Set the size of the points, from 1 to 40 pixels in diameter. + +Point size set to 6: + +![Show points point size 6 example](/static/img/docs/time-series-panel/points-graph-show-points-6-7-4.png) + +Point size set to 20: + +![Show points point size 20 example](/static/img/docs/time-series-panel/points-graph-show-points-20-7-4.png) + +Point size set to 35: + +![Show points point size 35 example](/static/img/docs/time-series-panel/points-graph-show-points-35-7-4.png) + +{{< docs/shared "visualizations/stack-series-link.md" >}} + +{{< docs/shared "visualizations/change-axis-link.md" >}} diff --git a/docs/sources/visualizations/time-series/graph-time-series-stacking.md b/docs/sources/visualizations/time-series/graph-time-series-stacking.md new file mode 100644 index 00000000..9b2ccdba --- /dev/null +++ b/docs/sources/visualizations/time-series/graph-time-series-stacking.md @@ -0,0 +1,55 @@ ++++ +title = "Graph stacked time series" +keywords = ["grafana", "time series panel", "documentation", "guide", "graph"] +aliases =["/docs/grafana/latest/features/panels/histogram/", "/docs/grafana/latest/panels/visualizations/time-series/graph-time-series-stacking/"] +weight = 400 ++++ + +# Graph stacked time series + +This section explains how to use Time series panel field options to control the stacking of the series and illustrates what the stacking options do. + +_Stacking_ allows Grafana to display series on top of each other. Be cautious when using stacking in the visualization as it can easily create misleading graphs. You can read more on why stacking may be not the best approach here: [Stacked Area Graphs Are Not Your Friend](https://everydayanalytics.ca/2014/08/stacked-area-graphs-are-not-your-friend.html). + +Use the following field settings to configure your series stacking. + +Some field options will not affect the visualization until you click outside of the field option box you are editing or press Enter. + +## Stack series + +Turn series stacking on or off. + +![Stack series editor](/static/img/docs/time-series-panel/stack-series-editor-8-0.png) + +### Off + +Turn off series stacking. A series will share the same space in the visualization. + +![No series stacking example](/static/img/docs/time-series-panel/stacking-off-8-0.png) + +### Normal + +Enable stacking series on top of each other. + +![Normal series stacking example](/static/img/docs/time-series-panel/stacking-normal-8-0.png) + +## Stack series in groups + +The stacking group option is only available as an override. + +For more information about creating field overrides, refer to [Field overrides]({{< relref "../../panels/field-overrides.md" >}}). + +Stack series in the same group. In the Overrides section: + +1. Create a field override for **Stack series** option. + + ![Stack series override](/static/img/docs/time-series-panel/stacking-override-default-8-0.png) + +1. Click on **Normal** stacking mode. +1. Name the stacking group you want the series to appear in. The stacking group name option is only available when creating an override. + +![Stack series override editor](/static/img/docs/time-series-panel/stack-series-override-editor-8-0.png) + +A-series and B-series stacked in group A, C-series, and D-series stacked in group B: + +![Stacking groups example](/static/img/docs/time-series-panel/stack-series-groups-8-0.png) diff --git a/docs/sources/whatsnew/_index.md b/docs/sources/whatsnew/_index.md new file mode 100644 index 00000000..de3a4f91 --- /dev/null +++ b/docs/sources/whatsnew/_index.md @@ -0,0 +1,45 @@ ++++ +title = "What's new" +aliases = ["/docs/grafana/latest/guides/"] +weight = 1 ++++ + +# What's new Grafana + +Grafana is changing all the time. For release highlights checkout links below, if you want a complete list of every change, as well +as info on deprecations, breaking changes and plugin development read the [release notes]({{< relref "../release-notes" >}}). + +## Grafana 8 + +- [What's new in 8.3]({{< relref "whats-new-in-v8-3" >}}) +- [What's new in 8.2]({{< relref "whats-new-in-v8-2" >}}) +- [What's new in 8.1]({{< relref "whats-new-in-v8-1" >}}) +- [What's new in 8.0]({{< relref "whats-new-in-v8-0" >}}) + +## Grafana 7 + +- [What's new in 7.5]({{< relref "whats-new-in-v7-5" >}}) +- [What's new in 7.4]({{< relref "whats-new-in-v7-4" >}}) +- [What's new in 7.3]({{< relref "whats-new-in-v7-3" >}}) +- [What's new in 7.2]({{< relref "whats-new-in-v7-2" >}}) +- [What's new in 7.1]({{< relref "whats-new-in-v7-1" >}}) +- [What's new in 7.0]({{< relref "whats-new-in-v7-0" >}}) + +## Grafana 6 + +- [What's new in 6.7]({{< relref "whats-new-in-v6-7" >}}) +- [What's new in 6.6]({{< relref "whats-new-in-v6-6" >}}) +- [What's new in 6.5]({{< relref "whats-new-in-v6-5" >}}) +- [What's new in 6.4]({{< relref "whats-new-in-v6-4" >}}) +- [What's new in 6.3]({{< relref "whats-new-in-v6-3" >}}) +- [What's new in 6.2]({{< relref "whats-new-in-v6-2" >}}) +- [What's new in 6.1]({{< relref "whats-new-in-v6-1" >}}) +- [What's new in 6.0]({{< relref "whats-new-in-v6-0" >}}) + +## Grafana 5 + +- [What's new in 5.4]({{< relref "whats-new-in-v5-4" >}}) +- [What's new in 5.3]({{< relref "whats-new-in-v5-3" >}}) +- [What's new in 5.2]({{< relref "whats-new-in-v5-2" >}}) +- [What's new in 5.1]({{< relref "whats-new-in-v5-1" >}}) +- [What's new in 5.0]({{< relref "whats-new-in-v5-0" >}}) diff --git a/docs/sources/whatsnew/whats-new-in-v2-0.md b/docs/sources/whatsnew/whats-new-in-v2-0.md new file mode 100644 index 00000000..4882bcca --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v2-0.md @@ -0,0 +1,178 @@ ++++ +title = "What's new in Grafana v2.0" +description = "Feature and improvement highlights for Grafana v2.0" +keywords = ["grafana", "new", "documentation", "2.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v2/"] +weight = -1 +[_build] +list = false ++++ + +# What's new in Grafana v2.0 + +Grafana 2.0 represents months of work by the Grafana team and the community. We are pleased to be able to +release the Grafana 2.0 beta. This is a guide that describes some of changes and new features that can +be found in Grafana V2.0. + +If you are interested in how to migrate from Grafana V1.x to V2.0, please read our [Migration Guide](../installation/migrating_to2.md) + +## New backend server + +Grafana now ships with its own required backend server. Also completely open-source, it's written in Go and has a full HTTP API. + +In addition to new features, the backend server makes it much easier to set up and enjoy Grafana. Grafana 2.0 now ships as cross platform binaries with no dependencies. Authentication is built in, and Grafana is now capable of proxying connections to Data Sources. There are no longer any CORS (Cross Origin Resource Sharing) issues requiring messy workarounds. Elasticsearch is no longer required just to store dashboards. + +## User and Organization permissions + +All Dashboards and Data Sources are linked to an Organization (not to a User). Users are linked to +Organizations via a role. That role can be: + +- `Viewer`: Can only view dashboards, not save / create them. +- `Editor`: Can view, update and create dashboards. +- `Admin`: Everything an Editor can plus edit and add data sources and organization users. + +> **Note:** A `Viewer` can still view all metrics exposed through a data source, not only +> the metrics used in already existing dashboards. That is because there are not +> per series permissions in Graphite, InfluxDB or OpenTSDB. + +There are currently no permissions on individual dashboards. + +Read more about Grafana's new user model on the [Admin section](../reference/admin/) + +## Dashboard Snapshot sharing + +A Dashboard Snapshot is an easy way to create and share a URL for a stripped down, point-in-time version of any Dashboard. +You can give this URL to anyone or everyone, and they can view the Snapshot even if they're not a User of your Grafana instance. + +You can set an expiration time for any Snapshots you create. When you create a Snapshot, we strip sensitive data, like +panel metric queries, annotation and template queries and panel links. The data points displayed on +screen for that specific time period in your Dashboard is saved in the JSON of the Snapshot itself. + +Sharing a Snapshot is similar to sharing a link to a screenshot of your dashboard, only way better (they'll look great at any screen resolution, you can hover over series, +even zoom in). Also they are fast to load as they aren't actually connected to any live Data Sources in any way. + +They're a great way to communicate about a particular incident with specific people who aren't users of your Grafana instance. You can also use them to show off your dashboards over the Internet. + +![](/static/img/docs/v2/dashboard_snapshot_dialog.png) + +### Publish snapshots + +You can publish snapshots locally or to [snapshot.raintank.io](http://snapshot.raintank.io). snapshot.raintank is a free service provided by [raintank](http://raintank.io) for hosting external Grafana snapshots. + +Either way, anyone with the link (and access to your Grafana instance for local snapshots) can view it. + +## Panel time overrides and timeshift + +In Grafana v2.x you can now override the relative time range for individual panels, causing them to be different than what is selected in the Dashboard time picker in the upper right. You can also add a time shift to individual panels. This allows you to show metrics from different time periods or days at the same time. + +![](/static/img/docs/v2/panel_time_override.jpg) + +You control these overrides in panel editor mode and the new tab `Time Range`. + +![](/static/img/docs/v2/time_range_tab.jpg) + +When you zoom or change the Dashboard time to a custom absolute time range, all panel overrides will be disabled. The panel relative time override is only active when the dashboard time is also relative. The panel timeshift override however is always active, even when the dashboard time is absolute. + +The `Hide time override info` option allows you to hide the override info text that is by default shown in the +upper right of a panel when overridden time range options. + +Currently you can only override the dashboard time with relative time ranges, not absolute time ranges. + +## Panel iframe embedding + +You can embed a single panel on another web page or your own application using the panel share dialog. + +Below you should see an iframe with a graph panel (taken from a Dashboard snapshot at [snapshot.raintank.io](http://snapshot.raintank.io). + +Try hovering or zooming on the panel below! + + + +This feature makes it easy to include interactive visualizations from your Grafana instance anywhere you want. + +## New dashboard top header + +The top header has gotten a major streamlining in Grafana V2.0. + + + +1. `Side menubar toggle` Toggle the side menubar on or off. This allows you to focus on the data presented on the Dashboard. The side menubar provides access to features unrelated to a Dashboard such as Users, Organizations, and Data Sources. +1. `Dashboard dropdown` The main dropdown shows you which Dashboard you are currently viewing, and allows you to easily switch to a new Dashboard. From here you can also create a new Dashboard, Import existing Dashboards, and manage the Playlist. +1. `Star Dashboard`: Star (or un-star) the current Dashboard. Starred Dashboards will show up on your own Home Dashboard by default, and are a convenient way to mark Dashboards that you're interested in. +1. `Share Dashboard`: Share the current dashboard by creating a link or create a static Snapshot of it. Make sure the Dashboard is saved before sharing. +1. `Save dashboard`: Save the current Dashboard with the current name. +1. `Settings`: Manage Dashboard settings and features such as Templating, Annotations and the name. + +> **Note:** In Grafana v2.0 when you change the title of a dashboard and then save it, it will no +> longer create a new Dashboard. It will just change the name for the current Dashboard. +> To change name and create a new Dashboard use the `Save As...` menu option + +### New Side menubar + +The new side menubar provides access to features such as User Preferences, Organizations, and Data Sources. + +If you have multiple Organizations, you can easily switch between them here. + +The side menubar will become more useful as we build out additional functionality in Grafana 2.x + +You can easily collapse or re-open the side menubar at any time by clicking the Grafana icon in the top left. We never want to get in the way of the data. + +## New search view and starring dashboards + +![](/static/img/docs/v2/dashboard_search.jpg) + +The dashboard search view has gotten a big overhaul. You can now see and filter by which dashboard you have personally starred. + +## Logarithmic scale + +The Graph panel now supports 3 logarithmic scales, `log base 10`, `log base 32`, `log base 1024`. Logarithmic y-axis scales are very useful when rendering many series of different order of magnitude on the same scale (eg. +latency, network traffic, and storage) + +![](/static/img/docs/v2/graph_logbase10_ms.png) + +## Dashlist panel + +![](/static/img/docs/v2/dashlist_starred.png) + +The dashlist is a new panel in Grafana v2.0. It allows you to show your personal starred dashboards, as well as do custom searches based on search strings or tags. + +dashlist is used on the new Grafana Home screen. It is included as a reference Panel and is useful to provide basic linking between Dashboards. + +## Data Source proxy and admin views + +Data sources in Grafana v2.0 are no longer defined in a config file. Instead, they are added through the UI or the HTTP API. + +The backend can now proxy data from Data Sources, which means that it is a lot easier to get started using Grafana with Graphite or OpenTSDB without having to spend time with CORS (Cross origin resource sharing) work-arounds. + +In addition, connections to Data Sources can be better controlled and secured, and authentication information no longer needs to be exposed to the browser. + +## Dashboard "now delay" + +A commonly reported problem has been graphs dipping to zero at the end, because metric data for the last interval has yet to be written to the Data Source. These graphs then "self correct" once the data comes in, but can look deceiving or alarming at times. + +You can avoid this problem by adding a `now delay` in `Dashboard Settings` > `Time Picker` tab. This new feature will cause Grafana to ignore the most recent data up to the set delay. +![](/static/img/docs/v2/timepicker_now_delay.jpg) + +The delay that may be necessary depends on how much latency you have in your collection pipeline. + +## Dashboard overwrite protection + +Grafana v2.0 protects Users from accidentally overwriting each others Dashboard changes. Similar protections are in place if you try to create a new Dashboard with the same name as an existing one. + +![](/static/img/docs/v2/overwrite_protection.jpg) + +These protections are only the first step; we will be building out additional capabilities around dashboard versioning and management in future versions of Grafana. + +## User preferences + +If you open side menu (by clicking on the Grafana icon in the top header) you can access your Profile Page. + +Here you can update your user details, UI Theme, and change your password. + +## Server-side Panel rendering + +Grafana now supports server-side PNG rendering. From the Panel share dialog you now have access to a link that will render a particular Panel to a PNG image. + +> **Note:** This requires that your Data Source is accessible from your Grafana instance. + +![](/static/img/docs/v2/share_dialog_image_highlight.jpg) diff --git a/docs/sources/whatsnew/whats-new-in-v2-1.md b/docs/sources/whatsnew/whats-new-in-v2-1.md new file mode 100644 index 00000000..e2872b94 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v2-1.md @@ -0,0 +1,148 @@ ++++ +title = "What's new in Grafana v2.1" +description = "Feature and improvement highlights for Grafana v2.1" +keywords = ["grafana", "new", "documentation", "2.1", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v2-1/"] +weight = -2 +[_build] +list = false ++++ + +# What's new in Grafana v2.1 + +Grafana 2.1 brings improvements in three core areas: dashboarding, authentication, and data sources. +As with every Grafana release, there is a whole slew of new features, enhancements, and bug fixes. + +## More Dynamic Dashboards + +The Templating system is one of the most powerful and well-used features of Grafana. +The 2.1 release brings numerous improvements that make dashboards more dynamic than ever before. + +### Multi-Value Template Variables + +A template variable with Multi-Value enabled allows for the selection of multiple values at the same time. +These variables can then be used in any Panel to make them more dynamic, and to give you the perfect view of your data. +Multi-Value variables are also enabling the new `row repeat` and `panel repeat` feature described below. + +![Multi-Value Select](/static/img/docs/v2/multi-select.gif 'Multi-Value Select') +

+ +### Repeating Rows and Panels + +It’s now possible to create a dashboard that automatically adds (or removes) both rows and panels based +on selected variable values. Any row or any panel can be configured to repeat (duplicate itself) based +on a multi-value template variable.

+ +![Repeating Rows and Panels](/static/img/docs/v2/panel-row-repeat.gif 'Repeating Rows and Panels') +

+ +### Dashboard Links and Navigation + +To support better navigation between dashboards, it's now possible to create custom and dynamic links from individual +panels to appropriate Dashboards. You also have the ability to create flexible top-level links on any +given dashboard thanks to the new dashboard navigation bar feature. + +![Dashboard Links](/static/img/docs/v2/dash_links.png 'Dashboard Links') + +Dashboard links can be added under dashboard settings. Either defined as static URLs with a custom icon or as dynamic +dashboard links or dropdowns based on custom dashboard search query. These links appear in the same +row under the top menu where template variables appear. + +--- + +### Better local Dashboard support + +Grafana can now index Dashboards saved locally as JSON from a given directory. These file based dashboards +will appear in the regular dashboard search along regular DB dashboards. + +> **Note:** Saving local dashboards back the folder is not supported; this feature is meant for statically generated JSON dashboards. + +--- + +## New Authentication Options + +New authentication methods add numerous options to manage users, roles and organizations. + +### LDAP support + +This highly requested feature now allows your Grafana users to login with their LDAP credentials. +You can also specify mappings between LDAP group memberships and Grafana Organization user roles. + +### Basic Auth Support + +You can now authenticate against the Grafana API utilizing a simple username and password with basic HTTP authentication. + +> **Note:** This can be useful for provisioning and configuring management systems that need +> to utilize the API without having to create an API key. + +### Auth Proxy Support + +You can now authenticate utilizing a header (eg. X-Authenticated-User, or X-WEBAUTH-USER) + +> **Note:** this can be useful in situations with reverse proxies. + +### New “Read-only Editor” User Role + +There is a new User role available in this version of Grafana: “Read-only Editor”. This role behaves just +like the Viewer role does in Grafana 2.0. That is you can edit graphs and queries but not save dashboards. +The Viewer role has been modified in Grafana 2.1 so that users assigned this role can no longer edit panels. + +--- + +## Data source Improvements + +### InfluxDB 0.9 Support + +Grafana 2.1 now comes with full support for InfluxDB 0.9. There is a new query editor designed from scratch +for the new features InfluxDB 0.9 enables. + +![InfluxDB Editor](/static/img/docs/v2/influx_09_editor_anim.gif 'InfluxDB Editor') + +
+ +### OpenTSDB Improvements + +Grafana OpenTSDB data source now supports template variable values queries. This means you can create +template variables that fetches the values from OpenTSDB (for example metric names, tag names, or tag values). +The query editor is also enhanced to limiting tags by metric. + +> **Note:** OpenTSDB config option tsd.core.meta.enable_realtime_ts must enabled for OpenTSDB lookup API) + +### New Data Source: KairosDB + +The Cassandra backed time series database KairosDB is now supported in Grafana out of the box. Thank you to +masaori335 for his hard work in getting it to this point. + +--- + +## Panel Improvements + +Grafana 2.1 gives you even more flexibility customizing how individual panels render. +Overriding the colors of specific series using regular expressions, changing how series stack, +and allowing string values will help you better understand your data at a glance. + +### Graph Panel + +Define series color using regex rule. This is useful when you have templated graphs with series names +that change depending selected template variables. Using a regex style override rule you could +for example make all series that contain the word **CPU** `red` and assigned to the second y axis. + +![Define series color using regex rule](/static/img/docs/v2/regex_color_override.png 'Define series color using regex rule') + +New series style override, negative-y transform and stack groups. Negative y transform is +very useful if you want to plot a series on the negative y scale without affecting the legend values like min or max or +the values shown in the hover tooltip. + +![Negative-y Transform](/static/img/docs/v2/negative-y.png 'Negative-y Transform') + +![Negative-y Transform](/static/img/docs/v2/negative-y-form.png 'Negative-y Transform') + +### Singlestat Panel + +Now support string values. Useful for time series database like InfluxDB that supports +string values. + +### Changelog + +For a detailed list and link to github issues for everything included in the 2.1 release please +view the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file. diff --git a/docs/sources/whatsnew/whats-new-in-v2-5.md b/docs/sources/whatsnew/whats-new-in-v2-5.md new file mode 100644 index 00000000..f85ed5b6 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v2-5.md @@ -0,0 +1,114 @@ ++++ +title = "What's new in Grafana v2.5" +description = "Feature and improvement highlights for Grafana v2.5" +keywords = ["grafana", "new", "documentation", "2.5", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v2-5/"] +weight = -3 +[_build] +list = false ++++ + +# What's new in Grafana v2.5 + +## Release highlights + +This is an exciting release, and we want to share some of the highlights. The release includes many +fixes and enhancements to all areas of Grafana, like new Data Sources, a new and improved timepicker, user invites, panel +resize handles and improved InfluxDB and OpenTSDB support. + +### New time range controls + +New Time picker + +A new timepicker with room for more quick ranges as well as new types of relative ranges, like `Today`, +`The day so far` and `This day last week`. Also an improved time and calendar picker that now works +correctly in UTC mode. + +### Elasticsearch + +Elasticsearch example +
+ +This release brings a fully featured query editor for Elasticsearch. You will now be able to visualize +logs or any kind of data stored in Elasticsearch. The query editor allows you to build both simple +and complex queries for logs or metrics. + +- Compute metrics from your documents, supported Elasticsearch aggregations: + - Count, Avg, Min, Max, Sum + - Percentiles, Std Dev, etc. +- Group by multiple terms or filters + - Specify group by options like Top 5 based on Avg @value +- Auto completion for field names +- Query only relevant indices based on time pattern +- Alias patterns for short readable series names + +Try the new Elasticsearch query editor on the [play.grafana.org](https://play.grafana.org/dashboard/db/elasticsearch-metrics) site. + +### CloudWatch + +Cloudwatch editor + +Grafana 2.5 ships with a new CloudWatch data source that will allow you to query and visualize CloudWatch +metrics directly from Grafana. + +- Rich editor with auto completion for metric names, namespaces and dimensions +- Templating queries for generic dashboards +- Alias patterns for short readable series names + +### Prometheus + +Prometheus editor + +Grafana 2.5 ships with a new Prometheus data source that will allow you to query and visualize data +stored in Prometheus. + +### Mix different data sources + +Mix data sources in the same dashboard or in the same graph! + +In previous releases you have been able to mix different data sources on the same dashboard. In v2.5 you +will be able to mix then on the same graph! You can enable this by selecting the built in `-- Mixed --` data source. +When selected this will allow you to specify data source on a per query basis. This will, for example, allow you +to plot metrics from different Graphite servers on the same Graph or plot data from Elasticsearch alongside +data from Prometheus. Mixing different data sources on the same graph works for any data source, even custom ones. + +### Panel Resize handles + + + +This release adds resize handles to the bottom right corners of panels making it easy to resize both width and height. + +### User invites + + + +This version also brings some new features for user management. + +- Organization admins can now invite new users (via email or manually via invite link) +- Users can signup using invite link and get automatically added to invited organization +- User signup workflow can (if enabled) contain an email verification step. +- Check out [#2353](https://github.com/grafana/grafana/issues/2353) for more info. + +### Miscellaneous improvements + +- InfluxDB query editor now supports math and AS expressions +- InfluxDB query editor now supports custom group by interval +- Panel drilldown link is easier to reach +- LDAP improvements (can now search for group membership if your LDAP server does not support memberOf attribute) +- More units for graph and singlestat panel (Length, Volume, Temperature, Pressure, Currency) +- Admin page for all organizations (remove / edit) + +### Breaking changes + +There have been some changes to the data source plugin API. If you are using a custom plugin check that there is an update for it before you upgrade. Also +the new time picker does not currently support custom quick ranges like the last one did. This will likely be added in a +future release. + +### Changelog + +For a detailed list and link to github issues for everything included in the 2.5 release please +view the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file. + +--- + +### Download Grafana 2.5 now diff --git a/docs/sources/whatsnew/whats-new-in-v2-6.md b/docs/sources/whatsnew/whats-new-in-v2-6.md new file mode 100644 index 00000000..d5c2dd4d --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v2-6.md @@ -0,0 +1,137 @@ ++++ +title = "What's new in Grafana v2.6" +description = "Feature and improvement highlights for Grafana v2.6" +keywords = ["grafana", "new", "documentation", "2.6", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v2-6/"] +weight = -4 +[_build] +list = false ++++ + +# What's new in Grafana v2.6 + +## Release highlights + +The release includes a new Table panel, a new InfluxDB query editor, support for Elasticsearch Pipeline Metrics and +support for multiple Cloudwatch credentials. + +## Table Panel + + + +The new table panel is very flexible, supporting both multiple modes for time series as well as for +table, annotation and raw JSON data. It also provides date formatting and value formatting and coloring options. + +### Time series to rows + +In the most simple mode you can turn time series to rows. This means you get a `Time`, `Metric` and a `Value` column. +Where `Metric` is the name of the time series. + + + +### Table Transform + +Above you see the options tab for the **Table Panel**. The most important option is the `To Table Transform`. +This option controls how the result of the metric/data query is turned into a table. + +### Column Styles + +The column styles allow you control how dates and numbers are formatted. + +### Time series to columns + +This transform allows you to take multiple time series and group them by time. Which will result in a `Time` column +and a column for each time series. + + + +In the screenshot above you can see how the same time series query as in the previous example can be transformed into +a different table by changing the `To Table Transform` to `Time series to columns`. + +### Time series to aggregations + +This transform works very similar to the legend values in the Graph panel. Each series gets its own row. In the Options +tab you can select which aggregations you want using the plus button the Columns section. + + + +You have to think about how accurate the aggregations will be. It depends on what aggregation is used in the time series query, +how many data points are fetched, etc. The time series aggregations are calculated by Grafana after aggregation is performed +by the time series database. + +### Raw logs queries + +If you want to show documents from Elasticsearch pick `Raw Document` as the first metric. + + + +This in combination with the `JSON Data` table transform will allow you to pick which fields in the document +you want to show in the table. + + + +### Elasticsearch aggregations + +You can also make Elasticsearch aggregation queries without a `Date Histogram`. This allows you to +use Elasticsearch metric aggregations to get accurate aggregations for the selected time range. + + + +### Annotations + +The table can also show any annotations you have enabled in the dashboard. + + + +## The New InfluxDB Editor + +The new InfluxDB editor is a lot more flexible and powerful. It supports nested functions, like `derivative`. +It also uses the same technique as the Graphite query editor in that it presents nested functions as chain of function +transformations. It tries to simplify and unify the complicated nature of InfluxDB's query language. + + + +In the `SELECT` row you can specify what fields and functions you want to use. If you have a +group by time you need an aggregation function. Some functions like derivative require an aggregation function. + +The editor tries simplify and unify this part of the query. For example: + +![](/static/img/docs/influxdb/select_editor.png) + +The above will generate the following InfluxDB `SELECT` clause: + +```sql +SELECT derivative(mean("value"), 10s) /10 AS "REQ/s" FROM .... +``` + +### Select multiple fields + +Use the plus button and select Field > field to add another SELECT clause. You can also +specify an asterix `*` to select all fields. + +### Group By + +To group by a tag click the plus icon at the end of the GROUP BY row. Pick a tag from the dropdown that appears. +You can remove the group by by clicking on the `tag` and then click on the x icon. + +The new editor also allows you to remove group by time and select `raw` table data. Which is very useful +in combination with the new Table panel to show raw log data stored in InfluxDB. + + + +## Pipeline metrics + +If you have Elasticsearch 2.x and Grafana 2.6 or above then you can use pipeline metric aggregations like +**Moving Average** and **Derivative**. Elasticsearch pipeline metrics require another metric to be based on. Use the eye icon next to the metric +to hide metrics from appearing in the graph. + +![](/static/img/docs/elasticsearch/pipeline_metrics_editor.png) + +## Changelog + +For a detailed list and link to github issues for everything included in the 2.6 release please +view the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file. + +--- + +Download Grafana 2.6 now diff --git a/docs/sources/whatsnew/whats-new-in-v3-0.md b/docs/sources/whatsnew/whats-new-in-v3-0.md new file mode 100644 index 00000000..a69ceee0 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v3-0.md @@ -0,0 +1,229 @@ ++++ +title = "What's new in Grafana v3.0" +description = "Feature and improvement highlights for Grafana v3.0" +keywords = ["grafana", "new", "documentation", "3.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v3/"] +weight = -5 +[_build] +list = false ++++ + +# What's new in Grafana v3.0 + +## Commercial Support + +Commercial Support subscriptions for Grafana are now [generally available](https://grafana.com/support/plans/). + +Raintank is committed to a 100% open-source strategy for Grafana. We +do not want to go down the “open core” route. If your organization +finds Grafana valuable, please consider purchasing a subscription. Get +direct support, bug fixes, and training from the core Grafana team. + +## Plugins + +With the popularity of Grafana continuing to accelerate, it has been +challenging to keep up with all the requests for new features, new +panels, new data sources, and new functionality. Saying “no” so often +has been frustrating, especially for an open source project with such +a vibrant community. + +The team felt that it was time to dramatically improve extensibility +through plugin support. Grafana 3.0 comes with a completely revamped +plugin SDK / API. + +We’ve refactored our **Data Source** plugin architecture and added +two new plugin types: + +- **Panel** plugins let you add new panel types for your Dashboards. +- **App** plugins bundle **Panels** plugins, **Data Sources** plugins, + Dashboards, and Grafana **Pages**. Apps are a great way to provide an + entire experience right within Grafana. + +## Grafana.com + + + +[Grafana.com](https://grafana.com) offers a central repository where the community can come together to discover, create and +share plugins (data sources, panels, apps) and dashboards. + +We are also working on a hosted Graphite-compatible data source that will be optimized for use with Grafana. +It’ll be easy to combine your existing data source(s) with this OpenSaaS option. Finally, Grafana.com can +also be a hub to manage all your Grafana instances. You’ll be able to monitor their health and availability, +perform dashboard backups, and more. + +We are also working on a hosted Graphite-compatible Data Source that +will be optimized for use with Grafana. It’ll be easy to combine your +existing Data Source(s) with this OpenSaaS option. + +Finally, Grafana.com will also be a hub to manage all your Grafana +instances. You’ll be able to monitor their health and availability, +perform Dashboard backups, and more. + +Grafana.net will officially launch along with the stable version of +Grafana 3.0, but go to and check out the preview +and sign up for an account in the meantime. + +## grafana-cli + +Grafana 3.0 comes with a new command line tool called grafana-cli. You +can easily install plugins from Grafana.net with it. For +example: + +``` +grafana-cli install grafana-pie-chart-panel +``` + +## Personalization and Preferences + +The home dashboard, timezone and theme can now be customized on Organization +and user Profile level. Grafana can also track recently viewed dashboards, which +can then be displayed in the dashboard list panel. + +## Improved Playlists + +You can now save Playlists, and start them by using a Playlist URL. If +you update a running Playlist, it will update after its next cycle. + +This is powerful as it allows you to remote control Grafana. If you +have a big TV display showing Grafana in your company lobby, create a +playlist named Lobby, and start it on the computer connected to the +Lobby TV. + +You can now change the Lobby playlist and have the dashboards shown in +the Lobby update accordingly, automatically. + +The playlist does not even have to contain multiple Dashboards; you +can use this feature to reload the whole Dashboard (and Grafana) +periodically and remotely. + +You can also make Playlists dynamic by using Dashboard **tags** to +define the Playlist. + + + +## Improved UI + +We’ve always tried to focus on a good looking, usable, and responsive +UI. We’ve continued to pay a lot of attention to these areas in this +release. + +Grafana 3.0 has a dramatically updated UI that not only looks better +but also has a number of usability improvements. The side menu now +works as a dropdown that you can pin to the side. The Organization / +Profile / Sign out side menu links have been combined into an on hover +slide out menu. + +In addition, all the forms and the layouts of all pages have been +updated to look and flow better, and be much more consistent. There +are literally hundreds of UI improvements and refinements. + +Here’s the new side menu in action: + + + +And here's the new look for Dashboard settings: + + + +Check out the Play +Site to get a feel for some of the UI changes. + +## Improved Annotations + +It is now possible to define a link in each annotation. You can hover +over the link and click the annotation text. This feature is very +useful for linking to particular commits or tickets where more +detailed information can be presented to the user. + + + +## Data source variables + +This has been a top requested feature for very long we are excited to finally provide +this feature. You can now add a new `Data source` type variable. That will +automatically be filled with instance names of your data sources. + + + +You can then use this variable as the panel data source: + + + +This will allow you to quickly change data source server and reuse the +same dashboard for different instances of your metrics backend. For example +you might have Graphite running in multiple data centers or environments. + +## Prometheus, InfluxDB, and OpenTSDB improvements + +All three of these popular included Data Sources have seen a variety +of improvements in this release. Here are some highlights: + +### Prometheus + +The Prometheus Data Source now supports annotations. + +### InfluxDB + +You can now select the InfluxDB policy from the query editor. + + +Grafana 3.0 also comes with support for InfluxDB 0.11 and InfluxDB 0.12. + +### OpenTSDB + +OpenTSDB 2.2 is better supported and now supports millisecond precision. + +## Breaking changes + +Dashboards from v2.6 are compatible; no manual updates should be necessary. There could +be some edge case scenarios where dashboards using templating could stop working. +If that is the case just enter the edit view for the template variable and hit Update button. +This is due to a simplification of the variable format system where template variables are +now stored without any formatting (glob/regex/etc), this is done on the fly when the +variable is interpolated. + +- Plugin API: The plugin API has changed so if you are using a custom + data source (or panel) they need to be updated as well. + +- InfluxDB 0.8: This data source is no longer included in releases, + you can still install manually from [Grafana.com](https://grafana.com) + +- KairosDB: This data source has also no longer shipped with Grafana, + you can install it manually from [Grafana.com](https://grafana.com) + +## Plugin showcase + +Discovering and installing plugins is very quick and easy with Grafana 3.0 and [Grafana.com](https://grafana.com). Here +are a couple that I encourage you try! + +#### [Clock Panel](https://grafana.com/plugins/grafana-clock-panel) + +Support's both current time and count down mode. + + +#### [Pie Chart Panel](https://grafana.com/plugins/grafana-piechart-panel) + +A simple pie chart panel is now available as an external plugin. + + +#### [WorldPing App](https://grafana.com/plugins/raintank-worldping-app) + +This is full blown Grafana App that adds new panels, data sources and pages to give +feature rich global performance monitoring directly from your on-prem Grafana. + + + +#### [Zabbix App](https://grafana.com/plugins/alexanderzobnin-zabbix-app) + +This app contains the already very pouplar Zabbix data source plugin, 2 dashboards and a triggers panel. It is +created and maintained by [Alexander Zobnin](https://github.com/alexanderzobnin/grafana-zabbix). + + + +Check out the full list of plugins on [Grafana.com](https://grafana.com/plugins) + +## CHANGELOG + +For a detailed list and link to github issues for everything included +in the 3.0 release please view the +[CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file. diff --git a/docs/sources/whatsnew/whats-new-in-v3-1.md b/docs/sources/whatsnew/whats-new-in-v3-1.md new file mode 100644 index 00000000..6f2ddf40 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v3-1.md @@ -0,0 +1,61 @@ ++++ +title = "What's new in Grafana v3.1" +description = "Feature and improvement highlights for Grafana v3.1" +keywords = ["grafana", "new", "documentation", "3.1", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v3-1/"] +weight = -6 +[_build] +list = false ++++ + +# What's new in Grafana v3.1 + +## Dashboard Export and Import + +The export feature is now accessed from the share menu. + + + +Dashboards exported from Grafana 3.1 are now more portable and easier for others to import than before. The export process extracts information data source types used by panels and adds these to a new `inputs` section in the dashboard json. So when you or another person tries to import the dashboard they will be asked to select data source and optional metric prefix options. + + + +The above screenshot shows the new import modal that gives you 3 options for how to import a dashboard. One notable new addition here is the ability to import directly from Dashboards shared on [Grafana.com](https://grafana.com). + +The next step in the import process: + + + +Here you can change the name of the dashboard and also pick what data sources you want the dashboard to use. The above screenshot shows a CollectD dashboard for Graphite that requires a metric prefix be specified. + +## Discover Dashboards + +On [Grafana.com](https://grafana.com) you can now browse and search for dashboards. We have already added a few but more are being uploaded every day. To import a dashboard just copy the dashboard URL and head back to Grafana, then Dashboard Search -> Import -> Paste Grafana.com Dashboard URL. + + + +## Constant template variables + +We added a new template variable named constant that makes it easier to share and export dashboard that have custom prefixes. + +## Dashboard URLs + +Having current time range and template variable value always sync with the URL makes it possible to always copy your current Grafana URL to share with a colleague without having to use the Share modal. + +## Internal metrics + +Do you want metrics about viewing metrics? Of course you do! In this release we added support for sending metrics about Grafana to graphite. You can configure interval and server in the config file. + +## Logging + +Switched logging framework to log15 to enable key value per logging and filtering based on different log levels. It's now possible to configure different log levels for different modules. + +### Breaking changes + +- **Logging** format have been changed to improve log filtering. +- **Graphite PNG** Graphite PNG support dropped from Graph panel (use Grafana native PNG instead). +- **Migration** No longer possible to migrate dashboards from 1.x (Stored in ES or Influx 0.8). + +## CHANGELOG + +For a detailed list and link to github issues for everything included in the 3.1 release please view the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file. diff --git a/docs/sources/whatsnew/whats-new-in-v4-0.md b/docs/sources/whatsnew/whats-new-in-v4-0.md new file mode 100644 index 00000000..e405e0d6 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v4-0.md @@ -0,0 +1,177 @@ ++++ +title = "What's new in Grafana v4.0" +description = "Feature and improvement highlights for Grafana v4.0" +keywords = ["grafana", "new", "documentation", "4.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v4/"] +weight = -7 +[_build] +list = false ++++ + +# What's new in Grafana v4.0 + +As usual this release contains a ton of minor new features, fixes and improved UX. But on top of the usual new goodies +is a core new feature: Alerting! Read on below for a detailed description of what's new in v4.0. + +## Alerting + +{{< figure class="float-right" max-width="40%" src="/static/img/docs/v4/drag_handles_gif.gif" caption="Alerting overview" >}} + +Alerting is a really revolutionary feature for Grafana. It transforms Grafana from a +visualization tool into a truly mission critical monitoring tool. The alert rules are very easy to +configure using your existing graph panels and threshold levels can be set simply by dragging handles to +the right side of the graph. The rules will continually be evaluated by grafana-server and +notifications will be sent out when the rule conditions are met. + +This feature has been worked on for over a year with many iterations and rewrites +just to make sure the foundations are really solid. We are really proud to finally release it! +Since the alerting execution is processed in the backend not all data source plugins are supported. +Right now Graphite, Prometheus, InfluxDB and OpenTSDB are supported. Elasticsearch is being worked +on but will be not ready for v4 release. + +
+ +### Rules + +{{< figure class="float-right" max-width="40%" src="/static/img/docs/v4/alerting_conditions.png" caption="Alerting Conditions" >}} + +The rule configuration allows you to specify a name, how often the rule should be evaluated and a series +of conditions that all need to be true for the alert to fire. + +Currently the only condition type that exists is a `Query` condition that allows you to +specify a query letter, time range and an aggregation function. The letter refers to +a query you already have added in the **Metrics** tab. The result from the +query and the aggregation function is a single value that is then used in the threshold check. + +We plan to add other condition types in the future, like `Other Alert`, where you can include the state +of another alert in your conditions, and `Time Of Day`. + +### Notifications + +{{< figure class="float-right" max-width="40%" src="/static/img/docs/v4/slack_notification.png" caption="Alerting Slack Notification" >}} + +Alerting would not be very useful if there was no way to send notifications when rules trigger and change state. You +can set up notifications of different types. We currently have `Slack`, `PagerDuty`, `Email` and `Webhook` with more in the +pipe that will be added during beta period. The notifications can then be added to your alert rules. +If you have configured an external image store in the grafana.ini config file (s3, webdav, and azure_blob options available) +you can get very rich notifications with an image of the graph and the metric +values all included in the notification. + +### Annotations + +Alert state changes are recorded in a new annotation store that is built into Grafana. This store +currently only supports storing annotations in Grafana's own internal database (mysql, postgres or sqlite). +The Grafana annotation storage is currently only used for alert state changes but we hope to add the ability for users +to add graph comments in the form of annotations directly from within Grafana in a future release. + +### Alert List Panel + +{{< figure class="float-right" max-width="30%" src="/static/img/docs/v4/alert_list_panel.png" caption="Alert List Panel" >}} + +This new panel allows you to show alert rules or a history of alert rule state changes. You can filter based on states you are +interested in. This panel is very useful for overview style dashboards. + +
+ +## Ad-hoc filter variable + +{{< figure class="float-right" max-width="30%" src="/static/img/docs/v4/adhoc_filters.gif" caption="Ad-hoc filters variable" >}} + +This is a new and very different type of template variable. It will allow you to create new key/value filters on the fly +with autocomplete for both key and values. The filter condition will be automatically applied to all +queries that use that data source. This feature opens up more exploratory dashboards. In the gif animation to the right +you have a dashboard for Elasticsearch log data. It uses one query variable that allow you to quickly change how the data +is grouped, and an interval variable for controlling the granularity of the time buckets. What was missing +was a way to dynamically apply filters to the log query. With the `Ad-Hoc Filters` variable you can +dynamically add filters to any log property! + +## UX Improvements + +We always try to bring some UX/UI refinements and polish in every release. + +### TV-mode and Kiosk mode + +
+
+

+ Grafana is so often used on wall mounted TVs that we figured a clean TV mode would be + really nice. In TV mode the top navbar, row and panel controls will all fade to transparent. +

+ +

+ This happens automatically after one minute of user inactivity but can also be toggled manually + with the d v sequence shortcut. Any mouse movement or keyboard action will + restore navbar and controls. +

+ +

+ Another feature is the kiosk mode. This can be enabled with d k + shortcut or by adding &kiosk to the URL when you load a dashboard. + In kiosk mode the navbar is completely hidden/removed from view. +

+ +
+
+ {{< figure src="/static/img/docs/v4/tvmode.png" caption="TV mode" >}} + +
+
+ +### New row menu and add panel experience + +{{< figure class="float-right" max-width="50%" src="/static/img/docs/v4/add_panel.gif" caption="Add Panel flow" >}} + +We spent a lot of time improving the dashboard building experience to make it both +more efficient and easier for beginners. After many good but not great experiments +with a `build mode` we eventually decided to just improve the green row menu and +continue work on a `build mode` for a future release. + +The new row menu automatically slides out when you mouse over the edge of the row. You no longer need +to hover over the small green icon and then click it to expand the row menu. + +There are some minor improvements to drag and drop behavior. Now when dragging a panel from one row +to another you will insert the panel and Grafana will automatically make room for it. +When you drag a panel within a row you will simply reorder the panels. + +If you look at the animation to the right you can see that you can drag and drop a new panel. This is not +required, you can also just click the panel type and it will be inserted at the end of the row +automatically. Dragging a new panel has an advantage in that you can insert a new panel where ever you want +not just at the end of the row. + +We plan to further improve dashboard building in the future with a more rich grid and layout system. + +### Keyboard shortcuts + +{{< figure class="float-right" max-width="40%" src="/static/img/docs/v4/shortcuts.png" caption="Shortcuts" >}} + +Grafana v4 introduces a number of really powerful keyboard shortcuts. You can now focus a panel +by hovering over it with your mouse. With a panel focused you can simply hit `e` to toggle panel +edit mode, or `v` to toggle fullscreen mode. `p r` removes the panel. `p s` opens share +modal. + +Some nice navigation shortcuts are: + +- `g h` for go to home dashboard +- `s s` open search with starred pre-selected +- `s t` open search in tags list view + +
+ +## Upgrade and Breaking changes + +There are no breaking changes. Old dashboards and features should work the same. Grafana-server will automatically upgrade its db +schema on restart. It's advisable to do a backup of Grafana's database before updating. + +If you are using plugins make sure to update your plugins as some might not work perfectly v4. + +You can update plugins using grafana-cli + + grafana-cli plugins update-all + +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list +of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v4-1.md b/docs/sources/whatsnew/whats-new-in-v4-1.md new file mode 100644 index 00000000..fb3d0c82 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v4-1.md @@ -0,0 +1,70 @@ ++++ +title = "What's new in Grafana v4.1" +description = "Feature and improvement highlights for Grafana v4.1" +keywords = ["grafana", "new", "documentation", "4.1.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v4-1/"] +weight = -8 +[_build] +list = false ++++ + +## What's new in Grafana v4.1 + +- **Graph**: Support for shared tooltip on all graphs as you hover over one graph. [#1578](https://github.com/grafana/grafana/pull/1578), [#6274](https://github.com/grafana/grafana/pull/6274) +- **Victorops**: Add VictorOps notification integration [#6411](https://github.com/grafana/grafana/issues/6411), thx [@ichekrygin](https://github.com/ichekrygin) +- **Opsgenie**: Add OpsGenie notification integratiion [#6687](https://github.com/grafana/grafana/issues/6687), thx [@kylemcc](https://github.com/kylemcc) +- **Cloudwatch**: Make it possible to specify access and secret key on the data source configuration page [#6697](https://github.com/grafana/grafana/issues/6697) +- **Elasticsearch**: Added support for Elasticsearch 5.x [#5740](https://github.com/grafana/grafana/issues/5740), thx [@lpic10](https://github.com/lpic10) +- **Panel**: Added help text for panels. [#4079](https://github.com/grafana/grafana/issues/4079), thx [@utkarshcmu](https://github.com/utkarshcmu) +- [Full changelog](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) + +### Shared tooltip + +{{< figure class="float-right" max-width="60%" src="/static/img/docs/v41/shared_tooltip.gif" caption="Shared tooltip" >}} + +Showing the tooltip on all panels at the same time has been a long standing request in Grafana and we are really happy to finally be able to release it. +You can enable/disable the shared tooltip from the dashboard settings menu or cycle between default, shared tooltip and shared crosshair by pressing Ctrl/Cmd+O. + +
+ +### Help text for panel + +{{< figure class="float-right" max-width="60%" src="/static/img/docs/v41/helptext_for_panel_settings.png" caption="Hovering help text" >}} + +You can set a help text in the general tab on any panel. The help text is using Markdown to enable better formatting and linking to other sites that can provide more information. + +
+ +{{< figure class="float-right" max-width="60%" src="/static/img/docs/v41/helptext_hover.png" caption="Hovering help text" >}} + +Panels with a help text available have a little indicator in the top left corner. You can show the help text by hovering the icon. + +
+ +### Easier Cloudwatch configuration + +{{< figure class="float-right" max-width="60%" src="/static/img/docs/v41/cloudwatch_settings.png" caption="Cloudwatch configuration" >}} + +In Grafana 4.1.0 you can configure your Cloudwatch data source with `access key` and `secret key` directly in the data source configuration page. +This enables people to use the Cloudwatch data source without having access to the filesystem where Grafana is running. + +Once the `access key` and `secret key` have been saved the user will no longer be able to view them. + +
+ +## Upgrade and Breaking changes + +Elasticsearch 1.x is no longer supported. Please upgrade to Elasticsearch 2.x or 5.x. Otherwise Grafana 4.1.0 contains no breaking changes. + +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list +of new features, changes, and bug fixes. + +## Download + +Head to [v4.1 download page](/download/4_1_0/) for download links and instructions. + +## Thanks + +A big thanks to all the Grafana users who contribute by submitting PRs, bug reports and feedback! diff --git a/docs/sources/whatsnew/whats-new-in-v4-2.md b/docs/sources/whatsnew/whats-new-in-v4-2.md new file mode 100644 index 00000000..4664cacb --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v4-2.md @@ -0,0 +1,86 @@ ++++ +title = "What's new in Grafana v4.2" +description = "Feature and improvement highlights for Grafana v4.2" +keywords = ["grafana", "new", "documentation", "4.2.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v4-2/"] +weight = -9 +[_build] +list = false ++++ + +## What's new in Grafana v4.2 + +Grafana v4.2 Beta is now [available for download](https://grafana.com/grafana/download/4.2.0). +Just like the last release this one contains lots bug fixes and minor improvements. +We are very happy to say that 27 of 40 issues was closed by pull requests from the community. +Big thumbs up! + +## Release Highlights + +- **Hipchat**: Adds support for sending alert notifications to hipchat [#6451](https://github.com/grafana/grafana/issues/6451), thx [@jregovic](https://github.com/jregovic) +- **Telegram**: Added Telegram alert notifier [#7098](https://github.com/grafana/grafana/pull/7098), thx [@leonoff](https://github.com/leonoff) +- **LINE**: Add LINE as alerting notification channel [#7301](https://github.com/grafana/grafana/pull/7301), thx [@huydx](https://github.com/huydx) +- **Templating**: Make $**interval and $**interval_ms global built in variables that can be used in by any data source (in panel queries), closes [#7190](https://github.com/grafana/grafana/issues/7190), closes [#6582](https://github.com/grafana/grafana/issues/6582) +- **Alerting**: Adds deduping of alert notifications [#7632](https://github.com/grafana/grafana/pull/7632) +- **Alerting**: Better information about why an alert triggered [#7035](https://github.com/grafana/grafana/issues/7035) +- **Orgs**: Sharing dashboards using Grafana share feature will now redirect to correct org. [#6948](https://github.com/grafana/grafana/issues/6948) +- [Full changelog](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) + +### New alert notification channels + +This release adds **five** new alert notifications channels, all of them contributed by the community. + +- Hipchat +- Telegram +- LINE +- Pushover +- Threema + +### Templating + +We added two new global built in variables in grafana. `$__interval` and `$__interval_ms` are now reserved template names in grafana and can be used by any data source. +We might add more global built in variables in the future and if we do we will prefix them with `$__`. So please avoid using that in your template variables. + +### Dedupe alert notifications when running multiple servers + +In this release we will dedupe alert notifications when you are running multiple servers. +This makes it possible to run alerting on multiple servers and only get one notification. + +We currently solve this with sql transactions which puts some limitations for how many servers you can use to execute the same rules. +3-5 servers should not be a problem but as always, it depends on how many alerts you have and how frequently they execute. + +Next up for a better HA situation is to add support for workload balancing between Grafana servers. + +### Alerting more info + +You can now see the reason why an alert triggered in the alert history. Its also easier to detect when an alert is set to `alerting` due to the `no_data` option. + +### Improved support for multi-org setup + +When loading dashboards we now set an query parameter called orgId. So we can detect from which org an user shared a dashboard. +This makes it possible for users to share dashboards between orgs without changing org first. + +We aim to introduce [dashboard groups](https://github.com/grafana/grafana/issues/1611) sometime in the future which will introduce access control and user groups within one org. +Making it possible to have users in multiple groups and have detailed access control. + +## Upgrade and Breaking changes + +If you're using HTTPS in grafana we now force you to use TLS 1.2 and the most secure ciphers. +We think its better to be secure by default rather then making it configurable. +If you want to run HTTPS with lower versions of TLS we suggest you put a reserve proxy in front of grafana. + +If you have template variables name `$__interval` or `$__interval_ms` they will no longer work since these keywords +are reserved as global built in variables. We might add more global built in variables in the future and if we do, we will prefix them with `$__`. So please avoid using that in your template variables. + +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list +of new features, changes, and bug fixes. + +## Download + +Head to [v4.2-beta download page](/download/4_2_0/) for download links and instructions. + +## Thanks + +A big thanks to all the Grafana users who contribute by submitting PRs, bug reports and feedback! diff --git a/docs/sources/whatsnew/whats-new-in-v4-3.md b/docs/sources/whatsnew/whats-new-in-v4-3.md new file mode 100644 index 00000000..7788150e --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v4-3.md @@ -0,0 +1,102 @@ ++++ +title = "What's new in Grafana v4.3" +description = "Feature and improvement highlights for Grafana v4.3" +keywords = ["grafana", "new", "documentation", "4.3.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v4-3/"] +weight = -10 +[_build] +list = false ++++ + +## What's new in Grafana v4.3 + +Grafana v4.3 Beta is now [available for download](https://grafana.com/grafana/download/4.3.0-beta1). + +## Release Highlights + +- New [Heatmap Panel](http://docs.grafana.org/features/panels/heatmap/) +- Graph Panel Histogram Mode +- Elasticsearch Histogram Aggregation +- Prometheus Table data format +- New [MySQL Data Source](http://docs.grafana.org/features/datasources/mysql/) (alpha version to get some early feedback) +- 60+ small fixes and improvements, most of them contributed by our fantastic community! + +Check out the [New Features in v4.3 Dashboard](https://play.grafana.org/dashboard/db/new-features-in-v4-3?orgId=1) on the Grafana Play site for a showcase of these new features. + +## Histogram Support + +A Histogram is a kind of bar chart that groups numbers into ranges, often called buckets or bins. Taller bars show that more data falls in that range. + +The Graph Panel now supports Histograms. + +![](/static/img/docs/v43/heatmap_histogram.png) + +## Histogram Aggregation Support for Elasticsearch + +Elasticsearch is the only supported data source that can return pre-bucketed data (data that is already grouped into ranges). With other data sources there is a risk of returning inaccurate data in a histogram due to using already aggregated data rather than raw data. This release adds support for Elasticsearch pre-bucketed data that can be visualized with the new [Heatmap Panel](http://docs.grafana.org/features/panels/heatmap/). + +## Heatmap Panel + +The Histogram support in the Graph Panel does not show changes over time - it aggregates all the data together for the chosen time range. To visualize a histogram over time, we have built a new [Heatmap Panel](http://docs.grafana.org/features/panels/heatmap/). + +Every column in a Heatmap is a histogram snapshot. Instead of visualizing higher values with higher bars, a heatmap visualizes higher values with color. The histogram shown above is equivalent to one column in the heatmap shown below. + +![](/static/img/docs/v43/heatmap_histogram_over_time.png) + +The Heatmap panel also works with Elasticsearch Histogram Aggregations for more accurate server side bucketing. + +![](/assets/img/blog/v4/elastic_heatmap.jpg) + +## MySQL Data Source (alpha) + +This release includes a [new core data source for MySQL](http://docs.grafana.org/features/datasources/mysql/). You can write any possible MySQL query and format it as either Time Series or Table Data allowing it be used with the Graph Panel, Table Panel and SingleStat Panel. + +We are still working on the MySQL data source. As it's missing some important features, like templating and macros and future changes could be breaking, we are +labeling the state of the data source as Alpha. Instead of holding up the release of v4.3 we are including it in its current shape to get some early feedback. So please try it out and let us know what you think on [twitter](https://twitter.com/intent/tweet?text=.%40grafana&source=4_3_beta_blog&related=blog) or on our [community forum](https://community.grafana.com/c/releases). Is this a feature that you would use? How can we make it better? + +**The query editor can show the generated and interpolated SQL that is sent to the MySQL server.** + +![](/static/img/docs/v43/mysql_table_query.png) + +**The query editor will also show any errors that resulted from running the query (very useful when you have a syntax error!).** + +![](/static/img/docs/v43/mysql_query_error.png) + +## Health Check Endpoint + +Now you can monitor the monitoring with the Health Check Endpoint! The new `/api/health` endpoint returns HTTP 200 OK if everything is up and HTTP 503 Error if the Grafana database cannot be pinged. + +## Lazy Load Panels + +Grafana now delays loading panels until they become visible (scrolled into view). This means panels out of view are not sending requests thereby reducing the load on your time series database. + +## Prometheus - Table Data (column per label) + +The Prometheus data source now supports the Table Data format by automatically assigning a column to a label. This makes it really easy to browse data in the table panel. + +![](/static/img/docs/v43/prom_table_cols_as_labels.png) + +## Other Highlights From The Changelog + +Changes: + +- **Table**: Support to change column header text [#3551](https://github.com/grafana/grafana/issues/3551) +- **InfluxDB**: influxdb query builder support for ORDER BY and LIMIT (allows TOPN queries) [#6065](https://github.com/grafana/grafana/issues/6065) Support influxdb's SLIMIT Feature [#7232](https://github.com/grafana/grafana/issues/7232) thx [@thuck](https://github.com/thuck) +- **Graph**: Support auto grid min/max when using log scale [#3090](https://github.com/grafana/grafana/issues/3090), thx [@bigbenhur](https://github.com/bigbenhur) +- **Prometheus**: Make Prometheus query field a textarea [#7663](https://github.com/grafana/grafana/issues/7663), thx [@hagen1778](https://github.com/hagen1778) +- **Server**: Support listening on a Unix socket [#4030](https://github.com/grafana/grafana/issues/4030), thx [@mitjaziv](https://github.com/mitjaziv) + +Fixes: + +- **MySQL**: 4-byte UTF8 not supported when using MySQL database (allows Emojis in Dashboard Names) [#7958](https://github.com/grafana/grafana/issues/7958) +- **Dashboard**: Description tooltip is not fully displayed [#7970](https://github.com/grafana/grafana/issues/7970) + +Lots more enhancements and fixes can be found in the [Changelog](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +## Download + +Head to the [v4.3 download page](https://grafana.com/grafana/download) for download links and instructions. + +## Thanks + +A big thanks to all the Grafana users who contribute by submitting PRs, bug reports, helping out on our [community site](https://community.grafana.com/) and providing feedback! diff --git a/docs/sources/whatsnew/whats-new-in-v4-4.md b/docs/sources/whatsnew/whats-new-in-v4-4.md new file mode 100644 index 00000000..902bdac4 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v4-4.md @@ -0,0 +1,48 @@ ++++ +title = "What's new in Grafana v4.4" +description = "Feature and improvement highlights for Grafana v4.4" +keywords = ["grafana", "new", "documentation", "4.4.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v4-4/"] +weight = -11 +[_build] +list = false ++++ + +## What's new in Grafana v4.4 + +Grafana v4.4 is now [available for download](https://grafana.com/grafana/download/4.4.0). + +**Highlights**: + +- Dashboard History - version control for dashboards. + +## New Features + +**Dashboard History**: View dashboard version history, compare any two versions (summary and json diffs), restore to old version. This big feature +was contributed by **Walmart Labs**. Big thanks to them for this massive contribution! +Initial feature request: [#4638](https://github.com/grafana/grafana/issues/4638) +Pull Request: [#8472](https://github.com/grafana/grafana/pull/8472) + +## Enhancements + +- **Elasticsearch**: Added filter aggregation label [#8420](https://github.com/grafana/grafana/pull/8420), thx [@tianzk](github.com/tianzk) +- **Sensu**: Added option for source and handler [#8405](https://github.com/grafana/grafana/pull/8405), thx [@joemiller](github.com/joemiller) +- **CSV**: Configurable csv export datetime format [#8058](https://github.com/grafana/grafana/issues/8058), thx [@cederigo](github.com/cederigo) +- **Table Panel**: Column style that preserves formatting/indentation (like pre tag) [#6617](https://github.com/grafana/grafana/issues/6617) +- **DingDing**: Add DingDing Alert Notifier [#8473](https://github.com/grafana/grafana/pull/8473) thx [@jiamliang](https://github.com/jiamliang) + +## Minor Enhancements + +- **Elasticsearch**: Add option for result set size in raw_document [#3426](https://github.com/grafana/grafana/issues/3426) [#8527](https://github.com/grafana/grafana/pull/8527), thx [@mk-dhia](github.com/mk-dhia) + +## Bug Fixes + +- **Graph**: Bug fix for negative values in histogram mode [#8628](https://github.com/grafana/grafana/issues/8628) + +## Download + +Head to the [v4.4 download page](https://grafana.com/grafana/download) for download links and instructions. + +## Thanks + +A big thanks to all the Grafana users who contribute by submitting PRs, bug reports, helping out on our [community site](https://community.grafana.com/) and providing feedback! diff --git a/docs/sources/whatsnew/whats-new-in-v4-5.md b/docs/sources/whatsnew/whats-new-in-v4-5.md new file mode 100644 index 00000000..57b4725a --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v4-5.md @@ -0,0 +1,70 @@ ++++ +title = "What's new in Grafana v4.5" +description = "Feature and improvement highlights for Grafana v4.5" +keywords = ["grafana", "new", "documentation", "4.5", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v4-5/"] +weight = -12 +[_build] +list = false ++++ + +# What's new in Grafana v4.5 + +## Highlights + +### New prometheus query editor + +The new query editor has full syntax highlighting. As well as auto complete for metrics, functions, and range vectors. There are also integrated function docs right from the query editor! + +{{< figure src="/static/img/docs/v45/prometheus_query_editor_still.png" class="docs-image--block" animated-gif="/static/img/docs/v45/prometheus_query_editor.gif" >}} + +### Elasticsearch: Add ad-hoc filters from the table panel + +{{< figure src="/static/img/docs/v45/elastic_ad_hoc_filters.png" class="docs-image--block" >}} + +### Table cell links! + +Create column styles that turn cells into links that use the value in the cell (or other row values) to generate a URL to another dashboard or system: +![](/static/img/docs/v45/table_links.jpg) + +### Query Inspector + +Query Inspector is a new feature that shows query requests and responses. This can be helpful if a graph is not shown or shows something very different than what you expected. +For more information about query inspector, refer to [using grafanas query inspector to troubleshoot issues](https://community.grafana.com/t/using-grafanas-query-inspector-to-troubleshoot-issues/2630). +![](/static/img/docs/v45/query_inspector.png) + +## Changelog + +### New Features + +- **Table panel**: Render cell values as links that can have an URL template that uses variables from current table row. [#3754](https://github.com/grafana/grafana/issues/3754) +- **Elasticsearch**: Add ad hoc filters directly by clicking values in table panel [#8052](https://github.com/grafana/grafana/issues/8052). +- **MySQL**: New rich query editor with syntax highlighting +- **Prometheus**: New rich query editor with syntax highlighting, metric and range auto complete and integrated function docs. [#5117](https://github.com/grafana/grafana/issues/5117) + +### Enhancements + +- **GitHub OAuth**: Support for GitHub organizations with 100+ teams. [#8846](https://github.com/grafana/grafana/issues/8846), thx [@skwashd](https://github.com/skwashd) +- **Graphite**: Calls to Graphite API /metrics/find now include panel or dashboard time range (from and until) in most cases, [#8055](https://github.com/grafana/grafana/issues/8055) +- **Graphite**: Added new graphite 1.0 functions, available if you set version to 1.0.x in data source settings. New Functions: mapSeries, reduceSeries, isNonNull, groupByNodes, offsetToZero, grep, weightedAverage, removeEmptySeries, aggregateLine, averageOutsidePercentile, delay, exponentialMovingAverage, fallbackSeries, integralByInterval, interpolate, invert, linearRegression, movingMin, movingMax, movingSum, multiplySeriesWithWildcards, pow, powSeries, removeBetweenPercentile, squareRoot, timeSlice, closes [#8261](https://github.com/grafana/grafana/issues/8261) +- **Elasticsearch**: Ad-hoc filters now use query phrase match filters instead of term filters, works on non keyword/raw fields [#9095](https://github.com/grafana/grafana/issues/9095). + +### Breaking change + +- **InfluxDB/Elasticsearch**: The panel and data source option named "Group by time interval" is now named "Min time interval" and does now always define a lower limit for the auto group by time. Without having to use `>` prefix (that prefix still works). This should in theory have close to zero actual impact on existing dashboards. It does mean that if you used this setting to define a hard group by time interval of, say "1d", if you zoomed to a time range wide enough the time range could increase above the "1d" range as the setting is now always considered a lower limit. + +This option is now renamed (and moved to Options sub section above your queries): +![image|519x120](upload://ySjHOVpavV6yk9LHQxL9nq2HIsT.png) + +Data source selection and options and help are now above your metric queries. +![image|690x179](upload://5kNDxKgMz1BycOKgG3iWYLsEVXv.png) + +### Minor Changes + +- **InfluxDB**: Change time range filter for absolute time ranges to be inclusive instead of exclusive [#8319](https://github.com/grafana/grafana/issues/8319), thx [@Oxydros](https://github.com/Oxydros) +- **InfluxDB**: Added parenthesis around tag filters in queries [#9131](https://github.com/grafana/grafana/pull/9131) + +## Bug Fixes + +- **Modals**: Maintain scroll position after opening/leaving modal [#8800](https://github.com/grafana/grafana/issues/8800) +- **Templating**: You cannot select data source variables as data source for other template variables [#7510](https://github.com/grafana/grafana/issues/7510) diff --git a/docs/sources/whatsnew/whats-new-in-v4-6.md b/docs/sources/whatsnew/whats-new-in-v4-6.md new file mode 100644 index 00000000..1b240fa7 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v4-6.md @@ -0,0 +1,73 @@ ++++ +title = "What's new in Grafana v4.6" +description = "Feature and improvement highlights for Grafana v4.6" +keywords = ["grafana", "new", "documentation", "4.6", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v4-6/"] +weight = -13 +[_build] +list = false ++++ + +# What's new in Grafana v4.6 + +Grafana v4.6 brings many enhancements to Annotations, Cloudwatch and Prometheus. It also adds support for Postgres as metric and table data source! + +### Annotations + +{{< figure src="/static/img/docs/v46/add_annotation_region.png" max-width= "800px" >}} + +You can now add annotation events and regions right from the graph panel! Just hold Ctrl/Cmd+Click or drag region to open the **Add Annotation** view. The +[Annotations]({{< relref "../dashboards/annotations.md" >}}) documentation is updated to include details on this new exciting feature. + +### Cloudwatch + +Cloudwatch now supports alerting. Set up alert rules for any Cloudwatch metric! + +{{< figure src="/static/img/docs/v46/cloudwatch_alerting.png" max-width= "800px" >}} + +### Postgres + +Grafana v4.6 now ships with a built-in data source plugin for Postgres. Have logs or metric data in Postgres? You can now visualize that data and +define alert rules on it like any of our other data sources. + +{{< figure src="/static/img/docs/v46/postgres_table_query.png" max-width= "800px" >}} + +### Prometheus + +New enhancements include support for **instant queries** and improvements to query editor in the form of autocomplete for label names and label values. +This makes exploring and filtering Prometheus data much easier. + +## Changelog + +### New Features + +- **GCS**: Adds support for Google Cloud Storage [#8370](https://github.com/grafana/grafana/issues/8370) thx [@chuhlomin](https://github.com/chuhlomin) +- **Prometheus**: Adds /metrics endpoint for exposing Grafana metrics. [#9187](https://github.com/grafana/grafana/pull/9187) +- **Graph**: Add support for local formatting in axis. [#1395](https://github.com/grafana/grafana/issues/1395), thx [@m0nhawk](https://github.com/m0nhawk) +- **Jaeger**: Add support for open tracing using jaeger in Grafana. [#9213](https://github.com/grafana/grafana/pull/9213) +- **Unit types**: New date and time unit types added, useful in singlestat to show dates and times. [#3678](https://github.com/grafana/grafana/issues/3678), [#6710](https://github.com/grafana/grafana/issues/6710), [#2764](https://github.com/grafana/grafana/issues/2764) +- **CLI**: Make it possible to install plugins from any URL [#5873](https://github.com/grafana/grafana/issues/5873) +- **Prometheus**: Add support for instant queries [#5765](https://github.com/grafana/grafana/issues/5765), thx [@mtanda](https://github.com/mtanda) +- **Cloudwatch**: Add support for alerting using the cloudwatch data source [#8050](https://github.com/grafana/grafana/pull/8050), thx [@mtanda](https://github.com/mtanda) +- **Pagerduty**: Include triggering series in pagerduty notification [#8479](https://github.com/grafana/grafana/issues/8479), thx [@rickymoorhouse](https://github.com/rickymoorhouse) +- **Timezone**: Time ranges like Today and Yesterday now work correctly when timezone setting is set to UTC [#8916](https://github.com/grafana/grafana/issues/8916), thx [@ctide](https://github.com/ctide) +- **Prometheus**: Align $\_\_interval with the step parameters. [#9226](https://github.com/grafana/grafana/pull/9226), thx [@alin-amana](https://github.com/alin-amana) +- **Prometheus**: Autocomplete for label name and label value [#9208](https://github.com/grafana/grafana/pull/9208), thx [@mtanda](https://github.com/mtanda) +- **Postgres**: New Postgres data source [#9209](https://github.com/grafana/grafana/pull/9209), thx [@svenklemm](https://github.com/svenklemm) +- **Data sources**: closes [#9371](https://github.com/grafana/grafana/issues/9371), [#5334](https://github.com/grafana/grafana/issues/5334), [#8812](https://github.com/grafana/grafana/issues/8812), thx [@mattbostock](https://github.com/mattbostock) + +### Minor Changes + +- **SMTP**: Make it possible to set specific EHLO for SMTP client. [#9319](https://github.com/grafana/grafana/issues/9319) +- **Dataproxy**: Allow Grafana to renegotiate TLS connection [#9250](https://github.com/grafana/grafana/issues/9250) +- **HTTP**: set net.Dialer.DualStack to true for all HTTP clients [#9367](https://github.com/grafana/grafana/pull/9367) +- **Alerting**: Add diff and percent diff as series reducers [#9386](https://github.com/grafana/grafana/pull/9386), thx [@shanhuhai5739](https://github.com/shanhuhai5739) +- **Slack**: Allow images to be uploaded to slack when Token is present [#7175](https://github.com/grafana/grafana/issues/7175), thx [@xginn8](https://github.com/xginn8) +- **Opsgenie**: Use their latest API instead of old version [#9399](https://github.com/grafana/grafana/pull/9399), thx [@cglrkn](https://github.com/cglrkn) +- **Table**: Add support for displaying the timestamp with milliseconds [#9429](https://github.com/grafana/grafana/pull/9429), thx [@s1061123](https://github.com/s1061123) +- **Hipchat**: Add metrics, message and image to hipchat notifications [#9110](https://github.com/grafana/grafana/issues/9110), thx [@eloo](https://github.com/eloo) +- **Postgres**: modify group by time macro so it can be used in select clause [#9527](https://github.com/grafana/grafana/pull/9527), thanks [@svenklemm](https://github.com/svenklemm) + +### Tech + +- **Go**: Grafana is now built using golang 1.9 diff --git a/docs/sources/whatsnew/whats-new-in-v5-0.md b/docs/sources/whatsnew/whats-new-in-v5-0.md new file mode 100644 index 00000000..890d1c3d --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v5-0.md @@ -0,0 +1,148 @@ ++++ +title = "What's new in Grafana v5.0" +description = "Feature and improvement highlights for Grafana v5.0" +keywords = ["grafana", "new", "documentation", "5.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v5/"] +weight = -14 +[_build] +list = false ++++ + +# What's new in Grafana v5.0 + +This is the most substantial update that Grafana has ever seen. This article will detail the major new features and enhancements. + +- [New Dashboard Layout Engine]({{< relref "#new-dashboard-layout-engine" >}}) enables a much easier drag, drop and resize experience and new types of layouts. +- [New UX]({{< relref "#new-ux-layout-engine" >}}). The UI has big improvements in both look and function. +- [New Light Theme]({{< relref "#new-light-theme" >}}) is now looking really nice. +- [Dashboard Folders]({{< relref "#dashboard-folders" >}}) helps you keep your dashboards organized. +- [Permissions]({{< relref "#dashboard-folders" >}}) on folders and dashboards helps manage larger Grafana installations. +- [Group users into teams]({{< relref "#teams" >}}) and use them in the new permission system. +- [Data source provisioning]({{< relref "#data-sources" >}}) makes it possible to set up data sources via config files. +- [Dashboard provisioning]({{< relref "#dashboards" >}}) makes it possible to set up dashboards via config files. +- [Persistent dashboard URL's]({{< relref "#dashboard-model-persistent-url-s-and-api-changes" >}}) makes it possible to rename dashboards without breaking links. +- [Graphite Tags and Integrated Function Docs]({{< relref "#graphite-tags-integrated-function-docs" >}}). + +### Video showing new features + + +
+ +## New Dashboard Layout Engine + +{{< figure src="/static/img/docs/v50/new_grid.png" max-width="1000px" class="docs-image--right">}} + +The new dashboard layout engine allows for much easier movement and sizing of panels, as other panels now move out of the way in +a very intuitive way. Panels are sized independently, so rows are no longer necessary to create layouts. This opens +up many new types of layouts where panels of different heights can be aligned easily. Check out the new grid in the video +above or on the [play site](https://play.grafana.org). All your existing dashboards will automatically migrate to the +new position system and look close to identical. The new panel position makes dashboards saved in v5.0 incompatible +with older versions of Grafana. + +
+ +## New UX + +{{< figure src="/static/img/docs/v50/new_ux_nav.png" max-width="1000px" class="docs-image--right" >}} + +Almost every page has seen significant UX improvements. All pages (except dashboard pages) have a new tab-based layout that improves navigation between pages. The side menu has also changed quite a bit. You can still hide the side menu completely if you click on the Grafana logo. + +
+ +## Dashboard Settings + +{{< figure src="/static/img/docs/v50/dashboard_settings.png" max-width="1000px" class="docs-image--right" >}} +Dashboard pages have a new header toolbar where buttons and actions are now all moved to the right. All the dashboard +settings views have been combined with a side nav which allows you to easily move between different setting categories. + +
+ +## New Light Theme + +{{< figure src="/static/img/docs/v50/new_white_theme.png" max-width="1000px" class="docs-image--right" >}} + +This theme has not seen a lot of love in recent years and we felt it was time to give it a major overhaul. We are very happy with the result. + +
+ +## Dashboard Folders + +{{< figure src="/static/img/docs/v50/new_search.png" max-width="1000px" class="docs-image--right" >}} + +The big new feature that comes with Grafana v5.0 is dashboard folders. Now you can organize your dashboards in folders, +which is very useful if you have a lot of dashboards or multiple teams. + +- New search design adds expandable sections for each folder, starred and recently viewed dashboards. +- New manage dashboard pages enable batch actions and views for folder settings and permissions. +- Set permissions on folders and have dashboards inherit the permissions. + +## Teams + +A team is a new concept in Grafana v5. They are simply a group of users that can be used in the new permission system for dashboards and folders. Only an admin can create teams. +We hope to do more with teams in future releases like integration with LDAP and a team landing page. + +## Permissions + +{{< figure src="/static/img/docs/v50/folder_permissions.png" max-width="1000px" class="docs-image--right" >}} + +You can assign permissions to folders and dashboards. The default user role-based permissions can be removed and +replaced with specific teams or users enabling more control over what a user can see and edit. + +Dashboard permissions only limits what dashboards and folders a user can view and edit not which +data sources a user can access nor what queries a user can issue. + +
+ +## Provisioning from configuration + +In previous versions of Grafana, you could only use the API for provisioning data sources and dashboards. +But that required the service to be running before you started creating dashboards and you also needed to +set up credentials for the HTTP API. In v5.0 we decided to improve this experience by adding a new active +provisioning system that uses config files. This will make GitOps more natural as data sources and dashboards can +be defined via files that can be version controlled. We hope to extend this system to later add support for users, orgs +and alerts as well. + +### Data sources + +Data sources can now be set up using config files. These data sources are by default not editable from the Grafana GUI. +It's also possible to update and delete data sources from the config file. More info in the [data source provisioning docs](/administration/provisioning/#datasources). + +### Dashboards + +We also deprecated the `[dashboard.json]` in favor of our new dashboard provisioner that keeps dashboards on disk +in sync with dashboards in Grafana's database. The dashboard provisioner has multiple advantages over the old +`[dashboard.json]` feature. Instead of storing the dashboard in memory we now insert the dashboard into the database, +which makes it possible to star them, use one as the home dashboard, set permissions and other features in Grafana that +expects the dashboards to exist in the database. More info in the [dashboard provisioning docs]({{< relref "../administration/provisioning.md" >}}) + +## Graphite Tags and Integrated Function Docs + +{{< figure src="/static/img/docs/v50/graphite_tags.png" max-width="1000px" class="docs-image--right" >}} + +The Graphite query editor has been updated to support the latest Graphite version (v1.2) that adds +many new functions and support for querying by tags. You can now also view function documentation right in the query editor! + +Read more on [Graphite Tag Support](http://graphite.readthedocs.io/en/latest/tags.html?highlight=tags). + +
+ +## Dashboard model, persistent URLs and API changes + +We are introducing a new unique identifier (`uid`) in the dashboard JSON model. It's automatically +generated if not provided when creating a dashboard and will have a length of 9-12 characters. + +The unique identifier allows having persistent URLs for accessing dashboards, sharing them +between instances and when using [dashboard provisioning](<(/administration/provisioning/#reusable-dashboard-urls)>). This means that dashboard can +be renamed without breaking any links. We're changing the URL format for dashboards +from `/dashboard/db/:slug` to `/d/:uid/:slug`. We'll keep supporting the old slug-based URLs for dashboards +and redirects to the new one for backward compatibility. Please note that the old slug-based URLs +have been deprecated and will be removed in a future release. + +Sharing dashboards between instances becomes much easier since the `uid` is unique (unique enough). +This might seem like a small change, but we are incredibly excited about it since it will make it +much easier to manage, collaborate and navigate between dashboards. + +### API changes + +New uid-based routes in the dashboard API have been introduced to retrieve and delete dashboards. +The corresponding slug-based routes have been deprecated and will be removed in a future release. diff --git a/docs/sources/whatsnew/whats-new-in-v5-1.md b/docs/sources/whatsnew/whats-new-in-v5-1.md new file mode 100644 index 00000000..194b65fc --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v5-1.md @@ -0,0 +1,122 @@ ++++ +title = "What's new in Grafana v5.1" +description = "Feature and improvement highlights for Grafana v5.1" +keywords = ["grafana", "new", "documentation", "5.1", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v5-1/"] +weight = -15 +[_build] +list = false ++++ + +# What's new in Grafana v5.1 + +Grafana v5.1 brings new features, many enhancements and bug fixes. This article will detail the major new features and enhancements. + +- [Improved scrolling experience]({{< relref "#improved-scrolling-experience" >}}) +- [Improved docker image]({{< relref "#improved-docker-image-breaking-change" >}}) with a breaking change! +- [Heatmap support for Prometheus]({{< relref "#prometheus" >}}) +- [Microsoft SQL Server]({{< relref "#microsoft-sql-server" >}}) as metric and table data source! +- [Dashboards and Panels]({{< relref "#dashboards-panels" >}}) Improved adding panels to dashboards and enhancements to Graph and Table panels. +- [New variable interpolation syntax]({{< relref "#new-variable-interpolation-syntax" >}}) +- [Improved workflow for provisioned dashboards]({{< relref "#improved-workflow-for-provisioned-dashboards" >}}) + +## Improved scrolling experience + +In Grafana v5.0 we introduced a new scrollbar component. Unfortunately this introduced a lot of issues and in some scenarios removed +the native scrolling functionality. Grafana v5.1 ships with a native scrollbar for all pages together with a scrollbar component for +the dashboard grid and panels that's not overriding the native scrolling functionality. We hope that these changes and improvements should +make the Grafana user experience much better! + +## Improved Docker image (breaking change) + +Grafana v5.1 brings an improved official docker image which should make it easier to run and use the Grafana docker image and at the same time give more control to the user how to use/run it. + +We've switched the id of the grafana user running Grafana inside a docker container. Unfortunately this means that files created prior to 5.1 won't have the correct permissions for later versions and thereby this introduces a breaking change. +We made this change so that it would be easier for you to control what user Grafana is executed as (see examples below). + +| Version | User | User ID | +| ------- | ------- | ------- | +| < 5.1 | grafana | 104 | +| >= 5.1 | grafana | 472 | + +Please read the [updated documentation](/installation/docker/#migrate-to-v51-or-later) which includes migration instructions and more information. + +## Prometheus + +{{< figure src="/static/img/docs/v51/prometheus_heatmap.png" max-width="800px" class="docs-image--right" >}} + +The Prometheus data source now support transforming Prometheus histograms to the heatmap panel. Prometheus histogram is a powerful feature, and we're +really happy to finally allow our users to render those as heatmaps. Please read [Heatmap panel documentation](/features/panels/heatmap/#pre-bucketed-data) +for more information on how to use it. + +Prometheus query editor also got support for autocomplete of template variables. More information in the [Prometheus data source documentation]({{< relref "../datasources/prometheus/" >}}). + +
+ +## Microsoft SQL Server + +{{< figure src="/static/img/docs/v51/mssql_query_editor_showcase.png" max-width= "800px" class="docs-image--right" >}} + +Grafana v5.1 now ships with a built-in Microsoft SQL Server (MSSQL) data source plugin that allows you to query and visualize data from any +Microsoft SQL Server 2005 or newer, including Microsoft Azure SQL Database. Do you have metric or log data in MSSQL? You can now visualize +that data and define alert rules on it like with any of Grafana's other core data sources. + +Please read [Using Microsoft SQL Server in Grafana documentation]({{< relref "../datasources/mssql/" >}}) for more detailed information on how to get started and use it. + +
+ +## Dashboards and Panels + +### Adding new panels to dashboards + +{{< figure src="/static/img/docs/v51/dashboard_add_panel.png" max-width= "800px" class="docs-image--right" >}} + +The control for adding new panels to dashboards have got some enhancements and now includes functionality to search for the type of panel +you want to add. Further, the control has tabs separating functionality for adding new panels and pasting +copied panels. + +By copying a panel in a dashboard it will be displayed in the `Paste` tab in _any_ dashboard and allows you to paste the +copied panel into the current dashboard. + +{{< figure src="/static/img/docs/v51/dashboard_panel_copy.png" max-width= "300px" >}} + +
+ +### Graph Panel + +New enhancements include support for multiple series stacking in histogram mode, thresholds for right Y axis, aligning left and right Y-axes to one level and additional units. More information in the [Graph panel documentation]({{< relref "../visualizations/graph-panel.md" >}}). + +### Table Panel + +New enhancements include support for mapping a numeric value/range to text and additional units. More information in the [Table panel documentation](/features/panels/table_panel/#string). + +## New variable interpolation syntax + +We now support a new option for rendering variables that gives the user full control of how the value(s) should be rendered. +In the table below you can see some examples and you can find all different options in the [Variables documentation](http://docs.grafana.org/variables/templates-and-variables/#advanced-formatting-options). + +| Filter Option | Example | Raw | Interpolated | Description | +| ------------- | ---------------- | ------------------ | -------------------------------- | --------------------------------------------------------- | +| `glob` | ${servers:glob} | `'test1', 'test2'` | `{test1,test2}` | Formats multi-value variable into a glob | +| `regex` | ${servers:regex} | `'test.', 'test2'` | (test\.|test2) | Formats multi-value variable into a regex string | +| `pipe` | ${servers:pipe} | `'test.', 'test2'` | test.|test2 | Formats multi-value variable into a pipe-separated string | +| `csv` | ${servers:csv} | `'test1', 'test2'` | `test1,test2` | Formats multi-value variable as a comma-separated string | + +## Improved workflow for provisioned dashboards + +{{< figure src="/static/img/docs/v51/provisioning_cannot_save_dashboard.png" max-width="800px" class="docs-image--right" >}} + +Grafana v5.1 brings an improved workflow for provisioned dashboards: + +- A populated `id` property in JSON is now automatically removed when provisioning dashboards. +- When making changes to a provisioned dashboard you can `Save` the dashboard which now will bring up a _Cannot save provisioned dashboard_ dialog like seen in the screenshot to the right. + +Available options in the dialog will let you `Copy JSON to Clipboard` and/or `Save JSON to file` which can help you synchronize your dashboard changes back to the provisioning source. +More information in the [Provisioning documentation](/administration/provisioning/). + +
+ +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list +of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v5-2.md b/docs/sources/whatsnew/whats-new-in-v5-2.md new file mode 100644 index 00000000..025640b1 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v5-2.md @@ -0,0 +1,99 @@ ++++ +title = "What's new in Grafana v5.2" +description = "Feature and improvement highlights for Grafana v5.2" +keywords = ["grafana", "new", "documentation", "5.2", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v5-2/"] +weight = -16 +[_build] +list = false ++++ + +# What's new in Grafana v5.2 + +Grafana v5.2 brings new features, many enhancements and bug fixes. This article will detail the major new features and enhancements. + +- [Elasticsearch alerting]({{< relref "#elasticsearch-alerting" >}}) it's finally here! +- [Native builds for ARM]({{< relref "#native-builds-for-arm" >}}) native builds of Grafana for many more platforms! +- [Improved Docker image]({{< relref "#improved-docker-image" >}}) with support for docker secrets +- [Security]({{< relref "#security" >}}) make your Grafana instance more secure +- [Prometheus]({{< relref "#prometheus" >}}) with alignment enhancements +- [InfluxDB]({{< relref "#influxdb" >}}) now supports the `mode` function +- [Alerting]({{< relref "#alerting" >}}) with alert notification channel type for Discord +- [Dashboards and Panels]({{< relref "#dashboards-panels" >}}) with save and import enhancements + +## Elasticsearch alerting + +{{< figure src="/static/img/docs/v52/elasticsearch_alerting.png" max-width="800px" class="docs-image--right" >}} + +Grafana v5.2 ships with an updated Elasticsearch data source with support for alerting. Alerting support for Elasticsearch has been one of +the most requested features by our community and now it's finally here. Please try it out and let us know what you think. + +
+ +## Native builds for ARM + +Grafana v5.2 brings an improved build pipeline with cross-platform support. This enables native builds of Grafana for ARMv7 (x32) and ARM64 (x64). +We've been longing for native ARM build support for ages. With the help from our amazing community this is now finally available. +Please try it out and let us know what you think. + +Another great addition with the improved build pipeline is that binaries for macOS/Darwin (x64) and Windows (x64) are now automatically built and +published for both stable and nightly builds. + +## Improved Docker image + +The Grafana docker image adds support for Docker secrets which enables you to supply Grafana with configuration through files. More +information in the [Installing using Docker documentation](/installation/docker/#reading-secrets-from-files-support-for-docker-secrets). + +## Security + +{{< figure src="/static/img/docs/v52/login_change_password.png" max-width="800px" class="docs-image--right" >}} + +Starting from Grafana v5.2, when you login with the administrator account using the default password you'll be presented with a form to change the password. +We hope this encourages users to follow Grafana's best practices and change the default administrator password. + +
+ +## Prometheus + +The Prometheus data source now aligns the start/end of the query sent to Prometheus with the step, which ensures PromQL expressions with _rate_ +functions get consistent results, and thus avoids graphs jumping around on reload. + +## InfluxDB + +The InfluxDB data source now includes support for the _mode_ function which returns the most frequent value in a list of field values. + +## Alerting + +By popular demand Grafana now includes support for an alert notification channel type for [Discord](https://discordapp.com/). + +## Dashboards and Panels + +### Modified time range and variables are no longer saved by default + +{{< figure src="/static/img/docs/v52/dashboard_save_modal.png" max-width="800px" class="docs-image--right" >}} + +Starting from Grafana v5.2, a modified time range or variable are no longer saved by default. To save a modified +time range or variable, you'll need to actively select that when saving a dashboard, see screenshot. +This should hopefully make it easier to have same defaults for time and variables in dashboards and make it more explicit +when you actually want to overwrite those settings. + +
+ +### Import dashboard enhancements + +{{< figure src="/static/img/docs/v52/dashboard_import.png" max-width="800px" class="docs-image--right" >}} + +Grafana v5.2 adds support for specifying an existing folder or creating a new one when importing a dashboard - a long-awaited feature since +Grafana v5.0 introduced support for dashboard folders and permissions. The import dashboard page has also got some general improvements +and should now make it more clear if a possible import will overwrite an existing dashboard, or not. + +This release also adds some improvements for those users only having editor or admin permissions in certain folders. The links to +_Create Dashboard_ and _Import Dashboard_ are now available in the side navigation, in dashboard search and on the manage dashboards/folder page for a +user that has editor role in an organization or the edit permission in at least one folder. + +
+ +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list +of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v5-3.md b/docs/sources/whatsnew/whats-new-in-v5-3.md new file mode 100644 index 00000000..423433d0 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v5-3.md @@ -0,0 +1,90 @@ ++++ +title = "What's new in Grafana v5.3" +description = "Feature and improvement highlights for Grafana v5.3" +keywords = ["grafana", "new", "documentation", "5.3", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v5-3/"] +weight = -17 +[_build] +list = false ++++ + +# What's new in Grafana v5.3 + +Grafana v5.3 brings new features, many enhancements and bug fixes. This article will detail the major new features and enhancements. + +- [Google Stackdriver]({{< relref "#google-stackdriver" >}}) as a core data source! +- [TV mode]({{< relref "#tv-and-kiosk-mode" >}}) is improved and more accessible +- [Alerting]({{< relref "#notification-reminders" >}}) with notification reminders +- [Postgres]({{< relref "#postgres-query-builder" >}}) gets a new query builder! +- [OAuth]({{< relref "#improved-oauth-support-for-gitlab" >}}) support for GitLab is improved +- [Annotations]({{< relref "#annotations" >}}) with template variable filtering +- [Variables]({{< relref "#variables" >}}) with free text support + +## Google Stackdriver + +{{< figure src="/static/img/docs/v53/stackdriver-with-heatmap.png" max-width= "600px" class="docs-image--no-shadow docs-image--right" >}} + +Grafana v5.3 ships with built-in support for [Google Stackdriver](https://cloud.google.com/stackdriver/) and enables you to visualize your Stackdriver metrics in Grafana. + +Getting started with the plugin is easy. Simply create a GCE Service account that has access to the Stackdriver API scope, download the Service Account key file from Google and upload it on the Stackdriver data source configuration page in Grafana and you should have a secure server-to-server authentication setup. Like other core plugins, Stackdriver has built-in support for alerting. It also comes with support for heatmaps and basic variables. + +If you're already accustomed to the Stackdriver Metrics Explorer UI, you'll notice that there are a lot of similarities to the query editor in Grafana. It is possible to add filters using wildcards and regular expressions. You can do Group By, Primary Aggregation and Alignment. + +Alias By allows you to format the legend the way you want, and it's a feature that is not yet present in the Metrics Explorer. Two other features that are only supported in the Grafana plugin are the abilities to manually set the Alignment Period in the query editor and to add Annotations queries. + +The Grafana Stackdriver plugin comes with support for automatic unit detection. Grafana will try to map the Stackdriver unit type to a corresponding unit type in Grafana, and if successful the panel Y-axes will be updated accordingly to display the correct unit of measure. This is the first core plugin to provide support for unit detection, and it is our intention to provide support for this in other core plugins in the near future. + +The data source is still in the `beta` phase, meaning it's currently in active development and is still missing one important feature - templating queries. +Please try it out, but be aware of that it might be subject to changes and possible bugs. We would love to hear your feedback. + +Refer to [Using Google Stackdriver in Grafana]({{< relref "../datasources/google-cloud-monitoring/_index.md" >}}) for more detailed information on how to get started and use it. + +## TV and Kiosk Mode + +{{< figure src="/static/img/docs/v53/tv_mode_still.png" max-width="600px" class="docs-image--no-shadow docs-image--right" animated-gif="/static/img/docs/v53/tv_mode.gif" >}} + +We've improved the TV and kiosk mode to make it easier to use. There's now an icon in the top bar that will let you cycle through the different view modes. + +1. In the first view mode, the sidebar and most of the buttons in the top bar will be hidden. +1. In the second view mode, the top bar is completely hidden so that only the dashboard itself is shown. +1. Hit the escape key to go back to the default view mode. + +When switching view modes, the URL will be updated to reflect the view mode selected. This allows a dashboard to be opened with a +certain view mode enabled. Additionally, this also enables [playlists](/dashboards/playlist) to be started with a certain view mode enabled. + +
+ +## Notification Reminders + +Do you use Grafana alerting and have some notifications that are more important than others? Then it's possible to set reminders so that you continue to be alerted until the problem is fixed. This is done on the notification channel itself and will affect all alerts that use that channel. +For additional examples of why reminders might be useful for you, see [multiple series](/alerting/alerts-overview/#multiple-series). + +For more information about how to enable and configure reminders, refer to [alerting reminders](/alerting/notifications/#send-reminders). + +## Postgres Query Builder + +Grafana 5.3 comes with a new graphical query builder for Postgres. This brings Postgres integration more in line with some of the other data sources and makes it easier for both advanced users and beginners to work with timeseries in Postgres. For more information about Postgres graphical query builder, refer to [query editor]({{< relref "../datasources/postgres/#query-editor" >}}). + +{{< figure src="/static/img/docs/v53/postgres_query_still.png" class="docs-image--no-shadow" animated-gif="/static/img/docs/v53/postgres_query.gif" >}} + +## Improved OAuth Support for GitLab + +Grafana 5.3 comes with a new OAuth integration for GitLab that enables configuration to only allow users that are a member of certain GitLab groups to authenticate. This makes it possible to use GitLab OAuth with Grafana in a shared environment without giving everyone access to Grafana. +For more information about how to enable and configure OAuth, refer to [Gitlab OAuth](/auth/gitlab/). + +## Annotations + +Grafana 5.3 brings improved support for [native annotations](/dashboards/annotations/#native-annotations) and makes it possible to use template variables when filtering by tags. +For more information about native annotation, refer to [query by tag](/dashboards/annotations/#query-by-tag). + +{{< figure src="/static/img/docs/v53/annotation_tag_filter_variable.png" max-width="600px" >}} + +## Variables + +Grafana 5.3 ships with a brand new variable type named `Text box` which makes it easier and more convenient to provide free text input to a variable. +This new variable type will display as a free text input field with an optional prefilled default value. + +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list +of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v5-4.md b/docs/sources/whatsnew/whats-new-in-v5-4.md new file mode 100644 index 00000000..db0b137b --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v5-4.md @@ -0,0 +1,81 @@ ++++ +title = "What's new in Grafana v5.4" +description = "Feature and improvement highlights for Grafana v5.4" +keywords = ["grafana", "new", "documentation", "5.4", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v5-4/"] +weight = -18 +[_build] +list = false ++++ + +# What's new in Grafana v5.4 + +Grafana v5.4 brings new features, many enhancements and bug fixes. This article will detail the major new features and enhancements. + +- [Alerting]({{< relref "#alerting" >}}) Limit false positives with the new `For` setting +- [Google Stackdriver]({{< relref "#google-stackdriver" >}}) Now with support for templating queries +- [MySQL]({{< relref "#mysql-query-builder" >}}) gets a new query builder! +- [Graph Panel]({{< relref "#graph-panel-enhancements" >}}) Highlight time regions and more +- [Team Preferences]({{< relref "#team-preferences" >}}) Give your teams their own home dashboard + +## Alerting + +{{< figure src="/static/img/docs/v54/alerting-for-dark-theme.png" max-width="600px" class="docs-image--right" >}} + +Grafana v5.4 ships with a new alert rule setting named `For` which is great for removing false positives. If an alert rule has a configured `For` and the query violates the configured threshold it will first go from `OK` to `Pending`. Going from `OK` to `Pending` Grafana will not send any notifications. Once the alert rule has been firing for more than `For` duration, it will change to `Alerting` and send alert notifications. Typically, it's always a good idea to use this setting since it's often worse to get false positive than wait a few minutes before the alert notification triggers. + +In the screenshot you can see an example timeline of an alert using the `For` setting. At ~16:04 the alert state changes to `Pending` and after 4 minutes it changes to `Alerting` which is when alert notifications are sent. Once the series falls back to normal the alert rule goes back to `OK`. [Learn more](/alerting/alerts-overview/#for). + +Additionally, there's now support for disable the sending of `OK` alert notifications. [Learn more](/alerting/notifications/#disable-resolve-message). + +
+ +## Google Stackdriver + +{{< figure src="/static/img/docs/v54/stackdriver_template_query.png" max-width="600px" class="docs-image--right" >}} + +Grafana v5.3 included built-in support for [Google Stackdriver](https://cloud.google.com/stackdriver/) which enables you to visualize your Stackdriver metrics in Grafana. +One important feature missing was support for templating queries. This is now included together with a brand new templating query editor for Stackdriver. + +The Stackdriver templating query editor lets you choose from a set of different Query Types. This will in turn reveal additional drop-downs to help you +find, filter and select the templating values you're interested in, see screenshot for details. The templating query editor also supports chaining multiple variables +making it easy to define variables that's dependent on other variables. + +Stackdriver is the first data source which has support for a custom templating query editor. But starting from Grafana v5.4 it's now possible for all data sources, including plugin data sources, to +create their very own templating query editor. + +Additionally, if Grafana is running on a Google Compute Engine (GCE) virtual machine, it is now possible for Grafana to automatically retrieve default credentials from the metadata server. +This has the advantage of not needing to generate a private key file for the service account and also not having to upload the file to Grafana. [Learn more]({{< relref "../datasources/google-cloud-monitoring/_index.md/#using-gce-default-service-account" >}}). + +Please read [Using Google Stackdriver in Grafana]({{< relref "../datasources/google-cloud-monitoring/_index.md/" >}}) for more detailed information on how to get started and use it. + +
+ +## MySQL Query Builder + +Grafana v5.4 comes with a new graphical query builder for MySQL. This brings MySQL integration more in line with some of the other data sources and makes it easier for both advanced users and beginners to work with timeseries in MySQL. For more information about MySQL graphical query builder, refer to [query editor]({{< relref "../datasources/mysql/#query-editor" >}}). + +{{< figure src="/static/img/docs/v54/mysql_query_still.png" animated-gif="/static/img/docs/v54/mysql_query.gif" >}} + +## Graph Panel Enhancements + +Grafana v5.4 adds support for highlighting weekdays and/or certain timespans in the graph panel. This should make it easier to compare for example weekends, business hours and/or off work hours. + +{{< figure src="/static/img/docs/v54/graph_time_regions.png" max-width= "800px" >}} + +Additionally, when rendering series as lines in the graph panel, should there be only one data point available for one series so that a connecting line cannot be established, a point will +automatically be rendered for that data point. This should make it easier to understand what's going on when only receiving a single data point. + +{{< figure src="/static/img/docs/v54/graph_dot_single_point.png" max-width= "800px" >}} + +## Team Preferences + +Grafana v5.4 adds support for customizing home dashboard, timezone and theme for teams, in addition to the existing customization on Organization and user Profile level. + +1. Specifying a preference on User Profile level will override preference on Team and/or Organization level +1. Specifying a preference on Team level will override preference on Organization level. + +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list +of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v6-0.md b/docs/sources/whatsnew/whats-new-in-v6-0.md new file mode 100644 index 00000000..1c07227f --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v6-0.md @@ -0,0 +1,174 @@ ++++ +title = "What's new in Grafana v6.0" +description = "Feature and improvement highlights for Grafana v6.0" +keywords = ["grafana", "new", "documentation", "6.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v6-0/"] +weight = -19 +[_build] +list = false ++++ + +# What's new in Grafana v6.0 + +This update to Grafana introduces a new way of exploring your data, support for log data, and tons of other features. + +The main highlights are: + +- [Explore]({{< relref "#explore" >}}) - A new query focused workflow for ad-hoc data exploration and troubleshooting. +- [Grafana Loki]({{< relref "#explore-and-grafana-loki" >}}) - Integration with the new open source log aggregation system from Grafana Labs. +- [Gauge Panel]({{< relref "#gauge-panel" >}}) - A new standalone panel for gauges. +- [New Panel Editor UX]({{< relref "#new-panel-editor" >}}) improves panel editing + and enables easy switching between different visualizations. +- [Google Stackdriver data source]({{< relref "#google-stackdriver-data-source" >}}) is out of beta and is officially released. +- [Azure Monitor]({{< relref "#azure-monitor-data-source" >}}) plugin is ported from being an external plugin to be a core data source +- [React Plugin]({{< relref "#react-panels-query-editors" >}}) support enables an easier way to build plugins. +- [Named Colors]({{< relref "#named-colors" >}}) in our new improved color picker. +- [Removal of user session storage]({{< relref "#easier-to-deploy-improved-security" >}}) makes Grafana easier to deploy and improves security. + +## Explore + +{{< figure src="/static/img/docs/v60/explore_prometheus.png" max-width="800px" class="docs-image--right" caption="Screenshot of the new Explore option in the panel menu" >}} + +Grafana's dashboard UI is all about building dashboards for visualization. **Explore** strips away all the dashboard and panel options so that you can focus on the query and metric exploration. Iterate until you have a working query and then think about building a dashboard. You can also jump from a dashboard panel into **Explore** and from there do some ad-hoc query exploration with the panel queries as a starting point. + +For infrastructure monitoring and incident response, you no longer need to switch to other tools to debug what went wrong. **Explore** allows you to dig deeper into your metrics and logs to find the cause. Grafana's new logging data source, [Loki](https://github.com/grafana/loki) is tightly integrated into Explore and allows you to correlate metrics and logs by viewing them side-by-side. + +**Explore** is a new paradigm for Grafana. It creates a new interactive debugging workflow that integrates two pillars +of observability—metrics and logs. Explore works with every data source but for Prometheus we have customized the +query editor and the experience to provide the best possible exploration UX. + +### Explore and Prometheus + +Explore features a new [Prometheus query editor](/explore/#prometheus-specific-features). This new editor has improved autocomplete, metric tree selector, +integrations with the Explore table view for easy label filtering, and useful query hints that can automatically apply +functions to your query. There is also integration between Prometheus and Grafana Loki (see more about Loki below) that +enabled jumping between metrics query and logs query with preserved label filters. + +### Explore splits + +Explore supports splitting the view so you can compare different queries, different data sources and metrics and logs side by side! + +{{< figure src="/static/img/docs/v60/explore_split.png" max-width="800px" caption="Screenshot of the new Explore option in the panel menu" >}} + +
+ +### Explore and Grafana Loki + +The log exploration and visualization features in Explore are available to any data source but are currently only implemented by the new open source log +aggregation system from Grafana Lab called [Grafana Loki](https://github.com/grafana/loki). + +Loki is a horizontally-scalable, highly-available, multi-tenant log aggregation system inspired by Prometheus. It is designed to be very cost effective, as it does not index the contents of the logs, but rather a set of labels for each log stream. The logs from Loki are queried in a similar way to querying with label selectors in Prometheus. It uses labels to group log streams which can be made to match up with your Prometheus labels. + +For more information about Grafana Loki, refer to [Github Grafana Loki](https://github.com/grafana/loki) or [Grafana Labs hosted Loki](https://grafana.com/loki). + +The Explore feature allows you to query logs and features a new log panel. In the near future, we will be adding support +for other log sources to Explore and the next planned integration is Elasticsearch. + +
+ +
+ +
+ +## New Panel Editor + +Grafana v6.0 has a completely redesigned UX around editing panels. You can now resize the visualization area if you want +more space for queries/options and vice versa. You can now also change visualization (panel type) from within the new +panel edit mode. No need to add a new panel to try out different visualizations! Check out the +video below to see the new Panel Editor in action. + +
+ +
+ +
+ +### Gauge Panel + +We have created a new separate Gauge panel as we felt having this visualization be a hidden option in the Singlestat panel +was not ideal. When it supports 100% of the Singlestat Gauge features, we plan to add a migration so all +singlestats that use it become Gauge panels instead. This new panel contains a new **Threshold** editor that we will +continue to refine and start using in other panels. + +{{< figure src="/static/img/docs/v60/gauge_panel.png" max-width="600px" caption="Gauge Panel" >}} + +
+ +### React Panels and Query Editors + +A major part of all the work that has gone into Grafana v6.0 has been on the migration to React. This investment +is part of the future-proofing of Grafana's code base and ecosystem. Starting in v6.0 **Panels** and **Data +source** plugins can be written in React using our published `@grafana/ui` sdk library. More information on this +will be shared soon. + +{{< figure src="/static/img/docs/v60/react_panels.png" max-width="600px" caption="React Panel" >}} +
+ +## Google Stackdriver data source + +Built-in support for [Google Stackdriver](https://cloud.google.com/stackdriver/) is officially released in Grafana 6.0. Beta support was added in Grafana 5.3 and we have added lots of improvements since then. + +To get started read the guide: [Using Google Stackdriver in Grafana]({{< relref "../datasources/google-cloud-monitoring/_index.md/" >}}). + +## Azure Monitor data source + +One of the goals of the Grafana v6.0 release is to add support for the three major clouds. Amazon CloudWatch has been a core data source for years and Google Stackdriver is also now supported. We developed an external plugin for Azure Monitor last year and for this release the [plugin](https://grafana.com/plugins/grafana-azure-monitor-datasource) is being moved into Grafana to be one of the built-in data sources. For users of the external plugin, Grafana will automatically start using the built-in version. As a core data source, the Azure Monitor data source is able to get alerting support, in the 6.0 release alerting is supported for the Azure Monitor service, with the rest to follow. + +The Azure Monitor data source integrates four Azure services with Grafana - Azure Monitor, Azure Log Analytics, Azure Application Insights and Azure Application Insights Analytics. + +Please read [Using Azure Monitor in Grafana documentation]({{< relref "../datasources/azuremonitor/" >}}) for more detailed information on how to get started and use it. + +## Provisioning support for alert notifiers + +Grafana now has support for provisioning alert notifiers from configuration files, allowing operators to provision notifiers without using the UI or the API. A new field called `uid` has been introduced which is a string identifier that the administrator can set themselves. This is the same kind of identifier used for dashboards since v5.0. This feature makes it possible to use the same notifier configuration in multiple environments and refer to notifiers in dashboard json by a string identifier instead of the numeric id which depends on insert order and how many notifiers exist in the instance. + +## Easier to deploy and improved security + +Grafana 6.0 removes the need to configure and set up additional storage for [user sessions](/tutorials/ha_setup/#user-sessions). This should make it easier to deploy and operate Grafana in a +high availability setup and/or if you're using a stateless user session store like Redis, Memcache, Postgres or MySQL. + +Instead of user sessions, we've implemented a solution based on short-lived tokens that are rotated frequently. This also replaces the old "remember me cookie" +solution, which allowed a user to be logged in between browser sessions and which have been subject to several security holes throughout the years. +For more information about the short-lived token solution and how to configure it, refer to [short lived token](/auth/overview/#login-and-short-lived-tokens). + +> Please note that due to these changes, all users will be required to login upon next visit after upgrade. + +Besides these changes we have also made security improvements regarding Cross-Site Request Forgery (CSRF) and Cross-site Scripting (XSS) vulnerabilities: + +- Cookies are per default using the [SameSite](/administration/configuration/#cookie-samesite) attribute to protect against CSRF attacks +- Script tags in text panels are per default [disabled](/administration/configuration/#disable-sanitize-html) to protect against XSS attacks + +> **Note:** If you're using [Auth Proxy Authentication](/auth/auth-proxy/) you still need to have user sessions set up and configured +> but our goal is to remove this requirement in the near future. + +## Named Colors + +{{< figure src="/static/img/docs/v60/named_colors.png" max-width="400px" class="docs-image--right" caption="Named Colors" >}} + +We have updated the color picker to show named colors and primary colors. We hope this will improve accessibility and +helps making colors more consistent across dashboards. We hope to do more in this color picker in the future, like showing +colors used in the dashboard. + +Named colors also enables Grafana to adapt colors to the current theme. + +
+ +## Other features + +- The ElasticSearch data source now supports [bucket script pipeline aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-script-aggregation.html). This gives the ability to do per-bucket computations like the difference or ratio between two metrics. +- Support for Google Hangouts Chat alert notifications +- New built in template variables for the current time range in `$__from` and `$__to` + +## Upgrading + +See [upgrade notes](/installation/upgrading/#upgrading-to-v6-0). + +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v6-1.md b/docs/sources/whatsnew/whats-new-in-v6-1.md new file mode 100644 index 00000000..5a4c132f --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v6-1.md @@ -0,0 +1,57 @@ ++++ +title = "What's new in Grafana v6.1" +description = "Feature and improvement highlights for Grafana v6.1" +keywords = ["grafana", "new", "documentation", "6.1", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v6-1/"] +weight = -20 +[_build] +list = false ++++ + +# What's new in Grafana v6.1 + +## Highlights + +### Ad hoc Filtering for Prometheus + +{{< figure class="float-right" max-width="30%" src="/static/img/docs/v61/prometheus-ad-hoc.gif" caption="Ad-hoc filters variable for Prometheus" >}} + +The ad hoc filter feature allows you to create new key/value filters on the fly with autocomplete for both key and values. The filter condition is then automatically applied to all queries on the dashboard. This makes it easier to explore your data in a dashboard without changing queries and without having to add new template variables. + +Other timeseries databases with label-based query languages have had this feature for a while. Recently Prometheus added support for fetching label names from their API and thanks to [Mitsuhiro Tanda](https://github.com/mtanda) implementing it in Grafana, the Prometheus data source finally supports ad hoc filtering. + +Support for fetching a list of label names was released in Prometheus v2.6.0 so that is a requirement for this feature to work in Grafana. + +### Permissions: Editors can own dashboards, folders and teams they create + +When the dashboard folders feature and permissions system was released in Grafana 5.0, users with the editor role were not allowed to administrate dashboards, folders or teams. In the 6.1 release, we have added a configuration option that can change the default permissions so that editors are admins for any Dashboard, Folder or Team they create. + +This feature also adds a new Team permission that can be assigned to any user with the editor or viewer role and enables that user to add other users to the Team. + +We believe that this is more in line with the Grafana philosophy, as it will allow teams to be more self-organizing. This option will be made permanent if it gets positive feedback from the community so let us know what you think in the [issue on GitHub](https://github.com/grafana/grafana/issues/15590). + +To turn this feature on add the following [configuration option](/administration/configuration/#editors-can-admin) to your Grafana ini file in the `users` section and then restart the Grafana server: + +```ini +[users] +editors_can_admin = true +``` + +### List and revoke of user auth tokens in the API + +As the first step of a feature to be able to list a user's signed in devices/sessions and to be able log out those devices from the Grafana UI, support has been added to the [API to list and revoke user authentication tokens](/http_api/admin/#auth-tokens-for-user). + +### Minor Features and Fixes + +This release contains a lot of small features and fixes: + +- A new keyboard shortcut `d l` toggles all Graph legends in a dashboard. +- A small bug fix for Elasticsearch - template variables in the alias field now work properly. +- Some new capabilities have been added for data source plugins that will be of interest to plugin authors: + - a new OAuth pass-through option. + - it is now possible to add user details to requests sent to the dataproxy. +- Heatmap and Explore fixes. + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list of new features, changes, and bug fixes. + +A huge thanks to our community for all the reported issues, bug fixes and feedback. diff --git a/docs/sources/whatsnew/whats-new-in-v6-2.md b/docs/sources/whatsnew/whats-new-in-v6-2.md new file mode 100644 index 00000000..a7321352 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v6-2.md @@ -0,0 +1,94 @@ ++++ +title = "What's new in Grafana v6.2" +description = "Feature and improvement highlights for Grafana v6.2" +keywords = ["grafana", "new", "documentation", "6.2", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v6-2/"] +weight = -21 +[_build] +list = false ++++ + +# What's new in Grafana v6.2 + +For all details please read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +If you use a password for your data sources please read the [upgrade notes](/installation/upgrading/#upgrading-to-v6-2). + +Check out the [demo dashboard](https://play.grafana.org/d/ZvPm55mWk/new-features-in-v6-2?orgId=1) of some the new features in v6.2. + +## Improved security + +Data sources now store passwords and basic auth passwords in `secureJsonData` encrypted by default. Existing data source with unencrypted passwords will keep working. +Read the [upgrade notes](/installation/upgrading/#upgrading-to-v6-2) on how to migrate existing data sources to use encrypted storage. + +To mitigate the risk of [Clickjacking](https://www.owasp.org/index.php/Clickjacking), embedding Grafana is no longer allowed per default. +Read the [upgrade notes](/installation/upgrading/#upgrading-to-v6-2) for further details of how this may affect you. + +To mitigate the risk of sensitive information being cached in browser after a user has logged out, browser caching is now disabled for full page requests. + +## Provisioning + +- Environment variables support, see [Using environment variables](/administration/provisioning/#using-environment-variables) for more information. +- Reload provisioning configs, see [Admin HTTP API](/http_api/admin/#reload-provisioning-configurations) for more information. +- Do not allow deletion of provisioned dashboards +- When trying to delete or save provisioned dashboard, relative file path to the file is shown in the dialog. + +## Official support for Elasticsearch 7 + +Grafana v6.2 ships with official support for Elasticsearch v7, see [Using Elasticsearch in Grafana]({{< relref "../datasources/elasticsearch/#elasticsearch-version" >}}) for more information. + +## Bar Gauge Panel + +Grafana v6.2 ships with a new exciting panel! This new panel, named Bar Gauge, is very similar to the current +Gauge panel and shares almost all it's options. The main difference is that the Bar Gauge uses both horizontal and +vertical space much better and can be more efficiently stacked both vertically and horizontally. The Bar Gauge also +comes with 3 unique display modes, Basic, Gradient, and Retro LED. Read the +[preview article](https://grafana.com/blog/2019/04/11/sneak-preview-of-new-visualizations-coming-to-grafana/) to learn +more about the design and features of this new panel. + +Retro LED display mode +{{< figure src="/assets/img/blog/bargauge/bar_gauge_retro_led.jpg" max-width="800px" caption="Bar Gauge LED mode" >}} + +Gradient mode +{{< figure src="/assets/img/blog/bargauge/gradient.jpg" max-width="800px" caption="Bar Gauge Gradient mode" >}} + +## Improved table data support + +We have been working on improving table support in our new react panels (Gauge and Bar Gauge) and this is ongoing work +that will eventually come to the new Graph and Singlestat and Table panels we are working on. But you can see it already in +the Gauge and Bar Gauge panels. Without any config, you can visualize any number of columns or choose to visualize each +row as its own gauge. + +## Lazy loading of panels out of view + +This has been one of the most requested features for many years and is now finally here! Lazy loading of panels means +Grafana will not issue any data queries for panels that are not visible. This will greatly reduce the load +on your data source backends when loading dashboards with many panels. + +## Panels without title + +Sometimes your panels do not need a title and having that panel header still take up space makes singlestats and +other panels look strange and have bad vertical centering. In v6.2 Grafana will allow panel content (visualizations) +to use the full panel height in case there is no panel title. + +{{< figure src="/static/img/docs/v62/panels_with_no_title.jpg" max-width="800px" caption="Bar Gauge Gradient mode" >}} + +## Minor Features and Fixes + +This release contains a lot of small features and fixes: + +- Explore - Adds user time zone support, reconnect for failing data sources and a fix that prevents killing Prometheus instances when Histogram metrics are loaded. +- Alerting - Adds support for configuring timeout durations and retries, see [configuration](/administration/configuration/#evaluation-timeout-seconds) for more information. +- Azure Monitor - Adds support for multiple subscriptions per data source. +- Elasticsearch - A small bug fix to properly display percentiles metrics in table panel. +- InfluxDB - Support for POST HTTP verb. +- CloudWatch - Important fix for default alias disappearing in v6.1. +- Search - Works in a scope of dashboard's folder by default when viewing dashboard. + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list of new features, changes, and bug fixes. + +A huge thanks to our community for all the reported issues, bug fixes and feedback. + +## Upgrading + +Read important [upgrade notes](/installation/upgrading/#upgrading-to-v6-2). diff --git a/docs/sources/whatsnew/whats-new-in-v6-3.md b/docs/sources/whatsnew/whats-new-in-v6-3.md new file mode 100644 index 00000000..3c15bb02 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v6-3.md @@ -0,0 +1,145 @@ ++++ +title = "What's new in Grafana v6.3" +description = "Feature and improvement highlights for Grafana v6.3" +keywords = ["grafana", "new", "documentation", "6.3", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v6-3/"] +weight = -22 +[_build] +list = false ++++ + +# What's new in Grafana v6.3 + +For all details please read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +## Highlights + +- New Explore features + - [Loki Live Streaming]({{< relref "#loki-live-streaming" >}}) + - [Loki Context Queries]({{< relref "#loki-context-queries" >}}) + - [Elasticsearch Logs Support]({{< relref "#elasticsearch-logs-support" >}}) + - [InfluxDB Logs Support]({{< relref "#influxdb-logs-support" >}}) +- [Data links]({{< relref "#data-links" >}}) +- [New Time Picker]({{< relref "#new-time-picker" >}}) +- [Graph Area Gradients]({{< relref "#graph-gradients" >}}) - A new graph display option! +- Grafana Enterprise + - [LDAP Active Sync]({{< relref "#ldap-active-sync" >}}) - LDAP Active Sync + - [SAML Authentication]({{< relref "#saml-authentication" >}}) - SAML Authentication + +## Explore improvements + +This release adds a ton of enhancements to Explore. Both in terms of new general enhancements but also in +new data source specific features. + +### Loki live streaming + +For log queries using the Loki data source you can now stream logs live directly to the Explore UI. + +### Loki context queries + +After finding a log line through the heavy use of query filters it can then be useful to +see the log lines surrounding the line your searched for. The `show context` feature +allows you to view lines before and after the line of interest. + +### Elasticsearch logs support + +This release adds support for searching and visualizing logs stored in Elasticsearch in the Explore mode. With a special +simplified query interface specifically designed for logs search. + +{{< figure src="/static/img/docs/v63/elasticsearch_explore_logs.png" max-width="600px" caption="New Time Picker" >}} + +Please read [Using Elasticsearch in Grafana]({{< relref "../datasources/elasticsearch/#elasticsearch-version" >}}) for more detailed information on how to get started and use it. + +### InfluxDB logs support + +This release adds support for searching and visualizing logs stored in InfluxDB in the Explore mode. With a special +simplified query interface specifically designed for logs search. + +{{< figure src="/static/img/docs/v63/influxdb_explore_logs.png" max-width="600px" caption="New Time Picker" >}} + +Please read [Using InfluxDB in Grafana]({{< relref "../datasources/influxdb/#querying-logs-beta" >}}) for more detailed information on how to get started and use it. + +## Data Links + +We have simplified the UI for defining panel drilldown links (and renamed them to Panel links). We have also added a +new type of link named `Data link`. The reason to have two different types is to make it clear how they are used +and what variables you can use in the link. Panel links are only shown in the top left corner of +the panel and you cannot reference series name or any data field. + +While `Data links` are used by the actual visualization and can reference data fields. + +Example: + +```url +http://my-grafana.com/d/bPCI6VSZz/other-dashboard?var-server=${__series_name} +``` + +You have access to these variables: + +| Name | Description | +| ----------------------- | -------------------------------------------------------------------------- | +| _${\_\_series_name}_ | The name of the time series (or table) | +| _${\_\_value_time}_ | The time of the point your clicking on (in millisecond epoch) | +| _${\_\_url_time_range}_ | Interpolates as the full time range (i.e. from=21312323412&to=21312312312) | +| _${\_\_all_variables}_ | Adds all current variables (and current values) to the URL | + +You can then click on point in the Graph. + +{{< figure src="/static/img/docs/v63/graph_datalink.png" max-width="400px" caption="New Time Picker" >}} + +For now only the Graph panel supports `Data links` but we hope to add these to many visualizations. + +## New Time Picker + +The time picker has been re-designed and with a more basic design that makes accessing quick ranges more easy. + +{{< figure src="/static/img/docs/v63/time_picker.png" max-width="400px" caption="New Time Picker" >}} + +## Graph Gradients + +Want more eye candy in your graphs? Then the fill gradient option might be for you! Works really well for +graphs with only a single series. + +{{< figure src="/static/img/docs/v63/graph_gradient_area.jpeg" max-width="800px" caption="Graph Gradient Area" >}} + +Looks really nice in light theme as well. + +{{< figure src="/static/img/docs/v63/graph_gradients_white.png" max-width="800px" caption="Graph Gradient Area" >}} + +## Grafana Enterprise + +Substantial refactoring and improvements to the external auth systems has gone in to this release making the features +listed below possible as well as laying a foundation for future enhancements. + +### LDAP Active Sync + +This is a new Enterprise feature that enables background syncing of user information, org role and teams memberships. +This syncing is otherwise only done at login time. With this feature you can schedule how often this user synchronization should +occur. + +For example, lets say a user is removed from an LDAP group. In previous versions of Grafana an admin would have to +wait for the user to logout or the session to expire for the Grafana permissions to update, a process that can take days. + +With active sync the user would be automatically removed from the corresponding team in Grafana or even logged out and disabled if no longer +belonging to an LDAP group that gives them access to Grafana. + +[Read more](/auth/enhanced_ldap/#active-ldap-synchronization). + +### SAML Authentication + +Built-in support for SAML is now available in Grafana Enterprise. + +[See docs]({{< relref "../auth/saml.md" >}}) + +### Team Sync for GitHub OAuth + +When setting up OAuth with GitHub it's now possible to sync GitHub teams with Teams in Grafana. + +[See docs]({{< relref "../auth/github.md" >}}) + +### Team Sync for Auth Proxy + +We've added support for enriching the Auth Proxy headers with Teams information, which makes it possible +to use Team Sync with Auth Proxy. + +[See docs](/auth/auth-proxy/#auth-proxy-authentication). diff --git a/docs/sources/whatsnew/whats-new-in-v6-4.md b/docs/sources/whatsnew/whats-new-in-v6-4.md new file mode 100644 index 00000000..6412224f --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v6-4.md @@ -0,0 +1,145 @@ ++++ +title = "What's new in Grafana v6.4" +description = "Feature and improvement highlights for Grafana v6.4" +keywords = ["grafana", "new", "documentation", "6.4", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v6-4/"] +weight = -23 +[_build] +list = false ++++ + +# What's new in Grafana v6.4 + +For all details please read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +## Highlights + +Grafana 6.4 comes with a lot of new features and enhancements backed with tons of work around the data models and query execution that is going to enable powerful future capabilities. +Some of those new capabilities can already be seen in this release, like sharing query results between panels. + +- [**Explore:** Go back to dashboard (with query changes)]({{< relref "#go-back-to-dashboard-from-explore" >}}) +- [**Explore:** Live tailing improvements]({{< relref "#live-tailing-improvements" >}}) +- **Loki:** Show logs as annotations in dashboard graphs +- **Loki:** Use Loki in dashboard panels +- [**Panels:** New logs panel]({{< relref "#new-logs-panel" >}}) +- [**Panels:** Data links improvements]({{< relref "#data-links-improvements" >}}) +- [**Graph:** Series override to turn constant (point) into a line]({{< relref "#series-override-to turn-constant-into-a-line" >}}) +- [**Dashboard:** Share query results between panels]({{< relref "#share-query-results-between-panels" >}}) +- [**Plugins:** Alpha version of grafana-toolkit]({{< relref "#alpha-version-of-grafana-toolkit" >}}) +- [**Image Rendering:** PhantomJS deprecation]({{< relref "#phantomjs-deprecation" >}}) +- [**Docker:** Alpine based docker image]({{< relref "#alpine-based-docker-image" >}}) +- [**LDAP:** Debug UI]({{< relref "#ldap-debug-ui" >}}) +- [**Enterprise**: Reporting]({{< relref "#reporting" >}}) +- [**Enterprise**: GitLab OAuth Team Sync support]({{< relref "#gitlab-oauth-team-sync-support" >}}) +- [**Enterprise**: Teams and LDAP Improvements]({{< relref "#ldap-teams" >}}) + +### Go back to dashboard from Explore + +To help accelerate workflows that involve regularly switching from Explore to a dashboard and vice-versa, we've added the ability to return to the origin dashboard +after navigating to Explore from the panel's dropdown. + +{{< figure src="/static/img/docs/v60/explore_panel_menu.png" caption="Screenshot of the new Explore Icon" >}} + +After you've navigated to Explore, you should notice a "Back" button in the Explore toolbar. + + + +Simply clicking the button will return you to the origin dashboard, or, if you'd like to bring changes you make in Explore back to the dashboard, simply click +the arrow next to the button to reveal a "Return to panel with changes" menu item. + + + +### Live tailing improvements + +With 6.4 version you can now pause the live tail view to see the last 1000 lines of logs without being interrupted by new logs coming in. You can either pause manually with pause button or the live tailing will automatically pause when you scroll up to see older logs. To resume you just hit the resume button to continue live tailing. + +We also introduced some performance optimizations to allow live tailing of higher throughput log streams and various UI fixes and improvements like more consistent styling and fresh logs highlighting. + + + +### New Logs Panel + +The logs panel shows log lines from datasources that support logs, e.g., Elastic, Influx, and Loki. Typically you would use this panel next to a graph panel to display the log output of a related process. + + + +Limitations: Even though Live tailing can be enabled on logs panels in dashboards, we recommend using Live tailing in Explore. On dashboards, the refresher at the top of the page should be used instead to keep the data of all panels in sync. Note that the logs panel is still beta and we're looking to get feedback. + +## Data Links improvements + +With Grafana 6.3 we introduced a new way of creating [Data Links](https://grafana.com/blog/2019/08/27/new-in-grafana-6.3-easy-to-use-data-links/). +Grafana 6.4 improves Data Links and adds them to the Gauge and Bar Gauge and panels. + +With Data Links you can define dynamic links to other dashboards and systems. The link can now reference template variables and query results like series name and labels, field name, value and time. + +For more information about Data Links, refer to [data link](https://grafana.com/docs/features/panels/graph/#data-link) + +## Series override to turn constant into a line + +Some graph query results are made up only of one datapoint per series but can be shown in the graph panel with the help of [series overrides](/features/panels/graph/#series-overrides). +To show a horizontal line through the Y-value of the datapoint across the whole graph, add a series override and select `Transform > constant`. + + + +## Share query results between panels + +Grafana 6.4 continues the work started in 6.3 of creating a data model and query execution lifecycle that can support robust analytics and streaming. These changes are mostly structural and lay the foundation for powerful features in future releases. + +The first new feature all these changes have enabled is the ability to share query results between panels. So for example if you have an expensive query you can visualize the same results in a graph, table and singlestat panel. To reuse another panel’s query result select the data source named `-- Dashboard --` and then select the panel. + +To make the sharing of query results even more powerful we are introducing a transformation step as well that allows you to select specific parts of the query result and transform it. This new transformation feature is in [alpha](https://grafana.com/docs/administration/configuration/#enable-alpha) state and has to be enabled in the config file. + +DataFrame, our primary data model, has now a [columnar](https://en.wikipedia.org/wiki/Column-oriented_DBMS) layout. This +will support easier frontend processing. The DataSource query interface has been updated to better support streaming. +The result can now either return a `Promise` or `Observable`. Be on the lookout for more on live data +streaming in the future! + +## Alpha version of grafana-toolkit + +[grafana-toolkit](https://www.npmjs.com/package/@grafana/toolkit/v/6.4.0-beta.1) is our attempt to simplify the life of plugin developers. It’s a CLI that helps them focus on the core value of their plugin rather than the ceremony around setting up the environment, configs, tests and builds. It’s available as an NPM package under `next` tag. + +You can read more about the grafana-toolkit [in the Readme](https://github.com/grafana/grafana/blob/master/packages/grafana-toolkit/README.md) and play with it by trying out our [react panel](https://github.com/grafana/simple-react-panel) or [angular panel](https://github.com/grafana/simple-angular-panel) templates. + +## PhantomJS deprecation + +[PhantomJS](https://phantomjs.org/), which is used for rendering images of dashboards and panels, have been deprecated and will be removed in a future Grafana release. A deprecation warning will from now on be logged when Grafana starts up if PhantomJS is in use. + +Please consider migrating from PhantomJS to the [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer). + +## Alpine-based Docker image + +Grafana’s Docker image is now based on Alpine 3.10 and should from now on report zero vulnerabilities when scanning the image for security vulnerabilities. + +## LDAP Debug UI + +After listening to customer feedback, we have been working at improving the experience to set up authentication and synchronization with LDAP. We're happy to present the new LDAP Debug View. + +You'll be able to see how a user authenticating with LDAP would be mapped and whether your LDAP integration is working correctly. Furthermore, it provides a simpler method to test your integration with LDAP server(s) and have a clear view of how attributes are mapped between both systems. + +The feature is currently limited to Grafana Server Admins. + +For more information on how to use this new feature, follow the [guide]({{< relref "../auth/ldap.md#ldap-debug-view" >}}). + +## Grafana Enterprise + +### Reporting + +A common request from Enterprise users have been to be able to set up reporting for Grafana, and now it’s here. A report is simply a PDF of a Grafana dashboard, outside of just generating a PDF you can set up a schedule so that you can get the report emailed to yourself (or whoever is interested) whenever it suits you. + +This feature is currently limited to Organization Admins. + +{{< figure src="/static/img/docs/v64/reports.jpeg" max-width="500px" caption="Reporting" >}} + +### GitLab OAuth Team Sync support + +GitLab OAuth gets support for Team Sync, making it possible to synchronize your GitLab Groups with Teams in Grafana. + +[Read more about Team Sync](https://grafana.com/docs/auth/team-sync/). + +## Upgrading + +See [upgrade notes](/installation/upgrading/#upgrading-to-v6-4). + +## Changelog + +Check out the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v6-5.md b/docs/sources/whatsnew/whats-new-in-v6-5.md new file mode 100644 index 00000000..eb3c8f0e --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v6-5.md @@ -0,0 +1,209 @@ ++++ +title = "What's new in Grafana v6.5" +description = "Feature and improvement highlights for Grafana v6.5" +keywords = ["grafana", "new", "documentation", "6.5", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v6-5/"] +weight = -24 +[_build] +list = false ++++ + +# What's new in Grafana v6.5 + +For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +## Highlights + +Grafana 6.5 comes with a lot of new features and enhancements: + +- [**Docker:** Ubuntu-based images and more]({{< relref "#ubuntu-based-docker-images" >}}) +- [**CloudWatch:** Major rewrite and lots of enhancements]({{< relref "#cloudwatch-data-source-improvements" >}}) +- [**Templating:** Dynamic typeahead queries using $__searchFilter]({{< relref "#dynamic-typeahead-support-in-query-variables" >}}) +- [**Graphite:** Support for additional Metrictank functionality]({{< relref "#graphite-support-for-additional-metrictank-functionality" >}}) +- [**Explore:** New log row details view]({{< relref "#explore-logs-log-row-details" >}}) +- [**Explore:** Turn parts of log message into a link using derived fields]({{< relref "#loki-explore-derived-fields" >}}) +- [**Explore:** Time-sync of split views]({{< relref "#time-sync-of-split-views-in-explore" >}}) +- [**Explore**: Hover/tooltip support in graphs]({{< relref "#explore-metrics-graph-hover-tooltip" >}}) +- [**Azure Monitor**: Alerting support for Azure Application Insights]({{< relref "#alerting-support-for-azure-application-insights" >}}) +- [**Provisioning**: Allow saving of provisioned dashboards from UI]({{< relref "#allow-saving-of-provisioned-dashboards-from-ui" >}}) +- [**Auth Proxy:** Mix auth proxy with Grafana login token and session cookie]({{< relref "#mix-auth-proxy-with-grafana-login-token-and-session-cookie" >}}) +- [**OAuth:** Generic OAuth now supports role mapping]({{< relref "#generic-oauth-role-mapping" >}}) +- [**Image Rendering:** Quick update since Grafana 6.4]({{< relref "#image-renderer-plugin" >}}) + +### Ubuntu-based Docker images + +In Grafana [v6.4]({{< relref "whats-new-in-v6-4/#alpine-based-docker-image" >}}), we switched the Grafana Docker image from Ubuntu to Alpine. This change provides a more secure and lightweight Docker image. + +This change has received both negative and positive feedback as well as some bug reports. We learned that switching to an Alpine-based Docker image was a big breaking change for a lot of users. We should have more clearly highlighted this in blog post, release notes, changelog, and the [Docker Hub readme](https://hub.docker.com/r/grafana/grafana). + +We also broke the Docker images for ARM, but this is fixed in Grafana v6.5. + +Grafana Docker images should be as secure as possible by default and that’s why the Alpine-based Docker images will continue to be the Grafana default (`grafana/grafana:`). With that said, it’s good to give users options, and that’s why starting from Grafana v6.5, Ubuntu-based Docker images are also (`grafana/grafana:-ubuntu`) available. + +Read more about [Installing using Docker]({{< relref "../installation/docker/" >}}). + +### CloudWatch data source improvements + +In this release, several feature improvements and additions were made in the CloudWatch data source. This work has been done in collaboration with the Amazon CloudWatch team. + +#### GetMetricData API + +For Grafana version 6.5 or higher, all API requests to GetMetricStatistics have been replaced with calls to GetMetricData, following Amazon’s [best practice to use the GetMetricData API](https://aws.amazon.com/premiumsupport/knowledge-center/cloudwatch-getmetricdata-api) instead of GetMetricStatistics, because data can be retrieved faster at scale with GetMetricData. This change provides better support for CloudWatch metric math and enables the use of automatic search expressions. + +While GetMetricStatistics qualified for the CloudWatch API free tier, this is not the case for GetMetricData calls. For more information, please refer to the [CloudWatch pricing page](https://aws.amazon.com/cloudwatch/pricing/). + +#### Dynamic queries using dimension wildcards + +In Grafana 6.5 or higher, you can monitor a dynamic list of metrics by using the asterisk (\*) wildcard for one or more dimension values. + +{{< figure src="/static/img/docs/v65/cloudwatch-dimension-wildcard.png" max-width="800px" class="docs-image--right" caption="CloudWatch dimension wildcard" >}} + +The example queries all metrics in the namespace `AWS/EC2` with a metric name of `CPUUtilization` and _any_ value for the `InstanceId` dimension. This can help you monitor metrics for AWS resources, like EC2 instances or containers. For example, when new instances get created as part of an auto scaling event, they automatically appear in the graph without you having to track new instance IDs. You can click `Show Query Preview` to see the search expression that is automatically built to support wildcards. To learn more about search expressions, visit the [CloudWatch documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/search-expression-syntax.html). + +By default, the search expression is defined in such a way that the queried metrics must match the defined dimension names exactly. This means that in the example it only returns metrics with exactly one dimension with name ‘InstanceId’. + +You can untoggle `Match Exact` to include metrics that have other dimensions defined. Turning off `Match Exact` also creates a search expression even if you don’t use wildcards. We simply search for any metric that match at least the namespace, metric name, and all defined dimensions. + +#### Deep linking from Grafana panels to the CloudWatch console + +{{< figure src="/static/img/docs/v65/cloudwatch-deep-linking.png" max-width="500px" class="docs-image--right" caption="CloudWatch deep linking" >}} + +Left-clicking a time series in the panel displays a context menu with a link to `View in CloudWatch console`. Clicking that link opens the CloudWatch console and displays all the metrics for that query. If you are not currently logged in to the CloudWatch console, then the link opens the login page. The link is valid for any account, but it only displays the right metrics if you are logged in to the account that corresponds to the selected data source in Grafana. + +This feature is not available for metrics based on math expressions. + +#### Improved feedback when throttling occurs + +If the [limit of the GetMetricData API](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_limits.html) is reached, either the transactions per second limit or the data points per second limit, then a throttling error will be returned by the CloudWatch API. Throttling limits are defined per account and region, so the alert modal indicates which data source got throttled in which region. A link to request a limit increase for the affected region is provided, but you will have to log in to the correct account. For example, for us-east-1, a limit increase can be requested on [AWS console](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/monitoring/quotas/L-5E141212). + +#### Multi-value template variables now use search expressions + +When defining dimension values based on multi-valued template variables, we now use search expressions to query for the matching metrics. This enables the use of multiple template variables in one query and also allows you to use template variables for queries that have the `Match Exact` option disabled. + +Search expressions are currently limited to 1024 characters, so your query may fail if you have a long list of values. We recommend using the asterisk (\*) wildcard instead of the `All` option if you want to query all metrics that have any value for a certain dimension name. + +The use of multi-valued template variables is only supported for dimension values. Using multi-valued template variables for `Region`, `Namespace`, or `Metric Name` is not supported. + +#### Curated Dashboards + +The updated CloudWatch data source is shipped with pre-configured dashboards for five of the most popular AWS services: + +- Amazon Elastic Compute Cloud `Amazon EC2` +- Amazon Elastic Block Store `Amazon EBS` +- AWS Lambda `AWS Lambda` +- Amazon CloudWatch Logs `Amazon CloudWatch Logs` +- Amazon Relational Database Service `Amazon RDS` + +To import the pre-configured dashboards, go to the configuration page of your CloudWatch data source and click on the `Dashboards` tab. Click `Import` for the dashboard you would like to use. To customize the dashboard, we recommend to save the dashboard under a different name, because otherwise the dashboard will be overwritten when a new version of the dashboard is released. + +{{< figure src="/static/img/docs/v65/cloudwatch-dashboard-import.png" max-width="600px" caption="CloudWatch dashboard import" >}} + +### Dynamic typeahead support in query variables + +If you have a query variable that has many thousands of values it can be quite slow to search for a specific value in the dropdown. This is due to the fact that all that search filtering is happening in the browser. + +Using `__searchFilter` in the template variable query field you can filter the query results based on what the user types in the variable dropdown input. When nothing has been entered by the user the default value for `__searchFilter` is `*` , `.*` or `%` depending on data source and formatting option. + +The example below shows how to use `__searchFilter` as part of the query field to enable searching for `server` while the user types in the dropdown select box. + +Query + +```bash +apps.$app.servers.$__searchFilter +``` + +TagValues + +```bash +tag_values(server, server=~${__searchFilter:regex}) +``` + +This feature is currently only supported by [Graphite]({{< relref "../datasources/graphite/#using-searchfilter-to-filter-results-in-query-variable" >}}), [MySQL]({{< relref "../datasources/mysql/#using-searchfilter-to-filter-results-in-query-variable" >}}) and [Postgres]({{< relref "../datasources/postgres/#using-searchfilter-to-filter-results-in-query-variable" >}}) data sources. + +### Graphite: Support for additional Metrictank functionality + +The Graphite data source now has an option to enable extra functionality when using [Metrictank](https://grafana.com/oss/metrictank/) as a Graphite datastore. +In the Datasource configuration for Graphite, you can change the type to Metrictank. +Metrictank returns 2 kinds of additional metadata along its responses: + +- **Performance information:** Time spent querying index, fetching data, running processing functions, the number of series and points fetched, cache hits/misses, etc. This can be useful for optimizing queries or tuning the chunk cache. +- **Lineage information about the returned series:** Which archive was fetched from (raw or rollup), which (if any) runtime consolidation was applied (using which processing function), etc. This is very useful information for anyone trying to understand how their data was generated and why it may not look as expected. + +To see the metadata response from Metrictank you can inspect the response using the Query Inspector found in the panel queries tab. +Grafana 6.5 includes a new `Panel Inspector` in alpha/preview where you also can see the metadata response from Metrictank. +You can try it out by enabling a feature flag in the Grafana configuration file: + +```bash +[feature_toggles] +enable = inspect +``` + +{{< figure src="/static/img/docs/v65/panel-inspector.png" max-width="400px" caption="New Panel Inspector modal" >}} + +In Grafana 6.6, this will have a more user friendly display. In the future, additional Metrictank functionality will become available when the Graphite datasource option is set to the `Metrictank` type. + +### Explore/Metrics: Graph hover/tooltip + +We finally got around to implementing the series hover that shows values of the timeseries you hover over. This has been a requested feature ever since Explore was released. The graph component has been rewritten from scratch, making it more composable for future interactions with the graph data. + +{{< figure src="/static/img/docs/v65/explore_tooltip.png" max-width="500px" caption="Explore graph tooltip/hover" >}} + +### Explore/Logs: Log row details + +We have massively simplified the way we display both log row labels/fields as well as parsed fields by putting them into an extendable area in each row. + +So far labels had been squashed into their own column, making long label values difficult to read or interact with. Similarly, the parsed fields (available for logfmt and JSON structured logs) were too fiddly for mouse interaction. To solve this we took both and put them into a collapsed area below each row for more robust interaction. We have also added the ability to filter out labels, i.e., turn them into a negative filter on click (in addition to a positive filter). + +{{< figure src="/static/img/docs/v65/explore_log_details.gif" caption="Explore Log row details" >}} + +### Loki/Explore: Derived fields + +Derived fields allow any part of a log message to be turned into a link. Leaning on the concept of data links for graphs, we've extended the log result viewer in Explore to turn certain parsed fields into a link, based on a pattern to match. + +This allows you to turn an occurrence of e.g., `traceId=624f706351956b81` in your log line, into a link to your distributed tracing system to view that trace. The configuration for the patterns to match can be found in the datasource settings. + +This release starts with support for Loki, but we will bring this concept to other data sources soon. + +### Time-sync of split views in Explore + +In the Explore split view, you can now link the two timepickers so that if you change one, the other gets changed as well. This helps with keeping start and end times of the split view queries in sync and will ensure that you're looking at the same time interval in both split panes. + +{{< figure src="/static/img/docs/v65/explore_time_sync.gif" caption="Time-sync of split views in Explore" >}} + +### Alerting support for Azure Application Insights + +The [Azure Monitor]({{< relref "../datasources/azuremonitor/" >}}) data source supports multiple services in the Azure cloud. Before Grafana v6.5, only the Azure Monitor service had support for [Grafana Alerting]({{< relref "../alerting" >}}). In Grafana 6.5, alerting support has been implemented for the [Application Insights service]({{< relref "../datasources/azuremonitor/#querying-the-application-insights-service" >}}). + +### Allow saving of provisioned dashboards from UI + +Historically it has been possible to make changes to a provisioned dashboard in the Grafana UI. However, it hasn't been possible to save the changes without manual intervention. In Grafana 6.5 we introduce a new dashboard provisioning setting named `allowUiUpdates`. If `allowUiUpdates` is set to `true` and you make changes to a provisioned dashboard, you can save the dashboard and the changes will be persisted to the Grafana database. + +Read more about this new feature in [Provisioning Grafana]({{< relref "../administration/provisioning/#making-changes-to-a-provisioned-dashboard" >}}). + +### Mix auth proxy with Grafana login token and session cookie + +With the new setting, `enable_login_token`, set to true Grafana will, after successful auth proxy header validation, assign the user a login token and cookie. You only have to configure your auth proxy to provide headers for the /login route. Requests via other routes will be authenticated using the cookie. + +Read more about this new feature in [Auth Proxy Authentication]({{< relref "../auth/auth-proxy/#login-token-and-session-cookie" >}}) + +### Generic OAuth role mapping + +Grafana 6.5 makes it possible to configure Generic OAuth to map a certain response from OAuth provider to a certain Grafana organization role, similar to the existing [LDAP Group Mappings]({{< relref "../auth/ldap/#group-mappings" >}}) feature. The new setting is named `role_attribute_path` and expects a [JMESPath](http://jmespath.org/) expression. + +Read more about this new feature in [Generic OAuth Authentication]({{< relref "../auth/generic-oauth/" >}}) and make sure to check out the [JMESPath examples]({{< relref "../auth/generic-oauth/#jmespath-examples" >}}). + +### Image renderer plugin + +Since we announced the deprecation of PhantomJS and the new [Image Renderer Plugin](https://grafana.com/grafana/plugins/grafana-image-renderer) in Grafana [6.4]({{< relref "whats-new-in-v6-4/#phantomjs-deprecation" >}}), we’ve received bug reports and valuable feedback. + +In Grafana 6.5 we’ve updated documentation to make it easier to understand how to install and troubleshoot possible problems. Read more about [Image Rendering]({{< relref "../image-rendering/" >}}). + +Please try the [Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer) and let us know what you think. + +## Upgrading + +See [upgrade notes]({{< relref "../installation/upgrading/#upgrading-to-v6-5" >}}). + +## Changelog + +Check out [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) for a complete list of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v6-6.md b/docs/sources/whatsnew/whats-new-in-v6-6.md new file mode 100644 index 00000000..100c84eb --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v6-6.md @@ -0,0 +1,218 @@ ++++ +title = "What's new in Grafana v6.6" +description = "Feature and improvement highlights for Grafana v6.6" +keywords = ["grafana", "new", "documentation", "6.6", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v6-6/"] +weight = -25 +[_build] +list = false ++++ + +# What's new in Grafana v6.6 + +For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +## Highlights + +Grafana 6.6 comes with a lot of new features and enhancements: + +- [**Panels:** New stat panel]({{< relref "#new-stat-panel" >}}) +- [**Panels:** Auto min/max for Bar Gauge/Gauge/Stat]({{< relref "#auto-min-max" >}}) +- [**Panels:** News panel]({{< relref "#news-panel" >}}) +- [**Panels:** Custom data units]({{< relref "#custom-data-units" >}}) +- [**Panels:** Bar Gauge unfilled option]({{< relref "#bar-gauge-unfilled-option" >}}) +- [**TimePicker:** New design & features]({{< relref "#new-time-picker" >}}) +- [**Alerting enhancements**]({{< relref "#alerting-enhancements" >}}) +- [**Explore:** Added log message line wrapping options for logs]({{< relref "#explore-logs-panel-log-message-line-wrapping-options" >}}) +- [**Explore:** Column with unique log labels ]({{< relref "#explore-logs-panel-column-with-unique-log-labels" >}}) +- [**Explore:** Context tooltip]({{< relref "#explore-context-tooltip" >}}) +- **Explore:** Added ability to specify step with Prometheus queries +- **Graphite:** Added Metrictank dashboard to Graphite datasource +- **Loki:** Support for template variable queries +- **Postgres/MySQL/MSSQL:** Added support for region annotations +- [**Security:** Added disabled option for cookie sameSite attribute]({{< relref "#cookie-management-modifications" >}}) +- **TablePanel, GraphPanel:** Exclude hidden columns from CSV +- [**Enterprise:** White labeling]({{< relref "#enterprise-white-labeling" >}}) +- [**Enterprise:** APT and YUM repositories]({{< relref "#enterprise-apt-and-yum-repositories" >}}) +- [**Stackdriver:** Meta labels]({{< relref "#stackdriver-meta-labels" >}}) +- [**CloudWatch:** Calculate period based on time range]({{< relref "#cloudwatch-calculate-period-based-on-time-range" >}}) +- [**CloudWatch:** Display partial result in graph when max DP/call limit is reached]({{< relref "#cloudwatch-display-partial-result-in-graph-when-max-data-points-per-call-limit-is-reached" >}}) + +## New stat panel + +{{< figure src="/static/img/docs/v66/stat_panel_dark2.png" max-width="1024px" caption="Stat panel" >}} + +This release adds a new panel named `Stat`. This panel is designed to replace the current `Singlestat` as the primary way to show big single number panels along with a sparkline. This panel is of course building on our new panel infrastructure and option design. So, you can use the new threshold UI and data links. It also supports the same repeating feature as the Gauge and Bar Gauge panels, meaning it will repeat a separate visualization for every series or row +in the query result. + +Key features: + +- Automatic font size handling +- Automatic layout handling based on panel size +- Colors based on thresholds that adapt to light or dark theme +- Data links support +- Repeats horizontally or vertically for every series, row, or column + +Here is how it looks in light theme: + +{{< figure src="/static/img/docs/v66/stat_panel_light.png" max-width="1024px" caption="Stat panel" >}} + +## Auto min-max + +For the panels Gauge, Bar Gauge, and Stat, you can now leave the min and max settings empty. Grafana will, in that case, calculate the min and max based on all the data. + +## News panel + +This panel shows RSS feeds as news items in the default home dashboard for v6.6. Add it to your custom home dashboards to keep up-to-date with Grafana news, or switch the default RSS feed to one of your choice. + +{{< figure src="/static/img/docs/v66/news_panel.png" max-width="600px" caption="News panel" >}} + +## Custom data units + +A top feature request for years is now finally here. All panels now support custom units. Type any text in the unit picker and select the `Custom: ` option. By default, the text will be used as a suffix unit. If you want a custom prefix, then type `prefix: ` to make the custom unit appear before the value. If you want a custom SI unit (with auto SI suffixes) specify `si:Ups`. A value like 1000 will be rendered as `1 kUps`. + +{{< figure src="/static/img/docs/v66/custom_unit_burger1.png" max-width="600px" caption="Custom unit" >}} + +You can also paste a native emoji in the unit picker and pick it as a custom unit: + +{{< figure src="/static/img/docs/v66/custom_unit_burger2.png" max-width="600px" caption="Custom unit emoji" >}} + +## Bar Gauge unfilled option + +The Bar Gauge visualization has a new display option: `Unfilled`. This new option is enabled by default, so it will change how this visualization is displayed on old dashboards. If you prefer the old default -- in which an unfilled area is not shown, and the value follows directly after -- you have to update the visualization settings. +{{< figure src="/static/img/docs/v66/bar_gauge_unfilled.png" max-width="900px" caption="Bar gauge unfilled" >}} + +## New time picker + +The time picker has gotten a major design update. Key changes: + +- Quickly access the absolute from and to input fields without an extra click. +- Calendar automatically shows when from or to inputs have focus. +- A single calendar view can be used to select and show the from and to date. +- You can now select recent absolute ranges. + +{{< figure src="/static/img/docs/v66/time_picker_update.png" max-width="700px" caption="New time picker" >}} + +## Alerting enhancements + +- We have introduced a new configuration for enforcing a minimal interval between evaluations to reduce load on the backend. +- The email notifier can now optionally send a single email to all recipients. +- OpsGenie, PagerDuty, Threema, and Google Chat notifiers have been updated to send additional information. + +## Cookie management modifications + +In order to align with a [change in Chrome 80](https://www.chromestatus.com/feature/5088147346030592), a breaking change has been introduced to Grafana's [`cookie_samesite` setting]({{< relref "../administration/configuration.md#cookie-samesite" >}}). Grafana now properly renders cookies with the `SameSite=None` attribute when this setting is `none`. The previous behavior of `none` was to omit the `SameSite` attribute from cookies. Grafana will use the previous behavior when `cookie_samesite` is set to `disabled`. + +Read more about this in the [upgrade notes]({{< relref "../installation/upgrading/#important-changes-regarding-samesite-cookie-attribute" >}}). + +## Explore/Logs Panel: Log message line wrapping options + +We introduced the wrap-lines option for logs because as for some of our users feel it's more efficient to see one line per log message. The wrapped-line option is set as a default; the unwrapped setting results in horizontal scrolling. + +{{< figure src="/static/img/docs/v66/explore_wrap_lines.gif" max-width="600px" caption="Log message line wrapping" >}} + +## Explore/Logs Panel: Column with unique log labels + +After feedback from our community, we have decided to reintroduce a labels column. However, for better readability and usefulness, we have transformed it into a Unique labels column which includes only non-common labels. All common labels are displayed above. + +{{< figure src="/static/img/docs/v66/explore_labels_column.png" max-width="600px" caption="Unique log labels column" >}} + +## Explore: Context tooltip + +Isolating a series from a big set of lines in a graph is important for drill-downs. That's why we have implemented the context tooltip in Explore, which allows you to copy data and labels from it to further refine the query. + +{{< figure src="/static/img/docs/v66/explore_context_tooltip.png" max-width="600px" caption="Explore context tooltip" >}} + +## Enterprise: White labeling + +This release adds new white labeling options to the grafana.ini file (can also be set via ENV variables). + +```bash +[white_labeling] +# Set to complete URL to override login logo +login_logo = https://my.logo.url/images/logo.png + +# Set to complete css background expression to override login background +login_background = url(http://www.bhmpics.com/wallpapers/starfield-1920x1080.jpg) + +# Set to complete URL to override menu logo +menu_logo = https://my.logo.url/images/logo_icon.png + +# Set to complete URL to override fav icon (icon shown in browser tab) +fav_icon = https://my.logo.url/images/logo_icon_32px.png + +# Set to complete URL to override apple/ios icon +apple_touch_icon = https://my.logo.url/images/logo_icon_32px.png + +# Below is an example for how to replace the default footer & help links with 2 custom links +footer_links = support guides +footer_links_support_text = Support +footer_links_support_url = http://your.support.site +footer_links_guides_text = Guides +footer_links_guides_url = http://your.guides.site +``` + +Customize the login page, side menu bar, and footer links. + +{{< figure src="/static/img/docs/v66/whitelabeling_1.png" max-width="700px" caption="White labeling example" >}} + +## Enterprise APT and YUM repositories + +Now you can install the enterprise edition from the APT and YUM repository. The following table shows the APT repository for each Grafana version (for instructions read the [installation notes]({{< relref "../installation/debian/#install-from-apt-repository" >}})) : + +| Grafana Version | Package | Repository | +| ------------------------- | ------------------ | --------------------------------------------------------- | +| Grafana OSS | grafana | `https://packages.grafana.com/oss/deb stable main` | +| Grafana OSS (Beta) | grafana | `https://packages.grafana.com/oss/deb beta main` | +| Grafana Enterprise | grafana-enterprise | `https://packages.grafana.com/enterprise/deb stable main` | +| Grafana Enterprise (Beta) | grafana-enterprise | `https://packages.grafana.com/enterprise/deb beta main` | + +The following table shows the YUM repositories for each Grafana version (for instructions read the [installation notes]({{< relref "../installation/rpm/#install-from-yum-repository" >}})) : + +| Grafana Version | Package | Repository | +| ------------------------- | ------------------ | -------------------------------------------------- | +| Grafana OSS | grafana | `https://packages.grafana.com/oss/rpm` | +| Grafana OSS (Beta) | grafana | `https://packages.grafana.com/oss/rpm-beta` | +| Grafana Enterprise | grafana-enterprise | `https://packages.grafana.com/enterprise/rpm` | +| Grafana Enterprise (Beta) | grafana-enterprise | `https://packages.grafana.com/enterprise/rpm-beta` | + +We recommend all users to install the Enterprise Edition of Grafana, which can be seamlessly upgraded with a Grafana Enterprise [subscription](https://grafana.com/products/enterprise/?utm_source=grafana-install-page). + +## Stackdriver: Meta labels + +From now on it will be possible to utilize meta data label in "group bys", filters and in the alias field. Unfortunately, there's no API to retrieve all the labels, but the group by field dropdown comes with a pre-defined list of common system labels. User labels cannot be pre-defined, but it's possible to enter them manually in the group by field. If a meta data label, user label or system label, is included in the group by segment, it will be possible to create filters based on it and to expand its value on the alias field. + +{{< figure src="/static/img/docs/v66/metadatalabels.gif" max-width="800px" caption="Stackdriver meta labels" >}} + +## CloudWatch: Calculate period based on time range + +When the period field was left blank in Grafana 6.5, it would default to 60 seconds. In case users issued queries with a large time span, there was a high risk that they would reach the 100,800 data points per request limit in the Get Metric Data (GMD) API. When the period field is left blank in Grafana 6.6, the period will be calculated automatically based on the time range. The formula that is used is `time range in seconds / 2000`, and then we snap to next higher value in an array of pre-defined periods `[60, 300, 900, 3600, 21600, 86400]`. This will reduce the risk for receiving a `Too many datapoints requested` error in the panel. + +## CloudWatch: Display partial result in graph when max data points per call limit is reached + +In case all queries in a GMD call are metric stat (not using math expressions), Grafana will paginate the response until all data points are received. But pagination is not supported in case a math expression is being used, so in that case it's not possible to receive more than 100,800 data points. Previously when that limit was reached, we only displayed an error message. In Grafana 6.6, we also display the 100,800 data points that were received in the graph. + +## Upgrading + +See [upgrade notes]({{< relref "../installation/upgrading/#upgrading-to-v6-6" >}}). + +## Changelog + +Check out [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) for a complete list of new features, changes, and bug fixes. + +## Notice about upcoming changes in backendSrv for plugin authors + +In our mission to migrate away from AngularJS to React we have removed all AngularJS dependencies in the core data retrieval service `backendSrv`. This change is already in master and will be introduced in the next `major` Grafana release. + +Removing the AngularJS dependencies in `backendSrv` has the unfortunate side effect of AngularJS digest no longer being triggered for any request made with `backendSrv`. Because of this, external plugins using `backendSrv` directly may suffer from strange behaviour in the UI. + +To remedy this issue as a plugin author you need to trigger the digest after a direct call to `backendSrv`. + +Example: + +```js +backendSrv.get(‘http://your.url/api’).then(result => { + this.result = result; + this.$scope.$digest(); +}); +``` diff --git a/docs/sources/whatsnew/whats-new-in-v6-7.md b/docs/sources/whatsnew/whats-new-in-v6-7.md new file mode 100644 index 00000000..af3918a7 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v6-7.md @@ -0,0 +1,98 @@ ++++ +title = "What's New in Grafana v6.7" +description = "Feature and improvement highlights for Grafana v6.7" +keywords = ["grafana", "new", "documentation", "6.7", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v6-7/"] +weight = -26 +[_build] +list = false ++++ + +# What's new in Grafana v6.7 + +This topic includes the release notes for the Grafana v6.7. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +Grafana 6.7 comes with a lot of new features and enhancements: + +- [**Dashboard:** Enforce minimum refresh interval]({{< relref "#enforce-minimum-dashboard-refresh-interval" >}}) +- **Data source:** Google Sheets data source +- [**Explore:** Query history]({{< relref "#query-history" >}}) +- [**Authorization:** Azure OAuth]({{< relref "#azure-oauth" >}}) +- [**Stackdriver:** Project Selector]({{< relref "#stackdriver-project-selector" >}}) +- [**Enterprise:** White Labeling for application title]({{< relref "#white-labeling-for-application-title" >}}) +- [**Enterprise:** Reporting configuration for timeout and concurrency]({{< relref "#reporting-configuration-for-timeout-and-concurrency" >}}) +- [**Enterprise:** Export dashboard as pdf]({{< relref "#export-dashboard-as-pdf" >}}) +- [**Enterprise:** Report landscape mode]({{< relref "#report-landscape-mode" >}}) +- [**Enterprise:** Azure OAuth Team Sync support]({{< relref "#azure-oauth-team-sync-support" >}}) + +## General features + +General features are included in all Grafana editions. + +### Query history + +> BETA: Query history is a beta feature. It is local to your browser and is not shared with others. + +Query history is a new feature that lets you view and interact with the queries that you have previously run in Explore. You can add queries to the Explore query editor, write comments, create and share URL links, star your favorite queries, and much more. Starred queries are displayed in Starred tab, so it is easier to reuse queries that you run often without typing them from scratch. + +Learn more about query history in [Explore]({{< relref "../explore" >}}). + +{{< figure src="/static/img/docs/v67/rich-history.gif" max-width="1024px" caption="Query history" >}} + +### Azure OAuth + +Grafana v6.7 comes with a new OAuth integration for Microsoft Azure Active Directory. You can now assign users and groups to Grafana roles from the Azure Portal. Learn how to enable and configure it in [Azure AD OAuth2 authentication]({{< relref "../auth/azuread/" >}}). + +### Enforce minimum dashboard refresh interval + +Allowing a low dashboard refresh interval can cause severe load on data sources and Grafana. Grafana v6.7 allows you to restrict the dashboard refresh interval so it cannot be set lower than a given interval. This provides a way for administrators to control dashboard refresh behavior on a global level. + +Refer to min_refresh_interval in [Configuration]({{< relref "../administration/configuration#min-refresh-interval" >}}) for more information and how to enable this feature. + +### Stackdriver project selector + +A Stackdriver data source in Grafana is configured for one service account only. That service account is always associated with a default project in Google Cloud Platform (GCP). Depending on your setup in GCP, the service account might be granted access to more projects than just the default project. + +In Grafana 6.7, the query editor has been enhanced with a project selector that makes it possible to query different projects without changing datasource. Many thanks [Eraac](https://github.com/Eraac), [eliaslaouiti](https://github.com/eliaslaouiti), and [NaurisSadovskis](https://github.com/NaurisSadovskis) for making this happen! + +## Grafana Enterprise features + +General features are included in the Grafana Enterprise edition software. + +### White labeling customizes application title + +This release adds a new white labeling option to customize the application title. Learn how to configure it in [White labeling]({{< relref "../enterprise/white-labeling/" >}}). + +``` +[white_labeling] +# Set to your company name to override application title +app_title = Your Company +``` + +### Configure reporting for timeout and concurrency + +This release adds more configuration for the reporting feature rendering requests. You can set the panel rendering request timeout and the maximum number of concurrent calls to the rendering service in your configuration. Learn how to do it in [Reporting]({{< relref "../enterprise/reporting/" >}}). + +``` +[reporting] +# Set timeout for each panel rendering request +rendering_timeout = 10s +# Set maximum number of concurrent calls to the rendering service +concurrent_render_limit = 10 +``` + +### Export dashboard as PDF + +This feature allows you to export a dashboard as a PDF document. All dashboard panels will be rendered as images and added into the PDF document. Learn more in [Export dashboard as PDF]({{< relref "../enterprise/export-pdf/" >}}). + +### Report landscape mode + +You can now use either portrait or landscape mode in your reports. Portrait will render three panels per page and landscape two. +{{< figure src="/static/img/docs/enterprise/reports_create_new.png" max-width="1024px" caption="New report" >}} + +[Reporting]({{< relref "../enterprise/reporting/" >}}) has been updated as a result of this change. + +### Azure OAuth Team Sync support + +When setting up OAuth with Microsoft Azure AD, you can now sync Azure groups with Teams in Grafana. +Learn more in [Team sync]({{< relref "../enterprise/team-sync/" >}}). diff --git a/docs/sources/whatsnew/whats-new-in-v7-0.md b/docs/sources/whatsnew/whats-new-in-v7-0.md new file mode 100644 index 00000000..b7212bb3 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v7-0.md @@ -0,0 +1,229 @@ ++++ +title = "What's New in Grafana v7.0" +description = "Feature and improvement highlights for Grafana v7" +keywords = ["grafana", "new", "documentation", "7.0", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v7-0/"] +weight = -27 +[_build] +list = false ++++ + +# What's new in Grafana v7.0 + +This topic includes the release notes for Grafana v7.0. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +This major release of Grafana is the next step in our Observability story. It includes powerful new features for manipulating, transforming, and doing math on data. Grafana Enterprise has the first version of Usage analytics, which will help Grafana Admins better manage large, corporate Grafana ecosystems. + +The Grafana 7.0 stable release is scheduled for the 18th of May. In the meantime, if you want to know more about what we've been up to and what is coming, sign up for our online GrafanaCon conference. + +[{{< figure src="/assets/img/blog/GrafanaCONline.jpg" max-width="800px" lightbox="false" caption="GrafanaCONline May 13-29" >}}](https://grafana.com/about/events/grafanacon/2020/?source=blog) + +The main highlights are: + +- [**New Panel Editor** Redesign based on community feedback.]({{< relref "#new-panel-editor-and-unified-data-model" >}}) +- [**Explore** New tracing UI and support for visualizing Jaeger and Zipkin traces.]({{< relref "#new-tracing-ui" >}}) +- [**Enterprise** Usage insights, Presence indicator, and Auth improvements.]({{< relref "#grafana-enterprise" >}}) +- [**Transformations** Transformations and simple Math operations for all data sources.]({{< relref "#transformations" >}}) +- [**Field overrides** Automatically configure panels with data from queries.]({{< relref "#field-options-and-overrides" >}}) +- [**Table** New Table panel.]({{< relref "#table-panel" >}}) +- [**Plugins** New plugins platform.]({{< relref "#plugins-platform" >}}) +- [**Tutorials** New tutorials section.]({{< relref "#new-tutorials" >}}) +- [**Cloudwatch** Support for Cloudwatch Logs in Explore and the Logs panel.]({{< relref "#cloudwatch-logs" >}}) +- [**Breaking change** PhantomJS removed.]({{< relref "#breaking-change-phantomjs-removed" >}}) +- [**Time zones** Time zone support]({{< relref "#time-zone-support" >}}) + +## New panel editor and unified data model + +We have redesigned the UI for editing panels. The first visible change is that we have separated panel display settings to a right-hand side pane that you can collapse or expand depending on what your focus is on. With this change we are also introducing our new unified option model and UI for defining data configuration and display options. This unified data configuration system powers a consistent UI for setting data options across visualizations, as well as making all data display settings data driven and overridable. + +This new option architecture and UI will make all panels have a consistent set of options and behaviors for attributes like unit, min, max, thresholds, links, decimals. Not only that but all these options will share a consistent UI for specifying override rules and is extensible for custom panel specific options. + +In previous versions of Grafana, each visualization had slightly different ways to define their options. One immediate benefit is after setting options like units or thresholds in a panel, you can seamlessly switch between visualization types and keep those options. This will bring increased ease of use and more consistency for users and plugin developers. + +We have yet to migrate all core panels to this new architecture so in 7.0 there will be some inconsistencies in the UI between panels. This will be fixed soon in future releases as we update all the core panels and help the community update the community panel plugins. + +Learn more about this feature in [Panel editor]({{< relref "../panels/panel-editor.md" >}}). + +## New tracing UI + +This release adds major support for distributed tracing, including a telemetry mode to complement the existing support for metrics and logs. Traces allow you to follow how single requests travel through a distributed system. We are starting with an integrated trace viewer and two new built-in data sources: Jaeger and Zipkin. + +You can use the new trace view in Explore either directly to search for a particular trace or you can configure Loki to detect trace IDs in the log lines and link directly to a trace timeline pulled from Jaeger or Zipkin data source. + +In the future we will add more workflows and integrations so that correlating between metrics, logs and traces is even easier. + +{{< figure src="/static/img/docs/v70/tracing_ui.png" max-width="1024px" caption="Tracing UI" >}} + +## Transformations + +The data you want to visualize can come from many different places and it is usually not in exactly the right form. Users can now transform non-time series data into tables (e.g., JSON files or even simple lookup tables) in seconds without any customization or additional overhead. They can then combine non-time series data with any other data in Grafana; data from an external database or a panel that already exists in one of their current dashboards. + +By chaining a simple set of point and click [transformations]({{< relref "../panels/transformations/_index.md" >}}), users will be able join, pivot, filter, re-name and do calculations to get the results they need. Perfect for operations across queries or data sources missing essential data transformations. + +[Transformations]({{< relref "../panels/transformations/_index.md" >}}) also adds the ability to do maths across queries. Lots of data sources do not support this natively, so being able to do it in Grafana is a powerful feature. + +For users with large dashboards or with heavy queries, being able to reuse the query result from one panel in another panel can be a huge performance gain for slow queries (e.g log or sql queries). From the data source menu in the query editor, you can choose the `--dashboard--` option and then choose the query result from another panel on the same dashboard. + +The [Google Sheets data source](https://grafana.com/grafana/plugins/grafana-googlesheets-datasource) that was published a few weeks ago works really well together with the transformations feature. + +We are also introducing a new shared data model for both time series and table data that we call [DataFrame]({{< relref "../developers/plugins/data-frames/#data-frames" >}}). A DataFrame is like a table with columns but we refer to columns as fields. A time series is a DataFrame with two fields (time & value). + +**Transformations shipping in 7.0** + +- **Reduce:** Reduce all rows or data points to a single value using a function like max, min, mean or last. +- **Filter by name:** Removes part of the query results using a regex pattern. The pattern can be inclusive or exclusive. +- **Filter data by query** Filter data by query. This is useful if you are sharing the results from a different panel that has many queries and you want to only visualize a subset of that in this panel. +- **Organize fields:** Allows the user to re-order, hide, or rename fields / columns. Useful when data source doesn't allow overrides for visualizing data. +- **Labels to fields:** Groups series by time and returns labels or tags as fields. Useful for showing time series with labels in a table where each label key becomes a separate column. +- **Outer join:** Joins many time series/tables by a field. This can be used to outer join multiple time series on the _time_ field to show many time series in one table. +- **Add field from calculation:** This is a powerful transformation that allows you perform many different types of math operations and add the result as a new field. Can be used to calculate the difference between two series or fields and add the result to a new field. Or multiply one field with another and add the result to a new field. + +Learn more about this feature in [Transformations]({{< relref "../panels/transformations/_index.md" >}}). + +## Field options and overrides + +With Grafana 7.0 we are introducing a new, unified data configuration system that powers a consistent UI for setting data options across visualizations as well as making all data display settings data driven and overridable. This new option architecture and UI will make all panels have a consistent set of options and behaviors for attributes like `unit`, `min`, `max`, `thresholds`, `links`, `decimals` or `value mappings`. Not only that but all these options will share a consistent UI for specifying override rules and is extensible for custom panel specific options. + +Up until now the overrides were available only for Graph and Table panel(via Column Styles), but with 7.0 they work consistently across all visualization types and plugins. + +This feature enables even more powerful visualizations and fine grained control over how the data is displayed. + +Learn more about this feature in [Field overrides]({{< relref "../panels/field-overrides.md" >}}). + +## Inspect panels and export data to CSV + +{{< figure src="/static/img/docs/v70/panel_edit_export_raw_data.png" max-width="800px" class="docs-image--right" caption="Panel Edit - Export raw data to CSV" >}} + +Another new feature of Grafana 7.0 is the panel inspector. Inspect allows you to view the raw data for any Grafana panel as well as export that data to a CSV file. With Panel inspect you will also be able to perform simple raw data transformations like join, view query stats or detailed execution data. + +Learn more about this feature in [Inspect a panel]({{< relref "../panels/inspect-panel.md" >}}). + +
+ +## Table panel + +Grafana 7.0 comes with a new table panel (and deprecates the old one). This new table panel supports horizontal scrolling and column resize. Paired with the new `Organize fields` transformation detailed above you can reorder, hide & rename columns. This new panel also supports new cell display modes, like showing a bar gauge inside a cell. + +{{< youtube J29wILRh3QQ >}} +
+ +## Auto grid mode for Stat panel and Gauge + +This new 7.0 feature is for the gauge and stat panels. Before, stat and gauge only supported horizontal or vertical stacking: The auto layout mode just selected vertical or horizontal stacking based on the panel dimensions (whatever was highest). But in 7.0 the auto layout for these two panels will allow dynamic grid layouts where Grafana will try to optimize the usage of space and lay out each sub-visualization in a grid. + +{{< youtube noq1rLGvsrU >}} +
+ +## Cloudwatch Logs + +Grafana 7.0 adds logging support to one of our most popular cloud provider data sources. Autocomplete support for Cloudwatch Logs queries is included for improved productivity. There is support for deep linking to the CloudWatch Logs Insights console for log queries, similar to the deep linking feature for Cloudwatch metrics. Since CloudWatch Logs queries can return time series data, for example through the use of the `stats` command, alerting is supported too. + +## Plugins platform + +The [platform for plugins]({{< relref "../developers/plugins/" >}}) has been completely re-imagined and provides ready-made components and tooling to help both inexperienced and experienced developers get up and running more quickly. The tooling, documentation, and new components will improve plugin quality and reduce long-term maintenance. We are already seeing that a high quality plugin with the Grafana look and feel can be written in much fewer lines of code than previously. + +Learn more about developing plugins in the new framework in [Build a plugin]({{< relref "../developers/plugins/_index.md" >}}). + +### Front end plugins platform + +In Grafana 7.0 we are maturing our panel and front-end datasource plugins platform. + +Plugins can use the same React components that the Grafana team uses to build Grafana. Using these components means the Grafana team will support and improve them continually and make your plugin as polished as the rest of Grafana’s UI. The new [`@grafana/ui` components library](https://developers.grafana.com/ui) is documented with Storybook (visual documentation) and is available on NPM. + +The `@grafana/data`, `@grafana/runtime`, `@grafana/e2e packages` (also available via NPM) aim to simplify the way plugins are developed. We want to deliver a set of [reliable APIs](https://grafana.com/docs/grafana/latest/packages_api/) for plugin developers. + +With [@grafana/toolkit](https://www.npmjs.com/package/@grafana/toolkit) we are delivering a simple CLI that helps plugin authors quickly scaffold, develop and test their plugins without worrying about configuration details. A plugin author no longer needs to be a grunt or webpack expert to build their plugin. + +### Support for backend plugins + +Grafana now officially supports [backend plugins]({{< relref "../developers/plugins/backend/_index.md" >}}) and the first type of plugin to be introduced is a backend component for data source plugins. You can optionally add a backend component to your data source plugin and implement the query logic there to automatically enable alerting in Grafana for your plugin. In the 7.0 release, we introduce the [Grafana Plugin SDK for Go]({{< relref "../developers/plugins/backend/grafana-plugin-sdk-for-go.md" >}}) that enables and simplifies building a backend plugin in [Go](https://golang.org/). + +Plugins can be monitored with the new metrics and health check capabilities. The new Resources capability means backend components can return non-time series data like JSON or static resources like images and opens up Grafana for new use cases. + +With this release, we are deprecating the unofficial first version of backend plugins which will be removed in a future release. + +To learn more, start with the [overview]({{< relref "../developers/plugins/backend/_index.md" >}}). Next, in this [tutorial](https://grafana.com/tutorials/build-a-data-source-backend-plugin/) you'll learn how to build a backend for a data source plugin and enable it for use with [Grafana Alerting]({{< relref "../alerting/_index.md" >}}). Make sure to keep an eye out for additional documentation and tutorials that will be published after the Grafana v7.0 release. + +## New tutorials + +To help you get started with Grafana, we’ve launched a brand new tutorials platform. We’ll continue to expand the platform with more tutorials, but here are some of the ones you can try out now: + +- [Grafana fundamentals](https://grafana.com/tutorials/grafana-fundamentals/) +- [Create users and teams](https://grafana.com/tutorials/create-users-and-teams/) +- [Build a panel plugin](https://grafana.com/tutorials/build-a-panel-plugin/) +- [Build a data source plugin](https://grafana.com/tutorials/build-a-data-source-plugin/) + +## Rollup indicator for Metrictank queries + +{{< figure src="/static/img/docs/v70/metrictank_rollup_metadata.png" max-width="800px" class="docs-image--right" caption="Metrictank rollup metadata" >}} + +Depending on the cardinality of the data and the time range MetricTank may return rolled up (aggregated) data. This can be as subtle as potentially only 1 or 2 graphs out of nine being rolled up. The new rollup indicator is visible in the panel title and you can also inspect extensive metadata and stats about the Metrictank query result and its rollups. + +
+ +## Breaking change - PhantomJS removed + +[PhantomJS](https://phantomjs.org/), have been used for rendering images of dashboards and panels and have been included with Grafana since Grafana v2.0. Since then we’ve had a lot of related bugs and security related issues, mainly due to the fact that PhantomJS have struggled with supporting modern web technologies. Throughout the years, maintaining PhantomJS support in Grafana has been a nightmare. Removing support for PhantomJS has been a high priority for the Grafana project and got stressed even more when the PhantomJS maintainer in March 2018 [announced](https://github.com/ariya/phantomjs/issues/15344) the end of the project. + +Since then we have been working towards removing PhantomJS. In October 2019, when Grafana v6.4 was released, we [announced](https://grafana.com/blog/2019/10/02/grafana-v6.4-released/#phantomjs-deprecation) the deprecation of PhantomJS. Grafana v7.0 removes all PhantomJS support which means that Grafana distribution no longer will include a built-in image renderer. + +As a replacement for PhantomJS we’ve developed the [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer) which is a plugin that runs on the backend and handles rendering panels and dashboards as PNG images using headless Chromium/Chrome. The [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer) can either be installed as a Grafana plugin running in its own process side-by-side with Grafana. or runs as an external HTTP service, hosted using Docker or as a standalone application. + +Read more about [Image Rendering]({{< relref "../image-rendering/" >}}) in the documentation for further instructions. + +## Query history in Explore out of beta + +The Query history feature lets you view and interact with the queries that you have previously run in Explore. You can add queries to the Explore query editor, write comments, create and share URL links, star your favorite queries, and much more. Starred queries are displayed in the Starred tab, so it is easier to reuse queries that you run often without typing them from scratch. + +It was released as a beta feature in Grafana 6.7. The feedback has been really positive and it is now out of beta for the 7.0 release. Learn more about query history in [Explore]({{< relref "../explore" >}}). + +## Stackdriver data source supports Service Monitoring + +[Service monitoring](https://cloud.google.com/service-monitoring) in Google Cloud Platform (GCP) enables you to monitor based on Service Level Objectives (SLOs) for your GCP services. The new SLO query builder in the Stackdriver data source allows you to display SLO data in Grafana. Read more about it in the [Stackdriver data source documentation]({{< relref "../datasources/google-cloud-monitoring/_index.md/#slo-service-level-objective-queries" >}}). + +## Time zone support + +You can now override the [time zone]({{< relref "../dashboards/time-range-controls/#dashboard-time-settings" >}}) used to display date and time values in a dashboard. One benefit of this is that you can specify the local time zone of the service or system that you are monitoring which can be helpful when monitoring a system or service that operates across several time zones. + +## Alerting and deep linking for Azure Log Analytics + +The Azure Monitor data source supports multiple Azure services. Log Analytics queries in the data source now have alerting support too (Azure Monitor and Application Insights already had alerting support). + +A new feature is [deep linking from the graph panel to the Log Analytics query editor in the Azure Portal]({{< relref "../datasources/azuremonitor/#deep-linking-from-grafana-panels-to-the-log-analytics-query-editor-in-azure-portal" >}}). Click on a time series in the panel to see a context menu with a link to View in Azure Portal. Clicking that link opens the Azure Log Analytics query editor in the Azure Portal and runs the query from the Grafana panel. + +## Grafana Enterprise + +Grafana Enterprise focuses on solving problems for large companies and Grafana installations. And in Grafana 7.0 we are finally +solving one of the most common problems of using Grafana at scale. + +This includes problems like: + +- There are too many dashboards, how do I find the right one? +- How to find popular dashboards +- How to find dashboards with errors +- How to identify dashboards that are not being used +- Who created or last viewed this dashboard? + +{{< figure src="/static/img/docs/v70/dashboard_insights_users.png" max-width="1024px" caption="Dashboard Insights Users" >}} + +### Usage insights and Presence indicator + +This release includes a series of features that build on our new usage analytics engine. This “Grafana about Grafana” feature will help our large customers get better insight into the behavior and utilization of their users, dashboards, and data sources. The improved [dashboard search]({{< relref "../enterprise/usage-insights/#improved-dashboard-search" >}}) allows you to sort dashboards by usage and errors. When a user opens a dashboard, they will see a [presence indicator]({{< relref "../enterprise/usage-insights/#presence-indicator" >}}) of who else is viewing the same dashboard. And finally [Dashboard insights]({{< relref "../enterprise/usage-insights/#dashboard-insights" >}}) allows you to view recent dashboard usage. + +{{< figure src="/static/img/docs/v70/presence_indicator.jpg" max-width="1024px" caption="Grafana Enterprise - Presence indicator" >}} + +### SAML Role and Team Sync + +SAML support in Grafana Enterprise is improved by adding Role and Team Sync. Read more about how to use these features in the [SAML team sync documentation]({{< relref "../enterprise/saml.md#configure-team-sync" >}}). + +### Okta OAuth Team Sync + +Okta gets its own provider which adds support for Team Sync. Read more about it in the [Okta documentation]({{< relref "../auth/okta.md" >}}). + +## Upgrading + +See [upgrade notes]({{< relref "../installation/upgrading/#upgrading-to-v7-0" >}}). + +## Changelog + +Check out [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) for a complete list of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v7-1.md b/docs/sources/whatsnew/whats-new-in-v7-1.md new file mode 100644 index 00000000..1d3fd565 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v7-1.md @@ -0,0 +1,112 @@ ++++ +title = "What's New in Grafana v7.1" +description = "Feature and improvement highlights for Grafana v7.1" +keywords = ["grafana", "new", "documentation", "7.1", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v7-1/"] +weight = -28 +[_build] +list = false ++++ + +# What's new in Grafana v7.1 + +This topic includes the release notes for the Grafana v7.1. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +The main highlights are: + +- [**Flux and InfluxDB 2.x support in the Influx Datasource**]({{< relref "#influx-datasource" >}}) +- [**Query history search**]({{< relref "#query-history-search" >}}) +- [**Unification of Explore modes**]({{< relref "#explore-modes-unified" >}}) +- [**Elasticsearch- link to another data source from Explore**]({{< relref "#internal-links-for-elasticsearch" >}}) +- [**Merge on time transform for the new table panel**]({{< relref "#transformations" >}}) +- [**Stat panel text mode**]({{< relref "#stat-panel-text-mode" >}}) +- [**Time range picker update**]({{< relref "#time-range-picker-update" >}}) +- [**Provisioning of apps**]({{< relref "#provisioning-of-apps" >}}) +- [**Azure Monitor Datasource**]({{< relref "#azure-monitor-datasource" >}}) +- [**Deep linking for Google Cloud Monitoring (formerly named Google Stackdriver) datasource**]({{< relref "#deep-linking-for-google-cloud-monitoring-formerly-named-google-stackdriver-datasource" >}}) +- [**Grafana Enterprise features**]({{< relref "#grafana-enterprise-features" >}}) + - [**Secret management with HashiCorp Vault**]({{< relref "#support-for-hashicorp-vault" >}}) + - [**Monthly schedules in reports**]({{< relref "#support-for-monthly-schedules-in-reports" >}}) + +## Influx data source + +Support for Flux and Influx v2 has been added. The InfluxData blog post, [How to Build Grafana Dashboards with InfluxDB, Flux and InfluxQL](https://www.influxdata.com/blog/how-grafana-dashboard-influxdb-flux-influxql/) explains the changes in depth. + +## Query history search + +In Grafana v 7.1 we are introducing search functionality in Query history. You can search across queries and your comments. It is especially useful in combination with a time filter and data source filter. Read more about [Query history here]({{< relref "../explore/_index.md#query-history" >}}). + +{{< figure src="/static/img/docs/v71/query_history_search.gif" max-width="800px" caption="Query history search" >}} + +## Explore modes unified + +Grafana 7.1 includes a major change to Explore: it removes the query mode selector. + +Many data sources tell Grafana whether a response contains time series data or logs data. Using this information, Explore chooses which visualization to use for that data. This means that you don't need to switch back and forth between Logs and Metrics modes depending on the type of query that you want to make. + +## Internal links for Elasticsearch + +The new internal linking feature for Elasticsearch allows you to link to other data sources from your logs. You can now create links in Elastic configuration that point to another data source (similar to an existing feature in Loki). An example would be using a traceID field from your logs to be able to link to traces in a tracing data source like Jaeger. + +## Transformations + +We have added a new **Merge on time** transform that can combine many time series or table results. Unlike the join transform, this combines the result into one table even when the time values do not align / match. + +The new table panel introduced in 7.0 was missing a few features that the old table panel had. This feature, along with ad hoc filtering, means that the new table panel has achieved feature parity with the old table panel. + +## Ad hoc filtering in the new table panel + +[Ad hoc filtering]({{}}), a way to automatically add filters to queries without having to define template variables is now supported in the new Table panel. + +## Stat panel text mode + +The [stat panel]({{}}) has a new **Text mode** option to control what text to show. + +By default, the Stat panel displays: + +- Just the value for a single series or field. +- Both the value and name for multiple series or fields. + +You can use the Text mode option to control what text the panel renders. If the value is not important, only name and color is, then change the `Text mode` to **Name**. The value will still be used to determine color and is displayed in a tooltip. + +{{< figure src="/static/img/docs/v71/stat-panel-text-modes.png" max-width="1025px" caption="Stat panel" >}} + +## Provisioning of apps + +Grafana v7.1 adds support for provisioning of app plugins. This allows app plugins to be configured and enabled/disabled using configuration files. For more information about provisioning of app, refer to [provisioning plugin]({{}}). + +## Azure Monitor data source + +Support for multiple dimensions has been added to all services in the Azure Monitor datasource. This means you can now group by more than one dimension with time series queries. With the Kusto based services, Log Analytics and Application Insights Analytics, you can also select multiple metrics as well as multiple dimensions. + +Additionally, the Raw Edit mode for Application Insights Analytics has been replaced with a new service in the drop-down for the data source and is called Insights Analytics. The new query editor behaves in the same way as Log Analytics. + +## Deep linking for Google Cloud Monitoring (formerly named Google Stackdriver) data source + +A new feature in Grafana 7.1 is [deep linking from Grafana panels to the Metrics Explorer in Google Cloud Console]({{}}). Click on a time series in the panel to see a context menu with a link to View in Metrics explorer in Google Cloud Console. Clicking that link opens the Metrics explorer in the Monitoring Google Cloud Console and runs the query from the Grafana panel there. + +## Time range picker update + +With 7.1 we are updating the dashboard's time range picker to allow time zone selection. You no longer need to go to dashboard settings to change the dashboard's time zone. + +The time zone picker itself also got UX improvements. Now you can search for the timezone using country or city name, time zone abbreviations, or UTC offsets. + +## Grafana Enterprise features + +General features are included in the Grafana Enterprise edition software. + +### Support for HashiCorp Vault + +You can now use HashiCorp Vault to get secrets for configuration and provisioning of Grafana Enterprise. For more information about HashiCorp Vault, refer to [vault]({{}}). + +### Support for monthly schedules in reports + +With Grafana Enterprise 7.1, you can generate reports on a [monthly schedule]({{}}). + +## Upgrading + +See [upgrade notes]({{}}). + +## Changelog + +Check out [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) for a complete list of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v7-2.md b/docs/sources/whatsnew/whats-new-in-v7-2.md new file mode 100644 index 00000000..e3d7f227 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v7-2.md @@ -0,0 +1,162 @@ ++++ +title = "What's New in Grafana v7.2" +description = "Feature and improvement highlights for Grafana v7.2" +keywords = ["grafana", "new", "documentation", "7.2", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v7-2/"] +weight = -29 +[_build] +list = false ++++ + +# What's new in Grafana v7.2 + +This topic includes the release notes for the Grafana v7.2. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +The main highlights are: + +- [**New date formatting options added**]({{< relref "#new=date-formatting-options-added" >}}) +- [**Field options are out of beta!**]({{< relref "#field-options-are-out-of-beta" >}}) + - [**Added table column filters**]({{< relref "#added-table-column-filters" >}}) + - [**New field override selection options**]({{< relref "#new-field-override-selection-options" >}}) +- [**New transformations and enhancements**]({{< relref "#new-transformations-and-enhancements" >}}) +- [**Drag to reorder queries**]({{< relref "#drag-to-reorder-queries" >}}) +- [**Inspect queries in Explore**]({{< relref "#inspect-queries-in-explore" >}}) +- [**$__rate_interval for Prometheus**]({{< relref "#__rate_interval-for-prometheus" >}}) +- [**Toggle parsed log fields**]({{< relref "#toggle-parsed-log-fields" >}}) +- [**Sensitive alert channel settings are now encrypted**]({{< relref "#sensitive-alert-channel-settings-are-now-encrypted" >}}) +- [**Grafana Enterprise features**]({{< relref "#grafana-enterprise-features" >}}) + - [**Report time range**]({{< relref "#report-time-range" >}}) + - [**Organization-wide report settings**]({{< relref "#organization-wide-report-settings" >}}) + - [**Report grid layout**]({{< relref "#report-grid-layout" >}}) +- [**What's new in other parts of the Grafana ecosystem**]({{< relref "#whats-new-in-other-parts-of-the-grafana-ecosystem">}}) + - [**ADX (Azure Data Explorer) plugin**]({{< relref "#adx-azure-data-explorer-plugin">}}) + - [**X-Ray data source plugin**]({{< relref "#x-ray-data-source-plugin" >}}) + +## New date formatting options added + +You can now customize how dates are formatted in Grafana. Custom date formats apply to the time range picker, graphs, and other panel visualizations. + +This screenshot shows both a custom full date format with a 12 hour clock and am/pm suffix. The graph is also showing the same 12-hour clock format and a customized month and day format compared to the Grafana default `MM/DD` format. + +{{< figure src="/static/img/docs/v72/date_formats.png" max-width="800px" caption="Custom date time formats" >}} + +Date formats are set for a Grafana instance by adjusting [server-wide settings]({{< relref "../administration/configuration.md#date_formats" >}}) in the Grafana configuration file. We hope to add org- and user-level settings in the future. + +``` +[date_formats] +full_date = MMM Do, YYYY @ hh:mm:ss a +interval_second = hh:mm:ss a +interval_minute = hh:mm a +interval_hour = MMM DD hh:mm a +interval_day = MMM DD +interval_month = YYYY-MM +interval_year = YYYY +``` + +There is also experimental support to use the browser location and language to dynamically change the current date format for each user. This feature is disabled by default. + +The [Configuration]({{< relref "../administration/configuration.md#date_formats" >}}) topic has been updated as a result of this change. + +## Field options are out of beta! + +After lots of testing and user feedback, we removed the beta label from the configuration options in the Field and Override tabs. This release also includes the following feature enhancements. + +### Added table column filters + +You can now dynamically apply value filters to any table column. This option can be enabled for all columns or one specific column using an override rule. + +{{< figure src="/static/img/docs/v72/table_column_filters.png" max-width="800px" caption="Table column filters" >}} + +[Filter table columns]({{< relref "../visualizations/table/filter-table-columns.md" >}}) has been added as a result of this feature. + +### New field override selection options + +You can now add override rules that use a regex matcher to choose which fields to apply rules to. + +[Field overrides]({{< relref "../panels/field-overrides.md" >}}) has been updated as a result of these changes. + +## New transformations and enhancements + +Grafana 7.2 includes the following transformation enhancements: + +- A new [Group By]({{< relref "../panels/transformations/types-options.md#group-by">}}) transformation that allows you to group by multiple fields and add any number of aggregations for other fields. +- The [Labels to fields]({{< relref "../panels/transformations/types-options.md#labels-to-fields">}}) transformation now allows you to pick one label and use that as the name of the value field. +- You can drag transformations to reorder them. Remember that transformations are processed in the order they are listed in the UI, so think before you move something! + +{{< figure src="/static/img/docs/v72/transformations.gif" max-width="800px" caption="Group by and reordering of transformations" >}} + +## Drag to reorder queries + +The up and down arrows, which were previously the only way to change query order, have been removed. Instead, there is now a grab icon that allows you to drag and drop queries in a list to change their order. + +{{< figure src="/static/img/docs/v72/drag-queries.gif" max-width="800px" caption="Drag to reorder queries" >}} + +The [Queries]({{< relref "../panels/queries.md" >}}) topic has been updated as a result of this change. + +## Inspect queries in Explore + +You can enjoy all the details query inspector gave you in dashboards now in Explore as well. You can open query inspector tab with the button next to query history. See [Query inspector in Explore]({{< relref "../explore/_index.md#query-inspector" >}}) for more details. + +## \$\_\_rate_interval for Prometheus + +You can now use the new variable `$__rate_interval` in Prometheus for rate functions mainly. `$__rate_interval` in general is one scrape interval larger than `$__interval` but is never smaller than four times the scrape interval (which is 15s by default). See the [Prometheus data source]({{< relref "../datasources/prometheus.md#using-__rate_interval-variable" >}}) for more details. + +## Toggle parsed log fields + +With this awesome contribution from one of our community members, you can now toggle parsed fields in Explore if your logs are structured in `json` or `logfmt`. + +{{< figure src="/static/img/docs/v72/explore-toggle-parsed-fields.gif" max-width="800px" caption="Toggling parsed fields in Explore" >}} + +The [Toggle parsed fields]({{< relref "../explore/_index.md#toggle-detected-fields" >}}) section has been added to [Explore]({{< relref "../explore/_index.md" >}}) as a result of this feature. + +## Sensitive alert channel settings are now encrypted + +Alert notification channels now store sensitive settings and secrets, such as API tokens and passwords, encrypted in the database. + +Please read the [upgrade notes]({{< relref "../installation/upgrading.md#ensure-encryption-of-existing-alert-notification-channel-secrets" >}}) for more information and how to migrate. + +## Grafana Enterprise features + +These features are included in the Grafana Enterprise edition software. + +### Report and export dashboards in grid layout + +A new layout option is available when rendering reports: the grid layout. With this option, your report uses the panel layout from your dashboard, so that what you see is what you get. Learn more about the [grid layout]({{< relref "../enterprise/reporting.md#layout-and-orientation" >}}) in the documentation. + +The grid layout is also available for the [Export dashboard as PDF]({{< relref "../enterprise/export-pdf.md" >}}) feature. + +{{< figure src="/static/img/docs/enterprise/reports_grid_landscape_preview.png" max-width="500px" class="docs-image--no-shadow" >}} + +### Report time range + +You can now generate a report with a different time range from the dashboard it is based on. This means that you no longer have to apply workarounds, such as copying dashboards or carefully aligning report generation with the end of the month, to generate reports that cover the period you want. + +For more information, refer to [Reports time range]({{< relref "../enterprise/reporting.md#report-time-range" >}}). + +### Organization-wide report settings + +You can now configure organization-wide report settings, such as report branding, in the Settings tab on the Reporting page. Settings are applied to all the reports of your current organization. + +{{< figure src="/static/img/docs/enterprise/reports_settings.png" max-width="500px" class="docs-image--no-shadow" caption="Reports settings" >}} + +For more information, refer to [Reports settings]({{< relref "../enterprise/reporting.md#reports-settings" >}}). + +## Upgrading + +See [upgrade notes]({{< relref "../installation/upgrading.md" >}}). + +## Changelog + +Check out [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) for a complete list of new features, changes, and bug fixes. + +## What's new in other parts of the Grafana ecosystem + +### ADX (Azure Data Explorer) plugin + +In collaboration with Microsoft, we have improved the usability of our ADX datasource plugin by adding a visual query builder. The goal is to make it easier for users, regardless of their previous knowledge of writing KQL (Kusto Query Language) queries, to query and visualize their data. + +{{< figure src="/static/img/docs/v72/adx-ds.png" max-width="800px" caption="ADX visual query builder" >}} + +### X-Ray data source plugin + +We are pleased to announce our very first version of our data source plugin for AWS X-Ray. You can use this plugin to visualize traces, look at analytics tables, and see insight summaries. For more information, refer to the [X-Ray data source](https://grafana.com/grafana/plugins/grafana-x-ray-datasource) plugin page. diff --git a/docs/sources/whatsnew/whats-new-in-v7-3.md b/docs/sources/whatsnew/whats-new-in-v7-3.md new file mode 100644 index 00000000..bab3cf37 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v7-3.md @@ -0,0 +1,161 @@ ++++ +title = "What's New in Grafana v7.3" +description = "Feature and improvement highlights for Grafana v7.3" +keywords = ["grafana", "new", "documentation", "7.3", "release notes"] +aliases = ["/docs/grafana/latest/guides/whats-new-in-v7-3/"] +weight = -30 +[_build] +list = false ++++ + +# What's new in Grafana v7.3 + +This topic includes the release notes for Grafana v7.3. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) or the [Patch release notes](#patch-release-notes). + +The main highlights are: + +- [**Google Cloud Monitoring:** Out of the box dashboards]({{< relref "#cloud-monitoring-out-of-the-box-dashboards" >}}) +- [**Shorten URL for dashboards and Explore**]({{< relref "#shorten-url-for-dashboards-and-explore" >}}) +- [**Table improvements and new image cell mode**]({{< relref "#table-improvements-and-new-image-cell-mode" >}}) +- [**New color scheme option**]({{< relref "#new-color-scheme-option" >}}) +- [**SigV4 Authentication for Amazon Elasticsearch Service**]({{< relref "#sigv4-authentication-for-aws-users" >}}) +- [**CSV exports for Excel**]({{< relref "#csv-exports-for-excel" >}}) + +## Table improvements and new image cell mode + +The table has been updated with improved hover behavior for cells that have longer content than what fits the current column width. As you can see +in the animated gif below the cell will automatically expand to show you full content of the cell. + +{{< figure src="/static/img/docs/v73/table_hover.gif" max-width="900px" caption="Table hover" >}} + +Another new feature that can be seen in the image above is the new image cell display mode. If you have a field value that is an image URL or a base64 encoded image you can configure the table to display it as an image. + +## New color scheme option + +{{< figure src="/static/img/docs/v73/color_scheme_dropdown.png" max-width="450px" caption="Color scheme" class="pull-right" >}} + +A new standard field [color scheme]({{< relref "../panels/standard-options.md#color-scheme" >}}) option has been added. This new option will provide a unified way for all new panels to specify how colors should be assigned. + +- **Single color**: Specifies a single color. Useful in an override rule. +- **From thresholds**: Informs Grafana to take color from the matching threshold. +- **Classic palette**: Assigns a color by looking up a color in a palette by series index. Useful for Graphs and pie charts, and other categorical data visualizations in Grafana. +- **Green-Yellow-Red (by value)**: A continuous color scheme where Grafana will interpolate a color based on the value assigned to the green, yellow, and red components. The value must be within the min & max limits. +- **Blue-Yellow-Red (by value)**: Same as above but different colors. +- **Blues (by value)**: Same as above but color scheme go from panel background to blue. + +
+ +As you can see this adds new continuous color schemes where Grafana will interpolate colors. A great use of these new color schemes is the table panel where you can color the background and get a heatmap like effect. + +{{< figure src="/static/img/docs/v73/table_color_scheme.png" max-width="900px" caption="table color scheme" >}} + +Another thing to highlight is that all these new color schemes are theme aware and adapt to the current theme. For example here is how the new monochrome color scheme look like in the light theme: + +{{< figure src="/static/img/docs/v73/table_color_scheme_mono_light.png" max-width="900px" caption="table color monochrome scheme" >}} + +As this new option is a standard field option it works in every panel. Here is another example from the [Bar Gauge]({{< relref "../visualizations/bar-gauge-panel.md" >}}) panel. + +{{< figure src="/static/img/docs/v73/bar_gauge_gradient_color_scheme.png" max-width="900px" caption="bar gauge color scheme" >}} + +## CSV exports for Excel + +In v7.0, we introduced a new table panel and inspect mode with Download CSV enabled. However, CSV export to Excel was removed. Due to a large number of inquiries and requests, this [community contribution from tomdaly](https://github.com/grafana/grafana/pull/27284) brought the feature back. + +For more information, refer to [Download raw query results as CSV]({{< relref "../panels/inspect-panel/#download-raw-query-results-as-csv" >}}) in the Grafana documentation. + +## Google Cloud monitoring out-of-the-box dashboards + +The updated Google Cloud monitoring data source is shipped with pre-configured dashboards for five of the most popular Google Cloud Platform (GCP) services: + +- BigQuery +- Cloud Load Balancing +- Cloud SQL +- Google Compute Engine `GCE` +- Google Kubernetes Engine `GKE` + +To import the pre-configured dashboards, go to the configuration page of your Google Cloud Monitoring data source and click on the `Dashboards` tab. Click `Import` for the dashboard you would like to use. To customize the dashboard, we recommend to save the dashboard under a different name, because otherwise the dashboard will be overwritten when a new version of the dashboard is released. + +For more details, see the [Google Cloud Monitoring docs]({{}}) + +## Shorten URL for dashboards and Explore + +This is an amazing new feature that was created in cooperation with one of our community members. The new share shortened link capability allows you to create smaller and simpler URLs of the format `/goto/:uid` instead of using longer URLs that can contain complex query parameters. In Explore, you can create a shortened link by clicking on the share button in Explore toolbar. In the dashboards, a shortened url option is available through the share panel or dashboard button. + +## SigV4 authentication for AWS users + +You can now configure your Elasticsearch data source to access your Amazon Elasticsearch Service domain directly from Grafana. + +For more details, refer to the [Elasticsearch docs]({{}}). + +## Chaining pipeline aggregation in Elasticsearch + +Thanks to a contribution from a community member, it's now possible to chain multiple pipeline aggregations together and use the results of one pipeline aggregation as the input of another. This unleashes the full power of Elasticsearch's pipeline aggregations in Grafana, allowing users to perform high order derivatives or use a pipeline aggregation result as a variable for a Bucket Script Aggregation. + +## Grafana Enterprise features + +These features are included in the Grafana Enterprise edition software. + +### Auditing + +Auditing tracks important changes to your Grafana instance to help you manage and mitigate suspicious activity and meet compliance requirements. Grafana logs events (as JSON) to file or directly to [loki](/oss/loki/). + +Example of a login event: + +```json +{ + "timestamp": "2020-10-22T10:18:00.838094347Z", + "user": { + "userId": 1, + "orgId": 1, + "isAnonymous": false + }, + "action": "login-grafana", + "result": { + "statusType": "success", + "statusCode": 200 + }, + "requestUri": "/login", + "ipAddress": "127.0.0.1:41324", + "userAgent": "Chrome/86.0.4240.111", + "grafanaVersion": "7.3.0" +} +``` + +For more details, see the [Auditing docs]({{}}). + +### Data source usage insights + +Data source usage insights allows you to gain insight into how a data source is being used and how well it works. There is a new tab in the data source settings page called insights that will show you information about how the data source has been used in the past 30 days. + +Insights: + +- Queries per day +- Errors per day +- Average load duration per day (ms) + +### SAML single logout + +SAML’s single logout (SLO) capability allows users to log out from all applications associated with the current identity provider (IdP) session established via SAML SSO. For more information, refer to the [docs]({{}}). + +### SAML IdP-initiated single sign on + +IdP-initiated single sign on (SSO) allows the user to log in directly from the SAML identity provider (IdP). It is disabled by default for security reasons. For more information, refer to the [docs]({{}}). + +## Upgrading + +See [upgrade notes]({{< relref "../installation/upgrading.md" >}}). + +## Changelog + +Check out [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) for a complete list of new features, changes, and bug fixes. + +## Patch release notes + +- [Grafana 7.3.0 release notes]({{< relref "../release-notes/release-notes-7-3-0.md" >}}) +- [Grafana 7.3.1 release notes]({{< relref "../release-notes/release-notes-7-3-1.md" >}}) +- [Grafana 7.3.2 release notes]({{< relref "../release-notes/release-notes-7-3-2.md" >}}) +- [Grafana 7.3.3 release notes]({{< relref "../release-notes/release-notes-7-3-3.md" >}}) +- [Grafana 7.3.4 release notes]({{< relref "../release-notes/release-notes-7-3-4.md" >}}) +- [Grafana 7.3.5 release notes]({{< relref "../release-notes/release-notes-7-3-5.md" >}}) +- [Grafana 7.3.6 release notes]({{< relref "../release-notes/release-notes-7-3-6.md" >}}) +- [Grafana 7.3.7 release notes]({{< relref "../release-notes/release-notes-7-3-7.md" >}}) diff --git a/docs/sources/whatsnew/whats-new-in-v7-4.md b/docs/sources/whatsnew/whats-new-in-v7-4.md new file mode 100644 index 00000000..d71053fb --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v7-4.md @@ -0,0 +1,243 @@ ++++ +title = "What's New in Grafana v7.4" +description = "Feature and improvement highlights for Grafana v7.4" +keywords = ["grafana", "new", "documentation", "7.4", "release notes"] +weight = -31 +aliases = ["/docs/grafana/latest/guides/whats-new-in-v7-4/"] +[_build] +list = false ++++ + +# What's new in Grafana v7.4 + +This topic includes the release notes for Grafana v7.4. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +Check out the [New Features in 7.4](https://play.grafana.org/d/nP8rcffGk/1-new-features-in-v7-4?orgId=1) dashboard on Grafana Play! + +## Grafana OSS features + +These features are included in the Grafana open source edition. + +### Time series panel visualization (Beta) + +Grafana 7.4 adds a beta version of the next-gen graph visualization. The new graph panel, the _Time series_ visualization, is high-performance visualization based on the uPlot library. This new graph visualization uses the new panel architecture introduced in Grafana 7.0 and integrates with field options, overrides, and transformations. + +The Time series beta panel implements the majority of the functionalities available in the current Graph panel. Our plan is to have close to full coverage of the features in Grafana 8.0, coming later this year. + +Apart from major performance improvements, the new Time series panel implements new features like line interpolation modes, support for more than two Y-axes, soft min and max axis limits, automatic points display based on data density, and gradient fill modes. + +{{< figure src="/static/img/docs/v74/timeseries_panel.png" max-width="900px" caption="Time series panel" >}} + +The following documentation topics were added for this feature: + +- [Time series panel]({{< relref "../visualizations/time-series/_index.md" >}}) +- [Graph time series as lines]({{< relref "../visualizations/time-series/graph-time-series-as-lines.md" >}}) +- [Graph time series as bars]({{< relref "../visualizations/time-series/graph-time-series-as-bars.md" >}}) +- [Graph time series as points]({{< relref "../visualizations/time-series/graph-time-series-as-points" >}}) +- [Change axis display]({{< relref "../visualizations/time-series/change-axis-display.md" >}}) + +### Node graph panel visualization (Beta) + +_Node graph_ is a new panel type that can visualize directed graphs or network in dashboards, but also in Explore. It uses directed force layout to effectively position the nodes so it can help with displaying complex infrastructure maps, hierarchies, or execution diagrams. + +All the information and stats shown in the Node graph beta are driven by the data provided in the response from the data source. The first data source that is using this panel is AWS X-Ray, for displaying their service map data. + +For more details about how to use the X-Ray service map feature, see the [X-Ray plugin documentation](https://grafana.com/grafana/plugins/grafana-x-ray-datasource). + +For more information, refer to [Node graph panel]({{< relref "../visualizations/node-graph.md" >}}). + +### New transformations + +The following transformations were added in Grafana 7.4. + +#### Sort by transformation + +The _Sort by_ transformation allows you to sort data before sending it to the visualization. + +For more information, refer to [Sort by]({{< relref "../panels/transformations/types-options.md#sort-by" >}}) in [Transformation types and options]({{< relref "../panels/transformations/types-options.md" >}}). + +#### Filter data by value transform + +The new _Filter data by value_ transformation allows you to filter your data directly in Grafana and remove some data points from your query result. + +This transformation is very useful if your data source does not natively filter by values. You might also use this to narrow values to display if you are using a shared query. + +For more information, refer to [Filter data by value]({{< relref "../panels/transformations/types-options.md#filter-data-by-value" >}}) in [Transformation types and options]({{< relref "../panels/transformations/types-options.md" >}}). + +### New override option + +On the Overrides tab, you can now set properties for fields returned by a specific query. + +For more information, refer to [Field overrides]({{< relref "../panels/field-overrides.md" >}}). + +### Exemplar support + +Grafana graphs now support Prometheus _exemplars_. They are displayed as diamonds in the graph visualization. + +> **Note:** Support for exemplars will be added in version Prometheus 2.25+. + +{{< figure src="/static/img/docs/v74/exemplars.png" max-width="900px" caption="Exemplar example" >}} + +For more information, refer to [Exemplars]({{< relref "../datasources/prometheus.md#exemplars" >}}). + +### Trace to logs + +You can now navigate from a span in a trace view directly to logs relevant for that span. This feature is available for the Tempo, Jaeger, and Zipkin data sources. + +The following topics were updated as a result of this feature: + +- [Explore]({{< relref "../explore/trace-integration.md" >}}) +- [Jaeger]({{< relref "../datasources/jaeger.md#trace-to-logs" >}}) +- [Tempo]({{< relref "../datasources/tempo.md#trace-to-logs" >}}) +- [Zipkin]({{< relref "../datasources/zipkin.md#trace-to-logs" >}}) + +### Server-side expressions + +_Server-side expressions_ is an experimental feature that allows you to manipulate data returned from backend data source queries. Expressions allow you to manipulate data with math and other operations when the data source is a backend data source or a **--Mixed--** data source. + +The main use case is for [multi-dimensional]({{< relref "../basics/timeseries-dimensions.md" >}}) data sources used with the upcoming next generation alerting, but expressions can be used with backend data sources and visualization as well. + +> **Note:** Queries built with this feature might break with minor version upgrades until Grafana 8 is released. This feature does not work with the current Grafana alerting. + +For more information, refer to [Expressions]({{< relref "../panels/expressions.md" >}}). [Queries]({{< relref "../panels/queries.md" >}}) was also updated as a result of this feature. + +### Alert notification query label interpolation + +You can now provide detailed information to alert notification recipients by injecting alert label data as template variables into an alert notification. Labels that exist from the evaluation of the alert query can be used in the alert rule name and in the alert notification message fields using the `${Label}` syntax. The alert label data is automatically injected into the notification fields when the alert is in the alerting state. When there are multiple unique values for the same label, the values are comma-separated. + +{{< figure src="/static/img/docs/alerting/alert-notification-template-7-4.png" max-width="700px" caption="Variable support in alert notifications" >}} + +For more information, refer to the [alert notification docs]({{< relref "../alerting/old-alerting/notifications.md#notification-templating" >}}). + +### Content security policy support + +We have added support for [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), a layer of security that helps detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. + +CSP support is disabled by default, to enable it you must set `content_security_policy = true` in the Grafana configuration. If enabling it, you should also review, and potentially tweak, the CSP header template, via the configuration setting `content_security_policy_template`. + +You can lock down what can be done in the frontend code. Lock down what can be loaded, what JavaScript is executed. Not compatible with some plugins. + +[content_security_policy]({{< relref "../administration/configuration.md#content_security_policy" >}}) and [content_security_policy_template]({{< relref "../administration/configuration.md#content_security_policy_template" >}}) were added to [Configuration]({{< relref "../administration/configuration.md" >}}) as a result of this change. + +### Hide users in UI + +You can now use the `hidden_users` configuration setting to hide specific users in the UI. For example, this feature can be used to hide users that are used for automation purposes. + +[Configuration]({{< relref "../administration/configuration.md#hidden_users" >}}) has been updated for this feature. + +### Elasticsearch data source updates + +Grafana 7.4 includes the following enhancements + +- Added support for serial differencing pipeline aggregation. +- Added support for moving function pipeline aggregation. +- Added support to the terms aggregation for ordering by percentiles and extended stats. +- Updated date histogram auto interval handling for alert queries. + +> **Note:** We have deprecated browser access mode. It will be removed in a future release. + +For more information, refer to the [Elasticsearch docs]({{}}). + +### Azure Monitor updates + +The Azure Monitor query type was renamed to Metrics and Azure Logs Analytics was renamed to Logs to match the service names in Azure and align the concepts with the rest of Grafana. + +[Azure Monitor]({{< relref "../datasources/azuremonitor/_index.md" >}}) was updated to reflect this change. + +### MQL support added for Google Cloud Monitoring + +You can now use Monitoring Query Language (MQL) for querying time-series data. MQL provides an expressive, text-based interface to retrieve, filter, and manipulate time-series data. + +Unlike the visual query builder, MQL allows you to control the time range and period of output data, create new labels to aggregate data, compute the ratio of current values to past values, and so on. + +MQL uses a set of operations and functions. Operations are linked together using the common pipe mechanism, where the output of one operation becomes the input to the next. Linking operations makes it possible to build up complex queries incrementally. + +Once query type Metrics is selected in the Cloud Monitoring query editor, you can toggle between the editor modes for visual query builder and MQL. For more information, refer to the [Google Cloud Monitoring docs]({{< relref "../datasources/google-cloud-monitoring/_index.md#out-of-the-box-dashboards" >}}). + +Many thanks to [mtanda](https://github.com/mtanda) this contribution! + +## Curated dashboards for Google Cloud Monitoring + +Google Cloud Monitoring data source ships with pre-configured dashboards for some of the most popular GCP services. These curated dashboards are based on similar dashboards in the GCP dashboard samples repository. In this release, we have expanded the set of pre-configured dashboards. + +{{< figure src="/static/img/docs/google-cloud-monitoring/curated-dashboards-7-4.png" max-width= "650px" >}} + +If you want to customize a dashboard, we recommend that you save it under a different name. Otherwise the dashboard will be overwritten when a new version of the dashboard is released. + +For more information, refer to the [Google Cloud Monitoring docs]({{< relref "../datasources/google-cloud-monitoring/_index.md/#out-of-the-box-dashboards" >}}). + +### Query Editor Help + +The feature previously referred to as DataSource Start Pages or Cheat Sheets has been renamed to Query Editor Help, and is now supported in panel query editors (depending on the data source), as well as in Explore. + +[Queries]({{< relref "../panels/queries.md" >}}) was updated as a result of this feature. + +For more information on adding a query editor help component to your plugin, refer to [Add a query editor help component]({{< relref "../developers/plugins/add-query-editor-help.md" >}}). + +### Variable inspector + +The variables list has an additional column indicating whether variables are referenced in queries and panel names or not. The dependencies graph provides an easy way to check variable dependencies. You can click on a variable name within the graph to make updates to the variable as needed. + +For more information, refer to [Inspect variables and their dependencies]({{< relref "../variables/inspect-variable.md">}}). + +## Grafana Enterprise features + +These features are included in the Grafana Enterprise edition. + +### Licensing changes + +When determining a user’s role for billing purposes, a user who has the ability to edit and save dashboards is considered an Editor. This includes any user who is an Editor or Admin at the Org level, and who has granted Admin or Edit permissions via [Dashboard and folder permissions]({{< relref "../permissions/dashboard-folder-permissions.md">}}). + +After the number of Viewers or Editors has reached its license limit, only Admins will see a banner in Grafana indicating that the license limit has been reached. Previously, all users saw the banner. + +Grafana Enterprise license tokens update automatically on a daily basis, which means you no longer need to manually update your license, and the process for adding additional users to a license is smoother than it was before. + +Refer to [Licensing restrictions]({{< relref "../enterprise/license/license-restrictions.md" >}}) for more information. + +### Export usage insights to Loki + +You can now export usage insights logs to Loki and query them from Grafana. Usage insights logs include dashboard visits, data source views, queries and errors, and more. + +For more information, refer to [Export logs of usage insights]({{< relref "../enterprise/usage-insights/export-logs.md" >}}). + +### New audit log events + +New log out events are logged based on when a token expires or is revoked, as well as [SAML Single Logout]({{< relref "../enterprise/saml.md#single-logout" >}}). A `tokenId` field was added to all audit logs to help understand which session was logged out of. + +Also, a counter for audit log writing actions with status (success / failure) and logger (loki / file / console) labels was added. + +[Auditing]({{< relref "../enterprise/auditing.md" >}}) was updated to reflect these changes. + +### Reports support Unicode + +You can now select a font, other than the default, for Unicode-based scripts. As a result, an automatically generated PDF of a dashboard, which contains for example Chinese or Cyrillic text, can display them. Because the size of a report increases as additional fonts are added, this feature is not on by default. + +[Reporting]({{< relref "../enterprise/reporting.md#rendering-configuration" >}}) was updated as a result of this change. + +### Request security + +Request security introduces ways to limit requests from the Grafana server, and it targets requests that are generated by users. + +For more information, refer to [Request security]({{< relref "../enterprise/request-security.md" >}}). + +## Breaking changes + +The following Grafana 7.4 changes might break previous functionality. + +### Plugin compatibility + +We have upgraded AngularJS from version 1.6.6 to 1.8.2. Due to this upgrade some old angular plugins might stop working and will require a small update. This is due to the deprecation and removal of pre-assigned bindings. So if your custom angular controllers expect component bindings in the controller constructor you need to move this code to an $onInit function. For more details on how to migrate AngularJS code open the migration guide and search for pre-assigning bindings. + +In order not to break all angular panel plugins and data sources we have some custom angular inject behavior that makes sure that bindings for these controllers are still set before constructor is called so many old angular panels and data source plugins will still work. + +### Fixes Constant variable persistence confusion + +In order to minimize the confusion with Constant variable usage, we've removed the ability to make Constant variables visible. This change will also migrate all existing visible Constant variables to Textbox variables because which we think this is a more appropriate type of variable for this use case. + +## Upgrading + +See [upgrade notes]({{< relref "../installation/upgrading.md" >}}). + +## Changelog + +Check out [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) for a complete list of new features, changes, and bug fixes. diff --git a/docs/sources/whatsnew/whats-new-in-v7-5.md b/docs/sources/whatsnew/whats-new-in-v7-5.md new file mode 100644 index 00000000..f66b9582 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v7-5.md @@ -0,0 +1,163 @@ ++++ +title = "What's new in Grafana v7.5" +description = "Feature and improvement highlights for Grafana v7.5" +keywords = ["grafana", "new", "documentation", "7.5", "release notes"] +weight = -32 +aliases = ["/docs/grafana/latest/guides/whats-new-in-v7-5/"] +[_build] +list = false ++++ + +# What’s new in Grafana v7.5 + +This topic includes the release notes for Grafana v7.5. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +## Grafana OSS features + +These features are included in the Grafana open source edition. + +### Pie chart panel visualization (beta) + +Grafana 7.5 adds a beta version of the next-generation pie chart panel. + +![Pie chart panel](/static/img/docs/pie-chart-panel/pie-chart-panel-7-5.png) + +For more information, refer to [Pie chart panel]({{< relref "../visualizations/pie-chart-panel.md" >}}). + +### Alerting for Loki + +Grafana 7.5 comes with alerting support for Loki. With LogQL you can wrap a log query with the functions that allow for creating metrics out of the logs, such as "rate()". Metric queries can then be used to calculate things such as the rate of error messages. [When combined with log parsers](https://www.youtube.com/watch?v=H9z2V0Ib1q0), they can be used to calculate metrics from a value within the log line, such latency or request size. + +With alerting support for Loki, you can now create alerts on Loki metrics queries. + +[Alerting]({{< relref "../alerting/_index.md" >}}) was updated as a result of this change. + +![Loki alerting](/static/img/docs/alerting/alerting-for-loki-7-5.png) + +### Loki label browser + +A new Loki logs browser lets you construct the queries step by step: you choose labels that you like to consider, such as "job", then you select the values that you like, such as "my-app1". Note that you can select values from more than one label, and that they get facetted. This means only possible label combinations are selectable. When you're done, you can run the query either as a logs or a metrics query (a metrics query returns the log volume in a chart). + +### Changed default HTTP method for new Prometheus data sources + +For new Prometheus data sources, we have changed the default HTTP method to POST. POST allows for much larger query bodies than using the GET method. This is necessary when sending queries from graphs with a lot of targets, for example, many hosts in a dashboard variable. The POST method also makes the Query Inspector data easier to read since the query is in plain text whereas the GET query is URL encoded. + +> **Note:** This is not going to affect provisioned data sources or already created data sources. + +[Prometheus data source]({{< relref "../datasources/prometheus.md" >}}) was updated as a result of this change. + +### Word highlighting for Elasticsearch + +When searching for text in Elasticsearch logs, matching words in the log line returned by the query are now highlighted. + +![Elastic logs highlighting](/static/img/docs/elasticsearch/elastic-word-highlighting-7-5.png) + +### Better format definition for trace data + +In Grafana 7.5, we changed how data for the trace view is sent from the data source. The required data frame has a clear format, which is more aligned with how data is generally represented in Grafana. This makes it easier for third-party developers to implement data sources leveraging the trace view. + +For more information, refer to [trace data API docs]({{< relref "../explore/trace-integration.md#data-api" >}}). + +### Paste in SSL certs for Postgres data source + +Previously, when users wanted to configure the Postgres data source to connect with SSL certification, they needed to put the certification on the server, and configure the data source with file path. + +Instead of the file path, users can now paste the SSL certification content in the UI. This allows them to configure the certification even when they do not have access to the server. + +> **Note:** It remains as limitation for the Grafana Cloud, as users may not have access to the server configuration. + +[Postgres data source]({{< relref "../datasources/postgres.md" >}}) and [Provisioning]({{< relref "../administration/provisioning.md" >}}) were updated as a result of this change. + +### Deprecation notice for some Azure Monitor queries + +In the upcoming Grafana 8.0 release, Application Insights and Insights Analytics query types within the Azure Monitor data source will be deprecated and be made read-only in favor of querying Application Insights from Metrics and Logs. + +Grafana 7.5 includes a deprecation notice for these queries, and some documentation to help users prepare for the upcoming changes. + +For more information, refer to [Deprecating Application Insights and Insights Analytics]({{< relref "../datasources/azuremonitor/_index.md#deprecating-application-insights-and-insights-analytics" >}}). + +### Cloudwatch data source enhancements + +- Support for region eu-south-1 has been added to the CloudWatch data source. New metrics have also been added to the namespaces AWS/Timestream, AWS/RDS (RDS Proxy metrics), AWS/NetworkFirewall, AWS/GroundStation, and AWS/DDoSProtection. Many thanks to [relvira](https://github.com/relvira), [ilyastoli](https://github.com/ilyastoli), and [rubycut](https://github.com/rubycut) for contributing! +- Added a page limit to the List Metrics API call to improve speed and reduce memory consumption. You can change this limit by entering a higher value in [list_metrics_page_limit]({{< relref "../administration/configuration.md#list-metrics-page-limit" >}}) in the Grafana configuration file. +- You can now enable or disable authentication providers and assume a role other than default by changing the [allowed_auth_providers]({{< relref "../administration/configuration.md#allowed-auth-providers" >}}) and [assume_role_enabled]({{< relref "../administration/configuration.md#assume-role-enabled" >}}) options in the Grafana configuration file. By default, the allowed authentication providers are _AWS SDK Default_, _Access and secret key_, and _Credentials File_, and role is _Assume role (ARN)_. +- You can now specify a custom endpoint in the CloudWatch data source configuration page. This field is optional, and if it is left empty, then the default endpoint for CloudWatch is used. By specifying a regional endpoint, you can reduce request latency. + + [AWS Cloudwatch data source]({{< relref "../datasources/aws-cloudwatch/_index.md" >}}) was updated as a result of this change. + +### Increased API limit for CloudMonitoring Services + +In previous versions, when querying metrics for Service Level Objectives (SLOs) in the CloudMonitoring data source, only the first 100 services were listed in the **Service** field list. To overcome this issue, the API limit for listing services has been increased to 1000. + +### Tempo as a backend data source + +We have converted Tempo to a backend data source and dropped support for tempo-query's (Jaeger) response. To configure it, you can now point to the port that is set in the Tempo configuration file. + +```yaml +server: + http_listen_port: 3101 +``` + +[Azure Monitor data source]({{< relref "../datasources/azuremonitor/_index.md" >}}) was updated as a result of this change. + +## Enterprise features + +These features are included in the Grafana Enterprise edition. + +### Query caching + +When caching is enabled, Grafana temporarily stores the results of data source queries. When you or another user submit the same query again, the results return from the cache instead of from the data source (such as Splunk or ServiceNow). + +Query caching advantages: + +- Faster dashboard load times, especially for popular dashboards. +- Reduced API costs. +- Reduced likelihood that APIs will rate-limit or throttle requests. + +Caching currently works for all backend data sources. You can enable the cache globally or per data source, and you can configure the cache duration per data source. The cache is currently in-memory. + +For more information, refer to [Query caching]({{< relref "../enterprise/query-caching.md" >}}). + +### Use template variable in reports + +If you have created dashboards with template variables, then you can choose which values are selected when rendering a report. This makes it easier to tailor reports to their audience or generate multiple reports from the same dashboard. + +Enable this feature in configuration settings using the `templateVariables` flag. + +For more information, refer to [Reporting]({{< relref "../enterprise/reporting.md#choose-template-variables" >}}). + +### Active user limits + +If a Grafana instance has exceeded its licensed number of active users, then non-active users who try to sign in to Grafana will be prevented from doing so. Active users are users who have logged in to Grafana in the past 30 days. The total number of users registered in Grafana does not affect this rule. This enforcement is applied separately for Viewers and for Editor/Admins, so if you reach your active Viewer limit, new Editor/Admins will still be able to sign in. This rule also includes a 10% buffer, meaning that you need to exceed your limit by 10% before users are prevented from signing in. + +Here is an example: + +A Grafana Enterprise instance includes 100 Viewers and 50 Editor/Admins. Over the course of the last 30 days, 110 Viewers and 20 Editor/Admins have signed in to Grafana. + +All of the Viewers who have signed in over the past 30 days will retain the ability to sign in. + +When a previously-inactive Viewer (someone who has not signed in over the past 30 days) tries to sign in, they will see a message and be prevented from signing in until the number of active users dips back below 110. New Editor/Admins are not affected by this; they can continue to sign in until the number of active Editors/Admins reaches 55. + +If you try to sign in to a fourth device or browser, then you will be prevented from doing so; the limit of concurrent sessions is three. + +If you sign in to a fourth device or browser, then you will be signed out of the session that is least current. +Concurrent session limits +Each Grafana Enterprise user will be limited to three concurrent user sessions. When a user opens a fourth session, then the longest-inactive session will be automatically signed out. + +A new session is created when you sign in to Grafana from a different device or a different browser. Multiple windows and tabs in the same browser are all part of the same session, so having many Grafana tabs open will not cause any issues. + +For more information on Grafana Enterprise licensing and restrictions, refer to [License restrictions]({{< relref "../enterprise/license/license-restrictions.md" >}}). + +## Breaking changes + +There are no known breaking changes in this release. + +## Updated configuration + +``` +[server] +read_timeout = 0 +``` + +Sets the maximum time using a duration format (5s/5m/5ms) before timing out read of an incoming request and closing idle connections. +`0` means there is no timeout for reading the request. diff --git a/docs/sources/whatsnew/whats-new-in-v8-0.md b/docs/sources/whatsnew/whats-new-in-v8-0.md new file mode 100644 index 00000000..a5e73e63 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v8-0.md @@ -0,0 +1,333 @@ ++++ +title = "What's new in Grafana v8.0" +description = "Feature and improvement highlights for Grafana v8.0" +keywords = ["grafana", "new", "documentation", "8.0", "release notes"] +weight = -33 +aliases = ["/docs/grafana/latest/guides/whats-new-in-v8-0/"] +[_build] +list = false ++++ + +# What’s new in Grafana v8.0 + +This topic includes the release notes for Grafana v8.0. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +## Grafana OSS features + +These features are included in the Grafana open source edition. + +### Grafana v8.0 alerts + +The new alerts in Grafana 8.0 are an opt-in feature that centralizes alerting information for Grafana managed alerts and alerts from Prometheus-compatible data sources in one UI and API. You can create and edit alerting rules for Grafana managed alerts, Cortex alerts, and Loki alerts as well as see alerting information from prometheus-compatible data sources in a single, searchable view. For more information, on how to create and edit alerts and notifications, refer to [Overview of Grafana 8.0 alerts]({{< relref "../alerting/unified-alerting/_index.md" >}}). + +As part of the new alert changes, we have introduced a new data source, Alertmanager, which includes built-in support for Prometheus Alertmanager. It is presently in alpha and it not accessible unless alpha plugins are enabled in Grafana settings. For more information, refer to [Alertmanager data source]({{< relref "../datasources/alertmanager.md" >}}). + +> **Note:** Out of the box, Grafana still supports old Grafana alerts. They are legacy alerts at this time, and will be deprecated in a future release. + +To learn more about the differences between new alerts and the legacy alerts, refer to [What's New with Grafana 8 Alerts]({{< relref "../alerting/unified-alerting/difference-old-new.md" >}}). + +### Library panels + +Library panels allow users to build panels that can be used in multiple dashboards. Any updates made to that shared panel will then automatically be applied to all the dashboards that have that panel. For instructions on how to create, add, unlink and manage library panels, refer to [Library panels]({{< relref "../panels/panel-library.md" >}}). + +### Real-time streaming + +Data sources can now send real-time updates to dashboards over a websocket connection. This can be used with the [MQTT data source](https://github.com/grafana/mqtt-datasource). + +In addition to data source integration, events can be sent to dashboards by posting metrics to the new live endpoint: `/api/live/push` endpoint. + +These metrics will be broadcast to all dashboards connected to that stream endpoint. + +For more information about real-time streaming, refer to [Grafana Live documentation]({{< relref "../live/_index.md" >}}). + +### Prometheus metrics browser + +The Prometheus metrics browser allows you to quickly find metrics and select relevant labels to build basic queries. If supported by your Prometheus instance, each metric will show its HELP and TYPE as a tooltip. For more information, refer to [Metrics browser documentation]({{< relref "../datasources/prometheus.md#metrics-browser" >}}). + +### Bar chart visualization (beta) + +The Bar chart panel is a new visualization that supports categorical data. It only supports one data frame and it needs to have at least one string field that will be used as the category for an X or Y axis and one or more numerical fields. + +{{< figure src="/static/img/docs/bar-chart-panel/bar-chart-example-v8-0.png" max-width="1025px" caption="Bar chart example" >}} + +To use it with time series you first have to add a **Reduce** transform. + +For more information, refer to [Bar chart visualization]({{< relref "../visualizations/bar-chart.md" >}}). + +### State timeline visualization (beta) + +The State timeline visualization shows discrete state changes over time. Each field or series is rendered as a unique horizontal band. This panel works well with string or boolean states, but it can also be used with time series data. When used with time series data, the thresholds are used to turn the numerical values into discrete state regions. + +This panel also takes advantage of the new value mapping features that allow you to color string and boolean values. + +Example with string values: +{{< figure src="/static/img/docs/v8/state_timeline_strings.png" max-width="800px" caption="state timeline with string states" >}} + +With time series data and thresholds: +{{< figure src="/static/img/docs/v8/state_timeline_time_series.png" max-width="800px" caption="state timeline with time series" >}} + +For more information, refer to [State timeline visualization]({{< relref "../visualizations/state-timeline.md" >}}). + +### Status history visualization (beta) + +A sister panel to the state timeline is the new Status history panel visualization. It can display periodic states in a grid view. It supports both numerical, string, or boolean states. You can assign colors using value mappings, thresholds, or gradient color. For more information, refer to [Status history]({{< relref "../visualizations/status-history.md" >}}). +schemes. + +![Status grid visualization](/static/img/docs/status-grid/status-grid-8-0.png) + +### Histogram visualization (beta) + +This hidden feature of the old Graph panel is now a standalone visualization. It combines a histogram transformation and bar chart visualization into a single, integrated, easy-to-use panel. There is also a new standalone histogram transformation that can be paired with any visualization. + +{{< figure src="/static/img/docs/histogram/histogram-8-0.png" max-width="1025px" caption="Histogram example" >}} + +For more information, refer to [Histogram]({{< relref "../visualizations/histogram.md" >}}) + +### Time series visualization updates + +The Time series is out of beta! We are removing the `Beta` tag and graduating the Time series visualization to a stable state. + +- **Time series** is now the default visualization option, replacing the **Graph (old)**. +- The Time series panel now supports stacking. For more information, refer to [Graph stacked time series]({{< relref "../visualizations/time-series/graph-time-series-stacking.md" >}}). +- You can now add alerts in the Time series panel, just like the old Graph panel. +- Updated [connect null values]({{< relref "../visualizations/time-series/graph-time-series-as-lines.md#connect-null-values" >}}) options. +- We added support for a shared crosshair and a tooltip that’s now smarter when it comes to data display in the tooltip. +- Various performance improvements. + +[Time series panel]({{< relref "../visualizations/time-series/_index.md" >}}) topics have been updated as a result of these changes. + +### Node graph visualization updates + +You can now expand the node graph for the displayed trace when using the Trace to logs feature. Depending on the data source, this can show spans of the trace as nodes in the graph, or as some additional context like service map based on the current trace. + +We also added a grid view and the ability to explore hidden nodes. + +[Tracing in Explore]({{< relref "../explore/trace-integration.md" >}}) and [Node graph]({{< relref "../visualizations/node-graph.md" >}}) were updated as a result of these changes. + +### Pie chart visualization updates + +The Pie chart is out of beta! We are removing the `beta` tag and graduating the Pie chart visualization to a stable state. + +### Panel editor updates + +Lots of panel editor improvements, heavily informed by user research and community feedback. + +- All options are now shown in a single pane. +- You can now search panel options. +- The Value mappings feature has been completely redesigned. For more information, refer to [Value mappings]({{< relref "../panels/value-mappings.md" >}}). +- New **Table view** option is always available. + +The [Panels]({{< relref "../panels/_index.md" >}}) section has been updated to reflect these changes. + +### Look and feel update + +Grafana 8 comes with a refreshed look and feel, including themes changed to be more accessible. The improved Grafana UI brings a number of adjustments and tweaks that make the application even more fun to use. Enjoy the new home dashboard design! + +Under the hood, the new theme architecture enables us to bring more sophisticated themes control in the future. + +### Download logs + +When you inspect a panel, you can now download log results as a text (.txt) file. + +[Download log results]({{< relref "../panels/inspect-panel.md#download-log-results" >}}) in [Inspect a panel]({{< relref "../panels/inspect-panel.md" >}}) was added as a result of this feature. + +### Inspector in Explore + +The new Explore inspector helps you understand and troubleshoot your queries. You can inspect the raw data, export that data to a comma-separated values (CSV) file, export log results in text format, and view query requests. + +[Inspector in Explore]({{< relref "../explore/explore-inspector.md" >}}) was added as a result of this feature. + +### Explore log improvements + +Log navigation in Explore has been significantly improved. We added pagination to logs, so you can click through older or newer logs as needed. + +[Logs in Explore]({{< relref "../explore/logs-integration.md" >}}) was updated as a result of these changes. + +![Navigate logs in Explore](/static/img/docs/explore/navigate-logs-8-0.png) + +### Plugin catalog + +You can now use the Plugin catalog app to easily manage your plugins from within Grafana. Install, update, and uninstall plugins without requiring a server restart. + +[Plugin catalog]({{< relref "../plugins/catalog.md" >}}) was added as a result of this feature. + +### Performance improvements + +Grafana 8.0 includes many performance enhancements. + +#### Initial startup and load performance + +We reduced the Grafana initial download size massively, approximately 40%. This means that on slower or mobile connections, the initial login page or home dashboard will load much faster. + +All panels that have migrated from Flot to uPlot will also render two to three times faster because the library is much more efficient. Right now, this includes the Time series, Stat, Timeline, Histogram, and Barchart panel visualizations. + +#### Operational and runtime performance + +These improvements affect any subsequent data updates or interactions, including: + +- Streaming performance +- General speed of interaction, such as zooming, tooltips, synchronized cursors, and panel updates while editing + +### Data source updates + +The following data source updates are included with this Grafana release. + +#### Azure Monitor data source + +Azure Resource Graph is now supported in the Azure Monitor data source. This is a service in Azure that is designed to extend Azure Resource Management by providing efficient and performant exploration of your Azure resources. + +The Azure Monitor data source now supports Managed Identity for users hosting Grafana in Azure to simplify and secure configuring Azure Monitor in Grafana. + +Also, in addition to querying Log Analytics Workspaces, you can now query the logs for any individual [supported resource](https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/metrics-supported), or for all resources in a subscription or resource group. + +> **Note:** In Grafana 7.5 we started the deprecation for separate Application Insights queries, in favor of querying Application Insights resources through Metrics and Logs. In Grafana 8.0 new Application Insights and Insights Analytics queries cannot be made, and existing queries have been made read-only. For more details, refer to the [Deprecating Application Insights]({{< relref "../datasources/azuremonitor/_index.md#deprecating-application-insights" >}}). + +[Azure Monitor data source]({{< relref "../datasources/azuremonitor/_index.md" >}}) was updated as a result of these changes. + +#### Elasticsearch data source + +[Elasticsearch data source]({{< relref "../datasources/elasticsearch.md" >}}) and [Provisioning]({{< relref "../administration/provisioning.md" >}}) were updated as a result of these changes. + +##### Use semver strings to identify Elasticsearch version + +We changed how the configured Elasticsearch version is handled. You can now specify via provisioning the full semver string version of your instance (such as “7.12.1”) instead of the old version format based on numbers. There’s no manual intervention needed, the old options will be correctly recognized. + +##### Generic support for template variables + +You can now use a different interpolation method to use template variables in a more extensive way. You can now use template variables in every query editor field that allows free input. + +![Elasticsearch template variables](/static/img/docs/elasticsearch/input-templates-8-0.png) + +##### Allow omitting field for metrics that support inline scripts + +Metric aggregations can be specified without a field if a script is provided. You can now deselect fields for metrics aggregation when they support scripting. + +Previously this was only possible when adding a new metric without selecting a field, because once selected, the field could not have been removed. + +![Elasticsearch omit fields](/static/img/docs/elasticsearch/omit-fields-8-0.png) + +##### Allow setting a custom limit for log queries + +You can now set a custom line limit for logs queries instead of accepting the previously hard-coded 500. We also simplified the query editor to only show relevant fields when issuing logs queries. + +![Elasticsearch custom log limit](/static/img/docs/elasticsearch/custom-log-limit-8-0.png) + +##### Guess field type from first non-empty value + +Response values were always interpreted as strings in Elasticsearch responses, which caused issues with some visualization types that applied logic based on numeric values. We now apply some heuristics to detect value types from the first non-empty value in each response. + +#### Google Cloud Monitoring data source + +In a prior release, Cloud Monitoring added _preprocessing_ support in their query editor. This capability has been added to the Cloud Monitoring data source in Grafana. + +Whenever a metric is selected in the query editor, a suitable preprocessing option is automatically selected for you. To avoid breaking changes, preprocessing is not enabled by default on existing queries. If you want to use preprocessing for existing queries, you have to manually select one in the query editor. + +[Google Cloud Monitoring data source]({{< relref "../datasources/google-cloud-monitoring/_index.md#pre-processing" >}}) was updated as a result of this change. + +#### Graphite data source + +[Graphite data source]({{< relref "../datasources/graphite.md" >}}) was updated as a result of these changes. + +##### Variable metric names expand + +Values for dashboard variables can be now populated using the [Graphite expand API](https://graphite-api.readthedocs.io/en/latest/api.html#metrics-expand). Expand API is used when the metric query is wrapped in expand() function. + +This way, values can contain not only the last matching node from the metric query, but also the full path of the metric. It can also be narrowed down to a specific node with a regular expression. + +##### Map Graphite queries to Loki + +Graphite queries are now automatically transformed to Loki queries according to user-defined rules when the data source changes in Explore. + +#### Jaeger data source + +You can now use more parameters to find traces. + +[Jaeger data source]({{< relref "../datasources/jaeger.md" >}}) was updated as a result of this change. + +### Authentication updates + +This Grafana release includes the following authentication updates. + +#### JWT + +JWT is a new authentication option in Grafana. + +#### Added JWT authentication support + +You can now configure Grafana to accept a JWT token provided in the HTTP header. + +[JWT authentication]({{< relref "../auth/jwt.md" >}}) was added and [Configuration]({{< relref "../administration/configuration.md#auth.jwt" >}}) was updated as a result of this feature. + +#### OAuth + +[Generic OAuth authentication]({{< relref "../auth/generic-oauth.md" >}}) has been updated as a result of these changes. + +##### Added OAuth support for empty scopes + +You can now configure generic OAuth with empty scopes. This allows OAuth Identity Providers that don't use or support scopes to work with Grafana authentication. + +##### Added OAuth support for strict parsing of role_attribute_path + +You can now configure generic OAuth with strict parsing of the `role_attribute_path`. By default, if the `role_attribute_path` property does not return a role, then the user is assigned the `Viewer` role. You can disable the role assignment by setting `role_attribute_strict = true`. It denies user access if no role or an invalid role is returned. + +#### Singlestat panel deprecated + +Support for Singlestat panel has been discontinued. When you upgrade to version 8.0, all existing Singlestat panels automatically becomes Stat panels. +Stat panel is available as plugin. + +### Grafana license update + +Grafana has updated its license from Apache 2.0 to the GNU Affero General Public License (AGPL). Please see the related [blog post](https://grafana.com/blog/2021/04/20/grafana-loki-tempo-relicensing-to-agplv3/), [Q&A](https://grafana.com/blog/2021/04/20/qa-with-our-ceo-on-relicensing/) and [license](https://github.com/grafana/grafana/blob/main/LICENSE) for more details. + +## Enterprise features + +These features are included in the Grafana Enterprise edition. + +### Fine-grained access control + +You can now add or remove detailed permissions from Viewer, Editor, and Admin org roles, to grant users just the right amount of access within Grafana. Available permissions include the ability to view and manage Users, Reports, and the Access Control API itself. Grafana will support more and more permissions over the coming months. + +[Fine-grained access control docs]({{< relref "../enterprise/access-control/_index.md" >}}) were added as a result of this feature. + +### Data source query caching + +Grafana caches the results of backend data source queries so that multiple users viewing the same dashboard or panel do not make multiple submissions of the same query to the data source (like Splunk or Snowflake) itself. + +This results in faster average load times for dashboards and fewer duplicate queries overall to data sources, which reduces cost and the risk of throttling, reaching API limits, or overloading your data sources. + +You can enable caching per data source, and time-to-live (TTL) can be configured globally and per data source. Query caching can be set up with Redis, Memcached, or a simple in-memory cache. + +For more information, refer to the [Data source query caching docs]({{< relref "../enterprise/query-caching.md" >}}). + +### Reporting updates + +When creating a report, you can now choose to export Table panels as .csv files attached to your report email. This makes it easier for recipients to view and work with that data. + +You can also link back to the dashboard directly from the email, for users who want to see the data live in Grafana. This release also includes some improvements to the Reports list view. + +For more information, refer to [Reporting docs]({{< relref "../enterprise/reporting.md" >}}). + +### License restrictions clarification in the docs + +The Grafana Enterprise documentation has been updated to describe more specifically how licensed roles are counted, how they can be updated, and where you can see details about dashboard and folder permissions that affect users' licensed roles. + +For more information, refer to [License restrictions docs]({{< relref "../enterprise/license/license-restrictions.md" >}}). + +## Breaking changes + +The following breaking changes are included in this release. + +### Variables + +- Removed the **Value groups/tags** feature from variables. Any tags will be removed. +- Removed the `never` refresh option for query variables. Existing variables will be migrated and any stored options will be removed. + +Documentation was updated to reflect these changes. + +### Elasticsearch: Use application/x-ndjson content type for multi-search requests + +For multi-search requests, we now use the correct application/x-ndjson content type instead of the incorrect application/json. Although this should be transparent to most of the users, if you are running Elasticsearch behind a proxy, then be sure that your proxy correctly handles requests with this content type. + +### Prometheus: Update default HTTP method to POST for existing data sources + +The default HTTP method for Prometheus data source is now POST, previously it was GET. The POST APIs are there since January 2018 (Prometheus 2.1.0) and they have fewer limitations than the GET APIs. Users with Prometheus instance with version < 2.1.0 that use the default HTTP method should update their HTTP method to GET. diff --git a/docs/sources/whatsnew/whats-new-in-v8-1.md b/docs/sources/whatsnew/whats-new-in-v8-1.md new file mode 100644 index 00000000..c675aec1 --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v8-1.md @@ -0,0 +1,162 @@ ++++ +title = "What's new in Grafana v8.1" +description = "Feature and improvement highlights for Grafana v8.1" +keywords = ["grafana", "new", "documentation", "8.1", "release notes"] +weight = -33 +aliases = ["/docs/grafana/latest/guides/whats-new-in-v8-1/"] +[_build] +list = false ++++ + +# What’s new in Grafana v8.1 + +> **Note:** This topic will be updated frequently between now and the final release. + +Grafana 8.1 builds upon our promise of a composable, open observability platform with new panels and extends functionality launched in Grafana 8.0. We’ve got new Geomap and Annotations panels, and some great updates to the Time Series panel. We’ve also got new transformations and updates to data sources. For our enterprise customers, there are additions to fine grained access control, updates to the reporting schedule and query caching, and more. Read on to learn more. + +In addition to what is summarized here, you might also be interested in our announcement blog post. For all the technical details, check out the complete [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). + +## Grafana OSS features + +These features are included in the Grafana open source edition. + +## Geomap panel + +Grafana 8.1 introduces the foundation for our new map panel. This new panel leverages [OpenLayers](https://openlayers.org/) and gives us a flexible solution for extending the way we use the new Geomap panel moving forward. The new Geomap panel includes multiple base layer styles (map layer options), as well as a more open data layer. The data layer can use coordinates and geo-hashed data in addition to a lookup table. + +The Geomap panel is also able to share views across multiple Geomap panels on the same dashboard, making it straightforward to visualize and explore multiple types of geospatial data using the same map zoom and focus settings. For more information, refer to [Geomap panel]({{< relref "../visualizations/geomap.md" >}}). +{{< figure src="/static/img/docs/geomap-panel/geomap_with_heatmap.png" max-width="850px" caption="Geomap panel: Heatmap" >}} + +## Annotation panel + +The new Annotations panel shows a list of available annotations you can use to create lists of annotated data available within your organization. Various options are available to filter the list based on the tags and on the current dashboard. This panel makes it easy to find and filter annotated data within and across multiple dashboards. + +{{< figure src="/static/img/docs/annotations-panel/annolist.png" max-width="900px" caption="Annotations panel" >}} + +### Time series panel updates + +The time series panel has been updated with the ability to color series and line by thresholds or gradient color scales. This allows users to create panels where the line color can change dynamically based on thresholds or using gradient color scales. It adds a layer of visibility to your data, making it easier to view the changes across thresholds at a glance quickly. + +Color scheme **From thresholds**: +{{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_thresholds_line.png" max-width="1200px" caption="Colors scheme: From thresholds" >}} + +Color scheme: **Green-Yellow-Red (by value)** +{{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_line.png" max-width="1200px" caption="Color scheme: Green-Yellow-Red" >}} + +For more on how to configure Graphs with by value color schemes read [Graph and color schemes]({{< relref "../visualizations/time-series/_index.md" >}}). + +You can also create [annotations]({{< relref "../visualizations/time-series/annotate-time-series.md" >}}) in the new Time series panel bringing it closer to parity with the legacy Graph panel. To learn more, refer to the [time series panel]({{< relref "../visualizations/time-series/_index.md" >}}). + +### Transformations improvements + +Grafana 8.1 includes some significant enhancements to transformations, including two new transformations designed around providing dynamic configuration to your panels and visulizations. + +#### Config from query (Beta) + +This transformation enables panel config (Threshold, Min, Max, etc.) to be derived from query results. For more information, refer to [Config from query results transform]({{< relref "../panels/transformations/config-from-query.md" >}}). + +#### Rows to fields (Beta) + +This transformation enables rows in returned data to be converted into separate fields. Prior to this enhancement, you could style and configure fields individually, but not rows. For more information, refer to [Rows to fields transform]. + +Example, Input: + +| Name | Value | Max | +| ------- | ----- | --- | +| ServerA | 10 | 100 | +| ServerB | 20 | 200 | +| ServerC | 30 | 300 | + +Output: + +| ServerA (config: max=100) | ServerB (config: max=200) | ServerC (config: max=300) | +| ------------------------- | ------------------------- | ------------------------- | +| 10 | 20 | 30 | + +As you can see each row in the source data becomes a separate field. Each field now also has a max config option set. Options like **Min**, **Max**, **Unit** and **Thresholds** are all part of field configuration and if set like this will be used by the visualization instead of any options manually configured in the panel editor options pane. + +For more on how to use this transformation, refer to [Rows to fields transform]({{< relref "../panels/transformations/rows-to-fields.md" >}}). + +#### Contextual & Inline Help + +Additional inline help will be available for Transformations. We can now share examples of how to use specific transformations and point users directly to the appropriate place in the docs for more information. + +### Data source updates + +The following data source updates are included with this Grafana release. + +#### MySQL Data Source + +We have added timezone support. As a result, you can now specify the time zone used in the database session, such as `Europe/Berlin` or `+02:00`. + +### Trace to logs improvements + +We changed the default behavior from creating a 1-hour span Loki query to the only query at the exact time the trace span started for the duration of it. For more fine grained control over this, you can shift this time in the tracing data source settings. Also, it is now possible to shift the start time and end time of the Loki query by the set amount. For more information, refer to [Trace to logs]({{< relref "../datasources/tempo.md#trace-to-logs" >}}). + +### Prettify JSON for Logs in Explore + +Added the ability to format JSON to make it easier to view, review and find relevant data in JSON format logs. This is a regular JSON log. + +{{< figure src="/static/img/docs/panels/pretty-json/regular-log-line.png" max-width="1200px" caption="Regular log line" >}} + +And here is the prettified JSON log. + +{{< figure src="/static/img/docs/panels/pretty-json/prettified-json.png" max-width="1200px" caption="Prettified JSON" >}} + +For more on how to prettify JSON logs, refer to [Visualization]({{< relref "../visualizations/_index.md" >}}) and [Display]({{< relref "../visualizations/logs-panel.md" >}}) options. + +### Plugin catalog - Updated UX and extended features + +We’ve made some changes to the plugins UI to help make it easier to discover and manage your plugins. Enterprise users can now also manage enterprise plugins from within the catalog. + +#### Documentation updates + +New panel summaries and preview on the top level [Visualizations]({{< relref "../visualizations/_index.md" >}}) page to help users pick or learn about specific visualizations more easily. + +### Upcoming changes to the Select component + +The `@grafana/ui` exposes a `Select` component, and its variants `MultiSelect`, `AsyncSelect`, and `AsyncMultiSelect`. We have made some internal changes to these components to make the behavior and positioning more consistent in all scenarios. + +To test the changes, you can use the `menuShouldPortal` property: + +```jsx + { + if (o.meta && isUnsignedPluginSignature(o.meta.signature) && o !== value) { + return ( + + {o.label} + + ); + } + return o.label || ''; + }} + /> + + ); + } +} diff --git a/packages/grafana-runtime/src/components/PanelDataErrorView.tsx b/packages/grafana-runtime/src/components/PanelDataErrorView.tsx new file mode 100644 index 00000000..25e577d6 --- /dev/null +++ b/packages/grafana-runtime/src/components/PanelDataErrorView.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { PanelData } from '@grafana/data'; + +/** + * Describes the properties that can be passed to the PanelDataErrorView. + * + * @alpha + */ +export interface PanelDataErrorViewProps { + message?: string; + panelId: number; + data: PanelData; + needsTimeField?: boolean; + needsNumberField?: boolean; + needsStringField?: boolean; + // suggestions?: VisualizationSuggestion[]; <<< for sure optional +} + +/** + * Simplified type with defaults that describes the PanelDataErrorView. + * + * @internal + */ +export type PanelDataErrorViewType = React.ComponentType; + +/** + * PanelDataErrorView allows panels to show a consistent error message when + * the result structure does not meet expected criteria + * + * @alpha + */ +export let PanelDataErrorView: PanelDataErrorViewType = ({ message }) => { + return
Unable to render data: {message}.
; +}; + +/** + * Used to bootstrap the PanelDataErrorView during application start so the + * PanelDataErrorView is exposed via runtime. + * + * @internal + */ +export function setPanelDataErrorView(renderer: PanelDataErrorViewType) { + PanelDataErrorView = renderer; +} diff --git a/packages/grafana-runtime/src/components/PanelRenderer.tsx b/packages/grafana-runtime/src/components/PanelRenderer.tsx new file mode 100644 index 00000000..a2f8cc34 --- /dev/null +++ b/packages/grafana-runtime/src/components/PanelRenderer.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { AbsoluteTimeRange, FieldConfigSource, PanelData } from '@grafana/data'; + +/** + * Describes the properties that can be passed to the PanelRenderer. + * + * @typeParam P - Panel options type for the panel being rendered. + * @typeParam F - Field options type for the panel being rendered. + * + * @internal + */ +export interface PanelRendererProps

{ + data: PanelData; + pluginId: string; + title: string; + options?: Partial

; + onOptionsChange?: (options: P) => void; + onChangeTimeRange?: (timeRange: AbsoluteTimeRange) => void; + fieldConfig?: FieldConfigSource>; + timeZone?: string; + width: number; + height: number; +} + +/** + * Simplified type with defaults that describes the PanelRenderer. + * + * @internal + */ +export type PanelRendererType

= React.ComponentType< + PanelRendererProps +>; + +/** + * PanelRenderer component that will be set via the {@link setPanelRenderer} function + * when Grafana starts. The implementation being used during runtime lives in Grafana + * core. + * + * @internal + */ +export let PanelRenderer: PanelRendererType = () => { + return

PanelRenderer can only be used after Grafana instance has been started.
; +}; + +/** + * Used to bootstrap the PanelRenderer during application start so the PanelRenderer + * is exposed via runtime. + * + * @internal + */ +export function setPanelRenderer(renderer: PanelRendererType) { + PanelRenderer = renderer; +} diff --git a/packages/grafana-runtime/src/config.ts b/packages/grafana-runtime/src/config.ts new file mode 100644 index 00000000..8d6ce2ae --- /dev/null +++ b/packages/grafana-runtime/src/config.ts @@ -0,0 +1,156 @@ +import { merge } from 'lodash'; +import { + BuildInfo, + createTheme, + DataSourceInstanceSettings, + FeatureToggles, + GrafanaConfig, + GrafanaTheme, + GrafanaTheme2, + LicenseInfo, + MapLayerOptions, + PanelPluginMeta, + PreloadPlugin, + systemDateFormats, + SystemDateFormatSettings, +} from '@grafana/data'; + +export interface AzureSettings { + cloud?: string; + managedIdentityEnabled: boolean; +} + +export class GrafanaBootConfig implements GrafanaConfig { + datasources: { [str: string]: DataSourceInstanceSettings } = {}; + panels: { [key: string]: PanelPluginMeta } = {}; + minRefreshInterval = ''; + appUrl = ''; + appSubUrl = ''; + windowTitlePrefix = ''; + buildInfo: BuildInfo = {} as BuildInfo; + newPanelTitle = ''; + bootData: any; + externalUserMngLinkUrl = ''; + externalUserMngLinkName = ''; + externalUserMngInfo = ''; + allowOrgCreate = false; + disableLoginForm = false; + defaultDatasource = ''; // UID + alertingEnabled = false; + alertingErrorOrTimeout = ''; + alertingNoDataOrNullValues = ''; + alertingMinInterval = 1; + authProxyEnabled = false; + exploreEnabled = false; + ldapEnabled = false; + sigV4AuthEnabled = false; + samlEnabled = false; + samlName = ''; + autoAssignOrg = true; + verifyEmailEnabled = false; + oauth: any; + disableUserSignUp = false; + loginHint: any; + passwordHint: any; + loginError: any; + navTree: any; + viewersCanEdit = false; + editorsCanAdmin = false; + disableSanitizeHtml = false; + liveEnabled = true; + theme: GrafanaTheme; + theme2: GrafanaTheme2; + pluginsToPreload: PreloadPlugin[] = []; + featureToggles: FeatureToggles = { + accesscontrol: false, + trimDefaults: false, + tempoServiceGraph: false, + tempoSearch: false, + recordedQueries: false, + newNavigation: false, + fullRangeLogsVolume: false, + queryOverLive: false, + dashboardPreviews: false, + }; + licenseInfo: LicenseInfo = {} as LicenseInfo; + rendererAvailable = false; + rendererVersion = ''; + http2Enabled = false; + dateFormats?: SystemDateFormatSettings; + sentry = { + enabled: false, + dsn: '', + customEndpoint: '', + sampleRate: 1, + }; + pluginCatalogURL = 'https://grafana.com/grafana/plugins/'; + pluginAdminEnabled = true; + pluginAdminExternalManageEnabled = false; + pluginCatalogHiddenPlugins: string[] = []; + expressionsEnabled = false; + customTheme?: any; + awsAllowedAuthProviders: string[] = []; + awsAssumeRoleEnabled = false; + azure: AzureSettings = { + managedIdentityEnabled: false, + }; + caching = { + enabled: false, + }; + geomapDefaultBaseLayerConfig?: MapLayerOptions; + geomapDisableCustomBaseLayer?: boolean; + unifiedAlertingEnabled = false; + applicationInsightsConnectionString?: string; + applicationInsightsEndpointUrl?: string; + recordedQueries = { + enabled: false, + }; + + constructor(options: GrafanaBootConfig) { + const mode = options.bootData.user.lightTheme ? 'light' : 'dark'; + this.theme2 = createTheme({ colors: { mode } }); + this.theme = this.theme2.v1; + + const defaults = { + datasources: {}, + windowTitlePrefix: 'Grafana - ', + panels: {}, + newPanelTitle: 'Panel Title', + playlist_timespan: '1m', + unsaved_changes_warning: true, + appUrl: '', + appSubUrl: '', + buildInfo: { + version: 'v1.0', + commit: '1', + env: 'production', + isEnterprise: false, + }, + viewersCanEdit: false, + editorsCanAdmin: false, + disableSanitizeHtml: false, + }; + + merge(this, defaults, options); + + if (this.dateFormats) { + systemDateFormats.update(this.dateFormats); + } + } +} + +const bootData = (window as any).grafanaBootData || { + settings: {}, + user: {}, + navTree: [], +}; + +const options = bootData.settings; +options.bootData = bootData; + +/** + * Use this to access the {@link GrafanaBootConfig} for the current running Grafana instance. + * + * @public + */ +export const config = new GrafanaBootConfig(options); diff --git a/packages/grafana-runtime/src/index.ts b/packages/grafana-runtime/src/index.ts new file mode 100644 index 00000000..1c3f648a --- /dev/null +++ b/packages/grafana-runtime/src/index.ts @@ -0,0 +1,29 @@ +/** + * A library containing services, configurations etc. used to interact with the Grafana engine. + * + * @packageDocumentation + */ +export * from './services'; +export * from './config'; +export * from './types'; +export { loadPluginCss, SystemJS, PluginCssOptions } from './utils/plugin'; +export { reportMetaAnalytics, reportInteraction, reportPageview } from './utils/analytics'; +export { logInfo, logDebug, logWarning, logError } from './utils/logging'; +export { + DataSourceWithBackend, + HealthCheckResult, + HealthCheckResultDetails, + HealthStatus, + StreamOptionsProvider, +} from './utils/DataSourceWithBackend'; +export { + toDataQueryResponse, + frameToMetricFindValue, + BackendDataSourceResponse, + DataResponse, +} from './utils/queryResponse'; +export { PanelRenderer, PanelRendererProps } from './components/PanelRenderer'; +export { PanelDataErrorView, PanelDataErrorViewProps } from './components/PanelDataErrorView'; +export { toDataQueryError } from './utils/toDataQueryError'; +export { setQueryRunnerFactory, createQueryRunner, QueryRunnerFactory } from './services/QueryRunner'; +export { DataSourcePicker, DataSourcePickerProps, DataSourcePickerState } from './components/DataSourcePicker'; diff --git a/packages/grafana-runtime/src/services/AngularLoader.ts b/packages/grafana-runtime/src/services/AngularLoader.ts new file mode 100644 index 00000000..c7beac4f --- /dev/null +++ b/packages/grafana-runtime/src/services/AngularLoader.ts @@ -0,0 +1,87 @@ +/** + * Used to enable rendering of Angular components within a + * React component without losing proper typings. + * + * @example + * ```typescript + * class Component extends PureComponent { + * element: HTMLElement; + * angularComponent: AngularComponent; + * + * componentDidMount() { + * const template = '' // angular template here; + * const scopeProps = { ctrl: angularController }; // angular scope properties here + * const loader = getAngularLoader(); + * this.angularComponent = loader.load(this.element, scopeProps, template); + * } + * + * componentWillUnmount() { + * if (this.angularComponent) { + * this.angularComponent.destroy(); + * } + * } + * + * render() { + * return ( + *
(this.element = element)} /> + * ); + * } + * } + * ``` + * + * @public + */ +export interface AngularComponent { + /** + * Should be called when the React component will unmount. + */ + destroy(): void; + /** + * Can be used to trigger a re-render of the Angular component. + */ + digest(): void; + /** + * Used to access the Angular scope from the React component. + */ + getScope(): any; +} + +/** + * Used to load an Angular component from the context of a React component. + * Please see the {@link AngularComponent} for a proper example. + * + * @public + */ +export interface AngularLoader { + /** + * + * @param elem - the element that the Angular component will be loaded into. + * @param scopeProps - values that will be accessed via the Angular scope. + * @param template - template used by the Angular component. + */ + load(elem: any, scopeProps: any, template: string): AngularComponent; +} + +let instance: AngularLoader; + +/** + * Used during startup by Grafana to set the AngularLoader so it is available + * via the {@link getAngularLoader} to the rest of the application. + * + * @internal + */ +export function setAngularLoader(v: AngularLoader) { + instance = v; +} + +/** + * Used to retrieve the {@link AngularLoader} that enables the use of Angular + * components within a React component. + * + * Please see the {@link AngularComponent} for a proper example. + * + * @public + */ +export function getAngularLoader(): AngularLoader { + return instance; +} diff --git a/packages/grafana-runtime/src/services/EchoSrv.ts b/packages/grafana-runtime/src/services/EchoSrv.ts new file mode 100644 index 00000000..7e8ae524 --- /dev/null +++ b/packages/grafana-runtime/src/services/EchoSrv.ts @@ -0,0 +1,142 @@ +/** + * Describes a size with width/height + * + * @public + */ +export interface SizeMeta { + width: number; + height: number; +} + +/** + * Describes the meta information that are sent together with each event. + * + * @public + */ +export interface EchoMeta { + screenSize: SizeMeta; + windowSize: SizeMeta; + userAgent: string; + url?: string; + /** + * A unique browser session + */ + sessionId: string; + /** + * The current users username used to login into Grafana e.g. email. + */ + userLogin: string; + /** + * The current users unique identifier. + */ + userId: number; + /** + * True when user is logged in into Grafana. + */ + userSignedIn: boolean; + /** + * A millisecond epoch + */ + ts: number; + /** + * A highres timestamp since navigation start + */ + timeSinceNavigationStart: number; +} + +/** + * Describes echo backends that can be registered to receive of events. + * + * @public + */ +export interface EchoBackend { + options: O; + supportedEvents: EchoEventType[]; + flush: () => void; + addEvent: (event: T) => void; +} + +/** + * Describes an echo event. + * + * @public + */ +export interface EchoEvent { + type: EchoEventType; + /** + * Event payload containing event specific data. + */ + payload: P; + meta: EchoMeta; +} + +/** + * Supported echo event types that can be sent via the {@link EchoSrv}. + * + * @public + */ +export enum EchoEventType { + Performance = 'performance', + MetaAnalytics = 'meta-analytics', + Sentry = 'sentry', + Pageview = 'pageview', + Interaction = 'interaction', +} + +/** + * Used to send events to all the registered backends. This should be accessed via the + * {@link getEchoSrv} function. Will, by default, flush events to the backends every + * 10s or when the flush function is triggered. + * + * @public + */ +export interface EchoSrv { + /** + * Call this to flush current events to the echo backends. + */ + flush(): void; + /** + * Add a new echo backend to the list of backends that will receive events. + */ + addBackend(backend: EchoBackend): void; + /** + * Call this to add event that will be sent to the echo backends upon next + * flush. + * + * @param event - Object containing event information. + * @param meta - Object that will extend/override the default meta object. + */ + addEvent(event: Omit, meta?: {}): void; +} + +let singletonInstance: EchoSrv; + +/** + * Used during startup by Grafana to set the EchoSrv so it is available + * via the {@link getEchoSrv} to the rest of the application. + * + * @internal + */ +export function setEchoSrv(instance: EchoSrv) { + singletonInstance = instance; +} + +/** + * Used to retrieve the {@link EchoSrv} that can be used to report events to registered + * echo backends. + * + * @public + */ +export function getEchoSrv(): EchoSrv { + return singletonInstance; +} + +/** + * Used to register echo backends that will receive Grafana echo events during application + * runtime. + * + * @public + */ +export const registerEchoBackend = (backend: EchoBackend) => { + getEchoSrv().addBackend(backend); +}; diff --git a/packages/grafana-runtime/src/services/LocationService.test.ts b/packages/grafana-runtime/src/services/LocationService.test.ts new file mode 100644 index 00000000..c01282b5 --- /dev/null +++ b/packages/grafana-runtime/src/services/LocationService.test.ts @@ -0,0 +1,54 @@ +import { locationService } from './LocationService'; + +describe('LocationService', () => { + describe('getSearchObject', () => { + it('returns query string as object', () => { + locationService.push('/test?query1=false&query2=123&query3=text'); + + expect(locationService.getSearchObject()).toEqual({ + query1: false, + query2: '123', + query3: 'text', + }); + }); + + it('returns keys added multiple times as an array', () => { + locationService.push('/test?servers=A&servers=B&servers=C'); + + expect(locationService.getSearchObject()).toEqual({ + servers: ['A', 'B', 'C'], + }); + }); + }); + + describe('partial', () => { + it('should handle removing params and updating', () => { + locationService.push('/test?query1=false&query2=123&query3=text'); + locationService.partial({ query1: null, query2: 'update' }); + + expect(locationService.getLocation().search).toBe('?query2=update&query3=text'); + }); + + it('should handle array values', () => { + locationService.push('/'); + locationService.partial({ servers: ['A', 'B', 'C'] }); + + expect(locationService.getLocation().search).toBe('?servers=A&servers=B&servers=C'); + }); + + it('persist state', () => { + locationService.push({ + pathname: '/d/123', + state: { + some: 'stateToPersist', + }, + }); + locationService.partial({ q: 1 }); + + expect(locationService.getLocation().search).toBe('?q=1'); + expect(locationService.getLocation().state).toEqual({ + some: 'stateToPersist', + }); + }); + }); +}); diff --git a/packages/grafana-runtime/src/services/LocationService.ts b/packages/grafana-runtime/src/services/LocationService.ts new file mode 100644 index 00000000..06196ad3 --- /dev/null +++ b/packages/grafana-runtime/src/services/LocationService.ts @@ -0,0 +1,160 @@ +import { deprecationWarning, UrlQueryMap, urlUtil } from '@grafana/data'; +import * as H from 'history'; +import { LocationUpdate } from './LocationSrv'; +import { attachDebugger, createLogger } from '@grafana/ui'; +import { config } from '../config'; + +/** + * @alpha + * A wrapper to help work with browser location and history + */ +export interface LocationService { + partial: (query: Record, replace?: boolean) => void; + push: (location: H.Path | H.LocationDescriptor) => void; + replace: (location: H.Path | H.LocationDescriptor) => void; + reload: () => void; + getLocation: () => H.Location; + getHistory: () => H.History; + getSearch: () => URLSearchParams; + getSearchObject: () => UrlQueryMap; + + /** + * This is from the old LocationSrv interface + * @deprecated use partial, push or replace instead */ + update: (update: LocationUpdate) => void; +} + +/** @internal */ +export class HistoryWrapper implements LocationService { + private readonly history: H.History; + + constructor(history?: H.History) { + // If no history passed create an in memory one if being called from test + this.history = + history || + (process.env.NODE_ENV === 'test' + ? H.createMemoryHistory({ initialEntries: ['/'] }) + : H.createBrowserHistory({ basename: config.appSubUrl ?? '/' })); + + this.partial = this.partial.bind(this); + this.push = this.push.bind(this); + this.replace = this.replace.bind(this); + this.getSearch = this.getSearch.bind(this); + this.getHistory = this.getHistory.bind(this); + this.getLocation = this.getLocation.bind(this); + } + + getHistory() { + return this.history; + } + + getSearch() { + return new URLSearchParams(this.history.location.search); + } + + partial(query: Record, replace?: boolean) { + const currentLocation = this.history.location; + const newQuery = this.getSearchObject(); + + for (const key of Object.keys(query)) { + // removing params with null | undefined + if (query[key] === null || query[key] === undefined) { + delete newQuery[key]; + } else { + newQuery[key] = query[key]; + } + } + + const updatedUrl = urlUtil.renderUrl(currentLocation.pathname, newQuery); + + if (replace) { + this.history.replace(updatedUrl, this.history.location.state); + } else { + this.history.push(updatedUrl, this.history.location.state); + } + } + + push(location: H.Path | H.LocationDescriptor) { + this.history.push(location); + } + + replace(location: H.Path | H.LocationDescriptor) { + this.history.replace(location); + } + + reload() { + const prevState = (this.history.location.state as any)?.routeReloadCounter; + this.history.replace({ + ...this.history.location, + state: { routeReloadCounter: prevState ? prevState + 1 : 1 }, + }); + } + + getLocation() { + return this.history.location; + } + + getSearchObject() { + return locationSearchToObject(this.history.location.search); + } + + /** @deprecated use partial, push or replace instead */ + update(options: LocationUpdate) { + deprecationWarning('LocationSrv', 'update', 'partial, push or replace'); + if (options.partial && options.query) { + this.partial(options.query, options.partial); + } else { + const newLocation: H.LocationDescriptor = { + pathname: options.path, + }; + if (options.query) { + newLocation.search = urlUtil.toUrlParams(options.query); + } + if (options.replace) { + this.replace(newLocation); + } else { + this.push(newLocation); + } + } + } +} + +/** + * @alpha + * Parses a location search string to an object + * */ +export function locationSearchToObject(search: string | number): UrlQueryMap { + let queryString = typeof search === 'number' ? String(search) : search; + + if (queryString.length > 0) { + if (queryString.startsWith('?')) { + return urlUtil.parseKeyValue(queryString.substring(1)); + } + return urlUtil.parseKeyValue(queryString); + } + + return {}; +} + +/** + * @alpha + */ +export let locationService: LocationService = new HistoryWrapper(); + +/** @internal + * Used for tests only + */ +export const setLocationService = (location: LocationService) => { + if (process.env.NODE_ENV !== 'test') { + throw new Error('locationService can be only overriden in test environment'); + } + locationService = location; +}; + +const navigationLog = createLogger('Router'); + +/** @internal */ +export const navigationLogger = navigationLog.logger; + +// For debugging purposes the location service is attached to global _debug variable +attachDebugger('location', locationService, navigationLog); diff --git a/packages/grafana-runtime/src/services/LocationSrv.ts b/packages/grafana-runtime/src/services/LocationSrv.ts new file mode 100644 index 00000000..c1cdd031 --- /dev/null +++ b/packages/grafana-runtime/src/services/LocationSrv.ts @@ -0,0 +1,75 @@ +/** + * Passed as options to the {@link LocationSrv} to describe how the automatically navigation + * should be performed. + * + * @public + */ +import { UrlQueryMap } from '@grafana/data'; + +/** + * @public + */ +export interface LocationUpdate { + /** + * Target path where you automatically wants to navigate the user. + */ + path?: string; + + /** + * Specify this value if you want to add values to the query string of the URL. + */ + query?: UrlQueryMap; + + /** + * If set to true, the query argument will be added to the existing URL. + */ + partial?: boolean; + + /** + * Used internally to sync the Redux state from Angular to make sure that the Redux location + * state is in sync when navigating using the Angular router. + * + * @remarks + * Do not change this unless you are the Angular router. + * + * @internal + */ + routeParams?: UrlQueryMap; + + /* + * If set to true, this will replace URL state (ie. cause no new browser history). + */ + replace?: boolean; +} + +/** + * If you need to automatically navigate the user to a new place in the application this should + * be done via the LocationSrv and it will make sure to update the application state accordingly. + * + * @public + */ +export interface LocationSrv { + update(options: LocationUpdate): void; +} + +let singletonInstance: LocationSrv; + +/** + * Used during startup by Grafana to set the LocationSrv so it is available + * via the {@link getLocationSrv} to the rest of the application. + * + * @internal + */ +export function setLocationSrv(instance: LocationSrv) { + singletonInstance = instance; +} + +/** + * Used to retrieve the {@link LocationSrv} that can be used to automatically navigate + * the user to a new place in Grafana. + * + * @public + */ +export function getLocationSrv(): LocationSrv { + return singletonInstance; +} diff --git a/packages/grafana-runtime/src/services/QueryRunner.ts b/packages/grafana-runtime/src/services/QueryRunner.ts new file mode 100644 index 00000000..8ce5b100 --- /dev/null +++ b/packages/grafana-runtime/src/services/QueryRunner.ts @@ -0,0 +1,33 @@ +import { QueryRunner } from '@grafana/data'; + +let factory: QueryRunnerFactory | undefined; + +/** + * @internal + */ +export type QueryRunnerFactory = () => QueryRunner; + +/** + * Used to bootstrap the {@link createQueryRunner} during application start. + * + * @internal + */ +export const setQueryRunnerFactory = (instance: QueryRunnerFactory): void => { + if (factory) { + throw new Error('Runner should only be set when Grafana is starting.'); + } + factory = instance; +}; + +/** + * Used to create QueryRunner instances from outside the core Grafana application. + * This is helpful to be able to create a QueryRunner to execute queries in e.g. an app plugin. + * + * @internal + */ +export const createQueryRunner = (): QueryRunner => { + if (!factory) { + throw new Error('`createQueryRunner` can only be used after Grafana instance has started.'); + } + return factory(); +}; diff --git a/packages/grafana-runtime/src/services/__mocks__/dataSourceSrv.ts b/packages/grafana-runtime/src/services/__mocks__/dataSourceSrv.ts new file mode 100644 index 00000000..ee35c224 --- /dev/null +++ b/packages/grafana-runtime/src/services/__mocks__/dataSourceSrv.ts @@ -0,0 +1,22 @@ +const ds1 = { + id: 1, + uid: 'c8eceabb-0275-4108-8f03-8f74faf4bf6d', + type: 'prometheus', + name: 'gdev-prometheus', + meta: { + info: { + logos: { + small: 'http://example.com/logo.png', + }, + }, + }, + jsonData: {}, + access: 'proxy', +}; + +export function getDataSourceSrv() { + return { + getList: () => [ds1], + getInstanceSettings: () => ds1, + }; +} diff --git a/packages/grafana-runtime/src/services/appEvents.ts b/packages/grafana-runtime/src/services/appEvents.ts new file mode 100644 index 00000000..c430a554 --- /dev/null +++ b/packages/grafana-runtime/src/services/appEvents.ts @@ -0,0 +1,59 @@ +import { BusEventBase, BusEventWithPayload, EventBus, GrafanaTheme2, PanelModel, TimeRange } from '@grafana/data'; + +/** + * Called when a dashboard is refreshed + * + * @public + */ +export class RefreshEvent extends BusEventBase { + static type = 'refresh'; +} + +/** + * Called when the theme settings change + * + * @public + */ +export class ThemeChangedEvent extends BusEventWithPayload { + static type = 'theme-changed'; +} + +/** + * Called when time range is updated + * + * @public + */ +export class TimeRangeUpdatedEvent extends BusEventWithPayload { + static type = 'time-range-updated'; +} + +/** + * Called to copy a panel JSON into local storage + * + * @public + */ +export class CopyPanelEvent extends BusEventWithPayload { + static type = 'copy-panel'; +} + +// Internal singleton instance +let singletonInstance: EventBus; + +/** + * Used during startup by Grafana to set the LocationSrv so it is available + * via the {@link getLocationSrv} to the rest of the application. + * + * @internal + */ +export function setAppEvents(instance: EventBus) { + singletonInstance = instance; +} + +/** + * Used to retrieve an event bus that manages application level events + * + * @public + */ +export function getAppEvents(): EventBus { + return singletonInstance; +} diff --git a/packages/grafana-runtime/src/services/backendSrv.ts b/packages/grafana-runtime/src/services/backendSrv.ts new file mode 100644 index 00000000..4260ef41 --- /dev/null +++ b/packages/grafana-runtime/src/services/backendSrv.ts @@ -0,0 +1,188 @@ +import { Observable } from 'rxjs'; + +/** + * Used to initiate a remote call via the {@link BackendSrv} + * + * @public + */ +export type BackendSrvRequest = { + /** + * Request URL + */ + url: string; + + /** + * Number of times to retry the remote call if it fails. + */ + retry?: number; + + /** + * HTTP headers that should be passed along with the remote call. + * Please have a look at {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API} + * for supported headers. + */ + headers?: Record; + + /** + * HTTP verb to perform in the remote call GET, POST, PUT etc. + */ + method?: string; + + /** + * Set to false an success application alert box will not be shown for successful PUT, DELETE, POST requests + */ + showSuccessAlert?: boolean; + + /** + * Set to false to not show an application alert box for request errors + */ + showErrorAlert?: boolean; + + /** + * Provided by the initiator to identify a particular remote call. An example + * of this is when a datasource plugin triggers a query. If the request id already + * exist the backendSrv will try to cancel and replace the previous call with the + * new one. + */ + requestId?: string; + + /** + * Set to to true to not include call in query inspector + */ + hideFromInspector?: boolean; + + /** + * The data to send + */ + data?: any; + + /** + * Query params + */ + params?: Record; + + /** + * Define how the response object should be parsed. See: + * + * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data + * + * By default values are json parsed from text + */ + responseType?: 'json' | 'text' | 'arraybuffer' | 'blob'; + + /** + * The credentials read-only property of the Request interface indicates whether the user agent should send cookies from the other domain in the case of cross-origin requests. + */ + credentials?: RequestCredentials; + + /** + * @deprecated withCredentials is deprecated in favor of credentials + */ + withCredentials?: boolean; +}; + +/** + * Response for fetch function in {@link BackendSrv} + * + * @public + */ +export interface FetchResponse { + data: T; + readonly status: number; + readonly statusText: string; + readonly ok: boolean; + readonly headers: Headers; + readonly redirected: boolean; + readonly type: ResponseType; + readonly url: string; + readonly config: BackendSrvRequest; +} + +/** + * Error type for fetch function in {@link BackendSrv} + * + * @public + */ +export interface FetchErrorDataProps { + message?: string; + status?: string; + error?: string | any; +} + +/** + * Error type for fetch function in {@link BackendSrv} + * + * @public + */ +export interface FetchError { + status: number; + statusText?: string; + data: T; + cancelled?: boolean; + isHandled?: boolean; + config: BackendSrvRequest; +} + +/** + * Used to communicate via http(s) to a remote backend such as the Grafana backend, + * a datasource etc. The BackendSrv is using the {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API} + * under the hood to handle all the communication. + * + * The request function can be used to perform a remote call by specifying a {@link BackendSrvRequest}. + * To make the BackendSrv a bit easier to use we have added a couple of shorthand functions that will + * use default values executing the request. + * + * @remarks + * By default, Grafana displays an error message alert if the remote call fails. To prevent this from + * happening `showErrorAlert = true` on the options object. + * + * @public + */ +export interface BackendSrv { + get(url: string, params?: any, requestId?: string): Promise; + delete(url: string, data?: any): Promise; + post(url: string, data?: any): Promise; + patch(url: string, data?: any): Promise; + put(url: string, data?: any): Promise; + + /** + * @deprecated Use the fetch function instead. If you prefer to work with a promise + * wrap the Observable returned by fetch with the lastValueFrom function. + */ + request(options: BackendSrvRequest): Promise; + + /** + * Special function used to communicate with datasources that will emit core + * events that the Grafana QueryInspector and QueryEditor is listening for to be able + * to display datasource query information. Can be skipped by adding `option.silent` + * when initializing the request. + * + * @deprecated Use the fetch function instead + */ + datasourceRequest(options: BackendSrvRequest): Promise>; + + /** + * Observable http request interface + */ + fetch(options: BackendSrvRequest): Observable>; +} + +let singletonInstance: BackendSrv; + +/** + * Used during startup by Grafana to set the BackendSrv so it is available + * via the {@link getBackendSrv} to the rest of the application. + * + * @internal + */ +export const setBackendSrv = (instance: BackendSrv) => { + singletonInstance = instance; +}; + +/** + * Used to retrieve the {@link BackendSrv} that can be used to communicate + * via http(s) to a remote backend such as the Grafana backend, a datasource etc. + * + * @public + */ +export const getBackendSrv = (): BackendSrv => singletonInstance; diff --git a/packages/grafana-runtime/src/services/dataSourceSrv.ts b/packages/grafana-runtime/src/services/dataSourceSrv.ts new file mode 100644 index 00000000..31baf9a9 --- /dev/null +++ b/packages/grafana-runtime/src/services/dataSourceSrv.ts @@ -0,0 +1,92 @@ +import { ScopedVars, DataSourceApi, DataSourceInstanceSettings, DataSourceRef } from '@grafana/data'; + +/** + * This is the entry point for communicating with a datasource that is added as + * a plugin (both external and internal). Via this service you will get access + * to the {@link @grafana/data#DataSourceApi | DataSourceApi} that have a rich API for + * communicating with the datasource. + * + * @public + */ +export interface DataSourceSrv { + /** + * Returns the requested dataSource. If it cannot be found it rejects the promise. + * @param ref - The datasource identifier, typically an object with UID and type, + * @param scopedVars - variables used to interpolate a templated passed as name. + */ + get(ref?: DataSourceRef | string | null, scopedVars?: ScopedVars): Promise; + + /** + * Get a list of data sources + */ + getList(filters?: GetDataSourceListFilters): DataSourceInstanceSettings[]; + + /** + * Get settings and plugin metadata by name or uid + */ + getInstanceSettings( + ref?: DataSourceRef | string | null, + scopedVars?: ScopedVars + ): DataSourceInstanceSettings | undefined; +} + +/** @public */ +export interface GetDataSourceListFilters { + /** Include mixed data source by setting this to true */ + mixed?: boolean; + + /** Only return data sources that support metrics response */ + metrics?: boolean; + + /** Only return data sources that support tracing response */ + tracing?: boolean; + + /** Only return data sources that support annotations */ + annotations?: boolean; + + /** Only filter data sources that support alerting */ + alerting?: boolean; + + /** + * By default only data sources that can be queried will be returned. Meaning they have tracing, + * metrics, logs or annotations flag set in plugin.json file + * */ + all?: boolean; + + /** Set to true to return dashboard data source */ + dashboard?: boolean; + + /** Set to true to return data source variables */ + variables?: boolean; + + /** filter list by plugin */ + pluginId?: string; + + /** apply a function to filter */ + filter?: (dataSource: DataSourceInstanceSettings) => boolean; + + /** Only returns datasources matching the specified types (ie. Loki, Prometheus) */ + type?: string | string[]; +} + +let singletonInstance: DataSourceSrv; + +/** + * Used during startup by Grafana to set the DataSourceSrv so it is available + * via the {@link getDataSourceSrv} to the rest of the application. + * + * @internal + */ +export function setDataSourceSrv(instance: DataSourceSrv) { + singletonInstance = instance; +} + +/** + * Used to retrieve the {@link DataSourceSrv} that is the entry point for communicating with + * a datasource that is added as a plugin (both external and internal). + * + * @public + */ +export function getDataSourceSrv(): DataSourceSrv { + return singletonInstance; +} diff --git a/packages/grafana-runtime/src/services/index.ts b/packages/grafana-runtime/src/services/index.ts new file mode 100644 index 00000000..04b7de73 --- /dev/null +++ b/packages/grafana-runtime/src/services/index.ts @@ -0,0 +1,10 @@ +export * from './backendSrv'; +export * from './AngularLoader'; +export * from './dataSourceSrv'; +export * from './LocationSrv'; +export * from './EchoSrv'; +export * from './templateSrv'; +export * from './legacyAngularInjector'; +export * from './live'; +export * from './LocationService'; +export * from './appEvents'; diff --git a/packages/grafana-runtime/src/services/legacyAngularInjector.ts b/packages/grafana-runtime/src/services/legacyAngularInjector.ts new file mode 100644 index 00000000..4c581ffd --- /dev/null +++ b/packages/grafana-runtime/src/services/legacyAngularInjector.ts @@ -0,0 +1,23 @@ +import { auto } from 'angular'; + +let singleton: auto.IInjectorService; + +/** + * Used during startup by Grafana to temporarily expose the angular injector to + * pure javascript plugins using {@link getLegacyAngularInjector}. + * + * @internal + */ +export const setLegacyAngularInjector = (instance: auto.IInjectorService) => { + singleton = instance; +}; + +/** + * WARNING: this function provides a temporary way for plugins to access anything in the + * angular injector. While the migration from angular to react continues, there are a few + * options that do not yet have good alternatives. Note that use of this function will + * be removed in the future. + * + * @beta + */ +export const getLegacyAngularInjector = (): auto.IInjectorService => singleton; diff --git a/packages/grafana-runtime/src/services/live.ts b/packages/grafana-runtime/src/services/live.ts new file mode 100644 index 00000000..a29973a0 --- /dev/null +++ b/packages/grafana-runtime/src/services/live.ts @@ -0,0 +1,120 @@ +import { + DataFrameJSON, + DataQueryRequest, + DataQueryResponse, + LiveChannelAddress, + LiveChannelEvent, + LiveChannelPresenceStatus, +} from '@grafana/data'; +import { Observable } from 'rxjs'; + +/** + * @alpha -- experimental + */ +export interface LiveDataFilter { + fields?: string[]; +} + +/** + * Indicate if the frame is appened or replace + * + * @alpha + */ +export enum StreamingFrameAction { + Append = 'append', + Replace = 'replace', +} + +/** + * @alpha + */ +export interface StreamingFrameOptions { + maxLength: number; // 1000 + maxDelta: number; // how long to keep things + action: StreamingFrameAction; // default will append + + /** optionally format field names based on labels */ + displayNameFormat?: string; +} + +/** + * @alpha + */ +export interface LiveDataStreamOptions { + addr: LiveChannelAddress; + frame?: DataFrameJSON; // initial results + key?: string; + buffer?: Partial; + filter?: LiveDataFilter; +} + +/** + * @alpha -- experimental: send a normal query request over websockt + */ +export interface LiveQueryDataOptions { + request: DataQueryRequest; + body: any; // processed queries, same as sent to `/api/query/ds` +} + +/** + * @alpha -- experimental + */ +export interface GrafanaLiveSrv { + /** + * Listen for changes to the main service + */ + getConnectionState(): Observable; + + /** + * Watch for messages in a channel + */ + getStream(address: LiveChannelAddress): Observable>; + + /** + * Connect to a channel and return results as DataFrames + */ + getDataStream(options: LiveDataStreamOptions): Observable; + + /** + * Execute a query over the live websocket and potentiall subscribe to a live channel. + * + * Since the initial request and subscription are on the same socket, this will support HA setups + * + * @alpha -- this function requires the feature toggle `queryOverLive` to be set + */ + getQueryData(options: LiveQueryDataOptions): Observable; + + /** + * For channels that support presence, this will request the current state from the server. + * + * Join and leave messages will be sent to the open stream + */ + getPresence(address: LiveChannelAddress): Promise; + + /** + * Publish into a channel + * + * @alpha -- experimental + */ + publish(address: LiveChannelAddress, data: any): Promise; +} + +let singletonInstance: GrafanaLiveSrv; + +/** + * Used during startup by Grafana to set the GrafanaLiveSrv so it is available + * via the {@link getGrafanaLiveSrv} to the rest of the application. + * + * @internal + */ +export const setGrafanaLiveSrv = (instance: GrafanaLiveSrv) => { + singletonInstance = instance; +}; + +/** + * Used to retrieve the GrafanaLiveSrv that allows you to subscribe to + * server side events and streams + * + * @alpha -- experimental + */ +export const getGrafanaLiveSrv = (): GrafanaLiveSrv => singletonInstance; diff --git a/packages/grafana-runtime/src/services/templateSrv.ts b/packages/grafana-runtime/src/services/templateSrv.ts new file mode 100644 index 00000000..962dacd7 --- /dev/null +++ b/packages/grafana-runtime/src/services/templateSrv.ts @@ -0,0 +1,40 @@ +import { VariableModel, ScopedVars } from '@grafana/data'; + +/** + * Via the TemplateSrv consumers get access to all the available template variables + * that can be used within the current active dashboard. + * + * For a more in-depth description visit: https://grafana.com/docs/grafana/latest/reference/templating + * @public + */ +export interface TemplateSrv { + /** + * List the dashboard variables + */ + getVariables(): VariableModel[]; + + /** + * Replace the values within the target string. See also {@link InterpolateFunction} + */ + replace(target?: string, scopedVars?: ScopedVars, format?: string | Function): string; +} + +let singletonInstance: TemplateSrv; + +/** + * Used during startup by Grafana to set the TemplateSrv so it is available + * via the {@link getTemplateSrv} to the rest of the application. + * + * @internal + */ +export const setTemplateSrv = (instance: TemplateSrv) => { + singletonInstance = instance; +}; + +/** + * Used to retrieve the {@link TemplateSrv} that can be used to fetch available + * template variables. + * + * @public + */ +export const getTemplateSrv = (): TemplateSrv => singletonInstance; diff --git a/packages/grafana-runtime/src/types/analytics.ts b/packages/grafana-runtime/src/types/analytics.ts new file mode 100644 index 00000000..99e158e2 --- /dev/null +++ b/packages/grafana-runtime/src/types/analytics.ts @@ -0,0 +1,123 @@ +import { EchoEvent, EchoEventType } from '../services/EchoSrv'; + +/** + * Describes the basic dashboard information that can be passed as the meta + * analytics payload. + * + * @public + */ +export interface DashboardInfo { + dashboardId: number; + dashboardUid: string; + dashboardName: string; + folderName?: string; +} + +/** + * Describes the data request information passed as the meta analytics payload. + * + * @public + */ +export interface DataRequestInfo extends Partial { + datasourceName: string; + datasourceId: number; + datasourceType: string; + panelId?: number; + panelName?: string; + duration: number; + error?: string; + dataSize?: number; +} + +/** + * The meta analytics events that can be added to the echo service. + * + * @public + */ +export enum MetaAnalyticsEventName { + DashboardView = 'dashboard-view', + DataRequest = 'data-request', +} + +/** + * Describes the payload of a dashboard view event. + * + * @public + */ +export interface DashboardViewEventPayload extends DashboardInfo { + eventName: MetaAnalyticsEventName.DashboardView; +} + +/** + * Describes the payload of a data request event. + * + * @public + */ +export interface DataRequestEventPayload extends DataRequestInfo { + eventName: MetaAnalyticsEventName.DataRequest; +} + +/** + * Describes the meta analytics payload passed with the {@link MetaAnalyticsEvent} + * + * @public + */ +export type MetaAnalyticsEventPayload = DashboardViewEventPayload | DataRequestEventPayload; + +/** + * Describes meta analytics event with predefined {@link EchoEventType.EchoEventType} type. + * + * @public + */ +export interface MetaAnalyticsEvent extends EchoEvent {} + +/** + * Describes the payload of a pageview event. + * + * @public + */ +export interface PageviewEchoEventPayload { + page: string; +} + +/** + * Describes pageview event with predefined {@link EchoEventType.EchoEventType} type. + * + * @public + */ +export type PageviewEchoEvent = EchoEvent; + +/** + * Describes the payload of a user interaction event. + * + * @public + */ +export interface InteractionEchoEventPayload { + interactionName: string; + properties?: Record; +} + +/** + * Describes interaction event with predefined {@link EchoEventType.EchoEventType} type. + * + * @public + */ +export type InteractionEchoEvent = EchoEvent; + +/** + * Pageview event typeguard. + * + * @public + */ +export const isPageviewEvent = (event: EchoEvent): event is PageviewEchoEvent => { + return Boolean(event.payload.page); +}; + +/** + * Interaction event typeguard. + * + * @public + */ +export const isInteractionEvent = (event: EchoEvent): event is InteractionEchoEvent => { + return Boolean(event.payload.interactionName); +}; diff --git a/packages/grafana-runtime/src/types/index.ts b/packages/grafana-runtime/src/types/index.ts new file mode 100644 index 00000000..77dc4f52 --- /dev/null +++ b/packages/grafana-runtime/src/types/index.ts @@ -0,0 +1 @@ +export * from './analytics'; diff --git a/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts b/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts new file mode 100644 index 00000000..92c24fea --- /dev/null +++ b/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts @@ -0,0 +1,116 @@ +import { BackendSrv, BackendSrvRequest } from 'src/services'; +import { DataSourceWithBackend, standardStreamOptionsProvider, toStreamingDataResponse } from './DataSourceWithBackend'; +import { + DataSourceJsonData, + DataQuery, + DataSourceInstanceSettings, + DataQueryRequest, + DataQueryResponseData, + MutableDataFrame, + DataSourceRef, +} from '@grafana/data'; +import { of } from 'rxjs'; + +class MyDataSource extends DataSourceWithBackend { + constructor(instanceSettings: DataSourceInstanceSettings) { + super(instanceSettings); + } +} + +const mockDatasourceRequest = jest.fn(); + +const backendSrv = ({ + fetch: (options: BackendSrvRequest) => { + return of(mockDatasourceRequest(options)); + }, +} as unknown) as BackendSrv; + +jest.mock('../services', () => ({ + ...(jest.requireActual('../services') as any), + getBackendSrv: () => backendSrv, + getDataSourceSrv: () => { + return { + getInstanceSettings: (ref?: DataSourceRef) => ({ type: ref?.type ?? '?', uid: ref?.uid ?? '?' }), + }; + }, +})); + +describe('DataSourceWithBackend', () => { + test('check the executed queries', () => { + const settings = { + name: 'test', + id: 1234, + uid: 'abc', + type: 'dummy', + jsonData: {}, + } as DataSourceInstanceSettings; + + mockDatasourceRequest.mockReset(); + mockDatasourceRequest.mockReturnValue(Promise.resolve({})); + const ds = new MyDataSource(settings); + + ds.query({ + maxDataPoints: 10, + intervalMs: 5000, + targets: [{ refId: 'A' }, { refId: 'B', datasource: { type: 'sample' } }], + } as DataQueryRequest); + + const mock = mockDatasourceRequest.mock; + expect(mock.calls.length).toBe(1); + + const args = mock.calls[0][0]; + expect(args).toMatchInlineSnapshot(` + Object { + "data": Object { + "queries": Array [ + Object { + "datasource": Object { + "type": "dummy", + "uid": "abc", + }, + "datasourceId": 1234, + "intervalMs": 5000, + "maxDataPoints": 10, + "refId": "A", + }, + Object { + "datasource": Object { + "type": "sample", + "uid": "?", + }, + "datasourceId": undefined, + "intervalMs": 5000, + "maxDataPoints": 10, + "refId": "B", + }, + ], + }, + "method": "POST", + "requestId": undefined, + "url": "/api/ds/query", + } + `); + }); + + test('it converts results with channels to streaming queries', () => { + const request: DataQueryRequest = { + intervalMs: 100, + } as DataQueryRequest; + + const rsp: DataQueryResponseData = { + data: [], + }; + + // Simple empty query + let obs = toStreamingDataResponse(rsp, request, standardStreamOptionsProvider); + expect(obs).toBeDefined(); + + let frame = new MutableDataFrame(); + frame.meta = { + channel: 'a/b/c', + }; + rsp.data = [frame]; + obs = toStreamingDataResponse(rsp, request, standardStreamOptionsProvider); + expect(obs).toBeDefined(); + }); +}); diff --git a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts new file mode 100644 index 00000000..9040bd70 --- /dev/null +++ b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts @@ -0,0 +1,328 @@ +import { + DataSourceApi, + DataQueryRequest, + DataQueryResponse, + DataSourceInstanceSettings, + DataQuery, + DataSourceJsonData, + ScopedVars, + makeClassES5Compatible, + DataFrame, + parseLiveChannelAddress, + getDataSourceRef, + DataSourceRef, + dataFrameToJSON, +} from '@grafana/data'; +import { merge, Observable, of } from 'rxjs'; +import { catchError, switchMap } from 'rxjs/operators'; +import { + getBackendSrv, + getDataSourceSrv, + getGrafanaLiveSrv, + StreamingFrameOptions, + StreamingFrameAction, +} from '../services'; +import { config } from '../config'; +import { BackendDataSourceResponse, toDataQueryResponse } from './queryResponse'; + +/** + * @internal + */ +export const ExpressionDatasourceRef = Object.freeze({ + type: '__expr__', + uid: '__expr__', +}); + +/** + * @internal + */ +export function isExpressionReference(ref?: DataSourceRef | string | null): boolean { + if (!ref) { + return false; + } + const v = (ref as any).type ?? ref; + return v === ExpressionDatasourceRef.type || v === '-100'; // -100 was a legacy accident that should be removed +} + +class HealthCheckError extends Error { + details: HealthCheckResultDetails; + + constructor(message: string, details: HealthCheckResultDetails) { + super(message); + this.details = details; + this.name = 'HealthCheckError'; + } +} + +/** + * Describes the current health status of a data source plugin. + * + * @public + */ +export enum HealthStatus { + Unknown = 'UNKNOWN', + OK = 'OK', + Error = 'ERROR', +} + +/** + * Describes the details in the payload returned when checking the health of a data source + * plugin. + * + * If the 'message' key exists, this will be displayed in the error message in DataSourceSettingsPage + * If the 'verboseMessage' key exists, this will be displayed in the expandable details in the error message in DataSourceSettingsPage + * + * @public + */ +export type HealthCheckResultDetails = Record | undefined; + +/** + * Describes the payload returned when checking the health of a data source + * plugin. + * + * @public + */ +export interface HealthCheckResult { + status: HealthStatus; + message: string; + details: HealthCheckResultDetails; +} + +/** + * Extend this class to implement a data source plugin that is depending on the Grafana + * backend API. + * + * @public + */ +class DataSourceWithBackend< + TQuery extends DataQuery = DataQuery, + TOptions extends DataSourceJsonData = DataSourceJsonData +> extends DataSourceApi { + constructor(instanceSettings: DataSourceInstanceSettings) { + super(instanceSettings); + } + + /** + * Ideally final -- any other implementation may not work as expected + */ + query(request: DataQueryRequest): Observable { + const { intervalMs, maxDataPoints, range, requestId } = request; + let targets = request.targets; + + if (this.filterQuery) { + targets = targets.filter((q) => this.filterQuery!(q)); + } + + const queries = targets.map((q) => { + let datasource = this.getRef(); + let datasourceId = this.id; + + if (isExpressionReference(q.datasource)) { + return { + ...q, + datasource: ExpressionDatasourceRef, + }; + } + + if (q.datasource) { + const ds = getDataSourceSrv().getInstanceSettings(q.datasource, request.scopedVars); + + if (!ds) { + throw new Error(`Unknown Datasource: ${JSON.stringify(q.datasource)}`); + } + + datasource = ds.rawRef ?? getDataSourceRef(ds); + datasourceId = ds.id; + } + + return { + ...this.applyTemplateVariables(q, request.scopedVars), + datasource, + datasourceId, // deprecated! + intervalMs, + maxDataPoints, + }; + }); + + // Return early if no queries exist + if (!queries.length) { + return of({ data: [] }); + } + + const body: any = { queries }; + + if (range) { + body.range = range; + body.from = range.from.valueOf().toString(); + body.to = range.to.valueOf().toString(); + } + + if (config.featureToggles.queryOverLive) { + return getGrafanaLiveSrv().getQueryData({ + request, + body, + }); + } + + return getBackendSrv() + .fetch({ + url: '/api/ds/query', + method: 'POST', + data: body, + requestId, + }) + .pipe( + switchMap((raw) => { + const rsp = toDataQueryResponse(raw, queries as DataQuery[]); + // Check if any response should subscribe to a live stream + if (rsp.data?.length && rsp.data.find((f: DataFrame) => f.meta?.channel)) { + return toStreamingDataResponse(rsp, request, this.streamOptionsProvider); + } + return of(rsp); + }), + catchError((err) => { + return of(toDataQueryResponse(err)); + }) + ); + } + + /** + * Apply template variables for explore + */ + interpolateVariablesInQueries(queries: TQuery[], scopedVars: ScopedVars | {}): TQuery[] { + return queries.map((q) => this.applyTemplateVariables(q, scopedVars) as TQuery); + } + + /** + * Override to apply template variables. The result is usually also `TQuery`, but sometimes this can + * be used to modify the query structure before sending to the backend. + * + * NOTE: if you do modify the structure or use template variables, alerting queries may not work + * as expected + * + * @virtual + */ + applyTemplateVariables(query: TQuery, scopedVars: ScopedVars): Record { + return query; + } + + /** + * Optionally override the streaming behavior + */ + streamOptionsProvider: StreamOptionsProvider = standardStreamOptionsProvider; + + /** + * Make a GET request to the datasource resource path + */ + async getResource(path: string, params?: any): Promise { + return getBackendSrv().get(`/api/datasources/${this.id}/resources/${path}`, params); + } + + /** + * Send a POST request to the datasource resource path + */ + async postResource(path: string, body?: any): Promise { + return getBackendSrv().post(`/api/datasources/${this.id}/resources/${path}`, { ...body }); + } + + /** + * Run the datasource healthcheck + */ + async callHealthCheck(): Promise { + return getBackendSrv() + .request({ method: 'GET', url: `/api/datasources/${this.id}/health`, showErrorAlert: false }) + .then((v) => { + return v as HealthCheckResult; + }) + .catch((err) => { + return err.data as HealthCheckResult; + }); + } + + /** + * Checks the plugin health + * see public/app/features/datasources/state/actions.ts for what needs to be returned here + */ + async testDatasource(): Promise { + return this.callHealthCheck().then((res) => { + if (res.status === HealthStatus.OK) { + return { + status: 'success', + message: res.message, + }; + } + + throw new HealthCheckError(res.message, res.details); + }); + } +} + +/** + * @internal exported for tests + */ +export function toStreamingDataResponse( + rsp: DataQueryResponse, + req: DataQueryRequest, + getter: (req: DataQueryRequest, frame: DataFrame) => Partial +): Observable { + const live = getGrafanaLiveSrv(); + if (!live) { + return of(rsp); // add warning? + } + + const staticdata: DataFrame[] = []; + const streams: Array> = []; + for (const f of rsp.data) { + const addr = parseLiveChannelAddress(f.meta?.channel); + if (addr) { + const frame = f as DataFrame; + streams.push( + live.getDataStream({ + addr, + buffer: getter(req, frame), + frame: dataFrameToJSON(f), + }) + ); + } else { + staticdata.push(f); + } + } + if (staticdata.length) { + streams.push(of({ ...rsp, data: staticdata })); + } + if (streams.length === 1) { + return streams[0]; // avoid merge wrapper + } + return merge(...streams); +} + +/** + * This allows data sources to customize the streaming connection query + * + * @public + */ +export type StreamOptionsProvider = ( + request: DataQueryRequest, + frame: DataFrame +) => Partial; + +/** + * @public + */ +export const standardStreamOptionsProvider: StreamOptionsProvider = (request: DataQueryRequest, frame: DataFrame) => { + const opts: Partial = { + maxLength: request.maxDataPoints ?? 500, + action: StreamingFrameAction.Append, + }; + + // For recent queries, clamp to the current time range + if (request.rangeRaw?.to === 'now') { + opts.maxDelta = request.range.to.valueOf() - request.range.from.valueOf(); + } + return opts; +}; + +//@ts-ignore +DataSourceWithBackend = makeClassES5Compatible(DataSourceWithBackend); + +export { DataSourceWithBackend }; diff --git a/packages/grafana-runtime/src/utils/analytics.ts b/packages/grafana-runtime/src/utils/analytics.ts new file mode 100644 index 00000000..e864cd5c --- /dev/null +++ b/packages/grafana-runtime/src/utils/analytics.ts @@ -0,0 +1,52 @@ +import { getEchoSrv, EchoEventType } from '../services/EchoSrv'; +import { + InteractionEchoEvent, + MetaAnalyticsEvent, + MetaAnalyticsEventPayload, + PageviewEchoEvent, +} from '../types/analytics'; +import { locationService } from '../services'; +import { config } from '../config'; + +/** + * Helper function to report meta analytics to the {@link EchoSrv}. + * + * @public + */ +export const reportMetaAnalytics = (payload: MetaAnalyticsEventPayload) => { + getEchoSrv().addEvent({ + type: EchoEventType.MetaAnalytics, + payload, + }); +}; + +/** + * Helper function to report pageview events to the {@link EchoSrv}. + * + * @public + */ +export const reportPageview = () => { + const location = locationService.getLocation(); + const page = `${config.appSubUrl ?? ''}${location.pathname}${location.search}${location.hash}`; + getEchoSrv().addEvent({ + type: EchoEventType.Pageview, + payload: { + page, + }, + }); +}; + +/** + * Helper function to report interaction events to the {@link EchoSrv}. + * + * @public + */ +export const reportInteraction = (interactionName: string, properties?: Record) => { + getEchoSrv().addEvent({ + type: EchoEventType.Interaction, + payload: { + interactionName, + properties, + }, + }); +}; diff --git a/packages/grafana-runtime/src/utils/logging.ts b/packages/grafana-runtime/src/utils/logging.ts new file mode 100644 index 00000000..0f8051a5 --- /dev/null +++ b/packages/grafana-runtime/src/utils/logging.ts @@ -0,0 +1,50 @@ +import { captureMessage, captureException, Severity as LogLevel } from '@sentry/browser'; +export { LogLevel }; + +// a bit stricter than what Sentry allows +type Contexts = Record>>; + +/** + * Log a message at INFO level. Depending on configuration might be forwarded to backend and logged to stdout or sent to Sentry + * + * @public + */ +export function logInfo(message: string, contexts?: Contexts) { + captureMessage(message, { + level: LogLevel.Info, + contexts, + }); +} + +/** + * Log a message at WARNING level. Depending on configuration might be forwarded to backend and logged to stdout or sent to Sentry + * + * @public + */ +export function logWarning(message: string, contexts?: Contexts) { + captureMessage(message, { + level: LogLevel.Warning, + contexts, + }); +} + +/** + * Log a message at DEBUG level. Depending on configuration might be forwarded to backend and logged to stdout or sent to Sentry + * + * @public + */ +export function logDebug(message: string, contexts?: Contexts) { + captureMessage(message, { + level: LogLevel.Debug, + contexts, + }); +} + +/** + * Log an error. Depending on configuration might be forwarded to backend and logged to stdout or sent to Sentry + * + * @public + */ +export function logError(err: Error, contexts?: Contexts) { + captureException(err, { contexts }); +} diff --git a/packages/grafana-runtime/src/utils/plugin.ts b/packages/grafana-runtime/src/utils/plugin.ts new file mode 100644 index 00000000..5791dd00 --- /dev/null +++ b/packages/grafana-runtime/src/utils/plugin.ts @@ -0,0 +1,32 @@ +import { config } from '../config'; + +// @ts-ignore +import System from 'systemjs/dist/system.js'; + +/** + * Option to specify a plugin css that should be applied for the dark + * and the light theme. + * + * @public + */ +export interface PluginCssOptions { + light: string; + dark: string; +} + +/** + * @internal + */ +export const SystemJS = System; + +/** + * Use this to load css for a Grafana plugin by specifying a {@link PluginCssOptions} + * containing styling for the dark and the light theme. + * + * @param options - plugin styling for light and dark theme. + * @public + */ +export function loadPluginCss(options: PluginCssOptions): Promise { + const theme = config.bootData.user.lightTheme ? options.light : options.dark; + return SystemJS.import(`${theme}!css`); +} diff --git a/packages/grafana-runtime/src/utils/queryResponse.test.ts b/packages/grafana-runtime/src/utils/queryResponse.test.ts new file mode 100644 index 00000000..eb8bb907 --- /dev/null +++ b/packages/grafana-runtime/src/utils/queryResponse.test.ts @@ -0,0 +1,376 @@ +import { DataQuery, toDataFrameDTO, DataFrame } from '@grafana/data'; +import { FetchError, FetchResponse } from 'src/services'; +import { BackendDataSourceResponse, toDataQueryResponse, toTestingStatus } from './queryResponse'; + +const resp = ({ + data: { + results: { + A: { + frames: [ + { + schema: { + refId: 'A', + fields: [ + { name: 'time', type: 'time', typeInfo: { frame: 'time.Time', nullable: true } }, + { name: 'A-series', type: 'number', typeInfo: { frame: 'float64', nullable: true } }, + ], + }, + data: { + values: [ + [1611767228473, 1611767240473, 1611767252473, 1611767264473, 1611767276473, 1611767288473], + [1, 20, 90, 30, 5, 0], + ], + }, + }, + ], + }, + B: { + frames: [ + { + schema: { + refId: 'B', + fields: [ + { name: 'time', type: 'time', typeInfo: { frame: 'time.Time', nullable: true } }, + { name: 'B-series', type: 'number', typeInfo: { frame: 'float64', nullable: true } }, + ], + }, + data: { + values: [ + [1611767228473, 1611767240473, 1611767252473, 1611767264473, 1611767276473, 1611767288473], + [1, 20, 90, 30, 5, 0], + ], + }, + }, + ], + }, + }, + }, +} as any) as FetchResponse; + +const resWithError = ({ + data: { + results: { + A: { + error: 'Hello Error', + frames: [ + { + schema: { + fields: [{ name: 'numbers', type: 'number' }], + meta: { + notices: [ + { + severity: 2, + text: 'Text', + }, + ], + }, + }, + data: { + values: [[1, 3]], + }, + }, + ], + }, + }, + }, +} as any) as FetchResponse; + +const emptyResults = { + data: { results: { '': { refId: '' } } }, +}; + +describe('Query Response parser', () => { + test('should parse output with dataframe', () => { + const res = toDataQueryResponse(resp); + const frames = res.data; + expect(frames).toHaveLength(2); + expect(frames[0].refId).toEqual('A'); + expect(frames[1].refId).toEqual('B'); + + const norm = frames.map((f) => toDataFrameDTO(f)); + expect(norm).toMatchInlineSnapshot(` + Array [ + Object { + "fields": Array [ + Object { + "config": Object {}, + "labels": undefined, + "name": "time", + "type": "time", + "values": Array [ + 1611767228473, + 1611767240473, + 1611767252473, + 1611767264473, + 1611767276473, + 1611767288473, + ], + }, + Object { + "config": Object {}, + "labels": undefined, + "name": "A-series", + "type": "number", + "values": Array [ + 1, + 20, + 90, + 30, + 5, + 0, + ], + }, + ], + "meta": undefined, + "name": undefined, + "refId": "A", + }, + Object { + "fields": Array [ + Object { + "config": Object {}, + "labels": undefined, + "name": "time", + "type": "time", + "values": Array [ + 1611767228473, + 1611767240473, + 1611767252473, + 1611767264473, + 1611767276473, + 1611767288473, + ], + }, + Object { + "config": Object {}, + "labels": undefined, + "name": "B-series", + "type": "number", + "values": Array [ + 1, + 20, + 90, + 30, + 5, + 0, + ], + }, + ], + "meta": undefined, + "name": undefined, + "refId": "B", + }, + ] + `); + }); + + test('should parse output with dataframe in order of queries', () => { + const queries: DataQuery[] = [{ refId: 'B' }, { refId: 'A' }]; + const res = toDataQueryResponse(resp, queries); + const frames = res.data; + expect(frames).toHaveLength(2); + expect(frames[0].refId).toEqual('B'); + expect(frames[1].refId).toEqual('A'); + + const norm = frames.map((f) => toDataFrameDTO(f)); + expect(norm).toMatchInlineSnapshot(` + Array [ + Object { + "fields": Array [ + Object { + "config": Object {}, + "labels": undefined, + "name": "time", + "type": "time", + "values": Array [ + 1611767228473, + 1611767240473, + 1611767252473, + 1611767264473, + 1611767276473, + 1611767288473, + ], + }, + Object { + "config": Object {}, + "labels": undefined, + "name": "B-series", + "type": "number", + "values": Array [ + 1, + 20, + 90, + 30, + 5, + 0, + ], + }, + ], + "meta": undefined, + "name": undefined, + "refId": "B", + }, + Object { + "fields": Array [ + Object { + "config": Object {}, + "labels": undefined, + "name": "time", + "type": "time", + "values": Array [ + 1611767228473, + 1611767240473, + 1611767252473, + 1611767264473, + 1611767276473, + 1611767288473, + ], + }, + Object { + "config": Object {}, + "labels": undefined, + "name": "A-series", + "type": "number", + "values": Array [ + 1, + 20, + 90, + 30, + 5, + 0, + ], + }, + ], + "meta": undefined, + "name": undefined, + "refId": "A", + }, + ] + `); + }); + + test('processEmptyResults', () => { + const frames = toDataQueryResponse(emptyResults).data; + expect(frames.length).toEqual(0); + }); + + test('keeps query order', () => { + const resp = { + data: { + results: { + X: { + series: [{ name: 'Requests/s', points: [[13.594958983547151, 1611839862951]] }] as any, + }, + B: { + series: [{ name: 'Requests/s', points: [[13.594958983547151, 1611839862951]] }] as any, + }, + A: { + series: [{ name: 'Requests/s', points: [[13.594958983547151, 1611839862951]] }] as any, + }, + }, + }, + }; + + const queries: DataQuery[] = [{ refId: 'A' }, { refId: 'B' }]; + + const ids = (toDataQueryResponse(resp, queries).data as DataFrame[]).map((f) => f.refId); + expect(ids).toEqual(['A', 'B']); + }); + + test('resultWithError', () => { + // Generated from: + // qdr.Responses[q.GetRefID()] = backend.DataResponse{ + // Error: fmt.Errorf("an Error: %w", fmt.Errorf("another error")), + // Frames: data.Frames{ + // { + // Fields: data.Fields{data.NewField("numbers", nil, []float64{1, 3})}, + // Meta: &data.FrameMeta{ + // Notices: []data.Notice{ + // { + // Severity: data.NoticeSeverityError, + // Text: "Text", + // }, + // }, + // }, + // }, + // }, + // } + const res = toDataQueryResponse(resWithError); + expect(res.error).toMatchInlineSnapshot(` + Object { + "message": "Hello Error", + "refId": "A", + } + `); + + const norm = res.data.map((f) => toDataFrameDTO(f)); + expect(norm).toMatchInlineSnapshot(` + Array [ + Object { + "fields": Array [ + Object { + "config": Object {}, + "labels": undefined, + "name": "numbers", + "type": "number", + "values": Array [ + 1, + 3, + ], + }, + ], + "meta": Object { + "notices": Array [ + Object { + "severity": 2, + "text": "Text", + }, + ], + }, + "name": undefined, + "refId": "A", + }, + ] + `); + }); + + describe('should convert to TestingStatus', () => { + test('from api/ds/query generic errors', () => { + const result = toTestingStatus({ status: 500, data: { message: 'message', error: 'error' } } as FetchError); + expect(result).toMatchObject({ + status: 'error', + message: 'message', + details: { message: 'error' }, + }); + }); + test('from api/ds/query result errors', () => { + const result = toTestingStatus({ + status: 400, + data: { + results: { + A: { + error: 'error', + }, + }, + }, + } as FetchError); + expect(result).toMatchObject({ + status: 'error', + message: 'error', + }); + }); + test('unknown errors', () => { + expect(() => { + toTestingStatus({ status: 503, data: 'Fatal Error' } as FetchError); + }).toThrow(); + + expect(() => { + toTestingStatus({ status: 503, data: {} } as FetchError); + }).toThrow(); + + expect(() => { + toTestingStatus({ status: 503 } as FetchError); + }).toThrow(); + }); + }); +}); diff --git a/packages/grafana-runtime/src/utils/queryResponse.ts b/packages/grafana-runtime/src/utils/queryResponse.ts new file mode 100644 index 00000000..55c12a20 --- /dev/null +++ b/packages/grafana-runtime/src/utils/queryResponse.ts @@ -0,0 +1,184 @@ +import { + DataQueryResponse, + KeyValue, + LoadingState, + DataQueryError, + TimeSeries, + TableData, + toDataFrame, + DataFrame, + MetricFindValue, + FieldType, + DataQuery, + DataFrameJSON, + dataFrameFromJSON, +} from '@grafana/data'; +import { FetchError, FetchResponse } from '../services'; +import { toDataQueryError } from './toDataQueryError'; + +/** + * Single response object from a backend data source. Properties are optional but response should contain at least + * an error or a some data (but can contain both). Main way to send data is with dataframes attribute as series and + * tables data attributes are legacy formats. + * + * @internal + */ +export interface DataResponse { + error?: string; + refId?: string; + frames?: DataFrameJSON[]; + + // Legacy TSDB format... + series?: TimeSeries[]; + tables?: TableData[]; +} + +/** + * This is the type of response expected form backend datasource. + * + * @internal + */ +export interface BackendDataSourceResponse { + results: KeyValue; +} + +/** + * Parse the results from /api/ds/query into a DataQueryResponse + * + * @param res - the HTTP response data. + * @param queries - optional DataQuery array that will order the response based on the order of query refId's. + * + * @public + */ +export function toDataQueryResponse( + res: + | { data: BackendDataSourceResponse | undefined } + | FetchResponse + | DataQueryError, + queries?: DataQuery[] +): DataQueryResponse { + const rsp: DataQueryResponse = { data: [], state: LoadingState.Done }; + // If the response isn't in a correct shape we just ignore the data and pass empty DataQueryResponse. + if ((res as FetchResponse).data?.results) { + const results = (res as FetchResponse).data.results; + const refIDs = queries?.length ? queries.map((q) => q.refId) : Object.keys(results); + const data: DataResponse[] = []; + + for (const refId of refIDs) { + const dr = results[refId]; + if (!dr) { + continue; + } + dr.refId = refId; + data.push(dr); + } + + for (const dr of data) { + if (dr.error) { + if (!rsp.error) { + rsp.error = { + refId: dr.refId, + message: dr.error, + }; + rsp.state = LoadingState.Error; + } + } + + if (dr.frames?.length) { + for (const js of dr.frames) { + const df = dataFrameFromJSON(js); + if (!df.refId) { + df.refId = dr.refId; + } + rsp.data.push(df); + } + continue; // the other tests are legacy + } + + if (dr.series?.length) { + for (const s of dr.series) { + if (!s.refId) { + s.refId = dr.refId; + } + rsp.data.push(toDataFrame(s)); + } + } + + if (dr.tables?.length) { + for (const s of dr.tables) { + if (!s.refId) { + s.refId = dr.refId; + } + rsp.data.push(toDataFrame(s)); + } + } + } + } + + // When it is not an OK response, make sure the error gets added + if ((res as FetchResponse).status && (res as FetchResponse).status !== 200) { + if (rsp.state !== LoadingState.Error) { + rsp.state = LoadingState.Error; + } + if (!rsp.error) { + rsp.error = toDataQueryError(res as DataQueryError); + } + } + + return rsp; +} + +/** + * Data sources using api/ds/query to test data sources can use this function to + * handle errors and convert them to TestingStatus object. + * + * If possible, this should be avoided in favor of implementing /health endpoint + * and testing data source with DataSourceWithBackend.testDataSource() + * + * Re-thrown errors are handled by testDataSource() in public/app/features/datasources/state/actions.ts + * + * @returns {TestingStatus} + */ +export function toTestingStatus(err: FetchError): any { + const queryResponse = toDataQueryResponse(err); + // POST api/ds/query errors returned as { message: string, error: string } objects + if (queryResponse.error?.data?.message) { + return { + status: 'error', + message: queryResponse.error.data.message, + details: queryResponse.error?.data?.error ? { message: queryResponse.error.data.error } : undefined, + }; + } + // POST api/ds/query errors returned in results object + else if (queryResponse.error?.refId && queryResponse.error?.message) { + return { + status: 'error', + message: queryResponse.error.message, + }; + } + + throw err; +} + +/** + * Return the first string or non-time field as the value + * + * @beta + */ +export function frameToMetricFindValue(frame: DataFrame): MetricFindValue[] { + if (!frame || !frame.length) { + return []; + } + + const values: MetricFindValue[] = []; + let field = frame.fields.find((f) => f.type === FieldType.string); + if (!field) { + field = frame.fields.find((f) => f.type !== FieldType.time); + } + if (field) { + for (let i = 0; i < field.values.length; i++) { + values.push({ text: '' + field.values.get(i) }); + } + } + return values; +} diff --git a/packages/grafana-runtime/src/utils/toDataQueryError.ts b/packages/grafana-runtime/src/utils/toDataQueryError.ts new file mode 100644 index 00000000..f616195a --- /dev/null +++ b/packages/grafana-runtime/src/utils/toDataQueryError.ts @@ -0,0 +1,31 @@ +import { DataQueryError } from '@grafana/data'; + +/** + * Convert an object into a DataQueryError -- if this is an HTTP response, + * it will put the correct values in the error field + * + * @public + */ +export function toDataQueryError(err: DataQueryError | string | Object): DataQueryError { + const error = (err || {}) as DataQueryError; + + if (!error.message) { + if (typeof err === 'string' || err instanceof String) { + return { message: err } as DataQueryError; + } + + let message = 'Query error'; + if (error.message) { + message = error.message; + } else if (error.data && error.data.message) { + message = error.data.message; + } else if (error.data && error.data.error) { + message = error.data.error; + } else if (error.status) { + message = `Query error: ${error.status} ${error.statusText}`; + } + error.message = message; + } + + return error; +} diff --git a/packages/grafana-runtime/tsconfig.build.json b/packages/grafana-runtime/tsconfig.build.json new file mode 100644 index 00000000..9ec189c2 --- /dev/null +++ b/packages/grafana-runtime/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "exclude": ["dist", "node_modules", "**/*.test.ts*"], + "extends": "./tsconfig.json" +} diff --git a/packages/grafana-runtime/tsconfig.json b/packages/grafana-runtime/tsconfig.json new file mode 100644 index 00000000..7f0a0655 --- /dev/null +++ b/packages/grafana-runtime/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "declarationDir": "dist", + "outDir": "compiled", + "rootDirs": ["."] + }, + "exclude": ["dist", "node_modules"], + "extends": "@grafana/tsconfig", + "include": ["src/**/*.ts*", "../../public/app/types/jquery/*.ts", "../../public/app/types/*.d.ts"] +} diff --git a/packages/grafana-schema/.eslintrc b/packages/grafana-schema/.eslintrc new file mode 100644 index 00000000..7a796b6e --- /dev/null +++ b/packages/grafana-schema/.eslintrc @@ -0,0 +1,13 @@ +{ + "rules": { + "no-restricted-imports": ["error", { "patterns": ["@grafana/*"] }] + }, + "overrides": [ + { + "files": ["**/*.test.{ts,tsx}"], + "rules": { + "no-restricted-imports": "off" + } + } + ] +} diff --git a/packages/grafana-schema/CHANGELOG.md b/packages/grafana-schema/CHANGELOG.md new file mode 100644 index 00000000..d224b5b5 --- /dev/null +++ b/packages/grafana-schema/CHANGELOG.md @@ -0,0 +1,3 @@ +# (2021-10) + +First public release diff --git a/packages/grafana-schema/LICENSE_APACHE2 b/packages/grafana-schema/LICENSE_APACHE2 new file mode 100644 index 00000000..373dde57 --- /dev/null +++ b/packages/grafana-schema/LICENSE_APACHE2 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2015 Grafana Labs + + Licensed 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/packages/grafana-schema/README.md b/packages/grafana-schema/README.md new file mode 100644 index 00000000..5632a8e9 --- /dev/null +++ b/packages/grafana-schema/README.md @@ -0,0 +1,5 @@ +# Grafana Schema Library + +> **@grafana/schema is currently in ALPHA**. + +This package holds the definitions for objects that should be stored in JSON configuration files diff --git a/packages/grafana-schema/api-extractor.json b/packages/grafana-schema/api-extractor.json new file mode 100644 index 00000000..5e96b3b0 --- /dev/null +++ b/packages/grafana-schema/api-extractor.json @@ -0,0 +1,3 @@ +{ + "extends": "../../api-extractor.json" +} diff --git a/packages/grafana-schema/index.js b/packages/grafana-schema/index.js new file mode 100644 index 00000000..5d1c9252 --- /dev/null +++ b/packages/grafana-schema/index.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./index.production.js'); +} else { + module.exports = require('./index.development.js'); +} diff --git a/packages/grafana-schema/package.json b/packages/grafana-schema/package.json new file mode 100644 index 00000000..0f85c0d7 --- /dev/null +++ b/packages/grafana-schema/package.json @@ -0,0 +1,39 @@ +{ + "author": "Grafana Labs", + "license": "Apache-2.0", + "name": "@grafana/schema", + "version": "8.4.0-pre", + "description": "Grafana Schema Library", + "keywords": [ + "typescript" + ], + "repository": { + "type": "git", + "url": "http://github.com/grafana/grafana.git", + "directory": "packages/grafana-schema" + }, + "main": "src/index.ts", + "types": "src/index.ts", + "scripts": { + "build": "grafana-toolkit package:build --scope=schema", + "bundle": "rollup -c rollup.config.ts", + "clean": "rimraf ./dist ./compiled", + "docsExtract": "mkdir -p ../../reports/docs && api-extractor run 2>&1 | tee ../../reports/docs/$(basename $(pwd)).log", + "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "@grafana/tsconfig": "^1.0.0-rc1", + "@rollup/plugin-commonjs": "21.0.1", + "@rollup/plugin-json": "4.1.0", + "@rollup/plugin-node-resolve": "13.1.1", + "@swc/helpers": "0.3.2", + "rimraf": "3.0.1", + "rollup": "2.63.0", + "rollup-plugin-sourcemaps": "0.6.3", + "rollup-plugin-terser": "7.0.2", + "typescript": "4.5.4" + }, + "dependencies": { + "tslib": "2.3.1" + } +} diff --git a/packages/grafana-schema/rollup.config.ts b/packages/grafana-schema/rollup.config.ts new file mode 100644 index 00000000..5342797f --- /dev/null +++ b/packages/grafana-schema/rollup.config.ts @@ -0,0 +1,33 @@ +import resolve from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import sourceMaps from 'rollup-plugin-sourcemaps'; +import { terser } from 'rollup-plugin-terser'; + +const pkg = require('./package.json'); + +const libraryName = pkg.name; + +const buildCjsPackage = ({ env }) => { + return { + input: `compiled/index.js`, + output: [ + { + file: `dist/index.${env}.js`, + name: libraryName, + format: 'cjs', + sourcemap: true, + exports: 'named', + globals: {}, + }, + ], + plugins: [ + commonjs({ + include: /node_modules/, + }), + resolve(), + sourceMaps(), + env === 'production' && terser(), + ], + }; +}; +export default [buildCjsPackage({ env: 'development' }), buildCjsPackage({ env: 'production' })]; diff --git a/packages/grafana-schema/src/index.ts b/packages/grafana-schema/src/index.ts new file mode 100644 index 00000000..e3c6d27d --- /dev/null +++ b/packages/grafana-schema/src/index.ts @@ -0,0 +1,6 @@ +/** + * A library containing most of the static shapes required by Grafana. + * + * @packageDocumentation + */ +export * from './schema/graph.gen'; diff --git a/packages/grafana-schema/src/schema/graph.cue b/packages/grafana-schema/src/schema/graph.cue new file mode 100644 index 00000000..0af58f7c --- /dev/null +++ b/packages/grafana-schema/src/schema/graph.cue @@ -0,0 +1,87 @@ +package schema + +AxisPlacement: "auto" | "top" | "right" | "bottom" | "left" | "hidden" @cuetsy(kind="enum") +VisibilityMode: "auto" | "never" | "always" @cuetsy(kind="enum") +GraphDrawStyle: "line" | "bars" | "points" @cuetsy(kind="enum") +LineInterpolation: "linear" | "smooth" | "stepBefore" | "stepAfter" @cuetsy(kind="enum") +ScaleDistribution: "linear" | "log" | "ordinal" @cuetsy(kind="enum") +GraphGradientMode: "none" | "opacity" | "hue" | "scheme" @cuetsy(kind="enum") +StackingMode: "none" | "normal" | "percent" @cuetsy(kind="enum") +BarAlignment: -1 | 0 | 1 @cuetsy(kind="enum",memberNames="Before|Center|After") +ScaleOrientation: 0 | 1 @cuetsy(kind="enum",memberNames="Horizontal|Vertical") +ScaleDirection: 1 | 1 | -1 | -1 @cuetsy(kind="enum",memberNames="Up|Right|Down|Left") +LineStyle: { + fill?: "solid" | "dash" | "dot" | "square" + dash?: [...number] +} @cuetsy(kind="interface") +LineConfig: { + lineColor?: string + lineWidth?: number + lineInterpolation?: LineInterpolation + lineStyle?: LineStyle + + // Indicate if null values should be treated as gaps or connected. + // When the value is a number, it represents the maximum delta in the + // X axis that should be considered connected. For timeseries, this is milliseconds + spanNulls?: bool | number +} @cuetsy(kind="interface") +BarConfig: { + barAlignment?: BarAlignment + barWidthFactor?: number + barMaxWidth?: number +} @cuetsy(kind="interface") +FillConfig: { + fillColor?: string + fillOpacity?: number + fillBelowTo?: string +} @cuetsy(kind="interface") +PointsConfig: { + showPoints?: VisibilityMode + pointSize?: number + pointColor?: string + pointSymbol?: string +} @cuetsy(kind="interface") +ScaleDistributionConfig: { + type: ScaleDistribution + log?: number +} @cuetsy(kind="interface") +AxisConfig: { + axisPlacement?: AxisPlacement + axisLabel?: string + axisWidth?: number + axisSoftMin?: number + axisSoftMax?: number + axisGridShow?: bool + scaleDistribution?: ScaleDistributionConfig +} @cuetsy(kind="interface") +HideSeriesConfig: { + tooltip: bool + legend: bool + viz: bool +} @cuetsy(kind="interface") +StackingConfig: { + mode?: StackingMode + group?: string +} @cuetsy(kind="interface") +StackableFieldConfig: { + stacking?: StackingConfig +} @cuetsy(kind="interface") +HideableFieldConfig: { + hideFrom?: HideSeriesConfig +} @cuetsy(kind="interface") +GraphTresholdsStyleMode: "off" | "line" | "area" | "line+area" | "series" @cuetsy(kind="enum",memberNames="Off|Line|Area|LineAndArea|Series") +GraphThresholdsStyleConfig: { + mode: GraphTresholdsStyleMode +} @cuetsy(kind="interface") +GraphFieldConfig: { + LineConfig + FillConfig + PointsConfig + AxisConfig + BarConfig + StackableFieldConfig + HideableFieldConfig + drawStyle?: GraphDrawStyle + gradientMode?: GraphGradientMode + thresholdsStyle?: GraphThresholdsStyleConfig +} @cuetsy(kind="interface") diff --git a/packages/grafana-schema/src/schema/graph.gen.ts b/packages/grafana-schema/src/schema/graph.gen.ts new file mode 100644 index 00000000..c6c8e20a --- /dev/null +++ b/packages/grafana-schema/src/schema/graph.gen.ts @@ -0,0 +1,287 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// This file was autogenerated by cuetsy from all the files in this directory, +// then hand-edited for correctness. It will be fully auto-generated Soon™. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export enum AxisPlacement { + Auto = 'auto', + Bottom = 'bottom', + Hidden = 'hidden', + Left = 'left', + Right = 'right', + Top = 'top', +} + +export enum VisibilityMode { + Always = 'always', + Auto = 'auto', + Never = 'never', +} + +export enum GraphDrawStyle { + Bars = 'bars', + Line = 'line', + Points = 'points', +} + +export enum LineInterpolation { + Linear = 'linear', + Smooth = 'smooth', + StepAfter = 'stepAfter', + StepBefore = 'stepBefore', +} + +export enum ScaleDistribution { + Linear = 'linear', + Log = 'log', + Ordinal = 'ordinal', +} + +export enum GraphGradientMode { + Hue = 'hue', + None = 'none', + Opacity = 'opacity', + Scheme = 'scheme', +} + +export enum StackingMode { + None = 'none', + Normal = 'normal', + Percent = 'percent', +} + +export enum BarAlignment { + After = 1, + Before = -1, + Center = 0, +} + +export enum ScaleOrientation { + Horizontal = 0, + Vertical = 1, +} + +export enum ScaleDirection { + Down = -1, + Left = -1, + Right = 1, + Up = 1, +} + +export interface LineStyle { + dash?: number[]; + fill?: 'solid' | 'dash' | 'dot' | 'square'; +} + +export interface LineConfig { + lineColor?: string; + lineInterpolation?: LineInterpolation; + lineStyle?: LineStyle; + lineWidth?: number; + spanNulls?: boolean | number; +} + +export interface BarConfig { + barAlignment?: BarAlignment; + barMaxWidth?: number; + barWidthFactor?: number; +} + +export interface FillConfig { + fillBelowTo?: string; + fillColor?: string; + fillOpacity?: number; +} + +export interface PointsConfig { + pointColor?: string; + pointSize?: number; + pointSymbol?: string; + showPoints?: VisibilityMode; +} + +export interface ScaleDistributionConfig { + log?: number; + type: ScaleDistribution; +} + +export interface AxisConfig { + axisGridShow?: boolean; + axisLabel?: string; + axisPlacement?: AxisPlacement; + axisSoftMax?: number; + axisSoftMin?: number; + axisWidth?: number; + scaleDistribution?: ScaleDistributionConfig; +} + +export interface HideSeriesConfig { + legend: boolean; + tooltip: boolean; + viz: boolean; +} + +export interface StackingConfig { + group?: string; + mode?: StackingMode; +} + +export interface StackableFieldConfig { + stacking?: StackingConfig; +} + +export interface HideableFieldConfig { + hideFrom?: HideSeriesConfig; +} + +export enum GraphTresholdsStyleMode { + Area = 'area', + Line = 'line', + LineAndArea = 'line+area', + Off = 'off', + Series = 'series', +} + +export interface GraphThresholdsStyleConfig { + mode: GraphTresholdsStyleMode; +} + +export type LegendPlacement = 'bottom' | 'right'; + +export enum LegendDisplayMode { + Hidden = 'hidden', + List = 'list', + Table = 'table', +} + +export interface TableSortByFieldState { + desc?: boolean; + displayName: string; +} + +export interface SingleStatBaseOptions extends OptionsWithTextFormatting { + orientation: VizOrientation; + reduceOptions: ReduceDataOptions; +} + +export interface ReduceDataOptions { + calcs: string[]; + fields?: string; + limit?: number; + values?: boolean; +} + +export enum VizOrientation { + Auto = 'auto', + Horizontal = 'horizontal', + Vertical = 'vertical', +} + +export interface OptionsWithTooltip { + tooltip: VizTooltipOptions; +} + +export interface OptionsWithLegend { + legend: VizLegendOptions; +} + +export interface OptionsWithTextFormatting { + text?: VizTextDisplayOptions; +} + +export enum BigValueColorMode { + Background = 'background', + None = 'none', + Value = 'value', +} + +export enum BigValueGraphMode { + Area = 'area', + Line = 'line', + None = 'none', +} + +export enum BigValueJustifyMode { + Auto = 'auto', + Center = 'center', +} + +export enum BigValueTextMode { + Auto = 'auto', + Name = 'name', + None = 'none', + Value = 'value', + Value_and_name = 'value_and_name', +} + +export type FieldTextAlignment = 'auto' | 'left' | 'right' | 'center'; + +export enum TableCellDisplayMode { + Auto = 'auto', + BasicGauge = 'basic', + ColorBackground = 'color-background', + ColorBackgroundSolid = 'color-background-solid', + ColorText = 'color-text', + GradientGauge = 'gradient-gauge', + Image = 'image', + JSONView = 'json-view', + LcdGauge = 'lcd-gauge', +} + +export interface VizTextDisplayOptions { + titleSize?: number; + valueSize?: number; +} + +export enum TooltipDisplayMode { + Multi = 'multi', + None = 'none', + Single = 'single', +} + +export interface GraphFieldConfig + extends LineConfig, + FillConfig, + PointsConfig, + AxisConfig, + BarConfig, + StackableFieldConfig, + HideableFieldConfig { + drawStyle?: GraphDrawStyle; + gradientMode?: GraphGradientMode; + thresholdsStyle?: GraphThresholdsStyleConfig; +} + +export interface VizLegendOptions { + asTable?: boolean; + calcs: string[]; + displayMode: LegendDisplayMode; + isVisible?: boolean; + placement: LegendPlacement; + sortBy?: string; + sortDesc?: boolean; +} + +export enum BarGaugeDisplayMode { + Basic = 'basic', + Gradient = 'gradient', + Lcd = 'lcd', +} + +export interface TableFieldOptions { + align: string; + displayMode: TableCellDisplayMode; + hidden?: boolean; + minWidth?: number; + width?: number; + filterable?: boolean; +} + +export const defaultTableFieldOptions: TableFieldOptions = { + align: 'auto', + displayMode: TableCellDisplayMode.Auto, +}; + +export interface VizTooltipOptions { + mode: TooltipDisplayMode; +} diff --git a/packages/grafana-schema/src/schema/legend.cue b/packages/grafana-schema/src/schema/legend.cue new file mode 100644 index 00000000..336ab232 --- /dev/null +++ b/packages/grafana-schema/src/schema/legend.cue @@ -0,0 +1,15 @@ +package schema + +LegendPlacement: "bottom" | "right" @cuetsy(kind="type") + +LegendDisplayMode: "list" | "table" | "hidden" @cuetsy(kind="enum") + +VizLegendOptions: { + displayMode: LegendDisplayMode + placement: LegendPlacement + asTable?: bool + isVisible?: bool + sortBy?: string + sortDesc?: bool + calcs: [...string] +} @cuetsy(kind="interface") diff --git a/packages/grafana-schema/src/schema/mudball.cue b/packages/grafana-schema/src/schema/mudball.cue new file mode 100644 index 00000000..3509e8c2 --- /dev/null +++ b/packages/grafana-schema/src/schema/mudball.cue @@ -0,0 +1,53 @@ +package schema + +// Use this file as a big TODO list - if it's still in here, it's a TODO to +// separate it out into a discrete file. + +TableSortByFieldState: { + displayName: string + desc?: bool +} @cuetsy(kind="interface") + +SingleStatBaseOptions: { + OptionsWithTextFormatting + reduceOptions: ReduceDataOptions + orientation: VizOrientation +} @cuetsy(kind="interface") +// TODO copy back to appropriate place +ReduceDataOptions: { + // If true show each row value + values?: bool + // if showing all values limit + limit?: number + // When !values, pick one value for the whole field + calcs: [...string] + // Which fields to show. By default this is only numeric fields + fields?: string +} @cuetsy(kind="interface") +// TODO copy back to appropriate place +VizOrientation: "auto" | "vertical" | "horizontal" @cuetsy(kind="enum") +// TODO copy back to appropriate place +OptionsWithTooltip: { + // FIXME this field is non-optional in the corresponding TS type + tooltip?: VizTooltipOptions +} @cuetsy(kind="interface") +// TODO copy back to appropriate place +OptionsWithLegend: { + // FIXME this field is non-optional in the corresponding TS type + legend?: VizLegendOptions +} @cuetsy(kind="interface") +// TODO copy back to appropriate place +OptionsWithTextFormatting: { + text?: VizTextDisplayOptions +} @cuetsy(kind="interface") +// TODO copy back to appropriate place +BigValueColorMode: "value" | "background" | "none" @cuetsy(kind="enum") +// TODO copy back to appropriate place +BigValueGraphMode: "none" | "line" | "area" @cuetsy(kind="enum") +// TODO copy back to appropriate place +BigValueJustifyMode: "auto" | "center" @cuetsy(kind="enum") +// TODO copy back to appropriate place +// TODO does cuetsy handle underscores the expected way? +BigValueTextMode: "auto" | "value" | "value_and_name" | "name" | "none" @cuetsy(kind="enum") +// TODO copy back to appropriate place +BarGaugeDisplayMode: "basic" | "lcd" | "gradient" @cuetsy(kind="enum") diff --git a/packages/grafana-schema/src/schema/table.cue b/packages/grafana-schema/src/schema/table.cue new file mode 100644 index 00000000..e62dbb3d --- /dev/null +++ b/packages/grafana-schema/src/schema/table.cue @@ -0,0 +1,15 @@ +package schema + +// TODO -- should not be table specific! +FieldTextAlignment: "auto" | "left" | "right" | "center" @cuetsy(kind="type") + +TableCellDisplayMode: "auto" | "color-text" | "color-background" | "color-background-solid" | "gradient-gauge" | "lcd-gauge" | "json-view" | "basic" | "image" @cuetsy(kind="enum",memberNames="Auto|ColorText|ColorBackground|ColorBackgroundSolid|GradientGauge|LcdGauge|JSONView|BasicGauge|Image") + +TableFieldOptions: { + width?: number + minWidth?: number + align: FieldTextAlignment | *"auto" + displayMode: TableCellDisplayMode | *"auto" + hidden?: bool // ?? default is missing or false ?? + filterable?: bool +} @cuetsy(kind="interface") diff --git a/packages/grafana-schema/src/schema/text.cue b/packages/grafana-schema/src/schema/text.cue new file mode 100644 index 00000000..d5475387 --- /dev/null +++ b/packages/grafana-schema/src/schema/text.cue @@ -0,0 +1,8 @@ +package schema + +VizTextDisplayOptions: { + // Explicit title text size + titleSize?: number + // Explicit value text size + valueSize?: number +} @cuetsy(kind="interface") diff --git a/packages/grafana-schema/src/schema/tooltip.cue b/packages/grafana-schema/src/schema/tooltip.cue new file mode 100644 index 00000000..c58ee739 --- /dev/null +++ b/packages/grafana-schema/src/schema/tooltip.cue @@ -0,0 +1,7 @@ +package schema + +TooltipDisplayMode: "single" | "multi" | "none" @cuetsy(kind="enum") + +VizTooltipOptions: { + mode: TooltipDisplayMode +} @cuetsy(kind="interface") diff --git a/packages/grafana-schema/src/scuemata/dashboard/dashboard.cue b/packages/grafana-schema/src/scuemata/dashboard/dashboard.cue new file mode 100644 index 00000000..6aed732d --- /dev/null +++ b/packages/grafana-schema/src/scuemata/dashboard/dashboard.cue @@ -0,0 +1,429 @@ +package dashboard + +import ( + "list" + + "github.com/grafana/grafana/cue/scuemata" +) + +Family: scuemata.#Family & { + lineages: [ + [ + { // 0.0 + // Unique numeric identifier for the dashboard. + // TODO must isolate or remove identifiers local to a Grafana instance...? + id?: number + // Unique dashboard identifier that can be generated by anyone. string (8-40) + uid?: string + // Title of dashboard. + title?: string + // Description of dashboard. + description?: string + + gnetId?: string + // Tags associated with dashboard. + tags?: [...string] + // Theme of dashboard. + style: *"light" | "dark" + // Timezone of dashboard, + timezone?: *"browser" | "utc" | "" + // Whether a dashboard is editable or not. + editable: bool | *true + // 0 for no shared crosshair or tooltip (default). + // 1 for shared crosshair. + // 2 for shared crosshair AND shared tooltip. + graphTooltip: >=0 & <=2 | *0 + // Time range for dashboard, e.g. last 6 hours, last 7 days, etc + time?: { + from: string | *"now-6h" + to: string | *"now" + } + // Timepicker metadata. + timepicker?: { + // Whether timepicker is collapsed or not. + collapse: bool | *false + // Whether timepicker is enabled or not. + enable: bool | *true + // Whether timepicker is visible or not. + hidden: bool | *false + // Selectable intervals for auto-refresh. + refresh_intervals: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] + } + // Templating. + templating?: list: [...{...}] + // Annotations. + annotations?: list: [...{ + builtIn: number | *0 + // Datasource to use for annotation. + datasource: string + // Whether annotation is enabled. + enable: bool | *true + // Whether to hide annotation. + hide?: bool | *false + // Annotation icon color. + iconColor?: string + // Name of annotation. + name?: string + type: string | *"dashboard" + // Query for annotation data. + rawQuery?: string + showIn: number | *0 + }] + // Auto-refresh interval. + refresh?: string | false + // Version of the JSON schema, incremented each time a Grafana update brings + // changes to said schema. + // FIXME this is the old schema numbering system, and will be replaced by scuemata + schemaVersion: number | *30 + // Version of the dashboard, incremented each time the dashboard is updated. + version?: number + panels?: [...(#Panel | #GraphPanel | #RowPanel)] + + // TODO docs + #FieldColorModeId: "thresholds" | "palette-classic" | "palette-saturated" | "continuous-GrYlRd" | "fixed" @cuetsy(kind="enum") + + // TODO docs + #FieldColorSeriesByMode: "min" | "max" | "last" @cuetsy(kind="type") + + // TODO docs + #FieldColor: { + // The main color scheme mode + mode: #FieldColorModeId | string + // Stores the fixed color value if mode is fixed + fixedColor?: string + // Some visualizations need to know how to assign a series color from by value color schemes + seriesBy?: #FieldColorSeriesByMode + } @cuetsy(kind="interface") + + // TODO docs + #Threshold: { + // TODO docs + // FIXME the corresponding typescript field is required/non-optional, but nulls currently appear here when serializing -Infinity to JSON + value?: number + // TODO docs + color: string + // TODO docs + // TODO are the values here enumerable into a disjunction? + // Some seem to be listed in typescript comment + state?: string + } @cuetsy(kind="interface") + + #ThresholdsMode: "absolute" | "percentage" @cuetsy(kind="enum") + + #ThresholdsConfig: { + mode: #ThresholdsMode + + // Must be sorted by 'value', first value is always -Infinity + steps: [...#Threshold] + } @cuetsy(kind="interface") + + // TODO docs + // FIXME this is extremely underspecfied; wasn't obvious which typescript types corresponded to it + #Transformation: { + id: string + options: {...} + } + + // Schema for panel targets is specified by datasource + // plugins. We use a placeholder definition, which the Go + // schema loader either left open/as-is with the Base + // variant of the Dashboard and Panel families, or filled + // with types derived from plugins in the Instance variant. + // When working directly from CUE, importers can extend this + // type directly to achieve the same effect. + #Target: {...} + + // Dashboard panels. Panels are canonically defined inline + // because they share a version timeline with the dashboard + // schema; they do not evolve independently. + #Panel: { + // The panel plugin type id. + type: !="" + + // TODO docs + id?: number + + // FIXME this almost certainly has to be changed in favor of scuemata versions + pluginVersion?: string + + // TODO docs + tags?: [...string] + + // Internal - the exact major and minor versions of the panel plugin + // schema. Hidden and therefore not a part of the data model, but + // expected to be filled with panel plugin schema versions so that it's + // possible to figure out which schema version matched on a successful + // unification. + // _pv: { maj: int, min: int } + // The major and minor versions of the panel plugin for this schema. + // TODO 2-tuple list instead of struct? + // panelSchema?: { maj: number, min: number } + panelSchema?: [number, number] + + // TODO docs + targets?: [...#Target] + + // Panel title. + title?: string + // Description. + description?: string + // Whether to display the panel without a background. + transparent: bool | *false + // Name of default datasource. + datasource?: string + // Grid position. + gridPos?: { + // Panel + h: number & >0 | *9 + // Panel + w: number & >0 & <=24 | *12 + // Panel x + x: number & >=0 & <24 | *0 + // Panel y + y: number & >=0 | *0 + // true if fixed + static?: bool + } + // Panel links. + // FIXME this is temporarily specified as a closed list so + // that validation will pass when no links are present, but + // to force a failure as soon as it's checked against there + // being anything in the list so it can be fixed in + // accordance with that object + links?: [] + + // Name of template variable to repeat for. + repeat?: string + // Direction to repeat in if 'repeat' is set. + // "h" for horizontal, "v" for vertical. + repeatDirection: *"h" | "v" + + // TODO docs + maxDataPoints?: number + + // TODO docs + thresholds?: [...] + + // TODO docs + timeRegions?: [...] + + transformations: [...#Transformation] + + // TODO docs + // TODO tighter constraint + interval?: string + + // TODO docs + // TODO tighter constraint + timeFrom?: string + + // TODO docs + // TODO tighter constraint + timeShift?: string + + // options is specified by the PanelOptions field in panel + // plugin schemas. + options: {} + + fieldConfig: { + defaults: { + // The display value for this field. This supports template variables blank is auto + displayName?: string + + // This can be used by data sources that return and explicit naming structure for values and labels + // When this property is configured, this value is used rather than the default naming strategy. + displayNameFromDS?: string + + // Human readable field metadata + description?: string + + // An explict path to the field in the datasource. When the frame meta includes a path, + // This will default to `${frame.meta.path}/${field.name} + // + // When defined, this value can be used as an identifier within the datasource scope, and + // may be used to update the results + path?: string + + // True if data source can write a value to the path. Auth/authz are supported separately + writeable?: bool + + // True if data source field supports ad-hoc filters + filterable?: bool + + // Numeric Options + unit?: string + + // Significant digits (for display) + decimals?: number + + min?: number + max?: number + + // Convert input values into a display string + // + // TODO this one corresponds to a complex type with + // generics on the typescript side. Ouch. Will + // either need special care, or we'll just need to + // accept a very loosely specified schema. It's very + // unlikely we'll be able to translate cue to + // typescript generics in the general case, though + // this particular one *may* be able to work. + mappings?: [...{...}] + + // Map numeric values to states + thresholds?: #ThresholdsConfig + + // // Map values to a display color + color?: #FieldColor + + // // Used when reducing field values + // nullValueMode?: NullValueMode + + // // The behavior when clicking on a result + links?: [...] + + // Alternative to empty string + noValue?: string + + // custom is specified by the PanelFieldConfig field + // in panel plugin schemas. + custom?: {} + } + overrides: [...{ + matcher: { + id: string | *"" + options?: _ + } + properties: [...{ + id: string | *"" + value?: _ + }] + }] + } + // Embed the disjunction of all injected panel schema, if any were injected. + if len(compose._panelSchemas) > 0 { + or(compose._panelSchemas) // TODO try to stick graph in here + } + + // Make the plugin-composed subtrees open if the panel is + // of unknown types. This is important in every possible case: + // - Base (this file only): no real dashboard json + // containing any panels would ever validate + // - Dist (this file + core plugin schema): dashboard json containing + // panels with any third-party panel plugins would fail to validate, + // as well as any core plugins lacking a models.cue. The latter case + // is not normally expected, but this is not the appropriate place + // to enforce the invariant, anyway. + // - Instance (this file + core + third-party plugin schema): dashboard + // json containing panels with a third-party plugin that exists but + // is not currently installed would fail to validate. + if !list.Contains(compose._panelTypes, type) { + options: {...} + fieldConfig: defaults: custom: {...} + ... + } + } + + // Row panel + #RowPanel: { + type: "row" + collapsed: bool | *false + title?: string + + // Name of default datasource. + datasource?: string + + gridPos?: { + // Panel + h: number & >0 | *9 + // Panel + w: number & >0 & <=24 | *12 + // Panel x + x: number & >=0 & <24 | *0 + // Panel y + y: number & >=0 | *0 + // true if fixed + static?: bool + } + id: number + panels: [...(#Panel | #GraphPanel)] + } + // Support for legacy graph panels. + #GraphPanel: { + ... + type: "graph" + thresholds: [...{...}] + timeRegions?: [...{...}] + seriesOverrides: [...{...}] + aliasColors?: [string]: string + bars: bool | *false + dashes: bool | *false + dashLength: number | *10 + fill?: number + fillGradient?: number + hiddenSeries: bool | *false + legend: {...} + lines: bool | *false + linewidth?: number + nullPointMode: *"null" | "connected" | "null as zero" + percentage: bool | *false + points: bool | *false + pointradius?: number + renderer: string + spaceLength: number | *10 + stack: bool | *false + steppedLine: bool | *false + tooltip?: { + shared?: bool + sort: number | *0 + value_type: *"individual" | "cumulative" + } + } + } + ] + ] + compose: { + // Scuemata families for all panel types that should be composed into the + // dashboard schema. + Panel: [string]: scuemata.#PanelFamily + + // _panelTypes: [for typ, _ in Panel {typ}] + _panelTypes: [for typ, _ in Panel {typ}, "graph", "row"] + _panelSchemas: [for typ, scue in Panel { + for lv, lin in scue.lineages { + for sv, sch in lin { + (_mapPanel & {arg: { + type: typ + v: [lv, sv] // TODO add optionality for exact, at least, at most, any + model: sch // TODO Does this need to be close()d? + }}).out + } + } + }, { type: string }] + _mapPanel: { + arg: { + type: string & !="" + v: [number, number] + model: {...} + } + // Until CUE introduces the must() constraint, we have to enforce + // that the input model is as expected by checking for unification + // in this hidden property (see https://github.com/cue-lang/cue/issues/575). + // If we unified arg.model with the scuemata.#PanelSchema + // meta-schema directly, the struct openness (PanelOptions: {...}) + // would be applied to the actual schema instance in the arg. Here, + // where we're actually putting those in the dashboard schema, want + // those to be closed, or at least preserve closed-ness. + _checkSchema: scuemata.#PanelSchema & arg.model + out: { + type: arg.type + panelSchema: arg.v // TODO add optionality for exact, at least, at most, any + options: arg.model.PanelOptions + fieldConfig: defaults: custom: {} + if arg.model.PanelFieldConfig != _|_ { + fieldConfig: defaults: custom: arg.model.PanelFieldConfig + } + } + } + } +} \ No newline at end of file diff --git a/packages/grafana-schema/tsconfig.build.json b/packages/grafana-schema/tsconfig.build.json new file mode 100644 index 00000000..9ec189c2 --- /dev/null +++ b/packages/grafana-schema/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "exclude": ["dist", "node_modules", "**/*.test.ts*"], + "extends": "./tsconfig.json" +} diff --git a/packages/grafana-schema/tsconfig.json b/packages/grafana-schema/tsconfig.json new file mode 100644 index 00000000..7bad1e46 --- /dev/null +++ b/packages/grafana-schema/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "declarationDir": "dist", + "outDir": "compiled", + "rootDirs": ["."] + }, + "exclude": ["dist", "node_modules"], + "extends": "@grafana/tsconfig", + "include": ["src/**/*.ts*"] +} diff --git a/packages/grafana-toolkit/.eslintrc b/packages/grafana-toolkit/.eslintrc new file mode 100644 index 00000000..a465b644 --- /dev/null +++ b/packages/grafana-toolkit/.eslintrc @@ -0,0 +1,14 @@ +{ + "rules": { + "no-restricted-imports": ["error", { "patterns": ["@grafana/runtime"] }] + }, + "overrides": [ + { + "files": ["./**/*.{ts,tsx}"], + "rules": { + "react-hooks/rules-of-hooks": "off", + "react-hooks/exhaustive-deps": "off" + } + } + ] +} diff --git a/packages/grafana-toolkit/CHANGELOG.md b/packages/grafana-toolkit/CHANGELOG.md new file mode 100644 index 00000000..aba77fd4 --- /dev/null +++ b/packages/grafana-toolkit/CHANGELOG.md @@ -0,0 +1,47 @@ +# 7.3.0-beta1 (2020-10-15) + +### Features / Enhancements + +- **grafana/toolkit**: expose Jest maxWorkers arg for plugin test & build tasks. [#27724](https://github.com/grafana/grafana/pull/27724), [@domasx2](https://github.com/domasx2) + +# 7.2.1 (2020-10-08) + +### Features / Enhancements + +- **grafana/toolkit**: Add --coverage flag to plugin build command. [#27743](https://github.com/grafana/grafana/pull/27743), [@gassiss](https://github.com/gassiss) + +# 7.2.0 (2020-09-23) + +### Bug Fixes + +- **grafana/toolkit**: avoid path.resolve with globby in moveStaticFiles. [#27670](https://github.com/grafana/grafana/pull/27670), [@kennytm](https://github.com/kennytm) + +# 7.0.0 (2020-05-18) + +### Bug Fixes + +- **@grafana/toolkit**: Use process.cwd() instead of PWD to get directory. [#24677](https://github.com/grafana/grafana/pull/24677), [@zoltanbedi](https://github.com/zoltanbedi) + +# 7.0.0-beta.1 (2020-04-28) + +### Features / Enhancements + +- **Grafana Toolkit**: Adds template for backend data source. [#23864](https://github.com/grafana/grafana/pull/23864), [@bergquist](https://github.com/bergquist) + +# 6.6.0-beta1 (2020-01-20) + +### Features / Enhancements + +- **grafana/toolkit**: Add option to override webpack config. [#20872](https://github.com/grafana/grafana/pull/20872), [@sebimarkgraf](https://github.com/sebimarkgraf) + +# 6.4.0 (2019-10-01) + +# 6.4.0-beta2 (2019-09-25) + +### Features / Enhancements + +- **grafana/toolkit**: Add plugin creation task. [#19207](https://github.com/grafana/grafana/pull/19207), [@dprokop](https://github.com/dprokop) + +# 6.4.0-beta1 (2019-09-17) + +First release, see [Readme](https://github.com/grafana/grafana/blob/v6.4.0-beta1/packages/grafana-toolkit/README.md) for details. diff --git a/packages/grafana-toolkit/LICENSE_APACHE2 b/packages/grafana-toolkit/LICENSE_APACHE2 new file mode 100644 index 00000000..373dde57 --- /dev/null +++ b/packages/grafana-toolkit/LICENSE_APACHE2 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2015 Grafana Labs + + Licensed 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/packages/grafana-toolkit/README.md b/packages/grafana-toolkit/README.md new file mode 100644 index 00000000..bbb06243 --- /dev/null +++ b/packages/grafana-toolkit/README.md @@ -0,0 +1,344 @@ +> **WARNING: @grafana/toolkit is currently in BETA**. + +# grafana-toolkit + +grafana-toolkit is a CLI that enables efficient development of Grafana plugins. We want to help our community focus on the core value of their plugins rather than all the setup required to develop them. + +## Getting started + +Set up a new plugin with `grafana-toolkit plugin:create` command: + +```sh +npx @grafana/toolkit plugin:create my-grafana-plugin +cd my-grafana-plugin +yarn install +yarn dev +``` + +## Update your plugin to use grafana-toolkit + +Follow the steps below to start using grafana-toolkit in your existing plugin. + +1. Add `@grafana/toolkit` package to your project by running `yarn add @grafana/toolkit` or `npm install @grafana/toolkit`. +2. Create `tsconfig.json` file in the root dir of your plugin and paste the code below: + +```json +{ + "extends": "./node_modules/@grafana/toolkit/src/config/tsconfig.plugin.json", + "include": ["src", "types"], + "compilerOptions": { + "rootDir": "./src", + "baseUrl": "./src", + "typeRoots": ["./node_modules/@types"] + } +} +``` + +3. Create `.prettierrc.js` file in the root dir of your plugin and paste the code below: + +```js +module.exports = { + ...require('./node_modules/@grafana/toolkit/src/config/prettier.plugin.config.json'), +}; +``` + +4. In your `package.json` file add following scripts: + +```json +"scripts": { + "build": "grafana-toolkit plugin:build", + "test": "grafana-toolkit plugin:test", + "dev": "grafana-toolkit plugin:dev", + "watch": "grafana-toolkit plugin:dev --watch" +}, +``` + +## Usage + +With grafana-toolkit, we give you a CLI that addresses common tasks performed when working on Grafana plugin: + +- `grafana-toolkit plugin:create` +- `grafana-toolkit plugin:dev` +- `grafana-toolkit plugin:test` +- `grafana-toolkit plugin:build` +- `grafana-toolkit plugin:sign` + +### Create your plugin + +`grafana-toolkit plugin:create plugin-name` + +This command creates a new Grafana plugin from template. + +If `plugin-name` is provided, then the template is downloaded to `./plugin-name` directory. Otherwise, it will be downloaded to the current directory. + +### Develop your plugin + +`grafana-toolkit plugin:dev` + +This command creates a development build that's easy to play with and debug using common browser tooling. + +Available options: + +- `-w`, `--watch` - run development task in a watch mode + +### Test your plugin + +`grafana-toolkit plugin:test` + +This command runs Jest against your codebase. + +Available options: + +- `--watch` - Runs tests in interactive watch mode. +- `--coverage` - Reports code coverage. +- `-u`, `--updateSnapshot` - Performs snapshots update. +- `--testNamePattern=` - Runs test with names that match provided regex (https://jestjs.io/docs/en/cli#testnamepattern-regex). +- `--testPathPattern=` - Runs test with paths that match provided regex (https://jestjs.io/docs/en/cli#testpathpattern-regex). +- `--maxWorkers=|` - Limit number of Jest workers spawned (https://jestjs.io/docs/en/cli#--maxworkersnumstring) + +### Build your plugin + +`grafana-toolkit plugin:build` + +This command creates a production-ready build of your plugin. + +Available options: + +- `--skipTest` - Skip running tests as part of build. Useful if you're running the build as part of a larger pipeline. +- `--skipLint` - Skip linting as part of build. Useful if you're running the build as part of a larger pipeline. +- `--coverage` - Reports code coverage after the test step of the build. +- `--preserveConsole` - Preserves console statements in the code. + +### Sign your plugin + +`grafana-toolkit plugin:sign` + +This command creates a signed MANIFEST.txt file which Grafana uses to validate the integrity of the plugin. + +Available options: + +- `--signatureType` - The [type of Signature](https://grafana.com/legal/plugins/) you are generating: `private`, `community` or `commercial` +- `--rootUrls` - For private signatures, a list of the Grafana instance URLs that the plugin will be used on + +To generate a signature, you will need to sign up for a free account on https://grafana.com, create an API key with the Plugin Publisher role, and pass that in the `GRAFANA_API_KEY` environment variable. + +## FAQ + +### Which version of grafana-toolkit should I use? + +See [Grafana packages versioning guide](https://github.com/grafana/grafana/blob/main/packages/README.md#versioning). + +### What tools does grafana-toolkit use? + +grafana-toolkit comes with TypeScript, ESLint, Prettier, Jest, CSS and SASS support. + +### How to start using grafana-toolkit in my plugin? + +See [Updating your plugin to use grafana-toolkit](#updating-your-plugin-to-use-grafana-toolkit). + +### Can I use TypeScript to develop Grafana plugins? + +Yes! grafana-toolkit supports TypeScript by default. + +### How can I test my plugin? + +grafana-toolkit comes with Jest as a test runner. + +Internally at Grafana we use Enzyme. If you are developing React plugin and you want to configure Enzyme as a testing utility, then you need to configure `enzyme-adapter-react`. To do so, create `/config/jest-setup.ts` file that will provide necessary setup. Copy the following code into that file to get Enzyme working with React: + +```ts +import { configure } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +configure({ adapter: new Adapter() }); +``` + +You can also set up Jest with shims of your needs by creating `jest-shim.ts` file in the same directory: `/config/jest-shim.ts` + +### Can I provide custom setup for Jest? + +You can provide custom Jest configuration with a `package.json` file. For more details, see [Jest docs](https://jest-bot.github.io/jest/docs/configuration.html). + +Currently we support following Jest configuration properties: + +- [`snapshotSerializers`](https://jest-bot.github.io/jest/docs/configuration.html#snapshotserializers-array-string) +- [`moduleNameMapper`](https://jestjs.io/docs/en/configuration#modulenamemapper-object-string-string) + +### How can I customize Webpack rules or plugins? + +You can provide your own `webpack.config.js` file that exports a `getWebpackConfig` function. We recommend that you extend the standard configuration, but you are free to create your own: + +```js +const CustomPlugin = require('custom-plugin'); + +module.exports.getWebpackConfig = (config, options) => ({ + ...config, + plugins: [...config.plugins, new CustomPlugin()], +}); +``` + +### How can I style my plugin? + +We support pure CSS, SASS, and CSS-in-JS approach (via [Emotion](https://emotion.sh/)). + +#### Single CSS or SASS file + +Create your CSS or SASS file and import it in your plugin entry point (typically `module.ts`): + +```ts +import 'path/to/your/css_or_sass'; +``` + +The styles will be injected via `style` tag during runtime. + +> **Note:** that imported static assets will be inlined as base64 URIs. _This can be subject of change in the future!_ + +#### Theme-specific stylesheets + +If you want to provide different stylesheets for dark/light theme, then create `dark.[css|scss]` and `light.[css|scss]` files in the `src/styles` directory of your plugin. grafana-toolkit generates theme-specific stylesheets that are stored in `dist/styles` directory. + +In order for Grafana to pick up your theme stylesheets, you need to use `loadPluginCss` from `@grafana/runtime` package. Typically you would do that in the entry point of your plugin: + +```ts +import { loadPluginCss } from '@grafana/runtime'; + +loadPluginCss({ + dark: 'plugins//styles/dark.css', + light: 'plugins//styles/light.css', +}); +``` + +You must add `@grafana/runtime` to your plugin dependencies by running `yarn add @grafana/runtime` or `npm install @grafana/runtime`. + +> **Note:** that in this case static files (png, svg, json, html) are all copied to dist directory when the plugin is bundled. Relative paths to those files does not change! + +#### Emotion + +Starting from Grafana 6.2 _our suggested way_ for styling plugins is by using [Emotion](https://emotion.sh). It's a CSS-in-JS library that we use internally at Grafana. The biggest advantage of using Emotion is that you can access Grafana Theme variables. + +To start using Emotion, you first must add it to your plugin dependencies: + +``` + yarn add "emotion"@10.0.27 +``` + +Then, import `css` function from Emotion: + +```ts +import { css } from 'emotion'; +``` + +Now you are ready to implement your styles: + +```tsx +const MyComponent = () => { + return ( +
+ ); +}; +``` + +To learn more about using Grafana theme please refer to [Theme usage guide](https://github.com/grafana/grafana/blob/main/style_guides/themes.md#react) + +> We do not support Emotion's `css` prop. Use className instead! + +### Can I adjust TypeScript configuration to suit my needs? + +Yes! However, it's important that your `tsconfig.json` file contains the following lines: + +```json +{ + "extends": "./node_modules/@grafana/toolkit/src/config/tsconfig.plugin.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "./src", + "typeRoots": ["./node_modules/@types"] + } +} +``` + +### Can I adjust ESLint configuration to suit my needs? + +grafana-toolkit comes with [default config for ESLint](https://github.com/grafana/grafana/blob/main/packages/grafana-toolkit/src/config/eslint.plugin.json). For now, there is no way to customise ESLint config. + +### How is Prettier integrated into grafana-toolkit workflow? + +When building plugin with [`grafana-toolkit plugin:build`](#building-plugin) task, grafana-toolkit performs Prettier check. If the check detects any Prettier issues, the build will not pass. To avoid such situation we suggest developing plugin with [`grafana-toolkit plugin:dev --watch`](#developing-plugin) task running. This task tries to fix Prettier issues automatically. + +### My editor does not respect Prettier config, what should I do? + +In order for your editor to pick up our Prettier config you need to create `.prettierrc.js` file in the root directory of your plugin with following content: + +```js +module.exports = { + ...require('./node_modules/@grafana/toolkit/src/config/prettier.plugin.config.json'), +}; +``` + +### How do I add third-party dependencies that are not npm packages? + +Put them in the `static` directory in the root of your project. The `static` directory is copied when the plugin is built. + +### I am getting this message when I run yarn install: `Request failed \"404 Not Found\"` + +If you are using version `canary`, this error occurs because a `canary` release unpublishes previous versions leaving `yarn.lock` outdated. Remove `yarn.lock` and run `yarn install` again. + +### I am getting this message when I run my plugin: `Unable to dynamically transpile ES module A loader plugin needs to be configured via SystemJS.config({ transpiler: 'transpiler-module' }).` + +This error occurs when you bundle your plugin using the `grafana-toolkit plugin:dev` task and your code comments include ES2016 code. + +There are two issues at play: + +- The `grafana-toolkit plugin:dev` task does not remove comments from your bundled package. +- Grafana does not support [ES modules](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/). + +If your comments include ES2016 code, then SystemJS v0.20.19, which Grafana uses internally to load plugins, interprets your code as an ESM and fails. + +To fix this error, remove the ES2016 code from your comments. + +### I would like to dynamically import modules in my plugin + +Create a webpack.config.js with this content (in the root of _your_ plugin) + +```ts +// webpack.config.js +const pluginJson = require('./src/plugin.json'); +module.exports.getWebpackConfig = (config, options) => ({ + ...config, + output: { + ...config.output, + publicPath: `public/plugins/${pluginJson.id}/`, + }, +}); +``` + +The plugin id is the id written in the plugin.json file. + +## Contribute to grafana-toolkit + +You can contribute to grafana-toolkit by helping develop it or by debugging it. + +### Develop grafana-toolkit + +Typically plugins should be developed using the `@grafana/toolkit` installed from npm. However, when working on the toolkit, you might want to use the local version. Follow the steps below to develop with a local version: + +1. Clone [Grafana repository](https://github.com/grafana/grafana). +2. Navigate to the directory you have cloned Grafana repo to and then run `yarn install --immutable`. +3. Navigate to `/packages/grafana-toolkit` and then run `yarn link`. +4. Navigate to the directory where your plugin code is and then run `npx grafana-toolkit plugin:dev --yarnlink`. This adds all dependencies required by grafana-toolkit to your project, as well as link your local grafana-toolkit version to be used by the plugin. + +### Debug grafana-toolkit + +To debug grafana-toolkit you can use standard [NodeJS debugging methods](https://nodejs.org/de/docs/guides/debugging-getting-started/#enable-inspector) (`node --inspect`, `node --inspect-brk`). + +To run grafana-toolkit in a debugging session use the following command in the toolkit's directory: + +`node --inspect-brk ./bin/grafana-toolkit.js [task]` + +To run [linked](#develop-grafana-toolkit) grafana-toolkit in a debugging session use the following command in the plugin's directory: + +`node --inspect-brk ./node_modules/@grafana/toolkit/bin/grafana-toolkit.js [task]` diff --git a/packages/grafana-toolkit/bin/grafana-toolkit.js b/packages/grafana-toolkit/bin/grafana-toolkit.js new file mode 100755 index 00000000..48cb58a9 --- /dev/null +++ b/packages/grafana-toolkit/bin/grafana-toolkit.js @@ -0,0 +1,49 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +let includeInternalScripts = false; + +const isLinkedMode = () => { + // In circleci we are in linked mode. Detect by using the circle working directory, + // rather than the present working directory. + const pwd = process.env.CIRCLE_WORKING_DIRECTORY || process.env.PWD || process.cwd(); + + if (path.basename(pwd) === 'grafana-toolkit') { + return true; + } + + try { + const resolvedPath = require.resolve('@grafana/toolkit'); + return fs.lstatSync(resolvedPath).isSymbolicLink(); + } catch { + return false; + } +}; + +const entrypoint = () => { + const entrypointBase = `${__dirname}/../src/cli/index`; + const resolvedJsDir = path.resolve(`${entrypointBase}.js`); + const resolvedTsDir = path.resolve(`${entrypointBase}.ts`); + + // IF we have a toolkit directory AND linked grafana toolkit AND the toolkit dir is a symbolic lik + // THEN run everything in linked mode + if (isLinkedMode() || !fs.existsSync(resolvedJsDir)) { + console.log('Running in local/linked mode'); + // This bin is used for cli executed internally + var tsProjectPath = path.resolve(__dirname, '../tsconfig.json'); + require('ts-node').register({ + project: tsProjectPath, + transpileOnly: true, + }); + + includeInternalScripts = true; + return resolvedTsDir; + } + + // The default entrypoint must exist, return it now. + return resolvedJsDir; +}; + +require(entrypoint()).run(includeInternalScripts); diff --git a/packages/grafana-toolkit/config/circleci/config.yml b/packages/grafana-toolkit/config/circleci/config.yml new file mode 100644 index 00000000..d1438c2b --- /dev/null +++ b/packages/grafana-toolkit/config/circleci/config.yml @@ -0,0 +1,295 @@ +version: 2.1 + +parameters: + ssh-fingerprint: + type: string + default: ${GITHUB_SSH_FINGERPRINT} + +aliases: + # Workflow filters + - &filter-only-master + branches: + only: master + - &filter-only-release + branches: + only: /^v[1-9]*[0-9]+\.[1-9]*[0-9]+\.x$/ + +workflows: + plugin_workflow: + jobs: + - yarn_install + - build_docs: + requires: + - yarn_install + - build_frontend: + requires: + - yarn_install + - build_backend: + requires: + - yarn_install + - package: + requires: + - build_frontend + - build_backend + - build_docs + - provisioning: + requires: + - build_frontend + - build_backend + - build_docs + - e2e_canary: + requires: + - provisioning + - package + - report: + requires: + - package + - e2e_canary + - approve_release: + type: approval + requires: + - report + filters: *filter-only-release + - publish_github_release: + requires: + - approve_release + filters: *filter-only-release + +executors: + default_exec: # declares a reusable executor + docker: + - image: srclosson/grafana-plugin-ci-alpine:latest + e2e_exec: + docker: + - image: srclosson/grafana-plugin-ci-e2e:latest + +jobs: + yarn_install: + executor: default_exec + steps: + - checkout + - restore_cache: + name: restore yarn cache + keys: + - build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - run: + name: Install dependencies + command: | + mkdir ci + yarn bin grafana-toolkit ] || yarn install --immutable + - save_cache: + name: save yarn cache + paths: + - ~/project/.yarn + key: build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - save_cache: + name: save cypress cache + paths: + - ~/.cache/Cypress + key: cypress-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + + build_docs: + executor: default_exec + steps: + - checkout + - restore_cache: + name: restore yarn cache + keys: + - build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - run: + name: Build docs + command: | + yarn run grafana-toolkit plugin:ci-docs + [ -d "dist" ] || circleci-agent step halt + - persist_to_workspace: + root: . + paths: + - dist + + build_frontend: + executor: default_exec + steps: + - checkout + - restore_cache: + name: restore yarn cache + keys: + - build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - run: + name: Build and test frontend + command: yarn run grafana-toolkit plugin:ci-build + - persist_to_workspace: + root: . + paths: + - dist + + build_backend: + executor: default_exec + steps: + - checkout + - restore_cache: + name: restore yarn cache + keys: + - build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - run: + name: Exit if no backend + command: | + [ -f "Magefile.go" ] || circleci-agent step halt + - run: + name: Build backend + command: mage -v buildAll + - run: + name: Test backend + command: | + mage -v lint + mage -v coverage + - persist_to_workspace: + root: . + paths: + - dist + + package: + executor: default_exec + steps: + - checkout + - restore_cache: + name: restore yarn cache + keys: + - build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - attach_workspace: + at: . + - run: + name: Move results to ci folder + command: yarn run grafana-toolkit plugin:ci-build --finish + - run: + name: Package distribution + command: | + yarn run grafana-toolkit plugin:ci-package + - persist_to_workspace: + root: . + paths: + - ci/jobs/package + - ci/packages + - ci/dist + - ci/grafana-test-env + - store_artifacts: + path: ci + + provisioning: + executor: default_exec + steps: + - run: + name: Continue if this plugin has a provisioning path + command: | + [ -z "${PROVISIONING_REPO_PATH}" ] && circleci-agent step halt + - checkout + - add_ssh_keys: + fingerprints: + - << pipeline.parameters.ssh-fingerprint >> + - run: + name: Checkout provisioning files + command: git clone --depth 1 git@github.com:grafana/plugin-provisioning.git + - run: + name: Prepare task output dir + command: | + mkdir ci # Avoid error if not exists + mkdir ci/jobs # Avoid error if not exists + mkdir ci/jobs/provisioning + mv plugin-provisioning/${PROVISIONING_REPO_PATH}/* ci/jobs/provisioning + - persist_to_workspace: + root: . + paths: + - ci/jobs/provisioning + + e2e_canary: + executor: e2e_exec + steps: + - run: + name: Continue if this plugin has a provisioning path + command: | + [ -z "${PROVISIONING_REPO_PATH}" ] && circleci-agent step halt + - checkout + - attach_workspace: + at: . + - restore_cache: + name: Restore yarn cache + keys: + - build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - restore_cache: + name: Restore cypress cache + keys: + - cypress-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - run: + name: Exit if no e2e tests configured + command: | + [ -d cypress ] || circleci-agent step halt + - run: + name: Setup Grafana (local install) + command: | + ginstall canary + /opt/grafana/bin/grafana-server -config ci/grafana-test-env/custom.ini -homepath /opt/grafana & + ## To make sure grafana has started up + while ! $(netstat -tulpn | grep 3000 >/dev/null 2>&1); do sleep 1; done + /opt/grafana/bin/grafana-cli --version + - run: + name: Copy provisioning files + command: cp -r ci/jobs/provisioning provisioning/ + - run: + name: Run e2e tests + command: | + # If the tests fail, but GRAFANACI_STRICT_E2E=0, don't worry about it + yarn run grafana-e2e run \ + || ( + [ "$GRAFANACI_STRICT_E2E" -eq 0 ] && echo "Bypassing fail. ci-nostrict enabled" + ) + - run: + when: always + name: Prepare task output dir + command: | + # TODO: probably move all of this to `@grafana/toolkit plugin:ci-test` + mkdir ci/jobs/e2e_canary + # only copy if they exist + cp cypress/screenshots/*.* ci/jobs/e2e_canary 2>/dev/null || : + cp cypress/videos/*.* ci/jobs/e2e_canary 2>/dev/null || : + - persist_to_workspace: + root: . + paths: + - ci/jobs/e2e_canary + - store_test_results: + path: ci/jobs/e2e_canary + - store_artifacts: + path: ci/jobs/e2e_canary + + report: + executor: default_exec + steps: + - checkout + - attach_workspace: + at: . + - restore_cache: + name: restore yarn cache + keys: + - build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - run: + name: Toolkit report + command: | + yarn run grafana-toolkit plugin:ci-report + - store_artifacts: + path: ci + + publish_github_release: + executor: default_exec + steps: + - checkout + - add_ssh_keys: + fingerprints: + - "dc:60:ab:c7:2d:8c:82:50:2a:2a:97:1a:c0:66:83:14" + - attach_workspace: + at: . + - restore_cache: + name: restore yarn cache + keys: + - build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - run: + name: "Publish Release on GitHub" + command: | + yarn run grafana-toolkit plugin:github-publish diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/Dockerfile b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/Dockerfile new file mode 100644 index 00000000..7365693e --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:3.15.0 + +USER root + +COPY scripts scripts +COPY install /usr/local + +WORKDIR scripts + +RUN ./deploy.sh diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/README.md b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/README.md new file mode 100644 index 00000000..94b42aef --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/README.md @@ -0,0 +1,71 @@ +# Using this docker image + +Uploaded to dockerhub as grafana/grafana-plugin-ci:latest-alpine + +Based off of `circleci/node:12-browsers` + +## User + +The user will be `circleci` +The home directory will be `/home/circleci` + +## Node + +- node 12 is installed +- yarn is installed globally +- npm is installed globally + +## Go + +- Go is installed in `/usr/local/bin/go` +- golangci-lint is installed in `/usr/local/bin/golangci-lint` +- mage is installed in `/home/circleci/go/bin/mage` + +All of the above directories are in the path, so there is no need to specify fully qualified paths. + +## Grafana + +- Installed in `/home/circleci/src/grafana` +- `yarn install` has been run + +## Integration/Release Testing + +There are 4 previous versions pre-downloaded to /usr/local/grafana. These versions are: + +1. 6.6.2 +2. 6.5.3 +3. 6.4.5 +4. 6.3.7 + +To test, your CircleCI config will need a run section with something similar to the following + +``` +- run: + name: Setup Grafana (local install) + command: | + sudo dpkg -i /usr/local/grafana/deb/grafana_6.6.2_amd64.deb + sudo cp ci/grafana-test-env/custom.ini /usr/share/grafana/conf/custom.ini + sudo cp ci/grafana-test-env/custom.ini /etc/grafana/grafana.ini + sudo service grafana-server start + grafana-cli --version +``` + +# Building + +To build, cd to `/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine` + +``` +./build.sh +``` + +# Developing/Testing + +To test, you should have docker-compose installed. + +``` +cd test +./start.sh +``` + +You will be in /home/circleci/test with the buildscripts installed to the local directory. +Do your edits/run tests. When saving, your edits will be available in the container immediately. diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/build.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/build.sh new file mode 100755 index 00000000..f024e617 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/build.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -eo pipefail + +source ./common.sh + +# +# No longer required, but useful to keep just in case we want to deploy +# changes in toolkit directly to the docker image +# +if [ -n "$INCLUDE_TOOLKIT" ]; then + /bin/rm -rfv install/grafana-toolkit + mkdir -pv install/grafana-toolkit + cp -rv ../../bin install/grafana-toolkit + cp -rv ../../src install/grafana-toolkit + cp -v ../../package.json install/grafana-toolkit + cp -v ../../tsconfig.json install/grafana-toolkit +fi + +docker build -t ${DOCKER_IMAGE_NAME} . +docker push $DOCKER_IMAGE_NAME + +[ -n "$INCLUDE_TOOLKIT" ] && /bin/rm -rfv install/grafana-toolkit diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/common.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/common.sh new file mode 100755 index 00000000..679a6f41 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/common.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +## +## Common variable declarations +## + +DOCKER_IMAGE_NAME="grafana/grafana-plugin-ci:1.3.0-alpine" diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/cp b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/cp new file mode 100755 index 00000000..fd23c3db --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/cp @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ "$1" == "-rn" ]; then + false | busybox cp -i -r "$2" "$3" 2>/dev/null +else + busybox cp $* +fi diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/ginstall b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/ginstall new file mode 100755 index 00000000..537305a1 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/ginstall @@ -0,0 +1,73 @@ +#!/bin/sh +## +# gget +# A script to get and install grafana versions +# for usage information see "show_help" below. +# + +latest=$(wget -O - 'https://raw.githubusercontent.com/grafana/grafana/main/latest.json' | jq -r '.stable') +canary=$(wget -O - "https://grafana.com/api/grafana/versions" | jq ".items[0].version" | tr -d '"') + +show_help() { + echo "Usage: gget " + echo "" + echo "where can be:" + echo " 1) A version from https://grafana.com/grafana/download (ex x.y.z)" + echo " 2) latest (currently $latest)" + echo " 3) canary (currently $canary)" + echo "" + echo " -h, --help: Display this help message" + echo "" + exit 0 +} + +opts=$(getopt -o h --long help -n 'gget' -- "$@") +[ $? -eq 0 ] || { + show_help +} + +eval set -- "$opts" +while true; do + case "$1" in + -h | --help) + show_help + ;; + --) + shift + break + ;; + *) + break + ;; + esac + shift +done + +[ -z "$1" ] && show_help + +# Make sure the script is being run as root +if [ $EUID -ne 0 ]; then + echo "This script must be run as root" + exit 1 +fi + +## +# MAIN +# +# Enough setup, let's actually do something +# +version=$1 +if [ "$version" == "latest" ]; then + version="$latest" + wget -O - "https://dl.grafana.com/oss/release/grafana-${version}.linux-amd64.tar.gz" | tar -C /opt -zxf - +elif [ "$version" == "canary" ]; then + version="$canary" + wget -O - "https://dl.grafana.com/oss/main/grafana-${version}.linux-amd64.tar.gz" | tar -C /opt -zxf - +else + wget -O - "https://dl.grafana.com/oss/release/grafana-${version}.linux-amd64.tar.gz" | tar -C /opt -zxf - +fi + +/bin/rm -rf /opt/grafana > /dev/null 2>&1 || true +ln -s /opt/grafana-${version} /opt/grafana + +# nohup /opt/grafana/bin/grafana-server -config /opt/grafana/conf/defaults.ini -homepath /opt/grafana >/dev/null 2>&1 & diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/githubRelease.js b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/githubRelease.js new file mode 100644 index 00000000..c6f42f71 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/githubRelease.js @@ -0,0 +1,153 @@ +'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); +var tslib_1 = require('tslib'); +var getPluginId_1 = require('../../config/utils/getPluginId'); +var pluginValidation_1 = require('../../config/utils/pluginValidation'); +var env_1 = require('../../plugins/env'); +var path = require('path'); +var fs = require('fs'); +// @ts-ignore +// import execa = require('execa'); +var githubClient_1 = tslib_1.__importDefault(require('./githubClient')); +var resolveContentType = function (extension) { + if (extension.startsWith('.')) { + extension = extension.substr(1); + } + switch (extension) { + case 'zip': + return 'application/zip'; + case 'json': + return 'application/json'; + case 'sha1': + return 'text/plain'; + default: + return 'application/octet-stream'; + } +}; +var GitHubRelease = /** @class */ (function () { + function GitHubRelease(token, username, repository, releaseNotes, commitHash) { + this.token = token; + this.username = username; + this.repository = repository; + this.releaseNotes = releaseNotes; + this.commitHash = commitHash; + this.git = new githubClient_1.default({ + required: true, + repo: repository, + }); + } + GitHubRelease.prototype.publishAssets = function (srcLocation, destUrl) { + var _this = this; + // Add the assets. Loop through files in the ci/dist folder and upload each asset. + var files = fs.readdirSync(srcLocation); + return files.map(function (file) { + return tslib_1.__awaiter(_this, void 0, void 0, function () { + var fileStat, fileData; + return tslib_1.__generator(this, function (_a) { + fileStat = fs.statSync(srcLocation + '/' + file); + fileData = fs.readFileSync(srcLocation + '/' + file); + return [ + 2 /*return*/, + this.git.client.post(destUrl + '?name=' + file, fileData, { + headers: { + 'Content-Type': resolveContentType(path.extname(file)), + 'Content-Length': fileStat.size, + }, + maxContentLength: fileStat.size * 2 * 1024 * 1024, + }), + ]; + }); + }); + }); + }; + GitHubRelease.prototype.release = function () { + var _a, _b, _c, _d; + return tslib_1.__awaiter(this, void 0, void 0, function () { + var ciDir, + distDir, + distContentDir, + pluginJsonFile, + pluginInfo, + PUBLISH_DIR, + commitHash, + latestRelease, + reason_1, + newReleaseResponse, + publishPromises, + reason_2; + return tslib_1.__generator(this, function (_e) { + switch (_e.label) { + case 0: + ciDir = env_1.getCiFolder(); + distDir = path.resolve(ciDir, 'dist'); + distContentDir = path.resolve(distDir, getPluginId_1.getPluginId()); + pluginJsonFile = path.resolve(distContentDir, 'plugin.json'); + pluginInfo = pluginValidation_1.getPluginJson(pluginJsonFile).info; + PUBLISH_DIR = path.resolve(env_1.getCiFolder(), 'packages'); + commitHash = this.commitHash || ((_a = pluginInfo.build) === null || _a === void 0 ? void 0 : _a.hash); + _e.label = 1; + case 1: + _e.trys.push([1, 5, , 6]); + return [4 /*yield*/, this.git.client.get('releases/tags/v' + pluginInfo.version)]; + case 2: + latestRelease = _e.sent(); + if (!(latestRelease.data.tag_name === 'v' + pluginInfo.version)) { + return [3 /*break*/, 4]; + } + return [4 /*yield*/, this.git.client.delete('releases/' + latestRelease.data.id)]; + case 3: + _e.sent(); + _e.label = 4; + case 4: + return [3 /*break*/, 6]; + case 5: + reason_1 = _e.sent(); + if (reason_1.response.status !== 404) { + // 404 just means no release found. Not an error. Anything else though, re throw the error + throw reason_1; + } + return [3 /*break*/, 6]; + case 6: + _e.trys.push([6, 9, , 10]); + return [ + 4 /*yield*/, + this.git.client.post('releases', { + tag_name: 'v' + pluginInfo.version, + target_commitish: commitHash, + name: 'v' + pluginInfo.version, + body: this.releaseNotes, + draft: false, + prerelease: false, + }), + ]; + case 7: + newReleaseResponse = _e.sent(); + publishPromises = this.publishAssets( + PUBLISH_DIR, + 'https://uploads.github.com/repos/' + + this.username + + '/' + + this.repository + + '/releases/' + + newReleaseResponse.data.id + + '/assets' + ); + return [4 /*yield*/, Promise.all(publishPromises)]; + case 8: + _e.sent(); + return [3 /*break*/, 10]; + case 9: + reason_2 = _e.sent(); + console.log(reason_2); + // Rethrow the error so that we can trigger a non-zero exit code to circle-ci + throw reason_2; + case 10: + return [2 /*return*/]; + } + }); + }); + }; + return GitHubRelease; +})(); +exports.GitHubRelease = GitHubRelease; +//# sourceMappingURL=githubRelease.js.map7027e10521e9 diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy-common.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy-common.sh new file mode 100755 index 00000000..92636913 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy-common.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +## +# Script to deploy a docker image. Must return exit code 0 +# +do_exit() { + message="$1" + exit_code="$2" + + echo "$message" + exit $exit_code +} + + +## +# Get file, get's a file, validates the SHA +# @param filename +# @param expected sha value +# @returns 0 if successful, -1 of checksum validation failed. +# +get_file () { + [ -n "$1" ] && url=$1 || do_exit "url required" 1 + [ -n "$2" ] && dest=$2 || do_exit "destination required" 2 + sha=$3 + file=$(basename $dest) + + curl -fL "${url}" -o "$dest" + if [ -n "$sha" ]; then + echo "$sha $dest" | sha256sum || do_exit "Checksum validation failed for $file. Exiting" 1 + fi +} + +untar_file () { + [ -n "$1" ] && src=$1 || do_exit "src required" 1 + [ -n "$2" ] && dest=$2 || dest="/usr/local" + + tar -C "$dest" -xf "$src" && /bin/rm -rf "$src" +} + +## +# WIP: Just started this and not finished. +# The intent it to download a release from a git repo, +# compile, and install +get_latest_release () { + tarsrc=$(curl -sL "https://api.github.com/repos/$1/$2/releases/latest" | jq ".tarball_url" | tr -d '"') + curl -fL -o /tmp/autoretrieved.tar.gz "$tarsrc" + origdir=$PWD + reponame=$(tar zxvf autoretrieved.tar.gz | tail -1 | awk -F / '{print $1}') + cd "/tmp/$reponame" + #perform compile + cd $origdir +} diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy-user.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy-user.sh new file mode 100755 index 00000000..f8926ec4 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy-user.sh @@ -0,0 +1,3 @@ +#!/bin/sh +source "./deploy-common.sh" + diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy.sh new file mode 100755 index 00000000..e1a5fb6c --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/scripts/deploy.sh @@ -0,0 +1,80 @@ +#!/bin/sh +set -eo pipefail + +source "./deploy-common.sh" + +# Make libgcc compatible +mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 + +# Replace cp with something that mocks the one that ci-package needs +rm /bin/cp +mv /usr/local/bin/cp /bin/cp + +apk add --no-cache curl npm yarn build-base openssh git-lfs perl-utils coreutils python3 + +# +# Only relevant for testing, but cypress does not work with musl/alpine. +# +# apk add --no-cache xvfb glib nss nspr gdk-pixbuf "gtk+3.0" pango atk cairo dbus-libs libxcomposite libxrender libxi libxtst libxrandr libxscrnsaver alsa-lib at-spi2-atk at-spi2-core cups-libs gcompat libc6-compat + +# Install Go +filename="go1.17.linux-amd64.tar.gz" +get_file "https://dl.google.com/go/$filename" "/tmp/$filename" "6bf89fc4f5ad763871cf7eac80a2d594492de7a818303283f1366a7f6a30372d" +untar_file "/tmp/$filename" + +# Install golangci-lint +GOLANGCILINT_VERSION=1.37.1 +filename="golangci-lint-${GOLANGCILINT_VERSION}-linux-amd64" +get_file "https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCILINT_VERSION}/$filename.tar.gz" \ + "/tmp/$filename.tar.gz" \ + "1929425d7733d136b342395c77f171d459aa89b198933465ec4c854aa34c41a2" +untar_file "/tmp/$filename.tar.gz" +ln -s /usr/local/${filename}/golangci-lint /usr/local/bin/golangci-lint +ln -s /usr/local/go/bin/go /usr/local/bin/go +ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt +chmod 755 /usr/local/bin/golangci-lint + +# Install dependencies +apk add --no-cache fontconfig zip jq + +# Install code climate +get_file "https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64" \ + "/usr/local/bin/cc-test-reporter" \ + "e1be1930379bd169d3a8e82135cf57216ad52ecfaf520b5804f269721e4dcc3d" +chmod 755 /usr/local/bin/cc-test-reporter + +curl -fL -o /usr/local/bin/grabpl "https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl" + +apk add --no-cache git +# Install Mage +mkdir -pv /tmp/mage $HOME/go/bin +git clone https://github.com/magefile/mage.git /tmp/mage +cd /tmp/mage && go run bootstrap.go +mv $HOME/go/bin/mage /usr/local/bin + +wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b /usr/local/bin v2.2.0 + +source "/etc/profile" +sh -l -c "go get -u github.com/mgechev/revive" +for file in $(ls $HOME/go/bin); do + mv -v $HOME/go/bin/$file /usr/local/bin/$file +done + +# Install grafana-toolkit deps +current_dir=$PWD +cd /usr/local/grafana-toolkit && yarn install && cd $current_dir +ln -s /usr/local/grafana-toolkit/bin/grafana-toolkit.js /usr/local/bin/grafana-toolkit + +GOOGLE_SDK_VERSION=365.0.1 +GOOGLE_SDK_CHECKSUM=17003cdba67a868c2518ac16efa60dc6175533b7a9fb87304459784308e30fb0 + +curl -fLO https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${GOOGLE_SDK_VERSION}-linux-x86_64.tar.gz +echo "${GOOGLE_SDK_CHECKSUM} google-cloud-sdk-${GOOGLE_SDK_VERSION}-linux-x86_64.tar.gz" | sha256sum --check --status +tar xvzf google-cloud-sdk-${GOOGLE_SDK_VERSION}-linux-x86_64.tar.gz -C /opt +rm google-cloud-sdk-${GOOGLE_SDK_VERSION}-linux-x86_64.tar.gz +ln -s /opt/google-cloud-sdk/bin/gsutil /usr/bin/gsutil +ln -s /opt/google-cloud-sdk/bin/gcloud /usr/bin/gcloud + +# Cleanup after yourself +/bin/rm -rf /tmp/mage +/bin/rm -rf $HOME/go diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/test/docker-compose.yml b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/test/docker-compose.yml new file mode 100644 index 00000000..9a3e53f2 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/test/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3' +services: + citest: + image: "amd64/alpine" + user: root + volumes: + - ../scripts:/home/circleci/scripts + - ../install:/home/circleci/install + - ${HOME}/.ssh:/root/.ssh + - ../../..:/home/circleci/grafana-toolkit + cibuilt: + image: "grafana/grafana-plugin-ci:latest-alpine" + user: root + volumes: + - ../scripts:/home/circleci/scripts + - ../install:/home/circleci/install + - ${HOME}/.ssh:/root/.ssh + - ../../..:/home/circleci/grafana-toolkit diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/test/start.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/test/start.sh new file mode 100755 index 00000000..f5551eb3 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/test/start.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +function finish { + echo "Exiting and cleaning up docker image" + docker-compose down +} +trap finish EXIT + +# Enter the docker container +if [ "$1" = "built" ]; then + docker-compose run cibuilt sh -c "cd /home/circleci; exec sh --login -i" +else + docker-compose run citest sh -c "cd /home/circleci; exec sh --login -i" +fi diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/Dockerfile b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/Dockerfile new file mode 100644 index 00000000..6aa2682c --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/Dockerfile @@ -0,0 +1,9 @@ +FROM debian:buster-slim + +ENV DEBIAN_FRONTEND=noninteractive + +COPY scripts scripts +COPY install /usr/local + +RUN cd scripts && ./deploy.sh +ENV DEBIAN_FRONTEND=newt diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/README.md b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/README.md new file mode 100644 index 00000000..1b37557a --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/README.md @@ -0,0 +1,67 @@ +# Using this docker image + +## User + +The user will be `circleci` +The home directory will be `/home/circleci` + +## Node + +- node 14 is installed +- yarn is installed globally +- npm is installed globally + +## Go + +- Go is installed in `/usr/local/bin/go` +- golangci-lint is installed in `/usr/local/bin/golangci-lint` +- mage is installed in `/usr/local/bin/mage` + +All of the above directories are in the path, so there is no need to specify fully qualified paths. + +## Grafana + +- Installed in `/home/circleci/src/grafana` +- `yarn install` has been run + +## Integration/Release Testing + +There are 4 previous versions pre-downloaded to /usr/local/grafana. These versions are: + +1. 6.6.2 +2. 6.5.3 +3. 6.4.5 +4. 6.3.7 + +To test, your CircleCI config will need a run section with something similar to the following + +``` +- run: + name: Setup Grafana (local install) + command: | + sudo dpkg -i /usr/local/grafana/deb/grafana_6.6.2_amd64.deb + sudo cp ci/grafana-test-env/custom.ini /usr/share/grafana/conf/custom.ini + sudo cp ci/grafana-test-env/custom.ini /etc/grafana/grafana.ini + sudo service grafana-server start + grafana-cli --version +``` + +# Building + +To build, cd to `/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e` + +``` +./build.sh +``` + +# Developing/Testing + +To test, you should have docker-compose installed. + +``` +cd test +./start.sh +``` + +You will be in /home/circleci/test with the buildscripts installed to the local directory. +Do your edits/run tests. When saving, your edits will be available in the container immediately. diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/build.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/build.sh new file mode 100755 index 00000000..14ca02a1 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/build.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -eo pipefail + +source ./common.sh + +# +# No longer required, but useful to keep just in case we want to deploy +# changes in toolkit directly to the docker image +# +if [ -n "$INCLUDE_TOOLKIT" ]; then + /bin/rm -rfv install/grafana-toolkit + mkdir -pv install/grafana-toolkit + cp -rv ../../bin install/grafana-toolkit + cp -rv ../../src install/grafana-toolkit + cp -v ../../package.json install/grafana-toolkit + cp -v ../../tsconfig.json install/grafana-toolkit +fi + +docker build -t ${DOCKER_IMAGE_NAME} . +docker push $DOCKER_IMAGE_NAME +docker tag ${DOCKER_IMAGE_NAME} ${DOCKER_IMAGE_BASE_NAME}:latest +docker push ${DOCKER_IMAGE_BASE_NAME}:latest + +[ -n "$INCLUDE_TOOLKIT" ] && /bin/rm -rfv install/grafana-toolkit diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/common.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/common.sh new file mode 100755 index 00000000..2e72f98a --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/common.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +## +## Common variable declarations +## + +DOCKER_IMAGE_BASE_NAME="grafana/grafana-plugin-ci-e2e" +DOCKER_IMAGE_VERSION="1.3.0" +DOCKER_IMAGE_NAME="${DOCKER_IMAGE_BASE_NAME}:${DOCKER_IMAGE_VERSION}" diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/install/ginstall b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/install/ginstall new file mode 100755 index 00000000..ce7e8953 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/install/ginstall @@ -0,0 +1,73 @@ +#!/bin/bash +## +# gget +# A script to get and install grafana versions +# for usage information see "show_help" below. +# + +latest=$(wget -O - 'https://raw.githubusercontent.com/grafana/grafana/main/latest.json' | jq -r '.stable') +canary=$(wget -O - "https://grafana.com/api/grafana/versions" | jq ".items[0].version" | tr -d '"') + +show_help() { + echo "Usage: gget " + echo "" + echo "where can be:" + echo " 1) A version from https://grafana.com/grafana/download (ex x.y.z)" + echo " 2) latest (currently $latest)" + echo " 3) canary (currently $canary)" + echo "" + echo " -h, --help: Display this help message" + echo "" + exit 0 +} + +opts=$(getopt -o h --long help -n 'gget' -- "$@") +[ $? -eq 0 ] || { + show_help +} + +eval set -- "$opts" +while true; do + case "$1" in + -h | --help) + show_help + ;; + --) + shift + break + ;; + *) + break + ;; + esac + shift +done + +[ -z "$1" ] && show_help + +# Make sure the script is being run as root +if [ $EUID -ne 0 ]; then + echo "This script must be run as root" + exit 1 +fi + +## +# MAIN +# +# Enough setup, let's actually do something +# +version=$1 +if [ "$version" == "latest" ]; then + version="$latest" + wget -O - "https://dl.grafana.com/oss/release/grafana-${version}.linux-amd64.tar.gz" | tar -C /opt -zxf - +elif [ "$version" == "canary" ]; then + version="$canary" + wget -O - "https://dl.grafana.com/oss/main/grafana-${version}.linux-amd64.tar.gz" | tar -C /opt -zxf - +else + wget -O - "https://dl.grafana.com/oss/release/grafana-${version}.linux-amd64.tar.gz" | tar -C /opt -zxf - +fi + +/bin/rm -rf /opt/grafana > /dev/null 2>&1 || true +ln -s /opt/grafana-${version} /opt/grafana + +# nohup /opt/grafana/bin/grafana-server -config /opt/grafana/conf/defaults.ini -homepath /opt/grafana >/dev/null 2>&1 & diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-common.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-common.sh new file mode 100755 index 00000000..af585d2e --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-common.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +## +# Script to deploy a docker image. Must return exit code 0 +# +do_exit() { + message="$1" + exit_code="$2" + + echo "$message" + exit $exit_code +} + +## +# Get file, get's a file, validates the SHA +# @param filename +# @param expected sha value +# @returns 0 if successful, -1 of checksum validation failed. +# +get_file () { + [ -n "$1" ] && url=$1 || do_exit "url required" -1 + [ -n "$2" ] && dest=$2 || do_exit "destination required" -2 + sha=$3 + file=$(basename $dest) + + wget "$url" -O "$dest" + if [ -n "$sha" ]; then + echo "$sha $dest" | sha256sum --check --status || do_exit "Checksum validation failed for $file. Exiting" -1 + fi +} + +untar_file () { + [ -n "$1" ] && src=$1 || do_exit "src required" -1 + [ -n "$2" ] && dest=$2 || dest="/usr/local" + + tar -C "$dest" -xf "$src" && /bin/rm -rf "$src" +} diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-slim.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-slim.sh new file mode 100755 index 00000000..9c3c0a31 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-slim.sh @@ -0,0 +1,27 @@ +#!/bin/bash +source "/etc/profile" + +apt-get --allow-insecure-repositories update +apt-get install --allow-unauthenticated -y \ + build-essential \ + wget git sudo adduser \ + libfontconfig1 \ + locate \ + libnss3 libnspr4 \ + libgdk-pixbuf2.0-0 \ + libgtk-3-0 \ + libpangocairo-1.0-0 \ + libpango-1.0-0 \ + libatk1.0-0 \ + libcairo2 \ + libdbus-1-3 \ + libxcomposite1 libxrender1 libxcursor1 libxi6 libxtst6 libxrandr2 libxss1 xauth xvfb \ + libasound2 \ + libatk-bridge2.0-0 \ + libatspi2.0-0 \ + libcups2 \ + jq net-tools git-lfs unzip pkg-config zip \ + libaio1 libaio-dev \ + netcat \ + libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb + diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-user.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-user.sh new file mode 100755 index 00000000..08f2b7b9 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy-user.sh @@ -0,0 +1,3 @@ +#!/bin/bash +source "./deploy-common.sh" + diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy.sh new file mode 100755 index 00000000..cdd3d4ab --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/scripts/deploy.sh @@ -0,0 +1,65 @@ +#!/bin/bash +set -eo pipefail + +source "/etc/profile" +source "./deploy-slim.sh" +source "./deploy-common.sh" + +NODEVER="v14.17.3" +# Install Node +wget -O - "https://nodejs.org/dist/${NODEVER}/node-${NODEVER}-linux-x64.tar.xz" | tar Jvxf - -C "/tmp" + +# Move node to /usr/local so it's in the path +pushd /tmp/node-${NODEVER}-linux-x64 +/bin/rm -f CHANGELOG.md README.md LICENSE +/bin/cp -r * /usr/local +popd +/bin/rm -rf /tmp/node-${NODEVER} + +# Resource the profile so we know our path is being honoured +source "/etc/profile" +# Install Yarn. Not in the path yet so fully qualified +npm i -g yarn + +# Install Go +filename="go1.17.linux-amd64.tar.gz" +get_file "https://dl.google.com/go/$filename" "/tmp/$filename" "6bf89fc4f5ad763871cf7eac80a2d594492de7a818303283f1366a7f6a30372d" +untar_file "/tmp/$filename" + +# Install golangci-lint +GOLANGCILINT_VERSION=1.37.1 +filename="golangci-lint-${GOLANGCILINT_VERSION}-linux-amd64" +get_file "https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCILINT_VERSION}/$filename.tar.gz" \ + "/tmp/$filename.tar.gz" \ + "1929425d7733d136b342395c77f171d459aa89b198933465ec4c854aa34c41a2" +untar_file "/tmp/$filename.tar.gz" +ln -s /usr/local/${filename}/golangci-lint /usr/local/bin/golangci-lint +ln -s /usr/local/go/bin/go /usr/local/bin/go +ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt +chmod 755 /usr/local/bin/golangci-lint + +# Install code climate +get_file "https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64" \ + "/usr/local/bin/cc-test-reporter" \ + "5e72323531a2d1842d81ec784a2b4ed789cc9c8ecf0213d4f701855fa13d1bfb" +chmod 755 /usr/local/bin/cc-test-reporter + +wget -O /usr/local/bin/grabpl "https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl" +chmod +x /usr/local/bin/grabpl + +# Install Mage +mkdir -pv /tmp/mage $HOME/go/bin +git clone https://github.com/magefile/mage.git /tmp/mage +pushd /tmp/mage && go run bootstrap.go && popd +mv $HOME/go/bin/mage /usr/local/bin +# Cleanup after yourself +/bin/rm -rf /tmp/mage +/bin/rm -rf $HOME/go + +# add cypress +yarn global add cypress +# verify cypress install +cypress verify + +# Get the size down +/bin/rm -rf /var/lib/apt/lists diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/test/docker-compose.yml b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/test/docker-compose.yml new file mode 100644 index 00000000..5d6297c4 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/test/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3' +services: + citest: + image: "debian:buster-slim" + user: root + volumes: + - ../scripts:/root/scripts + - ../install:/root/install + - ${HOME}/.ssh:/root/.ssh + - ../../..:/root/grafana-toolkit + cibuilt: + image: "grafana/grafana-plugin-ci-e2e" + user: root + volumes: + - ../scripts:/root/scripts + - ../install:/root/install + - ${HOME}/.ssh:/root/.ssh + - ../../..:/root/grafana-toolkit diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/test/start.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/test/start.sh new file mode 100755 index 00000000..2552c964 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e/test/start.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +function finish { + echo "Exiting and cleaning up docker image" + docker-compose down +} +trap finish EXIT + +# Enter the docker container +if [ "$1" = "built" ]; then + docker-compose run cibuilt sh -c "cd /root; exec bash --login -i" +else + docker-compose run citest sh -c "cd /root; exec bash --login -i" +fi diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/Dockerfile b/packages/grafana-toolkit/docker/grafana-plugin-ci/Dockerfile new file mode 100644 index 00000000..46228193 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/Dockerfile @@ -0,0 +1,8 @@ +FROM debian:testing-20210111-slim +USER root +COPY scripts scripts +WORKDIR scripts +RUN apt-get update && \ + apt-get install -y wget && \ + ./deploy.sh +COPY install/gget /usr/local/bin/gget diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/README.md b/packages/grafana-toolkit/docker/grafana-plugin-ci/README.md new file mode 100644 index 00000000..18bc1aec --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/README.md @@ -0,0 +1,71 @@ +# Using this docker image + +Currently tagged and uploaded to dockerhub as srclosson/integrations-ci-build + +Based off of `circleci/node:12-browsers` + +## User + +The user will be `circleci` +The home directory will be `/home/circleci` + +## Node + +- node 12 is installed +- yarn is installed globally +- npm is installed globally + +## Go + +- Go is installed in `/usr/local/bin/go` +- golangci-lint is installed in `/usr/local/bin/golangci-lint` +- mage is installed in `/home/circleci/go/bin/mage` + +All of the above directories are in the path, so there is no need to specify fully qualified paths. + +## Grafana + +- Installed in `/home/circleci/src/grafana` +- `yarn install` has been run + +## Integration/Release Testing + +There are 4 previous versions pre-downloaded to /usr/local/grafana. These versions are: + +1. 6.6.2 +2. 6.5.3 +3. 6.4.5 +4. 6.3.7 + +To test, your CircleCI config will need a run section with something similar to the following + +``` +- run: + name: Setup Grafana (local install) + command: | + sudo dpkg -i /usr/local/grafana/deb/grafana_6.6.2_amd64.deb + sudo cp ci/grafana-test-env/custom.ini /usr/share/grafana/conf/custom.ini + sudo cp ci/grafana-test-env/custom.ini /etc/grafana/grafana.ini + sudo service grafana-server start + grafana-cli --version +``` + +# Building + +To build, cd to `/packages/grafana-toolkit/docker/grafana-plugin-ci` + +``` +./build.sh +``` + +# Developing/Testing + +To test, you should have docker-compose installed. + +``` +cd test +./start.sh +``` + +You will be in /home/circleci/test with the buildscripts installed to the local directory. +Do your edits/run tests. When saving, your edits will be available in the container immediately. diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/build.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci/build.sh new file mode 100755 index 00000000..3d8d3d71 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/build.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -eo pipefail + +source ./common.sh + +docker build -t ${DOCKER_IMAGE_NAME} . +docker push $DOCKER_IMAGE_NAME + diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/common.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci/common.sh new file mode 100755 index 00000000..ebd1e7ad --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/common.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +## +## Common variable declarations +## + +DOCKER_IMAGE_NAME="grafana/grafana-plugin-ci:1.2.0" diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/install/gget b/packages/grafana-toolkit/docker/grafana-plugin-ci/install/gget new file mode 100755 index 00000000..3e38e2d5 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/install/gget @@ -0,0 +1,63 @@ +#!/bin/bash +## +# gget +# A script to get and install grafana versions +# for usage information see "show_help" below. +# + +latest=$(curl -s 'https://raw.githubusercontent.com/grafana/grafana/main/latest.json' | jq -r '.stable') +canary=$(curl -s "https://grafana.com/api/grafana/versions" | jq ".items[0].version" | tr -d '"') + +show_help() { + echo "Usage: gget " + echo "" + echo "where can be:" + echo " 1) A version from https://grafana.com/grafana/download (ex x.y.z)" + echo " 2) latest (currently $latest)" + echo " 3) canary (currently $canary)" + echo "" + echo " -h, --help: Display this help message" + echo "" + exit 0 +} + +opts=$(getopt -o h --long help -n 'gget' -- "$@") +[ $? -eq 0 ] || { + show_help +} + +eval set -- "$opts" +while true; do + case "$1" in + -h | --help) + show_help + ;; + --) + shift + break + ;; + *) + break + ;; + esac + shift +done + +[ -z "$1" ] && show_help + +# Make sure the script is being run as root +if [ $EUID -ne 0 ]; then + echo "This script must be run as root" + exit 1 +fi + +## +# MAIN +# +# Enough setup, let's actually do something +# +version=$1 +[ "$version" == "latest" ] && version="$latest" +[ "$version" == "canary" ] && version="$canary" +wget "https://dl.grafana.com/oss/release/grafana_${version}_amd64.deb" -O "/tmp/grafana_${version}_amd64.deb" +dpkg -i "/tmp/grafana_${version}_amd64.deb" && /bin/rm -rfv "/tmp/grafana_${version}_amd64.deb" diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy-common.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy-common.sh new file mode 100755 index 00000000..524bb5e4 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy-common.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +## +# Script to deploy a docker image. Must return exit code 0 +# +do_exit() { + message="$1" + exit_code="$2" + + echo "$message" + exit $exit_code +} + + +## +# Get file, get's a file, validates the SHA +# @param filename +# @param expected sha value +# @returns 0 if successful, -1 of checksum validation failed. +# +get_file () { + [ -n "$1" ] && url=$1 || do_exit "url required" -1 + [ -n "$2" ] && dest=$2 || do_exit "destination required" -2 + sha=$3 + file=$(basename $dest) + + wget "$url" -O "$dest" + if [ -n "$sha" ]; then + echo "$sha $dest" | sha256sum --check --status || do_exit "Checksum validation failed for $file. Exiting" -1 + fi +} + +untar_file () { + [ -n "$1" ] && src=$1 || do_exit "src required" -1 + [ -n "$2" ] && dest=$2 || dest="/usr/local" + + tar -C "$dest" -xf "$src" && /bin/rm -rf "$src" +} \ No newline at end of file diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy-user.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy-user.sh new file mode 100755 index 00000000..08f2b7b9 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy-user.sh @@ -0,0 +1,3 @@ +#!/bin/bash +source "./deploy-common.sh" + diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy.sh new file mode 100755 index 00000000..38b944a7 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/scripts/deploy.sh @@ -0,0 +1,57 @@ +#!/bin/bash +source "./deploy-common.sh" + +# Install Go +filename="go1.17.linux-amd64.tar.gz" +get_file "https://dl.google.com/go/$filename" "/tmp/$filename" "6bf89fc4f5ad763871cf7eac80a2d594492de7a818303283f1366a7f6a30372d" +untar_file "/tmp/$filename" + +# Install golangci-lint +GOLANGCILINT_VERSION=1.37.0 +filename="golangci-lint-${GOLANGCILINT_VERSION}-linux-amd64" +get_file "https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCILINT_VERSION}/$filename.tar.gz" \ + "/tmp/$filename.tar.gz" \ + "5fe9852e754b621c5264fb8ac810a75033e7f18e972315a60c5c3f8a37b3cb88" +untar_file "/tmp/$filename.tar.gz" +ln -s /usr/local/${filename}/golangci-lint /usr/local/bin/golangci-lint +ln -s /usr/local/go/bin/go /usr/local/bin/go +ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt +chmod 755 /usr/local/bin/golangci-lint + +# Install dependencies +apt-get update -y && apt-get install -y adduser libfontconfig1 locate && /bin/rm -rf /var/lib/apt/lists/* + +# Install code climate +get_file "https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64" \ + "/usr/local/bin/cc-test-reporter" \ + "e1be1930379bd169d3a8e82135cf57216ad52ecfaf520b5804f269721e4dcc3d" +chmod 755 /usr/local/bin/cc-test-reporter + +wget -O /usr/local/bin/grabpl "https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl" +chmod +x /usr/local/bin/grabpl + +# Install Mage +mkdir -pv /tmp/mage $HOME/go/bin +git clone https://github.com/magefile/mage.git /tmp/mage +pushd /tmp/mage && go run bootstrap.go && popd +mv $HOME/go/bin/mage /usr/local/bin + +GOOGLE_SDK_VERSION=316.0.0 +GOOGLE_SDK_CHECKSUM=96a0b75474dbfa9f3d46dcdec7a4d68a664cb7d57fade5710fe88b1fdf6babb3 + +curl -fLO https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${GOOGLE_SDK_VERSION}-linux-x86_64.tar.gz +echo "${GOOGLE_SDK_CHECKSUM} google-cloud-sdk-${GOOGLE_SDK_VERSION}-linux-x86_64.tar.gz" | sha256sum --check --status +tar xvzf google-cloud-sdk-${GOOGLE_SDK_VERSION}-linux-x86_64.tar.gz -C /opt +rm google-cloud-sdk-${GOOGLE_SDK_VERSION}-linux-x86_64.tar.gz +ln -s /opt/google-cloud-sdk/bin/gsutil /usr/bin/gsutil +ln -s /opt/google-cloud-sdk/bin/gcloud /usr/bin/gcloud + +# Cleanup after yourself +/bin/rm -rf /tmp/mage +/bin/rm -rf $HOME/go + +# Perform user specific initialization +sudo -u circleci ./deploy-user.sh + +# Get the size down +/bin/rm -rf /var/lib/apt/lists diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/test/docker-compose.yml b/packages/grafana-toolkit/docker/grafana-plugin-ci/test/docker-compose.yml new file mode 100644 index 00000000..d734b3a3 --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/test/docker-compose.yml @@ -0,0 +1,10 @@ +version: '3' +services: + citest: + image: "circleci/node:12-browsers" + user: root + volumes: + - ../scripts:/home/circleci/scripts + - ../install:/home/circleci/install + - ${HOME}/.ssh:/root/.ssh + - ../../..:/home/circleci/grafana-toolkit diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci/test/start.sh b/packages/grafana-toolkit/docker/grafana-plugin-ci/test/start.sh new file mode 100755 index 00000000..af3d91cb --- /dev/null +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci/test/start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +function finish { + echo "Exiting and cleaning up docker image" + docker-compose down +} +trap finish EXIT + +# Enter the docker container +docker-compose run citest bash -c "cd /home/circleci; exec bash --login -i" diff --git a/packages/grafana-toolkit/package.json b/packages/grafana-toolkit/package.json new file mode 100644 index 00000000..0c48ad69 --- /dev/null +++ b/packages/grafana-toolkit/package.json @@ -0,0 +1,107 @@ +{ + "author": "Grafana Labs", + "license": "Apache-2.0", + "name": "@grafana/toolkit", + "version": "8.4.0-pre", + "description": "Grafana Toolkit", + "keywords": [ + "grafana", + "cli", + "plugins", + "typescript" + ], + "repository": { + "type": "git", + "url": "http://github.com/grafana/grafana.git", + "directory": "packages/grafana-toolkit" + }, + "bin": { + "grafana-toolkit": "./bin/grafana-toolkit.js" + }, + "scripts": { + "build": "grafana-toolkit toolkit:build", + "clean": "rimraf ./dist ./compiled", + "precommit": "npm run lint & npm run typecheck", + "typecheck": "tsc --noEmit" + }, + "main": "src/index.ts", + "dependencies": { + "@babel/core": "7.13.14", + "@babel/preset-env": "7.13.12", + "@grafana/data": "8.4.0-pre", + "@grafana/eslint-config": "2.5.1", + "@grafana/tsconfig": "^1.0.0-rc1", + "@grafana/ui": "8.4.0-pre", + "@jest/core": "26.6.3", + "@rushstack/eslint-patch": "1.0.6", + "@types/command-exists": "^1.2.0", + "@types/eslint": "7.28.0", + "@types/fs-extra": "^9.0.13", + "@types/inquirer": "^8.0.0", + "@types/jest": "27.0.2", + "@types/lodash": "4.14.149", + "@types/node": "^16.0.0", + "@types/prettier": "^2.4.0", + "@types/react-dev-utils": "^9.0.4", + "@types/rimraf": "^3.0.0", + "@types/semver": "^7.0.0", + "@types/tmp": "^0.1.0", + "@types/webpack": "4.41.7", + "@typescript-eslint/eslint-plugin": "4.28.0", + "@typescript-eslint/parser": "4.28.0", + "axios": "0.21.2", + "babel-jest": "26.6.3", + "babel-loader": "8.2.2", + "babel-plugin-angularjs-annotate": "0.10.0", + "chalk": "^4.0.0", + "command-exists": "^1.2.8", + "commander": "^8.0.0", + "concurrently": "6.3.0", + "copy-webpack-plugin": "5.1.2", + "css-loader": "3.4.2", + "eslint": "7.28.0", + "execa": "^5.1.1", + "file-loader": "6.2.0", + "fork-ts-checker-webpack-plugin": "6.4.0", + "fs-extra": "^10.0.0", + "globby": "^10.0.1", + "html-loader": "0.5.5", + "html-webpack-plugin": "^3.2.0", + "inquirer": "^8.0.0", + "jest": "26.6.3", + "jest-canvas-mock": "2.3.0", + "jest-coverage-badges": "^1.1.2", + "jest-environment-jsdom-fifteen": "^1.0.2", + "jest-junit": "^13.0.0", + "less": "^3.11.1", + "less-loader": "^5.0.0", + "lodash": "4.17.21", + "md5-file": "^5.0.0", + "mini-css-extract-plugin": "^0.7.0", + "optimize-css-assets-webpack-plugin": "6.0.1", + "ora": "^4.0.3", + "pixelmatch": "^5.1.0", + "pngjs": "^6.0.0", + "postcss-flexbugs-fixes": "4.2.0", + "postcss-loader": "3.0.0", + "postcss-preset-env": "6.7.0", + "prettier": "^2.2.1", + "react-dev-utils": "^11.0.4", + "replace-in-file": "^4.1.0", + "replace-in-file-webpack-plugin": "^1.0.6", + "rimraf": "^3.0.0", + "sass": "1.27.0", + "sass-loader": "8.0.2", + "semver": "^7.1.3", + "simple-git": "^2.46.0", + "style-loader": "1.1.3", + "terser-webpack-plugin": "2.3.7", + "ts-jest": "26.4.4", + "ts-loader": "6.2.1", + "ts-node": "9.0.0", + "tslib": "2.3.1", + "typescript": "4.4.3", + "url-loader": "^2.0.1", + "webpack": "4.41.5" + } +} diff --git a/packages/grafana-toolkit/src/cli/index.d.ts b/packages/grafana-toolkit/src/cli/index.d.ts new file mode 100644 index 00000000..5f7aeecc --- /dev/null +++ b/packages/grafana-toolkit/src/cli/index.d.ts @@ -0,0 +1 @@ +export type Task = (options: T) => Promise; diff --git a/packages/grafana-toolkit/src/cli/index.ts b/packages/grafana-toolkit/src/cli/index.ts new file mode 100644 index 00000000..797684d4 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/index.ts @@ -0,0 +1,305 @@ +// @ts-ignore +import chalk from 'chalk'; +import { program } from 'commander'; +import { promises as fs } from 'fs'; +import { execTask } from './utils/execTask'; +import { startTask } from './tasks/core.start'; +import { changelogTask } from './tasks/changelog'; +import { cherryPickTask } from './tasks/cherrypick'; +import { templateTask } from './tasks/template'; +import { pluginBuildTask } from './tasks/plugin.build'; +import { toolkitBuildTask } from './tasks/toolkit.build'; +import { pluginTestTask } from './tasks/plugin.tests'; +import { searchTestDataSetupTask } from './tasks/searchTestDataSetup'; +import { closeMilestoneTask } from './tasks/closeMilestone'; +import { pluginDevTask } from './tasks/plugin.dev'; +import { githubPublishTask } from './tasks/plugin.utils'; +import { pluginUpdateTask } from './tasks/plugin.update'; +import { ciBuildPluginTask, ciPackagePluginTask, ciPluginReportTask } from './tasks/plugin.ci'; +import { buildPackageTask } from './tasks/package.build'; +import { pluginCreateTask } from './tasks/plugin.create'; +import { pluginSignTask } from './tasks/plugin.sign'; +import { bundleManagedTask } from './tasks/plugin/bundle.managed'; +import { componentCreateTask } from './tasks/component.create'; +import { nodeVersionCheckerTask } from './tasks/nodeVersionChecker'; + +export const run = (includeInternalScripts = false) => { + if (includeInternalScripts) { + program.option('-d, --depreciate ', 'Inform about npm script deprecation', (v) => v.split(',')); + program + .command('core:start') + .option('-h, --hot', 'Run front-end with HRM enabled') + .option('-T, --noTsCheck', 'Run bundler without TS type checking') + .option('-t, --watchTheme', 'Watch for theme changes and regenerate variables.scss files') + .description('Starts Grafana front-end in development mode with watch enabled') + .action(async (cmd) => { + await execTask(startTask)({ + watchThemes: cmd.watchTheme, + noTsCheck: cmd.noTsCheck, + hot: cmd.hot, + }); + }); + + program + .command('package:build') + .option('-s, --scope ', 'packages=[data|runtime|ui|toolkit|e2e|e2e-selectors]') + .description('Builds @grafana/* package to packages/grafana-*/dist') + .action(async (cmd) => { + await execTask(buildPackageTask)({ + scope: cmd.scope, + }); + }); + + program + .command('changelog') + .option('-m, --milestone ', 'Specify milestone') + .description('Builds changelog markdown') + .action(async (cmd) => { + if (!cmd.milestone) { + console.log('Please specify milestone, example: -m '); + return; + } + + await execTask(changelogTask)({ + milestone: cmd.milestone, + silent: true, + }); + }); + + program + .command('cherrypick') + .option('-e, --enterprise', 'Run task for grafana-enterprise') + .description('Helps find commits to cherry pick') + .action(async (cmd) => { + await execTask(cherryPickTask)({ enterprise: !!cmd.enterprise }); + }); + + program + .command('node-version-check') + .description('Verify node version') + .action(async (cmd) => { + await execTask(nodeVersionCheckerTask)({}); + }); + + program + .command('debug:template') + .description('Just testing') + .action(async (cmd) => { + await execTask(templateTask)({}); + }); + + program + .command('toolkit:build') + .description('Prepares grafana/toolkit dist package') + .action(async (cmd) => { + await execTask(toolkitBuildTask)({}); + }); + + program + .command('searchTestData') + .option('-c, --count ', 'Specify number of dashboards') + .description('Setup test data for search') + .action(async (cmd) => { + await execTask(searchTestDataSetupTask)({ count: cmd.count }); + }); + + program + .command('close-milestone') + .option('-m, --milestone ', 'Specify milestone') + .option('--dryRun', 'Only simulate actions') + .description('Helps ends a milestone by removing the cherry-pick label and closing it') + .action(async (cmd) => { + if (!cmd.milestone) { + console.log('Please specify milestone, example: -m '); + return; + } + + await execTask(closeMilestoneTask)({ + milestone: cmd.milestone, + dryRun: !!cmd.dryRun, + }); + }); + + // React generator + program + .command('component:create') + .description( + 'Scaffold React components. Optionally add test, story and .mdx files. The components are created in the same dir the script is run from.' + ) + .action(async () => { + await execTask(componentCreateTask)({}); + }); + } + + program.option('-v, --version', 'Toolkit version').action(async () => { + const pkg = await fs.readFile(`${__dirname}/../../package.json`, 'utf8'); + const { version } = JSON.parse(pkg); + console.log(`v${version}`); + }); + + program + .command('plugin:create [name]') + .description('Creates plugin from template') + .action(async (cmd) => { + await execTask(pluginCreateTask)({ name: cmd, silent: true }); + }); + + program + .command('plugin:build') + .option('--maxJestWorkers |', 'Limit number of Jest workers spawned') + .option('--coverage', 'Run code coverage', false) + .option('--skipTest', 'Skip running tests (for pipelines that run it separate)', false) + .option('--skipLint', 'Skip running lint (for pipelines that run it separate)', false) + .option('--preserveConsole', 'Preserves console calls', false) + .description('Prepares plugin dist package') + .action(async (cmd) => { + await execTask(pluginBuildTask)({ + coverage: cmd.coverage, + silent: true, + maxJestWorkers: cmd.maxJestWorkers, + preserveConsole: cmd.preserveConsole, + skipLint: cmd.skipLint, + skipTest: cmd.skipTest, + }); + }); + + program + .command('plugin:dev') + .option('-w, --watch', 'Run plugin development mode with watch enabled') + .option('--yarnlink', 'symlink this project to the local grafana/toolkit') + .description('Starts plugin dev mode') + .action(async (cmd) => { + await execTask(pluginDevTask)({ + watch: !!cmd.watch, + yarnlink: !!cmd.yarnlink, + silent: true, + }); + }); + + program + .command('plugin:test') + .option('-u, --updateSnapshot', 'Run snapshots update') + .option('--coverage', 'Run code coverage') + .option('--watch', 'Run tests in interactive watch mode') + .option('--testPathPattern ', 'Run only tests with a path that matches the regex') + .option('--testNamePattern ', 'Run only tests with a name that matches the regex') + .option('--maxWorkers |', 'Limit number of workers spawned') + .description('Executes plugin tests') + .action(async (cmd) => { + await execTask(pluginTestTask)({ + updateSnapshot: !!cmd.updateSnapshot, + coverage: !!cmd.coverage, + watch: !!cmd.watch, + testPathPattern: cmd.testPathPattern, + testNamePattern: cmd.testNamePattern, + maxWorkers: cmd.maxWorkers, + silent: true, + }); + }); + + program + .command('plugin:sign') + .option('--signatureType ', 'Signature Type') + .option( + '--rootUrls ', + 'Root URLs', + function (url: string, urls: string[]) { + if (typeof url !== 'string') { + return urls; + } + + const parts = url.split(','); + urls.push(...parts); + + return urls; + }, + [] + ) + .description('Create a plugin signature') + .action(async (cmd) => { + await execTask(pluginSignTask)({ + signatureType: cmd.signatureType, + rootUrls: cmd.rootUrls, + silent: true, + }); + }); + + program + .command('plugin:ci-build') + .option('--finish', 'move all results to the jobs folder', false) + .option('--maxJestWorkers |', 'Limit number of Jest workers spawned') + .description('[deprecated] Build the plugin, leaving results in /dist and /coverage') + .action(async (cmd) => { + await execTask(ciBuildPluginTask)({ + finish: cmd.finish, + maxJestWorkers: cmd.maxJestWorkers, + }); + }); + + program + .command('plugin:ci-package') + .option('--signatureType ', 'Signature Type') + .option('--rootUrls ', 'Root URLs') + .option('--signing-admin', 'Use the admin API endpoint for signing the manifest. (deprecated)', false) + .description('[deprecated] Create a zip packages for the plugin') + .action(async (cmd) => { + await execTask(ciPackagePluginTask)({ + signatureType: cmd.signatureType, + rootUrls: cmd.rootUrls, + }); + }); + + program + .command('plugin:ci-report') + .description('[deprecated] Build a report for this whole process') + .option('--upload', 'upload packages also') + .action(async (cmd) => { + await execTask(ciPluginReportTask)({ + upload: cmd.upload, + }); + }); + + program + .command('plugin:bundle-managed') + .description('Builds managed plugins') + .action(async (cmd) => { + await execTask(bundleManagedTask)({}); + }); + + program + .command('plugin:github-publish') + .option('--dryrun', 'Do a dry run only', false) + .option('--verbose', 'Print verbose', false) + .option('--commitHash ', 'Specify the commit hash') + .description('Publish to github') + .action(async (cmd) => { + await execTask(githubPublishTask)({ + dryrun: cmd.dryrun, + verbose: cmd.verbose, + commitHash: cmd.commitHash, + }); + }); + + program + .command('plugin:update-circleci') + .description('Update plugin') + .action(async (cmd) => { + await execTask(pluginUpdateTask)({}); + }); + + program.on('command:*', () => { + console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' ')); + process.exit(1); + }); + + program.parse(process.argv); + + const options = program.opts(); + if (options.depreciate && options.depreciate.length === 2) { + console.log( + chalk.yellow.bold( + `[NPM script depreciation] ${options.depreciate[0]} is deprecated! Use ${options.depreciate[1]} instead!` + ) + ); + } +}; diff --git a/packages/grafana-toolkit/src/cli/tasks/changelog.ts b/packages/grafana-toolkit/src/cli/tasks/changelog.ts new file mode 100644 index 00000000..7e797d15 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/changelog.ts @@ -0,0 +1,146 @@ +import { difference, sortBy } from 'lodash'; +import { Task } from './task'; +import GithubClient from '../utils/githubClient'; +import chalk from 'chalk'; +import { useSpinner } from '../utils/useSpinner'; + +interface ChangelogOptions { + milestone: string; +} + +const filterBugs = (item: any) => { + if (item.title.match(/fix|fixes/i)) { + return true; + } + if (item.labels.find((label: any) => label.name === 'type/bug')) { + return true; + } + return false; +}; + +const getPackageChangelog = (packageName: string, issues: any[]) => { + if (issues.length === 0) { + return ''; + } + + let markdown = chalk.bold.yellow(`\n\n/*** ${packageName} changelog ***/\n\n`); + const bugs = sortBy(issues.filter(filterBugs), 'title'); + const notBugs = sortBy(difference(issues, bugs), 'title'); + + if (notBugs.length > 0) { + markdown += '### Features / Enhancements\n'; + for (const item of notBugs) { + markdown += getMarkdownLineForIssue(item); + } + } + + if (bugs.length > 0) { + markdown += '\n### Bug Fixes\n'; + for (const item of bugs) { + markdown += getMarkdownLineForIssue(item); + } + } + + return markdown; +}; + +const changelogTaskRunner = ({ milestone }: ChangelogOptions) => + useSpinner('Generating changelog', async () => { + const githubClient = new GithubClient(); + const client = githubClient.client; + + if (!/^\d+$/.test(milestone)) { + console.log('Use milestone number not title, find number in milestone url'); + return; + } + + let res = await client.get('/issues', { + params: { + state: 'closed', + per_page: 100, + labels: 'add to changelog', + milestone: milestone, + }, + }); + + const data: any[] = res.data; + + while (res.headers.link) { + const links = parseLink(res.headers.link); + if (links.next) { + res = await client.get(links.next); + data.push(...res.data); + } else { + break; + } + } + + const mergedIssues = []; + for (const item of data) { + if (!item.pull_request) { + // it's an issue, not pull request + mergedIssues.push(item); + continue; + } + const isMerged = await client.get(item.pull_request.url + '/merge'); + if (isMerged.status === 204) { + mergedIssues.push(item); + } + } + const issues = sortBy(mergedIssues, 'title'); + + const toolkitIssues = issues.filter((item: any) => + item.labels.find((label: any) => label.name === 'area/grafana/toolkit') + ); + const grafanaUiIssues = issues.filter((item: any) => + item.labels.find((label: any) => label.name === 'area/grafana/ui') + ); + + let markdown = ''; + + markdown += getPackageChangelog('Grafana', issues); + markdown += getPackageChangelog('grafana-toolkit', toolkitIssues); + markdown += getPackageChangelog('grafana-ui', grafanaUiIssues); + + console.log(markdown); + }); + +function getMarkdownLineForIssue(item: any) { + const githubGrafanaUrl = 'https://github.com/grafana/grafana'; + let markdown = ''; + let title: string = item.title.replace(/^([^:]*)/, (_match: any, g1: any) => { + return `**${g1}**`; + }); + title = title.trim(); + if (title[title.length - 1] === '.') { + title = title.slice(0, -1); + } + + if (!item.pull_request) { + markdown += '* ' + title + '.'; + markdown += ` [#${item.number}](${githubGrafanaUrl}/issues/${item.number})`; + } else { + markdown += '* ' + title + '.'; + markdown += ` [#${item.number}](${githubGrafanaUrl}/pull/${item.number})`; + markdown += `, [@${item.user.login}](${item.user.html_url})`; + } + + markdown += '\n'; + + return markdown; +} + +function parseLink(s: any) { + const output: any = {}; + const regex = /<([^>]+)>; rel="([^"]+)"/g; + + let m; + while ((m = regex.exec(s))) { + const [, v, k] = m; + output[k] = v; + } + + return output; +} + +export const changelogTask = new Task('Changelog generator task', changelogTaskRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/cherrypick.ts b/packages/grafana-toolkit/src/cli/tasks/cherrypick.ts new file mode 100644 index 00000000..1a446a13 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/cherrypick.ts @@ -0,0 +1,95 @@ +import { Task, TaskRunner } from './task'; +import GithubClient from '../utils/githubClient'; + +interface CherryPickOptions { + enterprise: boolean; +} + +// https://github.com/lisposter/github-pagination/blob/master/lib/octopage.js +const pagingParser = (linkStr: string): { prev?: string; next?: string; last?: string; first?: string } => { + return linkStr + .split(',') + .map((rel) => { + //@ts-ignore + return rel.split(';').map((curr, idx) => { + if (idx === 0) { + //@ts-ignore + return /[^_]page=(\d+)/.exec(curr)[1]; + } + if (idx === 1) { + //@ts-ignore + return /rel="(.+)"/.exec(curr)[1]; + } + }); + }) + .reduce(function (obj, curr, i) { + //@ts-ignore + obj[curr[1]] = curr[0]; + return obj; + }, {}); +}; + +const getIssues = async (client: any, page: string) => { + const result = await client.get('/issues', { + params: { + state: 'closed', + per_page: 100, + labels: 'cherry-pick needed', + sort: 'closed', + direction: 'asc', + page, + }, + }); + + let data = result.data; + if (!result.headers.link) { + return data; + } + + const pages = pagingParser(result.headers.link); + + if (pages.next) { + const nextPage = await getIssues(client, pages.next); + data = data.concat(nextPage); + } + return data; +}; + +const cherryPickRunner: TaskRunner = async ({ enterprise }) => { + const githubClient = new GithubClient({ enterprise }); + const client = githubClient.client; + const results = await getIssues(client, '1'); + + // sort by closed date ASC + results.sort((a: any, b: any) => { + return new Date(a.closed_at).getTime() - new Date(b.closed_at).getTime(); + }); + + let commands = ''; + + console.log('--------------------------------------------------------------------'); + console.log('Printing PRs with cherry-pick-needed, in ASC merge date order'); + console.log('--------------------------------------------------------------------'); + + for (const item of results) { + if (!item.milestone) { + console.log(item.number + ' missing milestone!'); + continue; + } + const issueDetails = await client.get(item.pull_request.url); + + if (!issueDetails.data.merged) { + continue; + } + + console.log(`* ${item.title}, (#${item.number}), merge-sha: ${issueDetails.data.merge_commit_sha}`); + commands += `git cherry-pick -x ${issueDetails.data.merge_commit_sha}\n`; + } + + console.log('--------------------------------------------------------------------'); + console.log('Commands (in order of how they should be executed)'); + console.log('--------------------------------------------------------------------'); + console.log(commands); +}; + +export const cherryPickTask = new Task('Cherry pick task', cherryPickRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts b/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts new file mode 100644 index 00000000..0ac396a3 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts @@ -0,0 +1,95 @@ +import { Task, TaskRunner } from './task'; +import GithubClient from '../utils/githubClient'; + +interface CloseMilestoneOptions { + milestone: string; + dryRun: boolean; +} + +const closeMilestoneTaskRunner: TaskRunner = async ({ milestone, dryRun }) => { + const githubClient = new GithubClient({ required: true }); + + const cherryPickLabel = 'cherry-pick needed'; + const client = githubClient.client; + + if (!/^\d+$/.test(milestone)) { + console.log('Use milestone number not title, find number in milestone url'); + return; + } + + if (dryRun) { + console.log('dry run is enabled'); + } + + const milestoneRes = await client.get(`/milestones/${milestone}`, {}); + + const milestoneState = milestoneRes.data.state; + + if (milestoneState === 'closed') { + console.log('milestone already closed. ✅'); + return; + } + + console.log('fetching issues/PRs of the milestone ⏬'); + + let totalIssues = 0; + + while (true) { + // Get first 100 issues/PRs with the label cherry-pick + // Every pull request is actually an issue + const issuesRes = await client.get('/issues', { + params: { + state: 'closed', + labels: cherryPickLabel, + per_page: 100, + milestone: milestone, + }, + }); + + if (issuesRes.data.length < 1) { + break; + } + + const comparativeStr = totalIssues === 0 ? ' ' : ' more '; + console.log(`found ${issuesRes.data.length}${comparativeStr}issues to remove the cherry-pick label from 🔎`); + totalIssues += issuesRes.data.length; + + for (const issue of issuesRes.data) { + // the reason for using stdout.write is for achieving 'action -> result' on + // the same line + process.stdout.write(`🔧removing label from issue #${issue.number} 🗑...`); + if (!dryRun) { + const resDelete = await client.delete(`/issues/${issue.number}/labels/${cherryPickLabel}`, {}); + if (resDelete.status === 200) { + process.stdout.write('done ✅\n'); + } else { + console.log('failed ❌'); + } + } + } + } + + if (totalIssues === 0) { + console.log('no issues to remove label from'); + } else { + console.log(`cleaned up ${totalIssues} issues/prs ⚡️`); + } + + if (!dryRun) { + const resClose = await client.patch(`/milestones/${milestone}`, { + state: 'closed', + }); + + if (resClose.status === 200) { + console.log('milestone closed 🙌'); + } else { + console.log('failed to close the milestone, response:'); + console.log(resClose); + } + } +}; + +export const closeMilestoneTask = new Task( + 'Close Milestone generator task', + closeMilestoneTaskRunner +); diff --git a/packages/grafana-toolkit/src/cli/tasks/component.create.ts b/packages/grafana-toolkit/src/cli/tasks/component.create.ts new file mode 100644 index 00000000..8227c450 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/component.create.ts @@ -0,0 +1,86 @@ +import { Task, TaskRunner } from './task'; +import fs from 'fs'; +import { template as _template } from 'lodash'; +import { prompt } from 'inquirer'; +import { pascalCase } from '../utils/pascalCase'; +import { promptConfirm, promptInput, promptList } from '../utils/prompt'; +import { componentTpl, docsTpl, storyTpl, testTpl } from '../templates'; + +interface Details { + name?: string; + hasStory: boolean; + group?: string; + isStoryPublic: boolean; + hasTests: boolean; +} + +interface GeneratorOptions { + details: Details; + path: string; +} + +type ComponentGenerator = (options: GeneratorOptions) => Promise; + +const componentGroups = [ + { name: 'General', value: 'General' }, + { name: 'Forms', value: 'Forms' }, + { name: 'Panel', value: 'Panel' }, + { name: 'Visualizations', value: 'Visualizations' }, + { name: 'Others', value: 'Others' }, +]; + +export const promptDetails = () => { + return prompt
([ + promptInput('name', 'Component name', true), + promptConfirm('hasTests', "Generate component's test file?"), + promptConfirm('hasStory', "Generate component's story file?"), + promptConfirm( + 'isStoryPublic', + 'Generate public story? (Selecting "No" will create an internal story)', + true, + ({ hasStory }) => hasStory + ), + promptList( + 'group', + 'Select component group for the story (e.g. Forms, Layout)', + () => componentGroups, + 0, + ({ hasStory }) => hasStory + ), + ]); +}; + +export const generateComponents: ComponentGenerator = async ({ details, path }) => { + const name = pascalCase(details.name); + const getCompiled = (template: string) => { + return _template(template)({ ...details, name }); + }; + const filePath = `${path}/${name}`; + let paths = []; + + fs.writeFileSync(`${filePath}.tsx`, getCompiled(componentTpl)); + paths.push(`${filePath}.tsx`); + + if (details.hasTests) { + fs.writeFileSync(`${filePath}.test.tsx`, getCompiled(testTpl)); + paths.push(`${filePath}.test.tsx`); + } + + if (details.hasStory) { + const storyExt = details.isStoryPublic ? '.story.tsx' : '.story.internal.tsx'; + fs.writeFileSync(`${filePath}${storyExt}`, getCompiled(storyTpl)); + fs.writeFileSync(`${filePath}.mdx`, getCompiled(docsTpl)); + paths.push(`${filePath}${storyExt}`, `${filePath}.mdx`); + } + + console.log('Generated files:'); + console.log(paths.join('\n')); +}; + +const componentCreateRunner: TaskRunner = async () => { + const destPath = process.cwd(); + const details = await promptDetails(); + await generateComponents({ details, path: destPath }); +}; + +export const componentCreateTask = new Task('component:create', componentCreateRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/core.start.ts b/packages/grafana-toolkit/src/cli/tasks/core.start.ts new file mode 100644 index 00000000..d3d94dbc --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/core.start.ts @@ -0,0 +1,43 @@ +//@ts-ignore +import concurrently from 'concurrently'; +import { Task, TaskRunner } from './task'; + +interface StartTaskOptions { + watchThemes: boolean; + noTsCheck: boolean; + hot: boolean; +} + +const startTaskRunner: TaskRunner = async ({ watchThemes, noTsCheck, hot }) => { + const noTsCheckArg = noTsCheck ? 1 : 0; + const jobs = [ + watchThemes && { + command: 'nodemon -e ts -w ./packages/grafana-ui/src/themes -x yarn run themes:generate', + name: 'SASS variables generator', + }, + hot + ? { + command: 'webpack serve --progress --color --config scripts/webpack/webpack.hot.js', + name: 'Dev server', + } + : { + command: `webpack --progress --color --watch --env noTsCheck=${noTsCheckArg} --config scripts/webpack/webpack.dev.js`, + name: 'Webpack', + }, + ]; + + try { + await concurrently( + jobs.filter((job) => !!job), + { + killOthers: ['failure', 'failure'], + raw: true, + } + ); + } catch (e) { + console.error(e); + process.exit(1); + } +}; + +export const startTask = new Task('Core startTask', startTaskRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/nodeVersionChecker.ts b/packages/grafana-toolkit/src/cli/tasks/nodeVersionChecker.ts new file mode 100644 index 00000000..3e9942b0 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/nodeVersionChecker.ts @@ -0,0 +1,76 @@ +import { Task, TaskRunner } from './task'; +import chalk from 'chalk'; +import { coerce, satisfies } from 'semver'; +import { readFileSync } from 'fs'; + +interface FailedVersionCheck { + file: string; + line: string; +} + +interface NodeVersionCheckerOptions {} + +const pattern = /(circleci\/|FROM )node\:([0-9]+(\.[0-9]+){0,2})/gm; +const packageJsonFile = 'package.json'; + +const failures: FailedVersionCheck[] = []; + +export const nodeVersionFiles = [packageJsonFile, 'Dockerfile']; + +const nodeVersionCheckerRunner: TaskRunner = async () => { + // Read version from package json and treat that as the expected version in all other locations + const packageJson = require(`${process.cwd()}/${packageJsonFile}`); + const expectedVersion = packageJson.engines.node; + + console.log(chalk.yellow(`Specified node version in package.json is: ${expectedVersion}`)); + + for (const file of nodeVersionFiles) { + const fileContent = readFileSync(`${process.cwd()}/${file}`); + const matches = fileContent.toString('utf8').match(pattern); + + if (!matches) { + continue; + } + + for (const match of matches) { + const actualVersion = coerce(match); + if (!actualVersion) { + failures.push({ + file, + line: match, + }); + continue; + } + + const satisfied = satisfies(actualVersion, expectedVersion); + if (!satisfied) { + failures.push({ + file, + line: match, + }); + } + } + } + + if (failures.length > 0) { + console.log(chalk.red('--------------------------------------------------------------------')); + console.log(chalk.red(`These entries don't satisfy the engine version in ${packageJsonFile}`)); + console.log(chalk.red('--------------------------------------------------------------------')); + + for (let index = 0; index < failures.length; index++) { + const failure = failures[index]; + console.log(chalk.green(`\tIn ${failure.file} the line ${failure.line} does not satisfy ${expectedVersion}.`)); + } + + throw new Error('Node versions not in sync'); + } + + console.log(chalk.yellow('--------------------------------------------------------------------')); + console.log(chalk.yellow('All node versions seem ok.')); + console.log(chalk.yellow('--------------------------------------------------------------------')); +}; + +export const nodeVersionCheckerTask = new Task( + 'Node Version Checker', + nodeVersionCheckerRunner +); diff --git a/packages/grafana-toolkit/src/cli/tasks/package.build.ts b/packages/grafana-toolkit/src/cli/tasks/package.build.ts new file mode 100644 index 00000000..5e00ffb2 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/package.build.ts @@ -0,0 +1,90 @@ +import execa = require('execa'); +import { promises as fs } from 'fs'; +import * as path from 'path'; +import chalk from 'chalk'; +import { useSpinner } from '../utils/useSpinner'; +import { Task, TaskRunner } from './task'; +import { cloneDeep } from 'lodash'; +import globby from 'globby'; + +const clean = (cwd: string) => useSpinner('Cleaning', () => execa('npm', ['run', 'clean'], { cwd })); + +const compile = (cwd: string) => + useSpinner('Compiling sources', () => execa('tsc', ['-p', './tsconfig.build.json'], { cwd })); + +const bundle = (cwd: string) => useSpinner('Bundling', () => execa('npm', ['run', 'bundle'], { cwd })); + +const preparePackage = async (packageDist: string, pkg: any) => { + pkg = cloneDeep(pkg); // avoid mutations + + pkg.main = 'index.js'; + pkg.types = 'index.d.ts'; + + const version: string = pkg.version; + const name: string = pkg.name; + const deps: any = pkg.dependencies; + + // Below we are adding cross-dependencies to Grafana's packages + // with the version being published + if (name.endsWith('/ui')) { + deps['@grafana/data'] = version; + } else if (name.endsWith('/runtime')) { + deps['@grafana/data'] = version; + deps['@grafana/ui'] = version; + } else if (name.endsWith('/toolkit')) { + deps['@grafana/data'] = version; + deps['@grafana/ui'] = version; + } + + await useSpinner('Updating package.json', () => + fs.writeFile(`${packageDist}/package.json`, JSON.stringify(pkg, null, 2)) + ); +}; + +const moveFiles = (fromPath: string, toPath: string) => { + const files = ['README.md', 'CHANGELOG.md', 'index.js']; + + return useSpinner(`Moving ${files.join(', ')} files`, () => { + const promises = files.map((file) => fs.copyFile(`${fromPath}/${file}`, `${toPath}/${file}`)); + return Promise.all(promises); + }); +}; + +const moveStaticFiles = async (packageRoot: string, pkg: any) => { + if (pkg.name.endsWith('/ui')) { + return useSpinner('Moving static files', async () => { + const staticFiles = await globby(`${packageRoot}/src/**/*.{png,svg,gif,jpg}`); + const pathSearch = new RegExp(`^${packageRoot}/src`); + const pathReplace = `${packageRoot}/compiled`; + const promises = staticFiles.map((file) => fs.copyFile(file, file.replace(pathSearch, pathReplace))); + await Promise.all(promises); + }); + } +}; + +interface PackageBuildOptions { + scope: string; +} + +const buildTaskRunner: TaskRunner = async ({ scope }) => { + if (!scope) { + throw new Error('Provide packages with -s, --scope '); + } + + const scopes = scope.split(',').map(async (s) => { + const packageRoot = path.resolve(__dirname, `../../../../grafana-${s}`); + const packageDist = `${packageRoot}/dist`; + const pkg = require(`${packageRoot}/package.json`); + console.log(chalk.yellow(`Building ${pkg.name} (package.json version: ${pkg.version})`)); + await clean(packageRoot); + await compile(packageRoot); + await moveStaticFiles(packageRoot, pkg); + await bundle(packageRoot); + await preparePackage(packageDist, pkg); + await moveFiles(packageRoot, packageDist); + }); + + await Promise.all(scopes); +}; + +export const buildPackageTask = new Task('Package build', buildTaskRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.build.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.build.ts new file mode 100644 index 00000000..02b6d668 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.build.ts @@ -0,0 +1,151 @@ +import { useSpinner } from '../utils/useSpinner'; +import { testPlugin } from './plugin/tests'; +import { Task, TaskRunner } from './task'; +import rimrafCallback from 'rimraf'; +import { resolve as resolvePath } from 'path'; +import { promisify } from 'util'; +import globby from 'globby'; +import execa from 'execa'; +import { constants as fsConstants, promises as fs } from 'fs'; +import { CLIEngine } from 'eslint'; +import { bundlePlugin as bundleFn, PluginBundleOptions } from './plugin/bundle'; + +const { access, copyFile } = fs; +const { COPYFILE_EXCL } = fsConstants; +const rimraf = promisify(rimrafCallback); + +interface PluginBuildOptions { + coverage: boolean; + maxJestWorkers?: string; + preserveConsole?: boolean; + skipTest?: boolean; + skipLint?: boolean; +} + +interface Fixable { + fix?: boolean; +} + +const bundlePlugin = (options: PluginBundleOptions) => useSpinner('Compiling...', () => bundleFn(options)); + +// @ts-ignore +const clean = () => useSpinner('Cleaning', () => rimraf(`${process.cwd()}/dist`)); + +const copyIfNonExistent = (srcPath: string, destPath: string) => + copyFile(srcPath, destPath, COPYFILE_EXCL) + .then(() => console.log(`Created: ${destPath}`)) + .catch((error) => { + if (error.code !== 'EEXIST') { + throw error; + } + }); + +export const prepare = () => + useSpinner('Preparing', () => + Promise.all([ + // Remove local dependencies for @grafana/data/node_modules + // See: https://github.com/grafana/grafana/issues/26748 + rimraf(resolvePath(__dirname, 'node_modules/@grafana/data/node_modules')), + // Copy only if local tsconfig does not exist. Otherwise this will work, but have odd behavior + copyIfNonExistent( + resolvePath(__dirname, '../../config/tsconfig.plugin.local.json'), + resolvePath(process.cwd(), 'tsconfig.json') + ), + // Copy only if local prettierrc does not exist. Otherwise this will work, but have odd behavior + copyIfNonExistent( + resolvePath(__dirname, '../../config/prettier.plugin.rc.js'), + resolvePath(process.cwd(), '.prettierrc.js') + ), + ]) + ); + +export const versions = async () => { + try { + const nodeVersion = await execa('node', ['--version']); + console.log(`Using Node.js ${nodeVersion.stdout}`); + + const toolkitVersion = await execa('grafana-toolkit', ['--version']); + console.log(`Using @grafana/toolkit ${toolkitVersion.stdout}`); + } catch (err) { + console.log(`Error reading versions`, err); + } +}; + +// @ts-ignore +const typecheckPlugin = () => useSpinner('Typechecking', () => execa('tsc', ['--noEmit'])); + +const getTypescriptSources = () => globby(resolvePath(process.cwd(), 'src/**/*.+(ts|tsx)')); + +// @ts-ignore +const getStylesSources = () => globby(resolvePath(process.cwd(), 'src/**/*.+(scss|css)')); + +export const lintPlugin = ({ fix }: Fixable = {}) => + useSpinner('Linting', async () => { + try { + // Show a warning if the tslint file exists + await access(resolvePath(process.cwd(), 'tslint.json')); + console.log('\n'); + console.log('--------------------------------------------------------------'); + console.log('NOTE: @grafana/toolkit has migrated to use eslint'); + console.log('Update your configs to use .eslintrc rather than tslint.json'); + console.log('--------------------------------------------------------------'); + } catch { + // OK: tslint does not exist + } + + // @todo should remove this because the config file could be in a parent dir or within package.json + const configFile = await globby(resolvePath(process.cwd(), '.eslintrc?(.cjs|.js|.json|.yaml|.yml)')).then( + (filePaths) => { + if (filePaths.length > 0) { + return filePaths[0]; + } else { + return resolvePath(__dirname, '../../config/eslint.plugin.js'); + } + } + ); + + const cli = new CLIEngine({ + configFile, + fix, + useEslintrc: false, + }); + + const report = cli.executeOnFiles(await getTypescriptSources()); + + if (fix) { + CLIEngine.outputFixes(report); + } + + const { errorCount, results, warningCount } = report; + const formatter = cli.getFormatter(); + + if (errorCount > 0 || warningCount > 0) { + console.log('\n'); + console.log(formatter(results)); + console.log('\n'); + } + + if (errorCount > 0) { + throw new Error(`${errorCount} linting errors found in ${results.length} files`); + } + }); + +export const pluginBuildRunner: TaskRunner = async ({ + coverage, + maxJestWorkers, + preserveConsole, + skipTest, + skipLint, +}) => { + await versions(); + await prepare(); + if (!skipLint) { + await lintPlugin({ fix: false }); + } + if (!skipTest) { + await testPlugin({ updateSnapshot: false, coverage, maxWorkers: maxJestWorkers, watch: false }); + } + await bundlePlugin({ watch: false, production: true, preserveConsole }); +}; + +export const pluginBuildTask = new Task('Build plugin', pluginBuildRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.ci.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.ci.ts new file mode 100644 index 00000000..eb880cd5 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.ci.ts @@ -0,0 +1,255 @@ +import { Task, TaskRunner } from './task'; +import { pluginBuildRunner } from './plugin.build'; +import { getPluginJson } from '../../config/utils/pluginValidation'; +import { getPluginId } from '../../config/utils/getPluginId'; +import execa = require('execa'); +import path = require('path'); +import fs from 'fs-extra'; +import { getPackageDetails, getGrafanaVersions, readGitLog } from '../../plugins/utils'; +import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest'; +import { + getJobFolder, + writeJobStats, + getCiFolder, + getPluginBuildInfo, + getPullRequestNumber, + getCircleDownloadBaseURL, +} from '../../plugins/env'; +import { agregateWorkflowInfo, agregateCoverageInfo, agregateTestInfo } from '../../plugins/workflow'; +import { PluginPackageDetails, PluginBuildReport } from '../../plugins/types'; +import rimrafCallback from 'rimraf'; +import { promisify } from 'util'; +const rimraf = promisify(rimrafCallback); + +export interface PluginCIOptions { + finish?: boolean; + upload?: boolean; + signatureType?: string; + rootUrls?: string[]; + maxJestWorkers?: string; +} + +/** + * 1. BUILD + * + * when platform exists it is building backend, otherwise frontend + * + * Each build writes data: + * ~/ci/jobs/build_xxx/ + * + * Anything that should be put into the final zip file should be put in: + * ~/ci/jobs/build_xxx/dist + * + * @deprecated -- this task was written with a specific circle-ci build in mind. That system + * has been replaced with Drone, and this is no longer the best practice. Any new work + * should be defined in the grafana build pipeline tool or drone configs directly. + */ +const buildPluginRunner: TaskRunner = async ({ finish, maxJestWorkers }) => { + const start = Date.now(); + + if (finish) { + const workDir = getJobFolder(); + await rimraf(workDir); + fs.mkdirSync(workDir); + + // Move local folders to the scoped job folder + for (const name of ['dist', 'coverage']) { + const dir = path.resolve(process.cwd(), name); + if (fs.existsSync(dir)) { + fs.moveSync(dir, path.resolve(workDir, name)); + } + } + writeJobStats(start, workDir); + } else { + // Do regular build process with coverage + await pluginBuildRunner({ coverage: true, maxJestWorkers }); + } +}; + +export const ciBuildPluginTask = new Task('Build Plugin', buildPluginRunner); + +/** + * 2. Package + * + * Take everything from `~/ci/job/{any}/dist` and + * 1. merge it into: `~/ci/dist` + * 2. zip it into packages in `~/ci/packages` + * 3. prepare grafana environment in: `~/ci/grafana-test-env` + * + * + * @deprecated -- this task was written with a specific circle-ci build in mind. That system + * has been replaced with Drone, and this is no longer the best practice. Any new work + * should be defined in the grafana build pipeline tool or drone configs directly. + */ +const packagePluginRunner: TaskRunner = async ({ signatureType, rootUrls }) => { + const start = Date.now(); + const ciDir = getCiFolder(); + const packagesDir = path.resolve(ciDir, 'packages'); + const distDir = path.resolve(ciDir, 'dist'); + const docsDir = path.resolve(ciDir, 'docs'); + const jobsDir = path.resolve(ciDir, 'jobs'); + + fs.exists(jobsDir, (jobsDirExists) => { + if (!jobsDirExists) { + throw new Error('You must run plugin:ci-build prior to running plugin:ci-package'); + } + }); + + const grafanaEnvDir = path.resolve(ciDir, 'grafana-test-env'); + await execa('rimraf', [packagesDir, distDir, grafanaEnvDir]); + fs.mkdirSync(packagesDir); + fs.mkdirSync(distDir); + + // Updating the dist dir to have a pluginId named directory in it + // The zip needs to contain the plugin code wrapped in directory with a pluginId name + const distContentDir = path.resolve(distDir, getPluginId()); + fs.mkdirSync(grafanaEnvDir); + + console.log('Build Dist Folder'); + + // 1. Check for a local 'dist' folder + const d = path.resolve(process.cwd(), 'dist'); + if (fs.existsSync(d)) { + await execa('cp', ['-rn', d + '/.', distContentDir]); + } + + // 2. Look for any 'dist' folders under ci/job/XXX/dist + const dirs = fs.readdirSync(path.resolve(ciDir, 'jobs')); + for (const j of dirs) { + const contents = path.resolve(ciDir, 'jobs', j, 'dist'); + if (fs.existsSync(contents)) { + try { + await execa('cp', ['-rn', contents + '/.', distContentDir]); + } catch (er) { + throw new Error('Duplicate files found in dist folders'); + } + } + } + + console.log('Save the source info in plugin.json'); + const pluginJsonFile = path.resolve(distContentDir, 'plugin.json'); + const pluginInfo = getPluginJson(pluginJsonFile); + pluginInfo.info.build = await getPluginBuildInfo(); + fs.writeFileSync(pluginJsonFile, JSON.stringify(pluginInfo, null, 2), { encoding: 'utf-8' }); + + // Write a MANIFEST.txt file in the dist folder + try { + const manifest = await buildManifest(distContentDir); + if (signatureType) { + manifest.signatureType = signatureType; + } + if (rootUrls) { + manifest.rootUrls = rootUrls; + } + const signedManifest = await signManifest(manifest); + await saveManifest(distContentDir, signedManifest); + } catch (err) { + console.warn(`Error signing manifest: ${distContentDir}`, err); + } + + console.log('Building ZIP'); + let zipName = pluginInfo.id + '-' + pluginInfo.info.version + '.zip'; + let zipFile = path.resolve(packagesDir, zipName); + await execa('zip', ['-r', zipFile, '.'], { cwd: distDir }); + + const zipStats = fs.statSync(zipFile); + if (zipStats.size < 100) { + throw new Error('Invalid zip file: ' + zipFile); + } + + // Make a copy so it is easy for report to read + await execa('cp', [pluginJsonFile, distDir]); + + const info: PluginPackageDetails = { + plugin: await getPackageDetails(zipFile, distDir), + }; + + console.log('Setup Grafana Environment'); + let p = path.resolve(grafanaEnvDir, 'plugins', pluginInfo.id); + fs.mkdirSync(p, { recursive: true }); + await execa('unzip', [zipFile, '-d', p]); + + // If docs exist, zip them into packages + if (fs.existsSync(docsDir)) { + console.log('Creating documentation zip'); + zipName = pluginInfo.id + '-' + pluginInfo.info.version + '-docs.zip'; + zipFile = path.resolve(packagesDir, zipName); + await execa('zip', ['-r', zipFile, '.'], { cwd: docsDir }); + + info.docs = await getPackageDetails(zipFile, docsDir); + } + + p = path.resolve(packagesDir, 'info.json'); + fs.writeFileSync(p, JSON.stringify(info, null, 2), { encoding: 'utf-8' }); + + // Write the custom settings + p = path.resolve(grafanaEnvDir, 'custom.ini'); + const customIniBody = + `# Autogenerated by @grafana/toolkit \n` + + `[paths] \n` + + `plugins = ${path.resolve(grafanaEnvDir, 'plugins')}\n` + + `\n`; // empty line + fs.writeFileSync(p, customIniBody, { encoding: 'utf-8' }); + + writeJobStats(start, getJobFolder()); +}; + +export const ciPackagePluginTask = new Task('Bundle Plugin', packagePluginRunner); + +/** + * 4. Report + * + * Create a report from all the previous steps + * + * @deprecated -- this task was written with a specific circle-ci build in mind. That system + * has been replaced with Drone, and this is no longer the best practice. Any new work + * should be defined in the grafana build pipeline tool or drone configs directly. + */ +const pluginReportRunner: TaskRunner = async ({ upload }) => { + const ciDir = path.resolve(process.cwd(), 'ci'); + const packageDir = path.resolve(ciDir, 'packages'); + const packageInfo = require(path.resolve(packageDir, 'info.json')) as PluginPackageDetails; + + const pluginJsonFile = path.resolve(ciDir, 'dist', 'plugin.json'); + console.log('Load info from: ' + pluginJsonFile); + + const pluginMeta = getPluginJson(pluginJsonFile); + const report: PluginBuildReport = { + plugin: pluginMeta, + packages: packageInfo, + workflow: agregateWorkflowInfo(), + coverage: agregateCoverageInfo(), + tests: agregateTestInfo(), + artifactsBaseURL: await getCircleDownloadBaseURL(), + grafanaVersion: getGrafanaVersions(), + git: await readGitLog(), + }; + const pr = getPullRequestNumber(); + if (pr) { + report.pullRequest = pr; + } + + // Save the report to disk + const file = path.resolve(ciDir, 'report.json'); + fs.writeFileSync(file, JSON.stringify(report, null, 2), { encoding: 'utf-8' }); + + const GRAFANA_API_KEY = process.env.GRAFANA_API_KEY; + if (!GRAFANA_API_KEY) { + console.log('Enter a GRAFANA_API_KEY to upload the plugin report'); + return; + } + const url = `https://grafana.com/api/plugins/${report.plugin.id}/ci`; + + console.log('Sending report to:', url); + const axios = require('axios'); + const info = await axios.post(url, report, { + headers: { Authorization: 'Bearer ' + GRAFANA_API_KEY }, + }); + if (info.status === 200) { + console.log('OK: ', info.data); + } else { + console.warn('Error: ', info); + } +}; + +export const ciPluginReportTask = new Task('Generate Plugin Report', pluginReportRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.create.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.create.ts new file mode 100644 index 00000000..2b9a400d --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.create.ts @@ -0,0 +1,55 @@ +import { prompt } from 'inquirer'; +import path from 'path'; +import { promptConfirm } from '../utils/prompt'; +import { + fetchTemplate, + formatPluginDetails, + getPluginIdFromName, + prepareJsonFiles, + printGrafanaTutorialsDetails, + promptPluginDetails, + promptPluginType, + removeGitFiles, + verifyGitExists, + removeLockFile, +} from './plugin/create'; +import { Task, TaskRunner } from './task'; + +interface PluginCreateOptions { + name?: string; +} + +const pluginCreateRunner: TaskRunner = async ({ name }) => { + const destPath = path.resolve(process.cwd(), getPluginIdFromName(name || '')); + let pluginDetails; + + // 1. Verifying if git exists in user's env as templates are cloned from git templates + await verifyGitExists(); + + // 2. Prompt plugin template + const { type } = await promptPluginType(); + + // 3. Fetch plugin template from GitHub + await fetchTemplate({ type, dest: destPath }); + + // 4. Prompt plugin details + do { + pluginDetails = await promptPluginDetails(name); + formatPluginDetails(pluginDetails); + } while ((await prompt<{ confirm: boolean }>(promptConfirm('confirm', 'Is that ok?'))).confirm === false); + + // 5. Update json files (package.json, src/plugin.json) + await prepareJsonFiles({ type: type, pluginDetails, pluginPath: destPath }); + + // 6. Starter templates include `yarn.lock` files which will rarely (if ever) be in sync with `latest` dist-tag + // so best to remove it after cloning. + removeLockFile({ pluginPath: destPath }); + + // 7. Remove cloned repository .git dir + await removeGitFiles(destPath); + + // 8. Promote Grafana Tutorials :) + printGrafanaTutorialsDetails(type); +}; + +export const pluginCreateTask = new Task('plugin:create task', pluginCreateRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.dev.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.dev.ts new file mode 100644 index 00000000..7585bdf5 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.dev.ts @@ -0,0 +1,48 @@ +import { Task, TaskRunner } from './task'; +import { bundlePlugin as bundleFn, PluginBundleOptions } from './plugin/bundle'; +import { useSpinner } from '../utils/useSpinner'; +import { lintPlugin } from './plugin.build'; +import execa = require('execa'); +import path = require('path'); + +const bundlePlugin = (options: PluginBundleOptions) => + useSpinner('Bundling plugin in dev mode', () => bundleFn(options)); + +const yarnlink = () => + useSpinner('Linking local toolkit', async () => { + try { + // Make sure we are not using package.json defined toolkit + await execa('yarn', ['remove', '@grafana/toolkit']); + } catch (e: any) { + console.log('\n', e.message, '\n'); + } + await execa('yarn', ['link', '@grafana/toolkit']); + + // Add all the same dependencies as toolkit + const args: string[] = ['add']; + const packages = require(path.resolve(__dirname, '../../../package.json')); + for (const [key, value] of Object.entries(packages.dependencies)) { + args.push(`${key}@${value}`); + } + await execa('yarn', args); + + console.log('Added dependencies required by local @grafana/toolkit. Do not checkin this package.json!'); + }); + +const pluginDevRunner: TaskRunner = async (options) => { + if (options.yarnlink) { + return yarnlink(); + } + + if (options.watch) { + await bundleFn(options); + } else { + // Always fix lint in dev mode + await lintPlugin({ fix: true }); + + const result = await bundlePlugin(options); + return result; + } +}; + +export const pluginDevTask = new Task('Dev plugin', pluginDevRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.sign.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.sign.ts new file mode 100644 index 00000000..1a9d2a5b --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.sign.ts @@ -0,0 +1,38 @@ +import path from 'path'; +import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest'; +import { Task, TaskRunner } from './task'; + +interface PluginSignOptions { + signatureType?: string; + rootUrls?: string[]; +} + +const pluginSignRunner: TaskRunner = async ({ signatureType, rootUrls }) => { + const distContentDir = path.resolve('dist'); + + try { + console.log('Building manifest...'); + const manifest = await buildManifest(distContentDir); + // console.log(manifest); + + console.log('Signing manifest...'); + if (signatureType) { + manifest.signatureType = signatureType; + } + if (rootUrls) { + manifest.rootUrls = rootUrls; + } + + const signedManifest = await signManifest(manifest); + // console.log(signedManifest); + + console.log('Saving signed manifest...'); + await saveManifest(distContentDir, signedManifest); + + console.log('Signed successfully'); + } catch (err) { + console.warn(err); + } +}; + +export const pluginSignTask = new Task('plugin:sign task', pluginSignRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.tests.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.tests.ts new file mode 100644 index 00000000..f85c3f18 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.tests.ts @@ -0,0 +1,8 @@ +import { Task, TaskRunner } from './task'; +import { testPlugin, PluginTestOptions } from './plugin/tests'; + +const pluginTestRunner: TaskRunner = async (options) => { + await testPlugin(options); +}; + +export const pluginTestTask = new Task('Test plugin', pluginTestRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.update.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.update.ts new file mode 100644 index 00000000..026d9d05 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.update.ts @@ -0,0 +1,22 @@ +import { Task, TaskRunner } from './task'; +import { useSpinner } from '../utils/useSpinner'; +import fs = require('fs'); +import path = require('path'); + +interface UpdatePluginTask {} + +const updateCiConfig = () => + useSpinner('Updating CircleCI config', async () => { + const ciConfigPath = path.join(process.cwd(), '.circleci'); + if (!fs.existsSync(ciConfigPath)) { + fs.mkdirSync(ciConfigPath); + } + + const sourceFile = require.resolve('@grafana/toolkit/config/circleci/config.yml'); + const destFile = path.join(ciConfigPath, 'config.yml'); + fs.copyFileSync(sourceFile, destFile); + }); + +const pluginUpdateRunner: TaskRunner = () => updateCiConfig(); + +export const pluginUpdateTask = new Task('Update Plugin', pluginUpdateRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts new file mode 100755 index 00000000..2ffeabfc --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts @@ -0,0 +1,212 @@ +import { Task, TaskRunner } from './task'; +import { getPluginJson } from '../../config/utils/pluginValidation'; +import { GitHubRelease } from '../utils/githubRelease'; +import { getPluginId } from '../../config/utils/getPluginId'; +import { getCiFolder } from '../../plugins/env'; +import { useSpinner } from '../utils/useSpinner'; +import path = require('path'); +import execa = require('execa'); + +interface Command extends Array {} +const DEFAULT_EMAIL_ADDRESS = 'eng@grafana.com'; +const DEFAULT_USERNAME = 'CircleCI Automation'; + +const releaseNotes = async (): Promise => { + const { stdout } = await execa(`awk 'BEGIN {FS="##"; RS="##"} FNR==3 {print "##" $1; exit}' CHANGELOG.md`, { + shell: true, + }); + return stdout; +}; + +const checkoutBranch = async (branchName: string): Promise => { + const currentBranch = await execa(`git rev-parse --abbrev-ref HEAD`, { shell: true }); + const branchesAvailable = await execa( + `(git branch -a | grep "${branchName}$" | grep -v remote) || echo 'No release found'`, + { shell: true } + ); + + if (currentBranch.stdout !== branchName) { + console.log('available', branchesAvailable.stdout.trim()); + if (branchesAvailable.stdout.trim() === branchName) { + return ['git', ['checkout', branchName]]; + } else { + return ['git', ['checkout', '-b', branchName]]; + } + } + return []; +}; + +const gitUrlParse = (url: string): { owner: string; name: string } => { + let matchResult: RegExpMatchArray | null = []; + + if (url.match(/^git@github.com/)) { + // We have an ssh style url. + matchResult = url.match(/^git@github.com:(.*?)\/(.*?)\.git/); + } + + if (url.match(/^https:\/\/github.com\//)) { + // We have an https style url + matchResult = url.match(/^https:\/\/github.com\/(.*?)\/(.*?)\/.git/); + } + + if (matchResult && matchResult.length > 2) { + return { + owner: matchResult[1], + name: matchResult[2], + }; + } + + throw `Could not find a suitable git repository. Received [${url}]`; +}; + +const prepareRelease = ({ dryrun, verbose }: any) => + useSpinner('Preparing release', async () => { + const ciDir = getCiFolder(); + const distDir = path.resolve(ciDir, 'dist'); + const distContentDir = path.resolve(distDir, getPluginId()); + const pluginJsonFile = path.resolve(distContentDir, 'plugin.json'); + const pluginJson = getPluginJson(pluginJsonFile); + + const githubPublishScript: Command = [ + ['git', ['config', 'user.email', DEFAULT_EMAIL_ADDRESS]], + ['git', ['config', 'user.name', DEFAULT_USERNAME]], + await checkoutBranch(`release-${pluginJson.info.version}`), + ['/bin/rm', ['-rf', 'dist'], { dryrun }], + ['mv', ['-v', distContentDir, 'dist']], + ['git', ['add', '--force', 'dist'], { dryrun }], + ['/bin/rm', ['-rf', 'src'], { enterprise: true }], + ['git', ['rm', '-rf', 'src'], { enterprise: true }], + [ + 'git', + ['commit', '-m', `automated release ${pluginJson.info.version} [skip ci]`], + { + dryrun, + okOnError: [/nothing to commit/g, /nothing added to commit/g, /no changes added to commit/g], + }, + ], + ['git', ['push', '-f', 'origin', `release-${pluginJson.info.version}`], { dryrun }], + ['git', ['tag', '-f', `v${pluginJson.info.version}`]], + ['git', ['push', '-f', 'origin', `v${pluginJson.info.version}`]], + ]; + + for (let line of githubPublishScript) { + const opts = line.length === 3 ? line[2] : {}; + const command = line[0]; + const args = line[1]; + + try { + if (verbose) { + console.log('executing >>', line); + } + + if (line.length > 0 && line[0].length > 0) { + if (opts['dryrun']) { + line[1].push('--dry-run'); + } + + // Exit if the plugin is NOT an enterprise plugin + if (pluginJson.enterprise && !opts['enterprise']) { + continue; + } + + const { stdout } = await execa(command, args); + if (verbose) { + console.log(stdout); + } + } else { + if (verbose) { + console.log('skipping empty line'); + } + } + } catch (ex: any) { + const err: string = ex.message; + if (opts['okOnError'] && Array.isArray(opts['okOnError'])) { + let trueError = true; + for (let regex of opts['okOnError']) { + if (err.match(regex)) { + trueError = false; + break; + } + } + + if (!trueError) { + // This is not an error + continue; + } + } + console.error(err); + process.exit(-1); + } + } + }); + +interface GithubPublishReleaseOptions { + commitHash?: string; + githubToken: string; + githubUser: string; + gitRepoName: string; +} + +const createRelease = ({ commitHash, githubUser, githubToken, gitRepoName }: GithubPublishReleaseOptions) => + useSpinner('Creating release', async () => { + const gitRelease = new GitHubRelease(githubToken, githubUser, gitRepoName, await releaseNotes(), commitHash); + return gitRelease.release(); + }); + +export interface GithubPublishOptions { + dryrun?: boolean; + verbose?: boolean; + commitHash?: string; + dev?: boolean; +} + +const githubPublishRunner: TaskRunner = async ({ dryrun, verbose, commitHash }) => { + let repoUrl: string | undefined = process.env.DRONE_REPO_LINK || process.env.CIRCLE_REPOSITORY_URL; + if (!repoUrl) { + // Try and figure it out + const repo = await execa('git', ['config', '--local', 'remote.origin.url']); + if (repo && repo.stdout) { + repoUrl = repo.stdout; + } else { + throw new Error( + 'The release plugin requires you specify the repository url as environment variable DRONE_REPO_LINK or ' + + 'CIRCLE_REPOSITORY_URL' + ); + } + } + + if (!process.env['GITHUB_ACCESS_TOKEN']) { + // Try to use GITHUB_TOKEN, which may be set. + if (process.env['GITHUB_TOKEN']) { + process.env['GITHUB_ACCESS_TOKEN'] = process.env['GITHUB_TOKEN']; + } else { + throw new Error( + `GitHub publish requires that you set the environment variable GITHUB_ACCESS_TOKEN to a valid github api token. + See: https://github.com/settings/tokens for more details.` + ); + } + } + + if (!process.env['GITHUB_USERNAME']) { + // We can default this one + process.env['GITHUB_USERNAME'] = DEFAULT_EMAIL_ADDRESS; + } + + const parsedUrl = gitUrlParse(repoUrl); + const githubToken = process.env['GITHUB_ACCESS_TOKEN']; + const githubUser = parsedUrl.owner; + + await prepareRelease({ + dryrun, + verbose, + }); + + await createRelease({ + commitHash, + githubUser, + githubToken, + gitRepoName: parsedUrl.name, + }); +}; + +export const githubPublishTask = new Task('GitHub Publish', githubPublishRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.managed.ts b/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.managed.ts new file mode 100644 index 00000000..052c067a --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.managed.ts @@ -0,0 +1,33 @@ +import { promises as fs } from 'fs'; +import { Task, TaskRunner } from '../task'; +import execa = require('execa'); + +interface BundeManagedOptions {} + +const MANAGED_PLUGINS_PATH = `${process.cwd()}/plugins-bundled`; +const MANAGED_PLUGINS_SCOPES = ['internal', 'external']; + +const bundleManagedPluginsRunner: TaskRunner = async () => { + await Promise.all( + MANAGED_PLUGINS_SCOPES.map(async (scope) => { + try { + const plugins = await fs.readdir(`${MANAGED_PLUGINS_PATH}/${scope}`); + if (plugins.length > 0) { + for (const plugin of plugins) { + try { + console.log(`[${scope}]: ${plugin} building...`); + await execa('yarn', ['build'], { cwd: `${MANAGED_PLUGINS_PATH}/${scope}/${plugin}` }); + console.log(`[${scope}]: ${plugin} bundled`); + } catch (e: any) { + console.log(e.stdout); + } + } + } + } catch (e) { + console.log(e); + } + }) + ); +}; + +export const bundleManagedTask = new Task('Bundle managed plugins', bundleManagedPluginsRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.ts b/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.ts new file mode 100644 index 00000000..003dcf82 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.ts @@ -0,0 +1,81 @@ +import webpack = require('webpack'); +import formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); +import clearConsole = require('react-dev-utils/clearConsole'); +import { loadWebpackConfig } from '../../../config/webpack.plugin.config'; + +export interface PluginBundleOptions { + watch: boolean; + production?: boolean; + yarnlink?: boolean; + preserveConsole?: boolean; +} + +// export const bundlePlugin = ({ watch, production }: PluginBundleOptions) => useSpinner('Bundle plugin', async () => { +export const bundlePlugin = async ({ watch, production, preserveConsole }: PluginBundleOptions) => { + const compiler = webpack( + await loadWebpackConfig({ + watch, + production, + preserveConsole, + }) + ); + + const webpackPromise = new Promise((resolve, reject) => { + if (watch) { + console.log('Started watching plugin for changes...'); + compiler.watch({}, (err, stats) => {}); + + // @ts-ignore + compiler.hooks.invalid.tap('invalid', () => { + clearConsole(); + console.log('Compiling...'); + }); + + compiler.hooks.done.tap('done', (stats: webpack.Stats) => { + clearConsole(); + const json: any = stats.toJson(); // different @types/webpack between react-dev-utils and grafana-toolkit + const output = formatWebpackMessages(json); + + if (!output.errors.length && !output.warnings.length) { + console.log('Compiled successfully!\n'); + console.log(stats.toString({ colors: true })); + } + + if (output.errors.length) { + console.log('Compilation failed!'); + output.errors.forEach((e) => console.log(e)); + + if (output.warnings.length) { + console.log('Warnings:'); + output.warnings.forEach((w) => console.log(w)); + } + } + if (output.errors.length === 0 && output.warnings.length) { + console.log('Compiled with warnings!'); + output.warnings.forEach((w) => console.log(w)); + } + }); + } else { + compiler.run((err: Error, stats: webpack.Stats) => { + if (err) { + reject(err); + return; + } + + if (stats.hasErrors()) { + stats.compilation.errors.forEach((e) => { + console.log(e.message); + }); + + reject('Build failed'); + return; + } + + console.log('\n', stats.toString({ colors: true }), '\n'); + resolve(); + }); + } + }); + + return webpackPromise; +}; diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/create.ts b/packages/grafana-toolkit/src/cli/tasks/plugin/create.ts new file mode 100644 index 00000000..f4f91439 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/create.ts @@ -0,0 +1,198 @@ +import chalk from 'chalk'; +import commandExists from 'command-exists'; +import { promises as fs, readFileSync, existsSync, unlinkSync } from 'fs'; +import { prompt } from 'inquirer'; +import { kebabCase } from 'lodash'; +import path from 'path'; +import gitPromise from 'simple-git'; +import { promptConfirm, promptInput } from '../../utils/prompt'; +import { rmdir } from '../../utils/rmdir'; +import { useSpinner } from '../../utils/useSpinner'; + +const simpleGit = gitPromise(process.cwd()); + +interface PluginDetails { + name: string; + org: string; + description: string; + author: boolean | string; + url: string; + keywords: string; +} + +type PluginType = 'panel-plugin' | 'datasource-plugin' | 'backend-datasource-plugin'; + +const PluginNames: Record = { + 'panel-plugin': 'Grafana Panel Plugin', + 'datasource-plugin': 'Grafana Data Source Plugin', + 'backend-datasource-plugin': 'Grafana Backend Datasource Plugin', +}; +const RepositoriesPaths: Record = { + 'panel-plugin': 'https://github.com/grafana/simple-react-panel.git', + 'datasource-plugin': 'https://github.com/grafana/simple-datasource.git', + 'backend-datasource-plugin': 'https://github.com/grafana/simple-datasource-backend.git', +}; +const TutorialPaths: Record = { + 'panel-plugin': 'https://grafana.com/tutorials/build-a-panel-plugin', + 'datasource-plugin': 'https://grafana.com/tutorials/build-a-data-source-plugin', + 'backend-datasource-plugin': 'TODO', +}; + +export const getGitUsername = async () => { + const name = await simpleGit.raw(['config', '--global', 'user.name']); + return name || ''; +}; +export const getPluginIdFromName = (name: string) => kebabCase(name); +export const getPluginId = (pluginDetails: PluginDetails) => + `${kebabCase(pluginDetails.org)}-${getPluginIdFromName(pluginDetails.name)}`; + +export const getPluginKeywords = (pluginDetails: PluginDetails) => + pluginDetails.keywords + .split(',') + .map((k) => k.trim()) + .filter((k) => k !== ''); + +export const verifyGitExists = async () => { + return new Promise((resolve, reject) => { + commandExists('git', (err, exists) => { + if (exists) { + resolve(true); + } + reject(new Error('git is not installed')); + }); + }); +}; + +export const promptPluginType = async () => + prompt<{ type: PluginType }>([ + { + type: 'list', + message: 'Select plugin type', + name: 'type', + choices: [ + { name: 'Panel Plugin', value: 'panel-plugin' }, + { name: 'Datasource Plugin', value: 'datasource-plugin' }, + { name: 'Backend Datasource Plugin', value: 'backend-datasource-plugin' }, + ], + }, + ]); + +export const promptPluginDetails = async (name?: string) => { + const username = (await getGitUsername()).trim(); + const responses = await prompt([ + promptInput('name', 'Plugin name', true, name), + promptInput('org', 'Organization (used as part of plugin ID)', true), + promptInput('description', 'Description'), + promptInput('keywords', 'Keywords (separated by comma)'), + // Try using git specified username + promptConfirm('author', `Author (${username})`, username, username !== ''), + // Prompt for manual author entry if no git user.name specified + promptInput('author', `Author`, true, undefined, (answers: any) => !answers.author || username === ''), + promptInput('url', 'Your URL (i.e. organisation url)'), + ]); + + return { + ...responses, + author: responses.author === true ? username : responses.author, + }; +}; + +export const fetchTemplate = ({ type, dest }: { type: PluginType; dest: string }) => + useSpinner('Fetching plugin template...', async () => { + const url = RepositoriesPaths[type]; + if (!url) { + throw new Error('Unknown plugin type'); + } + + await simpleGit.clone(url, dest); + }); + +export const prepareJsonFiles = ({ + type, + pluginDetails, + pluginPath, +}: { + type: PluginType; + pluginDetails: PluginDetails; + pluginPath: string; +}) => + useSpinner('Saving package.json and plugin.json files', async () => { + const packageJsonPath = path.resolve(pluginPath, 'package.json'); + const pluginJsonPath = path.resolve(pluginPath, 'src/plugin.json'); + const packageJson: any = JSON.parse(readFileSync(packageJsonPath, 'utf8')); + const pluginJson: any = JSON.parse(readFileSync(pluginJsonPath, 'utf8')); + + const pluginId = `${kebabCase(pluginDetails.org)}-${getPluginIdFromName(pluginDetails.name)}`; + packageJson.name = pluginId; + packageJson.author = pluginDetails.author; + packageJson.description = pluginDetails.description; + + pluginJson.name = pluginDetails.name; + pluginJson.id = pluginId; + + if (type === 'backend-datasource-plugin') { + pluginJson.backend = true; + pluginJson.executable = 'gpx_' + pluginDetails.name; + } + + pluginJson.info = { + ...pluginJson.info, + description: pluginDetails.description, + author: { + name: pluginDetails.author, + url: pluginDetails.url, + }, + keywords: getPluginKeywords(pluginDetails), + }; + + await Promise.all( + [packageJson, pluginJson].map((f, i) => { + const filePath = i === 0 ? packageJsonPath : pluginJsonPath; + return fs.writeFile(filePath, JSON.stringify(f, null, 2)); + }) + ); + }); + +export const removeGitFiles = (pluginPath: string) => + useSpinner('Cleaning', async () => rmdir(`${path.resolve(pluginPath, '.git')}`)); + +/* eslint-disable no-console */ +export const formatPluginDetails = (details: PluginDetails) => { + console.group(); + console.log(); + console.log(chalk.bold.yellow('Your plugin details')); + console.log('---'); + console.log(chalk.bold('Name: '), details.name); + console.log(chalk.bold('ID: '), getPluginId(details)); + console.log(chalk.bold('Description: '), details.description); + console.log(chalk.bold('Keywords: '), getPluginKeywords(details)); + console.log(chalk.bold('Author: '), details.author); + console.log(chalk.bold('Organisation: '), details.org); + console.log(chalk.bold('Website: '), details.url); + console.log(); + console.groupEnd(); +}; + +export const printGrafanaTutorialsDetails = (type: PluginType) => { + console.group(); + console.log(); + console.log(chalk.bold.yellow(`Congrats! You have just created ${PluginNames[type]}.`)); + console.log('Please run `yarn install` to install frontend dependencies.'); + console.log(); + if (type !== 'backend-datasource-plugin') { + console.log(`${PluginNames[type]} tutorial: ${TutorialPaths[type]}`); + } + console.log( + 'Learn more about Grafana Plugins at https://grafana.com/docs/grafana/latest/plugins/developing/development/' + ); + console.log(); + console.groupEnd(); +}; +/* eslint-enable no-console */ + +export const removeLockFile = ({ pluginPath }: { pluginPath: string }) => { + const lockFilePath = path.resolve(pluginPath, 'yarn.lock'); + if (existsSync(lockFilePath)) { + unlinkSync(lockFilePath); + } +}; diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/test_exclude_image_suffix_in_manifest.png b/packages/grafana-toolkit/src/cli/tasks/plugin/test_exclude_image_suffix_in_manifest.png new file mode 100644 index 00000000..bb07b075 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/test_exclude_image_suffix_in_manifest.png @@ -0,0 +1 @@ +NOTE: not a real image, but should be excluded from hashed files \ No newline at end of file diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/tests.ts b/packages/grafana-toolkit/src/cli/tasks/plugin/tests.ts new file mode 100644 index 00000000..dd47ba09 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/tests.ts @@ -0,0 +1,49 @@ +import { runCLI } from '@jest/core'; +import { useSpinner } from '../../utils/useSpinner'; +import { loadJestPluginConfig } from '../../../config/jest.plugin.config'; + +export interface PluginTestOptions { + updateSnapshot: boolean; + coverage: boolean; + watch: boolean; + testPathPattern?: string; + testNamePattern?: string; + maxWorkers?: string; +} + +export const testPlugin = ({ + updateSnapshot, + coverage, + watch, + testPathPattern, + testNamePattern, + maxWorkers, +}: PluginTestOptions) => + useSpinner('Running tests', async () => { + const testConfig = loadJestPluginConfig(); + + const cliConfig = { + config: JSON.stringify(testConfig), + updateSnapshot, + coverage, + watch, + testPathPattern: testPathPattern ? [testPathPattern] : [], + testNamePattern: testNamePattern ? [testNamePattern] : [], + passWithNoTests: true, + maxWorkers, + }; + + // @ts-ignore + const runJest = () => runCLI(cliConfig, [process.cwd()]); + + if (watch) { + runJest(); + } else { + // @ts-ignore + const results = await runJest(); + + if (results.results.numFailedTests > 0 || results.results.numFailedTestSuites > 0) { + throw new Error('Tests failed'); + } + } + }); diff --git a/packages/grafana-toolkit/src/cli/tasks/searchTestDataSetup.ts b/packages/grafana-toolkit/src/cli/tasks/searchTestDataSetup.ts new file mode 100644 index 00000000..84c0ac0c --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/searchTestDataSetup.ts @@ -0,0 +1,116 @@ +import axios from 'axios'; +import { Task, TaskRunner } from './task'; + +interface SearchTestDataSetupOptions { + count: number; +} + +const client = axios.create({ + baseURL: 'http://localhost:3000/api', + auth: { + username: 'admin', + password: 'admin2', + }, +}); + +export async function getUser(user: any): Promise { + console.log('Creating user ' + user.name); + const search = await client.get('/users/search', { + params: { query: user.login }, + }); + + if (search.data.totalCount === 1) { + user.id = search.data.users[0].id; + return user; + } + + const rsp = await client.post('/admin/users', user); + user.id = rsp.data.id; + return user; +} + +export async function getTeam(team: any): Promise { + // delete if exists + const teams = await client.get('/teams/search'); + for (const existing of teams.data.teams) { + if (existing.name === team.name) { + console.log('Team exists, deleting'); + await client.delete('/teams/' + existing.id); + } + } + + console.log('Creating team ' + team.name); + const teamRsp = await client.post(`/teams`, team); + team.id = teamRsp.data.teamId; + return team; +} + +export async function addToTeam(team: any, user: any): Promise { + console.log(`Adding user ${user.name} to team ${team.name}`); + await client.post(`/teams/${team.id}/members`, { userId: user.id }); +} + +export async function setDashboardAcl(dashboardId: any, aclList: any) { + console.log('Setting Dashboard ACL ' + dashboardId); + await client.post(`/dashboards/id/${dashboardId}/permissions`, { items: aclList }); +} + +const searchTestDataSetupRunner: TaskRunner = async ({ count }) => { + const user1 = await getUser({ + name: 'searchTestUser1', + email: 'searchTestUser@team.com', + login: 'searchTestUser1', + password: '12345', + }); + + const team1 = await getTeam({ name: 'searchTestTeam1', email: 'searchtestdata@team.com' }); + addToTeam(team1, user1); + + // create or update folder + const folder: any = { + uid: 'search-test-data', + title: 'Search test data folder', + version: 1, + }; + + try { + await client.delete(`/folders/${folder.uid}`); + } catch (err) {} + + console.log('Creating folder'); + + const rsp = await client.post(`/folders`, folder); + folder.id = rsp.data.id; + folder.url = rsp.data.url; + + await setDashboardAcl(folder.id, []); + + console.log('Creating dashboards'); + + const dashboards: any = []; + + for (let i = 0; i < count; i++) { + const dashboard: any = { + uid: 'search-test-dash-' + i.toString().padStart(5, '0'), + title: 'Search test dash ' + i.toString().padStart(5, '0'), + }; + + const rsp = await client.post(`/dashboards/db`, { + dashboard: dashboard, + folderId: folder.id, + overwrite: true, + }); + + dashboard.id = rsp.data.id; + dashboard.url = rsp.data.url; + + console.log('Created dashboard ' + dashboard.title); + dashboards.push(dashboard); + await setDashboardAcl(dashboard.id, [{ userId: 0, teamId: team1.id, permission: 4 }]); + } +}; + +export const searchTestDataSetupTask = new Task( + 'Search test data setup', + searchTestDataSetupRunner +); diff --git a/packages/grafana-toolkit/src/cli/tasks/task.ts b/packages/grafana-toolkit/src/cli/tasks/task.ts new file mode 100644 index 00000000..4524508b --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/task.ts @@ -0,0 +1,22 @@ +export type TaskRunner = (options: T) => Promise; + +export class Task { + options: TOptions = {} as any; + + constructor(public name: string, public runner: TaskRunner) {} + setName = (name: string) => { + this.name = name; + }; + + setRunner = (runner: TaskRunner) => { + this.runner = runner; + }; + + setOptions = (options: TOptions) => { + this.options = options; + }; + + exec = () => { + return this.runner(this.options); + }; +} diff --git a/packages/grafana-toolkit/src/cli/tasks/template.ts b/packages/grafana-toolkit/src/cli/tasks/template.ts new file mode 100644 index 00000000..4a965e05 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/template.ts @@ -0,0 +1,9 @@ +import { Task, TaskRunner } from './task'; + +interface TemplateOptions {} + +const templateRunner: TaskRunner = async () => { + console.log('Template task'); +}; + +export const templateTask = new Task('Template task', templateRunner); diff --git a/packages/grafana-toolkit/src/cli/tasks/toolkit.build.ts b/packages/grafana-toolkit/src/cli/tasks/toolkit.build.ts new file mode 100644 index 00000000..47ccccd0 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tasks/toolkit.build.ts @@ -0,0 +1,123 @@ +import execa = require('execa'); +import * as fs from 'fs'; +import chalk from 'chalk'; +import { useSpinner } from '../utils/useSpinner'; +import { Task, TaskRunner } from './task'; + +const path = require('path'); + +let distDir: string, cwd: string; + +const clean = () => useSpinner('Cleaning', () => execa('npm', ['run', 'clean'])); + +const compile = () => + useSpinner('Compiling sources', async () => { + try { + await execa('tsc', ['-p', './tsconfig.json']); + } catch (e) { + console.log(e); + throw e; + } + }); + +const savePackage = ({ path, pkg }: { path: string; pkg: {} }) => + useSpinner('Updating package.json', async () => { + new Promise((resolve, reject) => { + fs.writeFile(path, JSON.stringify(pkg, null, 2), (err) => { + if (err) { + reject(err); + return; + } + resolve(); + }); + }); + }); + +const preparePackage = async (pkg: any) => { + pkg.bin = { + 'grafana-toolkit': './bin/grafana-toolkit.js', + }; + + await savePackage({ + path: `${cwd}/dist/package.json`, + pkg, + }); +}; + +const copyFiles = () => { + const files = [ + 'README.md', + 'CHANGELOG.md', + 'config/circleci/config.yml', + 'bin/grafana-toolkit.js', + 'src/config/prettier.plugin.config.json', + 'src/config/prettier.plugin.rc.js', + 'src/config/tsconfig.plugin.json', + 'src/config/tsconfig.plugin.local.json', + 'src/config/eslint.plugin.js', + 'src/config/styles.mock.js', + 'src/config/jest.plugin.config.local.js', + 'src/config/matchMedia.js', + 'src/config/react-inlinesvg.tsx', + ]; + + return useSpinner(`Moving ${files.join(', ')} files`, async () => { + const promises = files.map((file) => { + return new Promise((resolve, reject) => { + const basedir = path.dirname(`${distDir}/${file}`); + if (!fs.existsSync(basedir)) { + fs.mkdirSync(basedir, { recursive: true }); + } + fs.copyFile(`${cwd}/${file}`, `${distDir}/${file}`, (err) => { + if (err) { + reject(err); + return; + } + resolve(); + }); + }); + }); + + await Promise.all(promises); + }); +}; + +const copySassFiles = () => { + const files = ['_variables.generated.scss', '_variables.dark.generated.scss', '_variables.light.generated.scss']; + return useSpinner(`Copy scss files ${files.join(', ')} files`, async () => { + const sassDir = path.resolve(cwd, '../../public/sass/'); + const promises = files.map((file) => { + return new Promise((resolve, reject) => { + const name = file.replace('.generated', ''); + fs.copyFile(`${sassDir}/${file}`, `${distDir}/sass/${name}`, (err) => { + if (err) { + reject(err); + return; + } + resolve(); + }); + }); + }); + + await Promise.all(promises); + }); +}; + +interface ToolkitBuildOptions {} + +const toolkitBuildTaskRunner: TaskRunner = async () => { + cwd = path.resolve(__dirname, '../../../'); + distDir = `${cwd}/dist`; + const pkg = require(`${cwd}/package.json`); + console.log(chalk.yellow(`Building ${pkg.name} (package.json version: ${pkg.version})`)); + + await clean(); + await compile(); + await preparePackage(pkg); + fs.mkdirSync('./dist/bin'); + fs.mkdirSync('./dist/sass'); + await copyFiles(); + await copySassFiles(); +}; + +export const toolkitBuildTask = new Task('@grafana/toolkit build', toolkitBuildTaskRunner); diff --git a/packages/grafana-toolkit/src/cli/templates/component.test.tsx.template.ts b/packages/grafana-toolkit/src/cli/templates/component.test.tsx.template.ts new file mode 100644 index 00000000..b6737fea --- /dev/null +++ b/packages/grafana-toolkit/src/cli/templates/component.test.tsx.template.ts @@ -0,0 +1,12 @@ +export const testTpl = ` +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { <%= name %> } from './<%= name %>'; + + +describe('<%= name %>', () => { + it.skip('should render', () => { + + }); +}); +`; diff --git a/packages/grafana-toolkit/src/cli/templates/component.tsx.template.ts b/packages/grafana-toolkit/src/cli/templates/component.tsx.template.ts new file mode 100644 index 00000000..7345eb52 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/templates/component.tsx.template.ts @@ -0,0 +1,10 @@ +export const componentTpl = `import React, { FC } from 'react'; + +export interface Props {}; + +export const <%= name %>: FC = (props) => { + return ( +
Hello world!
+ ) +}; +`; diff --git a/packages/grafana-toolkit/src/cli/templates/docs.mdx.template.ts b/packages/grafana-toolkit/src/cli/templates/docs.mdx.template.ts new file mode 100644 index 00000000..b605f755 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/templates/docs.mdx.template.ts @@ -0,0 +1,16 @@ +export const docsTpl = `import { ArgsTable } from '@storybook/addon-docs/blocks'; +import { <%= name %> } from './<%= name %>'; + +# <%= name %> + +### Usage + +\`\`\`jsx +import { <%= name %> } from '@grafana/ui'; + +<<%= name %> /> +\`\`\` + +### Props +} /> +`; diff --git a/packages/grafana-toolkit/src/cli/templates/index.ts b/packages/grafana-toolkit/src/cli/templates/index.ts new file mode 100644 index 00000000..57a7319c --- /dev/null +++ b/packages/grafana-toolkit/src/cli/templates/index.ts @@ -0,0 +1,4 @@ +export { componentTpl } from './component.tsx.template'; +export { storyTpl } from './story.tsx.template'; +export { docsTpl } from './docs.mdx.template'; +export { testTpl } from './component.test.tsx.template'; diff --git a/packages/grafana-toolkit/src/cli/templates/story.tsx.template.ts b/packages/grafana-toolkit/src/cli/templates/story.tsx.template.ts new file mode 100644 index 00000000..21c87a1f --- /dev/null +++ b/packages/grafana-toolkit/src/cli/templates/story.tsx.template.ts @@ -0,0 +1,22 @@ +export const storyTpl = ` +import React from 'react'; +import { <%= name %> } from './<%= name %>'; +import { withCenteredStory } from '@grafana/ui/src/utils/storybook/withCenteredStory'; +import mdx from './<%= name %>.mdx'; + + +export default { + title: '<%= group %>/<%= name %>', + component: <%= name %>, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const Basic = () => { + return <<%= name %> />; +}; +`; diff --git a/packages/grafana-toolkit/src/cli/tsconfig.json b/packages/grafana-toolkit/src/cli/tsconfig.json new file mode 100644 index 00000000..36f0eda1 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "module": "commonjs" + }, + "extends": "@grafana/tsconfig" +} diff --git a/packages/grafana-toolkit/src/cli/utils/execTask.ts b/packages/grafana-toolkit/src/cli/utils/execTask.ts new file mode 100644 index 00000000..03d0a885 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/execTask.ts @@ -0,0 +1,23 @@ +/* eslint-disable no-console */ +import { Task } from '../tasks/task'; +import chalk from 'chalk'; + +interface TaskBasicOptions { + // Don't print task details when running + silent?: boolean; +} + +export const execTask = (task: Task) => async (options: TOptions & TaskBasicOptions) => { + if (!options.silent) { + console.log(chalk.yellow(`Running ${chalk.bold(task.name)} task`)); + } + task.setOptions(options); + try { + console.group(); + await task.exec(); + console.groupEnd(); + } catch (e) { + console.trace(e); + process.exit(1); + } +}; diff --git a/packages/grafana-toolkit/src/cli/utils/githubClient.test.ts b/packages/grafana-toolkit/src/cli/utils/githubClient.test.ts new file mode 100644 index 00000000..ff6cfb0b --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/githubClient.test.ts @@ -0,0 +1,107 @@ +import GithubClient from './githubClient'; + +const fakeClient = jest.fn(); + +beforeEach(() => { + delete process.env.GITHUB_USERNAME; + delete process.env.GITHUB_ACCESS_TOKEN; +}); + +afterEach(() => { + delete process.env.GITHUB_USERNAME; + delete process.env.GITHUB_ACCESS_TOKEN; +}); + +describe('GithubClient', () => { + it('should initialise a GithubClient', () => { + const github = new GithubClient(); + const githubEnterprise = new GithubClient({ enterprise: true }); + expect(github).toBeInstanceOf(GithubClient); + expect(githubEnterprise).toBeInstanceOf(GithubClient); + }); + + describe('#client', () => { + it('it should contain a grafana client', () => { + // @ts-ignore + const spy = jest.spyOn(GithubClient.prototype, 'createClient').mockImplementation(() => fakeClient); + + const github = new GithubClient(); + const client = github.client; + + expect(spy).toHaveBeenCalledWith({ + baseURL: 'https://api.github.com/repos/grafana/grafana', + timeout: 10000, + }); + expect(client).toEqual(fakeClient); + }); + + it('it should contain a grafana enterprise client', () => { + // @ts-ignore + const spy = jest.spyOn(GithubClient.prototype, 'createClient').mockImplementation(() => fakeClient); + + const github = new GithubClient({ enterprise: true }); + const client = github.client; + + expect(spy).toHaveBeenCalledWith({ + baseURL: 'https://api.github.com/repos/grafana/grafana-enterprise', + timeout: 10000, + }); + expect(client).toEqual(fakeClient); + }); + + describe('when the credentials are required', () => { + it('should create the client when the credentials are defined', () => { + const username = 'grafana'; + const token = 'averysecureaccesstoken'; + + process.env.GITHUB_USERNAME = username; + process.env.GITHUB_ACCESS_TOKEN = token; + + // @ts-ignore + const spy = jest.spyOn(GithubClient.prototype, 'createClient').mockImplementation(() => fakeClient); + + const github = new GithubClient({ required: true }); + const client = github.client; + + expect(spy).toHaveBeenCalledWith({ + baseURL: 'https://api.github.com/repos/grafana/grafana', + timeout: 10000, + auth: { username, password: token }, + }); + + expect(client).toEqual(fakeClient); + }); + + it('should create the enterprise client when the credentials are defined', () => { + const username = 'grafana'; + const token = 'averysecureaccesstoken'; + + process.env.GITHUB_USERNAME = username; + process.env.GITHUB_ACCESS_TOKEN = token; + + // @ts-ignore + const spy = jest.spyOn(GithubClient.prototype, 'createClient').mockImplementation(() => fakeClient); + + const github = new GithubClient({ required: true, enterprise: true }); + const client = github.client; + + expect(spy).toHaveBeenCalledWith({ + baseURL: 'https://api.github.com/repos/grafana/grafana-enterprise', + timeout: 10000, + auth: { username, password: token }, + }); + + expect(client).toEqual(fakeClient); + }); + + describe('when the credentials are not defined', () => { + it('should throw an error', () => { + expect(() => { + // eslint-disable-next-line + new GithubClient({ required: true }); + }).toThrow(/operation needs a GITHUB_USERNAME and GITHUB_ACCESS_TOKEN environment variables/); + }); + }); + }); + }); +}); diff --git a/packages/grafana-toolkit/src/cli/utils/githubClient.ts b/packages/grafana-toolkit/src/cli/utils/githubClient.ts new file mode 100644 index 00000000..9643c166 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/githubClient.ts @@ -0,0 +1,49 @@ +import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'; + +const grafanaURL = (owner: string, repo: string) => `https://api.github.com/repos/${owner}/${repo}`; +const enterpriseURL = 'https://api.github.com/repos/grafana/grafana-enterprise'; + +// Encapsulates the creation of a client for the GitHub API +// +// Two key things: +// 1. You can specify whenever you want the credentials to be required or not when imported. +// 2. If the credentials are available as part of the environment, even if +// they're not required - the library will use them. This allows us to overcome +// any API rate limiting imposed without authentication. + +interface GithubClientProps { + required?: boolean; + enterprise?: boolean; + owner?: string; + repo?: string; +} + +class GithubClient { + client: AxiosInstance; + + constructor({ required = false, enterprise = false, owner = 'grafana', repo = 'grafana' }: GithubClientProps = {}) { + const username = process.env.GITHUB_USERNAME; + const token = process.env.GITHUB_ACCESS_TOKEN; + + const clientConfig: AxiosRequestConfig = { + baseURL: enterprise ? enterpriseURL : grafanaURL(owner, repo), + timeout: 10000, + }; + + if (required && !username && !token) { + throw new Error('operation needs a GITHUB_USERNAME and GITHUB_ACCESS_TOKEN environment variables'); + } + + if (username && token) { + clientConfig.auth = { username: username, password: token }; + } + + this.client = this.createClient(clientConfig); + } + + private createClient(clientConfig: AxiosRequestConfig) { + return axios.create(clientConfig); + } +} + +export default GithubClient; diff --git a/packages/grafana-toolkit/src/cli/utils/githubRelease.test.ts b/packages/grafana-toolkit/src/cli/utils/githubRelease.test.ts new file mode 100644 index 00000000..74fedc2a --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/githubRelease.test.ts @@ -0,0 +1,10 @@ +import { GitHubRelease } from './githubRelease'; + +describe('GithubRelease', () => { + it('should initialise a GithubRelease', () => { + process.env.GITHUB_ACCESS_TOKEN = '12345'; + process.env.GITHUB_USERNAME = 'test@grafana.com'; + const github = new GitHubRelease('A token', 'A username', 'A repo', 'Some release notes'); + expect(github).toBeInstanceOf(GitHubRelease); + }); +}); diff --git a/packages/grafana-toolkit/src/cli/utils/githubRelease.ts b/packages/grafana-toolkit/src/cli/utils/githubRelease.ts new file mode 100644 index 00000000..a63a5609 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/githubRelease.ts @@ -0,0 +1,111 @@ +import { getPluginId } from '../../config/utils/getPluginId'; +import { getPluginJson } from '../../config/utils/pluginValidation'; +import { getCiFolder } from '../../plugins/env'; +import path = require('path'); +import fs = require('fs'); +import GithubClient from './githubClient'; +import { AxiosResponse } from 'axios'; + +const resolveContentType = (extension: string): string => { + if (extension.startsWith('.')) { + extension = extension.substr(1); + } + switch (extension) { + case 'zip': + return 'application/zip'; + case 'json': + return 'application/json'; + case 'sha1': + return 'text/plain'; + default: + return 'application/octet-stream'; + } +}; + +class GitHubRelease { + token: string; + username: string; + repository: string; + releaseNotes: string; + commitHash?: string; + git: GithubClient; + + constructor(token: string, username: string, repository: string, releaseNotes: string, commitHash?: string) { + this.token = token; + this.username = username; + this.repository = repository; + this.releaseNotes = releaseNotes; + this.commitHash = commitHash; + + this.git = new GithubClient({ + required: true, + owner: username, + repo: repository, + }); + } + + publishAssets(srcLocation: string, destUrl: string) { + // Add the assets. Loop through files in the ci/dist folder and upload each asset. + const files = fs.readdirSync(srcLocation); + + return files.map(async (file: string) => { + const fileStat = fs.statSync(`${srcLocation}/${file}`); + const fileData = fs.readFileSync(`${srcLocation}/${file}`); + return this.git.client.post(`${destUrl}?name=${file}`, fileData, { + headers: { + 'Content-Type': resolveContentType(path.extname(file)), + 'Content-Length': fileStat.size, + }, + maxContentLength: fileStat.size * 2 * 1024 * 1024, + }); + }); + } + + async release() { + const ciDir = getCiFolder(); + const distDir = path.resolve(ciDir, 'dist'); + const distContentDir = path.resolve(distDir, getPluginId()); + const pluginJsonFile = path.resolve(distContentDir, 'plugin.json'); + const pluginInfo = getPluginJson(pluginJsonFile).info; + const PUBLISH_DIR = path.resolve(getCiFolder(), 'packages'); + const commitHash = this.commitHash || pluginInfo.build?.hash; + + try { + const latestRelease: AxiosResponse = await this.git.client.get(`releases/tags/v${pluginInfo.version}`); + + // Re-release if the version is the same as an existing release + if (latestRelease.data.tag_name === `v${pluginInfo.version}`) { + await this.git.client.delete(`releases/${latestRelease.data.id}`); + } + } catch (reason: any) { + if (reason.response.status !== 404) { + // 404 just means no release found. Not an error. Anything else though, re throw the error + throw reason; + } + } + + try { + // Now make the release + const newReleaseResponse = await this.git.client.post('releases', { + tag_name: `v${pluginInfo.version}`, + target_commitish: commitHash, + name: `v${pluginInfo.version}`, + body: this.releaseNotes, + draft: false, + prerelease: false, + }); + + const publishPromises = this.publishAssets( + PUBLISH_DIR, + `https://uploads.github.com/repos/${this.username}/${this.repository}/releases/${newReleaseResponse.data.id}/assets` + ); + await Promise.all(publishPromises); + } catch (reason: any) { + console.error(reason.data?.message ?? reason.response.data ?? reason); + // Rethrow the error so that we can trigger a non-zero exit code to circle-ci + throw reason; + } + } +} + +export { GitHubRelease }; diff --git a/packages/grafana-toolkit/src/cli/utils/pascalCase.ts b/packages/grafana-toolkit/src/cli/utils/pascalCase.ts new file mode 100644 index 00000000..17694ef5 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/pascalCase.ts @@ -0,0 +1,3 @@ +import { flow, camelCase, upperFirst } from 'lodash'; + +export const pascalCase = flow([camelCase, upperFirst]); diff --git a/packages/grafana-toolkit/src/cli/utils/prompt.ts b/packages/grafana-toolkit/src/cli/utils/prompt.ts new file mode 100644 index 00000000..668f64c7 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/prompt.ts @@ -0,0 +1,79 @@ +import { + Question, + InputQuestion, + CheckboxQuestion, + NumberQuestion, + PasswordQuestion, + EditorQuestion, + ConfirmQuestion, + ListQuestion, + ChoiceOptions, +} from 'inquirer'; + +type QuestionWithValidation = + | InputQuestion + | CheckboxQuestion + | NumberQuestion + | PasswordQuestion + | EditorQuestion; + +export const answerRequired = (question: QuestionWithValidation): Question => { + return { + ...question, + validate: (answer: any) => answer.trim() !== '' || `${question.name} is required`, + }; +}; + +export const promptInput = ( + name: string, + message: string | ((answers: A) => string), + required = false, + def: any = undefined, + when: boolean | ((answers: A) => boolean | Promise) = true +) => { + const model: InputQuestion = { + type: 'input', + name, + message, + default: def, + when, + }; + + return required ? answerRequired(model) : model; +}; + +export const promptList = ( + name: string, + message: string | ((answers: A) => string), + choices: () => ChoiceOptions[], + def: any = undefined, + when: boolean | ((answers: A) => boolean | Promise) = true +) => { + const model: ListQuestion = { + type: 'list', + name, + message, + choices, + default: def, + when, + }; + + return model; +}; + +export const promptConfirm = ( + name: string, + message: string | ((answers: A) => string), + def: any = undefined, + when: boolean | ((answers: A) => boolean | Promise) = true +) => { + const model: ConfirmQuestion = { + type: 'confirm', + name, + message, + default: def, + when, + }; + + return model; +}; diff --git a/packages/grafana-toolkit/src/cli/utils/rmdir.ts b/packages/grafana-toolkit/src/cli/utils/rmdir.ts new file mode 100644 index 00000000..f1065628 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/rmdir.ts @@ -0,0 +1,23 @@ +import fs = require('fs'); +import path = require('path'); + +/** + * Remove directory recursively + * Ref https://stackoverflow.com/a/42505874 + */ +export const rmdir = (dirPath: string) => { + if (!fs.existsSync(dirPath)) { + return; + } + + fs.readdirSync(dirPath).forEach((entry) => { + const entryPath = path.join(dirPath, entry); + if (fs.lstatSync(entryPath).isDirectory()) { + rmdir(entryPath); + } else { + fs.unlinkSync(entryPath); + } + }); + + fs.rmdirSync(dirPath); +}; diff --git a/packages/grafana-toolkit/src/cli/utils/useSpinner.ts b/packages/grafana-toolkit/src/cli/utils/useSpinner.ts new file mode 100644 index 00000000..6ba94e33 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/useSpinner.ts @@ -0,0 +1,23 @@ +import ora from 'ora'; + +export const useSpinner = async (label: string, fn: () => Promise, killProcess = true) => { + const spinner = ora(label); + spinner.start(); + try { + await fn(); + spinner.succeed(); + } catch (err: any) { + spinner.fail(err.message || err); + + if (err.stdout) { + console.error(err.stdout); + } else if (err.message) { + // Return stack trace if error object + console.trace(err); // eslint-disable-line no-console + } + + if (killProcess) { + process.exit(1); + } + } +}; diff --git a/packages/grafana-toolkit/src/config/eslint.plugin.js b/packages/grafana-toolkit/src/config/eslint.plugin.js new file mode 100644 index 00000000..35cd51a7 --- /dev/null +++ b/packages/grafana-toolkit/src/config/eslint.plugin.js @@ -0,0 +1,8 @@ +require('@rushstack/eslint-patch/modern-module-resolution'); + +module.exports = { + extends: ['@grafana/eslint-config'], + rules: { + 'react/prop-types': 'off', + }, +}; diff --git a/packages/grafana-toolkit/src/config/index.ts b/packages/grafana-toolkit/src/config/index.ts new file mode 100644 index 00000000..ccb2e12e --- /dev/null +++ b/packages/grafana-toolkit/src/config/index.ts @@ -0,0 +1 @@ +export { CustomWebpackConfigurationGetter, WebpackConfigurationOptions } from './webpack.plugin.config'; diff --git a/packages/grafana-toolkit/src/config/jest.plugin.config.local.js b/packages/grafana-toolkit/src/config/jest.plugin.config.local.js new file mode 100644 index 00000000..bcf17c90 --- /dev/null +++ b/packages/grafana-toolkit/src/config/jest.plugin.config.local.js @@ -0,0 +1,8 @@ +// This file is needed because it is used by vscode and other tools that +// call `jest` directly. However, unless you are doing anything special +// do not edit this file + +const standard = require('@grafana/toolkit/src/config/jest.plugin.config'); + +// This process will use the same config that `yarn test` is using +module.exports = standard.jestConfig(); diff --git a/packages/grafana-toolkit/src/config/jest.plugin.config.test.ts b/packages/grafana-toolkit/src/config/jest.plugin.config.test.ts new file mode 100644 index 00000000..021d5c37 --- /dev/null +++ b/packages/grafana-toolkit/src/config/jest.plugin.config.test.ts @@ -0,0 +1,40 @@ +import { jestConfig, allowedJestConfigOverrides } from './jest.plugin.config'; + +describe('Jest config', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('should throw if not supported overrides provided', () => { + // Do not show console error,log when running test + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + const getConfig = () => jestConfig(`${__dirname}/mocks/jestSetup/unsupportedOverrides`); + + expect(getConfig).toThrow('Provided Jest config is not supported'); + }); + + it(`should allow ${allowedJestConfigOverrides} settings overrides`, () => { + const config = jestConfig(`${__dirname}/mocks/jestSetup/overrides`); + const configKeys = Object.keys(config); + + for (const whitelistedOption of allowedJestConfigOverrides) { + expect(configKeys).toContain(whitelistedOption); + } + }); + + describe('stylesheets support', () => { + it('should provide module name mapper for stylesheets by default', () => { + const config = jestConfig(`${__dirname}/mocks/jestSetup/noOverrides`); + expect(config.moduleNameMapper).toBeDefined(); + expect(Object.keys(config.moduleNameMapper)).toContain('\\.(css|sass|scss)$'); + }); + + it('should preserve mapping for stylesheets when moduleNameMapper overrides provided', () => { + const config = jestConfig(`${__dirname}/mocks/jestSetup/overrides`); + expect(config.moduleNameMapper).toBeDefined(); + expect(Object.keys(config.moduleNameMapper)).toContain('\\.(css|sass|scss)$'); + expect(Object.keys(config.moduleNameMapper)).toContain('someOverride'); + }); + }); +}); diff --git a/packages/grafana-toolkit/src/config/jest.plugin.config.ts b/packages/grafana-toolkit/src/config/jest.plugin.config.ts new file mode 100644 index 00000000..c0539c4d --- /dev/null +++ b/packages/grafana-toolkit/src/config/jest.plugin.config.ts @@ -0,0 +1,113 @@ +import path = require('path'); +import fs from 'fs'; + +export const allowedJestConfigOverrides = [ + 'snapshotSerializers', + 'moduleNameMapper', + 'globalSetup', + 'globalTeardown', + 'testEnvironment', +]; + +interface EnabledJestConfigOverrides { + snapshotSerializers: string[]; + moduleNameMapper: { [key: string]: string }; +} + +const getSetupFile = (filePath: string) => { + if (fs.existsSync(`${filePath}.js`)) { + return `${filePath}.js`; + } + if (fs.existsSync(`${filePath}.ts`)) { + return `${filePath}.ts`; + } + return undefined; +}; + +export const jestConfig = (baseDir: string = process.cwd()) => { + const jestConfigOverrides = (require(path.resolve(baseDir, 'package.json')).jest || {}) as EnabledJestConfigOverrides; + + const deniedOverrides = jestConfigOverrides + ? Object.keys(jestConfigOverrides).filter((override) => allowedJestConfigOverrides.indexOf(override) === -1) + : []; + + if (deniedOverrides.length > 0) { + console.error("\ngrafana-toolkit doesn't support following Jest options: ", deniedOverrides); + console.log('Supported Jest options are: ', JSON.stringify(allowedJestConfigOverrides)); + throw new Error('Provided Jest config is not supported'); + } + + const shimsFilePath = path.resolve(baseDir, 'config/jest-shim'); + const setupFilePath = path.resolve(baseDir, 'config/jest-setup'); + + // Mock css imports for tests. Otherwise Jest will have troubles understanding SASS/CSS imports + const { moduleNameMapper, ...otherOverrides } = jestConfigOverrides; + const moduleNameMapperConfig = { + '\\.(css|sass|scss)$': `${__dirname}/styles.mock.js`, + 'react-inlinesvg': `${__dirname}/react-inlinesvg.tsx`, + ...moduleNameMapper, + }; + + const setupFile = getSetupFile(setupFilePath); + const shimsFile = getSetupFile(shimsFilePath); + + const setupFiles = [setupFile, shimsFile, `${__dirname}/matchMedia.js`, require.resolve('jest-canvas-mock')].filter( + (f) => f + ); + const defaultJestConfig = { + verbose: false, + moduleDirectories: ['node_modules', 'src'], + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], + setupFiles, + globals: { + 'ts-jest': { + isolatedModules: true, + tsconfig: path.resolve(baseDir, 'tsconfig.json'), + }, + }, + coverageReporters: ['json-summary', 'text', 'lcov'], + collectCoverageFrom: ['src/**/*.{ts,tsx}', '!**/node_modules/**', '!**/vendor/**'], + reporters: [ + 'default', + [ + require.resolve('jest-junit'), + { + outputDirectory: 'coverage', + }, + ], + ], + testEnvironment: require.resolve('jest-environment-jsdom-fifteen'), + testMatch: [ + '/src/**/__tests__/**/*.{js,jsx,ts,tsx}', + '/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}', + '/spec/**/*.{spec,test,jest}.{js,jsx,ts,tsx}', + ], + transform: { + '^.+\\.js$': 'babel-jest', + '^.+\\.tsx?$': require.resolve('ts-jest'), + }, + transformIgnorePatterns: [ + '[/\\\\\\\\]node_modules[/\\\\\\\\].+\\\\.(js|jsx|ts|tsx)$', + '^.+\\\\.module\\\\.(css|sass|scss)$', + ], + moduleNameMapper: moduleNameMapperConfig, + }; + + return { + ...defaultJestConfig, + ...otherOverrides, + }; +}; + +/** + * This will load the existing just setup, or use the default if it exists + */ +export const loadJestPluginConfig = (baseDir: string = process.cwd()) => { + const cfgpath = path.resolve(baseDir, 'jest.config.js'); + if (!fs.existsSync(cfgpath)) { + const src = path.resolve(baseDir, 'node_modules/@grafana/toolkit/src/config/jest.plugin.config.local.js'); + fs.copyFileSync(src, cfgpath); + console.log('Using standard jest plugin config', src); + } + return require(cfgpath); +}; diff --git a/packages/grafana-toolkit/src/config/matchMedia.js b/packages/grafana-toolkit/src/config/matchMedia.js new file mode 100644 index 00000000..f4489dec --- /dev/null +++ b/packages/grafana-toolkit/src/config/matchMedia.js @@ -0,0 +1,14 @@ +// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom +Object.defineProperty(global, 'matchMedia', { + writable: true, + value: jest.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: jest.fn(), // deprecated + removeListener: jest.fn(), // deprecated + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + })), +}); diff --git a/packages/grafana-toolkit/src/config/mocks/jestSetup/noOverrides/package.json b/packages/grafana-toolkit/src/config/mocks/jestSetup/noOverrides/package.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/jestSetup/noOverrides/package.json @@ -0,0 +1 @@ +{} diff --git a/packages/grafana-toolkit/src/config/mocks/jestSetup/overrides/package.json b/packages/grafana-toolkit/src/config/mocks/jestSetup/overrides/package.json new file mode 100644 index 00000000..0b7f4df4 --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/jestSetup/overrides/package.json @@ -0,0 +1,11 @@ +{ + "jest": { + "moduleNameMapper": { + "someOverride": "somePath" + }, + "snapshotSerializers": "serializers", + "globalSetup": "path", + "globalTeardown": "path", + "testEnvironment": "node" + } +} diff --git a/packages/grafana-toolkit/src/config/mocks/jestSetup/unsupportedOverrides/package.json b/packages/grafana-toolkit/src/config/mocks/jestSetup/unsupportedOverrides/package.json new file mode 100644 index 00000000..8450f881 --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/jestSetup/unsupportedOverrides/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "runner": "some-runner" + } +} diff --git a/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/duplicates/src/styles/dark.css b/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/duplicates/src/styles/dark.css new file mode 100644 index 00000000..e69de29b diff --git a/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/duplicates/src/styles/dark.scss b/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/duplicates/src/styles/dark.scss new file mode 100644 index 00000000..e69de29b diff --git a/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/duplicates/src/styles/light.css b/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/duplicates/src/styles/light.css new file mode 100644 index 00000000..e69de29b diff --git a/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/missing-theme-file/src/styles/light.css b/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/missing-theme-file/src/styles/light.css new file mode 100644 index 00000000..e69de29b diff --git a/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/no-theme-files/src/styles/whatever.css b/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/no-theme-files/src/styles/whatever.css new file mode 100644 index 00000000..e69de29b diff --git a/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/ok/src/styles/dark.css b/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/ok/src/styles/dark.css new file mode 100644 index 00000000..e69de29b diff --git a/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/ok/src/styles/light.css b/packages/grafana-toolkit/src/config/mocks/stylesheetsSupport/ok/src/styles/light.css new file mode 100644 index 00000000..e69de29b diff --git a/packages/grafana-toolkit/src/config/mocks/webpack/noOverride/package.json b/packages/grafana-toolkit/src/config/mocks/webpack/noOverride/package.json new file mode 100644 index 00000000..4efb0bb1 --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/webpack/noOverride/package.json @@ -0,0 +1,3 @@ +{ + "version": "Testversion" +} diff --git a/packages/grafana-toolkit/src/config/mocks/webpack/overrides/package.json b/packages/grafana-toolkit/src/config/mocks/webpack/overrides/package.json new file mode 100644 index 00000000..4efb0bb1 --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/webpack/overrides/package.json @@ -0,0 +1,3 @@ +{ + "version": "Testversion" +} diff --git a/packages/grafana-toolkit/src/config/mocks/webpack/overrides/webpack.config.js b/packages/grafana-toolkit/src/config/mocks/webpack/overrides/webpack.config.js new file mode 100644 index 00000000..e96ceeed --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/webpack/overrides/webpack.config.js @@ -0,0 +1,10 @@ +'use strict'; +const { cloneDeep } = require('lodash'); + +const overrideWebpackConfig = (originalConfig, options) => { + const config = cloneDeep(originalConfig); + config.name = 'customConfig'; + return config; +}; + +module.exports = overrideWebpackConfig; diff --git a/packages/grafana-toolkit/src/config/mocks/webpack/overridesNamedExport/package.json b/packages/grafana-toolkit/src/config/mocks/webpack/overridesNamedExport/package.json new file mode 100644 index 00000000..4efb0bb1 --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/webpack/overridesNamedExport/package.json @@ -0,0 +1,3 @@ +{ + "version": "Testversion" +} diff --git a/packages/grafana-toolkit/src/config/mocks/webpack/overridesNamedExport/webpack.config.js b/packages/grafana-toolkit/src/config/mocks/webpack/overridesNamedExport/webpack.config.js new file mode 100644 index 00000000..d2e086e5 --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/webpack/overridesNamedExport/webpack.config.js @@ -0,0 +1,8 @@ +'use strict'; +const { cloneDeep } = require('lodash'); + +module.exports.getWebpackConfig = (originalConfig, options) => { + const config = cloneDeep(originalConfig); + config.name = 'customConfig'; + return config; +}; diff --git a/packages/grafana-toolkit/src/config/mocks/webpack/unsupportedOverride/package.json b/packages/grafana-toolkit/src/config/mocks/webpack/unsupportedOverride/package.json new file mode 100644 index 00000000..4efb0bb1 --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/webpack/unsupportedOverride/package.json @@ -0,0 +1,3 @@ +{ + "version": "Testversion" +} diff --git a/packages/grafana-toolkit/src/config/mocks/webpack/unsupportedOverride/webpack.config.js b/packages/grafana-toolkit/src/config/mocks/webpack/unsupportedOverride/webpack.config.js new file mode 100644 index 00000000..f62e5e8d --- /dev/null +++ b/packages/grafana-toolkit/src/config/mocks/webpack/unsupportedOverride/webpack.config.js @@ -0,0 +1,5 @@ +/* WRONG CONFIG ON PURPOSE - DO NOT COPY THIS */ + +module.exports.config = { + name: 'test', +}; diff --git a/packages/grafana-toolkit/src/config/prettier.plugin.config.json b/packages/grafana-toolkit/src/config/prettier.plugin.config.json new file mode 100644 index 00000000..49bc44f9 --- /dev/null +++ b/packages/grafana-toolkit/src/config/prettier.plugin.config.json @@ -0,0 +1,5 @@ +{ + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 120 +} diff --git a/packages/grafana-toolkit/src/config/prettier.plugin.rc.js b/packages/grafana-toolkit/src/config/prettier.plugin.rc.js new file mode 100644 index 00000000..c14684b0 --- /dev/null +++ b/packages/grafana-toolkit/src/config/prettier.plugin.rc.js @@ -0,0 +1,3 @@ +module.exports = { + ...require('@grafana/toolkit/src/config/prettier.plugin.config.json'), +}; diff --git a/packages/grafana-toolkit/src/config/react-inlinesvg.tsx b/packages/grafana-toolkit/src/config/react-inlinesvg.tsx new file mode 100644 index 00000000..d540f3aa --- /dev/null +++ b/packages/grafana-toolkit/src/config/react-inlinesvg.tsx @@ -0,0 +1,25 @@ +// Due to the grafana/ui Icon component making fetch requests to +// `/public/img/icon/.svg` we need to mock react-inlinesvg to prevent +// the failed fetch requests from displaying errors in console. + +import React from 'react'; + +type Callback = (...args: any[]) => void; + +export interface StorageItem { + content: string; + queue: Callback[]; + status: string; +} + +export const cacheStore: { [key: string]: StorageItem } = Object.create(null); + +const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/; + +const InlineSVG = ({ src }: { src: string }) => { + // testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`) + const testId = src.replace(SVG_FILE_NAME_REGEX, '$2'); + return ; +}; + +export default InlineSVG; diff --git a/packages/grafana-toolkit/src/config/styles.mock.js b/packages/grafana-toolkit/src/config/styles.mock.js new file mode 100644 index 00000000..ebea82fe --- /dev/null +++ b/packages/grafana-toolkit/src/config/styles.mock.js @@ -0,0 +1,4 @@ +// Mock for handling stylesheet file imports in tests +// https://jestjs.io/docs/en/webpack.html#handling-static-assets + +module.exports = {}; diff --git a/packages/grafana-toolkit/src/config/tsconfig.plugin.json b/packages/grafana-toolkit/src/config/tsconfig.plugin.json new file mode 100644 index 00000000..e2948cce --- /dev/null +++ b/packages/grafana-toolkit/src/config/tsconfig.plugin.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "alwaysStrict": true, + "declaration": false + }, + "extends": "@grafana/tsconfig" +} diff --git a/packages/grafana-toolkit/src/config/tsconfig.plugin.local.json b/packages/grafana-toolkit/src/config/tsconfig.plugin.local.json new file mode 100644 index 00000000..dcc552c6 --- /dev/null +++ b/packages/grafana-toolkit/src/config/tsconfig.plugin.local.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "rootDir": "./src", + "baseUrl": "./src", + "jsx": "react" + }, + "extends": "@grafana/toolkit/src/config/tsconfig.plugin.json", + "include": ["src", "types"] +} diff --git a/packages/grafana-toolkit/src/config/utils/getPluginId.ts b/packages/grafana-toolkit/src/config/utils/getPluginId.ts new file mode 100644 index 00000000..5acf8090 --- /dev/null +++ b/packages/grafana-toolkit/src/config/utils/getPluginId.ts @@ -0,0 +1,11 @@ +import path from 'path'; + +let PLUGIN_ID: string; + +export const getPluginId = () => { + if (!PLUGIN_ID) { + const pluginJson = require(path.resolve(process.cwd(), 'src/plugin.json')); + PLUGIN_ID = pluginJson.id; + } + return PLUGIN_ID; +}; diff --git a/packages/grafana-toolkit/src/config/utils/pluginValidation.test.ts b/packages/grafana-toolkit/src/config/utils/pluginValidation.test.ts new file mode 100644 index 00000000..33705710 --- /dev/null +++ b/packages/grafana-toolkit/src/config/utils/pluginValidation.test.ts @@ -0,0 +1,15 @@ +import { getPluginJson, validatePluginJson } from './pluginValidation'; + +describe('pluginValidation', () => { + describe('plugin.json', () => { + test('missing plugin.json file', () => { + expect(() => getPluginJson(`${__dirname}/mocks/missing-plugin.json`)).toThrowError(); + }); + }); + + describe('validatePluginJson', () => { + test('missing plugin.json file', () => { + expect(() => validatePluginJson({})).toThrow('Plugin id is missing in plugin.json'); + }); + }); +}); diff --git a/packages/grafana-toolkit/src/config/utils/pluginValidation.ts b/packages/grafana-toolkit/src/config/utils/pluginValidation.ts new file mode 100644 index 00000000..f2ff2cdf --- /dev/null +++ b/packages/grafana-toolkit/src/config/utils/pluginValidation.ts @@ -0,0 +1,38 @@ +import { PluginMeta } from '@grafana/data'; + +export const validatePluginJson = (pluginJson: any) => { + if (!pluginJson.id) { + throw new Error('Plugin id is missing in plugin.json'); + } + + if (!pluginJson.info) { + throw new Error('Plugin info node is missing in plugin.json'); + } + + if (!pluginJson.info.version) { + throw new Error('Plugin info.version is missing in plugin.json'); + } + + const types = ['panel', 'datasource', 'app']; + const type = pluginJson.type; + if (!types.includes(type)) { + throw new Error('Invalid plugin type in plugin.json: ' + type); + } + + if (!pluginJson.id.endsWith('-' + type)) { + throw new Error('[plugin.json] id should end with: -' + type); + } +}; + +export const getPluginJson = (path: string): PluginMeta => { + let pluginJson; + try { + pluginJson = require(path); + } catch (e) { + throw new Error('Unable to find: ' + path); + } + + validatePluginJson(pluginJson); + + return pluginJson as PluginMeta; +}; diff --git a/packages/grafana-toolkit/src/config/webpack.plugin.config.test.ts b/packages/grafana-toolkit/src/config/webpack.plugin.config.test.ts new file mode 100644 index 00000000..7d893834 --- /dev/null +++ b/packages/grafana-toolkit/src/config/webpack.plugin.config.test.ts @@ -0,0 +1,76 @@ +import { findModuleFiles, loadWebpackConfig } from './webpack.plugin.config'; +import fs from 'fs'; +// eslint-disable-next-line no-duplicate-imports +import * as webpackConfig from './webpack.plugin.config'; + +jest.mock('./webpack/loaders', () => ({ + getFileLoaders: (): Array<{}> => [], + getStylesheetEntries: () => ({}), + getStyleLoaders: (): Array<{}> => [], +})); + +const modulePathsMock = [ + 'some/path/module.ts', + 'some/path/module.ts.whatever', + 'some/path/module.tsx', + 'some/path/module.tsx.whatever', + 'some/path/anotherFile.ts', + 'some/path/anotherFile.tsx', +]; + +describe('Plugin webpack config', () => { + describe('findModuleTs', () => { + beforeAll(() => { + jest.spyOn(fs, 'statSync').mockReturnValue({ + isDirectory: () => false, + } as any); + }); + + afterAll(() => { + jest.restoreAllMocks(); + }); + + it('finds module.ts and module.tsx files', async () => { + const moduleFiles = await findModuleFiles('/', modulePathsMock); + expect(moduleFiles.length).toBe(2); + // normalize windows path - \\ -> / + expect(moduleFiles.map((p) => p.replace(/\\/g, '/'))).toEqual(['/some/path/module.ts', '/some/path/module.tsx']); + }); + }); + + describe('loadWebpackConfig', () => { + beforeAll(() => { + jest.spyOn(webpackConfig, 'findModuleFiles').mockReturnValue(new Promise((res, _) => res([]))); + }); + + afterAll(() => { + jest.restoreAllMocks(); + }); + + it('uses default config if no override exists', async () => { + const spy = jest.spyOn(process, 'cwd'); + spy.mockReturnValue(`${__dirname}/mocks/webpack/noOverride/`); + await loadWebpackConfig({}); + }); + + it('calls customConfig if it exists', async () => { + const spy = jest.spyOn(process, 'cwd'); + spy.mockReturnValue(`${__dirname}/mocks/webpack/overrides/`); + const config = await loadWebpackConfig({}); + expect(config.name).toBe('customConfig'); + }); + + it('loads export named getWebpackConfiguration', async () => { + const spy = jest.spyOn(process, 'cwd'); + spy.mockReturnValue(`${__dirname}/mocks/webpack/overridesNamedExport/`); + const config = await loadWebpackConfig({}); + expect(config.name).toBe('customConfig'); + }); + + it('throws an error if module does not export function', async () => { + const spy = jest.spyOn(process, 'cwd'); + spy.mockReturnValue(`${__dirname}/mocks/webpack/unsupportedOverride/`); + await expect(loadWebpackConfig({})).rejects.toThrowError(); + }); + }); +}); diff --git a/packages/grafana-toolkit/src/config/webpack.plugin.config.ts b/packages/grafana-toolkit/src/config/webpack.plugin.config.ts new file mode 100644 index 00000000..9e6e3238 --- /dev/null +++ b/packages/grafana-toolkit/src/config/webpack.plugin.config.ts @@ -0,0 +1,284 @@ +const fs = require('fs'); +const util = require('util'); +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const ReplaceInFileWebpackPlugin = require('replace-in-file-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +const readdirPromise = util.promisify(fs.readdir); +const accessPromise = util.promisify(fs.access); + +import * as webpack from 'webpack'; +import { getStyleLoaders, getStylesheetEntries, getFileLoaders } from './webpack/loaders'; + +export interface WebpackConfigurationOptions { + watch?: boolean; + production?: boolean; + preserveConsole?: boolean; +} + +type WebpackConfigurationGetter = (options: WebpackConfigurationOptions) => Promise; + +export type CustomWebpackConfigurationGetter = ( + originalConfig: webpack.Configuration, + options: WebpackConfigurationOptions +) => webpack.Configuration; + +export const findModuleFiles = async (base: string, files?: string[], result?: string[]) => { + files = files || (await readdirPromise(base)); + result = result || []; + + if (files) { + await Promise.all( + files.map(async (file) => { + const newbase = path.join(base, file); + if (fs.statSync(newbase).isDirectory()) { + result = await findModuleFiles(newbase, await readdirPromise(newbase), result); + } else { + const filename = path.basename(file); + if (/^module.(t|j)sx?$/.exec(filename)) { + // @ts-ignore + result.push(newbase); + } + } + }) + ); + } + return result; +}; + +const getModuleFiles = () => { + return findModuleFiles(path.resolve(process.cwd(), 'src')); +}; + +const getManualChunk = (id: string) => { + if (id.endsWith('module.ts') || id.endsWith('module.js') || id.endsWith('module.tsx')) { + const idx = id.lastIndexOf(path.sep + 'src' + path.sep); + if (idx > 0) { + const name = id.substring(idx + 5, id.lastIndexOf('.')); + + return { + name, + module: id, + }; + } + } + return null; +}; + +const getEntries = async () => { + const entries: { [key: string]: string } = {}; + const modules = await getModuleFiles(); + + modules.forEach((modFile) => { + const mod = getManualChunk(modFile); + // @ts-ignore + entries[mod.name] = mod.module; + }); + return { + ...entries, + ...getStylesheetEntries(), + }; +}; + +const getCommonPlugins = (options: WebpackConfigurationOptions) => { + const hasREADME = fs.existsSync(path.resolve(process.cwd(), 'src', 'README.md')); + const packageJson = require(path.resolve(process.cwd(), 'package.json')); + return [ + new MiniCssExtractPlugin({ + // both options are optional + filename: 'styles/[name].css', + }), + new webpack.optimize.OccurrenceOrderPlugin(true), + new CopyWebpackPlugin( + [ + // If src/README.md exists use it; otherwise the root README + { from: hasREADME ? 'README.md' : '../README.md', to: '.', force: true }, + { from: 'plugin.json', to: '.' }, + { from: '../LICENSE', to: '.' }, + { from: '../CHANGELOG.md', to: '.', force: true }, + { from: '**/*.json', to: '.' }, + { from: '**/*.svg', to: '.' }, + { from: '**/*.png', to: '.' }, + { from: '**/*.html', to: '.' }, + { from: 'img/**/*', to: '.' }, + { from: 'libs/**/*', to: '.' }, + { from: 'static/**/*', to: '.' }, + ], + { logLevel: options.watch ? 'silent' : 'warn' } + ), + + new ReplaceInFileWebpackPlugin([ + { + dir: 'dist', + files: ['plugin.json', 'README.md'], + rules: [ + { + search: '%VERSION%', + replace: packageJson.version, + }, + { + search: '%TODAY%', + replace: new Date().toISOString().substring(0, 10), + }, + ], + }, + ]), + new ForkTsCheckerWebpackPlugin({ + typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') }, + issue: { + include: [{ file: '**/*.{ts,tsx}' }], + }, + }), + ]; +}; + +const getBaseWebpackConfig: WebpackConfigurationGetter = async (options) => { + const plugins = getCommonPlugins(options); + const optimization: { [key: string]: any } = {}; + + if (options.production) { + const compressOptions = { drop_console: !options.preserveConsole, drop_debugger: true }; + optimization.minimizer = [ + new TerserPlugin({ sourceMap: true, terserOptions: { compress: compressOptions } }), + new OptimizeCssAssetsPlugin(), + ]; + } else if (options.watch) { + plugins.push(new HtmlWebpackPlugin()); + } + + return { + mode: options.production ? 'production' : 'development', + target: 'web', + node: { + fs: 'empty', + net: 'empty', + tls: 'empty', + }, + context: path.join(process.cwd(), 'src'), + devtool: 'source-map', + entry: await getEntries(), + output: { + filename: '[name].js', + path: path.join(process.cwd(), 'dist'), + libraryTarget: 'amd', + publicPath: '/', + }, + + performance: { hints: false }, + externals: [ + 'lodash', + 'jquery', + 'moment', + 'slate', + 'emotion', + '@emotion/react', + '@emotion/css', + 'prismjs', + 'slate-plain-serializer', + '@grafana/slate-react', + 'react', + 'react-dom', + 'react-redux', + 'redux', + 'rxjs', + 'react-router-dom', + 'd3', + 'angular', + '@grafana/ui', + '@grafana/runtime', + '@grafana/data', + // @ts-ignore + (context, request, callback) => { + const prefix = 'grafana/'; + if (request.indexOf(prefix) === 0) { + return callback(null, request.substr(prefix.length)); + } + + // @ts-ignore + callback(); + }, + ], + plugins, + resolve: { + extensions: ['.ts', '.tsx', '.js'], + modules: [path.resolve(process.cwd(), 'src'), 'node_modules'], + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loaders: [ + { + loader: require.resolve('babel-loader'), + options: { + presets: [[require.resolve('@babel/preset-env'), { modules: false }]], + plugins: [require.resolve('babel-plugin-angularjs-annotate')], + sourceMaps: true, + }, + }, + { + loader: require.resolve('ts-loader'), + options: { + onlyCompileBundledFiles: true, + transpileOnly: true, + }, + }, + ], + exclude: /(node_modules)/, + }, + { + test: /\.jsx?$/, + loaders: [ + { + loader: require.resolve('babel-loader'), + options: { + presets: [['@babel/preset-env', { modules: false }]], + plugins: ['angularjs-annotate'], + sourceMaps: true, + }, + }, + ], + exclude: /(node_modules)/, + }, + ...getStyleLoaders(), + { + test: /\.html$/, + exclude: [/node_modules/], + use: { + loader: require.resolve('html-loader'), + }, + }, + ...getFileLoaders(), + ], + }, + optimization, + }; +}; + +export const loadWebpackConfig: WebpackConfigurationGetter = async (options) => { + const baseConfig = await getBaseWebpackConfig(options); + const customWebpackPath = path.resolve(process.cwd(), 'webpack.config.js'); + + try { + await accessPromise(customWebpackPath); + const customConfig = require(customWebpackPath); + const configGetter = customConfig.getWebpackConfig || customConfig; + if (typeof configGetter !== 'function') { + throw Error( + 'Custom webpack config needs to export a function implementing CustomWebpackConfigurationGetter. Function needs to be ' + + 'module export or named "getWebpackConfig"' + ); + } + return (configGetter as CustomWebpackConfigurationGetter)(baseConfig, options); + } catch (err: any) { + if (err.code === 'ENOENT') { + return baseConfig; + } + throw err; + } +}; diff --git a/packages/grafana-toolkit/src/config/webpack/loaders.test.ts b/packages/grafana-toolkit/src/config/webpack/loaders.test.ts new file mode 100644 index 00000000..7f5b47e5 --- /dev/null +++ b/packages/grafana-toolkit/src/config/webpack/loaders.test.ts @@ -0,0 +1,47 @@ +import { getStylesheetEntries, hasThemeStylesheets } from './loaders'; + +describe('Loaders', () => { + describe('stylesheet helpers', () => { + jest.spyOn(console, 'log').mockImplementation(); + + afterAll(() => { + jest.restoreAllMocks(); + }); + + describe('getStylesheetEntries', () => { + it('returns entries for dark and light theme', () => { + const result = getStylesheetEntries(`${__dirname}/../mocks/stylesheetsSupport/ok`); + expect(Object.keys(result)).toHaveLength(2); + }); + it('throws on theme files duplicates', () => { + const result = () => { + getStylesheetEntries(`${__dirname}/../mocks/stylesheetsSupport/duplicates`); + }; + expect(result).toThrow(); + }); + }); + + describe('hasThemeStylesheets', () => { + it('throws when only one theme file is defined', () => { + jest.spyOn(console, 'error').mockImplementation(); + const result = () => { + hasThemeStylesheets(`${__dirname}/../mocks/stylesheetsSupport/missing-theme-file`); + }; + expect(result).toThrow(); + jest.restoreAllMocks(); + }); + + it('returns false when no theme files present', () => { + const result = hasThemeStylesheets(`${__dirname}/../mocks/stylesheetsSupport/no-theme-files`); + + expect(result).toBeFalsy(); + }); + + it('returns true when theme files present', () => { + const result = hasThemeStylesheets(`${__dirname}/../mocks/stylesheetsSupport/ok`); + + expect(result).toBeTruthy(); + }); + }); + }); +}); diff --git a/packages/grafana-toolkit/src/config/webpack/loaders.ts b/packages/grafana-toolkit/src/config/webpack/loaders.ts new file mode 100644 index 00000000..b247726e --- /dev/null +++ b/packages/grafana-toolkit/src/config/webpack/loaders.ts @@ -0,0 +1,170 @@ +import fs from 'fs'; +import path from 'path'; +import { getPluginId } from '../utils/getPluginId'; + +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + +const supportedExtensions = ['css', 'scss', 'less', 'sass']; + +const getStylesheetPaths = (root: string = process.cwd()) => { + return [`${root}/src/styles/light`, `${root}/src/styles/dark`]; +}; + +export const getStylesheetEntries = (root: string = process.cwd()) => { + const stylesheetsPaths = getStylesheetPaths(root); + const entries: { [key: string]: string } = {}; + supportedExtensions.forEach((e) => { + stylesheetsPaths.forEach((p) => { + const entryName = p.split('/').slice(-1)[0]; + if (fs.existsSync(`${p}.${e}`)) { + if (entries[entryName]) { + console.log(`\nSeems like you have multiple files for ${entryName} theme:`); + console.log(entries[entryName]); + console.log(`${p}.${e}`); + throw new Error('Duplicated stylesheet'); + } else { + entries[entryName] = `${p}.${e}`; + } + } + }); + }); + + return entries; +}; + +export const hasThemeStylesheets = (root: string = process.cwd()) => { + const stylesheetsPaths = getStylesheetPaths(root); + const stylesheetsSummary: boolean[] = []; + + const result = stylesheetsPaths.reduce((acc, current) => { + if (fs.existsSync(`${current}.css`) || fs.existsSync(`${current}.scss`)) { + stylesheetsSummary.push(true); + return acc && true; + } else { + stylesheetsSummary.push(false); + return false; + } + }, true); + + const hasMissingStylesheets = stylesheetsSummary.filter((s) => s).length === 1; + + // seems like there is one theme file defined only + if (result === false && hasMissingStylesheets) { + console.error('\nWe think you want to specify theme stylesheet, but it seems like there is something missing...'); + stylesheetsSummary.forEach((s, i) => { + if (s) { + console.log(stylesheetsPaths[i], 'discovered'); + } else { + console.log(stylesheetsPaths[i], 'missing'); + } + }); + + throw new Error('Stylesheet missing!'); + } + + return result; +}; + +export const getStyleLoaders = () => { + const extractionLoader = { + loader: MiniCssExtractPlugin.loader, + options: { + publicPath: '../', + }, + }; + + const cssLoaders = [ + { + loader: 'css-loader', + options: { + importLoaders: 1, + sourceMap: true, + }, + }, + { + loader: 'postcss-loader', + options: { + plugins: () => [ + require('postcss-flexbugs-fixes'), + require('postcss-preset-env')({ + autoprefixer: { flexbox: 'no-2009', grid: true }, + }), + ], + }, + }, + ]; + + const styleDir = path.resolve(process.cwd(), 'src', 'styles') + path.sep; + const rules = [ + { + test: /(dark|light)\.css$/, + use: [extractionLoader, ...cssLoaders], + }, + { + test: /(dark|light)\.scss$/, + use: [extractionLoader, ...cssLoaders, 'sass-loader'], + }, + { + test: /\.css$/, + use: ['style-loader', ...cssLoaders, 'sass-loader'], + exclude: [`${styleDir}light.css`, `${styleDir}dark.css`], + }, + { + test: /\.s[ac]ss$/, + use: ['style-loader', ...cssLoaders, 'sass-loader'], + exclude: [`${styleDir}light.scss`, `${styleDir}dark.scss`], + }, + { + test: /\.less$/, + use: [ + { + loader: 'style-loader', + }, + ...cssLoaders, + { + loader: 'less-loader', + options: { + javascriptEnabled: true, + }, + }, + ], + exclude: [`${styleDir}light.less`, `${styleDir}dark.less`], + }, + ]; + + return rules; +}; + +export const getFileLoaders = () => { + const shouldExtractCss = hasThemeStylesheets(); + + return [ + { + test: /\.(png|jpe?g|gif|svg)$/, + use: [ + shouldExtractCss + ? { + loader: require.resolve('file-loader'), + options: { + outputPath: '/', + name: '[path][name].[ext]', + }, + } + : // When using single css import images are inlined as base64 URIs in the result bundle + { + loader: 'url-loader', + }, + ], + }, + { + test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/, + loader: require.resolve('file-loader'), + options: { + // Keep publicPath relative for host.com/grafana/ deployments + publicPath: `public/plugins/${getPluginId()}/fonts`, + outputPath: 'fonts', + name: '[name].[ext]', + }, + }, + ]; +}; diff --git a/packages/grafana-toolkit/src/plugins/env.ts b/packages/grafana-toolkit/src/plugins/env.ts new file mode 100644 index 00000000..06b659c1 --- /dev/null +++ b/packages/grafana-toolkit/src/plugins/env.ts @@ -0,0 +1,145 @@ +import execa from 'execa'; +import path from 'path'; +import fs from 'fs'; +import { PluginBuildInfo } from '@grafana/data'; +import { JobInfo } from './types'; + +const getJobFromProcessArgv = () => { + const arg = process.argv[2]; + if (arg && arg.startsWith('plugin:ci-')) { + const task = arg.substring('plugin:ci-'.length); + if ('build' === task) { + if ('--backend' === process.argv[3] && process.argv[4]) { + return task + '_' + process.argv[4]; + } + return 'build_plugin'; + } + return task; + } + return 'unknown_job'; +}; + +export const job = + (process.env.DRONE_STEP_NAME ? process.env.DRONE_STEP_NAME : process.env.CIRCLE_JOB) || getJobFromProcessArgv(); + +export const getPluginBuildInfo = async (): Promise => { + if (process.env.CI === 'true') { + let repo: string | undefined; + let branch: string | undefined; + let hash: string | undefined; + let build: number | undefined; + let pr: number | undefined; + if (process.env.DRONE === 'true') { + repo = process.env.DRONE_REPO_LINK; + branch = process.env.DRONE_BRANCH; + hash = process.env.DRONE_COMMIT_SHA; + build = parseInt(process.env.DRONE_BUILD_NUMBER || '', 10); + pr = parseInt(process.env.DRONE_PULL_REQUEST || '', 10); + } else if (process.env.CIRCLECI === 'true') { + repo = process.env.CIRCLE_REPOSITORY_URL; + branch = process.env.CIRCLE_BRANCH; + hash = process.env.CIRCLE_SHA1; + build = parseInt(process.env.CIRCLE_BUILD_NUM || '', 10); + const url = process.env.CIRCLE_PULL_REQUEST || ''; + const idx = url.lastIndexOf('/') + 1; + pr = parseInt(url.substring(idx), 10); + } + + const info: PluginBuildInfo = { + time: Date.now(), + repo, + branch, + hash, + }; + if (pr) { + info.pr = pr; + } + if (build) { + info.number = build; + } + return info; + } + + const branch = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD']); + const hash = await execa('git', ['rev-parse', 'HEAD']); + return { + time: Date.now(), + branch: branch.stdout, + hash: hash.stdout, + }; +}; + +export const getBuildNumber = (): number | undefined => { + if (process.env.DRONE === 'true') { + return parseInt(process.env.DRONE_BUILD_NUMBER || '', 10); + } else if (process.env.CIRCLECI === 'true') { + return parseInt(process.env.CIRCLE_BUILD_NUM || '', 10); + } + + return undefined; +}; + +export const getPullRequestNumber = (): number | undefined => { + if (process.env.DRONE === 'true') { + return parseInt(process.env.DRONE_PULL_REQUEST || '', 10); + } else if (process.env.CIRCLECI === 'true') { + const url = process.env.CIRCLE_PULL_REQUEST || ''; + const idx = url.lastIndexOf('/') + 1; + return parseInt(url.substring(idx), 10); + } + + return undefined; +}; + +export const getJobFolder = () => { + const dir = path.resolve(process.cwd(), 'ci', 'jobs', job); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + return dir; +}; + +export const getCiFolder = () => { + const dir = path.resolve(process.cwd(), 'ci'); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + return dir; +}; + +export const writeJobStats = (startTime: number, workDir: string) => { + const endTime = Date.now(); + const stats: JobInfo = { + job, + startTime, + endTime, + elapsed: endTime - startTime, + buildNumber: getBuildNumber(), + }; + const f = path.resolve(workDir, 'job.json'); + fs.writeFile(f, JSON.stringify(stats, null, 2), (err) => { + if (err) { + throw new Error('Unable to stats: ' + f); + } + }); +}; + +// https://circleci.com/api/v1.1/project/github/NatelEnergy/grafana-discrete-panel/latest/artifacts +export async function getCircleDownloadBaseURL(): Promise { + try { + const axios = require('axios'); + const repo = process.env.CIRCLE_PROJECT_REPONAME; + const user = process.env.CIRCLE_PROJECT_USERNAME; + let url = `https://circleci.com/api/v1.1/project/github/${user}/${repo}/latest/artifacts`; + const rsp = await axios.get(url); + for (const s of rsp.data) { + const { path, url } = s; + if (url && path && path.endsWith('report.json')) { + return url.substring(url.length - 'report.json'.length); + } + } + } catch (e) { + console.log('Error reading CircleCI artifact URL', e); + } + return undefined; +} diff --git a/packages/grafana-toolkit/src/plugins/index.ts b/packages/grafana-toolkit/src/plugins/index.ts new file mode 100644 index 00000000..c302e909 --- /dev/null +++ b/packages/grafana-toolkit/src/plugins/index.ts @@ -0,0 +1,4 @@ +export * from './env'; +export * from './utils'; +export * from './workflow'; +export * from './types'; diff --git a/packages/grafana-toolkit/src/plugins/manifest.ts b/packages/grafana-toolkit/src/plugins/manifest.ts new file mode 100644 index 00000000..1b209c6f --- /dev/null +++ b/packages/grafana-toolkit/src/plugins/manifest.ts @@ -0,0 +1,90 @@ +import path from 'path'; +import fs from 'fs'; +import crypto from 'crypto'; +import { ManifestInfo } from './types'; + +const MANIFEST_FILE = 'MANIFEST.txt'; + +async function* walk(dir: string, baseDir: string): AsyncGenerator { + for await (const d of await (fs.promises as any).opendir(dir)) { + const entry = path.posix.join(dir, d.name); + if (d.isDirectory()) { + yield* await walk(entry, baseDir); + } else if (d.isFile()) { + yield path.posix.relative(baseDir, entry); + } else if (d.isSymbolicLink()) { + const realPath = await (fs.promises as any).realpath(entry); + if (!realPath.startsWith(baseDir)) { + throw new Error( + `symbolic link ${path.posix.relative( + baseDir, + entry + )} targets a file outside of the base directory: ${baseDir}` + ); + } + // if resolved symlink target is a file include it in the manifest + const stats = await (fs.promises as any).stat(realPath); + if (stats.isFile()) { + yield path.posix.relative(baseDir, entry); + } + } + } +} + +export async function buildManifest(dir: string): Promise { + const pluginJson = JSON.parse(fs.readFileSync(path.join(dir, 'plugin.json'), { encoding: 'utf8' })); + + const manifest = { + plugin: pluginJson.id, + version: pluginJson.info.version, + files: {}, + } as ManifestInfo; + + for await (const p of await walk(dir, dir)) { + if (p === MANIFEST_FILE) { + continue; + } + + manifest.files[p] = crypto + .createHash('sha256') + .update(fs.readFileSync(path.join(dir, p))) + .digest('hex'); + } + + return manifest; +} + +export async function signManifest(manifest: ManifestInfo): Promise { + const GRAFANA_API_KEY = process.env.GRAFANA_API_KEY; + if (!GRAFANA_API_KEY) { + throw new Error('You must enter a GRAFANA_API_KEY to sign the plugin manifest'); + } + + const GRAFANA_COM_URL = process.env.GRAFANA_COM_URL || 'https://grafana.com/api'; + const url = GRAFANA_COM_URL + '/plugins/ci/sign'; + + const axios = require('axios'); + + try { + const info = await axios.post(url, manifest, { + headers: { Authorization: 'Bearer ' + GRAFANA_API_KEY }, + }); + if (info.status !== 200) { + console.warn('Error: ', info); + throw new Error('Error signing manifest'); + } + + return info.data; + } catch (err: any) { + if (err.response?.data?.message) { + throw new Error('Error signing manifest: ' + err.response.data.message); + } + + throw new Error('Error signing manifest: ' + err.message); + } +} + +export async function saveManifest(dir: string, signedManifest: string): Promise { + fs.writeFileSync(path.join(dir, MANIFEST_FILE), signedManifest); + return true; +} diff --git a/packages/grafana-toolkit/src/plugins/types.ts b/packages/grafana-toolkit/src/plugins/types.ts new file mode 100644 index 00000000..792fd09e --- /dev/null +++ b/packages/grafana-toolkit/src/plugins/types.ts @@ -0,0 +1,101 @@ +import { PluginMeta, KeyValue } from '@grafana/data'; + +export interface PluginPackageDetails { + plugin: ZipFileInfo; + docs?: ZipFileInfo; +} + +export interface PluginBuildReport { + plugin: PluginMeta; + packages: PluginPackageDetails; + workflow: WorkflowInfo; + coverage: CoverageInfo[]; + tests: TestResultsInfo[]; + git?: GitLogInfo; + pullRequest?: number; + artifactsBaseURL?: string; + grafanaVersion?: KeyValue; +} + +export interface JobInfo { + job?: string; + startTime: number; + endTime: number; + elapsed: number; + status?: string; + buildNumber?: number; +} + +export interface WorkflowInfo extends JobInfo { + workflowId?: string; + jobs: JobInfo[]; + user?: string; + repo?: string; +} + +export interface CoverageDetails { + total: number; + covered: number; + skipped: number; + pct: number; +} + +export interface CoverageInfo { + job: string; + summary: { [key: string]: CoverageDetails }; + report?: string; // path to report +} + +export interface TestResultsInfo { + job: string; + grafana?: any; + error?: string; + passed: number; + failed: number; + screenshots: string[]; +} + +export interface CountAndSize { + count: number; + bytes: number; +} + +export interface ExtensionSize { + [key: string]: CountAndSize; +} + +export interface ZipFileInfo { + name: string; + size: number; + contents: ExtensionSize; + sha1?: string; + md5?: string; +} + +interface UserInfo { + name: string; + email: string; + time?: number; +} + +export interface GitLogInfo { + commit: string; + tree: string; + subject: string; + body?: string; + notes?: string; + author: UserInfo; + commiter: UserInfo; +} + +export interface ManifestInfo { + // time: number; << filled in by the server + // keyId: string; << filled in by the server + // signedByOrg: string; << filled in by the server + // signedByOrgName: string; << filled in by the server + signatureType?: string; // filled in by the server if not specified + rootUrls?: string[]; // for private signatures + plugin: string; + version: string; + files: Record; +} diff --git a/packages/grafana-toolkit/src/plugins/utils.ts b/packages/grafana-toolkit/src/plugins/utils.ts new file mode 100644 index 00000000..739c837b --- /dev/null +++ b/packages/grafana-toolkit/src/plugins/utils.ts @@ -0,0 +1,130 @@ +import execa from 'execa'; +import path from 'path'; +import fs from 'fs'; +import { KeyValue } from '@grafana/data'; +import { ExtensionSize, ZipFileInfo, GitLogInfo } from './types'; + +const md5File = require('md5-file'); + +export function getGrafanaVersions(): KeyValue { + const dir = path.resolve(process.cwd(), 'node_modules', '@grafana'); + const versions: KeyValue = {}; + try { + fs.readdirSync(dir).forEach((file) => { + const json = require(path.resolve(dir, file, 'package.json')); + versions[file] = json.version; + }); + } catch (err) { + console.warn('Error reading toolkit versions', err); + } + return versions; +} + +export function getFileSizeReportInFolder(dir: string, info?: ExtensionSize): ExtensionSize { + const acc: ExtensionSize = info ? info : {}; + + const files = fs.readdirSync(dir); + if (files) { + files.forEach((file) => { + const newbase = path.join(dir, file); + const stat = fs.statSync(newbase); + if (stat.isDirectory()) { + getFileSizeReportInFolder(newbase, info); + } else { + let ext = '_none_'; + const idx = file.lastIndexOf('.'); + if (idx > 0) { + ext = file.substring(idx + 1).toLowerCase(); + } + const current = acc[ext]; + if (current) { + current.count += 1; + current.bytes += stat.size; + } else { + acc[ext] = { bytes: stat.size, count: 1 }; + } + } + }); + } + return acc; +} + +export async function getPackageDetails(zipFile: string, zipSrc: string, writeChecksum = true): Promise { + const zipStats = fs.statSync(zipFile); + if (zipStats.size < 100) { + throw new Error('Invalid zip file: ' + zipFile); + } + const info: ZipFileInfo = { + name: path.basename(zipFile), + size: zipStats.size, + contents: getFileSizeReportInFolder(zipSrc), + }; + try { + const exe = await execa('shasum', [zipFile]); + const idx = exe.stdout.indexOf(' '); + const sha1 = exe.stdout.substring(0, idx); + if (writeChecksum) { + fs.writeFile(zipFile + '.sha1', sha1, (err) => {}); + } + info.sha1 = sha1; + } catch { + console.warn('Unable to read SHA1 Checksum'); + } + try { + info.md5 = md5File.sync(zipFile); + } catch { + console.warn('Unable to read MD5 Checksum'); + } + return info; +} + +export function findImagesInFolder(dir: string, prefix = '', append?: string[]): string[] { + const imgs = append || []; + + const files = fs.readdirSync(dir); + if (files) { + files.forEach((file) => { + if (file.endsWith('.png')) { + imgs.push(file); + } + }); + } + + return imgs; +} + +export async function readGitLog(): Promise { + try { + let exe = await execa('git', [ + 'log', + '-1', // last line + '--pretty=format:{%n "commit": "%H",%n "tree": "%T",%n "subject": "%s",%n "author": {%n "name": "%aN",%n "email": "%aE",%n "time":"%at" },%n "commiter": {%n "name": "%cN",%n "email": "%cE",%n "time":"%ct" }%n}', + ]); + const info = JSON.parse(exe.stdout) as GitLogInfo; + + // Read the body + exe = await execa('git', [ + 'log', + '-1', // last line + '--pretty=format:%b', // Just the body (with newlines!) + ]); + if (exe.stdout && exe.stdout.length) { + info.body = exe.stdout.trim(); + } + + // Read any commit notes + exe = await execa('git', [ + 'log', + '-1', // last line + '--pretty=format:%N', // commit notes (with newlines!) + ]); + if (exe.stdout && exe.stdout.length) { + info.notes = exe.stdout.trim(); + } + + return info; + } catch (err) { + console.warn('Error REading Git log info', err); + } + return undefined; +} diff --git a/packages/grafana-toolkit/src/plugins/workflow.ts b/packages/grafana-toolkit/src/plugins/workflow.ts new file mode 100644 index 00000000..770afe48 --- /dev/null +++ b/packages/grafana-toolkit/src/plugins/workflow.ts @@ -0,0 +1,99 @@ +import path from 'path'; +import fs from 'fs'; +import { JobInfo, WorkflowInfo, CoverageInfo, TestResultsInfo } from './types'; +import { getBuildNumber, getCiFolder } from './env'; + +export const agregateWorkflowInfo = (): WorkflowInfo => { + const now = Date.now(); + const workflow: WorkflowInfo = { + jobs: [], + startTime: now, + endTime: now, + workflowId: process.env.CIRCLE_WORKFLOW_ID, + repo: process.env.CIRCLE_PROJECT_REPONAME, + user: process.env.CIRCLE_PROJECT_USERNAME, + buildNumber: getBuildNumber(), + elapsed: 0, + }; + + const jobsFolder = path.resolve(getCiFolder(), 'jobs'); + if (fs.existsSync(jobsFolder)) { + const files = fs.readdirSync(jobsFolder); + if (files && files.length) { + files.forEach((file) => { + const p = path.resolve(jobsFolder, file, 'job.json'); + if (fs.existsSync(p)) { + const job = require(p) as JobInfo; + workflow.jobs.push(job); + if (job.startTime < workflow.startTime) { + workflow.startTime = job.startTime; + } + if (job.endTime > workflow.endTime) { + workflow.endTime = job.endTime; + } + } else { + console.log('Missing Job info: ', p); + } + }); + } else { + console.log('NO JOBS IN: ', jobsFolder); + } + } + + workflow.elapsed = workflow.endTime - workflow.startTime; + return workflow; +}; + +export const agregateCoverageInfo = (): CoverageInfo[] => { + const coverage: CoverageInfo[] = []; + const ciDir = getCiFolder(); + const jobsFolder = path.resolve(ciDir, 'jobs'); + if (fs.existsSync(jobsFolder)) { + const files = fs.readdirSync(jobsFolder); + if (files && files.length) { + files.forEach((file) => { + const dir = path.resolve(jobsFolder, file, 'coverage'); + if (fs.existsSync(dir)) { + const s = path.resolve(dir, 'coverage-summary.json'); + const r = path.resolve(dir, 'lcov-report', 'index.html'); + if (fs.existsSync(s)) { + const raw = require(s); + const info: CoverageInfo = { + job: file, + summary: raw.total, + }; + if (fs.existsSync(r)) { + info.report = r.substring(ciDir.length); + } + coverage.push(info); + } + } + }); + } else { + console.log('NO JOBS IN: ', jobsFolder); + } + } + return coverage; +}; + +export const agregateTestInfo = (): TestResultsInfo[] => { + const tests: TestResultsInfo[] = []; + const ciDir = getCiFolder(); + const jobsFolder = path.resolve(ciDir, 'jobs'); + if (fs.existsSync(jobsFolder)) { + const files = fs.readdirSync(jobsFolder); + if (files && files.length) { + files.forEach((file) => { + if (file.startsWith('test')) { + const summary = path.resolve(jobsFolder, file, 'results.json'); + if (fs.existsSync(summary)) { + tests.push(require(summary) as TestResultsInfo); + } + } + }); + } else { + console.log('NO Jobs IN: ', jobsFolder); + } + } + return tests; +}; diff --git a/packages/grafana-toolkit/tsconfig.json b/packages/grafana-toolkit/tsconfig.json new file mode 100644 index 00000000..864c187d --- /dev/null +++ b/packages/grafana-toolkit/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "declarationDir": "dist/src", + "module": "commonjs", + "outDir": "dist/src", + "rootDirs": ["."], + "paths": { + "@grafana/toolkit": ["."] + }, + "useUnknownInCatchVariables": false + }, + "exclude": ["dist", "node_modules"], + "extends": "@grafana/tsconfig", + "include": ["src/**/*.ts", "../../public/app/types/jquery/*.ts", "../../public/app/types/sanitize-url.d.ts"] +} diff --git a/packages/grafana-ui/.eslintrc b/packages/grafana-ui/.eslintrc new file mode 100644 index 00000000..fa09290c --- /dev/null +++ b/packages/grafana-ui/.eslintrc @@ -0,0 +1,14 @@ +{ + "rules": { + "no-restricted-imports": ["error", { "patterns": ["@grafana/runtime", "@grafana/data/*", "@grafana/ui", "@grafana/e2e"] }] + }, + "overrides": [ + { + "files": ["**/*.{test,story}.{ts,tsx}"], + "rules": { + "no-restricted-imports": "off", + "react/prop-types": "off" + } + } + ] +} diff --git a/packages/grafana-ui/.storybook/main.ts b/packages/grafana-ui/.storybook/main.ts new file mode 100644 index 00000000..a3fa12a8 --- /dev/null +++ b/packages/grafana-ui/.storybook/main.ts @@ -0,0 +1,175 @@ +const path = require('path'); +const TerserPlugin = require('terser-webpack-plugin'); +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); +const FilterWarningsPlugin = require('webpack-filter-warnings-plugin'); + +const stories = ['../src/**/*.story.{js,jsx,ts,tsx,mdx}']; + +if (process.env.NODE_ENV !== 'production') { + stories.push('../src/**/*.story.internal.{js,jsx,ts,tsx,mdx}'); +} + +module.exports = { + stories: stories, + addons: [ + { + name: '@storybook/addon-essentials', + options: { + backgrounds: false, + }, + }, + '@storybook/addon-a11y', + '@storybook/addon-knobs', + '@storybook/addon-storysource', + 'storybook-dark-mode', + ], + staticDirs: [ + { from: '../../../public/fonts', to: '/fonts' }, + { from: '../../../public/img', to: '/public/img' }, + { from: '../../../public/lib', to: '/public/lib' }, + ], + reactOptions: { + fastRefresh: true, + }, + core: { + builder: 'webpack5', + }, + typescript: { + check: true, + reactDocgen: 'react-docgen-typescript', + reactDocgenTypescriptOptions: { + tsconfigPath: path.resolve(__dirname, 'tsconfig.json'), + shouldExtractLiteralValuesFromEnum: true, + shouldRemoveUndefinedFromOptional: true, + propFilter: (prop: any) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), + savePropValueAsString: true, + }, + }, + webpackFinal: async (config: any, { configType }: any) => { + const isProductionBuild = configType === 'PRODUCTION'; + + config.resolve.fallback = { + ...(config.resolve.fallback || {}), + process: false, + }; + + // remove svg from default storybook webpack 5 config so we can use `raw-loader` + config.module.rules = config.module.rules.map((rule: any) => { + if ( + String(rule.test) === + String(/\.(svg|ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/) + ) { + return { + ...rule, + test: /\.(ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/, + }; + } + + return rule; + }); + + config.module.rules = [ + ...(config.module.rules || []), + { + test: /\.tsx?$/, + use: [ + { + loader: require.resolve('ts-loader'), + options: { + transpileOnly: true, + configFile: path.resolve(__dirname, 'tsconfig.json'), + }, + }, + ], + exclude: /node_modules/, + include: [path.resolve(__dirname, '../../../public/'), path.resolve(__dirname, '../../../packages/')], + }, + { + test: /\.scss$/, + use: [ + { + loader: 'style-loader', + options: { injectType: 'lazyStyleTag' }, + }, + { + loader: 'css-loader', + options: { + url: false, + importLoaders: 2, + }, + }, + { + loader: 'postcss-loader', + options: { + sourceMap: false, + postcssOptions: { + config: path.resolve(__dirname + '../../../../scripts/webpack/postcss.config.js'), + }, + }, + }, + { + loader: 'sass-loader', + options: { + sourceMap: false, + }, + }, + ], + }, + // for pre-caching SVGs as part of the JS bundles + { + test: /\.svg$/, + use: 'raw-loader', + }, + { + test: require.resolve('jquery'), + loader: 'expose-loader', + options: { + exposes: ['$', 'jQuery'], + }, + }, + ]; + + if (isProductionBuild) { + config.optimization = { + nodeEnv: 'production', + moduleIds: 'deterministic', + runtimeChunk: 'single', + splitChunks: { + chunks: 'all', + minChunks: 1, + cacheGroups: { + vendors: { + test: /[\\/]node_modules[\\/].*[jt]sx?$/, + chunks: 'initial', + priority: -10, + reuseExistingChunk: true, + enforce: true, + }, + default: { + priority: -20, + chunks: 'all', + test: /.*[jt]sx?$/, + reuseExistingChunk: true, + }, + }, + }, + minimize: isProductionBuild, + minimizer: isProductionBuild + ? [new TerserPlugin({ parallel: false, exclude: /monaco/ }), new CssMinimizerPlugin()] + : [], + }; + } + + config.resolve.alias['@grafana/ui'] = path.resolve(__dirname, '..'); + + // Silence "export not found" webpack warnings with transpileOnly + // https://github.com/TypeStrong/ts-loader#transpileonly + config.plugins.push( + new FilterWarningsPlugin({ + exclude: /export .* was not found in/, + }) + ); + + return config; + }, +}; diff --git a/packages/grafana-ui/.storybook/manager-head.html b/packages/grafana-ui/.storybook/manager-head.html new file mode 100644 index 00000000..56f4719a --- /dev/null +++ b/packages/grafana-ui/.storybook/manager-head.html @@ -0,0 +1 @@ + diff --git a/packages/grafana-ui/.storybook/preview-head.html b/packages/grafana-ui/.storybook/preview-head.html new file mode 100644 index 00000000..5bcc8d66 --- /dev/null +++ b/packages/grafana-ui/.storybook/preview-head.html @@ -0,0 +1,6 @@ + + diff --git a/packages/grafana-ui/.storybook/preview.ts b/packages/grafana-ui/.storybook/preview.ts new file mode 100644 index 00000000..d8a51bcd --- /dev/null +++ b/packages/grafana-ui/.storybook/preview.ts @@ -0,0 +1,62 @@ +import 'jquery'; +import '../../../public/vendor/flot/jquery.flot.js'; +import '../../../public/vendor/flot/jquery.flot.selection'; +import '../../../public/vendor/flot/jquery.flot.time'; +import '../../../public/vendor/flot/jquery.flot.stack'; +import '../../../public/vendor/flot/jquery.flot.stackpercent'; +import '../../../public/vendor/flot/jquery.flot.fillbelow'; +import '../../../public/vendor/flot/jquery.flot.crosshair'; +import '../../../public/vendor/flot/jquery.flot.dashes'; +import '../../../public/vendor/flot/jquery.flot.gauge'; +import { withTheme } from '../src/utils/storybook/withTheme'; +// @ts-ignore +import lightTheme from '../../../public/sass/grafana.light.scss'; +// @ts-ignore +import darkTheme from '../../../public/sass/grafana.dark.scss'; +import { GrafanaLight, GrafanaDark } from './storybookTheme'; +import addons from '@storybook/addons'; +import { ThemedDocsContainer } from '../src/utils/storybook/ThemedDocsContainer'; + +const handleThemeChange = (theme: any) => { + if (theme !== 'light') { + lightTheme.unuse(); + darkTheme.use(); + } else { + darkTheme.unuse(); + lightTheme.use(); + } +}; + +addons.setConfig({ + showRoots: false, + theme: GrafanaDark, +}); + +export const decorators = [withTheme(handleThemeChange)]; + +export const parameters = { + docs: { + container: ThemedDocsContainer, + }, + darkMode: { + dark: GrafanaDark, + light: GrafanaLight, + }, + layout: 'fullscreen', + actions: { argTypesRegex: '^on[A-Z].*' }, + options: { + showPanel: true, + panelPosition: 'right', + showNav: true, + isFullscreen: false, + isToolshown: true, + storySort: { + method: 'alphabetical', + // Order Docs Overview and Docs Overview/Intro story first + order: ['Docs Overview', ['Intro']], + }, + }, + knobs: { + disable: true, + }, +}; diff --git a/packages/grafana-ui/.storybook/storybookTheme.ts b/packages/grafana-ui/.storybook/storybookTheme.ts new file mode 100644 index 00000000..f2a51792 --- /dev/null +++ b/packages/grafana-ui/.storybook/storybookTheme.ts @@ -0,0 +1,46 @@ +import { GrafanaTheme2, createTheme } from '@grafana/data'; +//@ts-ignore +import { create } from '@storybook/theming'; +import '../src/components/Icon/iconBundle'; + +const createStorybookTheme = (theme: GrafanaTheme2) => { + return create({ + base: theme.colors.mode, + colorPrimary: theme.colors.primary.main, + colorSecondary: theme.colors.error.main, + + // UI + appBg: theme.colors.background.canvas, + appContentBg: theme.colors.background.primary, + appBorderColor: theme.colors.border.medium, + appBorderRadius: parseInt(theme.shape.borderRadius(1), 10), + + // Typography + fontBase: theme.typography.fontFamily, + fontCode: theme.typography.fontFamilyMonospace, + + // Text colors + textColor: theme.colors.text.primary, + textInverseColor: theme.colors.background.primary, + + // Toolbar default and active colors + barTextColor: theme.colors.text.primary, + barSelectedColor: theme.colors.emphasize(theme.colors.primary.text), + barBg: theme.colors.background.primary, + + // Form colors + inputBg: theme.components.input.background, + inputBorder: theme.components.input.borderColor, + inputTextColor: theme.components.input.text, + inputBorderRadius: parseInt(theme.shape.borderRadius(1), 10), + + brandTitle: 'Grafana UI', + brandUrl: './', + brandImage: `public/img/grafana_text_logo-${theme.colors.mode}.svg`, + }); +}; + +const GrafanaLight = createStorybookTheme(createTheme({ colors: { mode: 'light' } })); +const GrafanaDark = createStorybookTheme(createTheme({ colors: { mode: 'dark' } })); + +export { GrafanaLight, GrafanaDark }; diff --git a/packages/grafana-ui/.storybook/tsconfig.json b/packages/grafana-ui/.storybook/tsconfig.json new file mode 100644 index 00000000..7a8f86da --- /dev/null +++ b/packages/grafana-ui/.storybook/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "declarationDir": "dist", + "noUnusedLocals": false, + "outDir": "compiled" + }, + "exclude": ["../dist", "../node_modules"], + "extends": "../tsconfig.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.tsx", + "../../../public/app/types/sanitize-url.d.ts", + "../../../public/app/types/svg.d.ts" + ] +} diff --git a/packages/grafana-ui/CHANGELOG.md b/packages/grafana-ui/CHANGELOG.md new file mode 100644 index 00000000..efef3a4a --- /dev/null +++ b/packages/grafana-ui/CHANGELOG.md @@ -0,0 +1,172 @@ +# 7.3.0-beta1 (2020-10-15) + +### Features / Enhancements + +- **NamedColors**: Named colors refactors. [#28235](https://github.com/grafana/grafana/pull/28235), [@torkelo](https://github.com/torkelo) + +# 7.2.0 (2020-09-23) + +### Features / Enhancements + +- **grafana/ui**: Do not bundle jQuery. [#27667](https://github.com/grafana/grafana/pull/27667), [@kennytm](https://github.com/kennytm) + +# 7.1.0-beta1 (2020-07-01) + +### Features / Enhancements + +- **Grafana-UI**: Add FileUpload. [#25835](https://github.com/grafana/grafana/pull/25835), [@Clarity-89](https://github.com/Clarity-89) +- **Switch**: Deprecate checked prop in favor of value. [#25862](https://github.com/grafana/grafana/pull/25862), [@tskarhed](https://github.com/tskarhed) + +# 7.0.4 (2020-06-25) + +### Features / Enhancements + +- **Slider**: Update rc-slider dependency to 9.3.1. [#25617](https://github.com/grafana/grafana/pull/25617), [@torkelo](https://github.com/torkelo) + +# 7.0.0 (2020-05-18) + +### Bug Fixes + +- **Explore**: Fixes loading more logs in logs context view. [#24135](https://github.com/grafana/grafana/pull/24135), [@Estrax](https://github.com/Estrax) + +# 7.0.0-beta3 (2020-05-08) + +### Features / Enhancements + +- **Forms**: Remove Forms namespace [BREAKING]. Will cause all `Forms` imports to stop working. See migration guide below. [#24378](https://github.com/grafana/grafana/pull/24378), [@tskarhed](https://github.com/tskarhed) + +# 7.0.0-beta.2 (2020-05-07) + +### Bug Fixes + +- **Dashboard**: Fix for folder picker menu not being visible outside modal when saving dashboard. [#24296](https://github.com/grafana/grafana/pull/24296), [@tskarhed](https://github.com/tskarhed) +- **Select**: Fixes so component loses focus on selecting value or pressing outside of input. [#24008](https://github.com/grafana/grafana/pull/24008), [@mckn](https://github.com/mckn) + +# 7.0.0-beta.1 (2020-04-28) + +## Breaking changes + +### @grafana/ui forms migration notice + +In Grafana 7 we have migrated from our old form components to `LegacyForms` namespace. The new components were previously available under the `Forms` namespace. + +All the following components were moved to the LegacyForms namespace, and some replaced with the new form components: + +- `SecretFormField` +- `FormField` +- `Select` +- `AsyncSelect` +- `IndicatorsContainer` +- `NoOptionsMessage` +- `ButtonSelect` +- `Input` +- `Switch` + +One exception to this is `FormLabel`, which has been renamed to `InlineFormLabel`. + +If you were previously using the legacy form styles and your plugin is breaking, change from this: + +```jsx +import { Switch } from '@grafana/ui'; +… + +``` + +To this: + +```jsx +import { LegacyForms } from '@grafana/ui'; +… + +``` + +If you were previously using the new form styles under the `Forms` namespace, change from this: + +```jsx +import { Forms } from '@grafana/ui'; +… + +``` + +To this: + +```jsx +import { Switch} from '@grafana/ui'; +… + +``` + +To see the new form components visit [our Storybook](https://developers.grafana.com/ui) + +### Create custom value with Select + +Previously the only thing you had to do to enable creating a custom value with Select was to add the `allowCustomValue` prop. Now you also have to add a `onCreateOption` handler. + +Before: + +```jsx +import { Select } from '@grafana/ui'; +... + { + // Do things with the customValue +}} +/> + +``` + +### Features / Enhancements + +- **@grafana/ui**: Create Icon component and replace icons. [#23402](https://github.com/grafana/grafana/pull/23402), [@ivanahuckova](https://github.com/ivanahuckova) +- **@grafana/ui**: Create slider component. [#22275](https://github.com/grafana/grafana/pull/22275), [@ivanahuckova](https://github.com/ivanahuckova) +- **@grafana/ui**: Remove ColorPalette component. [#23592](https://github.com/grafana/grafana/pull/23592), [@ivanahuckova](https://github.com/ivanahuckova) +- **Components**: IconButton. [#23510](https://github.com/grafana/grafana/pull/23510), [@torkelo](https://github.com/torkelo) +- **Docs**: Adding API reference documentation support for the packages libraries. [#21931](https://github.com/grafana/grafana/pull/21931), [@mckn](https://github.com/mckn) +- **Migration**: Add old Input to legacy namespace. [#23286](https://github.com/grafana/grafana/pull/23286), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Final components to LegacyForms. [#23707](https://github.com/grafana/grafana/pull/23707), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Move Switch from Forms namespace. [#23386](https://github.com/grafana/grafana/pull/23386), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Move last components from Forms namespace. [#23556](https://github.com/grafana/grafana/pull/23556), [@tskarhed](https://github.com/tskarhed) +- **Migration**: Remove Button from Forms namespace. [#23105](https://github.com/grafana/grafana/pull/23105), [@tskarhed](https://github.com/tskarhed) +- **Migration**: TextArea from Forms namespace. [#23436](https://github.com/grafana/grafana/pull/23436), [@tskarhed](https://github.com/tskarhed) +- **grafana/ui**: Add basic horizontal and vertical layout components. [#22303](https://github.com/grafana/grafana/pull/22303), [@dprokop](https://github.com/dprokop) + +### Bug Fixes + +- **@grafana/ui**: Fix time range when only partial datetime is provided. [#23122](https://github.com/grafana/grafana/pull/23122), [@ivanahuckova](https://github.com/ivanahuckova) + +# 6.6.0-beta.1.0 (2020-01-20) + +### Features / Enhancements + +- **Forms**: introduce RadioButtonGroup. [#20828](https://github.com/grafana/grafana/pull/20828), [@dprokop](https://github.com/dprokop) +- **grafana/ui**: ConfirmModal component. [#20965](https://github.com/grafana/grafana/pull/20965), [@alexanderzobnin](https://github.com/alexanderzobnin) +- **grafana/ui**: Create Tabs component. [#21328](https://github.com/grafana/grafana/pull/21328), [@peterholmberg](https://github.com/peterholmberg) +- **grafana/ui**: New table component. [#20991](https://github.com/grafana/grafana/pull/20991), [@peterholmberg](https://github.com/peterholmberg) +- **grafana/ui**: New updated time picker. [#20931](https://github.com/grafana/grafana/pull/20931), [@mckn](https://github.com/mckn) + +### Bug Fixes + +- **API**: Optionally list expired API keys. [#20468](https://github.com/grafana/grafana/pull/20468), [@papagian](https://github.com/papagian) +- **grafana/ui**: Do not build grafana/ui in strict mode as it depends on non-strict libs. [#21319](https://github.com/grafana/grafana/pull/21319), [@dprokop](https://github.com/dprokop) + +# 6.0.0-alpha.0 (2019-02-22) + +Version update to 6.0.0 to keep @grafana/ui version in sync with [Grafana](https://github.com/grafana/grafana) + +# 1.0.0-alpha.0 (2019-02-21) + +First public release diff --git a/packages/grafana-ui/LICENSE_APACHE2 b/packages/grafana-ui/LICENSE_APACHE2 new file mode 100644 index 00000000..373dde57 --- /dev/null +++ b/packages/grafana-ui/LICENSE_APACHE2 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2015 Grafana Labs + + Licensed 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/packages/grafana-ui/README.md b/packages/grafana-ui/README.md new file mode 100644 index 00000000..00b712eb --- /dev/null +++ b/packages/grafana-ui/README.md @@ -0,0 +1,25 @@ +# Grafana UI components library + +> **@grafana/ui is currently in BETA**. + +@grafana/ui is a collection of components used by [Grafana](https://github.com/grafana/grafana) + +Our goal is to deliver Grafana's common UI elements for plugins developers and contributors. + +Browse the [Storybook catalog of the components](http://developers.grafana.com/). + +See [package source](https://github.com/grafana/grafana/tree/main/packages/grafana-ui) for more details. + +## Installation + +`yarn add @grafana/ui` + +`npm install @grafana/ui` + +## Development + +For development purposes we suggest using `yarn link` that will create symlink to @grafana/ui lib. To do so navigate to `packages/grafana-ui` and run `yarn link`. Then, navigate to your project and run `yarn link @grafana/ui` to use the linked version of the lib. To unlink follow the same procedure, but use `yarn unlink` instead. + +### Storybook 6.x migration + +We've upgraded Storybook to version 6 and with that we will convert to using [controls](https://storybook.js.org/docs/react/essentials/controls) instead of knobs for manipulating components. Controls will not require as much coding as knobs do. Please refer to the [storybook style-guide](https://github.com/grafana/grafana/blob/main/contribute/style-guides/storybook.md#contrls) for further information. diff --git a/packages/grafana-ui/api-extractor.json b/packages/grafana-ui/api-extractor.json new file mode 100644 index 00000000..5e96b3b0 --- /dev/null +++ b/packages/grafana-ui/api-extractor.json @@ -0,0 +1,3 @@ +{ + "extends": "../../api-extractor.json" +} diff --git a/packages/grafana-ui/index.js b/packages/grafana-ui/index.js new file mode 100644 index 00000000..5d1c9252 --- /dev/null +++ b/packages/grafana-ui/index.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./index.production.js'); +} else { + module.exports = require('./index.development.js'); +} diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json new file mode 100644 index 00000000..f4ccb9bc --- /dev/null +++ b/packages/grafana-ui/package.json @@ -0,0 +1,181 @@ +{ + "author": "Grafana Labs", + "license": "Apache-2.0", + "name": "@grafana/ui", + "version": "8.4.0-pre", + "description": "Grafana Components Library", + "keywords": [ + "grafana", + "react", + "react-component", + "typescript" + ], + "repository": { + "type": "git", + "url": "http://github.com/grafana/grafana.git", + "directory": "packages/grafana-ui" + }, + "main": "src/index.ts", + "scripts": { + "build": "grafana-toolkit package:build --scope=ui", + "bundle": "rollup -c rollup.config.ts", + "clean": "rimraf ./dist ./compiled", + "docsExtract": "mkdir -p ../../reports/docs && api-extractor run 2>&1 | tee ../../reports/docs/$(basename $(pwd)).log", + "storybook": "start-storybook -p 9001 -c .storybook", + "storybook:build": "build-storybook -o ./dist/storybook -c .storybook", + "typecheck": "tsc --noEmit" + }, + "browserslist": [ + "defaults", + "not IE 11" + ], + "dependencies": { + "@emotion/css": "11.1.3", + "@emotion/react": "11.1.5", + "@grafana/aws-sdk": "0.0.3", + "@grafana/data": "8.4.0-pre", + "@grafana/e2e-selectors": "8.4.0-pre", + "@grafana/schema": "8.4.0-pre", + "@grafana/slate-react": "0.22.10-grafana", + "@monaco-editor/react": "4.3.1", + "@popperjs/core": "2.11.0", + "@react-aria/button": "3.3.4", + "@react-aria/focus": "3.5.0", + "@react-aria/menu": "3.3.0", + "@react-aria/overlays": "3.7.2", + "@react-stately/menu": "3.2.3", + "@sentry/browser": "6.15.0", + "ansicolor": "1.1.95", + "calculate-size": "1.1.1", + "classnames": "2.3.1", + "clipboard": "2.0.4", + "core-js": "3.20.0", + "d3": "5.15.0", + "date-fns": "2.28.0", + "hoist-non-react-statics": "3.3.2", + "immutable": "4.0.0", + "is-hotkey": "0.2.0", + "jquery": "3.6.0", + "lodash": "4.17.21", + "memoize-one": "6.0.0", + "moment": "2.29.1", + "monaco-editor": "^0.31.1", + "prismjs": "1.25.0", + "rc-cascader": "1.5.0", + "rc-drawer": "4.4.0", + "rc-slider": "9.7.5", + "rc-time-picker": "^3.7.3", + "react": "17.0.1", + "react-beautiful-dnd": "13.1.0", + "react-calendar": "3.5.0", + "react-colorful": "5.5.1", + "react-custom-scrollbars-2": "4.4.0", + "react-dom": "17.0.1", + "react-dropzone": "11.4.2", + "react-highlight-words": "0.17.0", + "react-hook-form": "7.5.3", + "react-inlinesvg": "2.3.0", + "react-popper": "2.2.4", + "react-router-dom": "^5.2.0", + "react-select": "5.2.1", + "react-select-event": "^5.1.0", + "react-table": "7.7.0", + "react-transition-group": "4.4.1", + "react-use": "17.3.2", + "react-window": "1.8.5", + "rxjs": "7.5.1", + "slate": "0.47.8", + "slate-plain-serializer": "0.7.10", + "tinycolor2": "1.4.1", + "tslib": "2.3.1", + "uplot": "1.6.18", + "uuid": "8.3.0" + }, + "devDependencies": { + "@babel/core": "7.16.0", + "@grafana/tsconfig": "^1.0.0-rc1", + "@mdx-js/react": "1.6.22", + "@rollup/plugin-commonjs": "21.0.1", + "@rollup/plugin-image": "2.1.1", + "@rollup/plugin-node-resolve": "13.1.1", + "@storybook/addon-a11y": "6.4.4", + "@storybook/addon-actions": "6.4.4", + "@storybook/addon-docs": "6.4.4", + "@storybook/addon-essentials": "6.4.4", + "@storybook/addon-knobs": "6.4.0", + "@storybook/addon-storysource": "6.4.4", + "@storybook/addons": "6.4.4", + "@storybook/api": "6.4.4", + "@storybook/builder-webpack5": "6.4.4", + "@storybook/components": "6.4.4", + "@storybook/core-events": "6.4.4", + "@storybook/manager-webpack5": "6.4.4", + "@storybook/react": "6.4.4", + "@storybook/theming": "6.4.4", + "@swc/helpers": "0.3.2", + "@testing-library/dom": "8.11.1", + "@testing-library/jest-dom": "5.16.1", + "@testing-library/react": "12.1.2", + "@testing-library/react-hooks": "7.0.2", + "@testing-library/user-event": "13.5.0", + "@types/classnames": "2.3.0", + "@types/clipboard": "2.0.1", + "@types/common-tags": "^1.8.0", + "@types/d3": "7.1.0", + "@types/enzyme": "3.10.5", + "@types/enzyme-adapter-react-16": "1.0.6", + "@types/grafana__slate-react": "npm:@types/slate-react@0.22.5", + "@types/hoist-non-react-statics": "3.3.1", + "@types/is-hotkey": "0.1.1", + "@types/jest": "27.4.0", + "@types/jquery": "3.5.11", + "@types/lodash": "4.14.123", + "@types/mock-raf": "1.0.2", + "@types/node": "16.11.6", + "@types/prismjs": "1.16.0", + "@types/react": "17.0.30", + "@types/react-beautiful-dnd": "13.1.1", + "@types/react-calendar": "^3.4.3", + "@types/react-color": "3.0.1", + "@types/react-dom": "17.0.11", + "@types/react-router-dom": "^5.1.7", + "@types/react-table": "7.7.2", + "@types/react-test-renderer": "17.0.1", + "@types/react-transition-group": "4.4.0", + "@types/react-window": "1.8.1", + "@types/slate": "0.47.2", + "@types/slate-plain-serializer": "0.7.1", + "@types/slate-react": "0.22.5", + "@types/testing-library__jest-dom": "5.14.2", + "@types/testing-library__react-hooks": "^3.2.0", + "@types/tinycolor2": "1.4.1", + "@types/uuid": "8.3.0", + "@wojtekmaj/enzyme-adapter-react-17": "0.6.2", + "babel-loader": "8.2.2", + "common-tags": "^1.8.0", + "css-loader": "6.5.1", + "css-minimizer-webpack-plugin": "3.3.0", + "csstype": "3.0.9", + "enzyme": "3.11.0", + "expose-loader": "3.1.0", + "mock-raf": "1.0.1", + "postcss": "8.4.5", + "postcss-loader": "6.2.1", + "raw-loader": "4.0.2", + "react-docgen-typescript-loader": "3.7.2", + "react-test-renderer": "17.0.1", + "rimraf": "3.0.1", + "rollup": "2.63.0", + "rollup-plugin-sourcemaps": "0.6.3", + "rollup-plugin-terser": "7.0.2", + "sass-loader": "12.4.0", + "storybook-dark-mode": "1.0.8", + "style-loader": "3.3.0", + "terser-webpack-plugin": "5.3.0", + "ts-loader": "8.0.11", + "typescript": "4.5.4", + "webpack": "5.65.0", + "webpack-filter-warnings-plugin": "1.2.1" + }, + "types": "src/index.ts" +} diff --git a/packages/grafana-ui/rollup.config.ts b/packages/grafana-ui/rollup.config.ts new file mode 100644 index 00000000..d40c5776 --- /dev/null +++ b/packages/grafana-ui/rollup.config.ts @@ -0,0 +1,49 @@ +import resolve from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import image from '@rollup/plugin-image'; +import { terser } from 'rollup-plugin-terser'; + +const pkg = require('./package.json'); + +const libraryName = pkg.name; + +const buildCjsPackage = ({ env }) => { + return { + input: `compiled/index.js`, + output: [ + { + dir: 'dist', + name: libraryName, + format: 'cjs', + sourcemap: true, + strict: false, + exports: 'named', + chunkFileNames: `[name].${env}.js`, + globals: { + react: 'React', + 'prop-types': 'PropTypes', + }, + }, + ], + external: [ + 'react', + 'react-dom', + '@grafana/aws-sdk', + '@grafana/data', + '@grafana/schema', + '@grafana/e2e-selectors', + 'moment', + 'jquery', // required to use jquery.plot, which is assigned externally + 'react-inlinesvg', // required to mock Icon svg loading in tests + ], + plugins: [ + commonjs({ + include: /node_modules/, + }), + resolve(), + image(), + env === 'production' && terser(), + ], + }; +}; +export default [buildCjsPackage({ env: 'development' }), buildCjsPackage({ env: 'production' })]; diff --git a/packages/grafana-ui/src/Intro.story.mdx b/packages/grafana-ui/src/Intro.story.mdx new file mode 100644 index 00000000..11411323 --- /dev/null +++ b/packages/grafana-ui/src/Intro.story.mdx @@ -0,0 +1,51 @@ +import { Meta } from '@storybook/addon-docs/blocks'; + + + +# Grafana design system + +> **@grafana/ui is currently in BETA**. + +With the design system @grafana/ui, we want to democratize development. This library of reusable [Grafana](https://github.com/grafana/grafana) components and guidelines helps you with contribution and plugin development. + +## Our vision + +Grafana Labs started @grafana/ui to make contributing to Grafana as easy as possible for Grafanistas and community members of all fields. We want to create a component library that results in: + +- Understanding of how each component works and how you can use it to create a great user experience. +- Short development times and consistent code quality. +- A beautiful, visually consistent Grafana experience. +- Transparency about how we work and what we do. + +### Maintained by Grafana Labs and you + +Grafana Labs has a task force that helps create and maintain components. We make sure that components are documented and easy to use. The current status of the @grafana/ui development is available on [GitHub](https://github.com/grafana/grafana/projects/26). Feel free to contribute! + +### How to get involved + +When we notice that we need to change something, we determine together what the change should be, then we put the change in place and communicate it publicly. Developers and designers create and improve @grafana/ui together. Throughout the process, we strive to involve you and meet your needs. We are looking forward to discussing your design and improvement ideas on [GitHub](https://github.com/grafana/grafana/projects/26). + +## Get started + +- **Explore UI components** + Click on any of the component in the sidebar to see how they look, and how to configure them. Each component pages contains documentation of its properties, as well as code examples for how to use it. +- **Try them out** + - Experiment with different properties, by clicking **Canvas** at the top of each component page. + - Change the properties under **Knobs** in the bottom panel. +- **Use them** + Once you've found the right component for your use case, click the **Story** tab to see the code implementation, or look at examples under **Docs**. + + For more details, refer to the [package source](https://github.com/grafana/grafana/tree/main/packages/grafana-ui). + +## Installation + +`yarn add @grafana/ui` + +`npm install @grafana/ui` + +## Related links + +- [Build a panel plugin tutorial](https://grafana.com/tutorials/build-a-panel-plugin/#0) +- [Plugin Developer guide](https://grafana.com/docs/grafana/latest/plugins/developing/development/) +- [Boilerplate Panel Plugin](https://github.com/grafana/simple-react-panel) +- [Grafana Tutorials](https://grafana.com/tutorials/) diff --git a/packages/grafana-ui/src/components/Alert/Alert.mdx b/packages/grafana-ui/src/components/Alert/Alert.mdx new file mode 100644 index 00000000..eee11214 --- /dev/null +++ b/packages/grafana-ui/src/components/Alert/Alert.mdx @@ -0,0 +1,17 @@ +import { Meta, Props } from '@storybook/addon-docs/blocks'; +import { Alert } from './Alert'; + + + +# Alert + +An alert displays an important message in a way that attracts the user's attention without interrupting the user's task. +`onRemove` handler can be used to enable manually dismissing the alert. + +# Usage + +```jsx + +``` + + diff --git a/packages/grafana-ui/src/components/Alert/Alert.story.tsx b/packages/grafana-ui/src/components/Alert/Alert.story.tsx new file mode 100644 index 00000000..cb159b18 --- /dev/null +++ b/packages/grafana-ui/src/components/Alert/Alert.story.tsx @@ -0,0 +1,189 @@ +import React from 'react'; +import { Story } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import { Alert, AlertVariant, VerticalGroup } from '@grafana/ui'; +import { Props } from './Alert'; +import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; +import mdx from '../Alert/Alert.mdx'; +import { StoryExample } from '../../utils/storybook/StoryExample'; + +const severities: AlertVariant[] = ['error', 'warning', 'info', 'success']; + +export default { + title: 'Overlays/Alert', + component: Alert, + decorators: [withCenteredStory, withHorizontallyCenteredStory], + parameters: { + docs: { + page: mdx, + }, + knobs: { + disable: true, + }, + controls: { + exclude: ['onRemove'], + }, + }, + argTypes: { + severity: { control: { type: 'select', options: severities } }, + }, +}; + +export const Examples: Story = ({ severity, title, buttonContent }) => { + return ( + + + {buttonContent}} + onRemove={action('Remove button clicked')} + > + +
Child content that includes some alert details, like maybe what actually happened.
+
+
+
+ + + + + + + + + {severities.map((severity) => ( + + ))} + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam metus urna, aliquam eu scelerisque non, + facilisis eget est. Morbi eleifend egestas massa id vulputate. Fusce dignissim magna lacus, ut molestie odio + feugiat sed. Cras fringilla justo sit amet turpis scelerisque, a volutpat purus iaculis. Nunc sagittis + molestie faucibus. Curabitur at neque luctus, pellentesque urna eget, posuere urna. Nunc malesuada elit in + ipsum dictum egestas. Praesent convallis mauris massa, porta mattis ex gravida ut. Proin consectetur ultrices + tortor sit amet efficitur. Suspendisse nec turpis dapibus mauris venenatis maximus quis eget orci. Ut semper + enim magna, ullamcorper elementum sapien pharetra vitae. Vivamus at nulla ut metus bibendum ornare et ut leo. + Proin ante turpis, ornare a malesuada et, rutrum nec lorem. Maecenas vestibulum orci vel nibh convallis + eleifend. Quisque vitae consectetur massa, vitae elementum mauris. Pellentesque sit amet ligula lorem. Fusce + sit amet lorem non augue rutrum varius. Donec sed imperdiet libero, eget venenatis elit. Fusce porttitor + dapibus urna. Duis fringilla ante vel tempor tincidunt. In euismod vestibulum odio sit amet iaculis. Donec vel + dapibus libero. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lacinia commodo lectus. Aenean + in magna eget lectus luctus suscipit et vitae erat. Pellentesque quis ligula id lorem egestas sollicitudin sit + amet sed sem. Nullam et nibh a odio rhoncus efficitur sed nec est. Sed commodo lacus vitae sem congue, + accumsan dignissim metus iaculis. Praesent in dignissim nisl. Aliquam facilisis, sapien eget porttitor + ultrices, massa libero bibendum odio, at ornare diam arcu ac massa. Vestibulum egestas leo eget lorem congue + condimentum. Praesent egestas, neque id gravida vehicula, augue ex scelerisque lectus, finibus pellentesque + enim dolor vel ante. Cras convallis, sem at malesuada tincidunt, diam urna auctor leo, sed laoreet est ex in + libero. Ut condimentum ante eget ex gravida, id tempus metus ultricies. Pellentesque placerat, massa id + laoreet molestie, justo nisl varius metus, maximus vehicula erat libero vitae nulla. Mauris rhoncus ligula + vitae volutpat auctor. Suspendisse potenti. Quisque quis orci faucibus, ullamcorper dolor eget, mollis massa. + Etiam eu molestie ipsum. Sed laoreet diam metus, luctus maximus erat viverra quis. Ut eu felis dictum, + tincidunt erat sit amet, scelerisque neque. Orci varius natoque penatibus et magnis dis parturient montes, + nascetur ridiculus mus. Phasellus sit amet est tristique, fermentum massa ut, viverra metus. Interdum et + malesuada fames ac ante ipsum primis in faucibus. Nunc iaculis nunc elit, ut feugiat ipsum egestas eget. + Vestibulum pulvinar ligula mi, quis lacinia diam suscipit eget. Etiam consectetur vel nunc at hendrerit. + Pellentesque blandit eleifend aliquam. Etiam et malesuada purus, et bibendum sapien. Phasellus tincidunt + consequat eros consequat sodales. Vestibulum quis viverra neque. Integer sit amet lacinia nunc. Ut cursus, + elit id faucibus elementum, elit nunc dapibus tellus, non ornare nisi sapien et eros. Nunc sit amet suscipit + arcu. Nulla ut nunc tempor, auctor massa sed, consectetur orci. Pellentesque erat ante, placerat eget dictum + elementum, dapibus et ipsum. Nunc sit amet nulla gravida, finibus felis vel, tempus sem. In urna purus, + accumsan quis aliquam et, condimentum ac urna. Nullam volutpat ullamcorper sapien, quis ultricies purus + dignissim aliquam. Mauris quis enim ante. Etiam vulputate faucibus placerat. Ut pellentesque, purus vitae + euismod cursus, lacus enim vulputate sapien, in porttitor erat dui eu lectus. Duis eleifend, massa vel + vehicula gravida, magna urna rutrum ligula, vitae mollis ipsum neque id enim. Donec varius tristique nisi, et + vestibulum dolor efficitur eget. Cras mauris leo, bibendum eget pretium a, tincidunt faucibus massa. + Vestibulum hendrerit arcu magna, vel consequat est euismod nec. Vestibulum non lacus porttitor, congue tortor + ut, venenatis elit. Duis at lectus arcu. Nunc quis sapien eu ipsum rutrum accumsan. Orci varius natoque + penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus quis sapien luctus, volutpat nulla + eget, gravida nunc. Aenean placerat a felis quis imperdiet. Sed sapien tellus, ultrices non ipsum eget, + pretium rhoncus quam. Aliquam erat volutpat. Maecenas at interdum turpis, eu mattis ligula. Class aptent + taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In lobortis felis a leo + ultricies, venenatis mollis felis lobortis. Suspendisse placerat vel ante vel euismod. Aenean sit amet + ullamcorper mauris, id consectetur est. Ut ultricies enim non quam condimentum, et congue arcu commodo. + Praesent convallis eleifend turpis, vitae feugiat turpis imperdiet sit amet. Class aptent taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos. Quisque vulputate porttitor mattis. Pellentesque + sed ullamcorper lectus. Suspendisse velit tortor, viverra eget facilisis condimentum, accumsan sit amet felis. + Cras lobortis mi fermentum ligula consectetur, vitae tincidunt mauris scelerisque. Aenean ac condimentum erat, + quis lacinia lacus. Ut magna nibh, tempor et ligula suscipit, placerat laoreet ipsum. In semper semper nisl. + Donec risus lorem, tempor sed sollicitudin vitae, fringilla et mi. Vivamus pulvinar quam nisl, et tincidunt + justo tempus quis. Duis semper magna nunc, vitae faucibus lectus facilisis sed. Phasellus consequat arcu vel + interdum fermentum. In condimentum euismod neque, sed aliquet mauris posuere nec. Etiam metus eros, + pellentesque eget scelerisque id, porttitor at ligula. Curabitur eget nibh maximus enim lobortis sodales. + Etiam vulputate ligula lobortis vestibulum pulvinar. Curabitur eros justo, accumsan sed elit ac, mattis + lacinia nisi. Suspendisse ullamcorper lectus sit amet tellus condimentum porttitor. Duis cursus, neque et + aliquam congue, odio lectus porta elit, id lacinia dolor justo non leo. Aliquam vehicula at tellus ullamcorper + tincidunt. Phasellus neque nibh, convallis sit amet arcu sit amet, convallis egestas tortor. Etiam sit amet + vehicula quam. Praesent id consequat lacus, ac facilisis quam. Integer tristique lorem eros, id consequat + lorem lobortis vitae. Aliquam luctus purus eget sem molestie iaculis. Duis nisl risus, sodales sit amet nunc + vitae, volutpat cursus augue. Pellentesque congue massa eu metus pellentesque consectetur at vel neque. Donec + bibendum hendrerit erat, vitae dictum enim lobortis a. Quisque ac dapibus tellus, sit amet facilisis orci. + Cras pretium tortor non condimentum semper. Phasellus mollis condimentum blandit. Pellentesque at arcu risus. + Vivamus sit amet dui semper, suscipit est nec, elementum arcu. Praesent ante turpis, convallis ac leo eget, + rutrum bibendum ante. Sed venenatis vehicula lobortis. Phasellus consectetur velit nec congue venenatis. + Interdum et malesuada fames ac ante ipsum primis in faucibus. Nullam sagittis, arcu quis sagittis vestibulum, + odio lorem tempus massa, non condimentum enim turpis ut orci. Vivamus sit amet dignissim eros. Vestibulum ante + ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Phasellus efficitur est eu semper + luctus. Nunc gravida tristique urna, et mollis leo porttitor suscipit. In hac habitasse platea dictumst. Etiam + tempus varius mattis. Suspendisse potenti. Duis finibus ornare tortor, a auctor lacus dictum id. Suspendisse + eget auctor lorem, sollicitudin placerat ipsum. Aliquam suscipit ante at gravida tincidunt. Donec vel turpis + dui. Ut facilisis, dui id fermentum ultrices, nunc mi pretium ex, eu lobortis sem tellus porttitor nulla. Nam + sit amet mauris justo. Maecenas libero est, dignissim vel dolor ac, rutrum accumsan tellus. Nulla in lacinia + orci, facilisis feugiat mi. Nunc sit amet ultricies dolor. Sed ac interdum lacus. Quisque facilisis viverra + orci vel tincidunt. Suspendisse feugiat ligula non justo molestie viverra. Cras sed ultricies quam. Duis + aliquam ante lacus, non posuere neque pretium id. Fusce at orci facilisis, pretium justo eu, vestibulum sem. + Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis at lorem ultrices, + tincidunt nulla ac, molestie ligula. Phasellus erat nunc, consectetur ut velit vel, porta fringilla ante. + Vestibulum laoreet lorem erat, ultricies porta ex venenatis vel. Donec vestibulum enim id suscipit + pellentesque. Donec vitae dictum arcu. In ac tellus dignissim, imperdiet tellus quis, malesuada nisl. Aliquam + finibus urna commodo purus ultricies, non vulputate risus ullamcorper. Cras semper ultrices posuere. Etiam + massa nisi, vehicula sit amet volutpat sit amet, commodo vel mi. Maecenas commodo consectetur ipsum nec + ultrices. Sed hendrerit quam nulla, ut tincidunt tortor commodo eget. Vestibulum euismod condimentum + porttitor. Mauris egestas posuere justo ac suscipit. Nulla auctor tellus nec eros rhoncus, a congue odio + accumsan. Phasellus tempus risus ut orci commodo, sed lobortis ex porta. Nullam ligula erat, pretium ut nibh + volutpat, tincidunt pellentesque purus. Vivamus cursus eget nisi id ornare. Phasellus ut aliquet turpis. + Vestibulum ornare ex eros, quis accumsan neque porta id. Pellentesque eleifend, tortor eget dignissim + convallis, nisl felis fringilla dolor, dapibus bibendum mauris lacus dignissim metus. Cras cursus faucibus + condimentum. Curabitur non libero risus. Morbi nisi augue, aliquam quis neque sit amet, commodo ullamcorper + justo. Aenean pulvinar accumsan nibh, vel bibendum turpis rutrum vitae. Donec condimentum justo vel luctus + consectetur. Donec id nisl eu erat sollicitudin venenatis at eget justo. Mauris ac nulla laoreet, semper + tortor sed, egestas odio. Fusce ex ligula, aliquet sed tortor sit amet, porta malesuada libero. Aenean varius + tellus in enim fringilla tristique. Duis risus diam, condimentum ac ornare sed, imperdiet non lectus. Mauris + auctor condimentum pulvinar. Pellentesque dapibus ultricies neque eu egestas. Phasellus molestie volutpat + tincidunt. Aenean tristique felis aliquam consectetur fringilla. Pellentesque a mauris nibh. Maecenas commodo + dignissim sem, eget laoreet purus laoreet eu. Sed arcu mi, facilisis quis finibus ac, pulvinar ut sem. Nulla + facilisi. Maecenas in elit diam. Vivamus aliquam enim eget enim condimentum fermentum. Sed convallis tellus + nisl, eget congue diam hendrerit et. Nulla posuere, sem non condimentum aliquet, leo arcu scelerisque leo, sit + amet maximus ante massa in odio. Nunc dictum nibh ac dui luctus, sit amet tempor massa imperdiet. Nunc dictum + ligula augue, a auctor odio rutrum a. Cras auctor, mi vitae maximus dictum, purus mauris ornare libero, ac + consequat mauris diam sit amet mauris. In egestas eu felis ut volutpat. Etiam dignissim justo vitae sagittis + venenatis. Vestibulum fermentum lectus nisl, vitae tempor ipsum lobortis nec. Nam porttitor est vel libero + mollis, vel accumsan nisi iaculis. Suspendisse interdum consequat sapien, quis aliquam leo condimentum ut. In + ut risus sit amet quam viverra facilisis. Mauris dapibus tortor id purus egestas mollis. Quisque vitae ornare + ex. Vivamus non accumsan lectus. Mauris at iaculis ex. Curabitur rutrum magna nibh, eu accumsan felis + tristique in. Donec in fringilla orci. Quisque ante dolor, tempor vitae lacinia non, malesuada at dui. Ut + tincidunt bibendum magna vitae ornare. Suspendisse a ipsum ut nulla ornare pretium. Donec malesuada rhoncus + facilisis. Integer nulla mi, sagittis vel purus non, viverra sodales lectus. Pellentesque habitant morbi + tristique senectus et netus et malesuada fames ac turpis egestas. Aenean tristique turpis neque, nec elementum + ipsum condimentum tempor. Pellentesque mauris magna, venenatis ac sodales et, fermentum sed nunc. Pellentesque + dignissim lacinia suscipit. Pellentesque mollis tellus justo, eu facilisis neque tempor a. Aenean id metus + gravida, consectetur ligula eget, tincidunt sapien. Morbi in tellus id ex vestibulum sagittis sed vitae risus. + In vehicula sed arcu auctor ullamcorper. Etiam elementum mollis fringilla. + + +
+ ); +}; + +Examples.args = { + severity: 'error', + title: 'Some very important message', + buttonContent: 'Close', +}; diff --git a/packages/grafana-ui/src/components/Alert/Alert.tsx b/packages/grafana-ui/src/components/Alert/Alert.tsx new file mode 100644 index 00000000..b25ecc02 --- /dev/null +++ b/packages/grafana-ui/src/components/Alert/Alert.tsx @@ -0,0 +1,148 @@ +import React, { HTMLAttributes, ReactNode } from 'react'; +import { css, cx } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { useTheme2 } from '../../themes'; +import { Icon } from '../Icon/Icon'; +import { IconName } from '../../types/icon'; +import { IconButton } from '../IconButton/IconButton'; +import { Button } from '../Button/Button'; + +export type AlertVariant = 'success' | 'warning' | 'error' | 'info'; + +export interface Props extends HTMLAttributes { + title: string; + /** On click handler for alert button, mostly used for dismissing the alert */ + onRemove?: (event: React.MouseEvent) => void; + severity?: AlertVariant; + children?: ReactNode; + elevated?: boolean; + buttonContent?: React.ReactNode | string; + bottomSpacing?: number; +} + +function getIconFromSeverity(severity: AlertVariant): string { + switch (severity) { + case 'error': + case 'warning': + return 'exclamation-triangle'; + case 'info': + return 'info-circle'; + case 'success': + return 'check'; + default: + return ''; + } +} + +export const Alert = React.forwardRef( + ( + { title, onRemove, children, buttonContent, elevated, bottomSpacing, className, severity = 'error', ...restProps }, + ref + ) => { + const theme = useTheme2(); + const styles = getStyles(theme, severity, elevated, bottomSpacing); + + return ( +
+
+ +
+
+
{title}
+ {children &&
{children}
} +
+ {/* If onRemove is specified, giving preference to onRemove */} + {onRemove && !buttonContent && ( +
+ +
+ )} + {onRemove && buttonContent && ( +
+ +
+ )} +
+ ); + } +); + +Alert.displayName = 'Alert'; + +const getStyles = (theme: GrafanaTheme2, severity: AlertVariant, elevated?: boolean, bottomSpacing?: number) => { + const color = theme.colors[severity]; + const borderRadius = theme.shape.borderRadius(); + + return { + alert: css` + flex-grow: 1; + position: relative; + border-radius: ${borderRadius}; + display: flex; + flex-direction: row; + align-items: stretch; + background: ${theme.colors.background.secondary}; + box-shadow: ${elevated ? theme.shadows.z3 : theme.shadows.z1}; + margin-bottom: ${theme.spacing(bottomSpacing ?? 2)}; + + &:before { + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + background: ${theme.colors.background.primary}; + z-index: -1; + } + `, + icon: css` + padding: ${theme.spacing(2, 3)}; + background: ${color.main}; + border-radius: ${borderRadius} 0 0 ${borderRadius}; + color: ${color.contrastText}; + display: flex; + align-items: center; + justify-content: center; + `, + title: css` + font-weight: ${theme.typography.fontWeightMedium}; + color: ${theme.colors.text.primary}; + `, + body: css` + color: ${theme.colors.text.secondary}; + padding: ${theme.spacing(2)}; + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: center; + overflow-wrap: break-word; + word-break: break-word; + `, + content: css` + color: ${theme.colors.text.secondary}; + padding-top: ${theme.spacing(1)}; + max-height: 50vh; + overflow-y: scroll; + `, + buttonWrapper: css` + padding: ${theme.spacing(1)}; + background: none; + display: flex; + align-items: center; + `, + close: css` + padding: ${theme.spacing(2, 1)}; + background: none; + display: flex; + `, + }; +}; diff --git a/packages/grafana-ui/src/components/Badge/Badge.mdx b/packages/grafana-ui/src/components/Badge/Badge.mdx new file mode 100644 index 00000000..8782bceb --- /dev/null +++ b/packages/grafana-ui/src/components/Badge/Badge.mdx @@ -0,0 +1,5 @@ + + +# Badge + +The badge component adds meta information to other content, for example about release status or new elements. You can add any `Icon` component or use the badge without an icon. diff --git a/packages/grafana-ui/src/components/Badge/Badge.story.tsx b/packages/grafana-ui/src/components/Badge/Badge.story.tsx new file mode 100644 index 00000000..4d790acf --- /dev/null +++ b/packages/grafana-ui/src/components/Badge/Badge.story.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { Story } from '@storybook/react'; +import { Badge, BadgeProps } from '@grafana/ui'; +import { iconOptions } from '../../utils/storybook/knobs'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +export default { + title: 'Data Display/Badge', + component: Badge, + decorators: [withCenteredStory], + parameters: { + docs: {}, + }, + argTypes: { + icon: { options: iconOptions, control: { type: 'select' } }, + color: { control: 'select' }, + text: { control: 'text' }, + }, +}; + +const Template: Story = (args) => ; + +export const Basic = Template.bind({}); + +Basic.args = { + text: 'Badge label', + color: 'blue', + icon: 'rocket', +}; diff --git a/packages/grafana-ui/src/components/Badge/Badge.tsx b/packages/grafana-ui/src/components/Badge/Badge.tsx new file mode 100644 index 00000000..053f063e --- /dev/null +++ b/packages/grafana-ui/src/components/Badge/Badge.tsx @@ -0,0 +1,78 @@ +import React, { HTMLAttributes } from 'react'; +import { Icon } from '../Icon/Icon'; +import { useTheme } from '../../themes/ThemeContext'; +import { stylesFactory } from '../../themes/stylesFactory'; +import { IconName } from '../../types'; +import { Tooltip } from '../Tooltip/Tooltip'; +import { getColorForTheme, GrafanaTheme } from '@grafana/data'; +import tinycolor from 'tinycolor2'; +import { css, cx } from '@emotion/css'; +import { HorizontalGroup } from '../Layout/Layout'; + +export type BadgeColor = 'blue' | 'red' | 'green' | 'orange' | 'purple'; + +export interface BadgeProps extends HTMLAttributes { + text: React.ReactNode; + color: BadgeColor; + icon?: IconName; + tooltip?: string; +} + +export const Badge = React.memo(({ icon, color, text, tooltip, className, ...otherProps }) => { + const theme = useTheme(); + const styles = getStyles(theme, color); + const badge = ( +
+ + {icon && } + {text} + +
+ ); + + return tooltip ? ( + + {badge} + + ) : ( + badge + ); +}); + +Badge.displayName = 'Badge'; + +const getStyles = stylesFactory((theme: GrafanaTheme, color: BadgeColor) => { + let sourceColor = getColorForTheme(color, theme); + let borderColor = ''; + let bgColor = ''; + let textColor = ''; + + if (theme.isDark) { + bgColor = tinycolor(sourceColor).setAlpha(0.15).toString(); + borderColor = tinycolor(sourceColor).darken(30).toString(); + textColor = tinycolor(sourceColor).lighten(15).toString(); + } else { + bgColor = tinycolor(sourceColor).setAlpha(0.15).toString(); + borderColor = tinycolor(sourceColor).lighten(20).toString(); + textColor = tinycolor(sourceColor).darken(15).toString(); + } + + return { + wrapper: css` + font-size: ${theme.typography.size.sm}; + display: inline-flex; + padding: 1px 4px; + border-radius: 3px; + background: ${bgColor}; + border: 1px solid ${borderColor}; + color: ${textColor}; + font-weight: ${theme.typography.weight.regular}; + + > span { + position: relative; + top: 1px; + margin-left: 2px; + } + `, + }; +}); diff --git a/packages/grafana-ui/src/components/BarGauge/BarGauge.mdx b/packages/grafana-ui/src/components/BarGauge/BarGauge.mdx new file mode 100644 index 00000000..e28cf46c --- /dev/null +++ b/packages/grafana-ui/src/components/BarGauge/BarGauge.mdx @@ -0,0 +1,48 @@ +import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks'; +import { BarGauge } from './BarGauge'; + + + +# BarGauge + +## Usage + +```tsx +import { BarGauge, BarGaugeDisplayMode } from '@grafana/ui'; +import { VizOrientation, ThresholdsMode, Field, FieldType, getDisplayProcessor } from '@grafana/data'; + +const field: Partial = { + type: FieldType.number, + config: { + min: minValue, + max: maxValue, + thresholds: { + mode: ThresholdsMode.Absolute, + steps: [ + { value: -Infinity, color: 'green' }, + { value: threshold1Value, color: threshold1Color }, + { value: threshold2Value, color: threshold2Color }, + ], + }, + }, +}; +field.display = getDisplayProcessor({ field }); + +const value = { + text: value.toString(), + title: title, + numeric: value, +}; + +//... +; +``` + + diff --git a/packages/grafana-ui/src/components/BarGauge/BarGauge.story.tsx b/packages/grafana-ui/src/components/BarGauge/BarGauge.story.tsx new file mode 100644 index 00000000..232ff7d6 --- /dev/null +++ b/packages/grafana-ui/src/components/BarGauge/BarGauge.story.tsx @@ -0,0 +1,124 @@ +import React from 'react'; +import { Story, Meta } from '@storybook/react'; +import { BarGauge, BarGaugeDisplayMode } from '@grafana/ui'; +import { VizOrientation, ThresholdsMode, Field, FieldType, getDisplayProcessor } from '@grafana/data'; +import { Props } from './BarGauge'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import mdx from './BarGauge.mdx'; +import { useTheme2 } from '../../themes'; + +export default { + title: 'Visualizations/BarGauge', + component: BarGauge, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + controls: { + exclude: [ + 'theme', + 'field', + 'value', + 'display', + 'orientation', + 'text', + 'onClick', + 'className', + 'alignmentFactors', + ], + }, + }, + args: { + numeric: 70, + title: 'Title', + minValue: 0, + maxValue: 100, + threshold1Value: 40, + threshold1Color: 'orange', + threshold2Value: 60, + threshold2Color: 'red', + displayMode: BarGaugeDisplayMode.Gradient, + lcdCellWidth: 12, + itemSpacing: 8, + showUnfilled: true, + }, + argTypes: { + displayMode: { + control: { + type: 'select', + options: [BarGaugeDisplayMode.Lcd, BarGaugeDisplayMode.Gradient, BarGaugeDisplayMode.Basic], + }, + }, + width: { control: { type: 'range', min: 200, max: 800 } }, + height: { control: { type: 'range', min: 200, max: 800 } }, + threshold1Color: { control: 'color' }, + threshold2Color: { control: 'color' }, + }, +} as Meta; + +interface StoryProps extends Partial { + numeric: number; + title: string; + minValue: number; + maxValue: number; + threshold1Color: string; + threshold2Color: string; + threshold1Value: number; + threshold2Value: number; +} + +const AddBarGaugeStory = (storyProps: StoryProps) => { + const theme = useTheme2(); + + const field: Partial = { + type: FieldType.number, + config: { + min: storyProps.minValue, + max: storyProps.maxValue, + thresholds: { + mode: ThresholdsMode.Absolute, + steps: [ + { value: -Infinity, color: 'green' }, + { value: storyProps.threshold1Value, color: storyProps.threshold1Color }, + { value: storyProps.threshold2Value, color: storyProps.threshold2Color }, + ], + }, + }, + }; + field.display = getDisplayProcessor({ field, theme }); + + const props: Partial = { + theme, + lcdCellWidth: storyProps.lcdCellWidth, + itemSpacing: storyProps.itemSpacing, + showUnfilled: storyProps.showUnfilled, + width: storyProps.width, + height: storyProps.height, + value: { + text: storyProps.numeric.toString(), + title: storyProps.title, + numeric: storyProps.numeric, + }, + displayMode: storyProps.displayMode, + orientation: storyProps.orientation, + field: field.config!, + display: field.display!, + }; + + return ; +}; + +export const barGaugeVertical: Story = AddBarGaugeStory.bind({}); +barGaugeVertical.args = { + height: 500, + width: 100, + orientation: VizOrientation.Vertical, +}; + +export const barGaugeHorizontal: Story = AddBarGaugeStory.bind({}); +barGaugeHorizontal.args = { + height: 100, + width: 500, + orientation: VizOrientation.Horizontal, +}; diff --git a/packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx b/packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx new file mode 100644 index 00000000..b5d43851 --- /dev/null +++ b/packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx @@ -0,0 +1,334 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { + DisplayValue, + VizOrientation, + ThresholdsMode, + FALLBACK_COLOR, + Field, + FieldType, + getDisplayProcessor, + createTheme, +} from '@grafana/data'; +import { + BarGauge, + Props, + getCellColor, + getValueColor, + getBasicAndGradientStyles, + getBarGradient, + getTitleStyles, + getValuePercent, + BarGaugeDisplayMode, + calculateBarAndValueDimensions, +} from './BarGauge'; + +const green = '#73BF69'; +const orange = '#FF9830'; + +function getProps(propOverrides?: Partial): Props { + const field: Partial = { + type: FieldType.number, + config: { + min: 0, + max: 100, + thresholds: { + mode: ThresholdsMode.Absolute, + steps: [ + { value: -Infinity, color: 'green' }, + { value: 70, color: 'orange' }, + { value: 90, color: 'red' }, + ], + }, + }, + }; + const theme = createTheme(); + field.display = getDisplayProcessor({ field, theme }); + + const props: Props = { + displayMode: BarGaugeDisplayMode.Basic, + field: field.config!, + display: field.display!, + height: 300, + width: 300, + value: field.display(25), + theme, + orientation: VizOrientation.Horizontal, + }; + + Object.assign(props, propOverrides); + return props; +} + +const setup = (propOverrides?: object) => { + const props = getProps(propOverrides); + const wrapper = shallow(); + const instance = wrapper.instance() as BarGauge; + + return { + instance, + wrapper, + }; +}; + +function getValue(value: number, title?: string): DisplayValue { + return { numeric: value, text: value.toString(), title: title }; +} + +describe('BarGauge', () => { + describe('getCellColor', () => { + it('returns a fallback if the positionValue is null', () => { + const props = getProps(); + expect(getCellColor(null, props.value, props.display)).toEqual({ + background: FALLBACK_COLOR, + border: FALLBACK_COLOR, + }); + }); + + it('does not show as lit if the value is null (somehow)', () => { + const props = getProps(); + expect(getCellColor(1, (null as unknown) as DisplayValue, props.display)).toEqual( + expect.objectContaining({ + isLit: false, + }) + ); + }); + + it('does not show as lit if the numeric value is NaN', () => { + const props = getProps(); + expect( + getCellColor( + 1, + { + numeric: NaN, + text: '0', + }, + props.display + ) + ).toEqual( + expect.objectContaining({ + isLit: false, + }) + ); + }); + + it('does not show as lit if the positionValue is greater than the numeric value', () => { + const props = getProps(); + expect(getCellColor(75, props.value, props.display)).toEqual( + expect.objectContaining({ + isLit: false, + }) + ); + }); + + it('shows as lit otherwise', () => { + const props = getProps(); + expect(getCellColor(1, props.value, props.display)).toEqual( + expect.objectContaining({ + isLit: true, + }) + ); + }); + + it('returns a fallback if there is no display processor', () => { + const props = getProps(); + expect(getCellColor(null, props.value, undefined)).toEqual({ + background: FALLBACK_COLOR, + border: FALLBACK_COLOR, + }); + }); + }); + + describe('Get value color', () => { + it('should get the threshold color if value is same as a threshold', () => { + const props = getProps(); + props.value = props.display!(70); + expect(getValueColor(props)).toEqual(orange); + }); + it('should get the base threshold', () => { + const props = getProps(); + props.value = props.display!(-10); + expect(getValueColor(props)).toEqual(green); + }); + }); + + describe('Get value percent', () => { + it('0 to 100 and value 40', () => { + expect(getValuePercent(40, 0, 100)).toEqual(0.4); + }); + + it('50 to 100 and value 75', () => { + expect(getValuePercent(75, 50, 100)).toEqual(0.5); + }); + + it('-30 to 30 and value 0', () => { + expect(getValuePercent(0, -30, 30)).toEqual(0.5); + }); + + it('-30 to 30 and value 30', () => { + expect(getValuePercent(30, -30, 30)).toEqual(1); + }); + }); + + describe('Vertical bar', () => { + it('should adjust empty region to always have same width as colored bar', () => { + const props = getProps({ + width: 150, + value: getValue(100), + orientation: VizOrientation.Vertical, + }); + const styles = getBasicAndGradientStyles(props); + expect(styles.emptyBar.width).toBe('150px'); + }); + }); + + describe('Vertical bar without title', () => { + it('should not include title height in height', () => { + const props = getProps({ + height: 300, + value: getValue(100), + orientation: VizOrientation.Vertical, + }); + const styles = getBasicAndGradientStyles(props); + expect(styles.bar.height).toBe('270px'); + }); + }); + + describe('Vertical bar with title', () => { + it('should include title height in height', () => { + const props = getProps({ + height: 300, + value: getValue(100, 'ServerA'), + orientation: VizOrientation.Vertical, + }); + const styles = getBasicAndGradientStyles(props); + expect(styles.bar.height).toBe('249px'); + expect(styles.emptyBar.bottom).toBe('-3px'); + }); + }); + + describe('Horizontal bar', () => { + it('should stretch items', () => { + const props = getProps({ + height: 300, + value: getValue(100, 'ServerA'), + orientation: VizOrientation.Horizontal, + }); + const styles = getBasicAndGradientStyles(props); + expect(styles.wrapper.alignItems).toBe('stretch'); + expect(styles.emptyBar.left).toBe('-3px'); + }); + }); + + describe('Horizontal bar with title', () => { + it('should place above if height > 40', () => { + const props = getProps({ + height: 41, + value: getValue(100, 'AA'), + orientation: VizOrientation.Horizontal, + }); + const styles = getTitleStyles(props); + expect(styles.wrapper.flexDirection).toBe('column'); + }); + + it('should place below if height < 40', () => { + const props = getProps({ + height: 30, + value: getValue(100, 'AA'), + orientation: VizOrientation.Horizontal, + }); + const styles = getTitleStyles(props); + expect(styles.wrapper.flexDirection).toBe('row'); + }); + + it('should calculate title width based on title', () => { + const props = getProps({ + height: 30, + value: getValue(100, 'AA'), + orientation: VizOrientation.Horizontal, + }); + const styles = getTitleStyles(props); + expect(styles.title.width).toBe('17px'); + + const props2 = getProps({ + height: 30, + value: getValue(120, 'Longer title with many words'), + orientation: VizOrientation.Horizontal, + }); + const styles2 = getTitleStyles(props2); + expect(styles2.title.width).toBe('43px'); + }); + + it('Should limit text length to 40%', () => { + const props = getProps({ + height: 30, + value: getValue( + 100, + 'saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ), + orientation: VizOrientation.Horizontal, + }); + const styles = getTitleStyles(props); + expect(styles.title.width).toBe('119px'); + }); + + it('should use alignmentFactors if provided', () => { + const props = getProps({ + height: 30, + value: getValue(100, 'AA'), + alignmentFactors: { + title: 'Super duper long title', + text: '1000', + }, + orientation: VizOrientation.Horizontal, + }); + const styles = getTitleStyles(props); + expect(styles.title.width).toBe('37px'); + }); + + it('should adjust empty region to always have same height as colored bar', () => { + const props = getProps({ + height: 150, + value: getValue(100), + orientation: VizOrientation.Horizontal, + }); + const styles = getBasicAndGradientStyles(props); + expect(styles.emptyBar.height).toBe('150px'); + }); + }); + + describe('Gradient', () => { + it('should build gradient based on thresholds', () => { + const props = getProps({ orientation: VizOrientation.Vertical, value: getValue(100) }); + const gradient = getBarGradient(props, 300); + expect(gradient).toBe('linear-gradient(0deg, #73BF69, #73BF69 105px, #FF9830 240px, #F2495C)'); + }); + + it('should stop gradient if value < threshold', () => { + const props = getProps({ orientation: VizOrientation.Vertical, value: getValue(70) }); + const gradient = getBarGradient(props, 300); + expect(gradient).toBe('linear-gradient(0deg, #73BF69, #73BF69 105px, #FF9830)'); + }); + }); + + describe('Render with basic options', () => { + it('should render', () => { + const { wrapper } = setup(); + expect(wrapper).toMatchSnapshot(); + }); + }); + + describe('calculateBarAndValueDimensions', () => { + it('valueWidth should including paddings in valueWidth', () => { + const result = calculateBarAndValueDimensions( + getProps({ + height: 30, + width: 100, + value: getValue(1, 'AA'), + orientation: VizOrientation.Horizontal, + }) + ); + expect(result.valueWidth).toBe(21); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/BarGauge/BarGauge.tsx b/packages/grafana-ui/src/components/BarGauge/BarGauge.tsx new file mode 100644 index 00000000..7e5e4bf9 --- /dev/null +++ b/packages/grafana-ui/src/components/BarGauge/BarGauge.tsx @@ -0,0 +1,646 @@ +// Library +import React, { CSSProperties, PureComponent, ReactNode } from 'react'; +import tinycolor from 'tinycolor2'; +import { + DisplayProcessor, + DisplayValue, + DisplayValueAlignmentFactors, + FALLBACK_COLOR, + FieldColorModeId, + FieldConfig, + FormattedValue, + formattedValueToString, + GAUGE_DEFAULT_MAXIMUM, + GAUGE_DEFAULT_MINIMUM, + getFieldColorMode, + TextDisplayOptions, + ThresholdsMode, + TimeSeriesValue, + VizOrientation, +} from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay'; +import { calculateFontSize, measureText } from '../../utils/measureText'; +import { Themeable2 } from '../../types'; + +const MIN_VALUE_HEIGHT = 18; +const MAX_VALUE_HEIGHT = 50; +const MAX_VALUE_WIDTH = 150; +const TITLE_LINE_HEIGHT = 1.5; +const VALUE_LINE_HEIGHT = 1; +const VALUE_LEFT_PADDING = 10; + +export interface Props extends Themeable2 { + height: number; + width: number; + field: FieldConfig; + display?: DisplayProcessor; + value: DisplayValue; + orientation: VizOrientation; + text?: TextDisplayOptions; + itemSpacing?: number; + lcdCellWidth?: number; + displayMode: BarGaugeDisplayMode; + onClick?: React.MouseEventHandler; + className?: string; + showUnfilled?: boolean; + alignmentFactors?: DisplayValueAlignmentFactors; +} + +export enum BarGaugeDisplayMode { + Basic = 'basic', + Lcd = 'lcd', + Gradient = 'gradient', +} + +export class BarGauge extends PureComponent { + static defaultProps: Partial = { + lcdCellWidth: 12, + value: { + text: '100', + numeric: 100, + }, + displayMode: BarGaugeDisplayMode.Gradient, + orientation: VizOrientation.Horizontal, + field: { + min: 0, + max: 100, + thresholds: { + mode: ThresholdsMode.Absolute, + steps: [], + }, + }, + itemSpacing: 8, + showUnfilled: true, + }; + + render() { + const { onClick, className } = this.props; + const { title } = this.props.value; + const styles = getTitleStyles(this.props); + + if (!title) { + return ( +
+ {this.renderBarAndValue()} +
+ ); + } + + return ( +
+
{title}
+ {this.renderBarAndValue()} +
+ ); + } + + renderBarAndValue() { + switch (this.props.displayMode) { + case 'lcd': + return this.renderRetroBars(); + case 'basic': + case 'gradient': + default: + return this.renderBasicAndGradientBars(); + } + } + + renderBasicAndGradientBars(): ReactNode { + const { value, showUnfilled } = this.props; + + const styles = getBasicAndGradientStyles(this.props); + + return ( +
+ + {showUnfilled &&
} +
+
+ ); + } + + renderRetroBars(): ReactNode { + const { display, field, value, itemSpacing, alignmentFactors, orientation, lcdCellWidth, text } = this.props; + const { + valueHeight, + valueWidth, + maxBarHeight, + maxBarWidth, + wrapperWidth, + wrapperHeight, + } = calculateBarAndValueDimensions(this.props); + const minValue = field.min ?? GAUGE_DEFAULT_MINIMUM; + const maxValue = field.max ?? GAUGE_DEFAULT_MAXIMUM; + + const isVert = isVertical(orientation); + const valueRange = maxValue - minValue; + const maxSize = isVert ? maxBarHeight : maxBarWidth; + const cellSpacing = itemSpacing!; + const cellCount = Math.floor(maxSize / lcdCellWidth!); + const cellSize = Math.floor((maxSize - cellSpacing * cellCount) / cellCount); + const valueColor = getValueColor(this.props); + + const valueToBaseSizeOn = alignmentFactors ? alignmentFactors : value; + const valueStyles = getValueStyles(valueToBaseSizeOn, valueColor, valueWidth, valueHeight, orientation, text); + + const containerStyles: CSSProperties = { + width: `${wrapperWidth}px`, + height: `${wrapperHeight}px`, + display: 'flex', + }; + + if (isVert) { + containerStyles.flexDirection = 'column-reverse'; + containerStyles.alignItems = 'center'; + } else { + containerStyles.flexDirection = 'row'; + containerStyles.alignItems = 'center'; + valueStyles.justifyContent = 'flex-end'; + } + + const cells: JSX.Element[] = []; + + for (let i = 0; i < cellCount; i++) { + const currentValue = minValue + (valueRange / cellCount) * i; + const cellColor = getCellColor(currentValue, value, display); + const cellStyles: CSSProperties = { + borderRadius: '2px', + }; + + if (cellColor.isLit) { + cellStyles.backgroundImage = `radial-gradient(${cellColor.background} 10%, ${cellColor.backgroundShade})`; + } else { + cellStyles.backgroundColor = cellColor.background; + } + + if (isVert) { + cellStyles.height = `${cellSize}px`; + cellStyles.width = `${maxBarWidth}px`; + cellStyles.marginTop = `${cellSpacing}px`; + } else { + cellStyles.width = `${cellSize}px`; + cellStyles.height = `${maxBarHeight}px`; + cellStyles.marginRight = `${cellSpacing}px`; + } + + cells.push(
); + } + + return ( +
+ {cells} + +
+ ); + } +} + +interface CellColors { + background: string; + backgroundShade?: string; + border: string; + isLit?: boolean; +} + +interface TitleDimensions { + fontSize: number; + placement: 'above' | 'left' | 'below'; + width: number; + height: number; +} + +function isVertical(orientation: VizOrientation) { + return orientation === VizOrientation.Vertical; +} + +function calculateTitleDimensions(props: Props): TitleDimensions { + const { height, width, alignmentFactors, orientation, text } = props; + const title = alignmentFactors ? alignmentFactors.title : props.value.title; + + if (!title) { + return { fontSize: 0, width: 0, height: 0, placement: 'above' }; + } + + if (isVertical(orientation)) { + const fontSize = text?.titleSize ?? 14; + return { + fontSize: fontSize, + width: width, + height: fontSize * TITLE_LINE_HEIGHT, + placement: 'below', + }; + } + + // if height above 40 put text to above bar + if (height > 40) { + if (text?.titleSize) { + return { + fontSize: text?.titleSize, + width: 0, + height: text.titleSize * TITLE_LINE_HEIGHT, + placement: 'above', + }; + } + + const maxTitleHeightRatio = 0.45; + const titleHeight = Math.max(Math.min(height * maxTitleHeightRatio, MAX_VALUE_HEIGHT), 17); + + return { + fontSize: titleHeight / TITLE_LINE_HEIGHT, + width: 0, + height: titleHeight, + placement: 'above', + }; + } + + // title to left of bar scenario + const maxTitleHeightRatio = 0.6; + const titleHeight = Math.max(height * maxTitleHeightRatio, MIN_VALUE_HEIGHT); + const titleFontSize = titleHeight / TITLE_LINE_HEIGHT; + const textSize = measureText(title, titleFontSize); + + // Do not allow title to take up more than 40% width + const textWidth = Math.min(textSize.width + 15, width * 0.4); + + return { + fontSize: text?.titleSize ?? titleFontSize, + height: 0, + width: textWidth, + placement: 'left', + }; +} + +export function getTitleStyles(props: Props): { wrapper: CSSProperties; title: CSSProperties } { + const wrapperStyles: CSSProperties = { + display: 'flex', + overflow: 'hidden', + width: '100%', + }; + + const titleDim = calculateTitleDimensions(props); + + const titleStyles: CSSProperties = { + fontSize: `${titleDim.fontSize}px`, + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + width: '100%', + alignItems: 'center', + alignSelf: 'center', + }; + + if (isVertical(props.orientation)) { + wrapperStyles.flexDirection = 'column-reverse'; + titleStyles.textAlign = 'center'; + } else { + if (titleDim.placement === 'above') { + wrapperStyles.flexDirection = 'column'; + } else { + wrapperStyles.flexDirection = 'row'; + + titleStyles.width = `${titleDim.width}px`; + titleStyles.textAlign = 'right'; + titleStyles.paddingRight = '10px'; + } + } + + return { + wrapper: wrapperStyles, + title: titleStyles, + }; +} + +interface BasicAndGradientStyles { + wrapper: CSSProperties; + bar: CSSProperties; + emptyBar: CSSProperties; + value: CSSProperties; +} + +interface BarAndValueDimensions { + valueWidth: number; + valueHeight: number; + maxBarWidth: number; + maxBarHeight: number; + wrapperHeight: number; + wrapperWidth: number; +} + +/** + * @internal + * Only exported for unit tests + **/ +export function calculateBarAndValueDimensions(props: Props): BarAndValueDimensions { + const { height, width, orientation, text, alignmentFactors } = props; + const titleDim = calculateTitleDimensions(props); + const value = alignmentFactors ?? props.value; + const valueString = formattedValueToString(value); + + let maxBarHeight = 0; + let maxBarWidth = 0; + let valueHeight = 0; + let valueWidth = 0; + let wrapperWidth = 0; + let wrapperHeight = 0; + + // measure text with title font size or min 14px + const fontSizeToMeasureWith = text?.valueSize ?? Math.max(titleDim.fontSize, 12); + const realTextSize = measureText(valueString, fontSizeToMeasureWith); + const realValueWidth = realTextSize.width + VALUE_LEFT_PADDING * 2; + + if (isVertical(orientation)) { + if (text?.valueSize) { + valueHeight = text.valueSize * VALUE_LINE_HEIGHT; + } else { + valueHeight = Math.min(Math.max(height * 0.1, MIN_VALUE_HEIGHT), MAX_VALUE_HEIGHT); + } + + valueWidth = width; + maxBarHeight = height - (titleDim.height + valueHeight); + maxBarWidth = width; + wrapperWidth = width; + wrapperHeight = height - titleDim.height; + } else { + valueHeight = height - titleDim.height; + valueWidth = Math.max(Math.min(width * 0.2, MAX_VALUE_WIDTH), realValueWidth); + + maxBarHeight = height - titleDim.height; + maxBarWidth = width - valueWidth - titleDim.width; + + if (titleDim.placement === 'above') { + wrapperWidth = width; + wrapperHeight = height - titleDim.height; + } else { + wrapperWidth = width - titleDim.width; + wrapperHeight = height; + } + } + + return { + valueWidth, + valueHeight, + maxBarWidth, + maxBarHeight, + wrapperHeight, + wrapperWidth, + }; +} + +export function getCellColor( + positionValue: TimeSeriesValue, + value: Props['value'], + display: Props['display'] +): CellColors { + if (positionValue === null) { + return { + background: FALLBACK_COLOR, + border: FALLBACK_COLOR, + }; + } + + const color = display ? display(positionValue).color : null; + + if (color) { + // if we are past real value the cell is not "on" + if (value === null || isNaN(value.numeric) || (positionValue !== null && positionValue > value.numeric)) { + return { + background: tinycolor(color).setAlpha(0.18).toRgbString(), + border: 'transparent', + isLit: false, + }; + } else { + return { + background: tinycolor(color).setAlpha(0.95).toRgbString(), + backgroundShade: tinycolor(color).setAlpha(0.55).toRgbString(), + border: tinycolor(color).setAlpha(0.9).toRgbString(), + isLit: true, + }; + } + } + + return { + background: FALLBACK_COLOR, + border: FALLBACK_COLOR, + }; +} + +export function getValuePercent(value: number, minValue: number, maxValue: number): number { + return Math.min((value - minValue) / (maxValue - minValue), 1); +} + +/** + * Only exported to for unit test + */ +export function getBasicAndGradientStyles(props: Props): BasicAndGradientStyles { + const { displayMode, field, value, alignmentFactors, orientation, theme, text } = props; + const { valueWidth, valueHeight, maxBarHeight, maxBarWidth } = calculateBarAndValueDimensions(props); + + const minValue = field.min ?? GAUGE_DEFAULT_MINIMUM; + const maxValue = field.max ?? GAUGE_DEFAULT_MAXIMUM; + const valuePercent = getValuePercent(value.numeric, minValue, maxValue); + const valueColor = getValueColor(props); + + const valueToBaseSizeOn = alignmentFactors ? alignmentFactors : value; + const valueStyles = getValueStyles(valueToBaseSizeOn, valueColor, valueWidth, valueHeight, orientation, text); + + const isBasic = displayMode === 'basic'; + const wrapperStyles: CSSProperties = { + display: 'flex', + flexGrow: 1, + }; + + const barStyles: CSSProperties = { + borderRadius: '3px', + position: 'relative', + zIndex: 1, + }; + + const emptyBar: CSSProperties = { + background: `rgba(${theme.isDark ? '255,255,255' : '0,0,0'}, 0.07)`, + flexGrow: 1, + display: 'flex', + borderRadius: '3px', + position: 'relative', + }; + + if (isVertical(orientation)) { + const barHeight = Math.max(valuePercent * maxBarHeight, 1); + + // vertical styles + wrapperStyles.flexDirection = 'column'; + wrapperStyles.justifyContent = 'flex-end'; + + barStyles.transition = 'height 1s'; + barStyles.height = `${barHeight}px`; + barStyles.width = `${maxBarWidth}px`; + + // adjust so that filled in bar is at the bottom + emptyBar.bottom = '-3px'; + + //adjust empty region to always have same width as colored bar + emptyBar.width = `${valueWidth}px`; + + if (isBasic) { + // Basic styles + barStyles.background = `${tinycolor(valueColor).setAlpha(0.35).toRgbString()}`; + barStyles.borderTop = `2px solid ${valueColor}`; + } else { + // Gradient styles + barStyles.background = getBarGradient(props, maxBarHeight); + } + } else { + const barWidth = Math.max(valuePercent * maxBarWidth, 1); + + // Custom styles for horizontal orientation + wrapperStyles.flexDirection = 'row-reverse'; + wrapperStyles.justifyContent = 'flex-end'; + wrapperStyles.alignItems = 'stretch'; + + barStyles.transition = 'width 1s'; + barStyles.height = `${maxBarHeight}px`; + barStyles.width = `${barWidth}px`; + + // shift empty region back to fill gaps due to border radius + emptyBar.left = '-3px'; + + //adjust empty region to always have same height as colored bar + emptyBar.height = `${valueHeight}px`; + + if (isBasic) { + // Basic styles + barStyles.background = `${tinycolor(valueColor).setAlpha(0.35).toRgbString()}`; + barStyles.borderRight = `2px solid ${valueColor}`; + } else { + // Gradient styles + barStyles.background = getBarGradient(props, maxBarWidth); + } + } + + return { + wrapper: wrapperStyles, + bar: barStyles, + value: valueStyles, + emptyBar, + }; +} + +/** + * Only exported to for unit test + */ +export function getBarGradient(props: Props, maxSize: number): string { + const { field, value, orientation, theme } = props; + const cssDirection = isVertical(orientation) ? '0deg' : '90deg'; + const minValue = field.min!; + const maxValue = field.max!; + + let gradient = ''; + let lastpos = 0; + let mode = getFieldColorMode(field.color?.mode); + + if (mode.id === FieldColorModeId.Thresholds) { + const thresholds = field.thresholds!; + + for (let i = 0; i < thresholds.steps.length; i++) { + const threshold = thresholds.steps[i]; + const color = props.theme.visualization.getColorByName(threshold.color); + const valuePercent = + thresholds.mode === ThresholdsMode.Percentage + ? threshold.value / 100 + : getValuePercent(threshold.value, minValue, maxValue); + const pos = valuePercent * maxSize; + const offset = Math.round(pos - (pos - lastpos) / 2); + const thresholdValue = + thresholds.mode === ThresholdsMode.Percentage + ? minValue + (maxValue - minValue) * valuePercent + : threshold.value; + if (gradient === '') { + gradient = `linear-gradient(${cssDirection}, ${color}, ${color}`; + } else if (value.numeric < thresholdValue) { + break; + } else { + lastpos = pos; + gradient += ` ${offset}px, ${color}`; + } + } + + return gradient + ')'; + } + + if (mode.isContinuous && mode.getColors) { + const scheme = mode.getColors(theme); + + for (let i = 0; i < scheme.length; i++) { + const color = scheme[i]; + + if (gradient === '') { + gradient = `linear-gradient(${cssDirection}, ${color} 0px`; + } else { + const valuePercent = i / (scheme.length - 1); + const pos = valuePercent * maxSize; + gradient += `, ${color} ${pos}px`; + } + } + return gradient + ')'; + } + + return value.color ?? FALLBACK_COLOR; +} + +/** + * Only exported to for unit test + */ +export function getValueColor(props: Props): string { + const { value } = props; + if (value.color) { + return value.color; + } + + return FALLBACK_COLOR; +} + +function getValueStyles( + value: FormattedValue, + color: string, + width: number, + height: number, + orientation: VizOrientation, + text?: TextDisplayOptions +): CSSProperties { + const styles: CSSProperties = { + color, + height: `${height}px`, + width: `${width}px`, + display: 'flex', + alignItems: 'center', + lineHeight: VALUE_LINE_HEIGHT, + }; + + // how many pixels in wide can the text be? + let textWidth = width; + const formattedValueString = formattedValueToString(value); + + if (isVertical(orientation)) { + styles.fontSize = text?.valueSize ?? calculateFontSize(formattedValueString, textWidth, height, VALUE_LINE_HEIGHT); + styles.justifyContent = `center`; + } else { + styles.fontSize = + text?.valueSize ?? + calculateFontSize(formattedValueString, textWidth - VALUE_LEFT_PADDING * 2, height, VALUE_LINE_HEIGHT); + styles.justifyContent = `flex-end`; + styles.paddingLeft = `${VALUE_LEFT_PADDING}px`; + styles.paddingRight = `${VALUE_LEFT_PADDING}px`; + // Need to remove the left padding from the text width constraints + textWidth -= VALUE_LEFT_PADDING; + } + + return styles; +} diff --git a/packages/grafana-ui/src/components/BarGauge/__snapshots__/BarGauge.test.tsx.snap b/packages/grafana-ui/src/components/BarGauge/__snapshots__/BarGauge.test.tsx.snap new file mode 100644 index 00000000..3907e77f --- /dev/null +++ b/packages/grafana-ui/src/components/BarGauge/__snapshots__/BarGauge.test.tsx.snap @@ -0,0 +1,81 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`BarGauge Render with basic options should render 1`] = ` +
+
+ +
+
+
+
+`; diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.mdx b/packages/grafana-ui/src/components/BigValue/BigValue.mdx new file mode 100644 index 00000000..673b4e7b --- /dev/null +++ b/packages/grafana-ui/src/components/BigValue/BigValue.mdx @@ -0,0 +1,75 @@ +import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks'; +import { BigValue } from './BigValue'; + + + +# BigValue + +Component for showing a value based on a [DisplayValue](https://grafana.com/docs/grafana/latest/packages_api/data/displayvalue/#displayvalue-interface). + +### Display properties + +There are a few properties that will determine the look of the BigValue. + +#### Justify mode + +There are two modes for aligning text, auto and center. + +#### Graph mode + +You can control graph shown in BigValue with the `GraphMode` property. `GraphMode.Area` renders a +graph in the behind the value. `GrapMode.None` will hide it. + +#### Color mode + +`ColorMode` controls which part of the component that should have the color from thresholds or field config, +`ColorMode.Background` and `ColorMode.Value`. + +Note, `ColorMode.Value` will only set the color for the value. + +#### Text mode + +There are four variants to render text: + +- `TextMode.Auto` - Show value and name if there's more than on BigValue in the same pane. +- `TextMode.Value` - Show only the value. +- `TextMode.ValueAndName` - Show value and the name. +- `TextMode.None` - Do not show any value or name. + +### Example usage + +An example usage is in the [Stat panel](https://grafana.com/docs/grafana/latest/panels/visualizations/stat-panel/). + +```tsx +import { DisplayValue } from '@grafana/data'; +import { + BigValue, + BigValueColorMode, + BigValueGraphMode, + BigValueJustifyMode, + BigValueTextMode, + useTheme, +} from '@grafana/ui'; + +const bigValue: DisplayValue = { + color: 'red', + value: '5000', + numeric: 5000, + title: 'Volume', +}; + +return ( + +); +``` + +### Props + + diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx new file mode 100644 index 00000000..95013d5f --- /dev/null +++ b/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx @@ -0,0 +1,108 @@ +import React from 'react'; +import { Story, Meta } from '@storybook/react'; +import { + BigValue, + BigValueColorMode, + BigValueGraphMode, + BigValueJustifyMode, + BigValueTextMode, + Props, +} from './BigValue'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import mdx from './BigValue.mdx'; +import { useTheme2 } from '../../themes'; +import { ArrayVector, FieldSparkline, FieldType } from '@grafana/data'; + +export default { + title: 'Visualizations/BigValue', + component: BigValue, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + controls: { + exclude: ['value', 'sparkline', 'onClick', 'className', 'alignmentFactors', 'text', 'count', 'theme'], + }, + }, + argTypes: { + width: { control: { type: 'range', min: 200, max: 800 } }, + height: { control: { type: 'range', min: 200, max: 800 } }, + colorMode: { control: { type: 'select', options: [BigValueColorMode.Value, BigValueColorMode.Background] } }, + graphMode: { control: { type: 'select', options: [BigValueGraphMode.Area, BigValueGraphMode.None] } }, + justifyMode: { control: { type: 'select', options: [BigValueJustifyMode.Auto, BigValueJustifyMode.Center] } }, + textMode: { + control: { + type: 'radio', + options: [ + BigValueTextMode.Auto, + BigValueTextMode.Name, + BigValueTextMode.ValueAndName, + BigValueTextMode.None, + BigValueTextMode.Value, + ], + }, + }, + color: { control: 'color' }, + }, +} as Meta; + +interface StoryProps extends Partial { + numeric: number; + title: string; + color: string; + valueText: string; +} + +export const Basic: Story = ({ + valueText, + title, + colorMode, + graphMode, + height, + width, + color, + textMode, + justifyMode, +}) => { + const theme = useTheme2(); + const sparkline: FieldSparkline = { + y: { + name: '', + values: new ArrayVector([1, 2, 3, 4, 3]), + type: FieldType.number, + config: {}, + }, + }; + + return ( + + ); +}; + +Basic.args = { + valueText: '$5022', + title: 'Total Earnings', + colorMode: BigValueColorMode.Value, + graphMode: BigValueGraphMode.Area, + justifyMode: BigValueJustifyMode.Auto, + width: 400, + height: 300, + color: 'red', + textMode: BigValueTextMode.Auto, +}; diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx new file mode 100644 index 00000000..94b995cc --- /dev/null +++ b/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { BigValue, Props, BigValueColorMode, BigValueGraphMode } from './BigValue'; +import { createTheme } from '@grafana/data'; + +function getProps(propOverrides?: Partial): Props { + const props: Props = { + colorMode: BigValueColorMode.Background, + graphMode: BigValueGraphMode.Line, + height: 300, + width: 300, + value: { + text: '25', + numeric: 25, + color: 'red', + }, + theme: createTheme(), + }; + + Object.assign(props, propOverrides); + return props; +} + +const setup = (propOverrides?: object) => { + const props = getProps(propOverrides); + const wrapper = shallow(); + const instance = wrapper.instance() as BigValue; + + return { + instance, + wrapper, + }; +}; + +describe('BigValue', () => { + describe('Render with basic options', () => { + it('should render', () => { + const { wrapper } = setup(); + expect(wrapper).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.tsx new file mode 100644 index 00000000..ff222b5d --- /dev/null +++ b/packages/grafana-ui/src/components/BigValue/BigValue.tsx @@ -0,0 +1,100 @@ +// Library +import React, { PureComponent } from 'react'; +import { DisplayValue, DisplayValueAlignmentFactors, FieldSparkline, TextDisplayOptions } from '@grafana/data'; + +// Types +import { Themeable2 } from '../../types'; +import { buildLayout } from './BigValueLayout'; +import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay'; + +export enum BigValueColorMode { + Value = 'value', + Background = 'background', + None = 'none', +} + +export enum BigValueGraphMode { + None = 'none', + Line = 'line', + Area = 'area', +} + +export enum BigValueJustifyMode { + Auto = 'auto', + Center = 'center', +} + +/** + * Options for how the value & title are to be displayed + */ +export enum BigValueTextMode { + Auto = 'auto', + Value = 'value', + ValueAndName = 'value_and_name', + Name = 'name', + None = 'none', +} + +export interface Props extends Themeable2 { + /** Height of the component */ + height: number; + /** Width of the component */ + width: number; + /** Value displayed as Big Value */ + value: DisplayValue; + /** Sparkline values for showing a graph under/behind the value */ + sparkline?: FieldSparkline; + /** onClick handler for the value */ + onClick?: React.MouseEventHandler; + /** Custom styling */ + className?: string; + /** Color mode for coloring the value or the background */ + colorMode: BigValueColorMode; + /** Show a graph behind/under the value */ + graphMode: BigValueGraphMode; + /** Auto justify value and text or center it */ + justifyMode?: BigValueJustifyMode; + /** Factors that should influence the positioning of the text */ + alignmentFactors?: DisplayValueAlignmentFactors; + /** Explicit font size control */ + text?: TextDisplayOptions; + /** Specify which text should be visible in the BigValue */ + textMode?: BigValueTextMode; + /** If true disables the tooltip */ + hasLinks?: boolean; + + /** + * If part of a series of stat panes, this is the total number. + * Used by BigValueTextMode.Auto text mode. + */ + count?: number; +} + +export class BigValue extends PureComponent { + static defaultProps: Partial = { + justifyMode: BigValueJustifyMode.Auto, + }; + + render() { + const { onClick, className, hasLinks } = this.props; + const layout = buildLayout(this.props); + const panelStyles = layout.getPanelStyles(); + const valueAndTitleContainerStyles = layout.getValueAndTitleContainerStyles(); + const valueStyles = layout.getValueStyles(); + const titleStyles = layout.getTitleStyles(); + const textValues = layout.textValues; + + // When there is an outer data link this tooltip will override the outer native tooltip + const tooltip = hasLinks ? undefined : textValues.tooltip; + + return ( +
+
+ {textValues.title &&
{textValues.title}
} + +
+ {layout.renderChart()} +
+ ); + } +} diff --git a/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx b/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx new file mode 100644 index 00000000..9f311c98 --- /dev/null +++ b/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx @@ -0,0 +1,52 @@ +import { Props, BigValueColorMode, BigValueGraphMode } from './BigValue'; +import { buildLayout, StackedWithChartLayout, WideWithChartLayout } from './BigValueLayout'; +import { ArrayVector, createTheme, FieldType } from '@grafana/data'; + +function getProps(propOverrides?: Partial): Props { + const props: Props = { + colorMode: BigValueColorMode.Background, + graphMode: BigValueGraphMode.Area, + height: 300, + width: 300, + value: { + text: '25', + numeric: 25, + }, + sparkline: { + y: { + name: '', + values: new ArrayVector([1, 2, 3, 4, 3]), + type: FieldType.number, + config: {}, + }, + }, + theme: createTheme(), + }; + + Object.assign(props, propOverrides); + return props; +} + +describe('BigValueLayout', () => { + describe('buildLayout', () => { + it('should auto select to stacked layout', () => { + const layout = buildLayout( + getProps({ + width: 300, + height: 300, + }) + ); + expect(layout).toBeInstanceOf(StackedWithChartLayout); + }); + + it('should auto select to wide layout', () => { + const layout = buildLayout( + getProps({ + width: 300, + height: 100, + }) + ); + expect(layout).toBeInstanceOf(WideWithChartLayout); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx b/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx new file mode 100644 index 00000000..a42db2a3 --- /dev/null +++ b/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx @@ -0,0 +1,504 @@ +// Libraries +import React, { CSSProperties } from 'react'; +import tinycolor from 'tinycolor2'; + +// Utils +import { formattedValueToString, DisplayValue, FieldConfig, FieldType } from '@grafana/data'; +import { calculateFontSize } from '../../utils/measureText'; + +// Types +import { BigValueColorMode, Props, BigValueJustifyMode, BigValueTextMode } from './BigValue'; +import { getTextColorForBackground } from '../../utils'; +import { GraphDrawStyle, GraphFieldConfig } from '@grafana/schema'; +import { Sparkline } from '../Sparkline/Sparkline'; + +const LINE_HEIGHT = 1.2; +const MAX_TITLE_SIZE = 30; + +export abstract class BigValueLayout { + titleFontSize: number; + valueFontSize: number; + chartHeight: number; + chartWidth: number; + valueColor: string; + panelPadding: number; + justifyCenter: boolean; + titleToAlignTo?: string; + valueToAlignTo: string; + maxTextWidth: number; + maxTextHeight: number; + textValues: BigValueTextValues; + + constructor(private props: Props) { + const { width, height, value, text } = props; + + this.valueColor = value.color ?? 'gray'; + this.panelPadding = height > 100 ? 12 : 8; + this.textValues = getTextValues(props); + this.justifyCenter = shouldJustifyCenter(props.justifyMode, this.textValues.title); + this.valueToAlignTo = this.textValues.valueToAlignTo; + this.titleToAlignTo = this.textValues.titleToAlignTo; + this.titleFontSize = 14; + this.valueFontSize = 14; + this.chartHeight = 0; + this.chartWidth = 0; + this.maxTextWidth = width - this.panelPadding * 2; + this.maxTextHeight = height - this.panelPadding * 2; + + // Explicit font sizing + if (text) { + if (text.titleSize) { + this.titleFontSize = text.titleSize; + this.titleToAlignTo = undefined; + } + if (text.valueSize) { + this.valueFontSize = text.valueSize; + this.valueToAlignTo = ''; + } + } + } + + getTitleStyles(): CSSProperties { + const styles: CSSProperties = { + fontSize: `${this.titleFontSize}px`, + lineHeight: LINE_HEIGHT, + }; + + if (this.props.colorMode === BigValueColorMode.Background) { + styles.color = getTextColorForBackground(this.valueColor); + } + + return styles; + } + + getValueStyles(): CSSProperties { + const styles: CSSProperties = { + fontSize: this.valueFontSize, + fontWeight: 500, + lineHeight: LINE_HEIGHT, + position: 'relative', + zIndex: 1, + }; + + if (this.justifyCenter) { + styles.textAlign = 'center'; + } + + switch (this.props.colorMode) { + case BigValueColorMode.Value: + styles.color = this.valueColor; + break; + case BigValueColorMode.Background: + styles.color = getTextColorForBackground(this.valueColor); + break; + case BigValueColorMode.None: + styles.color = this.props.theme.colors.text.primary; + break; + } + + return styles; + } + + getValueAndTitleContainerStyles() { + const styles: CSSProperties = { + display: 'flex', + }; + + if (this.justifyCenter) { + styles.alignItems = 'center'; + styles.justifyContent = 'center'; + styles.flexGrow = 1; + } + + return styles; + } + + getPanelStyles(): CSSProperties { + const { width, height, theme, colorMode } = this.props; + + const panelStyles: CSSProperties = { + width: `${width}px`, + height: `${height}px`, + padding: `${this.panelPadding}px`, + borderRadius: '3px', + position: 'relative', + display: 'flex', + }; + + const themeFactor = theme.isDark ? 1 : -0.7; + + switch (colorMode) { + case BigValueColorMode.Background: + const bgColor2 = tinycolor(this.valueColor) + .darken(15 * themeFactor) + .spin(8) + .toRgbString(); + const bgColor3 = tinycolor(this.valueColor) + .darken(5 * themeFactor) + .spin(-8) + .toRgbString(); + panelStyles.background = `linear-gradient(120deg, ${bgColor2}, ${bgColor3})`; + break; + case BigValueColorMode.Value: + panelStyles.background = `transparent`; + break; + } + + if (this.justifyCenter) { + panelStyles.alignItems = 'center'; + panelStyles.flexDirection = 'row'; + } + + return panelStyles; + } + + renderChart(): JSX.Element | null { + const { sparkline, colorMode } = this.props; + + if (!sparkline || sparkline.y?.type !== FieldType.number) { + return null; + } + + let fillColor: string; + let lineColor: string; + + switch (colorMode) { + case BigValueColorMode.Background: + fillColor = 'rgba(255,255,255,0.4)'; + lineColor = tinycolor(this.valueColor).brighten(40).toRgbString(); + break; + case BigValueColorMode.None: + case BigValueColorMode.Value: + default: + lineColor = this.valueColor; + fillColor = tinycolor(this.valueColor).setAlpha(0.2).toRgbString(); + break; + } + + // The graph field configuration applied to Y values + const config: FieldConfig = { + custom: { + drawStyle: GraphDrawStyle.Line, + lineWidth: 1, + fillColor, + lineColor, + }, + }; + + return ( +
+ +
+ ); + } + getChartStyles(): CSSProperties { + return { + position: 'absolute', + right: 0, + bottom: 0, + }; + } +} + +export class WideNoChartLayout extends BigValueLayout { + constructor(props: Props) { + super(props); + + const valueWidthPercent = this.titleToAlignTo?.length ? 0.3 : 1.0; + + if (this.valueToAlignTo.length) { + // initial value size + this.valueFontSize = calculateFontSize( + this.valueToAlignTo, + this.maxTextWidth * valueWidthPercent, + this.maxTextHeight, + LINE_HEIGHT + ); + } + + if (this.titleToAlignTo?.length) { + // How big can we make the title and still have it fit + this.titleFontSize = calculateFontSize( + this.titleToAlignTo, + this.maxTextWidth * 0.6, + this.maxTextHeight, + LINE_HEIGHT, + MAX_TITLE_SIZE + ); + + // make sure it's a bit smaller than valueFontSize + this.titleFontSize = Math.min(this.valueFontSize * 0.7, this.titleFontSize); + } + } + + getValueAndTitleContainerStyles() { + const styles = super.getValueAndTitleContainerStyles(); + styles.flexDirection = 'row'; + styles.alignItems = 'center'; + styles.flexGrow = 1; + + if (!this.justifyCenter) { + styles.justifyContent = 'space-between'; + } + + return styles; + } + + renderChart(): JSX.Element | null { + return null; + } + + getPanelStyles() { + const panelStyles = super.getPanelStyles(); + panelStyles.alignItems = 'center'; + return panelStyles; + } +} + +export class WideWithChartLayout extends BigValueLayout { + constructor(props: Props) { + super(props); + + const { width, height } = props; + + const chartHeightPercent = 0.5; + const titleWidthPercent = 0.6; + const valueWidthPercent = 1 - titleWidthPercent; + const textHeightPercent = 0.4; + + this.chartWidth = width; + this.chartHeight = height * chartHeightPercent; + + if (this.titleToAlignTo?.length) { + this.titleFontSize = calculateFontSize( + this.titleToAlignTo, + this.maxTextWidth * titleWidthPercent, + this.maxTextHeight * textHeightPercent, + LINE_HEIGHT, + MAX_TITLE_SIZE + ); + } + + if (this.valueToAlignTo.length) { + this.valueFontSize = calculateFontSize( + this.valueToAlignTo, + this.maxTextWidth * valueWidthPercent, + this.maxTextHeight * chartHeightPercent, + LINE_HEIGHT + ); + } + } + + getValueAndTitleContainerStyles() { + const styles = super.getValueAndTitleContainerStyles(); + styles.flexDirection = 'row'; + styles.flexGrow = 1; + + if (!this.justifyCenter) { + styles.justifyContent = 'space-between'; + } + + return styles; + } + + getPanelStyles() { + const styles = super.getPanelStyles(); + styles.flexDirection = 'row'; + styles.justifyContent = 'space-between'; + return styles; + } +} + +export class StackedWithChartLayout extends BigValueLayout { + constructor(props: Props) { + super(props); + + const { width, height } = props; + const titleHeightPercent = 0.15; + const chartHeightPercent = 0.25; + let titleHeight = 0; + + this.chartHeight = height * chartHeightPercent; + this.chartWidth = width; + + if (this.titleToAlignTo?.length) { + this.titleFontSize = calculateFontSize( + this.titleToAlignTo, + this.maxTextWidth, + height * titleHeightPercent, + LINE_HEIGHT, + MAX_TITLE_SIZE + ); + } + titleHeight = this.titleFontSize * LINE_HEIGHT; + + if (this.valueToAlignTo.length) { + this.valueFontSize = calculateFontSize( + this.valueToAlignTo, + this.maxTextWidth, + this.maxTextHeight - this.chartHeight - titleHeight, + LINE_HEIGHT + ); + } + + // make title fontsize it's a bit smaller than valueFontSize + if (this.titleToAlignTo?.length) { + this.titleFontSize = Math.min(this.valueFontSize * 0.7, this.titleFontSize); + } + + // make chart take up unused space + this.chartHeight = height - this.titleFontSize * LINE_HEIGHT - this.valueFontSize * LINE_HEIGHT; + } + + getValueAndTitleContainerStyles() { + const styles = super.getValueAndTitleContainerStyles(); + styles.flexDirection = 'column'; + styles.justifyContent = 'center'; + return styles; + } + + getPanelStyles() { + const styles = super.getPanelStyles(); + styles.flexDirection = 'column'; + return styles; + } +} + +export class StackedWithNoChartLayout extends BigValueLayout { + constructor(props: Props) { + super(props); + + const { height } = props; + const titleHeightPercent = 0.15; + let titleHeight = 0; + + if (this.titleToAlignTo?.length) { + this.titleFontSize = calculateFontSize( + this.titleToAlignTo, + this.maxTextWidth, + height * titleHeightPercent, + LINE_HEIGHT, + MAX_TITLE_SIZE + ); + + titleHeight = this.titleFontSize * LINE_HEIGHT; + } + + if (this.valueToAlignTo.length) { + this.valueFontSize = calculateFontSize( + this.valueToAlignTo, + this.maxTextWidth, + this.maxTextHeight - titleHeight, + LINE_HEIGHT + ); + } + + // make title fontsize it's a bit smaller than valueFontSize + this.titleFontSize = Math.min(this.valueFontSize * 0.7, this.titleFontSize); + } + + getValueAndTitleContainerStyles() { + const styles = super.getValueAndTitleContainerStyles(); + styles.flexDirection = 'column'; + styles.flexGrow = 1; + return styles; + } + + getPanelStyles() { + const styles = super.getPanelStyles(); + styles.alignItems = 'center'; + return styles; + } +} + +export function buildLayout(props: Props): BigValueLayout { + const { width, height, sparkline } = props; + const useWideLayout = width / height > 2.5; + + if (useWideLayout) { + if (height > 50 && !!sparkline) { + return new WideWithChartLayout(props); + } else { + return new WideNoChartLayout(props); + } + } + + // stacked layouts + if (height > 100 && !!sparkline) { + return new StackedWithChartLayout(props); + } else { + return new StackedWithNoChartLayout(props); + } +} + +export function shouldJustifyCenter(justifyMode?: BigValueJustifyMode, title?: string) { + if (justifyMode === BigValueJustifyMode.Center) { + return true; + } + + return (title ?? '').length === 0; +} + +export interface BigValueTextValues extends DisplayValue { + valueToAlignTo: string; + titleToAlignTo?: string; + tooltip?: string; +} + +function getTextValues(props: Props): BigValueTextValues { + const { value, alignmentFactors, count } = props; + let { textMode } = props; + + const titleToAlignTo = alignmentFactors ? alignmentFactors.title : value.title; + const valueToAlignTo = formattedValueToString(alignmentFactors ? alignmentFactors : value); + + // In the auto case we only show title if this big value is part of more panes (count > 1) + if (textMode === BigValueTextMode.Auto && (count ?? 1) === 1) { + textMode = BigValueTextMode.Value; + } + + switch (textMode) { + case BigValueTextMode.Name: + return { + ...value, + title: undefined, + prefix: undefined, + suffix: undefined, + text: value.title || '', + titleToAlignTo: undefined, + valueToAlignTo: titleToAlignTo ?? '', + tooltip: formattedValueToString(value), + }; + case BigValueTextMode.Value: + return { + ...value, + title: undefined, + titleToAlignTo: undefined, + valueToAlignTo, + tooltip: value.title, + }; + case BigValueTextMode.None: + return { + numeric: value.numeric, + color: value.color, + title: undefined, + text: '', + titleToAlignTo: undefined, + valueToAlignTo: '1', + tooltip: `Name: ${value.title}\nValue: ${formattedValueToString(value)}`, + }; + case BigValueTextMode.ValueAndName: + default: + return { + ...value, + titleToAlignTo, + valueToAlignTo, + }; + } +} diff --git a/packages/grafana-ui/src/components/BigValue/__snapshots__/BigValue.test.tsx.snap b/packages/grafana-ui/src/components/BigValue/__snapshots__/BigValue.test.tsx.snap new file mode 100644 index 00000000..5acf66fb --- /dev/null +++ b/packages/grafana-ui/src/components/BigValue/__snapshots__/BigValue.test.tsx.snap @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`BigValue Render with basic options should render 1`] = ` +
+
+ +
+
+`; diff --git a/packages/grafana-ui/src/components/BrowserLabel/Label.tsx b/packages/grafana-ui/src/components/BrowserLabel/Label.tsx new file mode 100644 index 00000000..8132c891 --- /dev/null +++ b/packages/grafana-ui/src/components/BrowserLabel/Label.tsx @@ -0,0 +1,154 @@ +import React, { forwardRef, HTMLAttributes, useCallback } from 'react'; +import { cx, css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { useTheme2 } from '../../themes'; +// @ts-ignore +import Highlighter from 'react-highlight-words'; +import { PartialHighlighter } from '../Typeahead/PartialHighlighter'; +import { HighlightPart } from '../../types'; + +type OnLabelClick = (name: string, value: string | undefined, event: React.MouseEvent) => void; + +interface Props extends Omit, 'onClick'> { + name: string; + active?: boolean; + loading?: boolean; + searchTerm?: string; + value?: string; + facets?: number; + title?: string; + highlightParts?: HighlightPart[]; + onClick?: OnLabelClick; +} + +/** + * @internal + */ +export const Label = forwardRef( + ( + { + name, + value, + hidden, + facets, + onClick, + className, + loading, + searchTerm, + active, + style, + title, + highlightParts, + ...rest + }, + ref + ) => { + const theme = useTheme2(); + const styles = getLabelStyles(theme); + const searchWords = searchTerm ? [searchTerm] : []; + + const onLabelClick = useCallback( + (event: React.MouseEvent) => { + if (onClick && !hidden) { + onClick(name, value, event); + } + }, + [onClick, name, hidden, value] + ); + + // Using this component for labels and label values. If value is given use value for display text. + let text = value || name; + if (facets) { + text = `${text} (${facets})`; + } + + return ( + + ); + } +); + +Label.displayName = 'Label'; + +const getLabelStyles = (theme: GrafanaTheme2) => ({ + base: css` + display: inline-block; + cursor: pointer; + font-size: ${theme.typography.size.sm}; + line-height: ${theme.typography.bodySmall.lineHeight}; + background-color: ${theme.colors.background.secondary}; + color: ${theme.colors.text}; + white-space: nowrap; + text-shadow: none; + padding: ${theme.spacing(0.5)}; + border-radius: ${theme.shape.borderRadius()}; + margin-right: ${theme.spacing(1)}; + margin-bottom: ${theme.spacing(0.5)}; + `, + loading: css` + font-weight: ${theme.typography.fontWeightMedium}; + background-color: ${theme.colors.primary.shade}; + color: ${theme.colors.text.primary}; + animation: pulse 3s ease-out 0s infinite normal forwards; + @keyframes pulse { + 0% { + color: ${theme.colors.text.primary}; + } + 50% { + color: ${theme.colors.text.secondary}; + } + 100% { + color: ${theme.colors.text.disabled}; + } + } + `, + active: css` + font-weight: ${theme.typography.fontWeightMedium}; + background-color: ${theme.colors.primary.main}; + color: ${theme.colors.primary.contrastText}; + `, + matchHighLight: css` + background: inherit; + color: ${theme.colors.primary.text}; + background-color: ${theme.colors.primary.transparent}; + `, + hidden: css` + opacity: 0.6; + cursor: default; + border: 1px solid transparent; + `, + hover: css` + &:hover { + opacity: 0.85; + cursor: pointer; + } + `, +}); diff --git a/packages/grafana-ui/src/components/Button/Button.mdx b/packages/grafana-ui/src/components/Button/Button.mdx new file mode 100644 index 00000000..a2ba4801 --- /dev/null +++ b/packages/grafana-ui/src/components/Button/Button.mdx @@ -0,0 +1,101 @@ +import { Meta, Preview, ArgsTable } from '@storybook/addon-docs/blocks'; +import { Button, LinkButton } from './Button'; + + + +# Button + +## Primary + +Used for "call to action", i.e. triggering the main action. There should never be more than one on a page. If you need multiple buttons for different actions, decide which action is the most important and make that the primary `Button`. All other `Button` components should be secondary. + +If there is no primary action, all `Button` components should be secondary. + + +
+ + + +
+
+ +## Secondary + +The secondary `Button` is the default button style and can trigger various actions. How it is used depends on its surroundings: + +1. When next to the primary `Button`, the Secondary style can for example be used for "Cancel" or "Abort" actions. +2. When there is no main important action on a given page, all `Button` components should use the secondary style. + + +
+ + + +
+
+ +## Destructive + +Used for triggering a removing or deleting action. Because of its dominant coloring, it should be used sparingly. If you need multiple Destructive `Button` components in one view, we recommend using a secondary `Button` or Link variant instead and only use the Destructive variant to double confirm. + + +
+ + + +
+
+ +## Text + + +
+ + + +
+
+ + + +## Links + +To add an anchor that looks like a button use the `` component and pass a href prop. + + +
+ + Small + + + Medium + + + Large + +
+
diff --git a/packages/grafana-ui/src/components/Button/Button.story.tsx b/packages/grafana-ui/src/components/Button/Button.story.tsx new file mode 100644 index 00000000..9d70bf1b --- /dev/null +++ b/packages/grafana-ui/src/components/Button/Button.story.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { Story, Meta } from '@storybook/react'; +import { allButtonVariants, allButtonFills, Button, ButtonProps } from './Button'; +import mdx from './Button.mdx'; +import { HorizontalGroup, VerticalGroup } from '../Layout/Layout'; +import { ButtonGroup } from './ButtonGroup'; +import { ComponentSize } from '../../types/size'; +import { Card } from '../Card/Card'; + +export default { + title: 'Buttons/Button', + component: Button, + parameters: { + docs: { + page: mdx, + }, + }, +} as Meta; + +export const Variants: Story = () => { + const sizes: ComponentSize[] = ['lg', 'md', 'sm']; + return ( + + {allButtonFills.map((buttonFill) => ( + + + {allButtonVariants.map((variant) => ( + + {sizes.map((size) => ( + + ))} + + + ))} + +
+ + ))} + +
With icon and text
+ + + +
+
+ +
With icon only
+ +
+ +
Inside ButtonGroup
+ + + + ))} + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Button/Button.tsx b/packages/grafana-ui/src/components/Button/Button.tsx new file mode 100644 index 00000000..714808d9 --- /dev/null +++ b/packages/grafana-ui/src/components/Button/Button.tsx @@ -0,0 +1,280 @@ +import React, { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react'; +import { css, CSSObject, cx } from '@emotion/css'; +import { useTheme2 } from '../../themes'; +import { IconName } from '../../types/icon'; +import { getPropertiesForButtonSize } from '../Forms/commonStyles'; +import { colorManipulator, GrafanaTheme2, ThemeRichColor } from '@grafana/data'; +import { ComponentSize } from '../../types/size'; +import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; +import { Icon } from '../Icon/Icon'; + +export type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'link'; +export const allButtonVariants: ButtonVariant[] = ['primary', 'secondary', 'destructive']; +export type ButtonFill = 'solid' | 'outline' | 'text'; +export const allButtonFills: ButtonFill[] = ['solid', 'outline', 'text']; + +type CommonProps = { + size?: ComponentSize; + variant?: ButtonVariant; + fill?: ButtonFill; + icon?: IconName; + className?: string; + children?: React.ReactNode; + fullWidth?: boolean; +}; + +export type ButtonProps = CommonProps & ButtonHTMLAttributes; + +export const Button = React.forwardRef( + ({ variant = 'primary', size = 'md', fill = 'solid', icon, fullWidth, children, className, ...otherProps }, ref) => { + const theme = useTheme2(); + const styles = getButtonStyles({ + theme, + size, + variant, + fill, + fullWidth, + iconOnly: !children, + }); + + deprecatedPropWarning( + variant === 'link', + `${Button.displayName}: Prop variant="link" is deprecated. Please use fill="text".` + ); + + return ( + + ); + } +); + +Button.displayName = 'Button'; + +type ButtonLinkProps = CommonProps & ButtonHTMLAttributes & AnchorHTMLAttributes; + +export const LinkButton = React.forwardRef( + ( + { + variant = 'primary', + size = 'md', + fill = 'solid', + icon, + fullWidth, + children, + className, + onBlur, + onFocus, + disabled, + ...otherProps + }, + ref + ) => { + const theme = useTheme2(); + const styles = getButtonStyles({ + theme, + fullWidth, + size, + variant, + fill, + iconOnly: !children, + }); + + const linkButtonStyles = cx(styles.button, { [styles.disabled]: disabled }, className); + + deprecatedPropWarning( + variant === 'link', + `${LinkButton.displayName}: Prop variant="link" is deprecated. Please use fill="text".` + ); + + return ( + + {icon && } + {children && {children}} + + ); + } +); + +LinkButton.displayName = 'LinkButton'; + +export interface StyleProps { + size: ComponentSize; + variant: ButtonVariant; + fill?: ButtonFill; + iconOnly?: boolean; + theme: GrafanaTheme2; + fullWidth?: boolean; + narrow?: boolean; +} + +export const getButtonStyles = (props: StyleProps) => { + const { theme, variant, fill = 'solid', size, iconOnly, fullWidth } = props; + const { height, padding, fontSize } = getPropertiesForButtonSize(size, theme); + const variantStyles = getPropertiesForVariant(theme, variant, fill); + const disabledStyles = getPropertiesForDisabled(theme, variant, fill); + const focusStyle = getFocusStyles(theme); + const paddingMinusBorder = theme.spacing.gridSize * padding - 1; + + return { + button: css({ + label: 'button', + display: 'inline-flex', + alignItems: 'center', + fontSize: fontSize, + fontWeight: theme.typography.fontWeightMedium, + fontFamily: theme.typography.fontFamily, + padding: `0 ${paddingMinusBorder}px`, + height: theme.spacing(height), + // Deduct border from line-height for perfect vertical centering on windows and linux + lineHeight: `${theme.spacing.gridSize * height - 2}px`, + verticalAlign: 'middle', + cursor: 'pointer', + borderRadius: theme.shape.borderRadius(1), + '&:focus': focusStyle, + '&:focus-visible': focusStyle, + '&:focus:not(:focus-visible)': getMouseFocusStyles(theme), + ...(fullWidth && { + flexGrow: 1, + justifyContent: 'center', + }), + ...variantStyles, + ':disabled': disabledStyles, + '&[disabled]': disabledStyles, + }), + disabled: css(disabledStyles), + img: css` + width: 16px; + height: 16px; + margin: ${theme.spacing(0, 1, 0, 0.5)}; + `, + icon: iconOnly + ? css({ + // Important not to set margin bottom here as it would override internal icon bottom margin + marginRight: theme.spacing(-padding / 2), + marginLeft: theme.spacing(-padding / 2), + }) + : css({ + marginRight: theme.spacing(padding / 2), + }), + content: css` + display: flex; + flex-direction: row; + align-items: center; + white-space: nowrap; + height: 100%; + `, + }; +}; + +function getButtonVariantStyles(theme: GrafanaTheme2, color: ThemeRichColor, fill: ButtonFill): CSSObject { + if (fill === 'outline') { + return { + background: 'transparent', + color: color.text, + border: `1px solid ${color.border}`, + transition: theme.transitions.create(['background-color', 'border-color', 'color'], { + duration: theme.transitions.duration.short, + }), + + '&:hover': { + background: colorManipulator.alpha(color.main, theme.colors.action.hoverOpacity), + borderColor: theme.colors.emphasize(color.border, 0.25), + color: color.text, + }, + }; + } + + if (fill === 'text') { + return { + background: 'transparent', + color: color.text, + border: '1px solid transparent', + transition: theme.transitions.create(['background-color', 'color'], { + duration: theme.transitions.duration.short, + }), + + '&:focus': { + outline: 'none', + textDecoration: 'none', + }, + + '&:hover': { + background: colorManipulator.alpha(color.shade, theme.colors.action.hoverOpacity), + textDecoration: 'none', + }, + }; + } + + return { + background: color.main, + color: color.contrastText, + border: `1px solid transparent`, + transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color', 'color'], { + duration: theme.transitions.duration.short, + }), + + '&:hover': { + background: color.shade, + color: color.contrastText, + boxShadow: theme.shadows.z1, + }, + }; +} + +function getPropertiesForDisabled(theme: GrafanaTheme2, variant: ButtonVariant, fill: ButtonFill) { + const disabledStyles: CSSObject = { + cursor: 'not-allowed', + boxShadow: 'none', + pointerEvents: 'none', + color: theme.colors.text.disabled, + transition: 'none', + }; + + if (fill === 'text' || variant === 'link') { + return { + ...disabledStyles, + background: 'transparent', + border: `1px solid transparent`, + }; + } + + if (fill === 'outline') { + return { + ...disabledStyles, + background: 'transparent', + border: `1px solid ${theme.colors.action.disabledText}`, + }; + } + + return { + ...disabledStyles, + background: theme.colors.action.disabledBackground, + border: `1px solid transparent`, + }; +} + +export function getPropertiesForVariant(theme: GrafanaTheme2, variant: ButtonVariant, fill: ButtonFill) { + const buttonVariant = variant === 'link' ? 'primary' : variant; + const buttonFill = variant === 'link' ? 'text' : fill; + + switch (buttonVariant) { + case 'secondary': + return getButtonVariantStyles(theme, theme.colors.secondary, buttonFill); + + case 'destructive': + return getButtonVariantStyles(theme, theme.colors.error, buttonFill); + + case 'primary': + default: + return getButtonVariantStyles(theme, theme.colors.primary, buttonFill); + } +} + +function deprecatedPropWarning(test: boolean, message: string) { + if (process.env.NODE_ENV === 'development' && test) { + console.warn(`@grafana/ui ${message}`); + } +} diff --git a/packages/grafana-ui/src/components/Button/ButtonGroup.tsx b/packages/grafana-ui/src/components/Button/ButtonGroup.tsx new file mode 100644 index 00000000..456bb7ab --- /dev/null +++ b/packages/grafana-ui/src/components/Button/ButtonGroup.tsx @@ -0,0 +1,39 @@ +import React, { forwardRef, HTMLAttributes } from 'react'; +import { css, cx } from '@emotion/css'; +import { useStyles2 } from '../../themes'; +import { GrafanaTheme2 } from '@grafana/data'; + +export interface Props extends HTMLAttributes { + className?: string; +} + +export const ButtonGroup = forwardRef(({ className, children, ...rest }, ref) => { + const styles = useStyles2(getStyles); + + return ( +
+ {children} +
+ ); +}); + +ButtonGroup.displayName = 'ButtonGroup'; + +const getStyles = (theme: GrafanaTheme2) => ({ + wrapper: css` + display: flex; + + > .button-group:not(:first-child) > button, + > button:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + > .button-group:not(:last-child) > button, + > button:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right-width: 0; + } + `, +}); diff --git a/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx b/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx new file mode 100644 index 00000000..601aec9f --- /dev/null +++ b/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx @@ -0,0 +1,33 @@ +import React, { FC } from 'react'; +import { css, cx } from '@emotion/css'; +import { stylesFactory } from '../../themes'; + +export interface Props { + className?: string; +} + +export const FullWidthButtonContainer: FC = ({ className, children }) => { + const styles = getStyles(); + + return
{children}
; +}; + +const getStyles = stylesFactory(() => { + return css` + display: flex; + + button { + flex-grow: 1; + justify-content: center; + } + + > * { + flex-grow: 1; + } + + label { + flex-grow: 1; + text-align: center; + } + `; +}); diff --git a/packages/grafana-ui/src/components/Button/ToolbarButton.story.tsx b/packages/grafana-ui/src/components/Button/ToolbarButton.story.tsx new file mode 100644 index 00000000..d20f90cd --- /dev/null +++ b/packages/grafana-ui/src/components/Button/ToolbarButton.story.tsx @@ -0,0 +1,97 @@ +import React from 'react'; +import { ToolbarButton, ButtonGroup, VerticalGroup, HorizontalGroup } from '@grafana/ui'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { ToolbarButtonRow } from './ToolbarButtonRow'; +import { ToolbarButtonVariant } from './ToolbarButton'; +import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas'; + +export default { + title: 'Buttons/ToolbarButton', + component: ToolbarButton, + decorators: [withCenteredStory], + parameters: {}, +}; + +export const List = () => { + const variants: ToolbarButtonVariant[] = ['default', 'active', 'primary', 'destructive']; + + return ( + + + Button states + + Just text + + With imgSrc + + isOpen + + + isOpen = false + + +
+ disabled + + + Disabled + + +
+ Variants + + {variants.map((variant) => ( + + {variant} + + ))} + +
+ disabled + + + Disabled + + +
+ Variants + + {variants.map((variant) => ( + + {variant} + + ))} + +
+ Wrapped in noSpacing ButtonGroup + + + 2020-10-02 + + + +
+ + + + +
+ As primary and destructive variant + + + + Run query + + + + + + Run query + + + + +
+
+ ); +}; diff --git a/packages/grafana-ui/src/components/Button/ToolbarButton.tsx b/packages/grafana-ui/src/components/Button/ToolbarButton.tsx new file mode 100644 index 00000000..84eb8c0b --- /dev/null +++ b/packages/grafana-ui/src/components/Button/ToolbarButton.tsx @@ -0,0 +1,213 @@ +import React, { forwardRef, ButtonHTMLAttributes } from 'react'; +import { cx, css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { styleMixins, useStyles2 } from '../../themes'; +import { IconName } from '../../types/icon'; +import { Tooltip } from '../Tooltip/Tooltip'; +import { Icon } from '../Icon/Icon'; +import { getPropertiesForVariant } from './Button'; +import { isString } from 'lodash'; +import { selectors } from '@grafana/e2e-selectors'; +import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; + +export interface Props extends ButtonHTMLAttributes { + /** Icon name */ + icon?: IconName | React.ReactNode; + /** Tooltip */ + tooltip?: string; + /** For image icons */ + imgSrc?: string; + /** Alt text for imgSrc */ + imgAlt?: string; + /** if true or false will show angle-down/up */ + isOpen?: boolean; + /** Controls flex-grow: 1 */ + fullWidth?: boolean; + /** reduces padding to xs */ + narrow?: boolean; + /** variant */ + variant?: ToolbarButtonVariant; + /** Hide any children and only show icon */ + iconOnly?: boolean; +} + +export type ToolbarButtonVariant = 'default' | 'primary' | 'destructive' | 'active'; + +export const ToolbarButton = forwardRef( + ( + { + tooltip, + icon, + className, + children, + imgSrc, + imgAlt, + fullWidth, + isOpen, + narrow, + variant = 'default', + iconOnly, + 'aria-label': ariaLabel, + ...rest + }, + ref + ) => { + const styles = useStyles2(getStyles); + + const buttonStyles = cx( + 'toolbar-button', + { + [styles.button]: true, + [styles.buttonFullWidth]: fullWidth, + [styles.narrow]: narrow, + }, + (styles as any)[variant], + className + ); + + const contentStyles = cx({ + [styles.content]: true, + [styles.contentWithIcon]: !!icon, + [styles.contentWithRightIcon]: isOpen !== undefined, + }); + + const body = ( + + ); + + return tooltip ? ( + + {body} + + ) : ( + body + ); + } +); + +ToolbarButton.displayName = 'ToolbarButton'; + +function getButtonAriaLabel(ariaLabel: string | undefined, tooltip: string | undefined) { + return ariaLabel ? ariaLabel : tooltip ? selectors.components.PageToolbar.item(tooltip) : undefined; +} + +function renderIcon(icon: IconName | React.ReactNode) { + if (!icon) { + return null; + } + + if (isString(icon)) { + return ; + } + + return icon; +} + +const getStyles = (theme: GrafanaTheme2) => { + const primaryVariant = getPropertiesForVariant(theme, 'primary', 'solid'); + const destructiveVariant = getPropertiesForVariant(theme, 'destructive', 'solid'); + + return { + button: css` + label: toolbar-button; + display: flex; + align-items: center; + height: ${theme.spacing(theme.components.height.md)}; + padding: ${theme.spacing(0, 1)}; + border-radius: ${theme.shape.borderRadius()}; + line-height: ${theme.components.height.md * theme.spacing.gridSize - 2}px; + font-weight: ${theme.typography.fontWeightMedium}; + border: 1px solid ${theme.colors.border.weak}; + white-space: nowrap; + transition: ${theme.transitions.create(['background', 'box-shadow', 'border-color', 'color'], { + duration: theme.transitions.duration.short, + })}; + + &:focus, + &:focus-visible { + ${getFocusStyles(theme)} + z-index: 1; + } + + &:focus:not(:focus-visible) { + ${getMouseFocusStyles(theme)} + } + + &:hover { + box-shadow: ${theme.shadows.z1}; + } + + &[disabled], + &:disabled { + cursor: not-allowed; + opacity: ${theme.colors.action.disabledOpacity}; + background: ${theme.colors.action.disabledBackground}; + box-shadow: none; + + &:hover { + color: ${theme.colors.text.disabled}; + background: ${theme.colors.action.disabledBackground}; + box-shadow: none; + } + } + `, + default: css` + color: ${theme.colors.text.secondary}; + background-color: ${theme.colors.background.primary}; + + &:hover { + color: ${theme.colors.text.primary}; + background: ${theme.colors.background.secondary}; + } + `, + active: css` + color: ${theme.v1.palette.orangeDark}; + border-color: ${theme.v1.palette.orangeDark}; + background-color: transparent; + + &:hover { + color: ${theme.colors.text.primary}; + background: ${theme.colors.emphasize(theme.colors.background.canvas, 0.03)}; + } + `, + primary: css(primaryVariant), + destructive: css(destructiveVariant), + narrow: css` + padding: 0 ${theme.spacing(0.5)}; + `, + img: css` + width: 16px; + height: 16px; + margin-right: ${theme.spacing(1)}; + `, + buttonFullWidth: css` + flex-grow: 1; + `, + content: css` + flex-grow: 1; + `, + contentWithIcon: css` + display: none; + padding-left: ${theme.spacing(1)}; + + @media ${styleMixins.mediaUp(theme.v1.breakpoints.md)} { + display: block; + } + `, + contentWithRightIcon: css` + padding-right: ${theme.spacing(0.5)}; + `, + }; +}; diff --git a/packages/grafana-ui/src/components/Button/ToolbarButtonRow.tsx b/packages/grafana-ui/src/components/Button/ToolbarButtonRow.tsx new file mode 100644 index 00000000..eda19387 --- /dev/null +++ b/packages/grafana-ui/src/components/Button/ToolbarButtonRow.tsx @@ -0,0 +1,35 @@ +import React, { forwardRef, HTMLAttributes } from 'react'; +import { css, cx } from '@emotion/css'; +import { useStyles2 } from '../../themes'; +import { GrafanaTheme2 } from '@grafana/data'; + +export interface Props extends HTMLAttributes { + className?: string; +} + +export const ToolbarButtonRow = forwardRef(({ className, children, ...rest }, ref) => { + const styles = useStyles2(getStyles); + + return ( +
+ {children} +
+ ); +}); + +ToolbarButtonRow.displayName = 'ToolbarButtonRow'; + +const getStyles = (theme: GrafanaTheme2) => ({ + wrapper: css` + display: flex; + + > .button-group, + > .toolbar-button { + margin-left: ${theme.spacing(1)}; + + &:first-child { + margin-left: 0; + } + } + `, +}); diff --git a/packages/grafana-ui/src/components/Button/index.ts b/packages/grafana-ui/src/components/Button/index.ts new file mode 100644 index 00000000..cc6da63a --- /dev/null +++ b/packages/grafana-ui/src/components/Button/index.ts @@ -0,0 +1,4 @@ +export * from './Button'; +export { ButtonGroup } from './ButtonGroup'; +export { ToolbarButton, ToolbarButtonVariant } from './ToolbarButton'; +export { ToolbarButtonRow } from './ToolbarButtonRow'; diff --git a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.story.tsx b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.story.tsx new file mode 100644 index 00000000..27b5e5cb --- /dev/null +++ b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.story.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { Story, Meta } from '@storybook/react'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { ButtonCascader } from '@grafana/ui'; +import { ButtonCascaderProps } from './ButtonCascader'; + +export default { + title: 'Forms/Cascader/ButtonCascader', + component: ButtonCascader, + decorators: [withCenteredStory], + parameters: { + controls: { + exclude: ['className', 'value', 'fieldNames', 'loadData', 'onChange', 'onPopupVisibleChange'], + }, + }, + args: { + disabled: false, + children: 'Click me!', + options: [ + { + label: 'A', + value: 'A', + children: [ + { label: 'B', value: 'B' }, + { label: 'C', value: 'C' }, + ], + }, + { label: 'D', value: 'D' }, + ], + }, + argTypes: { + icon: { control: { type: 'select', options: ['plus', 'minus', 'table'] } }, + options: { control: 'object' }, + }, +} as Meta; + +const Template: Story = ({ children, ...args }) => { + return {children}; +}; + +export const simple = Template.bind({}); + +export const withIcon = Template.bind({}); +withIcon.args = { + icon: 'plus', +}; diff --git a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx new file mode 100644 index 00000000..a485813b --- /dev/null +++ b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import { Icon } from '../Icon/Icon'; +import { IconName } from '../../types/icon'; +import { css, cx } from '@emotion/css'; + +// @ts-ignore +import RCCascader from 'rc-cascader'; +import { CascaderOption } from '../Cascader/Cascader'; +import { onChangeCascader, onLoadDataCascader } from '../Cascader/optionMappings'; +import { stylesFactory, useTheme2 } from '../../themes'; +import { GrafanaTheme2 } from '@grafana/data'; + +export interface ButtonCascaderProps { + options: CascaderOption[]; + children: string; + icon?: IconName; + disabled?: boolean; + value?: string[]; + fieldNames?: { label: string; value: string; children: string }; + loadData?: (selectedOptions: CascaderOption[]) => void; + onChange?: (value: string[], selectedOptions: CascaderOption[]) => void; + onPopupVisibleChange?: (visible: boolean) => void; + className?: string; +} + +const getStyles = stylesFactory((theme: GrafanaTheme2) => { + return { + popup: css` + label: popup; + z-index: ${theme.zIndex.dropdown}; + `, + icons: { + right: css` + margin: 1px 0 0 4px; + `, + left: css` + margin: -1px 4px 0 0; + `, + }, + }; +}); + +export const ButtonCascader: React.FC = (props) => { + const { onChange, className, loadData, icon, ...rest } = props; + const theme = useTheme2(); + const styles = getStyles(theme); + + return ( + + + + ); +}; + +ButtonCascader.displayName = 'ButtonCascader'; diff --git a/packages/grafana-ui/src/components/ButtonCascader/_ButtonCascader.scss b/packages/grafana-ui/src/components/ButtonCascader/_ButtonCascader.scss new file mode 100644 index 00000000..8793c831 --- /dev/null +++ b/packages/grafana-ui/src/components/ButtonCascader/_ButtonCascader.scss @@ -0,0 +1,190 @@ +.rc-cascader { + font-size: 12px; + + &-menus { + font-size: 12px; + overflow: hidden; + background: $page-bg; + position: absolute; + border: $panel-border; + border-radius: $border-radius; + box-shadow: $typeahead-shadow; + white-space: nowrap; + + &-hidden { + display: none; + } + + &.slide-up-enter, + &.slide-up-appear { + animation-duration: 0.3s; + animation-fill-mode: both; + transform-origin: 0 0; + opacity: 0; + animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); + animation-play-state: paused; + } + + &.slide-up-enter.slide-up-enter-active.rc-cascader-menus-placement, + &.slide-up-appear.slide-up-appear-active.rc-cascader-menus-placement { + &-bottomLeft { + animation-name: SlideUpIn; + animation-play-state: running; + } + + &-topLeft { + animation-name: SlideDownIn; + animation-play-state: running; + } + } + + &.slide-up-leave { + animation-duration: 0.3s; + animation-fill-mode: both; + transform-origin: 0 0; + opacity: 1; + animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); + animation-play-state: paused; + + &.slide-up-leave-active.rc-cascader-menus-placement { + &-bottomLeft { + animation-name: SlideUpOut; + animation-play-state: running; + } + + &-topLeft { + animation-name: SlideDownOut; + animation-play-state: running; + } + } + } + } + + &-menu { + display: inline-block; + /* width: 100px; */ + max-width: 50vw; + height: 192px; + list-style: none; + margin: 0; + padding: 0; + border-right: $panel-border; + overflow: auto; + + &:last-child { + border-right: 0; + } + + &-item { + height: 32px; + line-height: 32px; + padding: 0 2.5em 0 16px; + cursor: pointer; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + transition: all 0.3s ease; + position: relative; + + &:hover { + background: $typeahead-selected-bg; + } + + &-disabled { + cursor: not-allowed; + color: $text-color-weak; + + &:hover { + background: transparent; + } + + &:after { + position: absolute; + right: 12px; + content: 'loading'; + color: $text-color-weak; + font-style: italic; + } + } + + &-active { + color: $typeahead-selected-color; + background: $typeahead-selected-bg; + + &:hover { + color: $typeahead-selected-color; + background: $typeahead-selected-bg; + } + } + + &-expand { + position: relative; + + &:after { + content: '>'; + font-size: 12px; + color: $text-color-weak; + position: absolute; + right: 16px; + line-height: 32px; + } + } + } + } +} + +@keyframes SlideUpIn { + 0% { + opacity: 0; + transform-origin: 0% 0%; + transform: scaleY(0.8); + } + + 100% { + opacity: 1; + transform-origin: 0% 0%; + transform: scaleY(1); + } +} + +@keyframes SlideUpOut { + 0% { + opacity: 1; + transform-origin: 0% 0%; + transform: scaleY(1); + } + + 100% { + opacity: 0; + transform-origin: 0% 0%; + transform: scaleY(0.8); + } +} + +@keyframes SlideDownIn { + 0% { + opacity: 0; + transform-origin: 0% 100%; + transform: scaleY(0.8); + } + + 100% { + opacity: 1; + transform-origin: 0% 100%; + transform: scaleY(1); + } +} + +@keyframes SlideDownOut { + 0% { + opacity: 1; + transform-origin: 0% 100%; + transform: scaleY(1); + } + + 100% { + opacity: 0; + transform-origin: 0% 100%; + transform: scaleY(0.8); + } +} diff --git a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.internal.tsx b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.internal.tsx new file mode 100644 index 00000000..31ea9c22 --- /dev/null +++ b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.internal.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { CallToActionCard, CallToActionCardProps } from './CallToActionCard'; +import { Story, Meta } from '@storybook/react'; +import { Button } from '../Button/Button'; +import { action } from '@storybook/addon-actions'; + +export default { + title: 'Layout/CallToActionCard', + component: CallToActionCard, + parameters: { + controls: { + exclude: ['className', 'callToActionElement', 'theme'], + }, + }, + argTypes: { + Element: { control: { type: 'select', options: ['button', 'custom'] } }, + }, +} as Meta; + +interface StoryProps extends Partial { + Element: string; + H1Text: string; + buttonText: string; +} + +export const Basic: Story = (args) => { + const ctaElements: { [key: string]: JSX.Element } = { + custom:

{args.H1Text}

, + button: ( + + ), + }; + + return ( + + ); +}; + +Basic.args = { + Element: 'custom', + message: 'Renders message prop content', + footer: 'Renders footer prop content', + H1Text: 'This is just H1 tag, you can any component as CTA element', + buttonText: 'Add datasource', +}; diff --git a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.test.tsx b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.test.tsx new file mode 100644 index 00000000..633902d3 --- /dev/null +++ b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.test.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { render } from 'enzyme'; +import { CallToActionCard } from './CallToActionCard'; + +describe('CallToActionCard', () => { + describe('rendering', () => { + it('when no message and footer provided', () => { + const tree = render(Click me
} />); + expect(tree).toMatchSnapshot(); + }); + + it('when message and no footer provided', () => { + const tree = render( + Click me} + /> + ); + expect(tree).toMatchSnapshot(); + }); + + it('when message and footer provided', () => { + const tree = render( + Click me} + /> + ); + expect(tree).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.tsx b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.tsx new file mode 100644 index 00000000..d566a866 --- /dev/null +++ b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.tsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { css, cx } from '@emotion/css'; +import { useStyles2 } from '../../themes/ThemeContext'; +import { GrafanaTheme2 } from '@grafana/data'; + +export interface CallToActionCardProps { + message?: string | JSX.Element; + callToActionElement: JSX.Element; + footer?: string | JSX.Element; + className?: string; +} + +export const CallToActionCard: React.FunctionComponent = ({ + message, + callToActionElement, + footer, + className, +}) => { + const css = useStyles2(getStyles); + + return ( +
+ {message &&
{message}
} + {callToActionElement} + {footer &&
{footer}
} +
+ ); +}; + +const getStyles = (theme: GrafanaTheme2) => ({ + wrapper: css` + label: call-to-action-card; + padding: ${theme.spacing(3)}; + background: ${theme.colors.background.secondary}; + border-radius: ${theme.shape.borderRadius(2)}; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + flex-grow: 1; + `, + message: css` + margin-bottom: ${theme.spacing(3)}; + font-style: italic; + `, + footer: css` + margin-top: ${theme.spacing(3)}}; + `, +}); diff --git a/packages/grafana-ui/src/components/CallToActionCard/__snapshots__/CallToActionCard.test.tsx.snap b/packages/grafana-ui/src/components/CallToActionCard/__snapshots__/CallToActionCard.test.tsx.snap new file mode 100644 index 00000000..511fd516 --- /dev/null +++ b/packages/grafana-ui/src/components/CallToActionCard/__snapshots__/CallToActionCard.test.tsx.snap @@ -0,0 +1,52 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CallToActionCard rendering when message and footer provided 1`] = ` +
+
+ Click button bellow +
+ + Click me + +
+ footer content +
+
+`; + +exports[`CallToActionCard rendering when message and no footer provided 1`] = ` +
+
+ Click button bellow +
+ + Click me + +
+`; + +exports[`CallToActionCard rendering when no message and footer provided 1`] = ` + +`; diff --git a/packages/grafana-ui/src/components/Card/Card.mdx b/packages/grafana-ui/src/components/Card/Card.mdx new file mode 100644 index 00000000..e3364418 --- /dev/null +++ b/packages/grafana-ui/src/components/Card/Card.mdx @@ -0,0 +1,389 @@ +import { Meta, Preview, Props } from '@storybook/addon-docs/blocks'; +import { Card } from './Card'; +import { Button } from '../Button'; +import { IconButton } from '../IconButton/IconButton'; +import { TagList } from '../Tags/TagList'; + +export const logo = 'https://grafana.com/static/assets/img/apple-touch-icon.png'; + + + +# Card + +## Usage + +### Basic + +A basic `Card` component expects at least a heading, used as a title. + +```jsx + + Filter by name + Filter data by query. + +``` + + + + Filter by name + Filter data by query. + + + +### Multiple metadata elements + +For providing metadata elements, which can be any extra information for the card, `Card.Meta` component should be used. If metadata consists of multiple strings, each of them has to be escaped (wrapped in brackets `{}`) or better passed in as an array. + +```jsx + + Test dashboard + {['Folder: Test', 'Views: 100']} + +``` + + + + Test dashboard + {['Folder: Test', 'Views: 100']} + + + +Metadata also accepts HTML elements, which could be links, for example. For elements, that are not strings, a `key` prop has to be manually specified. + +```jsx + + Test dashboard + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + +``` + + + + Test dashboard + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + + +The separator for multiple metadata elements defaults to a vertical line `|`, but can be customised. + +```jsx + + Test dashboard + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + +``` + + + + Test dashboard + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + + +### Tags + +Tags can be rendered inside the Card, by being wrapped in `Card.Tags` component. Note that this component does not provide any tag styling and that should be handled by the children. It is recommended to use it with Grafana-UI's `TagList` component. + +```jsx + + Test dashboard + Card with a list of tags + + console.log(tag)} /> + + +``` + + + + Test dashboard + Card with a list of tags + + console.log(tag)} /> + + + + +### As a link + +Card can be used as a clickable link item by specifying `href` prop. In this case the Card's content will be rendered inside `a`. + +```jsx + + Redirect to Grafana + Clicking this card will redirect to grafana website + +``` + + + + Redirect to Grafana + Clicking this card will redirect to grafana website + + + +### Inside a list item + +To render cards in a list, it is possible to nest them inside `li` items. + +```jsx +
    +
  • + + List card item + Card that is rendered inside li element. + +
  • +
  • + + List card item + Card that is rendered inside li element. + +
  • +
  • + + List card item + Card that is rendered inside li element. + +
  • +
  • + + List card item + Card that is rendered inside li element. + +
  • +
+``` + + +
    +
  • + + List card item + Card that is rendered inside li element. + +
  • +
  • + + List card item + Card that is rendered inside li element. + +
  • +
  • + + List card item + Card that is rendered inside li element. + +
  • +
  • + + List card item + Card that is rendered inside li element. + +
  • +
+
+ +### With media elements + +Cards can also be rendered with media content such icons or images. Such elements need to be wrapped in `Card.Figure` component. + +```jsx + + 1-ops-tools1-fallback + + Grafana Logo + + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + +``` + + + + 1-ops-tools1-fallback + + Grafana Logo + + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + + +### Action Cards + +Cards also accept primary and secondary actions. Usually the primary actions are displayed as buttons while secondary actions are displayed as icon buttons. The actions need to be wrappd in `Card.Actions` and `Card.SecondaryActions` components respectively. + +```jsx + + 1-ops-tools1-fallback + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + Grafana Logo + + + + + + + + + + +``` + + + + 1-ops-tools1-fallback + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + Grafana Logo + + + + + + + + + + + + +### Disabled state + +Card can have a disabled state, effectively making it and its actions non-clickable. If there are any actions, they will be disabled instead of the whole card. + +```jsx + + 1-ops-tools1-fallback + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + Grafana Logo + + +``` + + + + 1-ops-tools1-fallback + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + Grafana Logo + + + + +```jsx + + 1-ops-tools1-fallback + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + Grafana Logo + + + + + + + + + + +``` + + + + 1-ops-tools1-fallback + + Grafana + + https://ops-us-east4.grafana.net/api/prom + + + + Grafana Logo + + + + + + + + + + + + +### Props + + diff --git a/packages/grafana-ui/src/components/Card/Card.story.tsx b/packages/grafana-ui/src/components/Card/Card.story.tsx new file mode 100644 index 00000000..6c88efd0 --- /dev/null +++ b/packages/grafana-ui/src/components/Card/Card.story.tsx @@ -0,0 +1,156 @@ +import React from 'react'; +import { Story } from '@storybook/react'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { Card, Props } from './Card'; +import mdx from './Card.mdx'; +import { Button } from '../Button'; +import { IconButton } from '../IconButton/IconButton'; +import { TagList } from '../Tags/TagList'; +import { VerticalGroup } from '../Layout/Layout'; + +const logo = 'https://grafana.com/static/assets/img/apple-touch-icon.png'; + +export default { + title: 'General/Card', + component: Card, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + controls: { + exclude: ['onClick', 'href', 'heading', 'description', 'className'], + }, + }, +}; + +export const Basic: Story = ({ disabled }) => { + return ( + + Filter by name + + Filter data by query. This is useful if you are sharing the results from a different panel that has many queries + and you want to only visualize a subset of that in this panel. + + + ); +}; + +export const AsLink: Story = ({ disabled }) => { + return ( + + + Filter by name + + Filter data by query. This is useful if you are sharing the results from a different panel that has many + queries and you want to only visualize a subset of that in this panel. + + + + Filter by name2 + + Filter data by query. This is useful if you are sharing the results from a different panel that has many + queries and you want to only visualize a subset of that in this panel. + + + + Production system overview + Meta tags + + + ); +}; + +export const WithTags: Story = ({ disabled }) => { + return ( + + Elasticsearch – Custom Templated Query + Elastic Search + + console.log('tag', tag)} /> + + + ); +}; + +export const WithMedia: Story = ({ disabled }) => { + return ( + + 1-ops-tools1-fallback + + Prometheus + + https://ops-us-east4.grafana.net/api/prom + + + + Prometheus Logo + + + ); +}; +export const WithActions: Story = ({ disabled }) => { + return ( + + 1-ops-tools1-fallback + + Prometheus + + https://ops-us-east4.grafana.net/api/prom + + + + Prometheus Logo + + + + + + + + + + + ); +}; + +export const Full: Story = ({ disabled }) => { + return ( + + Card title + + Description, body text. Greetings! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. + + + {['Subtitle', 'Meta info 1', 'Meta info 2']} + + https://ops-us-east4.grafana.net/api/prom + + + + Prometheus Logo + + + + + + + + + + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Card/Card.test.tsx b/packages/grafana-ui/src/components/Card/Card.test.tsx new file mode 100644 index 00000000..6dd2b587 --- /dev/null +++ b/packages/grafana-ui/src/components/Card/Card.test.tsx @@ -0,0 +1,103 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { Card } from './Card'; +import { Button } from '../Button'; +import { IconButton } from '../IconButton/IconButton'; + +describe('Card', () => { + it('should execute callback when clicked', () => { + const callback = jest.fn(); + render( + + Test Heading + + ); + fireEvent.click(screen.getByText('Test Heading')); + expect(callback).toBeCalledTimes(1); + }); + + describe('Card Actions', () => { + it('Children should be disabled or enabled according to Card disabled prop', () => { + const { rerender } = render( + + Test Heading + + + + + + + + ); + + expect(screen.getByRole('button', { name: 'Click Me' })).not.toBeDisabled(); + expect(screen.getByRole('button', { name: 'Delete' })).not.toBeDisabled(); + + rerender( + + Test Heading + + + + + + + + ); + + expect(screen.getByRole('button', { name: 'Click Me' })).toBeDisabled(); + expect(screen.getByRole('button', { name: 'Delete' })).toBeDisabled(); + }); + + it('Children should be independently enabled or disabled if explicitly set', () => { + const { rerender } = render( + + Test Heading + + + + + + + + ); + + expect(screen.getByRole('button', { name: 'Click Me' })).toBeDisabled(); + expect(screen.getByRole('button', { name: 'Delete' })).toBeDisabled(); + + rerender( + + Test Heading + + + + + + + + ); + + expect(screen.getByRole('button', { name: 'Click Me' })).not.toBeDisabled(); + expect(screen.getByRole('button', { name: 'Delete' })).not.toBeDisabled(); + }); + + it('Children should be conditional', () => { + const shouldNotRender = false; + render( + + Test Heading + + + {shouldNotRender && } + + + {shouldNotRender && } + + + ); + + expect(screen.getByRole('button', { name: 'Click Me' })).not.toBeDisabled(); + expect(screen.queryByRole('button', { name: 'Delete' })).not.toBeInTheDocument(); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/Card/Card.tsx b/packages/grafana-ui/src/components/Card/Card.tsx new file mode 100644 index 00000000..92466b93 --- /dev/null +++ b/packages/grafana-ui/src/components/Card/Card.tsx @@ -0,0 +1,352 @@ +import React, { memo, cloneElement, FC, useMemo, useContext, ReactNode } from 'react'; +import { css, cx } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2, useTheme2 } from '../../themes'; +import { CardContainer, CardContainerProps, getCardContainerStyles } from './CardContainer'; +import { getFocusStyles } from '../../themes/mixins'; + +/** + * @public + */ +export interface Props extends Omit { + /** Indicates if the card and all its actions can be interacted with */ + disabled?: boolean; + /** Link to redirect to on card click. If provided, the Card inner content will be rendered inside `a` */ + href?: string; + /** On click handler for the Card */ + onClick?: () => void; + /** @deprecated Use `Card.Heading` instead */ + heading?: ReactNode; + /** @deprecated Use `Card.Description` instead */ + description?: string; +} + +export interface CardInterface extends FC { + Heading: typeof Heading; + Tags: typeof Tags; + Figure: typeof Figure; + Meta: typeof Meta; + Actions: typeof Actions; + SecondaryActions: typeof SecondaryActions; + Description: typeof Description; +} + +const CardContext = React.createContext<{ + href?: string; + onClick?: () => void; + disabled?: boolean; +} | null>(null); + +/** + * Generic card component + * + * @public + */ +export const Card: CardInterface = ({ + disabled, + href, + onClick, + children, + heading: deprecatedHeading, + description: deprecatedDescription, + className, + ...htmlProps +}) => { + const hasHeadingComponent = useMemo( + () => + React.Children.toArray(children).some( + (c) => React.isValidElement(c) && (c.type as any).displayName === Heading.displayName + ), + [children] + ); + + const disableHover = disabled || (!onClick && !href); + const onCardClick = onClick && !disabled ? onClick : undefined; + const theme = useTheme2(); + const styles = getCardContainerStyles(theme, disabled, disableHover); + + return ( + + + {!hasHeadingComponent && } + {deprecatedHeading && {deprecatedHeading}} + {deprecatedDescription && {deprecatedDescription}} + {children} + + + ); +}; + +interface ChildProps { + className?: string; + disabled?: boolean; + children?: React.ReactNode; + + /** @deprecated Use `className` to add new styles */ + styles?: ReturnType; +} + +/** Main heading for the card */ +const Heading = ({ children, className, 'aria-label': ariaLabel }: ChildProps & { 'aria-label'?: string }) => { + const context = useContext(CardContext); + const styles = useStyles2(getHeadingStyles); + + const { href, onClick } = context ?? { href: undefined, onClick: undefined }; + + return ( +

+ {href ? ( + + {children} + + ) : onClick ? ( + + ) : ( + <>{children} + )} +

+ ); +}; +Heading.displayName = 'Heading'; + +const getHeadingStyles = (theme: GrafanaTheme2) => ({ + heading: css({ + gridArea: 'Heading', + justifySelf: 'start', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + marginBottom: 0, + fontSize: theme.typography.size.md, + letterSpacing: 'inherit', + lineHeight: theme.typography.body.lineHeight, + color: theme.colors.text.primary, + fontWeight: theme.typography.fontWeightMedium, + }), + linkHack: css({ + all: 'unset', + '&::after': { + position: 'absolute', + content: '""', + top: 0, + bottom: 0, + left: 0, + right: 0, + borderRadius: theme.shape.borderRadius(1), + }, + + '&:focus-visible': { + outline: 'none', + outlineOffset: 0, + boxShadow: 'none', + + '&::after': { + ...getFocusStyles(theme), + zIndex: 1, + }, + }, + }), +}); + +const Tags = ({ children, className }: ChildProps) => { + const styles = useStyles2(getTagStyles); + return
{children}
; +}; +Tags.displayName = 'Tags'; + +const getTagStyles = (theme: GrafanaTheme2) => ({ + tagList: css({ + position: 'relative', + gridArea: 'Tags', + alignSelf: 'center', + }), +}); + +/** Card description text */ +const Description = ({ children, className }: ChildProps) => { + const styles = useStyles2(getDescriptionStyles); + return

{children}

; +}; +Description.displayName = 'Description'; + +const getDescriptionStyles = (theme: GrafanaTheme2) => ({ + description: css({ + width: '100%', + gridArea: 'Description', + margin: theme.spacing(1, 0, 0), + color: theme.colors.text.secondary, + lineHeight: theme.typography.body.lineHeight, + }), +}); + +const Figure = ({ children, align = 'start', className }: ChildProps & { align?: 'start' | 'center' }) => { + const styles = useStyles2(getFigureStyles); + return ( +
+ {children} +
+ ); +}; +Figure.displayName = 'Figure'; + +const getFigureStyles = (theme: GrafanaTheme2) => ({ + media: css({ + position: 'relative', + gridArea: 'Figure', + + marginRight: theme.spacing(2), + width: '40px', + + '> img': { + width: '100%', + }, + + '&:empty': { + display: 'none', + }, + }), +}); + +const Meta = memo(({ children, className, separator = '|' }: ChildProps & { separator?: string }) => { + const styles = useStyles2(getMetaStyles); + let meta = children; + + // Join meta data elements by separator + if (Array.isArray(children) && separator) { + const filtered = React.Children.toArray(children).filter(Boolean); + if (!filtered.length) { + return null; + } + meta = filtered.reduce((prev, curr, i) => [ + prev, + + {separator} + , + curr, + ]); + } + return
{meta}
; +}); +Meta.displayName = 'Meta'; + +const getMetaStyles = (theme: GrafanaTheme2) => ({ + metadata: css({ + gridArea: 'Meta', + display: 'flex', + alignItems: 'center', + width: '100%', + fontSize: theme.typography.size.sm, + color: theme.colors.text.secondary, + margin: theme.spacing(0.5, 0, 0), + lineHeight: theme.typography.bodySmall.lineHeight, + overflowWrap: 'anywhere', + }), + separator: css({ + margin: `0 ${theme.spacing(1)}`, + }), +}); + +interface ActionsProps extends ChildProps { + children?: React.ReactNode; + variant?: 'primary' | 'secondary'; +} + +const BaseActions = ({ children, disabled, variant, className }: ActionsProps) => { + const styles = useStyles2(getActionStyles); + const context = useContext(CardContext); + const isDisabled = context?.disabled || disabled; + + const css = variant === 'primary' ? styles.actions : styles.secondaryActions; + return ( +
+ {React.Children.map(children, (child) => { + return React.isValidElement(child) ? cloneElement(child, { disabled: isDisabled, ...child.props }) : null; + })} +
+ ); +}; + +const getActionStyles = (theme: GrafanaTheme2) => ({ + actions: css({ + gridArea: 'Actions', + marginTop: theme.spacing(2), + '& > *': { + marginRight: theme.spacing(1), + }, + }), + secondaryActions: css({ + display: 'flex', + gridArea: 'Secondary', + alignSelf: 'center', + color: theme.colors.text.secondary, + marginTtop: theme.spacing(2), + + '& > *': { + marginRight: `${theme.spacing(1)} !important`, + }, + }), +}); + +const Actions = ({ children, disabled, className }: ChildProps) => { + return ( + + {children} + + ); +}; +Actions.displayName = 'Actions'; + +const SecondaryActions = ({ children, disabled, className }: ChildProps) => { + return ( + + {children} + + ); +}; +SecondaryActions.displayName = 'SecondaryActions'; + +/** + * @public + * @deprecated Use `className` on respective components to modify styles + */ +export const getCardStyles = (theme: GrafanaTheme2) => { + return { + inner: css` + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + flex-wrap: wrap; + `, + ...getHeadingStyles(theme), + ...getMetaStyles(theme), + ...getDescriptionStyles(theme), + ...getFigureStyles(theme), + ...getActionStyles(theme), + ...getTagStyles(theme), + }; +}; + +Card.Heading = Heading; +Card.Tags = Tags; +Card.Figure = Figure; +Card.Meta = Meta; +Card.Actions = Actions; +Card.SecondaryActions = SecondaryActions; +Card.Description = Description; diff --git a/packages/grafana-ui/src/components/Card/CardContainer.tsx b/packages/grafana-ui/src/components/Card/CardContainer.tsx new file mode 100644 index 00000000..8cfa2e2a --- /dev/null +++ b/packages/grafana-ui/src/components/Card/CardContainer.tsx @@ -0,0 +1,119 @@ +import React, { HTMLAttributes } from 'react'; +import { css, cx } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { styleMixins, stylesFactory, useStyles2, useTheme2 } from '../../themes'; + +/** + * @public + */ +export interface CardInnerProps { + href?: string; + children?: React.ReactNode; +} + +/** @deprecated This component will be removed in a future release */ +const CardInner = ({ children, href }: CardInnerProps) => { + const { inner } = useStyles2(getCardInnerStyles); + return href ? ( + + {children} + + ) : ( + <>{children} + ); +}; + +const getCardInnerStyles = (theme: GrafanaTheme2) => ({ + inner: css({ + display: 'flex', + width: '100%', + padding: theme.spacing(2), + }), +}); + +/** + * @public + */ +export interface CardContainerProps extends HTMLAttributes, CardInnerProps { + /** Disable pointer events for the Card, e.g. click events */ + disableEvents?: boolean; + /** No style change on hover */ + disableHover?: boolean; + /** Custom container styles */ + className?: string; +} + +/** @deprecated Using `CardContainer` directly is discouraged and should be replaced with `Card` */ +export const CardContainer = ({ + children, + disableEvents, + disableHover, + className, + href, + ...props +}: CardContainerProps) => { + const theme = useTheme2(); + const { oldContainer } = getCardContainerStyles(theme, disableEvents, disableHover); + return ( +
+ {children} +
+ ); +}; + +export const getCardContainerStyles = stylesFactory((theme: GrafanaTheme2, disabled = false, disableHover = false) => { + return { + container: css({ + display: 'grid', + position: 'relative', + gridTemplateColumns: 'auto 1fr auto', + gridTemplateRows: '1fr auto auto auto', + gridAutoColumns: '1fr', + gridAutoFlow: 'row', + gridTemplateAreas: ` + "Figure Heading Tags" + "Figure Meta Tags" + "Figure Description Tags" + "Figure Actions Secondary"`, + width: '100%', + padding: theme.spacing(2), + background: theme.colors.background.secondary, + borderRadius: theme.shape.borderRadius(), + marginBottom: '8px', + pointerEvents: disabled ? 'none' : 'auto', + transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color', 'color'], { + duration: theme.transitions.duration.short, + }), + + ...(!disableHover && { + '&:hover': { + background: theme.colors.emphasize(theme.colors.background.secondary, 0.03), + cursor: 'pointer', + zIndex: 1, + }, + '&:focus': styleMixins.getFocusStyles(theme), + }), + }), + oldContainer: css({ + display: 'flex', + width: '100%', + background: theme.colors.background.secondary, + borderRadius: theme.shape.borderRadius(), + position: 'relative', + pointerEvents: disabled ? 'none' : 'auto', + marginBottom: theme.spacing(1), + transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color', 'color'], { + duration: theme.transitions.duration.short, + }), + + ...(!disableHover && { + '&:hover': { + background: theme.colors.emphasize(theme.colors.background.secondary, 0.03), + cursor: 'pointer', + zIndex: 1, + }, + '&:focus': styleMixins.getFocusStyles(theme), + }), + }), + }; +}); diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.mdx b/packages/grafana-ui/src/components/Cascader/Cascader.mdx new file mode 100644 index 00000000..e8cfb7a6 --- /dev/null +++ b/packages/grafana-ui/src/components/Cascader/Cascader.mdx @@ -0,0 +1,12 @@ +import { Meta, Props } from '@storybook/addon-docs/blocks'; +import { Cascader } from './Cascader'; + + + +# Cascader + +The cascader component is a `Select` with a cascading flyout menu. When you have lots of options in your select, they can be hard to navigate from a regular dropdown list. In that case you can use the cascader to organize your options into groups hierarchically. Just like in the `Select` component, the cascader input doubles as a search field to quickly jump to a selection without navigating the list. + +You can either use the `Simple` cascader component for an empty input as default state or use the `initialValue` or `allowCustomValue` fields to pre-fill your cascader. Initial value means that one of the options from your cascaded list is pre-selected. Custom value means that apart from existing options from the list, your users can add custom values to the list by typing them in the `Select` input. + + diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.story.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.story.tsx new file mode 100644 index 00000000..a3ea1f80 --- /dev/null +++ b/packages/grafana-ui/src/components/Cascader/Cascader.story.tsx @@ -0,0 +1,100 @@ +import { Story, Meta } from '@storybook/react'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { Cascader } from '@grafana/ui'; +import { CascaderOption, CascaderProps } from './Cascader'; +import mdx from './Cascader.mdx'; +import React from 'react'; + +const onSelect = (val: string) => console.log(val); +const options = [ + { + label: 'First', + value: '1', + items: [ + { + label: 'Second', + value: '2', + }, + { + label: 'Third', + value: '3', + }, + { + label: 'Fourth', + value: '4', + }, + ], + }, + { + label: 'FirstFirst', + value: '5', + }, +]; + +export default { + title: 'Forms/Cascader', + component: Cascader, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + controls: { + exclude: [ + 'placeholder', + 'initialValue', + 'changeOnSelect', + 'onSelect', + 'loadData', + 'onChange', + 'onPopupVisibleChange', + 'formatCreateLabel', + ], + }, + }, + args: { + onSelect, + options, + }, + argTypes: { + width: { control: { type: 'range', min: 0, max: 70 } }, + }, +} as Meta; + +const Template: Story = (args) => ; + +export const Simple = Template.bind({}); +Simple.args = { + separator: '', +}; + +export const WithInitialValue = Template.bind({}); +WithInitialValue.args = { + initialValue: '3', +}; + +export const WithCustomValue = Template.bind({}); +WithCustomValue.args = { + initialValue: 'Custom Initial Value', + allowCustomValue: true, + formatCreateLabel: (val) => 'Custom Label' + val, +}; + +export const WithDisplayAllSelectedLevels = Template.bind({}); +WithDisplayAllSelectedLevels.args = { + displayAllSelectedLevels: true, + separator: ',', +}; + +export const WithOptionsStateUpdate = () => { + const [updatedOptions, setOptions] = React.useState([ + { + label: 'Initial state option', + value: 'initial', + }, + ]); + + setTimeout(() => setOptions(options), 2000); + + return ; +}; diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx new file mode 100644 index 00000000..702a98a0 --- /dev/null +++ b/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx @@ -0,0 +1,163 @@ +import React from 'react'; +import { Cascader, CascaderOption, CascaderProps } from './Cascader'; +import { render, screen, act } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +const options = [ + { + label: 'First', + value: '1', + items: [ + { + label: 'Second', + value: '2', + }, + { + label: 'Third', + value: '3', + }, + { + label: 'Fourth', + value: '4', + }, + ], + }, + { + label: 'FirstFirst', + value: '5', + }, +]; + +const CascaderWithOptionsStateUpdate = (props: Omit) => { + const [updatedOptions, setOptions] = React.useState([ + { + label: 'Initial state option', + value: 'initial', + }, + ]); + + setTimeout(() => setOptions(options), 1000); + + return ; +}; + +describe('Cascader', () => { + const placeholder = 'cascader-placeholder'; + + describe('options from state change', () => { + beforeEach(() => { + jest.useFakeTimers('modern'); + }); + + it('displays updated options', () => { + render(); + + userEvent.click(screen.getByPlaceholderText(placeholder)); + + expect(screen.getByText('Initial state option')).toBeInTheDocument(); + expect(screen.queryByText('First')).not.toBeInTheDocument(); + + act(() => { + jest.runAllTimers(); + }); + + userEvent.click(screen.getByPlaceholderText(placeholder)); + expect(screen.queryByText('Initial state option')).not.toBeInTheDocument(); + expect(screen.getByText('First')).toBeInTheDocument(); + }); + + it('filters updated results when searching', () => { + render(); + + act(() => { + jest.runAllTimers(); + }); + + userEvent.type(screen.getByPlaceholderText(placeholder), 'Third'); + expect(screen.queryByText('Second')).not.toBeInTheDocument(); + expect(screen.getByText('First / Third')).toBeInTheDocument(); + }); + }); + + it('filters results when searching', () => { + render(); + + userEvent.type(screen.getByPlaceholderText(placeholder), 'Third'); + + expect(screen.queryByText('Second')).not.toBeInTheDocument(); + expect(screen.getByText('First / Third')).toBeInTheDocument(); + }); + + it('displays selected value with all levels when displayAllSelectedLevels is true and selecting a value from the search', () => { + render( + + ); + + userEvent.type(screen.getByPlaceholderText(placeholder), 'Third'); + userEvent.click(screen.getByText('First / Third')); + + expect(screen.getByDisplayValue('First / Third')).toBeInTheDocument(); + }); + + it('displays all levels selected with default separator when displayAllSelectedLevels is true', () => { + render( + {}} /> + ); + + expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument(); + + userEvent.click(screen.getByPlaceholderText(placeholder)); + // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed + userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true }); + userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true }); + + expect(screen.getByDisplayValue('First/Second')).toBeInTheDocument(); + }); + + it('displays all levels selected with separator passed in when displayAllSelectedLevels is true', () => { + const separator = ','; + + render( + {}} + /> + ); + + expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument(); + + userEvent.click(screen.getByPlaceholderText(placeholder)); + // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed + userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true }); + userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true }); + + expect(screen.getByDisplayValue(`First${separator}Second`)).toBeInTheDocument(); + }); + + it('displays last level selected when displayAllSelectedLevels is false', () => { + render( + + ); + + userEvent.click(screen.getByPlaceholderText(placeholder)); + // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed + userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true }); + userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true }); + + expect(screen.getByDisplayValue('Second')).toBeInTheDocument(); + }); + + it('displays last level selected when displayAllSelectedLevels is not passed in', () => { + render(); + + userEvent.click(screen.getByPlaceholderText(placeholder)); + // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed + userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true }); + userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true }); + + expect(screen.getByDisplayValue('Second')).toBeInTheDocument(); + }); +}); diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.tsx new file mode 100644 index 00000000..3ef8ca48 --- /dev/null +++ b/packages/grafana-ui/src/components/Cascader/Cascader.tsx @@ -0,0 +1,242 @@ +import React from 'react'; +import { Icon } from '../Icon/Icon'; +import RCCascader from 'rc-cascader'; + +import { Select } from '../Select/Select'; +import { Input } from '../Input/Input'; +import { SelectableValue } from '@grafana/data'; +import { css } from '@emotion/css'; +import { onChangeCascader } from './optionMappings'; +import memoizeOne from 'memoize-one'; + +export interface CascaderProps { + /** The separator between levels in the search */ + separator?: string; + placeholder?: string; + options: CascaderOption[]; + /** Changes the value for every selection, including branch nodes. Defaults to true. */ + changeOnSelect?: boolean; + onSelect(val: string): void; + /** Sets the width to a multiple of 8px. Should only be used with inline forms. Setting width of the container is preferred in other cases.*/ + width?: number; + initialValue?: string; + allowCustomValue?: boolean; + /** A function for formatting the message for custom value creation. Only applies when allowCustomValue is set to true*/ + formatCreateLabel?: (val: string) => string; + displayAllSelectedLevels?: boolean; +} + +interface CascaderState { + isSearching: boolean; + focusCascade: boolean; + //Array for cascade navigation + rcValue: SelectableValue; + activeLabel: string; +} + +export interface CascaderOption { + /** + * The value used under the hood + */ + value: any; + /** + * The label to display in the UI + */ + label: string; + /** Items will be just flattened into the main list of items recursively. */ + items?: CascaderOption[]; + disabled?: boolean; + /** Avoid using */ + title?: string; + /** Children will be shown in a submenu. Use 'items' instead, as 'children' exist to ensure backwards compatibility.*/ + children?: CascaderOption[]; +} + +const disableDivFocus = css(` +&:focus{ + outline: none; +} +`); + +const DEFAULT_SEPARATOR = '/'; + +export class Cascader extends React.PureComponent { + constructor(props: CascaderProps) { + super(props); + const searchableOptions = this.getSearchableOptions(props.options); + const { rcValue, activeLabel } = this.setInitialValue(searchableOptions, props.initialValue); + this.state = { + isSearching: false, + focusCascade: false, + rcValue, + activeLabel, + }; + } + + static defaultProps = { changeOnSelect: true }; + + flattenOptions = (options: CascaderOption[], optionPath: CascaderOption[] = []) => { + let selectOptions: Array> = []; + for (const option of options) { + const cpy = [...optionPath]; + cpy.push(option); + if (!option.items) { + selectOptions.push({ + singleLabel: cpy[cpy.length - 1].label, + label: cpy.map((o) => o.label).join(this.props.separator || ` ${DEFAULT_SEPARATOR} `), + value: cpy.map((o) => o.value), + }); + } else { + selectOptions = [...selectOptions, ...this.flattenOptions(option.items, cpy)]; + } + } + return selectOptions; + }; + + getSearchableOptions = memoizeOne((options: CascaderOption[]) => this.flattenOptions(options)); + + setInitialValue(searchableOptions: Array>, initValue?: string) { + if (!initValue) { + return { rcValue: [], activeLabel: '' }; + } + for (const option of searchableOptions) { + const optionPath = option.value || []; + + if (optionPath.indexOf(initValue) === optionPath.length - 1) { + return { + rcValue: optionPath, + activeLabel: this.props.displayAllSelectedLevels ? option.label : option.singleLabel || '', + }; + } + } + if (this.props.allowCustomValue) { + return { rcValue: [], activeLabel: initValue }; + } + return { rcValue: [], activeLabel: '' }; + } + + //For rc-cascader + onChange = (value: string[], selectedOptions: CascaderOption[]) => { + this.setState({ + rcValue: value, + focusCascade: true, + activeLabel: this.props.displayAllSelectedLevels + ? selectedOptions.map((option) => option.label).join(this.props.separator || DEFAULT_SEPARATOR) + : selectedOptions[selectedOptions.length - 1].label, + }); + + this.props.onSelect(selectedOptions[selectedOptions.length - 1].value); + }; + + //For select + onSelect = (obj: SelectableValue) => { + const valueArray = obj.value || []; + this.setState({ + activeLabel: this.props.displayAllSelectedLevels ? obj.label : obj.singleLabel || '', + rcValue: valueArray, + isSearching: false, + }); + this.props.onSelect(valueArray[valueArray.length - 1]); + }; + + onCreateOption = (value: string) => { + this.setState({ + activeLabel: value, + rcValue: [], + isSearching: false, + }); + this.props.onSelect(value); + }; + + onBlur = () => { + this.setState({ + isSearching: false, + focusCascade: false, + }); + + if (this.state.activeLabel === '') { + this.setState({ + rcValue: [], + }); + } + }; + + onBlurCascade = () => { + this.setState({ + focusCascade: false, + }); + }; + + onInputKeyDown = (e: React.KeyboardEvent) => { + if ( + e.key === 'ArrowDown' || + e.key === 'ArrowUp' || + e.key === 'Enter' || + e.key === 'ArrowLeft' || + e.key === 'ArrowRight' + ) { + return; + } + this.setState({ + focusCascade: false, + isSearching: true, + }); + }; + + render() { + const { allowCustomValue, placeholder, width, changeOnSelect, options } = this.props; + const { focusCascade, isSearching, rcValue, activeLabel } = this.state; + + const searchableOptions = this.getSearchableOptions(options); + + return ( +
+ {isSearching ? ( + {}} + suffix={ + focusCascade ? ( + + ) : ( + + ) + } + /> +
+ + )} +
+ ); + } +} diff --git a/packages/grafana-ui/src/components/Cascader/optionMappings.ts b/packages/grafana-ui/src/components/Cascader/optionMappings.ts new file mode 100644 index 00000000..45e13237 --- /dev/null +++ b/packages/grafana-ui/src/components/Cascader/optionMappings.ts @@ -0,0 +1,36 @@ +import { CascaderValueType, CascaderOption as RCCascaderOption } from 'rc-cascader/lib/Cascader'; +import { CascaderOption } from './Cascader'; + +type onChangeType = ((values: string[], options: CascaderOption[]) => void) | undefined; + +export const onChangeCascader = (onChanged: onChangeType) => ( + values: CascaderValueType, + options: RCCascaderOption[] +) => { + if (onChanged) { + // map values to strings for backwards compatibility with Cascader components + onChanged( + values.map((value) => String(value)), + fromRCOptions(options) + ); + } +}; + +type onLoadDataType = ((options: CascaderOption[]) => void) | undefined; + +export const onLoadDataCascader = (onLoadData: onLoadDataType) => (options: RCCascaderOption[]) => { + if (onLoadData) { + onLoadData(fromRCOptions(options)); + } +}; + +const fromRCOptions = (options: RCCascaderOption[]): CascaderOption[] => { + return options.map(fromRCOption); +}; + +const fromRCOption = (option: RCCascaderOption): CascaderOption => { + return { + value: option.value ?? '', + label: (option.label as unknown) as string, + }; +}; diff --git a/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.mdx b/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.mdx new file mode 100644 index 00000000..074ffbd6 --- /dev/null +++ b/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.mdx @@ -0,0 +1,19 @@ +import { Meta, Props } from '@storybook/addon-docs/blocks'; +import { ClickOutsideWrapper } from './ClickOutsideWrapper'; + + + +# ClickOutsideWrapper + +A wrapper component that detects clicks outside of the elements by attaching event listener to `window` or `document` objects. +Useful for components that require an action being triggered when a click outside has occurred, for example closing an overlay or popup. + +# Usage + +```jsx + console.log('Clicked outside')}> +
Container
+
+``` + + diff --git a/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.story.tsx b/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.story.tsx new file mode 100644 index 00000000..8746e6b2 --- /dev/null +++ b/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.story.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import { ClickOutsideWrapper } from './ClickOutsideWrapper'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import mdx from './ClickOutsideWrapper.mdx'; + +export default { + title: 'Layout/ClickOutsideWrapper', + component: ClickOutsideWrapper, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const basic = () => { + return ( + +
Container
+
+ ); +}; diff --git a/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.tsx b/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.tsx new file mode 100644 index 00000000..e976629d --- /dev/null +++ b/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.tsx @@ -0,0 +1,61 @@ +import React, { PureComponent, createRef } from 'react'; + +export interface Props { + /** + * Callback to trigger when clicking outside of current element occurs. + */ + onClick: () => void; + /** + * Runs the 'onClick' function when pressing a key outside of the current element. Defaults to true. + */ + includeButtonPress: boolean; + /** Object to attach the click event listener to. */ + parent: Window | Document; + /** + * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener. Defaults to false. + */ + useCapture?: boolean; +} + +interface State { + hasEventListener: boolean; +} + +export class ClickOutsideWrapper extends PureComponent { + static defaultProps = { + includeButtonPress: true, + parent: window, + useCapture: false, + }; + myRef = createRef(); + state = { + hasEventListener: false, + }; + + componentDidMount() { + this.props.parent.addEventListener('click', this.onOutsideClick, this.props.useCapture); + if (this.props.includeButtonPress) { + // Use keyup since keydown already has an event listener on window + this.props.parent.addEventListener('keyup', this.onOutsideClick, this.props.useCapture); + } + } + + componentWillUnmount() { + this.props.parent.removeEventListener('click', this.onOutsideClick, this.props.useCapture); + if (this.props.includeButtonPress) { + this.props.parent.removeEventListener('keyup', this.onOutsideClick, this.props.useCapture); + } + } + + onOutsideClick = (event: any) => { + const domNode = this.myRef.current; + + if (!domNode || !domNode.contains(event.target)) { + this.props.onClick(); + } + }; + + render() { + return
{this.props.children}
; + } +} diff --git a/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.mdx b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.mdx new file mode 100644 index 00000000..e08401ba --- /dev/null +++ b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.mdx @@ -0,0 +1,22 @@ +import { Meta, Props } from '@storybook/addon-docs/blocks'; +import { ClipboardButton } from './ClipboardButton'; + + + +# ClipboardButton + +A wrapper for [clipboard.js](https://github.com/zenorocha/clipboard.js) library that allows copying text to clipboard. The text to be copied should be provided via `getText` prop. + +# Usage + +```jsx + 'Text to be copied'} + onClipboardCopy={() => console.log('text copied')} +> + Copy to clipboard + +``` + + diff --git a/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.story.internal.tsx b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.story.internal.tsx new file mode 100644 index 00000000..8bc335d7 --- /dev/null +++ b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.story.internal.tsx @@ -0,0 +1,52 @@ +import React, { useState } from 'react'; +import { Story, Meta } from '@storybook/react'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { ClipboardButton, Props } from './ClipboardButton'; +import { Input } from '../Forms/Legacy/Input/Input'; +import mdx from './ClipboardButton.mdx'; + +export default { + title: 'Buttons/ClipboardButton', + component: ClipboardButton, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + controls: { + exclude: ['variant', 'icon', 'className', 'fullWidth', 'getText', 'onClipboardCopy', 'onClipboardError'], + }, + }, +} as Meta; + +interface StoryProps extends Partial { + inputText: string; + buttonText: string; +} + +const Wrapper: Story = (args) => { + const [copyMessage, setCopyMessage] = useState(''); + const clipboardCopyMessage = 'Value copied to clipboard'; + return ( +
+
+ args.inputText} + onClipboardCopy={() => setCopyMessage(clipboardCopyMessage)} + > + {args.buttonText} + + {}} /> +
+ {copyMessage} +
+ ); +}; +export const CopyToClipboard = Wrapper.bind({}); +CopyToClipboard.args = { + inputText: 'go run build.go -goos linux -pkg-arch amd64 ${OPT} package-only', + buttonText: 'Copy to clipboard', + size: 'md', +}; diff --git a/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.tsx b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.tsx new file mode 100644 index 00000000..52e8d105 --- /dev/null +++ b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.tsx @@ -0,0 +1,51 @@ +import React, { PureComponent } from 'react'; +import Clipboard from 'clipboard'; +import { Button, ButtonProps } from '../Button'; + +export interface Props extends ButtonProps { + /** A function that returns text to be copied */ + getText(): string; + /** Callback when the text has been successfully copied */ + onClipboardCopy?(e: Clipboard.Event): void; + /** Callback when there was an error copying the text */ + onClipboardError?(e: Clipboard.Event): void; +} + +export class ClipboardButton extends PureComponent { + private clipboard!: Clipboard; + private elem!: HTMLButtonElement; + + setRef = (elem: HTMLButtonElement) => { + this.elem = elem; + }; + + componentDidMount() { + const { getText, onClipboardCopy, onClipboardError } = this.props; + + this.clipboard = new Clipboard(this.elem, { + text: () => getText(), + }); + + this.clipboard.on('success', (e: Clipboard.Event) => { + onClipboardCopy && onClipboardCopy(e); + }); + + this.clipboard.on('error', (e: Clipboard.Event) => { + onClipboardError && onClipboardError(e); + }); + } + + componentWillUnmount() { + this.clipboard.destroy(); + } + + render() { + const { getText, onClipboardCopy, onClipboardError, children, ...buttonProps } = this.props; + + return ( + + ); + } +} diff --git a/packages/grafana-ui/src/components/Collapse/CollapsableSection.mdx b/packages/grafana-ui/src/components/Collapse/CollapsableSection.mdx new file mode 100644 index 00000000..8640b019 --- /dev/null +++ b/packages/grafana-ui/src/components/Collapse/CollapsableSection.mdx @@ -0,0 +1,10 @@ +import { Meta, Props } from '@storybook/addon-docs/blocks'; +import { CollapsableSection } from './CollapsableSection'; + + + +# Collapsable Section + +A simple container for enabling collapsing/expanding of content. + + diff --git a/packages/grafana-ui/src/components/Collapse/CollapsableSection.story.tsx b/packages/grafana-ui/src/components/Collapse/CollapsableSection.story.tsx new file mode 100644 index 00000000..6e02c8cf --- /dev/null +++ b/packages/grafana-ui/src/components/Collapse/CollapsableSection.story.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { CollapsableSection } from './CollapsableSection'; +import mdx from './CollapsableSection.mdx'; + +export default { + title: 'Layout/CollapsableSection', + component: CollapsableSection, + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const simple = () => { + return ( + +
{"Here's some content"}
+
+ ); +}; diff --git a/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx b/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx new file mode 100644 index 00000000..3e2ac0ad --- /dev/null +++ b/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx @@ -0,0 +1,55 @@ +import React, { FC, ReactNode, useState } from 'react'; +import { css } from '@emotion/css'; +import { useStyles2 } from '../../themes'; +import { Icon } from '..'; +import { GrafanaTheme2 } from '@grafana/data'; + +export interface Props { + label: ReactNode; + isOpen: boolean; + /** Callback for the toggle functionality */ + onToggle?: (isOpen: boolean) => void; + children: ReactNode; +} + +export const CollapsableSection: FC = ({ label, isOpen, onToggle, children }) => { + const [open, toggleOpen] = useState(isOpen); + const styles = useStyles2(collapsableSectionStyles); + const headerStyle = open ? styles.header : styles.headerCollapsed; + const tooltip = `Click to ${open ? 'collapse' : 'expand'}`; + const onClick = () => { + onToggle?.(!open); + toggleOpen(!open); + }; + + return ( +
+
+ {label} + +
+ {open &&
{children}
} +
+ ); +}; + +const collapsableSectionStyles = (theme: GrafanaTheme2) => { + const header = css({ + display: 'flex', + justifyContent: 'space-between', + fontSize: theme.typography.size.lg, + padding: `${theme.spacing(0.5)} 0`, + cursor: 'pointer', + }); + const headerCollapsed = css(header, { + borderBottom: `1px solid ${theme.colors.border.weak}`, + }); + const icon = css({ + color: theme.colors.text.secondary, + }); + const content = css({ + padding: `${theme.spacing(2)} 0`, + }); + + return { header, headerCollapsed, icon, content }; +}; diff --git a/packages/grafana-ui/src/components/Collapse/Collapse.mdx b/packages/grafana-ui/src/components/Collapse/Collapse.mdx new file mode 100644 index 00000000..68ea7ab7 --- /dev/null +++ b/packages/grafana-ui/src/components/Collapse/Collapse.mdx @@ -0,0 +1,18 @@ +import { Meta, Preview, Props } from '@storybook/addon-docs/blocks'; +import { Collapse } from './Collapse'; + +# Collapse + +A content area, which can be horizontally collapsed and expanded. Can be used to hide extra information on the page. + +## Usage + +```jsx +const [isOpen, setIsOpen] = useState(false); + + setIsOpen(!isOpen)}> +

Panel data

+
; +``` + + diff --git a/packages/grafana-ui/src/components/Collapse/Collapse.story.tsx b/packages/grafana-ui/src/components/Collapse/Collapse.story.tsx new file mode 100644 index 00000000..b7b00dcb --- /dev/null +++ b/packages/grafana-ui/src/components/Collapse/Collapse.story.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { Collapse, ControlledCollapse } from './Collapse'; +import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { UseState } from '../../utils/storybook/UseState'; +import mdx from './Collapse.mdx'; + +export default { + title: 'Layout/Collapse', + component: Collapse, + decorators: [withCenteredStory, withHorizontallyCenteredStory], + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const basic = () => { + return ( + + {(state, updateValue) => { + return ( + updateValue({ isOpen: !state.isOpen })} + > +

Panel data

+
+ ); + }} +
+ ); +}; + +export const controlled = () => { + return ( + +

Panel data

+
+ ); +}; diff --git a/packages/grafana-ui/src/components/Collapse/Collapse.tsx b/packages/grafana-ui/src/components/Collapse/Collapse.tsx new file mode 100644 index 00000000..adcd7642 --- /dev/null +++ b/packages/grafana-ui/src/components/Collapse/Collapse.tsx @@ -0,0 +1,153 @@ +import React, { FunctionComponent, useState } from 'react'; +import { css, cx } from '@emotion/css'; + +import { useStyles2 } from '../../themes/ThemeContext'; +import { Icon } from '../Icon/Icon'; +import { GrafanaTheme2 } from '@grafana/data'; + +const getStyles = (theme: GrafanaTheme2) => ({ + collapse: css` + label: collapse; + margin-bottom: ${theme.spacing(1)}; + `, + collapseBody: css` + label: collapse__body; + padding: ${theme.spacing(theme.components.panel.padding)}; + padding-top: 0; + flex: 1; + overflow: hidden; + display: flex; + flex-direction: column; + `, + bodyContentWrapper: css` + label: bodyContentWrapper; + flex: 1; + overflow: hidden; + `, + loader: css` + label: collapse__loader; + height: 2px; + position: relative; + overflow: hidden; + background: none; + margin: ${theme.spacing(0.5)}; + `, + loaderActive: css` + label: collapse__loader_active; + &:after { + content: ' '; + display: block; + width: 25%; + top: 0; + top: -50%; + height: 250%; + position: absolute; + animation: loader 2s cubic-bezier(0.17, 0.67, 0.83, 0.67) 500ms; + animation-iteration-count: 100; + left: -25%; + background: ${theme.colors.primary.main}; + } + @keyframes loader { + from { + left: -25%; + opacity: 0.1; + } + to { + left: 100%; + opacity: 1; + } + } + `, + header: css` + label: collapse__header; + padding: ${theme.spacing(1, 2, 0.5, 2)}; + display: flex; + cursor: inherit; + transition: all 0.1s linear; + cursor: pointer; + `, + headerCollapsed: css` + label: collapse__header--collapsed; + padding: ${theme.spacing(1, 2, 0.5, 2)}; + `, + headerLabel: css` + label: collapse__header-label; + font-weight: ${theme.typography.fontWeightMedium}; + margin-right: ${theme.spacing(1)}; + font-size: ${theme.typography.size.md}; + `, + icon: css` + label: collapse__icon; + margin: ${theme.spacing(0, 1, 0, -1)}; + `, +}); + +export interface Props { + /** Expand or collapse te content */ + isOpen?: boolean; + /** Element or text for the Collapse header */ + label: React.ReactNode; + /** Indicates loading state of the content */ + loading?: boolean; + /** Toggle collapsed header icon */ + collapsible?: boolean; + /** Callback for the toggle functionality */ + onToggle?: (isOpen: boolean) => void; + /** Additional class name for the root element */ + className?: string; +} + +export const ControlledCollapse: FunctionComponent = ({ isOpen, onToggle, ...otherProps }) => { + const [open, setOpen] = useState(isOpen); + return ( + { + setOpen(!open); + if (onToggle) { + onToggle(!open); + } + }} + /> + ); +}; + +export const Collapse: FunctionComponent = ({ + isOpen, + label, + loading, + collapsible, + onToggle, + className, + children, +}) => { + const style = useStyles2(getStyles); + const onClickToggle = () => { + if (onToggle) { + onToggle(!isOpen); + } + }; + + const panelClass = cx([style.collapse, 'panel-container', className]); + const loaderClass = loading ? cx([style.loader, style.loaderActive]) : cx([style.loader]); + const headerClass = collapsible ? cx([style.header]) : cx([style.headerCollapsed]); + + return ( +
+
+ {collapsible && } +
{label}
+
+ {isOpen && ( +
+
+
{children}
+
+ )} +
+ ); +}; + +Collapse.displayName = 'Collapse'; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx new file mode 100644 index 00000000..684dd41c --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx @@ -0,0 +1,110 @@ +import React from 'react'; +import tinycolor from 'tinycolor2'; +import { debounce } from 'lodash'; + +import { ColorPickerProps } from './ColorPickerPopover'; +import { Input } from '../Input/Input'; +import { useStyles2 } from '../../themes'; +import { GrafanaTheme2 } from '@grafana/data'; +import { cx, css } from '@emotion/css'; + +interface ColorInputState { + previousColor: string; + value: string; +} + +interface ColorInputProps extends ColorPickerProps { + style?: React.CSSProperties; + className?: string; +} + +class ColorInput extends React.PureComponent { + constructor(props: ColorInputProps) { + super(props); + this.state = { + previousColor: props.color, + value: props.color, + }; + + this.updateColor = debounce(this.updateColor, 100); + } + + static getDerivedStateFromProps(props: ColorPickerProps, state: ColorInputState) { + const newColor = tinycolor(props.color); + if (newColor.isValid() && props.color !== state.previousColor) { + return { + ...state, + previousColor: props.color, + value: newColor.toString(), + }; + } + + return state; + } + updateColor = (color: string) => { + this.props.onChange(color); + }; + + onChange = (event: React.SyntheticEvent) => { + const newColor = tinycolor(event.currentTarget.value); + + this.setState({ + value: event.currentTarget.value, + }); + + if (newColor.isValid()) { + this.updateColor(newColor.toString()); + } + }; + + onBlur = () => { + const newColor = tinycolor(this.state.value); + + if (!newColor.isValid()) { + this.setState({ + value: this.props.color, + }); + } + }; + + render() { + const { value } = this.state; + return ( + } + /> + ); + } +} + +export default ColorInput; + +interface ColorPreviewProps { + color: string; +} + +const ColorPreview = ({ color }: ColorPreviewProps) => { + const styles = useStyles2(getColorPreviewStyles); + + return ( +
+ ); +}; + +const getColorPreviewStyles = (theme: GrafanaTheme2) => css` + height: 100%; + width: ${theme.spacing.gridSize * 4}px; + border-radius: ${theme.shape.borderRadius()} 0 0 ${theme.shape.borderRadius()}; + border: 1px solid ${theme.colors.border.medium}; +`; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.mdx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.mdx new file mode 100644 index 00000000..6f1b631c --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.mdx @@ -0,0 +1,14 @@ +import { Meta, Props } from '@storybook/addon-docs/blocks'; +import { ColorPicker } from './ColorPicker'; + + + +# ColorPicker + +The `ColorPicker` component group consists of several building blocks that are combined in Grafana to create the `ColorPicker`: popover, pickers and palettes. There are different combinations of these building blocks depending on where the `ColorPicker` is used in Grafana. + +The `Popover` is a tabbed view where you can switch between `Palettes`. The `NamedColorsPalette` shows an arrangement of preset colors, while the `SpectrumPalette` is an unlimited HSB color picker. The preset colors are optimized to work well with both light and dark theme. `Popover` is triggered, for example, by the series legend of graphs, or by `Pickers`. + +The `Pickers` are single circular color fields that show the currently picked color. On click, they open the `Popover`. + + diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx new file mode 100644 index 00000000..1312169c --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { Meta, Story } from '@storybook/react'; +import { SeriesColorPicker, ColorPicker } from '@grafana/ui'; +import { action } from '@storybook/addon-actions'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { UseState } from '../../utils/storybook/UseState'; +import { renderComponentWithTheme } from '../../utils/storybook/withTheme'; +import { ColorPickerProps } from './ColorPickerPopover'; +import mdx from './ColorPicker.mdx'; + +export default { + title: 'Pickers and Editors/ColorPicker', + component: ColorPicker, + subcomponents: { SeriesColorPicker }, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + controls: { + exclude: ['color', 'onChange', 'onColorChange'], + }, + }, + args: { + enableNamedColors: false, + }, +} as Meta; + +export const Basic: Story = ({ enableNamedColors }) => { + return ( + + {(selectedColor, updateSelectedColor) => { + return renderComponentWithTheme(ColorPicker, { + enableNamedColors, + color: selectedColor, + onChange: (color: any) => { + action('Color changed')(color); + updateSelectedColor(color); + }, + }); + }} + + ); +}; + +export const SeriesPicker: Story = ({ enableNamedColors }) => { + return ( + + {(selectedColor, updateSelectedColor) => { + return ( + {}} + color={selectedColor} + onChange={(color) => updateSelectedColor(color)} + > + {({ ref, showColorPicker, hideColorPicker }) => ( +
+ Open color picker +
+ )} +
+ ); + }} +
+ ); +}; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.test.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.test.tsx new file mode 100644 index 00000000..00a703f3 --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.test.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import { ColorPicker } from './ColorPicker'; +import { ColorSwatch } from './ColorSwatch'; + +describe('ColorPicker', () => { + it('renders ColorPickerTrigger component by default', () => { + expect( + renderer.create( {}} />).root.findByType(ColorSwatch) + ).toBeTruthy(); + }); + + it('renders custom trigger when supplied', () => { + const div = renderer + .create( + {}}> + {() =>
Custom trigger
} +
+ ) + .root.findByType('div'); + expect(div.children[0]).toBe('Custom trigger'); + }); +}); diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx new file mode 100644 index 00000000..4d96440b --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx @@ -0,0 +1,122 @@ +import React, { Component, createRef } from 'react'; +import { PopoverController } from '../Tooltip/PopoverController'; +import { Popover } from '../Tooltip/Popover'; +import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover'; +import { GrafanaTheme2 } from '@grafana/data'; +import { SeriesColorPickerPopover } from './SeriesColorPickerPopover'; + +import { css } from '@emotion/css'; +import { withTheme2, stylesFactory } from '../../themes'; +import { ColorSwatch } from './ColorSwatch'; +import { closePopover } from '../../utils/closePopover'; + +/** + * If you need custom trigger for the color picker you can do that with a render prop pattern and supply a function + * as a child. You will get show/hide function which you can map to desired interaction (like onClick or onMouseLeave) + * and a ref which needs to be passed to an HTMLElement for correct positioning. If you want to use class or functional + * component as a custom trigger you will need to forward the reference to first HTMLElement child. + */ +type ColorPickerTriggerRenderer = (props: { + // This should be a React.RefObject but due to how object refs are defined you cannot downcast from that + // to a specific type like React.RefObject even though it would be fine in runtime. + ref: React.RefObject; + showColorPicker: () => void; + hideColorPicker: () => void; +}) => React.ReactNode; + +export const colorPickerFactory = ( + popover: React.ComponentType, + displayName = 'ColorPicker' +) => { + return class ColorPicker extends Component { + static displayName = displayName; + pickerTriggerRef = createRef(); + + onColorChange = (color: string) => { + const { onColorChange, onChange } = this.props; + const changeHandler = (onColorChange || onChange) as ColorPickerChangeHandler; + + return changeHandler(color); + }; + + render() { + const { theme, children } = this.props; + const styles = getStyles(theme); + const popoverElement = React.createElement(popover, { + ...{ ...this.props, children: null }, + onChange: this.onColorChange, + }); + + return ( + + {(showPopper, hidePopper, popperProps) => { + return ( + <> + {this.pickerTriggerRef.current && ( + closePopover(event, hidePopper)} + /> + )} + + {children ? ( + // Children have a bit weird type due to intersection used in the definition so we need to cast here, + // but the definition is correct and should not allow to pass a children that does not conform to + // ColorPickerTriggerRenderer type. + (children as ColorPickerTriggerRenderer)({ + ref: this.pickerTriggerRef, + showColorPicker: showPopper, + hideColorPicker: hidePopper, + }) + ) : ( + + )} + + ); + }} + + ); + } + }; +}; + +export const ColorPicker = withTheme2(colorPickerFactory(ColorPickerPopover, 'ColorPicker')); +export const SeriesColorPicker = withTheme2(colorPickerFactory(SeriesColorPickerPopover, 'SeriesColorPicker')); + +const getStyles = stylesFactory((theme: GrafanaTheme2) => { + return { + colorPicker: css` + position: absolute; + z-index: ${theme.zIndex.tooltip}; + color: ${theme.colors.text.primary}; + max-width: 400px; + font-size: ${theme.typography.size.sm}; + // !important because these styles are also provided to popper via .popper classes from Tooltip component + // hope to get rid of those soon + padding: 15px !important; + & [data-placement^='top'] { + padding-left: 0 !important; + padding-right: 0 !important; + } + & [data-placement^='bottom'] { + padding-left: 0 !important; + padding-right: 0 !important; + } + & [data-placement^='left'] { + padding-top: 0 !important; + } + & [data-placement^='right'] { + padding-top: 0 !important; + } + `, + }; +}); diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.story.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.story.tsx new file mode 100644 index 00000000..5b04d0da --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.story.tsx @@ -0,0 +1,30 @@ +import { ColorPickerPopover } from './ColorPickerPopover'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { SeriesColorPickerPopover } from './SeriesColorPickerPopover'; +import { renderComponentWithTheme } from '../../utils/storybook/withTheme'; + +export default { + title: 'Pickers and Editors/ColorPicker/Popovers', + component: ColorPickerPopover, + subcomponents: { SeriesColorPickerPopover }, + decorators: [withCenteredStory], +}; + +export const basic = () => { + return renderComponentWithTheme(ColorPickerPopover, { + color: '#BC67E6', + onChange: (color: any) => { + console.log(color); + }, + }); +}; + +export const seriesColorPickerPopover = () => { + return renderComponentWithTheme(SeriesColorPickerPopover, { + color: '#BC67E6', + onChange: (color: any) => { + console.log(color); + }, + }); +}; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx new file mode 100644 index 00000000..1c0ab924 --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { act, render, screen } from '@testing-library/react'; +import { ColorPickerPopover } from './ColorPickerPopover'; +import { createTheme } from '@grafana/data'; +import userEvent from '@testing-library/user-event'; + +describe('ColorPickerPopover', () => { + const theme = createTheme(); + + it('should be tabbable', () => { + render( {}} />); + const color = screen.getByRole('button', { name: 'dark-red color' }); + const customTab = screen.getByRole('button', { name: 'Custom' }); + + act(() => { + userEvent.tab(); + }); + expect(customTab).toHaveFocus(); + + act(() => { + userEvent.tab(); + }); + expect(color).toHaveFocus(); + }); + + describe('rendering', () => { + it('should render provided color as selected if color provided by name', () => { + render( {}} />); + const color = screen.getByRole('button', { name: 'green color' }); + const colorSwatchWrapper = screen.getAllByTestId('data-testid-colorswatch'); + + expect(color).toBeInTheDocument(); + expect(colorSwatchWrapper[0]).toBeInTheDocument(); + + act(() => { + userEvent.click(colorSwatchWrapper[0]); + }); + expect(color).toHaveStyle('box-shadow: inset 0 0 0 2px #73BF69,inset 0 0 0 4px #000000'); + }); + }); + + describe('named colors support', () => { + const onChangeSpy = jest.fn(); + + it('should pass hex color value to onChange prop by default', () => { + render(); + const color = screen.getByRole('button', { name: 'red color' }); + act(() => { + userEvent.click(color); + }); + + expect(onChangeSpy).toBeCalledTimes(1); + expect(onChangeSpy).toBeCalledWith(theme.visualization.getColorByName('red')); + }); + + it('should pass color name to onChange prop when named colors enabled', () => { + render(); + const color = screen.getByRole('button', { name: 'red color' }); + act(() => { + userEvent.click(color); + }); + + expect(onChangeSpy).toBeCalledTimes(2); + expect(onChangeSpy).toBeCalledWith(theme.visualization.getColorByName('red')); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx new file mode 100644 index 00000000..ff99b57c --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx @@ -0,0 +1,189 @@ +import React from 'react'; +import { NamedColorsPalette } from './NamedColorsPalette'; +import { PopoverContentProps } from '../Tooltip/Tooltip'; +import SpectrumPalette from './SpectrumPalette'; +import { Themeable2 } from '../../types/theme'; +import { warnAboutColorPickerPropsDeprecation } from './warnAboutColorPickerPropsDeprecation'; +import { css } from '@emotion/css'; +import { GrafanaTheme2, colorManipulator } from '@grafana/data'; +import { stylesFactory, withTheme2 } from '../../themes'; +import { FocusScope } from '@react-aria/focus'; + +export type ColorPickerChangeHandler = (color: string) => void; + +export interface ColorPickerProps extends Themeable2 { + color: string; + onChange: ColorPickerChangeHandler; + + /** + * @deprecated Use onChange instead + */ + onColorChange?: ColorPickerChangeHandler; + enableNamedColors?: boolean; +} + +export interface Props extends ColorPickerProps, PopoverContentProps { + customPickers?: T; +} + +type PickerType = 'palette' | 'spectrum'; + +export interface CustomPickersDescriptor { + [key: string]: { + tabComponent: React.ComponentType; + name: string; + }; +} + +interface State { + activePicker: PickerType | keyof T; +} + +class UnThemedColorPickerPopover extends React.Component, State> { + constructor(props: Props) { + super(props); + this.state = { + activePicker: 'palette', + }; + warnAboutColorPickerPropsDeprecation('ColorPickerPopover', props); + } + + getTabClassName = (tabName: PickerType | keyof T) => { + const { activePicker } = this.state; + return `ColorPickerPopover__tab ${activePicker === tabName && 'ColorPickerPopover__tab--active'}`; + }; + + handleChange = (color: any) => { + const { onColorChange, onChange, enableNamedColors, theme } = this.props; + const changeHandler = onColorChange || onChange; + if (enableNamedColors) { + return changeHandler(color); + } + changeHandler(colorManipulator.asHexString(theme.visualization.getColorByName(color))); + }; + + onTabChange = (tab: PickerType | keyof T) => { + return () => this.setState({ activePicker: tab }); + }; + + renderPicker = () => { + const { activePicker } = this.state; + const { color } = this.props; + + switch (activePicker) { + case 'spectrum': + return ; + case 'palette': + return ; + default: + return this.renderCustomPicker(activePicker); + } + }; + + renderCustomPicker = (tabKey: keyof T) => { + const { customPickers, color, theme } = this.props; + if (!customPickers) { + return null; + } + + return React.createElement(customPickers[tabKey].tabComponent, { + color, + theme, + onChange: this.handleChange, + }); + }; + + renderCustomPickerTabs = () => { + const { customPickers } = this.props; + + if (!customPickers) { + return null; + } + + return ( + <> + {Object.keys(customPickers).map((key) => { + return ( +
+ {customPickers[key].name} +
+ ); + })} + + ); + }; + + render() { + const { theme } = this.props; + const styles = getStyles(theme); + return ( + +
+
+ + + {this.renderCustomPickerTabs()} +
+
{this.renderPicker()}
+
+
+ ); + } +} + +export const ColorPickerPopover = withTheme2(UnThemedColorPickerPopover); +ColorPickerPopover.displayName = 'ColorPickerPopover'; + +const getStyles = stylesFactory((theme: GrafanaTheme2) => { + return { + colorPickerPopover: css` + border-radius: ${theme.shape.borderRadius()}; + box-shadow: ${theme.shadows.z3}; + background: ${theme.colors.background.primary}; + border: 1px solid ${theme.colors.border.medium}; + + .ColorPickerPopover__tab { + width: 50%; + text-align: center; + padding: ${theme.spacing(1, 0)}; + background: ${theme.colors.background.secondary}; + color: ${theme.colors.text.secondary}; + font-size: ${theme.typography.bodySmall.fontSize}; + cursor: pointer; + border: none; + + &:focus:not(:focus-visible) { + outline: none; + box-shadow: none; + } + + :focus-visible { + position: relative; + } + } + + .ColorPickerPopover__tab--active { + color: ${theme.colors.text.primary}; + font-weight: ${theme.typography.fontWeightMedium}; + background: ${theme.colors.background.primary}; + } + `, + colorPickerPopoverContent: css` + width: 246px; + font-size: ${theme.typography.bodySmall.fontSize}; + min-height: 184px; + padding: ${theme.spacing(1)}; + display: flex; + flex-direction: column; + `, + colorPickerPopoverTabs: css` + display: flex; + width: 100%; + border-radius: ${theme.shape.borderRadius()} ${theme.shape.borderRadius()} 0 0; + `, + }; +}); diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorSwatch.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorSwatch.tsx new file mode 100644 index 00000000..99417069 --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/ColorSwatch.tsx @@ -0,0 +1,87 @@ +import { useFocusRing } from '@react-aria/focus'; +import React from 'react'; +import tinycolor from 'tinycolor2'; +import { useTheme2 } from '../../themes/ThemeContext'; +import { selectors } from '@grafana/e2e-selectors'; +import { GrafanaTheme2 } from '@grafana/data'; +import { css } from '@emotion/css'; + +/** @internal */ +export enum ColorSwatchVariant { + Small = 'small', + Large = 'large', +} + +/** @internal */ +export interface Props extends React.HTMLAttributes { + color: string; + label?: string; + variant?: ColorSwatchVariant; + isSelected?: boolean; +} + +/** @internal */ +export const ColorSwatch = React.forwardRef( + ({ color, label, variant = ColorSwatchVariant.Small, isSelected, 'aria-label': ariaLabel, ...otherProps }, ref) => { + const theme = useTheme2(); + const { isFocusVisible, focusProps } = useFocusRing(); + const styles = getStyles(theme, variant, color, isFocusVisible, isSelected); + const hasLabel = !!label; + const colorLabel = `${ariaLabel || label} color`; + + return ( +
+ {hasLabel && {label}} +
+ ); + } +); + +const getStyles = ( + theme: GrafanaTheme2, + variant: ColorSwatchVariant, + color: string, + isFocusVisible: boolean, + isSelected?: boolean +) => { + const tc = tinycolor(color); + const isSmall = variant === ColorSwatchVariant.Small; + const swatchSize = isSmall ? '16px' : '32px'; + let border = 'none'; + + if (tc.getAlpha() < 0.1) { + border = `2px solid ${theme.colors.border.medium}`; + } + + return { + wrapper: css({ + display: 'flex', + alignItems: 'center', + cursor: 'pointer', + }), + label: css({ + marginRight: theme.spacing(1), + }), + swatch: css({ + width: swatchSize, + height: swatchSize, + background: `${color}`, + border, + borderRadius: '50%', + outlineOffset: '1px', + outline: isFocusVisible ? `2px solid ${theme.colors.primary.main}` : 'none', + boxShadow: isSelected + ? `inset 0 0 0 2px ${color}, inset 0 0 0 4px ${theme.colors.getContrastText(color)}` + : 'none', + transition: theme.transitions.create(['transform'], { + duration: theme.transitions.duration.short, + }), + '&:hover': { + transform: 'scale(1.1)', + }, + }), + }; +}; + +ColorSwatch.displayName = 'ColorSwatch'; diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx new file mode 100644 index 00000000..607eaf03 --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx @@ -0,0 +1,72 @@ +import React, { FunctionComponent } from 'react'; +import { GrafanaTheme2, ThemeVizHue } from '@grafana/data'; +import { Property } from 'csstype'; +import { ColorSwatch, ColorSwatchVariant } from './ColorSwatch'; +import { upperFirst } from 'lodash'; +import { useStyles2 } from '../../themes/ThemeContext'; +import { css } from '@emotion/css'; +import { reverseMap } from '../../utils/reverseMap'; + +interface NamedColorsGroupProps { + hue: ThemeVizHue; + selectedColor?: Property.Color; + onColorSelect: (colorName: string) => void; + key?: string; +} + +const NamedColorsGroup: FunctionComponent = ({ + hue, + selectedColor, + onColorSelect, + ...otherProps +}) => { + const label = upperFirst(hue.name); + const styles = useStyles2(getStyles); + + return ( +
+
{label}
+
+ {reverseMap(hue.shades, (shade) => ( + onColorSelect(shade.name)} + /> + ))} +
+
+ ); +}; + +export default NamedColorsGroup; + +const getStyles = (theme: GrafanaTheme2) => { + return { + colorRow: css` + display: grid; + grid-template-columns: 25% 1fr; + grid-column-gap: ${theme.spacing(2)}; + padding: ${theme.spacing(0.5, 0)}; + + &:hover { + background: ${theme.colors.background.secondary}; + } + `, + colorLabel: css` + padding-left: ${theme.spacing(2)}; + display: flex; + align-items: center; + `, + swatchRow: css` + display: flex; + gap: ${theme.spacing(1)}; + align-items: center; + justify-content: space-around; + flex-direction: row; + `, + }; +}; diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx new file mode 100644 index 00000000..cb24e5ce --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx @@ -0,0 +1,35 @@ +import React, { useState } from 'react'; +import { NamedColorsPalette, NamedColorsPaletteProps } from './NamedColorsPalette'; +import { Meta, Story } from '@storybook/react'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import mdx from './ColorPicker.mdx'; + +export default { + title: 'Pickers and Editors/ColorPicker/Palettes/NamedColorsPalette', + component: NamedColorsPalette, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + controls: { + exclude: ['theme', 'color'], + }, + }, + argTypes: { + selectedColor: { control: { type: 'select', options: ['green', 'red', 'light-blue', 'yellow'] } }, + }, +} as Meta; + +interface StoryProps extends Partial { + selectedColor: string; +} + +export const NamedColors: Story = ({ selectedColor }) => { + const [color, setColor] = useState('green'); + return ; +}; + +NamedColors.args = { + color: 'green', +}; diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx new file mode 100644 index 00000000..023dad1f --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { mount, ReactWrapper } from 'enzyme'; +import { NamedColorsPalette } from './NamedColorsPalette'; +import { createTheme } from '@grafana/data'; +import { ColorSwatch } from './ColorSwatch'; + +describe('NamedColorsPalette', () => { + const theme = createTheme(); + const greenHue = theme.visualization.hues.find((x) => x.name === 'green')!; + const selectedShade = greenHue.shades[2]; + + describe('theme support for named colors', () => { + let wrapper: ReactWrapper, selectedSwatch; + + afterEach(() => { + wrapper.unmount(); + }); + + it('should render provided color variant specific for theme', () => { + wrapper = mount( {}} />); + selectedSwatch = wrapper.find(ColorSwatch).findWhere((node) => node.key() === selectedShade.name); + expect(selectedSwatch.prop('color')).toBe(selectedShade.color); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx new file mode 100644 index 00000000..548b814c --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import NamedColorsGroup from './NamedColorsGroup'; +import { ColorSwatch } from './ColorSwatch'; +import { useStyles2, useTheme2 } from '../../themes/ThemeContext'; +import { GrafanaTheme2 } from '@grafana/data'; +import { css } from '@emotion/css'; + +export interface NamedColorsPaletteProps { + color?: string; + onChange: (colorName: string) => void; +} + +export const NamedColorsPalette = ({ color, onChange }: NamedColorsPaletteProps) => { + const theme = useTheme2(); + const styles = useStyles2(getStyles); + + const swatches: JSX.Element[] = []; + for (const hue of theme.visualization.hues) { + swatches.push(); + } + + return ( + <> +
{swatches}
+
+ onChange('transparent')} + /> + onChange('text')} + /> +
+ + ); +}; + +const getStyles = (theme: GrafanaTheme2) => { + return { + container: css` + display: flex; + flex-direction: column; + `, + extraColors: css` + display: flex; + align-items: center; + justify-content: space-around; + gap: ${theme.spacing(1)}; + padding: ${theme.spacing(1, 0)}; + `, + swatches: css` + display: grid; + flex-grow: 1; + `, + }; +}; diff --git a/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx new file mode 100644 index 00000000..37c806c6 --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx @@ -0,0 +1,104 @@ +import React, { FunctionComponent } from 'react'; + +import { ColorPickerPopover, ColorPickerProps } from './ColorPickerPopover'; +import { PopoverContentProps } from '../Tooltip/Tooltip'; +import { Switch } from '../Forms/Legacy/Switch/Switch'; +import { css } from '@emotion/css'; +import { withTheme2, useStyles } from '../../themes'; +import { Button } from '../Button'; + +export interface SeriesColorPickerPopoverProps extends ColorPickerProps, PopoverContentProps { + yaxis?: number; + onToggleAxis?: () => void; +} + +export const SeriesColorPickerPopover: FunctionComponent = (props) => { + const styles = useStyles(getStyles); + const { yaxis, onToggleAxis, color, ...colorPickerProps } = props; + + const customPickers = onToggleAxis + ? { + yaxis: { + name: 'Y-Axis', + tabComponent() { + return ( + { + if (onToggleAxis) { + onToggleAxis(); + } + }} + /> + ); + }, + }, + } + : undefined; + return ; +}; + +interface AxisSelectorProps { + yaxis: number; + onToggleAxis?: () => void; +} + +interface AxisSelectorState { + yaxis: number; +} + +export class AxisSelector extends React.PureComponent { + constructor(props: AxisSelectorProps) { + super(props); + this.state = { + yaxis: this.props.yaxis, + }; + this.onToggleAxis = this.onToggleAxis.bind(this); + } + + onToggleAxis() { + this.setState({ + yaxis: this.state.yaxis === 2 ? 1 : 2, + }); + + if (this.props.onToggleAxis) { + this.props.onToggleAxis(); + } + } + + render() { + const leftButtonVariant = this.state.yaxis === 1 ? 'primary' : 'secondary'; + const rightButtonVariant = this.state.yaxis === 2 ? 'primary' : 'secondary'; + + return ( +
+ + + +
+ ); + } +} + +// This component is to enable SeriesColorPickerPopover usage via series-color-picker-popover directive +export const SeriesColorPickerPopoverWithTheme = withTheme2(SeriesColorPickerPopover); + +const getStyles = () => { + return { + colorPickerAxisSwitch: css` + width: 100%; + `, + colorPickerAxisSwitchLabel: css` + display: flex; + flex-grow: 1; + `, + }; +}; diff --git a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.story.tsx b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.story.tsx new file mode 100644 index 00000000..dc6713e3 --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.story.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import SpectrumPalette from './SpectrumPalette'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { UseState } from '../../utils/storybook/UseState'; +import { renderComponentWithTheme } from '../../utils/storybook/withTheme'; +import mdx from './ColorPicker.mdx'; + +export default { + title: 'Pickers and Editors/ColorPicker/Palettes/SpectrumPalette', + component: SpectrumPalette, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const simple = () => { + return ( + + {(selectedColor, updateSelectedColor) => { + return renderComponentWithTheme(SpectrumPalette, { color: selectedColor, onChange: updateSelectedColor }); + }} + + ); +}; diff --git a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx new file mode 100644 index 00000000..3b6a7ca5 --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx @@ -0,0 +1,76 @@ +import React, { useMemo, useState } from 'react'; + +import { RgbaStringColorPicker } from 'react-colorful'; +import tinycolor from 'tinycolor2'; +import ColorInput from './ColorInput'; +import { GrafanaTheme2, colorManipulator } from '@grafana/data'; +import { css, cx } from '@emotion/css'; +import { useStyles2, useTheme2 } from '../../themes'; +import { useThrottleFn } from 'react-use'; + +export interface SpectrumPaletteProps { + color: string; + onChange: (color: string) => void; +} + +const SpectrumPalette: React.FunctionComponent = ({ color, onChange }) => { + const [currentColor, setColor] = useState(color); + + useThrottleFn( + (c) => { + onChange(colorManipulator.asHexString(theme.visualization.getColorByName(c))); + }, + 500, + [currentColor] + ); + + const theme = useTheme2(); + const styles = useStyles2(getStyles); + + const rgbaString = useMemo(() => { + return currentColor.startsWith('rgba') + ? currentColor + : tinycolor(theme.visualization.getColorByName(color)).toRgbString(); + }, [currentColor, theme, color]); + + return ( +
+ + +
+ ); +}; + +const getStyles = (theme: GrafanaTheme2) => ({ + wrapper: css` + flex-grow: 1; + `, + root: css` + &.react-colorful { + width: auto; + } + + .react-colorful { + &__saturation { + border-radius: ${theme.v1.border.radius.sm} ${theme.v1.border.radius.sm} 0 0; + } + &__alpha { + border-radius: 0 0 ${theme.v1.border.radius.sm} ${theme.v1.border.radius.sm}; + } + &__alpha, + &__hue { + height: ${theme.spacing(2)}; + position: relative; + } + &__pointer { + height: ${theme.spacing(2)}; + width: ${theme.spacing(2)}; + } + } + `, + colorInput: css` + margin-top: ${theme.spacing(2)}; + `, +}); + +export default SpectrumPalette; diff --git a/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts b/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts new file mode 100644 index 00000000..145cf5d5 --- /dev/null +++ b/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts @@ -0,0 +1,9 @@ +import { deprecationWarning } from '@grafana/data'; +import { ColorPickerProps } from './ColorPickerPopover'; + +export const warnAboutColorPickerPropsDeprecation = (componentName: string, props: ColorPickerProps) => { + const { onColorChange } = props; + if (onColorChange) { + deprecationWarning(componentName, 'onColorChange', 'onChange'); + } +}; diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.mdx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.mdx new file mode 100644 index 00000000..fb42bf4b --- /dev/null +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.mdx @@ -0,0 +1,32 @@ +import { Meta, Props } from '@storybook/addon-docs/blocks'; +import { ConfirmButton } from './ConfirmButton'; + + + +# ConfirmButton + +The ConfirmButton is an interactive component that adds a double-confirm option to a clickable action. When clicked, the action is replaced by an inline confirmation with the option to cancel. In Grafana, this is used, for example, for editing values in settings tables. + +## Variants + +There are four variants of the `ConfirmButton`: primary, secondary, destructive, and link. The primary and secondary variants include a primary or secondary `Button` component. The primary and secondary variant should be used to confirm actions like saving or adding data. The destructive variant includes a destructive `Button` component. The destructive variant should be used to double-confirm a deletion or removal of an element. The link variant doesn't include any button and double-confirms as links instead. + +Apart from the button variant, you can also modify the button size and the button text. + +## Usage + +```jsx + { + console.log('Action confirmed!'); + }} +> + Click me + +``` + + diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx new file mode 100644 index 00000000..cdf99180 --- /dev/null +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx @@ -0,0 +1,93 @@ +import React from 'react'; +import { Meta, Story } from '@storybook/react'; +import { ConfirmButton } from '@grafana/ui'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { action } from '@storybook/addon-actions'; +import { Button } from '../Button'; +import { DeleteButton } from './DeleteButton'; +import { Props } from './ConfirmButton'; +import mdx from './ConfirmButton.mdx'; + +export default { + title: 'Buttons/ConfirmButton', + component: ConfirmButton, + decorators: [withCenteredStory], + subcomponents: { DeleteButton }, + parameters: { + docs: { + page: mdx, + }, + controls: { + exclude: ['className', 'onClick', 'onCancel', 'onConfirm'], + }, + }, + args: { + buttonText: 'Edit', + confirmText: 'Save', + size: 'md', + confirmVariant: 'primary', + disabled: false, + closeOnConfirm: true, + }, + argTypes: { + confirmVariant: { + control: { + type: 'select', + }, + options: ['primary', 'secondary', 'destructive', 'link'], + }, + size: { control: { type: 'select' }, options: ['xs', 'sm', 'md', 'lg'] }, + }, +} as Meta; + +interface StoryProps extends Partial { + buttonText: string; +} + +export const Basic: Story = (args) => { + return ( + { + action('Saved')('save!'); + }} + > + {args.buttonText} + + ); +}; + +export const WithCustomButton: Story = (args) => { + return ( + { + action('Saved')('save!'); + }} + > + + + ); +}; + +export const Delete: Story = (args) => { + return ( + { + action('Deleted')('delete!'); + }} + /> + ); +}; diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx new file mode 100644 index 00000000..e3117ec9 --- /dev/null +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { ConfirmButton } from './ConfirmButton'; +import { mount, ShallowWrapper } from 'enzyme'; +import { Button } from '../Button'; + +describe('ConfirmButton', () => { + let wrapper: any; + let deleted: any; + + beforeAll(() => { + deleted = false; + + function deleteItem() { + deleted = true; + } + + wrapper = mount( + deleteItem()}> + Delete + + ); + }); + + it('should show confirm delete when clicked', () => { + expect(deleted).toBe(false); + wrapper + .find(Button) + .findWhere((n: ShallowWrapper) => { + return n.text() === 'Confirm delete' && n.type() === Button; + }) + .simulate('click'); + expect(deleted).toBe(true); + }); +}); diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx new file mode 100644 index 00000000..d41edf0b --- /dev/null +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx @@ -0,0 +1,200 @@ +import React, { PureComponent, SyntheticEvent } from 'react'; +import { cx, css } from '@emotion/css'; +import { stylesFactory, withTheme } from '../../themes'; +import { GrafanaTheme } from '@grafana/data'; +import { Themeable } from '../../types'; +import { ComponentSize } from '../../types/size'; +import { Button, ButtonVariant } from '../Button'; + +export interface Props extends Themeable { + /** Confirm action callback */ + onConfirm(): void; + /** Custom button styles */ + className?: string; + /** Button size */ + size?: ComponentSize; + /** Text for the Confirm button */ + confirmText?: string; + /** Disable button click action */ + disabled?: boolean; + /** Variant of the Confirm button */ + confirmVariant?: ButtonVariant; + /** Hide confirm actions when after of them is clicked */ + closeOnConfirm?: boolean; + /** Move focus to button when mounted */ + autoFocus?: boolean; + + /** Optional on click handler for the original button */ + onClick?(): void; + /** Callback for the cancel action */ + onCancel?(): void; +} + +interface State { + showConfirm: boolean; +} + +class UnThemedConfirmButton extends PureComponent { + mainButtonRef = React.createRef(); + confirmButtonRef = React.createRef(); + state: State = { + showConfirm: false, + }; + + onClickButton = (event: SyntheticEvent) => { + if (event) { + event.preventDefault(); + } + + this.setState( + { + showConfirm: true, + }, + () => { + if (this.props.autoFocus && this.confirmButtonRef.current) { + this.confirmButtonRef.current.focus(); + } + } + ); + + if (this.props.onClick) { + this.props.onClick(); + } + }; + + onClickCancel = (event: SyntheticEvent) => { + if (event) { + event.preventDefault(); + } + this.setState( + { + showConfirm: false, + }, + () => { + this.mainButtonRef.current?.focus(); + } + ); + if (this.props.onCancel) { + this.props.onCancel(); + } + }; + onConfirm = (event: SyntheticEvent) => { + if (event) { + event.preventDefault(); + } + this.props.onConfirm(); + if (this.props.closeOnConfirm) { + this.setState({ + showConfirm: false, + }); + } + }; + + render() { + const { + theme, + className, + size, + disabled, + confirmText, + confirmVariant: confirmButtonVariant, + children, + } = this.props; + const styles = getStyles(theme); + const buttonClass = cx( + className, + this.state.showConfirm ? styles.buttonHide : styles.buttonShow, + disabled && styles.buttonDisabled + ); + const confirmButtonClass = cx( + styles.confirmButton, + this.state.showConfirm ? styles.confirmButtonShow : styles.confirmButtonHide + ); + + const onClick = disabled ? () => {} : this.onClickButton; + + return ( + + {typeof children === 'string' ? ( + + + + ) : ( + + {children} + + )} + + + + + + ); + } +} + +export const ConfirmButton = withTheme(UnThemedConfirmButton); + +const getStyles = stylesFactory((theme: GrafanaTheme) => { + return { + buttonContainer: css` + display: flex; + align-items: center; + justify-content: flex-end; + `, + buttonDisabled: css` + text-decoration: none; + color: ${theme.colors.text}; + opacity: 0.65; + cursor: not-allowed; + pointer-events: none; + `, + buttonShow: css` + opacity: 1; + transition: opacity 0.1s ease; + z-index: 2; + `, + buttonHide: css` + opacity: 0; + transition: opacity 0.1s ease, visibility 0 0.1s; + visibility: hidden; + z-index: 0; + `, + confirmButton: css` + align-items: flex-start; + background: ${theme.colors.bg1}; + display: flex; + position: absolute; + pointer-events: none; + `, + confirmButtonShow: css` + z-index: 1; + opacity: 1; + transition: opacity 0.08s ease-out, transform 0.1s ease-out; + transform: translateX(0); + pointer-events: all; + `, + confirmButtonHide: css` + opacity: 0; + visibility: hidden; + transition: opacity 0.12s ease-in, transform 0.14s ease-in, visibility 0s 0.12s; + transform: translateX(100px); + `, + }; +}); + +// Declare defaultProps directly on the themed component so they are displayed +// in the props table +ConfirmButton.defaultProps = { + size: 'md', + confirmText: 'Save', + disabled: false, + confirmVariant: 'primary', +}; +ConfirmButton.displayName = 'ConfirmButton'; diff --git a/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx b/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx new file mode 100644 index 00000000..f383a31e --- /dev/null +++ b/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx @@ -0,0 +1,28 @@ +import React, { FC } from 'react'; +import { ConfirmButton } from './ConfirmButton'; +import { ComponentSize } from '../../types/size'; +import { Button } from '../Button'; + +export interface Props { + /** Confirm action callback */ + onConfirm(): void; + /** Button size */ + size?: ComponentSize; + /** Disable button click action */ + disabled?: boolean; + 'aria-label'?: string; +} + +export const DeleteButton: FC = ({ size, disabled, onConfirm, 'aria-label': ariaLabel }) => { + return ( + + + + {onAlternative ? ( + + ) : null} + + + ); +}; + +const getStyles = (theme: GrafanaTheme2) => ({ + modal: css` + width: 500px; + `, + modalText: css({ + fontSize: theme.typography.h5.fontSize, + color: theme.colors.text.primary, + }), + modalDescription: css({ + fontSize: theme.typography.body.fontSize, + }), + modalConfirmationInput: css({ + paddingTop: theme.spacing(1), + }), +}); diff --git a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.mdx b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.mdx new file mode 100644 index 00000000..81003e07 --- /dev/null +++ b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.mdx @@ -0,0 +1,38 @@ +import { Props } from '@storybook/addon-docs/blocks'; +import { ContextMenu } from './ContextMenu'; +import { WithContextMenu } from './WithContextMenu'; + +# ContextMenu + +A menu displaying additional options when it's not possible to show them at all times due to a space constraint. + +### Usage + +There are controlled and uncontrolled versions of the component available. With the controlled component (`ContextMenu`) the open/close logic needs to be handled separately. Uncontrolled component (`WithContextMenu`) handles this logic internally. + +#### Controlled component + +```jsx + {}} + items={[{ label: 'Test', items: [{ label: 'First' }, { label: 'Second' }] }]} +/> +``` + +#### Uncontrolled component + +```jsx + [{ label: 'Test', items: [{ label: 'First' }, { label: 'Second' }] }]}> + {({ openMenu }) => } + +``` + +### Props of ContextMenu + + + +### Props of WithContextMenu + + diff --git a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.story.tsx b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.story.tsx new file mode 100644 index 00000000..edcc1948 --- /dev/null +++ b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.story.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { IconButton } from '../IconButton/IconButton'; +import { ContextMenu } from './ContextMenu'; +import { WithContextMenu } from './WithContextMenu'; +import mdx from './ContextMenu.mdx'; +import { MenuGroup } from '../Menu/MenuGroup'; +import { MenuItem } from '../Menu/MenuItem'; + +export default { + title: 'General/ContextMenu', + component: ContextMenu, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + }, +}; + +const menuItems = [ + { + label: 'Test', + items: [ + { label: 'First', ariaLabel: 'First' }, + { label: 'Second', ariaLabel: 'Second' }, + { label: 'Third', ariaLabel: 'Third' }, + { label: 'Fourth', ariaLabel: 'Fourth' }, + { label: 'Fifth', ariaLabel: 'Fifth' }, + ], + }, +]; + +const renderMenuItems = () => { + return menuItems.map((group, index) => ( + + {group.items.map((item) => ( + + ))} + + )); +}; + +export const Basic = () => { + return {}} renderMenuItems={renderMenuItems} />; +}; + +export const WithState = () => { + return ( + + {({ openMenu }) => } + + ); +}; diff --git a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx new file mode 100644 index 00000000..369782f4 --- /dev/null +++ b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx @@ -0,0 +1,77 @@ +import React, { useRef, useState, useLayoutEffect } from 'react'; +import { selectors } from '@grafana/e2e-selectors'; +import { useClickAway } from 'react-use'; +import { Portal } from '../Portal/Portal'; +import { Menu } from '../Menu/Menu'; + +export interface ContextMenuProps { + /** Starting horizontal position for the menu */ + x: number; + /** Starting vertical position for the menu */ + y: number; + /** Callback for closing the menu */ + onClose?: () => void; + /** RenderProp function that returns menu items to display */ + renderMenuItems?: () => React.ReactNode; + /** A function that returns header element */ + renderHeader?: () => React.ReactNode; +} + +export const ContextMenu: React.FC = React.memo( + ({ x, y, onClose, renderMenuItems, renderHeader }) => { + const menuRef = useRef(null); + const [positionStyles, setPositionStyles] = useState({}); + + useLayoutEffect(() => { + const menuElement = menuRef.current; + if (menuElement) { + const rect = menuElement.getBoundingClientRect(); + const OFFSET = 5; + const collisions = { + right: window.innerWidth < x + rect.width, + bottom: window.innerHeight < rect.bottom + rect.height + OFFSET, + }; + + setPositionStyles({ + position: 'fixed', + left: collisions.right ? x - rect.width - OFFSET : x - OFFSET, + top: collisions.bottom ? y - rect.height - OFFSET : y + OFFSET, + }); + } + }, [x, y]); + + useClickAway(menuRef, () => { + onClose?.(); + }); + const header = renderHeader?.(); + const menuItems = renderMenuItems?.(); + const onOpen = (setFocusedItem: (a: number) => void) => { + setFocusedItem(0); + }; + const onKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Escape') { + e.preventDefault(); + e.stopPropagation(); + onClose?.(); + } + }; + + return ( + + + {menuItems} + + + ); + } +); + +ContextMenu.displayName = 'ContextMenu'; diff --git a/packages/grafana-ui/src/components/ContextMenu/WithContextMenu.tsx b/packages/grafana-ui/src/components/ContextMenu/WithContextMenu.tsx new file mode 100644 index 00000000..f7c69446 --- /dev/null +++ b/packages/grafana-ui/src/components/ContextMenu/WithContextMenu.tsx @@ -0,0 +1,36 @@ +import React, { useState } from 'react'; +import { ContextMenu } from '../ContextMenu/ContextMenu'; + +interface WithContextMenuProps { + /** Menu item trigger that accepts openMenu prop */ + children: (props: { openMenu: React.MouseEventHandler }) => JSX.Element; + /** A function that returns an array of menu items */ + renderMenuItems: () => React.ReactNode; +} + +export const WithContextMenu: React.FC = ({ children, renderMenuItems }) => { + const [isMenuOpen, setIsMenuOpen] = useState(false); + const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 }); + return ( + <> + {children({ + openMenu: (e) => { + setIsMenuOpen(true); + setMenuPosition({ + x: e.pageX, + y: e.pageY, + }); + }, + })} + + {isMenuOpen && ( + setIsMenuOpen(false)} + x={menuPosition.x} + y={menuPosition.y} + renderMenuItems={renderMenuItems} + /> + )} + + ); +}; diff --git a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.test.tsx b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.test.tsx new file mode 100644 index 00000000..32375a5d --- /dev/null +++ b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.test.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import { CustomScrollbar } from './CustomScrollbar'; + +describe('CustomScrollbar', () => { + it('renders correctly', () => { + const tree = renderer + .create( + +

Scrollable content

+
+ ) + .toJSON(); + expect(tree).toMatchSnapshot(); + }); +}); diff --git a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx new file mode 100644 index 00000000..fa228b87 --- /dev/null +++ b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx @@ -0,0 +1,189 @@ +import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import classNames from 'classnames'; +import { isNil } from 'lodash'; +import React, { FC, RefCallback, useCallback, useEffect, useRef } from 'react'; +import Scrollbars, { positionValues } from 'react-custom-scrollbars-2'; +import { useStyles2 } from '../../themes'; + +export type ScrollbarPosition = positionValues; + +interface Props { + className?: string; + autoHide?: boolean; + autoHideTimeout?: number; + autoHeightMax?: string; + hideTracksWhenNotNeeded?: boolean; + hideHorizontalTrack?: boolean; + hideVerticalTrack?: boolean; + scrollRefCallback?: RefCallback; + scrollTop?: number; + setScrollTop?: (position: ScrollbarPosition) => void; + autoHeightMin?: number | string; + updateAfterMountMs?: number; +} + +/** + * Wraps component into component from `react-custom-scrollbars` + */ +export const CustomScrollbar: FC = ({ + autoHide = false, + autoHideTimeout = 200, + setScrollTop, + className, + autoHeightMin = '0', + autoHeightMax = '100%', + hideTracksWhenNotNeeded = false, + hideHorizontalTrack, + hideVerticalTrack, + scrollRefCallback, + updateAfterMountMs, + scrollTop, + children, +}) => { + const ref = useRef(null); + useEffect(() => { + if (ref.current) { + scrollRefCallback?.(ref.current.view); + } + }, [ref, scrollRefCallback]); + const styles = useStyles2(getStyles); + + const updateScroll = () => { + if (ref.current && !isNil(scrollTop)) { + ref.current.scrollTop(scrollTop); + } + }; + + useEffect(() => { + updateScroll(); + }); + + /** + * Special logic for doing a update a few milliseconds after mount to check for + * updated height due to dynamic content + */ + + useEffect(() => { + if (!updateAfterMountMs) { + return; + } + setTimeout(() => { + const scrollbar = ref.current as any; + if (scrollbar?.update) { + scrollbar.update(); + } + }, updateAfterMountMs); + }, [updateAfterMountMs]); + + function renderTrack(className: string, hideTrack: boolean | undefined, passedProps: any) { + if (passedProps.style && hideTrack) { + passedProps.style.display = 'none'; + } + + return
; + } + + const renderTrackHorizontal = useCallback( + (passedProps: any) => { + return renderTrack('track-horizontal', hideHorizontalTrack, passedProps); + }, + [hideHorizontalTrack] + ); + + const renderTrackVertical = useCallback( + (passedProps: any) => { + return renderTrack('track-vertical', hideVerticalTrack, passedProps); + }, + [hideVerticalTrack] + ); + + const renderThumbHorizontal = useCallback((passedProps: any) => { + return
; + }, []); + + const renderThumbVertical = useCallback((passedProps: any) => { + return
; + }, []); + + const renderView = useCallback((passedProps: any) => { + return
; + }, []); + + const onScrollStop = useCallback(() => { + ref.current && setScrollTop && setScrollTop(ref.current.getValues()); + }, [setScrollTop]); + + return ( + + {children} + + ); +}; + +export default CustomScrollbar; + +const getStyles = (theme: GrafanaTheme2) => { + return { + customScrollbar: css` + // Fix for Firefox. For some reason sometimes .view container gets a height of its content, but in order to + // make scroll working it should fit outer container size (scroll appears only when inner container size is + // greater than outer one). + display: flex; + flex-grow: 1; + .scrollbar-view { + display: flex; + flex-grow: 1; + flex-direction: column; + } + .track-vertical { + border-radius: ${theme.shape.borderRadius(2)}; + width: ${theme.spacing(1)} !important; + right: 0px; + bottom: ${theme.spacing(0.25)}; + top: ${theme.spacing(0.25)}; + } + .track-horizontal { + border-radius: ${theme.shape.borderRadius(2)}; + height: ${theme.spacing(1)} !important; + right: ${theme.spacing(0.25)}; + bottom: ${theme.spacing(0.25)}; + left: ${theme.spacing(0.25)}; + } + .thumb-vertical { + background: ${theme.colors.action.focus}; + border-radius: ${theme.shape.borderRadius(2)}; + opacity: 0; + } + .thumb-horizontal { + background: ${theme.colors.action.focus}; + border-radius: ${theme.shape.borderRadius(2)}; + opacity: 0; + } + &:hover { + .thumb-vertical, + .thumb-horizontal { + opacity: 1; + transition: opacity 0.3s ease-in-out; + } + } + `, + }; +}; diff --git a/packages/grafana-ui/src/components/CustomScrollbar/__snapshots__/CustomScrollbar.test.tsx.snap b/packages/grafana-ui/src/components/CustomScrollbar/__snapshots__/CustomScrollbar.test.tsx.snap new file mode 100644 index 00000000..6011fd4d --- /dev/null +++ b/packages/grafana-ui/src/components/CustomScrollbar/__snapshots__/CustomScrollbar.test.tsx.snap @@ -0,0 +1,82 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CustomScrollbar renders correctly 1`] = ` +
+
+

+ Scrollable content +

+
+
+
+
+
+
+
+
+`; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkButton.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkButton.tsx new file mode 100644 index 00000000..95d8b8d4 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkButton.tsx @@ -0,0 +1,35 @@ +import { Field, LinkModel } from '@grafana/data'; +import React from 'react'; +import { ButtonProps, Button } from '../Button'; + +type DataLinkButtonProps = { + link: LinkModel; + buttonProps?: ButtonProps; +}; + +/** + * @internal + */ +export function DataLinkButton({ link, buttonProps }: DataLinkButtonProps) { + return ( + { + if (!(event.ctrlKey || event.metaKey || event.shiftKey) && link.onClick) { + event.preventDefault(); + link.onClick(event); + } + } + : undefined + } + > + + + ); +} diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx new file mode 100644 index 00000000..b433d029 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx @@ -0,0 +1,69 @@ +import React, { ChangeEvent } from 'react'; +import { VariableSuggestion, GrafanaTheme2, DataLink } from '@grafana/data'; +import { Switch } from '../Switch/Switch'; +import { css } from '@emotion/css'; +import { useStyles2 } from '../../themes/index'; +import { DataLinkInput } from './DataLinkInput'; +import { Field } from '../Forms/Field'; +import { Input } from '../Input/Input'; + +interface DataLinkEditorProps { + index: number; + isLast: boolean; + value: DataLink; + suggestions: VariableSuggestion[]; + onChange: (index: number, link: DataLink, callback?: () => void) => void; +} + +const getStyles = (theme: GrafanaTheme2) => ({ + listItem: css` + margin-bottom: ${theme.spacing()}; + `, + infoText: css` + padding-bottom: ${theme.spacing(2)}; + margin-left: 66px; + color: ${theme.colors.text.secondary}; + `, +}); + +export const DataLinkEditor: React.FC = React.memo( + ({ index, value, onChange, suggestions, isLast }) => { + const styles = useStyles2(getStyles); + + const onUrlChange = (url: string, callback?: () => void) => { + onChange(index, { ...value, url }, callback); + }; + const onTitleChange = (event: ChangeEvent) => { + onChange(index, { ...value, title: event.target.value }); + }; + + const onOpenInNewTabChanged = () => { + onChange(index, { ...value, targetBlank: !value.targetBlank }); + }; + + return ( +
+ + + + + + + + + + + + + {isLast && ( +
+ With data links you can reference data variables like series name, labels and values. Type CMD+Space, + CTRL+Space, or $ to open variable suggestions. +
+ )} +
+ ); + } +); + +DataLinkEditor.displayName = 'DataLinkEditor'; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx new file mode 100644 index 00000000..011da4b4 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx @@ -0,0 +1,227 @@ +import React, { memo, RefObject, useEffect, useMemo, useRef, useState } from 'react'; +import usePrevious from 'react-use/lib/usePrevious'; +import { DataLinkSuggestions } from './DataLinkSuggestions'; +import { makeValue } from '../../index'; +import { SelectionReference } from './SelectionReference'; +import { Portal } from '../index'; + +// @ts-ignore +import Prism, { Grammar, LanguageMap } from 'prismjs'; +import { Editor } from '@grafana/slate-react'; +import { Value } from 'slate'; +import Plain from 'slate-plain-serializer'; +import { Popper as ReactPopper } from 'react-popper'; +import { css, cx } from '@emotion/css'; + +import { SlatePrism } from '../../slate-plugins'; +import { SCHEMA } from '../../utils/slate'; +import { useStyles2 } from '../../themes'; +import { DataLinkBuiltInVars, GrafanaTheme2, VariableOrigin, VariableSuggestion } from '@grafana/data'; +import { getInputStyles } from '../Input/Input'; +import CustomScrollbar from '../CustomScrollbar/CustomScrollbar'; + +const modulo = (a: number, n: number) => a - n * Math.floor(a / n); + +interface DataLinkInputProps { + value: string; + onChange: (url: string, callback?: () => void) => void; + suggestions: VariableSuggestion[]; + placeholder?: string; +} + +const datalinksSyntax: Grammar = { + builtInVariable: { + pattern: /(\${\S+?})/, + }, +}; + +const plugins = [ + SlatePrism( + { + onlyIn: (node: any) => node.type === 'code_block', + getSyntax: () => 'links', + }, + { ...(Prism.languages as LanguageMap), links: datalinksSyntax } + ), +]; + +const getStyles = (theme: GrafanaTheme2) => ({ + input: getInputStyles({ theme, invalid: false }).input, + editor: css` + .token.builtInVariable { + color: ${theme.colors.success.text}; + } + .token.variable { + color: ${theme.colors.primary.text}; + } + `, + suggestionsWrapper: css` + box-shadow: ${theme.shadows.z2}; + `, + // Wrapper with child selector needed. + // When classnames are applied to the same element as the wrapper, it causes the suggestions to stop working + wrapperOverrides: css` + width: 100%; + > .slate-query-field__wrapper { + padding: 0; + background-color: transparent; + border: none; + } + `, +}); + +// This memoised also because rerendering the slate editor grabs focus which created problem in some cases this +// was used and changes to different state were propagated here. +export const DataLinkInput: React.FC = memo( + ({ value, onChange, suggestions, placeholder = 'http://your-grafana.com/d/000000010/annotations' }) => { + const editorRef = useRef() as RefObject; + const styles = useStyles2(getStyles); + const [showingSuggestions, setShowingSuggestions] = useState(false); + const [suggestionsIndex, setSuggestionsIndex] = useState(0); + const [linkUrl, setLinkUrl] = useState(makeValue(value)); + const prevLinkUrl = usePrevious(linkUrl); + + // Workaround for https://github.com/ianstormtaylor/slate/issues/2927 + const stateRef = useRef({ showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange }); + stateRef.current = { showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange }; + + // Used to get the height of the suggestion elements in order to scroll to them. + const activeRef = useRef(null); + const activeIndexPosition = useMemo(() => getElementPosition(activeRef.current, suggestionsIndex), [ + suggestionsIndex, + ]); + + // SelectionReference is used to position the variables suggestion relatively to current DOM selection + const selectionRef = useMemo(() => new SelectionReference(), []); + + const onKeyDown = React.useCallback((event: KeyboardEvent, next: () => any) => { + if (!stateRef.current.showingSuggestions) { + if (event.key === '=' || event.key === '$' || (event.keyCode === 32 && event.ctrlKey)) { + return setShowingSuggestions(true); + } + return next(); + } + + switch (event.key) { + case 'Backspace': + case 'Escape': + setShowingSuggestions(false); + return setSuggestionsIndex(0); + + case 'Enter': + event.preventDefault(); + return onVariableSelect(stateRef.current.suggestions[stateRef.current.suggestionsIndex]); + + case 'ArrowDown': + case 'ArrowUp': + event.preventDefault(); + const direction = event.key === 'ArrowDown' ? 1 : -1; + return setSuggestionsIndex((index) => modulo(index + direction, stateRef.current.suggestions.length)); + default: + return next(); + } + }, []); + + useEffect(() => { + // Update the state of the link in the parent. This is basically done on blur but we need to do it after + // our state have been updated. The duplicity of state is done for perf reasons and also because local + // state also contains things like selection and formating. + if (prevLinkUrl && prevLinkUrl.selection.isFocused && !linkUrl.selection.isFocused) { + stateRef.current.onChange(Plain.serialize(linkUrl)); + } + }, [linkUrl, prevLinkUrl]); + + const onUrlChange = React.useCallback(({ value }: { value: Value }) => { + setLinkUrl(value); + }, []); + + const onVariableSelect = (item: VariableSuggestion, editor = editorRef.current!) => { + const includeDollarSign = Plain.serialize(editor.value).slice(-1) !== '$'; + if (item.origin !== VariableOrigin.Template || item.value === DataLinkBuiltInVars.includeVars) { + editor.insertText(`${includeDollarSign ? '$' : ''}\{${item.value}}`); + } else { + editor.insertText(`\${${item.value}:queryparam}`); + } + + setLinkUrl(editor.value); + setShowingSuggestions(false); + + setSuggestionsIndex(0); + stateRef.current.onChange(Plain.serialize(editor.value)); + }; + + return ( +
+
+
+ {showingSuggestions && ( + + + {({ ref, style, placement }) => { + return ( +
+ + setShowingSuggestions(false)} + activeIndex={suggestionsIndex} + /> + +
+ ); + }} +
+
+ )} + onKeyDown(event as KeyboardEvent, next)} + plugins={plugins} + className={cx( + styles.editor, + styles.input, + css` + padding: 3px 8px; + ` + )} + /> +
+
+
+ ); + } +); + +DataLinkInput.displayName = 'DataLinkInput'; + +function getElementPosition(suggestionElement: HTMLElement | null, activeIndex: number) { + return (suggestionElement?.clientHeight ?? 0) * activeIndex; +} diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx new file mode 100644 index 00000000..e3dff496 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx @@ -0,0 +1,137 @@ +import { VariableSuggestion, GrafanaTheme2 } from '@grafana/data'; +import { css, cx } from '@emotion/css'; +import { groupBy, capitalize } from 'lodash'; +import React, { useRef, useMemo } from 'react'; +import useClickAway from 'react-use/lib/useClickAway'; +import { List } from '../index'; +import { useStyles2 } from '../../themes'; + +interface DataLinkSuggestionsProps { + activeRef?: React.RefObject; + suggestions: VariableSuggestion[]; + activeIndex: number; + onSuggestionSelect: (suggestion: VariableSuggestion) => void; + onClose?: () => void; +} + +const getStyles = (theme: GrafanaTheme2) => { + return { + list: css` + border-bottom: 1px solid ${theme.colors.border.weak}; + &:last-child { + border: none; + } + `, + wrapper: css` + background: ${theme.colors.background.primary}; + width: 250px; + `, + item: css` + background: none; + padding: 2px 8px; + color: ${theme.colors.text.primary}; + cursor: pointer; + &:hover { + background: ${theme.colors.action.hover}; + } + `, + label: css` + color: ${theme.colors.text.secondary}; + `, + activeItem: css` + background: ${theme.colors.background.secondary}; + &:hover { + background: ${theme.colors.background.secondary}; + } + `, + itemValue: css` + font-family: ${theme.typography.fontFamilyMonospace}; + font-size: ${theme.typography.size.sm}; + `, + }; +}; + +export const DataLinkSuggestions: React.FC = ({ suggestions, ...otherProps }) => { + const ref = useRef(null); + + useClickAway(ref, () => { + if (otherProps.onClose) { + otherProps.onClose(); + } + }); + + const groupedSuggestions = useMemo(() => { + return groupBy(suggestions, (s) => s.origin); + }, [suggestions]); + + const styles = useStyles2(getStyles); + + return ( +
+ {Object.keys(groupedSuggestions).map((key, i) => { + const indexOffset = + i === 0 + ? 0 + : Object.keys(groupedSuggestions).reduce((acc, current, index) => { + if (index >= i) { + return acc; + } + return acc + groupedSuggestions[current].length; + }, 0); + + return ( + + ); + })} +
+ ); +}; + +DataLinkSuggestions.displayName = 'DataLinkSuggestions'; + +interface DataLinkSuggestionsListProps extends DataLinkSuggestionsProps { + label: string; + activeIndexOffset: number; + activeRef?: React.RefObject; +} + +const DataLinkSuggestionsList: React.FC = React.memo( + ({ activeIndex, activeIndexOffset, label, onClose, onSuggestionSelect, suggestions, activeRef: selectedRef }) => { + const styles = useStyles2(getStyles); + + return ( + <> + { + const isActive = index + activeIndexOffset === activeIndex; + return ( +
{ + onSuggestionSelect(item); + }} + title={item.documentation} + > + + {label} {item.label} + +
+ ); + }} + /> + + ); + } +); + +DataLinkSuggestionsList.displayName = 'DataLinkSuggestionsList'; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.test.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.test.tsx new file mode 100644 index 00000000..9ac75b37 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.test.tsx @@ -0,0 +1,77 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataLinksContextMenu } from './DataLinksContextMenu'; +import { selectors } from '@grafana/e2e-selectors'; + +const fakeAriaLabel = 'fake aria label'; +describe('DataLinksContextMenu', () => { + it('renders context menu when there are more than one data links', () => { + render( + [ + { + href: '/link1', + title: 'Link1', + target: '_blank', + origin: {}, + }, + { + href: '/link2', + title: 'Link2', + target: '_blank', + origin: {}, + }, + ]} + config={{ + links: [ + { + title: 'Link1', + url: '/link1', + }, + { + title: 'Link2', + url: '/link2', + }, + ], + }} + > + {() => { + return
; + }} + + ); + + expect(screen.getByLabelText(fakeAriaLabel)).toBeInTheDocument(); + expect(screen.queryAllByLabelText(selectors.components.DataLinksContextMenu.singleLink)).toHaveLength(0); + }); + + it('renders link when there is a single data link', () => { + render( + [ + { + href: '/link1', + title: 'Link1', + target: '_blank', + origin: {}, + }, + ]} + config={{ + links: [ + { + title: 'Link1', + url: '/link1', + }, + ], + }} + > + {() => { + return
; + }} + + ); + + expect(screen.getByLabelText(fakeAriaLabel)).toBeInTheDocument(); + expect(screen.getByLabelText(selectors.components.DataLinksContextMenu.singleLink)).toBeInTheDocument(); + }); +}); diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx new file mode 100644 index 00000000..7eb4714a --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { FieldConfig, LinkModel } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { css } from '@emotion/css'; +import { WithContextMenu } from '../ContextMenu/WithContextMenu'; +import { linkModelToContextMenuItems } from '../../utils/dataLinks'; +import { MenuGroup, MenuItemsGroup } from '../Menu/MenuGroup'; +import { MenuItem } from '../Menu/MenuItem'; + +interface DataLinksContextMenuProps { + children: (props: DataLinksContextMenuApi) => JSX.Element; + links: () => LinkModel[]; + config: FieldConfig; +} + +export interface DataLinksContextMenuApi { + openMenu?: React.MouseEventHandler; + targetClassName?: string; +} + +export const DataLinksContextMenu: React.FC = ({ children, links, config }) => { + const linksCounter = config.links!.length; + const itemsGroup: MenuItemsGroup[] = [{ items: linkModelToContextMenuItems(links), label: 'Data links' }]; + const renderMenuGroupItems = () => { + return itemsGroup.map((group, index) => ( + + {(group.items || []).map((item) => ( + + ))} + + )); + }; + + // Use this class name (exposed via render prop) to add context menu indicator to the click target of the visualization + const targetClassName = css` + cursor: context-menu; + `; + + if (linksCounter > 1) { + return ( + + {({ openMenu }) => { + return children({ openMenu, targetClassName }); + }} + + ); + } else { + const linkModel = links()[0]; + return ( + + {children({})} + + ); + } +}; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx new file mode 100644 index 00000000..3d3a25fd --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx @@ -0,0 +1,49 @@ +import { DataFrame, DataLink, VariableSuggestion } from '@grafana/data'; +import React, { FC, useState } from 'react'; +import { DataLinkEditor } from '../DataLinkEditor'; +import { Button } from '../../Button'; +import { Modal } from '../../Modal/Modal'; + +interface DataLinkEditorModalContentProps { + link: DataLink; + index: number; + data: DataFrame[]; + getSuggestions: () => VariableSuggestion[]; + onSave: (index: number, ink: DataLink) => void; + onCancel: (index: number) => void; +} + +export const DataLinkEditorModalContent: FC = ({ + link, + index, + getSuggestions, + onSave, + onCancel, +}) => { + const [dirtyLink, setDirtyLink] = useState(link); + return ( + <> + { + setDirtyLink(link); + }} + /> + + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx new file mode 100644 index 00000000..c4e56940 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx @@ -0,0 +1,121 @@ +import { DataFrame, DataLink, GrafanaTheme2, VariableSuggestion } from '@grafana/data'; +import React, { useState } from 'react'; +import { css } from '@emotion/css'; +import { Button } from '../../Button/Button'; +import { cloneDeep } from 'lodash'; +import { Modal } from '../../Modal/Modal'; +import { stylesFactory, useTheme2 } from '../../../themes'; +import { DataLinksListItem } from './DataLinksListItem'; +import { DataLinkEditorModalContent } from './DataLinkEditorModalContent'; + +interface DataLinksInlineEditorProps { + links?: DataLink[]; + onChange: (links: DataLink[]) => void; + getSuggestions: () => VariableSuggestion[]; + data: DataFrame[]; +} + +export const DataLinksInlineEditor: React.FC = ({ + links, + onChange, + getSuggestions, + data, +}) => { + const theme = useTheme2(); + const [editIndex, setEditIndex] = useState(null); + const [isNew, setIsNew] = useState(false); + + const styles = getDataLinksInlineEditorStyles(theme); + const linksSafe: DataLink[] = links ?? []; + const isEditing = editIndex !== null; + + const onDataLinkChange = (index: number, link: DataLink) => { + if (isNew) { + if (link.title.trim() === '' && link.url.trim() === '') { + setIsNew(false); + setEditIndex(null); + return; + } else { + setEditIndex(null); + setIsNew(false); + } + } + const update = cloneDeep(linksSafe); + update[index] = link; + onChange(update); + setEditIndex(null); + }; + + const onDataLinkAdd = () => { + let update = cloneDeep(linksSafe); + setEditIndex(update.length); + setIsNew(true); + }; + + const onDataLinkCancel = (index: number) => { + if (isNew) { + setIsNew(false); + } + setEditIndex(null); + }; + + const onDataLinkRemove = (index: number) => { + const update = cloneDeep(linksSafe); + update.splice(index, 1); + onChange(update); + }; + + return ( + <> + {linksSafe.length > 0 && ( +
+ {linksSafe.map((l, i) => { + return ( + setEditIndex(i)} + onRemove={() => onDataLinkRemove(i)} + data={data} + /> + ); + })} +
+ )} + + {isEditing && editIndex !== null && ( + { + onDataLinkCancel(editIndex); + }} + > + + + )} + + + + ); +}; + +const getDataLinksInlineEditorStyles = stylesFactory((theme: GrafanaTheme2) => { + return { + wrapper: css` + margin-bottom: ${theme.spacing(2)}; + `, + }; +}); diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.test.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.test.tsx new file mode 100644 index 00000000..850f00b2 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.test.tsx @@ -0,0 +1,103 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataLinksListItem, DataLinksListItemProps } from './DataLinksListItem'; + +const baseLink = { + url: '', + title: '', + onBuildUrl: jest.fn(), + onClick: jest.fn(), +}; + +function setupTestContext(options: Partial) { + const defaults: DataLinksListItemProps = { + index: 0, + link: baseLink, + data: [], + onChange: jest.fn(), + onEdit: jest.fn(), + onRemove: jest.fn(), + }; + + const props = { ...defaults, ...options }; + const { rerender } = render(); + + return { rerender, props }; +} + +describe('DataLinksListItem', () => { + describe('when link has title', () => { + it('then the link title should be visible', () => { + const link = { + ...baseLink, + title: 'Some Data Link Title', + }; + setupTestContext({ link }); + + expect(screen.getByText(/some data link title/i)).toBeInTheDocument(); + }); + }); + + describe('when link has url', () => { + it('then the link url should be visible', () => { + const link = { + ...baseLink, + url: 'http://localhost:3000', + }; + setupTestContext({ link }); + + expect(screen.getByText(/http:\/\/localhost\:3000/i)).toBeInTheDocument(); + expect(screen.getByTitle(/http:\/\/localhost\:3000/i)).toBeInTheDocument(); + }); + }); + + describe('when link is missing title', () => { + it('then the link title should be replaced by [Data link title not provided]', () => { + const link = { + ...baseLink, + title: (undefined as unknown) as string, + }; + setupTestContext({ link }); + + expect(screen.getByText(/data link title not provided/i)).toBeInTheDocument(); + }); + }); + + describe('when link is missing url', () => { + it('then the link url should be replaced by [Data link url not provided]', () => { + const link = { + ...baseLink, + url: (undefined as unknown) as string, + }; + setupTestContext({ link }); + + expect(screen.getByText(/data link url not provided/i)).toBeInTheDocument(); + expect(screen.getByTitle('')).toBeInTheDocument(); + }); + }); + + describe('when link title is empty', () => { + it('then the link title should be replaced by [Data link title not provided]', () => { + const link = { + ...baseLink, + title: ' ', + }; + setupTestContext({ link }); + + expect(screen.getByText(/data link title not provided/i)).toBeInTheDocument(); + }); + }); + + describe('when link url is empty', () => { + it('then the link url should be replaced by [Data link url not provided]', () => { + const link = { + ...baseLink, + url: ' ', + }; + setupTestContext({ link }); + + expect(screen.getByText(/data link url not provided/i)).toBeInTheDocument(); + expect(screen.getByTitle('')).toBeInTheDocument(); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx new file mode 100644 index 00000000..5fc55c31 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx @@ -0,0 +1,72 @@ +import React, { FC } from 'react'; +import { css, cx } from '@emotion/css'; +import { DataFrame, DataLink, GrafanaTheme2 } from '@grafana/data'; +import { stylesFactory, useTheme2 } from '../../../themes'; +import { HorizontalGroup, VerticalGroup } from '../../Layout/Layout'; +import { IconButton } from '../../IconButton/IconButton'; + +export interface DataLinksListItemProps { + index: number; + link: DataLink; + data: DataFrame[]; + onChange: (index: number, link: DataLink) => void; + onEdit: () => void; + onRemove: () => void; + isEditing?: boolean; +} + +export const DataLinksListItem: FC = ({ link, onEdit, onRemove }) => { + const theme = useTheme2(); + const styles = getDataLinkListItemStyles(theme); + const { title = '', url = '' } = link; + + const hasTitle = title.trim() !== ''; + const hasUrl = url.trim() !== ''; + + return ( +
+ + +
+ {hasTitle ? title : 'Data link title not provided'} +
+ + + + +
+
+ {hasUrl ? url : 'Data link url not provided'} +
+
+
+ ); +}; + +const getDataLinkListItemStyles = stylesFactory((theme: GrafanaTheme2) => { + return { + wrapper: css` + margin-bottom: ${theme.spacing(2)}; + width: 100%; + &:last-child { + margin-bottom: 0; + } + `, + notConfigured: css` + font-style: italic; + `, + title: css` + color: ${theme.colors.text.primary}; + font-size: ${theme.typography.size.sm}; + font-weight: ${theme.typography.fontWeightMedium}; + `, + url: css` + color: ${theme.colors.text.secondary}; + font-size: ${theme.typography.size.sm}; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 90%; + `, + }; +}); diff --git a/packages/grafana-ui/src/components/DataLinks/FieldLinkList.tsx b/packages/grafana-ui/src/components/DataLinks/FieldLinkList.tsx new file mode 100644 index 00000000..0124ac5d --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/FieldLinkList.tsx @@ -0,0 +1,71 @@ +import { Field, GrafanaTheme, LinkModel } from '@grafana/data'; +import { css } from '@emotion/css'; +import React from 'react'; +import { useStyles } from '../../themes'; +import { Icon } from '../Icon/Icon'; +import { DataLinkButton } from './DataLinkButton'; + +type Props = { + links: Array>; +}; + +/** + * @internal + */ +export function FieldLinkList({ links }: Props) { + const styles = useStyles(getStyles); + + if (links.length === 1) { + return ; + } + + const externalLinks = links.filter((link) => link.target === '_blank'); + const internalLinks = links.filter((link) => link.target === '_self'); + + return ( + <> + {internalLinks.map((link, i) => { + return ; + })} +
+

External links

+ {externalLinks.map((link, i) => ( + + + {link.title} + + ))} +
+ + ); +} + +const getStyles = (theme: GrafanaTheme) => ({ + wrapper: css` + flex-basis: 150px; + width: 100px; + margin-top: ${theme.spacing.sm}; + `, + externalLinksHeading: css` + color: ${theme.colors.textWeak}; + font-weight: ${theme.typography.weight.regular}; + font-size: ${theme.typography.size.sm}; + margin: 0; + `, + externalLink: css` + color: ${theme.colors.linkExternal}; + font-weight: ${theme.typography.weight.regular}; + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + &:hover { + text-decoration: underline; + } + + div { + margin-right: ${theme.spacing.sm}; + } + `, +}); diff --git a/packages/grafana-ui/src/components/DataLinks/SelectionReference.ts b/packages/grafana-ui/src/components/DataLinks/SelectionReference.ts new file mode 100644 index 00000000..725ec3f2 --- /dev/null +++ b/packages/grafana-ui/src/components/DataLinks/SelectionReference.ts @@ -0,0 +1,30 @@ +import { VirtualElement } from '@popperjs/core/lib/types'; + +export class SelectionReference implements VirtualElement { + getBoundingClientRect() { + const selection = window.getSelection(); + const node = selection && selection.anchorNode; + + if (node && node.parentElement) { + const rect = node.parentElement.getBoundingClientRect(); + return rect; + } + + return { + top: 0, + left: 0, + bottom: 0, + right: 0, + width: 0, + height: 0, + } as DOMRect; + } + + get clientWidth() { + return this.getBoundingClientRect().width; + } + + get clientHeight() { + return this.getBoundingClientRect().height; + } +} diff --git a/packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx new file mode 100644 index 00000000..79135144 --- /dev/null +++ b/packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx @@ -0,0 +1,71 @@ +import { DataSourceInstanceSettings, DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data'; +import React, { useMemo } from 'react'; +import { Switch } from '../Forms/Legacy/Switch/Switch'; +import { InlineField } from '../Forms/InlineField'; +import { InlineFieldRow } from '../Forms/InlineFieldRow'; +import { Select } from '../Select/Select'; + +interface Props extends Pick, 'options' | 'onOptionsChange'> { + alertmanagerDataSources: Array>; +} + +interface AlertingConfig extends DataSourceJsonData { + manageAlerts?: boolean; +} + +export function AlertingSettings({ + alertmanagerDataSources, + options, + onOptionsChange, +}: Props): JSX.Element { + const alertmanagerOptions = useMemo( + () => + alertmanagerDataSources.map((ds) => ({ + label: ds.name, + value: ds.uid, + imgUrl: ds.meta.info.logos.small, + meta: ds.meta, + })), + [alertmanagerDataSources] + ); + + return ( + <> +

Alerting

+
+
+
+ + onOptionsChange({ + ...options, + jsonData: { ...options.jsonData, manageAlerts: event!.currentTarget.checked }, + }) + } + /> +
+
+ + + + + + ) : ( + +
+ +
+ + +
+
+
+ +
+
+
+
+ +
+
+ + +
+
+ +
+
+
+ +
+
+ + +
+
+
+
diff --git a/public/app/angular/promiseToDigest.test.ts b/public/app/angular/promiseToDigest.test.ts new file mode 100644 index 00000000..037dfbb3 --- /dev/null +++ b/public/app/angular/promiseToDigest.test.ts @@ -0,0 +1,27 @@ +import { IScope } from 'angular'; +import { promiseToDigest } from './promiseToDigest'; + +describe('promiseToDigest', () => { + describe('when called with a promise that resolves', () => { + it('then evalAsync should be called on $scope', async () => { + const $scope: IScope = ({ $evalAsync: jest.fn() } as any) as IScope; + + await promiseToDigest($scope)(Promise.resolve(123)); + + expect($scope.$evalAsync).toHaveBeenCalledTimes(1); + }); + }); + + describe('when called with a promise that rejects', () => { + it('then evalAsync should be called on $scope', async () => { + const $scope: IScope = ({ $evalAsync: jest.fn() } as any) as IScope; + + try { + await promiseToDigest($scope)(Promise.reject(123)); + } catch (error) { + expect(error).toEqual(123); + expect($scope.$evalAsync).toHaveBeenCalledTimes(1); + } + }); + }); +}); diff --git a/public/app/angular/promiseToDigest.ts b/public/app/angular/promiseToDigest.ts new file mode 100644 index 00000000..b06a87db --- /dev/null +++ b/public/app/angular/promiseToDigest.ts @@ -0,0 +1,3 @@ +import { IScope } from 'angular'; + +export const promiseToDigest = ($scope: IScope) => (promise: Promise) => promise.finally($scope.$evalAsync); diff --git a/public/app/angular/react2angular.ts b/public/app/angular/react2angular.ts new file mode 100644 index 00000000..db10ac0b --- /dev/null +++ b/public/app/angular/react2angular.ts @@ -0,0 +1,11 @@ +import coreModule from 'app/angular/core_module'; +import { provideTheme } from 'app/core/utils/ConfigProvider'; + +export function react2AngularDirective(name: string, component: any, options: any) { + coreModule.directive(name, [ + 'reactDirective', + (reactDirective) => { + return reactDirective(provideTheme(component), options); + }, + ]); +} diff --git a/public/app/angular/rebuild_on_change.ts b/public/app/angular/rebuild_on_change.ts new file mode 100644 index 00000000..243aacfe --- /dev/null +++ b/public/app/angular/rebuild_on_change.ts @@ -0,0 +1,73 @@ +import $ from 'jquery'; +import coreModule from './core_module'; + +function getBlockNodes(nodes: any[]) { + let node = nodes[0]; + const endNode = nodes[nodes.length - 1]; + let blockNodes: any[] | undefined; + node = node.nextSibling; + + for (let i = 1; node !== endNode && node; i++) { + if (blockNodes || nodes[i] !== node) { + if (!blockNodes) { + blockNodes = $([].slice.call(nodes, 0, i)) as any; + } + + blockNodes!.push(node); + } + node = node.nextSibling; + } + + return blockNodes || nodes; +} + +/** @ngInject */ +function rebuildOnChange($animate: any) { + return { + multiElement: true, + terminal: true, + transclude: true, + priority: 600, + restrict: 'E', + link: (scope: any, elem: any, attrs: any, ctrl: any, transclude: any) => { + let block: any, childScope: any, previousElements: any; + + function cleanUp() { + if (previousElements) { + previousElements.remove(); + previousElements = null; + } + if (childScope) { + childScope.$destroy(); + childScope = null; + } + if (block) { + previousElements = getBlockNodes(block.clone); + $animate.leave(previousElements).then(() => { + previousElements = null; + }); + block = null; + } + } + + scope.$watch(attrs.property, function rebuildOnChangeAction(value: any, oldValue: any) { + if (childScope && value !== oldValue) { + cleanUp(); + } + + if (!childScope && (value || attrs.showNull)) { + transclude((clone: any, newScope: any) => { + childScope = newScope; + clone[clone.length++] = document.createComment(' end rebuild on change '); + block = { clone: clone }; + $animate.enter(clone, elem.parent(), elem); + }); + } else { + cleanUp(); + } + }); + }, + }; +} + +coreModule.directive('rebuildOnChange', rebuildOnChange); diff --git a/public/app/angular/registerComponents.ts b/public/app/angular/registerComponents.ts new file mode 100644 index 00000000..c0fda500 --- /dev/null +++ b/public/app/angular/registerComponents.ts @@ -0,0 +1,19 @@ +import { getBackendSrv, getDataSourceSrv } from '@grafana/runtime'; +import { contextSrv } from 'app/core/core'; +import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv'; +import { getLinkSrv } from 'app/features/panel/panellinks/link_srv'; +import coreModule from './core_module'; +import { AnnotationsSrv } from './services/annotations_srv'; +import { UtilSrv } from './services/UtilSrv'; + +export function registerComponents() { + coreModule.factory('backendSrv', () => getBackendSrv()); + coreModule.factory('contextSrv', () => contextSrv); + coreModule.factory('dashboardSrv', () => getDashboardSrv()); + coreModule.factory('datasourceSrv', () => getDataSourceSrv()); + coreModule.factory('linkSrv', () => getLinkSrv()); + coreModule.factory('validationSrv', () => validationSrv); + coreModule.service('annotationsSrv', AnnotationsSrv); + coreModule.service('utilSrv', UtilSrv); +} diff --git a/public/app/angular/services/AngularLoader.ts b/public/app/angular/services/AngularLoader.ts new file mode 100644 index 00000000..438da88c --- /dev/null +++ b/public/app/angular/services/AngularLoader.ts @@ -0,0 +1,38 @@ +import angular from 'angular'; +import coreModule from 'app/angular/core_module'; +import { assign } from 'lodash'; + +import { AngularComponent, AngularLoader as AngularLoaderInterface } from '@grafana/runtime'; +import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; + +export class AngularLoader implements AngularLoaderInterface { + /** @ngInject */ + constructor(private $compile: any, private $rootScope: GrafanaRootScope) {} + + load(elem: any, scopeProps: any, template: string): AngularComponent { + const scope = this.$rootScope.$new(); + + assign(scope, scopeProps); + + const compiledElem = this.$compile(template)(scope); + const rootNode = angular.element(elem); + rootNode.append(compiledElem); + + return { + destroy: () => { + scope.$destroy(); + compiledElem.remove(); + }, + digest: () => { + if (!scope.$$phase) { + scope.$digest(); + } + }, + getScope: () => { + return scope; + }, + }; + } +} + +coreModule.service('angularLoader', AngularLoader); diff --git a/public/app/angular/services/UtilSrv.ts b/public/app/angular/services/UtilSrv.ts new file mode 100644 index 00000000..6d2a970a --- /dev/null +++ b/public/app/angular/services/UtilSrv.ts @@ -0,0 +1,64 @@ +import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; +import { HideModalEvent, ShowModalEvent } from '../../types/events'; +import { deprecationWarning } from '@grafana/data'; +import { appEvents } from 'app/core/app_events'; + +/** + * Old legacy utilSrv exposed to angular services and handles angular modals. + * Not used by any core or known external plugin. + */ +export class UtilSrv { + modalScope: any; + + /** @ngInject */ + constructor(private $rootScope: GrafanaRootScope, private $modal: any) {} + + init() { + appEvents.subscribe(ShowModalEvent, (e) => this.showModal(e.payload)); + appEvents.subscribe(HideModalEvent, this.hideModal.bind(this)); + } + + /** + * @deprecated use showModalReact instead that has this capability built in + */ + hideModal() { + deprecationWarning('UtilSrv', 'hideModal', 'showModalReact'); + if (this.modalScope && this.modalScope.dismiss) { + this.modalScope.dismiss(); + } + } + + /** + * @deprecated use showModalReact instead + */ + showModal(options: any) { + deprecationWarning('UtilSrv', 'showModal', 'showModalReact'); + if (this.modalScope && this.modalScope.dismiss) { + this.modalScope.dismiss(); + } + + this.modalScope = options.scope; + + if (options.model) { + this.modalScope = this.$rootScope.$new(); + this.modalScope.model = options.model; + } else if (!this.modalScope) { + this.modalScope = this.$rootScope.$new(); + } + + const modal = this.$modal({ + modalClass: options.modalClass, + template: options.src, + templateHtml: options.templateHtml, + persist: false, + show: false, + scope: this.modalScope, + keyboard: false, + backdrop: options.backdrop, + }); + + Promise.resolve(modal).then((modalEl) => { + modalEl.modal('show'); + }); + } +} diff --git a/public/app/angular/services/alert_srv.ts b/public/app/angular/services/alert_srv.ts new file mode 100644 index 00000000..ce4d2225 --- /dev/null +++ b/public/app/angular/services/alert_srv.ts @@ -0,0 +1,12 @@ +import coreModule from 'app/angular/core_module'; + +export class AlertSrv { + constructor() {} + + set() { + console.warn('old deprecated alert srv being used'); + } +} + +// this is just added to not break old plugins that might be using it +coreModule.service('alertSrv', AlertSrv); diff --git a/public/app/angular/services/annotations_srv.test.ts b/public/app/angular/services/annotations_srv.test.ts new file mode 100644 index 00000000..621cdff0 --- /dev/null +++ b/public/app/angular/services/annotations_srv.test.ts @@ -0,0 +1,30 @@ +import { AnnotationsSrv } from './annotations_srv'; + +describe('AnnotationsSrv', () => { + const annotationsSrv = new AnnotationsSrv(); + + describe('When translating the query result', () => { + const annotationSource = { + datasource: '-- Grafana --', + enable: true, + hide: false, + limit: 200, + name: 'test', + scope: 'global', + tags: ['test'], + type: 'event', + }; + + const time = 1507039543000; + const annotations = [{ id: 1, panelId: 1, text: 'text', time: time }]; + let translatedAnnotations: any; + + beforeEach(() => { + translatedAnnotations = annotationsSrv.translateQueryResult(annotationSource, annotations); + }); + + it('should set defaults', () => { + expect(translatedAnnotations[0].source).toEqual(annotationSource); + }); + }); +}); diff --git a/public/app/angular/services/annotations_srv.ts b/public/app/angular/services/annotations_srv.ts new file mode 100644 index 00000000..3e90ee3e --- /dev/null +++ b/public/app/angular/services/annotations_srv.ts @@ -0,0 +1,87 @@ +import { cloneDeep } from 'lodash'; +import { AnnotationEvent, deprecationWarning } from '@grafana/data'; + +import { deleteAnnotation, saveAnnotation, updateAnnotation } from 'app/features/annotations/api'; +import { AnnotationQueryOptions } from 'app/features/annotations/types'; + +/** + * @deprecated AnnotationsSrv is deprecated in favor of DashboardQueryRunner + */ +export class AnnotationsSrv { + /** + * @deprecated clearPromiseCaches is deprecated + */ + clearPromiseCaches() { + deprecationWarning('annotations_srv.ts', 'clearPromiseCaches', 'DashboardQueryRunner'); + } + + /** + * @deprecated getAnnotations is deprecated in favor of DashboardQueryRunner.getResult + */ + getAnnotations(options: AnnotationQueryOptions) { + deprecationWarning('annotations_srv.ts', 'getAnnotations', 'DashboardQueryRunner.getResult'); + return Promise.resolve({ annotations: [], alertState: undefined }); + } + + /** + * @deprecated getAlertStates is deprecated in favor of DashboardQueryRunner.getResult + */ + getAlertStates(options: any) { + deprecationWarning('annotations_srv.ts', 'getAlertStates', 'DashboardQueryRunner.getResult'); + return Promise.resolve(undefined); + } + + /** + * @deprecated getGlobalAnnotations is deprecated in favor of DashboardQueryRunner.getResult + */ + getGlobalAnnotations(options: AnnotationQueryOptions) { + deprecationWarning('annotations_srv.ts', 'getGlobalAnnotations', 'DashboardQueryRunner.getResult'); + return Promise.resolve([]); + } + + /** + * @deprecated saveAnnotationEvent is deprecated + */ + saveAnnotationEvent(annotation: AnnotationEvent) { + deprecationWarning('annotations_srv.ts', 'saveAnnotationEvent', 'api/saveAnnotation'); + return saveAnnotation(annotation); + } + + /** + * @deprecated updateAnnotationEvent is deprecated + */ + updateAnnotationEvent(annotation: AnnotationEvent) { + deprecationWarning('annotations_srv.ts', 'updateAnnotationEvent', 'api/updateAnnotation'); + return updateAnnotation(annotation); + } + + /** + * @deprecated deleteAnnotationEvent is deprecated + */ + deleteAnnotationEvent(annotation: AnnotationEvent) { + deprecationWarning('annotations_srv.ts', 'deleteAnnotationEvent', 'api/deleteAnnotation'); + return deleteAnnotation(annotation); + } + + /** + * @deprecated translateQueryResult is deprecated in favor of DashboardQueryRunner/utils/translateQueryResult + */ + translateQueryResult(annotation: any, results: any) { + deprecationWarning('annotations_srv.ts', 'translateQueryResult', 'DashboardQueryRunner/utils/translateQueryResult'); + // if annotation has snapshotData + // make clone and remove it + if (annotation.snapshotData) { + annotation = cloneDeep(annotation); + delete annotation.snapshotData; + } + + for (const item of results) { + item.source = annotation; + item.color = annotation.iconColor; + item.type = annotation.name; + item.isRegion = item.timeEnd && item.time !== item.timeEnd; + } + + return results; + } +} diff --git a/public/app/angular/services/dynamic_directive_srv.ts b/public/app/angular/services/dynamic_directive_srv.ts new file mode 100644 index 00000000..30c4c860 --- /dev/null +++ b/public/app/angular/services/dynamic_directive_srv.ts @@ -0,0 +1,55 @@ +import angular from 'angular'; +import coreModule from '../core_module'; + +class DynamicDirectiveSrv { + /** @ngInject */ + constructor(private $compile: angular.ICompileService) {} + + addDirective(element: any, name: string, scope: any) { + const child = angular.element(document.createElement(name)); + this.$compile(child)(scope); + + element.empty(); + element.append(child); + } + + link(scope: any, elem: JQLite, attrs: any, options: any) { + const directiveInfo = options.directive(scope); + if (!directiveInfo || !directiveInfo.fn) { + elem.empty(); + return; + } + + if (!directiveInfo.fn.registered) { + coreModule.directive(attrs.$normalize(directiveInfo.name), directiveInfo.fn); + directiveInfo.fn.registered = true; + } + + this.addDirective(elem, directiveInfo.name, scope); + } + + create(options: any) { + const directiveDef = { + restrict: 'E', + scope: options.scope, + link: (scope: any, elem: JQLite, attrs: any) => { + if (options.watchPath) { + let childScope: any = null; + scope.$watch(options.watchPath, () => { + if (childScope) { + childScope.$destroy(); + } + childScope = scope.$new(); + this.link(childScope, elem, attrs, options); + }); + } else { + this.link(scope, elem, attrs, options); + } + }, + }; + + return directiveDef; + } +} + +coreModule.service('dynamicDirectiveSrv', DynamicDirectiveSrv); diff --git a/public/app/angular/services/nav_model_srv.ts b/public/app/angular/services/nav_model_srv.ts new file mode 100644 index 00000000..57341325 --- /dev/null +++ b/public/app/angular/services/nav_model_srv.ts @@ -0,0 +1,77 @@ +import coreModule from 'app/angular/core_module'; +import config from 'app/core/config'; +import { find, isNumber } from 'lodash'; +import { NavModel } from '@grafana/data'; + +export class NavModelSrv { + navItems: any; + + constructor() { + this.navItems = config.bootData.navTree; + } + + getCfgNode() { + return find(this.navItems, { id: 'cfg' }); + } + + getNav(...args: Array) { + let children = this.navItems; + const nav = { + breadcrumbs: [], + } as any; + + for (const id of args) { + // if its a number then it's the index to use for main + if (isNumber(id)) { + nav.main = nav.breadcrumbs[id]; + break; + } + + const node: any = find(children, { id: id }); + nav.breadcrumbs.push(node); + nav.node = node; + nav.main = node; + children = node.children; + } + + if (nav.main.children) { + for (const item of nav.main.children) { + item.active = false; + + if (item.url === nav.node.url) { + item.active = true; + } + } + } + + return nav; + } + + getNotFoundNav() { + return getNotFoundNav(); // the exported function + } +} + +export function getExceptionNav(error: any): NavModel { + console.error(error); + return getWarningNav('Exception thrown', 'See console for details'); +} + +export function getNotFoundNav(): NavModel { + return getWarningNav('Page not found', '404 Error'); +} + +export function getWarningNav(text: string, subTitle?: string): NavModel { + const node = { + text, + subTitle, + icon: 'exclamation-triangle', + }; + return { + breadcrumbs: [node], + node: node, + main: node, + }; +} + +coreModule.service('navModelSrv', NavModelSrv); diff --git a/public/app/angular/services/ng_react.ts b/public/app/angular/services/ng_react.ts new file mode 100644 index 00000000..3cf65f48 --- /dev/null +++ b/public/app/angular/services/ng_react.ts @@ -0,0 +1,316 @@ +// +// This is using ng-react with this PR applied https://github.com/ngReact/ngReact/pull/199 +// + +// # ngReact +// ### Use React Components inside of your Angular applications +// +// Composed of +// - reactComponent (generic directive for delegating off to React Components) +// - reactDirective (factory for creating specific directives that correspond to reactComponent directives) + +import { kebabCase } from 'lodash'; +import React, { ComponentType } from 'react'; +import ReactDOM from 'react-dom'; +import angular, { auto } from 'angular'; + +// get a react component from name (components can be an angular injectable e.g. value, factory or +// available on window +function getReactComponent(name: string | Function, $injector: auto.IInjectorService): ComponentType { + // if name is a function assume it is component and return it + if (angular.isFunction(name)) { + return (name as unknown) as ComponentType; + } + + // a React component name must be specified + if (!name) { + throw new Error('ReactComponent name attribute must be specified'); + } + + // ensure the specified React component is accessible, and fail fast if it's not + let reactComponent; + try { + reactComponent = $injector.get(name); + } catch (e) {} + + if (!reactComponent) { + try { + reactComponent = name.split('.').reduce((current, namePart) => { + // @ts-ignore + return current[namePart]; + }, window); + } catch (e) {} + } + + if (!reactComponent) { + throw Error('Cannot find react component ' + name); + } + + return (reactComponent as unknown) as ComponentType; +} + +// wraps a function with scope.$apply, if already applied just return +function applied(fn: any, scope: any) { + if (fn.wrappedInApply) { + return fn; + } + // this had the equivalent of `eslint-disable-next-line prefer-arrow/prefer-arrow-functions` + const wrapped: any = function () { + const args = arguments; + const phase = scope.$root.$$phase; + if (phase === '$apply' || phase === '$digest') { + return fn.apply(null, args); + } else { + return scope.$apply(() => { + return fn.apply(null, args); + }); + } + }; + wrapped.wrappedInApply = true; + return wrapped; +} + +/** + * wraps functions on obj in scope.$apply + * + * keeps backwards compatibility, as if propsConfig is not passed, it will + * work as before, wrapping all functions and won't wrap only when specified. + * + * @version 0.4.1 + * @param obj react component props + * @param scope current scope + * @param propsConfig configuration object for all properties + * @returns {Object} props with the functions wrapped in scope.$apply + */ +function applyFunctions(obj: any, scope: any, propsConfig?: any): object { + return Object.keys(obj || {}).reduce((prev, key) => { + const value = obj[key]; + const config = (propsConfig || {})[key] || {}; + /** + * wrap functions in a function that ensures they are scope.$applied + * ensures that when function is called from a React component + * the Angular digest cycle is run + */ + // @ts-ignore + prev[key] = angular.isFunction(value) && config.wrapApply !== false ? applied(value, scope) : value; + + return prev; + }, {}); +} + +/** + * + * @param watchDepth (value of HTML watch-depth attribute) + * @param scope (angular scope) + * + * Uses the watchDepth attribute to determine how to watch props on scope. + * If watchDepth attribute is NOT reference or collection, watchDepth defaults to deep watching by value + */ +function watchProps(watchDepth: string, scope: any, watchExpressions: any[], listener: any) { + const supportsWatchCollection = angular.isFunction(scope.$watchCollection); + const supportsWatchGroup = angular.isFunction(scope.$watchGroup); + + const watchGroupExpressions = []; + + for (const expr of watchExpressions) { + const actualExpr = getPropExpression(expr); + const exprWatchDepth = getPropWatchDepth(watchDepth, expr); + + // ignore empty expressions & expressions with functions + if (!actualExpr || actualExpr.match(/\(.*\)/) || exprWatchDepth === 'one-time') { + continue; + } + + if (exprWatchDepth === 'collection' && supportsWatchCollection) { + scope.$watchCollection(actualExpr, listener); + } else if (exprWatchDepth === 'reference' && supportsWatchGroup) { + watchGroupExpressions.push(actualExpr); + } else { + scope.$watch(actualExpr, listener, exprWatchDepth !== 'reference'); + } + } + + if (watchDepth === 'one-time') { + listener(); + } + + if (watchGroupExpressions.length) { + scope.$watchGroup(watchGroupExpressions, listener); + } +} + +// render React component, with scope[attrs.props] being passed in as the component props +function renderComponent(component: any, props: object, scope: any, elem: Element[]) { + scope.$evalAsync(() => { + ReactDOM.render(React.createElement(component, props), elem[0]); + }); +} + +// get prop name from prop (string or array) +function getPropName(prop: any) { + return Array.isArray(prop) ? prop[0] : prop; +} + +// get prop name from prop (string or array) +function getPropConfig(prop: any) { + return Array.isArray(prop) ? prop[1] : {}; +} + +// get prop expression from prop (string or array) +function getPropExpression(prop: any) { + return Array.isArray(prop) ? prop[0] : prop; +} + +/** + * Finds the normalized attribute knowing that React props accept any type of capitalization and it also handles + * kabab case attributes which can be used in case the attribute would also be a standard html attribute and would be + * evaluated by the browser as such. + * @param attrs All attributes of the component. + * @param propName Name of the prop that react component expects. + */ +function findAttribute(attrs: string, propName: string): string { + const index = Object.keys(attrs).find((attr) => { + return attr.toLowerCase() === propName.toLowerCase() || attr.toLowerCase() === kebabCase(propName); + }); + // @ts-ignore + return attrs[index]; +} + +// get watch depth of prop (string or array) +function getPropWatchDepth(defaultWatch: string, prop: string | any[]) { + const customWatchDepth = Array.isArray(prop) && angular.isObject(prop[1]) && prop[1].watchDepth; + return customWatchDepth || defaultWatch; +} + +// # reactComponent +// Directive that allows React components to be used in Angular templates. +// +// Usage: +// +// +// This requires that there exists an injectable or globally available 'Hello' React component. +// The 'props' attribute is optional and is passed to the component. +// +// The following would would create and register the component: +// +// var module = angular.module('ace.react.components'); +// module.value('Hello', React.createClass({ +// render: function() { +// return
Hello {this.props.name}
; +// } +// })); +// +const reactComponent = ($injector: any): any => { + return { + restrict: 'E', + replace: true, + link: function (scope: any, elem: Element[], attrs: any) { + const reactComponent = getReactComponent(attrs.name, $injector); + + const renderMyComponent = () => { + const scopeProps = scope.$eval(attrs.props); + const props = applyFunctions(scopeProps, scope); + + renderComponent(reactComponent, props, scope, elem); + }; + + // If there are props, re-render when they change + attrs.props ? watchProps(attrs.watchDepth, scope, [attrs.props], renderMyComponent) : renderMyComponent(); + + // cleanup when scope is destroyed + scope.$on('$destroy', () => { + if (!attrs.onScopeDestroy) { + ReactDOM.unmountComponentAtNode(elem[0]); + } else { + scope.$eval(attrs.onScopeDestroy, { + unmountComponent: ReactDOM.unmountComponentAtNode.bind(this, elem[0]), + }); + } + }); + }, + }; +}; + +// # reactDirective +// Factory function to create directives for React components. +// +// With a component like this: +// +// var module = angular.module('ace.react.components'); +// module.value('Hello', React.createClass({ +// render: function() { +// return
Hello {this.props.name}
; +// } +// })); +// +// A directive can be created and registered with: +// +// module.directive('hello', function(reactDirective) { +// return reactDirective('Hello', ['name']); +// }); +// +// Where the first argument is the injectable or globally accessible name of the React component +// and the second argument is an array of property names to be watched and passed to the React component +// as props. +// +// This directive can then be used like this: +// +// +// +const reactDirective = ($injector: auto.IInjectorService) => { + return (reactComponentName: string, props: string[], conf: any, injectableProps: any) => { + const directive = { + restrict: 'E', + replace: true, + link: function (scope: any, elem: Element[], attrs: any) { + const reactComponent = getReactComponent(reactComponentName, $injector); + + // if props is not defined, fall back to use the React component's propTypes if present + props = props || Object.keys(reactComponent.propTypes || {}); + + // for each of the properties, get their scope value and set it to scope.props + const renderMyComponent = () => { + let scopeProps: any = {}; + const config: any = {}; + + props.forEach((prop) => { + const propName = getPropName(prop); + scopeProps[propName] = scope.$eval(findAttribute(attrs, propName)); + config[propName] = getPropConfig(prop); + }); + + scopeProps = applyFunctions(scopeProps, scope, config); + scopeProps = angular.extend({}, scopeProps, injectableProps); + renderComponent(reactComponent, scopeProps, scope, elem); + }; + + // watch each property name and trigger an update whenever something changes, + // to update scope.props with new values + const propExpressions = props.map((prop) => { + return Array.isArray(prop) + ? [findAttribute(attrs, prop[0]), getPropConfig(prop)] + : findAttribute(attrs, prop); + }); + + // If we don't have any props, then our watch statement won't fire. + props.length ? watchProps(attrs.watchDepth, scope, propExpressions, renderMyComponent) : renderMyComponent(); + + // cleanup when scope is destroyed + scope.$on('$destroy', () => { + if (!attrs.onScopeDestroy) { + ReactDOM.unmountComponentAtNode(elem[0]); + } else { + scope.$eval(attrs.onScopeDestroy, { + unmountComponent: ReactDOM.unmountComponentAtNode.bind(this, elem[0]), + }); + } + }); + }, + }; + return angular.extend(directive, conf); + }; +}; + +const ngModule = angular.module('react', []); +ngModule.directive('reactComponent', ['$injector', reactComponent]); +ngModule.factory('reactDirective', ['$injector', reactDirective]); diff --git a/public/app/angular/services/popover_srv.ts b/public/app/angular/services/popover_srv.ts new file mode 100644 index 00000000..e84c0975 --- /dev/null +++ b/public/app/angular/services/popover_srv.ts @@ -0,0 +1,81 @@ +import { extend } from 'lodash'; +import coreModule from 'app/angular/core_module'; +// @ts-ignore +import Drop from 'tether-drop'; +import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; + +/** @ngInject */ +function popoverSrv(this: any, $compile: any, $rootScope: GrafanaRootScope, $timeout: any) { + let openDrop: any = null; + + this.close = () => { + if (openDrop) { + openDrop.close(); + } + }; + + this.show = (options: any) => { + if (openDrop) { + openDrop.close(); + openDrop = null; + } + + const scope = extend($rootScope.$new(true), options.model); + let drop: any; + + const cleanUp = () => { + setTimeout(() => { + scope.$destroy(); + + if (drop.tether) { + drop.destroy(); + } + + if (options.onClose) { + options.onClose(); + } + }); + + openDrop = null; + }; + + scope.dismiss = () => { + drop.close(); + }; + + const contentElement = document.createElement('div'); + contentElement.innerHTML = options.template; + + $compile(contentElement)(scope); + + $timeout(() => { + drop = new Drop({ + target: options.element, + content: contentElement, + position: options.position, + classes: options.classNames || 'drop-popover', + openOn: options.openOn, + hoverCloseDelay: 200, + tetherOptions: { + constraints: [{ to: 'scrollParent', attachment: 'together' }], + }, + }); + + drop.on('close', () => { + cleanUp(); + }); + + openDrop = drop; + openDrop.open(); + }, 100); + + // return close function + return () => { + if (drop) { + drop.close(); + } + }; + }; +} + +coreModule.service('popoverSrv', popoverSrv); diff --git a/public/app/angular/services/segment_srv.ts b/public/app/angular/services/segment_srv.ts new file mode 100644 index 00000000..b0c37eee --- /dev/null +++ b/public/app/angular/services/segment_srv.ts @@ -0,0 +1,122 @@ +import { each, isString, map } from 'lodash'; +import coreModule from '../core_module'; + +/** @ngInject */ +export function uiSegmentSrv(this: any, $sce: any, templateSrv: any) { + const self = this; + + class MetricSegment { + value: string; + html: any; + type: any; + expandable?: boolean; + text?: string; + cssClass?: string; + fake?: boolean; + custom?: boolean; + selectMode?: any; + + constructor(options: any) { + if (options === '*' || options.value === '*') { + this.value = '*'; + this.html = $sce.trustAsHtml(''); + this.type = options.type; + this.expandable = true; + return; + } + + if (isString(options)) { + this.value = options; + this.html = $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value)); + return; + } + + // temp hack to work around legacy inconsistency in segment model + this.text = options.value; + + this.cssClass = options.cssClass; + this.custom = options.custom; + this.type = options.type; + this.fake = options.fake; + this.value = options.value; + this.selectMode = options.selectMode; + this.expandable = options.expandable; + this.html = options.html || $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value)); + } + } + + this.getSegmentForValue = function (value: string, fallbackText: string) { + if (value) { + return this.newSegment(value); + } else { + return this.newSegment({ value: fallbackText, fake: true }); + } + }; + + this.newSelectMeasurement = () => { + return new MetricSegment({ value: 'select measurement', fake: true }); + }; + + this.newFake = (text: string, type: string, cssClass: string) => { + return new MetricSegment({ value: text, fake: true, type: type, cssClass: cssClass }); + }; + + this.newSegment = (options: any) => { + return new MetricSegment(options); + }; + + this.newKey = (key: string) => { + return new MetricSegment({ value: key, type: 'key', cssClass: 'query-segment-key' }); + }; + + this.newKeyValue = (value: string) => { + return new MetricSegment({ value: value, type: 'value', cssClass: 'query-segment-value' }); + }; + + this.newCondition = (condition: string) => { + return new MetricSegment({ value: condition, type: 'condition', cssClass: 'query-keyword' }); + }; + + this.newOperator = (op: string) => { + return new MetricSegment({ value: op, type: 'operator', cssClass: 'query-segment-operator' }); + }; + + this.newOperators = (ops: string[]) => { + return map(ops, (op) => { + return new MetricSegment({ value: op, type: 'operator', cssClass: 'query-segment-operator' }); + }); + }; + + this.transformToSegments = (addTemplateVars: boolean, variableTypeFilter: string) => { + return (results: any[]) => { + const segments = map(results, (segment) => { + return self.newSegment({ value: segment.text, expandable: segment.expandable }); + }); + + if (addTemplateVars) { + each(templateSrv.getVariables(), (variable) => { + if (variableTypeFilter === void 0 || variableTypeFilter === variable.type) { + segments.unshift(self.newSegment({ type: 'value', value: '$' + variable.name, expandable: true })); + } + }); + } + + return segments; + }; + }; + + this.newSelectMetric = () => { + return new MetricSegment({ value: 'select metric', fake: true }); + }; + + this.newPlusButton = () => { + return new MetricSegment({ + fake: true, + html: '', + type: 'plus-button', + cssClass: 'query-part', + }); + }; +} + +coreModule.service('uiSegmentSrv', uiSegmentSrv); diff --git a/public/app/angular/services/timer.ts b/public/app/angular/services/timer.ts new file mode 100644 index 00000000..177b3fc1 --- /dev/null +++ b/public/app/angular/services/timer.ts @@ -0,0 +1,31 @@ +import { without, each } from 'lodash'; +import coreModule from 'app/angular/core_module'; +import { ITimeoutService } from 'angular'; + +// This service really just tracks a list of $timeout promises to give us a +// method for canceling them all when we need to +export class Timer { + timers: Array> = []; + + /** @ngInject */ + constructor(private $timeout: ITimeoutService) {} + + register(promise: angular.IPromise) { + this.timers.push(promise); + return promise; + } + + cancel(promise: angular.IPromise) { + this.timers = without(this.timers, promise); + this.$timeout.cancel(promise); + } + + cancelAll() { + each(this.timers, (t) => { + this.$timeout.cancel(t); + }); + this.timers = []; + } +} + +coreModule.service('timer', Timer); diff --git a/public/app/angular/tags.ts b/public/app/angular/tags.ts new file mode 100644 index 00000000..aad0db6e --- /dev/null +++ b/public/app/angular/tags.ts @@ -0,0 +1,118 @@ +import angular from 'angular'; +import { getTagColorsFromName } from '@grafana/ui'; +import $ from 'jquery'; +import coreModule from './core_module'; +import 'vendor/tagsinput/bootstrap-tagsinput.js'; + +function setColor(name: string, element: JQuery) { + const { color, borderColor } = getTagColorsFromName(name); + element.css('background-color', color); + element.css('border-color', borderColor); +} + +function tagColorFromName() { + return { + scope: { tagColorFromName: '=' }, + link: (scope: any, element: any) => { + setColor(scope.tagColorFromName, element); + }, + }; +} + +function bootstrapTagsinput() { + function getItemProperty(scope: any, property: any) { + if (!property) { + return undefined; + } + + if (angular.isFunction(scope.$parent[property])) { + return scope.$parent[property]; + } + + return (item: any) => { + return item[property]; + }; + } + + return { + restrict: 'EA', + scope: { + model: '=ngModel', + onTagsUpdated: '&', + }, + template: '', + replace: false, + link: function (scope: any, element: any, attrs: any) { + if (!angular.isArray(scope.model)) { + scope.model = []; + } + + const select = $('select', element); + + if (attrs.placeholder) { + select.attr('placeholder', attrs.placeholder); + } + + select.tagsinput({ + typeahead: { + source: angular.isFunction(scope.$parent[attrs.typeaheadSource]) + ? scope.$parent[attrs.typeaheadSource] + : null, + }, + widthClass: attrs.widthClass, + itemValue: getItemProperty(scope, attrs.itemvalue), + itemText: getItemProperty(scope, attrs.itemtext), + tagClass: angular.isFunction(scope.$parent[attrs.tagclass]) + ? scope.$parent[attrs.tagclass] + : () => { + return attrs.tagclass; + }, + }); + + select.on('itemAdded', (event: any) => { + if (scope.model.indexOf(event.item) === -1) { + scope.model.push(event.item); + if (scope.onTagsUpdated) { + scope.onTagsUpdated(); + } + } + const tagElement = select + .next() + .children('span') + .filter(() => { + return $(this).text() === event.item; + }); + setColor(event.item, tagElement); + }); + + select.on('itemRemoved', (event: any) => { + const idx = scope.model.indexOf(event.item); + if (idx !== -1) { + scope.model.splice(idx, 1); + if (scope.onTagsUpdated) { + scope.onTagsUpdated(); + } + } + }); + + scope.$watch( + 'model', + () => { + if (!angular.isArray(scope.model)) { + scope.model = []; + } + + select.tagsinput('removeAll'); + + for (let i = 0; i < scope.model.length; i++) { + select.tagsinput('add', scope.model[i]); + } + }, + true + ); + }, + }; +} + +coreModule.directive('tagColorFromName', tagColorFromName); +coreModule.directive('bootstrapTagsinput', bootstrapTagsinput); diff --git a/public/app/app.ts b/public/app/app.ts new file mode 100644 index 00000000..dde68451 --- /dev/null +++ b/public/app/app.ts @@ -0,0 +1,246 @@ +import 'symbol-observable'; +import 'core-js'; +import 'regenerator-runtime/runtime'; + +import 'whatwg-fetch'; // fetch polyfill needed for PhantomJs rendering +import './polyfills/old-mediaquerylist'; // Safari < 14 does not have mql.addEventListener() +import 'file-saver'; +import 'jquery'; + +// eslint-disable-next-line lodash/import-scope +import _ from 'lodash'; +import ReactDOM from 'react-dom'; +import React from 'react'; +import config from 'app/core/config'; +// @ts-ignore ignoring this for now, otherwise we would have to extend _ interface with move +import { + locationUtil, + monacoLanguageRegistry, + setLocale, + setTimeZoneResolver, + setWeekStart, + standardEditorsRegistry, + standardFieldConfigEditorRegistry, + standardTransformersRegistry, +} from '@grafana/data'; +import { arrayMove } from 'app/core/utils/arrayMove'; +import { preloadPlugins } from './features/plugins/pluginPreloader'; +import { + locationService, + registerEchoBackend, + setBackendSrv, + setDataSourceSrv, + setEchoSrv, + setLocationSrv, + setQueryRunnerFactory, +} from '@grafana/runtime'; +import { Echo } from './core/services/echo/Echo'; +import { reportPerformance } from './core/services/echo/EchoSrv'; +import { PerformanceBackend } from './core/services/echo/backends/PerformanceBackend'; +import 'app/features/all'; +import { getScrollbarWidth, getStandardFieldConfigs } from '@grafana/ui'; +import { getDefaultVariableAdapters, variableAdapters } from './features/variables/adapters'; +import { initDevFeatures } from './dev'; +import { getStandardTransformers } from 'app/core/utils/standardTransformers'; +import { SentryEchoBackend } from './core/services/echo/backends/sentry/SentryBackend'; +import { setVariableQueryRunner, VariableQueryRunner } from './features/variables/query/VariableQueryRunner'; +import { configureStore } from './store/configureStore'; +import { AppWrapper } from './AppWrapper'; +import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks'; +import { PanelRenderer } from './features/panel/components/PanelRenderer'; +import { QueryRunner } from './features/query/state/QueryRunner'; +import { getTimeSrv } from './features/dashboard/services/TimeSrv'; +import { getVariablesUrlParams } from './features/variables/getAllVariableValuesForUrl'; +import getDefaultMonacoLanguages from '../lib/monaco-languages'; +import { contextSrv } from './core/services/context_srv'; +import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend'; +import { ApplicationInsightsBackend } from './core/services/echo/backends/analytics/ApplicationInsightsBackend'; +import { RudderstackBackend } from './core/services/echo/backends/analytics/RudderstackBackend'; +import { getAllOptionEditors } from './core/components/editors/registry'; +import { backendSrv } from './core/services/backend_srv'; +import { setPanelRenderer } from '@grafana/runtime/src/components/PanelRenderer'; +import { PanelDataErrorView } from './features/panel/components/PanelDataErrorView'; +import { setPanelDataErrorView } from '@grafana/runtime/src/components/PanelDataErrorView'; +import { DatasourceSrv } from './features/plugins/datasource_srv'; +import { AngularApp } from './angular'; +import { ModalManager } from './core/services/ModalManager'; +import { initWindowRuntime } from './features/runtime/init'; + +// add move to lodash for backward compatabilty with plugins +// @ts-ignore +_.move = arrayMove; + +// import symlinked extensions +const extensionsIndex = (require as any).context('.', true, /extensions\/index.ts/); +const extensionsExports = extensionsIndex.keys().map((key: any) => { + return extensionsIndex(key); +}); + +if (process.env.NODE_ENV === 'development') { + initDevFeatures(); +} + +export class GrafanaApp { + angularApp: AngularApp; + + constructor() { + this.angularApp = new AngularApp(); + } + + async init() { + try { + setBackendSrv(backendSrv); + initEchoSrv(); + addClassIfNoOverlayScrollbar(); + setLocale(config.bootData.user.locale); + setWeekStart(config.bootData.user.weekStart); + setPanelRenderer(PanelRenderer); + setPanelDataErrorView(PanelDataErrorView); + setLocationSrv(locationService); + setTimeZoneResolver(() => config.bootData.user.timezone); + // Important that extension reducers are initialized before store + addExtensionReducers(); + configureStore(); + initExtensions(); + + standardEditorsRegistry.setInit(getAllOptionEditors); + standardFieldConfigEditorRegistry.setInit(getStandardFieldConfigs); + standardTransformersRegistry.setInit(getStandardTransformers); + variableAdapters.setInit(getDefaultVariableAdapters); + monacoLanguageRegistry.setInit(getDefaultMonacoLanguages); + + setQueryRunnerFactory(() => new QueryRunner()); + setVariableQueryRunner(new VariableQueryRunner()); + + locationUtil.initialize({ + config, + getTimeRangeForUrl: getTimeSrv().timeRangeForUrl, + getVariablesUrlParams: getVariablesUrlParams, + }); + + // intercept anchor clicks and forward it to custom history instead of relying on browser's history + document.addEventListener('click', interceptLinkClicks); + + // Init DataSourceSrv + const dataSourceSrv = new DatasourceSrv(); + dataSourceSrv.init(config.datasources, config.defaultDatasource); + setDataSourceSrv(dataSourceSrv); + initWindowRuntime(); + + // init modal manager + const modalManager = new ModalManager(); + modalManager.init(); + + // Init angular + this.angularApp.init(); + + // Preload selected app plugins + await preloadPlugins(config.pluginsToPreload); + + ReactDOM.render( + React.createElement(AppWrapper, { + app: this, + }), + document.getElementById('reactRoot') + ); + } catch (error: any) { + console.error('Failed to start Grafana', error); + window.__grafana_load_failed(); + } + } +} + +function addExtensionReducers() { + if (extensionsExports.length > 0) { + extensionsExports[0].addExtensionReducers(); + } +} + +function initExtensions() { + if (extensionsExports.length > 0) { + extensionsExports[0].init(); + } +} + +function initEchoSrv() { + setEchoSrv(new Echo({ debug: process.env.NODE_ENV === 'development' })); + + window.addEventListener('load', (e) => { + const loadMetricName = 'frontend_boot_load_time_seconds'; + // Metrics below are marked in public/views/index-template.html + const jsLoadMetricName = 'frontend_boot_js_done_time_seconds'; + const cssLoadMetricName = 'frontend_boot_css_time_seconds'; + + if (performance) { + performance.mark(loadMetricName); + reportMetricPerformanceMark('first-paint', 'frontend_boot_', '_time_seconds'); + reportMetricPerformanceMark('first-contentful-paint', 'frontend_boot_', '_time_seconds'); + reportMetricPerformanceMark(loadMetricName); + reportMetricPerformanceMark(jsLoadMetricName); + reportMetricPerformanceMark(cssLoadMetricName); + } + }); + + if (contextSrv.user.orgRole !== '') { + registerEchoBackend(new PerformanceBackend({})); + } + + if (config.sentry.enabled) { + registerEchoBackend( + new SentryEchoBackend({ + ...config.sentry, + user: config.bootData.user, + buildInfo: config.buildInfo, + }) + ); + } + + if ((config as any).googleAnalyticsId) { + registerEchoBackend( + new GAEchoBackend({ + googleAnalyticsId: (config as any).googleAnalyticsId, + }) + ); + } + + if ((config as any).rudderstackWriteKey && (config as any).rudderstackDataPlaneUrl) { + registerEchoBackend( + new RudderstackBackend({ + writeKey: (config as any).rudderstackWriteKey, + dataPlaneUrl: (config as any).rudderstackDataPlaneUrl, + user: config.bootData.user, + sdkUrl: (config as any).rudderstackSdkUrl, + configUrl: (config as any).rudderstackConfigUrl, + }) + ); + } + + if (config.applicationInsightsConnectionString) { + registerEchoBackend( + new ApplicationInsightsBackend({ + connectionString: config.applicationInsightsConnectionString, + endpointUrl: config.applicationInsightsEndpointUrl, + }) + ); + } +} + +function addClassIfNoOverlayScrollbar() { + if (getScrollbarWidth() > 0) { + document.body.classList.add('no-overlay-scrollbar'); + } +} + +/** + * Report when a metric of a given name was marked during the document lifecycle. Works for markers with no duration, + * like PerformanceMark or PerformancePaintTiming (e.g. created with performance.mark, or first-contentful-paint) + */ +function reportMetricPerformanceMark(metricName: string, prefix = '', suffix = ''): void { + const metric = _.first(performance.getEntriesByName(metricName)); + if (metric) { + const metricName = metric.name.replace(/-/g, '_'); + reportPerformance(`${prefix}${metricName}${suffix}`, Math.round(metric.startTime) / 1000); + } +} + +export default new GrafanaApp(); diff --git a/public/app/core/actions/cleanUp.ts b/public/app/core/actions/cleanUp.ts new file mode 100644 index 00000000..a1c362a6 --- /dev/null +++ b/public/app/core/actions/cleanUp.ts @@ -0,0 +1,11 @@ +import { createAction } from '@reduxjs/toolkit'; + +import { StoreState } from '../../types'; + +export type StateSelector = (state: StoreState) => T; + +export interface CleanUp { + stateSelector: (state: StoreState) => T; +} + +export const cleanUpAction = createAction>('core/cleanUpState'); diff --git a/public/app/core/actions/index.ts b/public/app/core/actions/index.ts new file mode 100644 index 00000000..4df4144e --- /dev/null +++ b/public/app/core/actions/index.ts @@ -0,0 +1,3 @@ +import { clearAppNotification, notifyApp } from '../reducers/appNotification'; +import { updateNavIndex, updateConfigurationSubtitle } from '../reducers/navModel'; +export { updateNavIndex, updateConfigurationSubtitle, notifyApp, clearAppNotification }; diff --git a/public/app/core/app_events.ts b/public/app/core/app_events.ts new file mode 100644 index 00000000..2c3552ec --- /dev/null +++ b/public/app/core/app_events.ts @@ -0,0 +1,5 @@ +import { EventBusSrv, EventBusExtended } from '@grafana/data'; + +export const appEvents: EventBusExtended = new EventBusSrv(); + +export default appEvents; diff --git a/public/app/core/components/AccessControl/AddPermission.tsx b/public/app/core/components/AccessControl/AddPermission.tsx new file mode 100644 index 00000000..17d7495a --- /dev/null +++ b/public/app/core/components/AccessControl/AddPermission.tsx @@ -0,0 +1,101 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { UserPicker } from 'app/core/components/Select/UserPicker'; +import { TeamPicker } from 'app/core/components/Select/TeamPicker'; +import { Button, Form, HorizontalGroup, Select } from '@grafana/ui'; +import { OrgRole } from 'app/types/acl'; +import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; +import { Assignments, PermissionTarget, SetPermission } from './types'; + +export interface Props { + permissions: string[]; + assignments: Assignments; + canListUsers: boolean; + onCancel: () => void; + onAdd: (state: SetPermission) => void; +} + +export const AddPermission = ({ permissions, assignments, canListUsers, onAdd, onCancel }: Props) => { + const [target, setPermissionTarget] = useState(PermissionTarget.User); + const [teamId, setTeamId] = useState(0); + const [userId, setUserId] = useState(0); + const [builtInRole, setBuiltinRole] = useState(''); + const [permission, setPermission] = useState(''); + + const targetOptions = useMemo(() => { + const options = []; + if (assignments.users && canListUsers) { + options.push({ value: PermissionTarget.User, label: 'User', isDisabled: false }); + } + if (assignments.teams) { + options.push({ value: PermissionTarget.Team, label: 'Team' }); + } + if (assignments.builtInRoles) { + options.push({ value: PermissionTarget.BuiltInRole, label: 'Role' }); + } + return options; + }, [assignments, canListUsers]); + + useEffect(() => { + if (permissions.length > 0) { + setPermission(permissions[0]); + } + }, [permissions]); + + const isValid = () => + (target === PermissionTarget.Team && teamId > 0) || + (target === PermissionTarget.User && userId > 0) || + (PermissionTarget.BuiltInRole && OrgRole.hasOwnProperty(builtInRole)); + + return ( +
+ +
Add Permission For
+
onAdd({ userId, teamId, builtInRole, permission, target })} + > + {() => ( + + ({ value: r, label: r }))} + onChange={(r) => setBuiltinRole(r.value || '')} + width={40} + /> + )} + + onChange(item, p.value!)} + value={permissionLevels.find((p) => p === item.permission)} + options={permissionLevels.map((p) => ({ value: p, label: p }))} + /> +
+ + + + + + + + {item.isManaged ? ( + + )} +
+ +
+ + setIsAdding(false)} + /> + + + + +
+
+ ); +}; + +const getDescription = async (resource: string): Promise => { + try { + return await getBackendSrv().get(`/api/access-control/${resource}/description`); + } catch (e) { + console.error('failed to load resource description: ', e); + return INITIAL_DESCRIPTION; + } +}; + +const getPermissions = (resource: string, datasourceId: number): Promise => + getBackendSrv().get(`/api/access-control/${resource}/${datasourceId}`); + +const setUserPermission = (resource: string, resourceId: number, userId: number, permission: string) => + setPermission(resource, resourceId, 'users', userId, permission); + +const setTeamPermission = (resource: string, resourceId: number, teamId: number, permission: string) => + setPermission(resource, resourceId, 'teams', teamId, permission); + +const setBuiltInRolePermission = (resource: string, resourceId: number, builtInRole: string, permission: string) => + setPermission(resource, resourceId, 'builtInRoles', builtInRole, permission); + +const setPermission = ( + resource: string, + resourceId: number, + type: 'users' | 'teams' | 'builtInRoles', + typeId: number | string, + permission: string +): Promise => + getBackendSrv().post(`/api/access-control/${resource}/${resourceId}/${type}/${typeId}/`, { permission }); diff --git a/public/app/core/components/AccessControl/index.ts b/public/app/core/components/AccessControl/index.ts new file mode 100644 index 00000000..753f2b4b --- /dev/null +++ b/public/app/core/components/AccessControl/index.ts @@ -0,0 +1 @@ +export * from './Permissions'; diff --git a/public/app/core/components/AccessControl/types.ts b/public/app/core/components/AccessControl/types.ts new file mode 100644 index 00000000..b6bba211 --- /dev/null +++ b/public/app/core/components/AccessControl/types.ts @@ -0,0 +1,38 @@ +export type ResourcePermission = { + id: number; + resourceId: string; + isManaged: boolean; + userId?: number; + userLogin?: string; + userAvatarUrl?: string; + team?: string; + teamId?: number; + teamAvatarUrl?: string; + builtInRole?: string; + actions: string[]; + permission: string; +}; + +export type SetPermission = { + userId?: number; + teamId?: number; + builtInRole?: string; + permission: string; + target: PermissionTarget; +}; + +export enum PermissionTarget { + Team = 'Team', + User = 'User', + BuiltInRole = 'builtInRole', +} +export type Description = { + assignments: Assignments; + permissions: string[]; +}; + +export type Assignments = { + users: boolean; + teams: boolean; + builtInRoles: boolean; +}; diff --git a/public/app/core/components/Animations/FadeIn.tsx b/public/app/core/components/Animations/FadeIn.tsx new file mode 100644 index 00000000..bf047393 --- /dev/null +++ b/public/app/core/components/Animations/FadeIn.tsx @@ -0,0 +1,44 @@ +import React, { FC, CSSProperties } from 'react'; +import Transition, { ExitHandler } from 'react-transition-group/Transition'; + +interface Props { + duration: number; + children: JSX.Element; + in: boolean; + unmountOnExit?: boolean; + onExited?: ExitHandler; +} + +export const FadeIn: FC = (props) => { + const defaultStyle: CSSProperties = { + transition: `opacity ${props.duration}ms linear`, + opacity: 0, + }; + + const transitionStyles: { [str: string]: CSSProperties } = { + exited: { opacity: 0, display: 'none' }, + entering: { opacity: 0 }, + entered: { opacity: 1 }, + exiting: { opacity: 0 }, + }; + + return ( + + {(state) => ( +
+ {props.children} +
+ )} +
+ ); +}; diff --git a/public/app/core/components/Animations/SlideDown.tsx b/public/app/core/components/Animations/SlideDown.tsx new file mode 100644 index 00000000..3f550d2f --- /dev/null +++ b/public/app/core/components/Animations/SlideDown.tsx @@ -0,0 +1,51 @@ +import React, { CSSProperties, FC } from 'react'; +import Transition from 'react-transition-group/Transition'; + +interface Style { + transition?: string; + overflow?: string; +} + +// When animating using max-height we need to use a static value. +// If this is not enough, pass in + + {appNotifications.map((appNotification, index) => { + return ( + this.onClearAppNotification(id)} + /> + ); + })} + +
+ ); + } +} + +export const AppNotificationList = connector(AppNotificationListUnConnected); diff --git a/public/app/core/components/Branding/Branding.tsx b/public/app/core/components/Branding/Branding.tsx new file mode 100644 index 00000000..15035264 --- /dev/null +++ b/public/app/core/components/Branding/Branding.tsx @@ -0,0 +1,66 @@ +import React, { FC } from 'react'; +import { css, cx } from '@emotion/css'; +import { useTheme2, styleMixins } from '@grafana/ui'; +import { colorManipulator } from '@grafana/data'; + +export interface BrandComponentProps { + className?: string; + children?: JSX.Element | JSX.Element[]; +} + +const LoginLogo: FC = ({ className }) => { + return Grafana; +}; + +const LoginBackground: FC = ({ className, children }) => { + const theme = useTheme2(); + + const background = css` + &:before { + content: ''; + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; + background: url(public/img/g8_login_${theme.isDark ? 'dark' : 'light'}.svg); + background-position: top center; + background-size: auto; + background-repeat: no-repeat; + + opacity: 0; + transition: opacity 3s ease-in-out; + + @media ${styleMixins.mediaUp(theme.v1.breakpoints.md)} { + background-position: center; + background-size: cover; + } + } + `; + + return
{children}
; +}; + +const MenuLogo: FC = ({ className }) => { + return Grafana; +}; + +const LoginBoxBackground = () => { + const theme = useTheme2(); + return css` + background: ${colorManipulator.alpha(theme.colors.background.primary, 0.7)}; + background-size: cover; + `; +}; + +export class Branding { + static LoginLogo = LoginLogo; + static LoginBackground = LoginBackground; + static MenuLogo = MenuLogo; + static LoginBoxBackground = LoginBoxBackground; + static AppTitle = 'Grafana'; + static LoginTitle = 'Welcome to Grafana'; + static GetLoginSubTitle = (): null | string => { + return null; + }; +} diff --git a/public/app/core/components/CardButton.tsx b/public/app/core/components/CardButton.tsx new file mode 100644 index 00000000..45d87b60 --- /dev/null +++ b/public/app/core/components/CardButton.tsx @@ -0,0 +1,52 @@ +import React, { HTMLAttributes } from 'react'; +import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Icon, IconName, useStyles2 } from '@grafana/ui'; + +interface Props extends HTMLAttributes { + icon: IconName; + onClick: () => void; + children: React.ReactNode; +} + +export const CardButton = React.forwardRef( + ({ icon, children, onClick, ...restProps }, ref) => { + const styles = useStyles2(getStyles); + + return ( + + ); + } +); + +CardButton.displayName = 'CardButton'; + +const getStyles = (theme: GrafanaTheme2) => { + return { + action: css` + display: flex; + flex-direction: column; + height: 100%; + + justify-self: center; + cursor: pointer; + background: ${theme.colors.background.secondary}; + border-radius: ${theme.shape.borderRadius(1)}; + color: ${theme.colors.text.primary}; + border: unset; + width: 100%; + display: flex; + + justify-content: center; + align-items: center; + text-align: center; + + &:hover { + background: ${theme.colors.emphasize(theme.colors.background.secondary)}; + } + `, + }; +}; diff --git a/public/app/core/components/CloseButton/CloseButton.tsx b/public/app/core/components/CloseButton/CloseButton.tsx new file mode 100644 index 00000000..fc66c1a6 --- /dev/null +++ b/public/app/core/components/CloseButton/CloseButton.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { css } from '@emotion/css'; +import { IconButton, useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; + +type Props = { + onClick: () => void; + 'aria-label'?: string; +}; + +export const CloseButton: React.FC = ({ onClick, 'aria-label': ariaLabel }) => { + const styles = useStyles2(getStyles); + return ; +}; + +const getStyles = (theme: GrafanaTheme2) => + css` + position: absolute; + right: ${theme.spacing(0.5)}; + top: ${theme.spacing(1)}; + `; diff --git a/public/app/core/components/CopyToClipboard/CopyToClipboard.tsx b/public/app/core/components/CopyToClipboard/CopyToClipboard.tsx new file mode 100644 index 00000000..0b618d09 --- /dev/null +++ b/public/app/core/components/CopyToClipboard/CopyToClipboard.tsx @@ -0,0 +1,78 @@ +import React, { PureComponent, ReactNode } from 'react'; +import ClipboardJS from 'clipboard'; + +interface Props { + text: () => string; + elType?: string | React.ForwardRefExoticComponent; + onSuccess?: (evt: any) => void; + onError?: (evt: any) => void; + className?: string; + children?: ReactNode; +} + +export class CopyToClipboard extends PureComponent { + clipboardjs?: ClipboardJS; + myRef: any; + + constructor(props: Props) { + super(props); + this.myRef = React.createRef(); + } + + componentDidMount() { + this.initClipboardJS(); + } + + componentDidUpdate() { + if (this.clipboardjs) { + this.clipboardjs.destroy(); + } + this.initClipboardJS(); + } + + initClipboardJS = () => { + const { text, onSuccess, onError } = this.props; + + this.clipboardjs = new ClipboardJS(this.myRef.current, { + text: text, + }); + + if (onSuccess) { + this.clipboardjs.on('success', (evt) => { + evt.clearSelection(); + onSuccess(evt); + }); + } + + if (onError) { + this.clipboardjs.on('error', (evt) => { + console.error('Action:', evt.action); + console.error('Trigger:', evt.trigger); + onError(evt); + }); + } + }; + + componentWillUnmount() { + if (this.clipboardjs) { + this.clipboardjs.destroy(); + } + } + + getElementType = () => { + return this.props.elType || 'button'; + }; + + render() { + const { elType, text, children, onError, onSuccess, ...restProps } = this.props; + + return React.createElement( + this.getElementType(), + { + ref: this.myRef, + ...restProps, + }, + this.props.children + ); + } +} diff --git a/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx b/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx new file mode 100644 index 00000000..a235c9a4 --- /dev/null +++ b/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx @@ -0,0 +1,45 @@ +import React, { FunctionComponent } from 'react'; +import { Button, stylesFactory } from '@grafana/ui'; +import { css } from '@emotion/css'; +import { useUrlParams } from 'app/core/navigation/hooks'; + +const getStyles = stylesFactory(() => { + return css` + width: 508px; + margin: 128px auto; + `; +}); + +interface Props { + error: Error | null; +} + +export const ErrorLoadingChunk: FunctionComponent = ({ error }) => { + const [params, updateUrlParams] = useUrlParams(); + + if (!params.get('chunkNotFound')) { + updateUrlParams({ chunkNotFound: true }, true); + window.location.reload(); + } + + return ( +
+

Unable to find application file

+
+

Grafana has likely been updated. Please try reloading the page.

+
+
+ +
+
+ {error && error.message ? error.message : 'Unexpected error occurred'} +
+ {error && error.stack ? error.stack : null} +
+
+ ); +}; + +ErrorLoadingChunk.displayName = 'ErrorLoadingChunk'; diff --git a/public/app/core/components/DynamicImports/LoadingChunkPlaceHolder.tsx b/public/app/core/components/DynamicImports/LoadingChunkPlaceHolder.tsx new file mode 100644 index 00000000..a5813a03 --- /dev/null +++ b/public/app/core/components/DynamicImports/LoadingChunkPlaceHolder.tsx @@ -0,0 +1,10 @@ +import React, { FunctionComponent } from 'react'; +import { LoadingPlaceholder } from '@grafana/ui'; + +export const LoadingChunkPlaceHolder: FunctionComponent = React.memo(() => ( +
+ +
+)); + +LoadingChunkPlaceHolder.displayName = 'LoadingChunkPlaceHolder'; diff --git a/public/app/core/components/DynamicImports/SafeDynamicImport.test.tsx b/public/app/core/components/DynamicImports/SafeDynamicImport.test.tsx new file mode 100644 index 00000000..3dbfe7b5 --- /dev/null +++ b/public/app/core/components/DynamicImports/SafeDynamicImport.test.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { loadComponentHandler } from './SafeDynamicImport'; +import { ErrorLoadingChunk } from './ErrorLoadingChunk'; +import { LoadingChunkPlaceHolder } from './LoadingChunkPlaceHolder'; + +describe('loadComponentHandler', () => { + describe('when there is no error and pastDelay is false', () => { + it('then it should return null', () => { + const error: Error | null = null; + const pastDelay = false; + const element = loadComponentHandler({ error: (error as unknown) as Error, pastDelay }); + + expect(element).toBe(null); + }); + }); + + describe('when there is an error', () => { + it('then it should return ErrorLoadingChunk', () => { + const error: Error = new Error('Some chunk failed to load'); + const pastDelay = false; + const element = loadComponentHandler({ error, pastDelay }); + + expect(element).toEqual(); + }); + }); + + describe('when loading is taking more then default delay of 200ms', () => { + it('then it should return LoadingChunkPlaceHolder', () => { + const error: Error | null = null; + const pastDelay = true; + const element = loadComponentHandler({ error: (error as unknown) as Error, pastDelay }); + + expect(element).toEqual(); + }); + }); +}); diff --git a/public/app/core/components/DynamicImports/SafeDynamicImport.tsx b/public/app/core/components/DynamicImports/SafeDynamicImport.tsx new file mode 100644 index 00000000..4544d88a --- /dev/null +++ b/public/app/core/components/DynamicImports/SafeDynamicImport.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import Loadable from 'react-loadable'; +import { LoadingChunkPlaceHolder } from './LoadingChunkPlaceHolder'; +import { ErrorLoadingChunk } from './ErrorLoadingChunk'; +import { GrafanaRouteComponent } from 'app/core/navigation/types'; + +export const loadComponentHandler = (props: { error: Error; pastDelay: boolean }) => { + const { error, pastDelay } = props; + + if (error) { + return ; + } + + if (pastDelay) { + return ; + } + + return null; +}; + +export const SafeDynamicImport = (loader: () => Promise): GrafanaRouteComponent => + Loadable({ + loader: loader, + loading: loadComponentHandler, + }); diff --git a/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx b/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx new file mode 100644 index 00000000..a8c7220f --- /dev/null +++ b/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx @@ -0,0 +1,95 @@ +import React, { MouseEvent } from 'react'; +import { css } from '@emotion/css'; +import { CallToActionCard, Icon, IconName, LinkButton } from '@grafana/ui'; +import { selectors } from '@grafana/e2e-selectors'; + +export interface Props { + title: string; + buttonIcon: IconName; + buttonLink?: string; + buttonTitle: string; + buttonDisabled?: boolean; + onClick?: (event: MouseEvent) => void; + proTip?: string; + proTipLink?: string; + proTipLinkTitle?: string; + proTipTarget?: string; + infoBox?: { __html: string }; + infoBoxTitle?: string; +} + +const ctaStyle = css` + text-align: center; +`; + +const infoBoxStyles = css` + max-width: 700px; + margin: 0 auto; +`; + +const EmptyListCTA: React.FunctionComponent = ({ + title, + buttonIcon, + buttonLink, + buttonTitle, + buttonDisabled, + onClick, + proTip, + proTipLink, + proTipLinkTitle, + proTipTarget, + infoBox, + infoBoxTitle, +}) => { + const footer = () => { + return ( + <> + {proTip ? ( + + + <> ProTip: {proTip} + {proTipLink && ( + + {proTipLinkTitle} + + )} + + ) : ( + '' + )} + {infoBox ? ( +
+ {infoBoxTitle &&
{infoBoxTitle}
} +
+
+ ) : ( + '' + )} + + ); + }; + + const ctaElementClassName = !footer() + ? css` + margin-bottom: 20px; + ` + : ''; + + const ctaElement = ( + + {buttonTitle} + + ); + + return ; +}; + +export default EmptyListCTA; diff --git a/public/app/core/components/ErrorPage/ErrorPage.tsx b/public/app/core/components/ErrorPage/ErrorPage.tsx new file mode 100644 index 00000000..d1263769 --- /dev/null +++ b/public/app/core/components/ErrorPage/ErrorPage.tsx @@ -0,0 +1,90 @@ +import React, { PureComponent } from 'react'; +import { connect, MapStateToProps } from 'react-redux'; +import { NavModel } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { Icon } from '@grafana/ui'; +import Page from '../Page/Page'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types'; + +interface ConnectedProps { + navModel: NavModel; +} + +interface OwnProps {} + +type Props = ConnectedProps; + +export class ErrorPage extends PureComponent { + render() { + const { navModel } = this.props; + return ( + + +
+
+
+
+
+

100%

+

80%

+

60%

+

40%

+

20%

+

0%

+
+
+ graph +
+

Then

+

Now

+
+
+
+
+
+
+

current

+
+
+ +
+
+

Chances you are on the page you are looking for.

+

0%

+
+
+

Sorry for the inconvenience

+

+ Please go back to your{' '} + + home dashboard + {' '} + and try again. +

+

+ If the error persists, seek help on the{' '} + + community site + + . +

+
+
+
+
+
+
+
+
+ ); + } +} + +const mapStateToProps: MapStateToProps = (state) => { + return { + navModel: getNavModel(state.navIndex, 'not-found'), + }; +}; + +export default connect(mapStateToProps)(ErrorPage); diff --git a/public/app/core/components/FolderFilter/FolderFilter.tsx b/public/app/core/components/FolderFilter/FolderFilter.tsx new file mode 100644 index 00000000..37cc3e04 --- /dev/null +++ b/public/app/core/components/FolderFilter/FolderFilter.tsx @@ -0,0 +1,106 @@ +import React, { useCallback, useMemo, useState } from 'react'; +import { css } from '@emotion/css'; +import debounce from 'debounce-promise'; +import { AsyncMultiSelect, Icon, useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; + +import { FolderInfo, PermissionLevelString } from 'app/types'; +import { getBackendSrv } from 'app/core/services/backend_srv'; + +export interface FolderFilterProps { + onChange: (folder: FolderInfo[]) => void; + maxMenuHeight?: number; +} + +export function FolderFilter({ onChange: propsOnChange, maxMenuHeight }: FolderFilterProps): JSX.Element { + const styles = useStyles2(getStyles); + const [loading, setLoading] = useState(false); + const getOptions = useCallback((searchString: string) => getFoldersAsOptions(searchString, setLoading), []); + const debouncedLoadOptions = useMemo(() => debounce(getOptions, 300), [getOptions]); + const [value, setValue] = useState>>([]); + const onChange = useCallback( + (folders: Array>) => { + const changedFolders = []; + for (const folder of folders) { + if (folder.value) { + changedFolders.push(folder.value); + } + } + propsOnChange(changedFolders); + setValue(folders); + }, + [propsOnChange] + ); + const selectOptions = { + defaultOptions: true, + isMulti: true, + noOptionsMessage: 'No folders found', + placeholder: 'Filter by folder', + maxMenuHeight, + value, + onChange, + }; + + return ( +
+ {value.length > 0 && ( + onChange([])}> + Clear folders + + )} + } + aria-label="Folder filter" + /> +
+ ); +} + +async function getFoldersAsOptions(searchString: string, setLoading: (loading: boolean) => void) { + setLoading(true); + + const params = { + query: searchString, + type: 'dash-folder', + permission: PermissionLevelString.View, + }; + + const searchHits = await getBackendSrv().search(params); + const options = searchHits.map((d) => ({ label: d.title, value: { id: d.id, title: d.title } })); + if (!searchString || 'general'.includes(searchString.toLowerCase())) { + options.unshift({ label: 'General', value: { id: 0, title: 'General' } }); + } + + setLoading(false); + + return options; +} + +function getStyles(theme: GrafanaTheme2) { + return { + container: css` + label: container; + position: relative; + min-width: 180px; + flex-grow: 1; + `, + clear: css` + label: clear; + text-decoration: underline; + font-size: ${theme.spacing(1.5)}; + position: absolute; + top: -${theme.spacing(2.75)}; + right: 0; + cursor: pointer; + color: ${theme.colors.text.link}; + + &:hover { + color: ${theme.colors.text.maxContrast}; + } + `, + }; +} diff --git a/public/app/core/components/Footer/Footer.tsx b/public/app/core/components/Footer/Footer.tsx new file mode 100644 index 00000000..9096de39 --- /dev/null +++ b/public/app/core/components/Footer/Footer.tsx @@ -0,0 +1,90 @@ +import React, { FC } from 'react'; +import config from 'app/core/config'; +import { Icon, IconName } from '@grafana/ui'; + +export interface FooterLink { + text: string; + id?: string; + icon?: string; + url?: string; + target?: string; +} + +export let getFooterLinks = (): FooterLink[] => { + return [ + { + text: 'Documentation', + icon: 'document-info', + url: 'https://grafana.com/docs/grafana/latest/?utm_source=grafana_footer', + target: '_blank', + }, + { + text: 'Support', + icon: 'question-circle', + url: 'https://grafana.com/products/enterprise/?utm_source=grafana_footer', + target: '_blank', + }, + { + text: 'Community', + icon: 'comments-alt', + url: 'https://community.grafana.com/?utm_source=grafana_footer', + target: '_blank', + }, + ]; +}; + +export let getVersionLinks = (): FooterLink[] => { + const { buildInfo, licenseInfo } = config; + const links: FooterLink[] = []; + const stateInfo = licenseInfo.stateInfo ? ` (${licenseInfo.stateInfo})` : ''; + + links.push({ text: `${buildInfo.edition}${stateInfo}`, url: licenseInfo.licenseUrl }); + + if (buildInfo.hideVersion) { + return links; + } + + links.push({ text: `v${buildInfo.version} (${buildInfo.commit})` }); + + if (buildInfo.hasUpdate) { + links.push({ + id: 'updateVersion', + text: `New version available!`, + icon: 'download-alt', + url: 'https://grafana.com/grafana/download?utm_source=grafana_footer', + target: '_blank', + }); + } + + return links; +}; + +export function setFooterLinksFn(fn: typeof getFooterLinks) { + getFooterLinks = fn; +} + +export function setVersionLinkFn(fn: typeof getFooterLinks) { + getVersionLinks = fn; +} + +export const Footer: FC = React.memo(() => { + const links = getFooterLinks().concat(getVersionLinks()); + + return ( + + ); +}); + +Footer.displayName = 'Footer'; diff --git a/public/app/core/components/ForgottenPassword/ChangePassword.tsx b/public/app/core/components/ForgottenPassword/ChangePassword.tsx new file mode 100644 index 00000000..69c813b4 --- /dev/null +++ b/public/app/core/components/ForgottenPassword/ChangePassword.tsx @@ -0,0 +1,62 @@ +import React, { FC, SyntheticEvent } from 'react'; +import { Tooltip, Form, Field, VerticalGroup, Button } from '@grafana/ui'; +import { selectors } from '@grafana/e2e-selectors'; +import { submitButton } from '../Login/LoginForm'; +import { PasswordField } from '../PasswordField/PasswordField'; +interface Props { + onSubmit: (pw: string) => void; + onSkip?: (event?: SyntheticEvent) => void; +} + +interface PasswordDTO { + newPassword: string; + confirmNew: string; +} + +export const ChangePassword: FC = ({ onSubmit, onSkip }) => { + const submit = (passwords: PasswordDTO) => { + onSubmit(passwords.newPassword); + }; + return ( + + {({ errors, register, getValues }) => ( + <> + + + + + v === getValues().newPassword || 'Passwords must match!', + })} + /> + + + + + {onSkip && ( + + + + )} + + + )} + + ); +}; diff --git a/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx b/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx new file mode 100644 index 00000000..c8a92dcf --- /dev/null +++ b/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx @@ -0,0 +1,82 @@ +import React from 'react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; + +import { ChangePasswordPage, Props } from './ChangePasswordPage'; + +const postMock = jest.fn(); +jest.mock('@grafana/runtime', () => ({ + getBackendSrv: () => ({ + post: postMock, + }), +})); + +jest.mock('app/core/config', () => { + return { + loginError: false, + buildInfo: { + version: 'v1.0', + commit: '1', + env: 'production', + edition: 'Open Source', + isEnterprise: false, + }, + licenseInfo: { + stateInfo: '', + licenseUrl: '', + }, + appSubUrl: '', + }; +}); +const props: Props = { + ...getRouteComponentProps({ + queryParams: { code: 'some code' }, + }), +}; + +describe('ChangePassword Page', () => { + it('renders correctly', () => { + render(); + + expect(screen.getByLabelText('New password')).toBeInTheDocument(); + expect(screen.getByLabelText('Confirm new password')).toBeInTheDocument(); + + expect(screen.getByRole('button', { name: 'Submit' })).toBeInTheDocument(); + }); + it('should pass validation checks for password and confirm password field', async () => { + render(); + + fireEvent.click(screen.getByRole('button', { name: 'Submit' })); + expect(await screen.findByText('New Password is required')).toBeInTheDocument(); + expect(screen.getByText('Confirmed Password is required')).toBeInTheDocument(); + + userEvent.type(screen.getByLabelText('New password'), 'admin'); + userEvent.type(screen.getByLabelText('Confirm new password'), 'a'); + await waitFor(() => expect(screen.getByText('Passwords must match!')).toBeInTheDocument()); + + userEvent.type(screen.getByLabelText('Confirm new password'), 'dmin'); + await waitFor(() => expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument()); + }); + it('should navigate to default url if change password is successful', async () => { + Object.defineProperty(window, 'location', { + value: { + assign: jest.fn(), + }, + }); + postMock.mockResolvedValueOnce({ message: 'Logged in' }); + render(); + + userEvent.type(screen.getByLabelText('New password'), 'test'); + userEvent.type(screen.getByLabelText('Confirm new password'), 'test'); + fireEvent.click(screen.getByRole('button', { name: 'Submit' })); + await waitFor(() => + expect(postMock).toHaveBeenCalledWith('/api/user/password/reset', { + code: 'some code', + confirmPassword: 'test', + newPassword: 'test', + }) + ); + expect(window.location.assign).toHaveBeenCalledWith('/'); + }); +}); diff --git a/public/app/core/components/ForgottenPassword/ChangePasswordPage.tsx b/public/app/core/components/ForgottenPassword/ChangePasswordPage.tsx new file mode 100644 index 00000000..55bb5da3 --- /dev/null +++ b/public/app/core/components/ForgottenPassword/ChangePasswordPage.tsx @@ -0,0 +1,21 @@ +import React, { FC } from 'react'; +import { LoginLayout, InnerBox } from '../Login/LoginLayout'; +import { ChangePassword } from './ChangePassword'; +import LoginCtrl from '../Login/LoginCtrl'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; + +export interface Props extends GrafanaRouteComponentProps<{}, { code: string }> {} + +export const ChangePasswordPage: FC = (props) => { + return ( + + + + {({ changePassword }) => } + + + + ); +}; + +export default ChangePasswordPage; diff --git a/public/app/core/components/ForgottenPassword/ForgottenPassword.tsx b/public/app/core/components/ForgottenPassword/ForgottenPassword.tsx new file mode 100644 index 00000000..94b4f0b2 --- /dev/null +++ b/public/app/core/components/ForgottenPassword/ForgottenPassword.tsx @@ -0,0 +1,72 @@ +import React, { FC, useState } from 'react'; +import { Form, Field, Input, Button, Legend, Container, useStyles, HorizontalGroup, LinkButton } from '@grafana/ui'; +import { getBackendSrv } from '@grafana/runtime'; +import { css } from '@emotion/css'; +import { GrafanaTheme } from '@grafana/data'; +import config from 'app/core/config'; + +interface EmailDTO { + userOrEmail: string; +} + +const paragraphStyles = (theme: GrafanaTheme) => css` + color: ${theme.colors.formDescription}; + font-size: ${theme.typography.size.sm}; + font-weight: ${theme.typography.weight.regular}; + margin-top: ${theme.spacing.sm}; + display: block; +`; + +export const ForgottenPassword: FC = () => { + const [emailSent, setEmailSent] = useState(false); + const styles = useStyles(paragraphStyles); + const loginHref = `${config.appSubUrl}/login`; + + const sendEmail = async (formModel: EmailDTO) => { + const res = await getBackendSrv().post('/api/user/password/send-reset-email', formModel); + if (res) { + setEmailSent(true); + } + }; + + if (emailSent) { + return ( +
+

An email with a reset link has been sent to the email address. You should receive it shortly.

+ + + Back to login + +
+ ); + } + return ( +
+ {({ register, errors }) => ( + <> + Reset password + + + + + + + Back to login + + + +

Did you forget your username or email? Contact your Grafana administrator.

+ + )} +
+ ); +}; diff --git a/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx b/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx new file mode 100644 index 00000000..57b5ccbc --- /dev/null +++ b/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { SendResetMailPage } from './SendResetMailPage'; + +const postMock = jest.fn(); +jest.mock('@grafana/runtime', () => ({ + getBackendSrv: () => ({ + post: postMock, + }), +})); + +jest.mock('app/core/config', () => { + return { + buildInfo: { + version: 'v1.0', + commit: '1', + env: 'production', + edition: 'Open Source', + isEnterprise: false, + }, + licenseInfo: { + stateInfo: '', + licenseUrl: '', + }, + appSubUrl: '', + }; +}); + +describe('VerifyEmail Page', () => { + it('renders correctly', () => { + render(); + expect(screen.getByText('Reset password')).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: /User Enter your information/i })).toBeInTheDocument(); + + expect(screen.getByRole('button', { name: 'Send reset email' })).toBeInTheDocument(); + + expect(screen.getByRole('link', { name: 'Back to login' })).toBeInTheDocument(); + expect(screen.getByRole('link', { name: 'Back to login' })).toHaveAttribute('href', '/login'); + }); + it('should pass validation checks for email field', async () => { + render(); + + fireEvent.click(screen.getByRole('button', { name: 'Send reset email' })); + expect(await screen.findByText('Email or username is required')).toBeInTheDocument(); + + userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com'); + await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument()); + }); + it('should show success meessage if reset-password is successful', async () => { + postMock.mockResolvedValueOnce({ message: 'Email sent' }); + render(); + + userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com'); + fireEvent.click(screen.getByRole('button', { name: 'Send reset email' })); + await waitFor(() => + expect(postMock).toHaveBeenCalledWith('/api/user/password/send-reset-email', { + userOrEmail: 'test@gmail.com', + }) + ); + expect(screen.getByText(/An email with a reset link/i)).toBeInTheDocument(); + expect(screen.getByRole('link', { name: 'Back to login' })).toBeInTheDocument(); + expect(screen.getByRole('link', { name: 'Back to login' })).toHaveAttribute('href', '/login'); + }); +}); diff --git a/public/app/core/components/ForgottenPassword/SendResetMailPage.tsx b/public/app/core/components/ForgottenPassword/SendResetMailPage.tsx new file mode 100644 index 00000000..1ab5a36f --- /dev/null +++ b/public/app/core/components/ForgottenPassword/SendResetMailPage.tsx @@ -0,0 +1,14 @@ +import React, { FC } from 'react'; + +import { LoginLayout, InnerBox } from '../Login/LoginLayout'; +import { ForgottenPassword } from './ForgottenPassword'; + +export const SendResetMailPage: FC = () => ( + + + + + +); + +export default SendResetMailPage; diff --git a/public/app/core/components/Layers/AddLayerButton.tsx b/public/app/core/components/Layers/AddLayerButton.tsx new file mode 100644 index 00000000..27273528 --- /dev/null +++ b/public/app/core/components/Layers/AddLayerButton.tsx @@ -0,0 +1,23 @@ +import React from 'react'; + +import { ValuePicker } from '@grafana/ui'; +import { SelectableValue } from '@grafana/data'; + +type AddLayerButtonProps = { + onChange: (sel: SelectableValue) => void; + options: Array>; + label: string; +}; + +export const AddLayerButton = ({ onChange, options, label }: AddLayerButtonProps) => { + return ( + + ); +}; diff --git a/public/app/core/components/Layers/LayerDragDropList.tsx b/public/app/core/components/Layers/LayerDragDropList.tsx new file mode 100644 index 00000000..282ed0be --- /dev/null +++ b/public/app/core/components/Layers/LayerDragDropList.tsx @@ -0,0 +1,172 @@ +import React from 'react'; +import { DragDropContext, Draggable, Droppable, DropResult } from 'react-beautiful-dnd'; +import { css, cx } from '@emotion/css'; +import { Icon, IconButton, stylesFactory } from '@grafana/ui'; +import { GrafanaTheme } from '@grafana/data'; +import { config } from '@grafana/runtime'; + +import { LayerName } from './LayerName'; +import { LayerElement } from './types'; + +type LayerDragDropListProps = { + layers: T[]; + getLayerInfo: (element: T) => string; + onDragEnd: (result: DropResult) => void; + onSelect: (element: T) => any; + onDelete: (element: T) => any; + onDuplicate?: (element: T) => any; + isGroup?: (element: T) => boolean; + selection?: string[]; // list of unique ids (names) + excludeBaseLayer?: boolean; + onNameChange: (element: T, newName: string) => any; + verifyLayerNameUniqueness?: (nameToCheck: string) => boolean; +}; + +export const LayerDragDropList = ({ + layers, + getLayerInfo, + onDragEnd, + onSelect, + onDelete, + onDuplicate, + isGroup, + selection, + excludeBaseLayer, + onNameChange, + verifyLayerNameUniqueness, +}: LayerDragDropListProps) => { + const style = styles(config.theme); + + const getRowStyle = (isSelected: boolean) => { + return isSelected ? `${style.row} ${style.sel}` : style.row; + }; + + return ( + + + {(provided, snapshot) => ( +
+ {(() => { + // reverse order + const rows: any = []; + const lastLayerIndex = excludeBaseLayer ? 1 : 0; + const shouldRenderDragIconLengthThreshold = excludeBaseLayer ? 2 : 1; + for (let i = layers.length - 1; i >= lastLayerIndex; i--) { + const element = layers[i]; + const uid = element.getName(); + + const isSelected = Boolean(selection?.includes(uid)); + rows.push( + + {(provided, snapshot) => ( +
onSelect(element)} + > + onNameChange(element, v)} + verifyLayerNameUniqueness={verifyLayerNameUniqueness ?? undefined} + /> +
  {getLayerInfo(element)}
+ + {!isGroup!(element) && ( + <> + {onDuplicate ? ( + onDuplicate(element)} + surface="header" + /> + ) : null} + + onDelete(element)} + surface="header" + /> + {layers.length > shouldRenderDragIconLengthThreshold && ( + + )} + + )} +
+ )} +
+ ); + } + + return rows; + })()} + + {provided.placeholder} +
+ )} +
+
+ ); +}; + +LayerDragDropList.defaultProps = { + isGroup: () => false, +}; + +const styles = stylesFactory((theme: GrafanaTheme) => ({ + wrapper: css` + margin-bottom: ${theme.spacing.md}; + `, + row: css` + padding: ${theme.spacing.xs} ${theme.spacing.sm}; + border-radius: ${theme.border.radius.sm}; + background: ${theme.colors.bg2}; + min-height: ${theme.spacing.formInputHeight}px; + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 3px; + cursor: pointer; + + border: 1px solid ${theme.colors.formInputBorder}; + &:hover { + border: 1px solid ${theme.colors.formInputBorderHover}; + } + `, + sel: css` + border: 1px solid ${theme.colors.formInputBorderActive}; + &:hover { + border: 1px solid ${theme.colors.formInputBorderActive}; + } + `, + dragIcon: css` + cursor: drag; + `, + actionIcon: css` + color: ${theme.colors.textWeak}; + &:hover { + color: ${theme.colors.text}; + } + `, + typeWrapper: css` + color: ${theme.colors.textBlue}; + margin-right: 5px; + `, + textWrapper: css` + display: flex; + align-items: center; + flex-grow: 1; + overflow: hidden; + margin-right: ${theme.spacing.sm}; + `, +})); diff --git a/public/app/core/components/Layers/LayerName.test.tsx b/public/app/core/components/Layers/LayerName.test.tsx new file mode 100644 index 00000000..0fda27cf --- /dev/null +++ b/public/app/core/components/Layers/LayerName.test.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { LayerNameProps, LayerName } from './LayerName'; + +describe('LayerName', () => { + it('Can edit title', () => { + const scenario = renderScenario({}); + screen.getByTestId('layer-name-div').click(); + + const input = screen.getByTestId('layer-name-input'); + fireEvent.change(input, { target: { value: 'new name' } }); + fireEvent.blur(input); + + expect((scenario.props.onChange as any).mock.calls[0][0]).toBe('new name'); + }); + + it('Show error when empty name is specified', async () => { + renderScenario({}); + + screen.getByTestId('layer-name-div').click(); + const input = screen.getByTestId('layer-name-input'); + fireEvent.change(input, { target: { value: '' } }); + const alert = await screen.findByRole('alert'); + + expect(alert.textContent).toBe('An empty layer name is not allowed'); + }); + + it('Show error when other layer with same name exists', async () => { + renderScenario({}); + + screen.getByTestId('layer-name-div').click(); + const input = screen.getByTestId('layer-name-input'); + fireEvent.change(input, { target: { value: 'Layer 2' } }); + const alert = await screen.findByRole('alert'); + + expect(alert.textContent).toBe('Layer name already exists'); + }); + + function renderScenario(overrides: Partial) { + const props: LayerNameProps = { + name: 'Layer 1', + onChange: jest.fn(), + verifyLayerNameUniqueness: (nameToCheck: string) => { + const names = new Set(['Layer 1', 'Layer 2']); + return !names.has(nameToCheck); + }, + }; + + Object.assign(props, overrides); + + return { + props, + renderResult: render(), + }; + } +}); diff --git a/public/app/core/components/Layers/LayerName.tsx b/public/app/core/components/Layers/LayerName.tsx new file mode 100644 index 00000000..c229d7f0 --- /dev/null +++ b/public/app/core/components/Layers/LayerName.tsx @@ -0,0 +1,157 @@ +import React, { useState } from 'react'; +import { css, cx } from '@emotion/css'; +import { Icon, Input, FieldValidationMessage, useStyles } from '@grafana/ui'; +import { GrafanaTheme } from '@grafana/data'; + +export interface LayerNameProps { + name: string; + onChange: (v: string) => void; + verifyLayerNameUniqueness?: (nameToCheck: string) => boolean; +} + +export const LayerName = ({ name, onChange, verifyLayerNameUniqueness }: LayerNameProps) => { + const styles = useStyles(getStyles); + + const [isEditing, setIsEditing] = useState(false); + const [validationError, setValidationError] = useState(null); + + const onEditLayer = (event: React.SyntheticEvent) => { + setIsEditing(true); + }; + + const onEndEditName = (newName: string) => { + setIsEditing(false); + + if (validationError) { + setValidationError(null); + return; + } + + if (name !== newName) { + onChange(newName); + } + }; + + const onInputChange = (event: React.SyntheticEvent) => { + const newName = event.currentTarget.value.trim(); + + if (newName.length === 0) { + setValidationError('An empty layer name is not allowed'); + return; + } + + if (verifyLayerNameUniqueness && !verifyLayerNameUniqueness(newName) && newName !== name) { + setValidationError('Layer name already exists'); + return; + } + + if (validationError) { + setValidationError(null); + } + }; + + const onEditLayerBlur = (event: React.SyntheticEvent) => { + onEndEditName(event.currentTarget.value.trim()); + }; + + const onKeyDown = (event: React.KeyboardEvent) => { + if (event.key === 'Enter') { + onEndEditName((event.target as any).value); + } + }; + + const onFocus = (event: React.FocusEvent) => { + event.target.select(); + }; + + return ( + <> +
+ {!isEditing && ( + + )} + + {isEditing && ( + <> + + {validationError && {validationError}} + + )} +
+ + ); +}; + +const getStyles = (theme: GrafanaTheme) => { + return { + wrapper: css` + label: Wrapper; + display: flex; + align-items: center; + margin-left: ${theme.spacing.xs}; + `, + layerNameWrapper: css` + display: flex; + cursor: pointer; + border: 1px solid transparent; + border-radius: ${theme.border.radius.md}; + align-items: center; + padding: 0 0 0 ${theme.spacing.xs}; + margin: 0; + background: transparent; + + &:hover { + background: ${theme.colors.bg3}; + border: 1px dashed ${theme.colors.border3}; + } + + &:focus { + border: 2px solid ${theme.colors.formInputBorderActive}; + } + + &:hover, + &:focus { + .query-name-edit-icon { + visibility: visible; + } + } + `, + layerName: css` + font-weight: ${theme.typography.weight.semibold}; + color: ${theme.colors.textBlue}; + cursor: pointer; + overflow: hidden; + margin-left: ${theme.spacing.xs}; + `, + layerEditIcon: cx( + css` + margin-left: ${theme.spacing.md}; + visibility: hidden; + `, + 'query-name-edit-icon' + ), + layerNameInput: css` + max-width: 300px; + margin: -4px 0; + `, + }; +}; diff --git a/public/app/core/components/Layers/types.ts b/public/app/core/components/Layers/types.ts new file mode 100644 index 00000000..cf65396c --- /dev/null +++ b/public/app/core/components/Layers/types.ts @@ -0,0 +1,4 @@ +/** An interface that has a getName method */ +export interface LayerElement { + getName: () => string; +} diff --git a/public/app/core/components/LocalStorageValueProvider/LocalStorageValueProvider.tsx b/public/app/core/components/LocalStorageValueProvider/LocalStorageValueProvider.tsx new file mode 100644 index 00000000..c8923f3e --- /dev/null +++ b/public/app/core/components/LocalStorageValueProvider/LocalStorageValueProvider.tsx @@ -0,0 +1,51 @@ +import React, { PureComponent } from 'react'; +import store from '../../store'; + +export interface Props { + storageKey: string; + defaultValue: T; + children: (value: T, onSaveToStore: (value: T) => void, onDeleteFromStore: () => void) => React.ReactNode; +} + +interface State { + value: T; +} + +export class LocalStorageValueProvider extends PureComponent, State> { + constructor(props: Props) { + super(props); + + const { storageKey, defaultValue } = props; + + this.state = { + value: store.getObject(storageKey, defaultValue), + }; + } + + onSaveToStore = (value: T) => { + const { storageKey } = this.props; + try { + store.setObject(storageKey, value); + } catch (error) { + console.error(error); + } + this.setState({ value }); + }; + + onDeleteFromStore = () => { + const { storageKey, defaultValue } = this.props; + try { + store.delete(storageKey); + } catch (error) { + console.log(error); + } + this.setState({ value: defaultValue }); + }; + + render() { + const { children } = this.props; + const { value } = this.state; + + return <>{children(value, this.onSaveToStore, this.onDeleteFromStore)}; + } +} diff --git a/public/app/core/components/LocalStorageValueProvider/index.tsx b/public/app/core/components/LocalStorageValueProvider/index.tsx new file mode 100644 index 00000000..e4bde7cc --- /dev/null +++ b/public/app/core/components/LocalStorageValueProvider/index.tsx @@ -0,0 +1 @@ +export { LocalStorageValueProvider } from './LocalStorageValueProvider'; diff --git a/public/app/core/components/Login/LoginCtrl.tsx b/public/app/core/components/Login/LoginCtrl.tsx new file mode 100644 index 00000000..aa969a8d --- /dev/null +++ b/public/app/core/components/Login/LoginCtrl.tsx @@ -0,0 +1,154 @@ +import React, { PureComponent } from 'react'; +import config from 'app/core/config'; +import { getBackendSrv } from '@grafana/runtime'; +import appEvents from 'app/core/app_events'; +import { AppEvents } from '@grafana/data'; + +const isOauthEnabled = () => { + return !!config.oauth && Object.keys(config.oauth).length > 0; +}; + +export interface FormModel { + user: string; + password: string; + email: string; +} + +interface Props { + resetCode?: string; + + children: (props: { + isLoggingIn: boolean; + changePassword: (pw: string) => void; + isChangingPassword: boolean; + skipPasswordChange: Function; + login: (data: FormModel) => void; + disableLoginForm: boolean; + ldapEnabled: boolean; + authProxyEnabled: boolean; + disableUserSignUp: boolean; + isOauthEnabled: boolean; + loginHint: string; + passwordHint: string; + }) => JSX.Element; +} + +interface State { + isLoggingIn: boolean; + isChangingPassword: boolean; +} + +export class LoginCtrl extends PureComponent { + result: any = {}; + + constructor(props: Props) { + super(props); + this.state = { + isLoggingIn: false, + isChangingPassword: false, + }; + + if (config.loginError) { + appEvents.emit(AppEvents.alertWarning, ['Login Failed', config.loginError]); + } + } + + changePassword = (password: string) => { + const pw = { + newPassword: password, + confirmNew: password, + oldPassword: 'admin', + }; + + if (!this.props.resetCode) { + getBackendSrv() + .put('/api/user/password', pw) + .then(() => { + this.toGrafana(); + }) + .catch((err: any) => console.error(err)); + } + + const resetModel = { + code: this.props.resetCode, + newPassword: password, + confirmPassword: password, + }; + + getBackendSrv() + .post('/api/user/password/reset', resetModel) + .then(() => { + this.toGrafana(); + }); + }; + + login = (formModel: FormModel) => { + this.setState({ + isLoggingIn: true, + }); + + getBackendSrv() + .post('/login', formModel) + .then((result: any) => { + this.result = result; + if (formModel.password !== 'admin' || config.ldapEnabled || config.authProxyEnabled) { + this.toGrafana(); + return; + } else { + this.changeView(); + } + }) + .catch(() => { + this.setState({ + isLoggingIn: false, + }); + }); + }; + + changeView = () => { + this.setState({ + isChangingPassword: true, + }); + }; + + toGrafana = () => { + // Use window.location.href to force page reload + if (this.result.redirectUrl) { + if (config.appSubUrl !== '' && !this.result.redirectUrl.startsWith(config.appSubUrl)) { + window.location.assign(config.appSubUrl + this.result.redirectUrl); + } else { + window.location.assign(this.result.redirectUrl); + } + } else { + window.location.assign(config.appSubUrl + '/'); + } + }; + + render() { + const { children } = this.props; + const { isLoggingIn, isChangingPassword } = this.state; + const { login, toGrafana, changePassword } = this; + const { loginHint, passwordHint, disableLoginForm, ldapEnabled, authProxyEnabled, disableUserSignUp } = config; + + return ( + <> + {children({ + isOauthEnabled: isOauthEnabled(), + loginHint, + passwordHint, + disableLoginForm, + ldapEnabled, + authProxyEnabled, + disableUserSignUp, + login, + isLoggingIn, + changePassword, + skipPasswordChange: toGrafana, + isChangingPassword, + })} + + ); + } +} + +export default LoginCtrl; diff --git a/public/app/core/components/Login/LoginForm.tsx b/public/app/core/components/Login/LoginForm.tsx new file mode 100644 index 00000000..e7dc1d4d --- /dev/null +++ b/public/app/core/components/Login/LoginForm.tsx @@ -0,0 +1,59 @@ +import React, { FC, ReactElement } from 'react'; +import { selectors } from '@grafana/e2e-selectors'; + +import { FormModel } from './LoginCtrl'; +import { Button, Form, Input, Field } from '@grafana/ui'; +import { css } from '@emotion/css'; +import { PasswordField } from '../PasswordField/PasswordField'; + +interface Props { + children: ReactElement; + onSubmit: (data: FormModel) => void; + isLoggingIn: boolean; + passwordHint: string; + loginHint: string; +} + +const wrapperStyles = css` + width: 100%; + padding-bottom: 16px; +`; + +export const submitButton = css` + justify-content: center; + width: 100%; +`; + +export const LoginForm: FC = ({ children, onSubmit, isLoggingIn, passwordHint, loginHint }) => { + return ( +
+
+ {({ register, errors }) => ( + <> + + + + + + + + {children} + + )} +
+
+ ); +}; diff --git a/public/app/core/components/Login/LoginLayout.tsx b/public/app/core/components/Login/LoginLayout.tsx new file mode 100644 index 00000000..c2e5f448 --- /dev/null +++ b/public/app/core/components/Login/LoginLayout.tsx @@ -0,0 +1,153 @@ +import React, { FC, useEffect, useState } from 'react'; +import { cx, css, keyframes } from '@emotion/css'; +import { useStyles2, styleMixins } from '@grafana/ui'; +import { Branding } from '../Branding/Branding'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Footer } from '../Footer/Footer'; + +interface InnerBoxProps { + enterAnimation?: boolean; +} +export const InnerBox: FC = ({ children, enterAnimation = true }) => { + const loginStyles = useStyles2(getLoginStyles); + return
{children}
; +}; + +export const LoginLayout: FC = ({ children }) => { + const loginStyles = useStyles2(getLoginStyles); + const subTitle = Branding.GetLoginSubTitle(); + const [startAnim, setStartAnim] = useState(false); + + useEffect(() => setStartAnim(true), []); + + return ( + +
+
+ +
+

{Branding.LoginTitle}

+ {subTitle &&

{Branding.GetLoginSubTitle()}

} +
+
+
{children}
+
+